# 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.