# Domain Entities — Unit 1: master-backend ## Entity Overview ```mermaid graph TD MasterDbCtx["MasterDbContext\n(per-module EF Core DbContext)"] CmsInst["CmsInstance\n(aggregate root)"] Status["CmsInstanceStatus\n(enum)"] Opts["MasterModuleOptions\n(config POCO)"] DP["IDataProtector\n(ApiKey encryption)"] DTO["CmsInstanceDto\n(API response shape)"] CreateReq["CreateCmsInstanceRequest\n(API input)"] UpdateReq["UpdateStatusRequest\n(API input)"] UpdateRes["UpdateStatusResult\n(API response for status update)"] MasterDbCtx -->|"owns"| CmsInst CmsInst -->|"has"| Status CmsInst -->|"ApiKey encrypted via"| DP CmsInst -->|"projected to"| DTO CreateReq -->|"creates"| CmsInst UpdateReq -->|"mutates status of"| CmsInst UpdateRes -->|"returned from UpdateStatusAsync"| CmsInst Opts -->|"IntegrityCheckIntervalMinutes"| MasterDbCtx Opts -->|"MasterUrl fallback"| MasterDbCtx classDef entity fill:#9ae6b4,stroke:#2f855a,stroke-width:2px,color:#000 classDef infra fill:#63b3ed,stroke:#2b6cb0,stroke-width:1px,color:#000 classDef dto fill:#FFC107,stroke:#F57F17,stroke-width:1px,color:#000 classDef config fill:#CE93D8,stroke:#6A1B9A,stroke-width:1px,color:#000 class CmsInst entity class MasterDbCtx,DP infra class Status,DTO,CreateReq,UpdateReq,UpdateRes dto class Opts config ``` Text alternative: MasterDbContext owns CmsInstance; CmsInstance has a Status enum and its ApiKey is encrypted via IDataProtector; request/response shapes map to and from CmsInstance. --- ## CmsInstance **Table**: `CmsInstances` (owned by `MasterDbContext`, migrations in `SlpModularCms.Modules.Master`) | Field | Type | Nullable | Notes | |-------|------|----------|-------| | `Id` | `Guid` | No | Primary key | | `Name` | `string` | No | Friendly display name; required | | `Url` | `string` | No | Base URL of slave CMS API; must start with `http://` or `https://` | | `ApiKey` | `string` | No | Encrypted via ASP.NET Core Data Protection before storage; decrypted before HTTP calls | | `Status` | `CmsInstanceStatus` | No | Default: `Available` on creation | | `DisableMessage` | `string?` | Yes | Required when `Status = NotAvailable`; null otherwise | | `LastContactedAt` | `DateTimeOffset?` | Yes | Null = never successfully contacted; set on successful registration or integrity check | | `LastStatusPushedAt` | `DateTimeOffset?` | Yes | Null = status never successfully pushed; set after successful `PushStatusAsync` | | `LastIntegrityCheckFailedAt` | `DateTimeOffset?` | Yes | Null = no pending failure; set when integrity check cannot reach slave or re-registration fails; cleared on next successful contact | --- ## CmsInstanceStatus ```csharp public enum CmsInstanceStatus { Available = 0, NotAvailable = 1, Inactive = 2, } ``` | Value | Meaning | Master Contacts Slave? | |-------|---------|----------------------| | `Available` | Slave is enabled; normal operation | Yes (status push + integrity checks) | | `NotAvailable` | Slave is disabled; `DisableMessage` served to end-users | Yes (status push + integrity checks) | | `Inactive` | Soft-removed; greyed out in UI | **No** — all HTTP contact is halted | --- ## MasterModuleOptions **Config section**: `"MasterModule"` in `appsettings.json` | Property | Type | Default | Side | Notes | |----------|------|---------|------|-------| | `IntegrityCheckIntervalMinutes` | `int` | `60` | Master | Interval for `IntegrityCheckBackgroundService` | | `MasterUrl` | `string?` | `null` | Master | Fallback public URL of this master CMS; used by background service when `HttpContext` is unavailable | | `CacheMinutes` | `int` | `60` | Slave | Slave pull cache interval (used by Unit 2) | | `ApiKey` | `string?` | `null` | Slave | Slave API key for validating incoming master requests (used by Unit 2) | --- ## CmsInstanceDto (API Response) **Rule**: `ApiKey` is **never** included (NFR-MASTER-03). | Property | Type | Notes | |----------|------|-------| | `Id` | `Guid` | | | `Name` | `string` | | | `Url` | `string` | | | `Status` | `string` | Serialized as string (`"Available"` / `"NotAvailable"` / `"Inactive"`) | | `DisableMessage` | `string?` | | | `LastContactedAt` | `DateTimeOffset?` | | | `LastStatusPushedAt` | `DateTimeOffset?` | | | `LastIntegrityCheckFailedAt` | `DateTimeOffset?` | Visible in UI so owner knows which slaves have pending check failures | --- ## CreateCmsInstanceRequest (API Input) | Property | Type | Validation | |----------|------|-----------| | `Name` | `string` | Required, non-empty | | `Url` | `string` | Required; must start with `http://` or `https://` | | `ApiKey` | `string` | Required, non-empty | --- ## UpdateStatusRequest (API Input) | Property | Type | Validation | |----------|------|-----------| | `Status` | `CmsInstanceStatus` | Required; must be valid enum value | | `DisableMessage` | `string?` | Required and non-empty when `Status = NotAvailable`; ignored otherwise | --- ## UpdateStatusResult (Service Return / API Response) | Property | Type | Notes | |----------|------|-------| | `Success` | `bool` | Always `true` when status persisted to DB (DB is the authority) | | `SlaveContactSuccess` | `bool` | `true` if HTTP push to slave succeeded; `false` if push failed (slave unreachable); not applicable for `Inactive` transitions (returns `true`) |