# Business Overview
## Business Context Diagram
```mermaid
graph TD
owner["Owner
(system owner)"]
admin["Administrator"]
enduser["User"]
visitor["Public website visitor"]
cms["SlpModularCms instance
(single host process)"]
slave["Other CMS instances
(slaves)"]
db[("SQL Server
database")]
owner --> cms
admin --> cms
enduser --> cms
visitor --> cms
cms --> db
cms -->|"pushes availability status"| slave
slave -->|"polls own status"| cms
classDef actor fill:#f6e05e,stroke:#c05621,stroke-width:1px,color:#000;
classDef system fill:#63b3ed,stroke:#2b6cb0,stroke-width:1px,color:#000;
classDef external fill:#9ae6b4,stroke:#2f855a,stroke-width:1px,color:#000;
classDef store fill:#d6bcfa,stroke:#6b46c1,stroke-width:1px,color:#000;
class owner,admin,enduser,visitor actor;
class cms system;
class slave external;
class db store;
```
Text alternative: Owners, administrators, users and public visitors all interact with a single SlpModularCms host process, which persists to SQL Server and — when acting as a Master — centrally manages the availability of other (slave) CMS instances that in turn poll it for their own status.
## Business Description
- **Business Description**: SlpModularCms is a modular-monolith content management system built on .NET 10. A single deployed instance serves three surfaces from one host process: the customer's public website (`/`), the CMS administration UI (`/admin`), and the REST API (`/api/v1`). Functionality is delivered by pluggable modules discovered at startup, so one codebase can be deployed in different capability configurations. One instance can additionally take the role of **Master**, from which the system owner centrally enables or disables other ("slave") CMS instances — the commercial lever that lets the operator suspend a customer site (for example on non-payment) without needing access to that site's own hosting.
- **Business Transactions**:
| Transaction | Description |
|---|---|
| Initial system bootstrap | On a fresh installation the first Owner account is created via a one-time setup flow; afterwards the setup endpoint reports the system as initialized. |
| Authenticate a user | A user logs in and receives a short-lived access token plus a rotating refresh token held in an httpOnly cookie; the session refreshes silently and can be revoked. |
| Change own password | An authenticated user replaces their own password. |
| Invite and onboard a user | An administrator invites a person; the invitee validates the invitation token and completes registration to become an active user. |
| Manage users | An administrator lists users, changes a user's role, activates or deactivates a user, or deletes a user. Role changes obey a hierarchy (Owner > Administrator > User). |
| Maintain own profile | Any authenticated user updates their own profile details. |
| Control local availability | An Owner switches the instance between Available, NotAvailable and Maintenance, with an optional reason shown to blocked callers. |
| Register a slave instance | On the Master an Owner adds another CMS instance by URL; the Master generates an API key, stores it encrypted and pushes the registration to that instance. |
| Centrally set a slave's status | The Owner sets a registered instance to Available, NotAvailable or Inactive on the Master; the change is pushed to the slave synchronously. |
| Reconcile slave status | A recurring integrity check on the Master re-pushes the authoritative status to every active slave, and each slave independently polls the Master for its own status — so a restarted slave or a locally tampered status self-heals. |
| Discover instance capabilities | A client asks which optional modules are loaded on this instance, so it can hide features the deployment does not have rather than showing an error. |
| Serve the public website | An anonymous visitor loads the customer's public website from the same host process that runs the API. |
- **Business Dictionary**:
| Term | Meaning |
|---|---|
| **Module** | A self-contained functional unit implementing `IModule`, discovered from disk at startup. Determines what a deployed instance can do. |
| **Master** | An instance running the Master module, from which the availability of other instances is centrally managed. |
| **Slave** | An instance whose availability is (partly) controlled by a Master. Technically any instance running the Availability module that holds a Master registration. |
| **Availability status** | Whether an instance serves requests: `Available`, `NotAvailable`, or `Maintenance`. |
| **CMS instance status** | The Master's view of a registered instance: `Available`, `NotAvailable`, or `Inactive` (no longer managed by the Master; the gate is released). |
| **Master gate** | The check that blocks requests when the Master has marked this instance unavailable — separate from, and in addition to, the instance's own local availability switch. |
| **Fail-open** | Safety rule: if a slave cannot reach its Master for longer than a configured window, it reverts to Available, so an unreachable Master can never permanently block a site. |
| **Admin bypass** | An Owner or Administrator bearer token passes the availability gate, so administrators can always reach the system to switch it back on. |
| **Capability** | A module present on this instance, exposed so clients can distinguish "feature absent in this deployment" from "error". |
| **Owner / Administrator / User** | The hierarchical roles; a higher role satisfies every requirement of a lower one. |
| **Invitation** | A time-limited token allowing a named person to create an account. |
| **Public website** | The customer-facing site served at `/`. Built and deployed separately; **not part of this repository**. |
| **Admin SPA** | The CMS administration single-page application served at `/admin`, built from `frontend/`. |
## Component Level Business Descriptions
### SlpModularCms.Api (host / Client)
- **Purpose**: The deployable application. Boots the module system and serves all three surfaces — public website, admin SPA and API — from one process.
- **Responsibilities**: Compose configuration; discover and activate modules; serve static files and per-path SPA fallbacks; expose the API under a single `/api/v1` prefix; build and embed the admin SPA at publish time.
### SlpModularCms.Api.Slave (host / Client)
- **Purpose**: A second host representing an instance **without** the Master module, so master↔slave behaviour can be exercised locally.
- **Responsibilities**: Same as the Api host minus central management; deliberately references only Core, Identity and Availability.
### SlpModularCms.Core
- **Purpose**: The shared foundation every module builds on.
- **Responsibilities**: Identity, authentication and hierarchical authorization; the module contract and orchestrator; the availability contract; uniform RFC 9457 error responses; the `/api/v1` routing convention; capability reporting.
### SlpModularCms.Modules.Identity
- **Purpose**: Exposes account and access management to clients.
- **Responsibilities**: Login/refresh/revoke and password change; first-Owner setup; invitations; user administration.
### SlpModularCms.Modules.Availability
- **Purpose**: Decides whether this instance serves requests, honouring both the local switch and the Master's verdict.
- **Responsibilities**: Persist local availability; hold the Master registration; enforce the gate as middleware with documented bypasses; poll the Master for its own status; fail open when the Master is unreachable.
### SlpModularCms.Modules.Master
- **Purpose**: Turns an instance into the central control point for other instances.
- **Responsibilities**: Register instances and issue encrypted API keys; push status changes to slaves; answer a slave's status poll; reconcile periodically so drift and restarts self-heal.
### frontend (admin SPA)
- **Purpose**: The web UI through which Owners, Administrators and Users operate the CMS.
- **Responsibilities**: Login and silent session refresh; dashboard; user and invitation management; profile; availability settings (locked when the Master controls it); Master instance management; capability-driven feature gating.
### Test projects
- **Purpose**: Protect the business rules above against regression.
- **Responsibilities**: `SlpModularCms.Core.Tests`, `SlpModularCms.Modules.Identity.Tests`, `SlpModularCms.Modules.Availability.Tests` and `SlpModularCms.Modules.Master.Tests` mirror the production projects; the admin SPA has its own Vitest suite. `SlpModularCms.Api.Slave` has no test project by design.