165 lines
7.8 KiB
Markdown
165 lines
7.8 KiB
Markdown
# 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` |
|