Application Design — Master CMS Module
Design Decisions Summary
| Question |
Decision |
| Q1 — HTTP client (Master → Slave) |
A) Typed client — ISlaveApiClient / SlaveApiClient via AddHttpClient<> |
| Q2 — Two-phase gate middleware |
B) Extend AvailabilityMiddleware — Master gate added at top of InvokeAsync |
| Q3 — Slave-side status caching |
A) Static field + timestamp — consistent with existing circuit breaker pattern |
| Q4 — Service responsibility split |
B) CmsInstanceRepository + CmsInstanceService — data and orchestration separated |
| Q5 — Master controller granularity |
A) Single CmsInstanceController — all actions in one controller |
| Q6 — Slave internal endpoint placement |
B) Extended AvailabilityController — registration endpoint added to existing controller |
| Q7 — Frontend hooks organization |
B) Separate hook files — one file per hook: useCmsInstances.ts, useAddCmsInstance.ts, useUpdateCmsInstanceStatus.ts |
Architecture Overview
Text alternative: Master CMS has new module with controller, service, repository, typed HTTP client, and background service; Slave CMS has extended middleware with two-phase gate, new MasterAvailabilityService, new AvailabilityDbContext, and extended controller; Frontend has CmsPage with hooks and components calling Master REST API.
Component Inventory
Unit 1 — master-backend (SlpModularCms.Modules.Master)
| Component |
Type |
New/Modified |
MasterModule |
IModule |
New |
MasterDbContext |
EF Core DbContext |
New |
CmsInstance |
Entity |
New |
CmsInstanceStatus |
Enum |
New |
ICmsInstanceRepository / CmsInstanceRepository |
Repository |
New |
ICmsInstanceService / CmsInstanceService |
Service |
New |
ISlaveApiClient / SlaveApiClient |
Typed HTTP client |
New |
CmsInstanceController |
Controller |
New |
IntegrityCheckBackgroundService |
BackgroundService |
New |
MasterModuleOptions |
Config POCO |
New |
CmsInstanceDto |
DTO |
New |
CreateCmsInstanceRequest |
Request model |
New |
UpdateStatusRequest |
Request model |
New |
Unit 2 — slave-availability-extension (SlpModularCms.Modules.Availability)
| Component |
Type |
New/Modified |
MasterRegistration |
Entity |
New |
AvailabilityDbContext |
EF Core DbContext |
New |
IMasterAvailabilityService / MasterAvailabilityService |
Service |
New |
AvailabilityMiddleware |
Middleware |
Modified |
AvailabilityController |
Controller |
Modified |
MasterGateResult |
Result record |
New |
RegisterMasterRequest |
Request model |
New |
Unit 3 — frontend-cms-page (frontend/)
| Component |
Type |
New/Modified |
CmsPage |
React page |
New |
CmsInstanceList |
React component |
New |
AddCmsInstanceDialog |
React component |
New |
SetStatusDialog |
React component |
New |
useCmsInstances |
TanStack Query hook |
New |
useAddCmsInstance |
TanStack Query hook |
New |
useUpdateCmsInstanceStatus |
TanStack Query hook |
New |
CmsInstance |
TypeScript type |
New |
CmsInstanceStatus |
TypeScript enum |
New |
Unit 4 — documentation
| Artifact |
Type |
New/Modified |
README.md — Migrations section |
Documentation |
Modified |
README.md — Module guide section |
Documentation |
Modified |
README.md — Production env vars |
Documentation |
Modified |
frontend/README.md |
Documentation |
Modified |
Key Design Constraints
| Constraint |
Source |
Impact |
ApiKey never returned in API responses |
NFR-MASTER-03 |
CmsInstanceDto excludes ApiKey; only accepted in CreateCmsInstanceRequest |
| Fail-open on Master unreachable |
NFR-MASTER-01 |
(Updated 2026-07-04) Originally only an in-memory startup default (_masterIsAvailable = true); now actively enforced by MasterStatusPollingBackgroundService.RecordPollFailureAsync, which forces the gate open if the master has been unreachable via poll for longer than MasterPolling:FailOpenAfterMinutes — this is the slave-pull half of FR-MASTER-06/07 that was originally specified but not implemented until 2026-07-04 (see slave-availability-extension/functional-design/business-rules.md Rule Set 5) |
| Per-module DbContext + migrations |
NFR-MASTER-06 |
New MasterDbContext in Modules.Master; new AvailabilityDbContext in Modules.Availability |
| Master exemption from own gate |
FR-MASTER-09 |
Handled naturally: no MasterRegistration record exists on Master instance → gate skipped |
| Disable message required for NotAvailable |
FR-MASTER-14 |
Validated in CmsInstanceService.UpdateStatusAsync before persistence |
| Inactive slaves: no further HTTP contact |
FR-MASTER-13 |
(Updated 2026-07-04) GetActiveAsync() filters out Inactive instances from ongoing integrity checks and status re-pushes, as before — but the transition into Inactive itself now always performs one final push (Available, no message) to release the master gate before the instance drops out; previously this transition performed no push at all, leaving the slave stuck on its last status |
| Owner role only |
FR-MASTER-10 |
[Authorize(Policy = "OwnerOnly")] on all CmsInstanceController actions |
Artifact References
| Artifact |
Path |
| Component definitions |
aidlc-docs/features/master-cms-module/inception/application-design/components.md |
| Method signatures |
aidlc-docs/features/master-cms-module/inception/application-design/component-methods.md |
| Service orchestration + flows |
aidlc-docs/features/master-cms-module/inception/application-design/services.md |
| Dependency diagrams + matrix |
aidlc-docs/features/master-cms-module/inception/application-design/component-dependency.md |