Adds the AI-DLC inception record for deploying the CMS as a single .NET application on hosting where no server configuration is possible. The reverse-engineering artifacts were regenerated: the previous set predated the Master module, the Slave host, the solution reorganisation and single-host serving, all of which matter for deployment. Findings were verified by running the build, both test suites and the linter rather than inferred, which surfaced two facts the plan depends on: the frontend lint gate currently fails (5 errors), and two transitive packages carry high-severity advisories. Records 24 functional requirements, 32 traced decisions and a seven-unit decomposition whose ordering is load-bearing: durability work must land before the first automated deploy, or the very first deploy is the one that silently breaks master/slave trust. Two conflicts found while designing and carried into the units: - Both modules call AddDataProtection(), which runs after the host and would override a persistent key store while still passing any registration test. - The availability gate runs before authentication, so its admin bypass cannot read HttpContext.User. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01HHoJpxYXzHACSQguHrC5fw
8.6 KiB
Business Overview
Business Context Diagram
graph TD
owner["Owner<br/>(system owner)"]
admin["Administrator"]
enduser["User"]
visitor["Public website visitor"]
cms["SlpModularCms instance<br/>(single host process)"]
slave["Other CMS instances<br/>(slaves)"]
db[("SQL Server<br/>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, orMaintenance.CMS instance status The Master's view of a registered instance: Available,NotAvailable, orInactive(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 fromfrontend/.
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/v1prefix; 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/v1routing 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.TestsandSlpModularCms.Modules.Master.Testsmirror the production projects; the admin SPA has its own Vitest suite.SlpModularCms.Api.Slavehas no test project by design.