Adds 2 units and docs for unit 3. nfr-requirements plan

This commit is contained in:
2026-06-29 22:18:37 +02:00
parent 0e01ca1e1c
commit c156107cb1
126 changed files with 15204 additions and 80199 deletions
@@ -0,0 +1,63 @@
# Code Summary — Unit 1: master-backend
## New Project: SlpModularCms.Modules.Master
| File | Description |
|------|-------------|
| `SlpModularCms.Modules.Master.csproj` | Project file; references Core; adds Microsoft.Extensions.Http.Resilience 9.6.0 |
| `Options/MasterModuleOptions.cs` | Configuration POCO: IntegrityCheckIntervalMinutes, HttpTimeoutSeconds, MasterUrl, CacheMinutes, ApiKey |
| `Data/Entities/CmsInstanceStatus.cs` | Enum: Available=0, NotAvailable=1, Inactive=2 |
| `Data/Entities/CmsInstance.cs` | EF Core entity with all domain fields including LastIntegrityCheckFailedAt |
| `Data/MasterDbContext.cs` | Per-module DbContext; table MasterCmsInstances; configured via OnModelCreating |
| `Models/CmsInstanceDto.cs` | Record DTO (excludes ApiKey); ExcludeFromCodeCoverage |
| `Models/CreateCmsInstanceRequest.cs` | Record request for POST; ExcludeFromCodeCoverage |
| `Models/UpdateStatusRequest.cs` | Record request for status update; ExcludeFromCodeCoverage |
| `Models/UpdateStatusResult.cs` | Record result with Success + SlaveContactSuccess; ExcludeFromCodeCoverage |
| `Repositories/ICmsInstanceRepository.cs` | Interface: GetAllAsync, GetActiveAsync, GetByIdAsync, AddAsync, Update, SaveChangesAsync |
| `Repositories/CmsInstanceRepository.cs` | EF Core implementation; GetActiveAsync excludes Inactive |
| `Services/IApiKeyProtector.cs` | Interface: Protect/Unprotect |
| `Services/ApiKeyProtector.cs` | Data Protection wrapper; purpose string "SlpModularCms.Master.ApiKey" |
| `Services/ISlaveApiClient.cs` | Interface: RegisterMasterAsync, PushStatusAsync, GetRegisteredMasterUrlAsync |
| `Services/SlaveApiClient.cs` | Typed HTTP client; X-Master-Api-Key header on each call; fail-open (returns false on exception) |
| `Services/MasterServiceDependencies.cs` | Record aggregating 6 CmsInstanceService dependencies; ExcludeFromCodeCoverage |
| `Services/ICmsInstanceService.cs` | Interface: GetAllAsync, AddAsync, UpdateStatusAsync, VerifyIntegrityAsync |
| `Services/CmsInstanceService.cs` | Business logic; HttpContext → config fallback for MasterUrl; never returns ApiKey in DTO |
| `BackgroundServices/IntegrityCheckBackgroundService.cs` | PeriodicTimer; per-tick IServiceScope; catches all exceptions per tick |
| `Controllers/CmsInstanceController.cs` | [Authorize(Policy="OwnerOnly")]; GET / POST / PUT /{id}/status |
| `MasterModule.cs` | IModule implementation; DI registration; db.Database.Migrate() in UseModule; ExcludeFromCodeCoverage |
| `Migrations/.gitkeep` | Placeholder; run CLI to generate migration (see below) |
## New Project: SlpModularCms.Modules.Master.Tests
| File | Description |
|------|-------------|
| `SlpModularCms.Modules.Master.Tests.csproj` | xUnit + NSubstitute + FluentAssertions + EF InMemory |
| `Repositories/CmsInstanceRepositoryTests.cs` | EF InMemory; covers all repository methods |
| `Services/ApiKeyProtectorTests.cs` | Uses EphemeralDataProtectionProvider; round-trip + invalid ciphertext tests |
| `Services/SlaveApiClientTests.cs` | FakeHttpMessageHandler; tests success/failure/exception paths + header assertion |
| `Services/CmsInstanceServiceTests.cs` | NSubstitute; covers all business logic branches including HttpContext fallback |
| `BackgroundServices/IntegrityCheckBackgroundServiceTests.cs` | PeriodicTimer integration; verifies exception isolation |
| `Controllers/CmsInstanceControllerTests.cs` | NSubstitute ICmsInstanceService; verifies all HTTP response codes |
## Modified Files
| File | Change |
|------|--------|
| `src/SlpModularCms.Api/SlpModularCms.Api.csproj` | Added ProjectReference to SlpModularCms.Modules.Master |
| `SlpModularCms.sln` | Added both new projects with GUIDs and src folder nesting |
## EF Core Migration
After building the solution, run:
```bash
dotnet ef migrations add InitialCreate --project src/SlpModularCms.Modules.Master --startup-project src/SlpModularCms.Api
```
This generates the `Migrations/` folder contents. The migration is applied automatically on startup via `db.Database.Migrate()` in `MasterModule.UseModule`.
## Notes
- `Microsoft.Extensions.Http.Resilience` version `9.6.0` — verify/update during `dotnet restore` if a newer version is available for .NET 10
- `IntegrityCheckIntervalMinutes = 0` in tests forces immediate PeriodicTimer ticks (valid for test scenarios only)
- Slave-side endpoints (`/api/v1/master/register`, `/api/v1/master/status`, `/api/v1/master/registered-url`) are implemented in Unit 2 (slave-availability-extension)