Adds 2 units and docs for unit 3. nfr-requirements plan
This commit is contained in:
+164
@@ -0,0 +1,164 @@
|
||||
# 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
|
||||
|
||||
```mermaid
|
||||
graph TD
|
||||
subgraph MasterCms["Master CMS Instance"]
|
||||
MasterModule["MasterModule\n(IModule)"]
|
||||
CmsCtrl["CmsInstanceController\n/api/v1/CmsInstances"]
|
||||
CmsService["CmsInstanceService\n(orchestration)"]
|
||||
CmsRepo["CmsInstanceRepository\n(data access)"]
|
||||
MasterDb["MasterDbContext\nCmsInstances table"]
|
||||
SlaveClient["SlaveApiClient\n(typed HTTP client)"]
|
||||
BgService["IntegrityCheckBackgroundService\n(PeriodicTimer)"]
|
||||
MasterOpts["MasterModuleOptions"]
|
||||
end
|
||||
|
||||
subgraph SlaveCms["Slave CMS Instance"]
|
||||
ExtAvailMw["AvailabilityMiddleware\n(EXTENDED — two-phase gate)"]
|
||||
MasterAvailSvc["MasterAvailabilityService\n(pull + cache + fallback)"]
|
||||
LocalAvailSvc["IAvailabilityService\n(existing local gate)"]
|
||||
AvailDb["AvailabilityDbContext\nMasterRegistrations table"]
|
||||
ExtAvailCtrl["AvailabilityController\n(EXTENDED + RegisterMaster)"]
|
||||
SlaveOpts["MasterModuleOptions\n(ApiKey, CacheMinutes)"]
|
||||
end
|
||||
|
||||
subgraph FrontendApp["Frontend (Master UI)"]
|
||||
CmsPage["CmsPage\n(/cms route)"]
|
||||
Hooks["TanStack Query Hooks\n(useCmsInstances, useAddCmsInstance,\nuseUpdateCmsInstanceStatus)"]
|
||||
Components["Components\n(CmsInstanceList,\nAddCmsInstanceDialog,\nSetStatusDialog)"]
|
||||
end
|
||||
|
||||
FrontendApp -->|"REST /api/v1/CmsInstances"| MasterCms
|
||||
MasterCms -->|"HTTP slave API"| SlaveCms
|
||||
SlaveCms -->|"HTTP pull status"| MasterCms
|
||||
|
||||
CmsPage --> Components
|
||||
Components --> Hooks
|
||||
Hooks -->|"GET/POST/PUT"| CmsCtrl
|
||||
CmsCtrl --> CmsService
|
||||
CmsService --> CmsRepo
|
||||
CmsService --> SlaveClient
|
||||
CmsRepo --> MasterDb
|
||||
BgService --> CmsService
|
||||
CmsService --> MasterOpts
|
||||
BgService --> MasterOpts
|
||||
ExtAvailMw --> MasterAvailSvc
|
||||
ExtAvailMw --> LocalAvailSvc
|
||||
MasterAvailSvc --> AvailDb
|
||||
MasterAvailSvc --> SlaveOpts
|
||||
ExtAvailCtrl --> AvailDb
|
||||
ExtAvailCtrl --> SlaveOpts
|
||||
|
||||
classDef module fill:#9ae6b4,stroke:#2f855a,stroke-width:2px,color:#000
|
||||
classDef controller fill:#63b3ed,stroke:#2b6cb0,stroke-width:1px,color:#000
|
||||
classDef service fill:#FFC107,stroke:#F57F17,stroke-width:1px,color:#000
|
||||
classDef data fill:#CE93D8,stroke:#6A1B9A,stroke-width:1px,color:#000
|
||||
classDef frontend fill:#FC8181,stroke:#C53030,stroke-width:1px,color:#000
|
||||
classDef config fill:#B0BEC5,stroke:#546E7A,stroke-width:1px,color:#000
|
||||
class MasterModule module
|
||||
class CmsCtrl,ExtAvailCtrl controller
|
||||
class CmsService,MasterAvailSvc,SlaveClient,LocalAvailSvc,BgService service
|
||||
class CmsRepo,MasterDb,AvailDb data
|
||||
class CmsPage,Hooks,Components frontend
|
||||
class MasterOpts,SlaveOpts config
|
||||
```
|
||||
|
||||
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 | `MasterAvailabilityService` returns last cached status (default Available) on HTTP failure |
|
||||
| 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 HTTP contact | FR-MASTER-13 | `GetActiveAsync()` filters out Inactive before integrity checks and status pushes |
|
||||
| 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` |
|
||||
Reference in New Issue
Block a user