Completes master-cms-module: Build & Test, docs, and appsettings
Finishes the master-cms-module feature (Units 1-4): runs Build and Test across master-backend, slave-availability-extension and frontend-cms-page, fixes a missing Availability EF migration for MasterRegistration and a TanStack Query v5 mutation-callback type break, adds the missing MasterModule appsettings section, and documents the module in README.md. Also seeds a tech-debt-backlog feature to track dead config and pre-existing/introduced frontend lint findings for later cleanup.
This commit is contained in:
@@ -5,7 +5,7 @@
|
||||
- **Feature Slug**: master-cms-module
|
||||
- **Project Type**: Brownfield
|
||||
- **Start Date**: 2026-06-26T00:00:00Z
|
||||
- **Current Stage**: CONSTRUCTION - Unit 3 (frontend-cms-page) Code Generation Complete
|
||||
- **Current Stage**: COMPLETE - All 4 units done, Build and Test passed, Unit 4 approved
|
||||
- **Branch**: unknown
|
||||
|
||||
## Workspace State
|
||||
@@ -55,9 +55,11 @@
|
||||
- [x] NFR Requirements — Complete (Unit 3)
|
||||
- [x] NFR Design — Complete (Unit 3)
|
||||
- [x] Code Generation — Complete (Unit 3)
|
||||
- [ ] Infrastructure Design — Skipped
|
||||
- [ ] Code Generation — Execute (per unit)
|
||||
- [ ] Build and Test — Execute
|
||||
- [x] Infrastructure Design — Skipped (Units 1-3)
|
||||
- [x] Code Generation — Complete (Units 1-3)
|
||||
- [x] Build and Test — Complete (Units 1-3: build success, 402 automated tests pass)
|
||||
- [x] Functional Design — Skipped (Unit 4 - documentation only, no business logic)
|
||||
- [x] Code Generation — Complete (Unit 4 - documentation: README.md, frontend/README.md, appsettings.json/Development.json)
|
||||
|
||||
### 🟡 OPERATIONS PHASE
|
||||
- [ ] Operations — Placeholder
|
||||
- [x] Operations — Placeholder acknowledged; workflow complete
|
||||
|
||||
@@ -1,5 +1,108 @@
|
||||
# Audit Log — Master CMS Module
|
||||
|
||||
## Build and Test Stage — Approved
|
||||
|
||||
**Timestamp**: 2026-07-01T00:10:00Z
|
||||
|
||||
**User Input**: "Goedkeuren & doorgaan naar Unit 4 documentation"
|
||||
|
||||
**AI Response**: "Build and Test resultaten goedgekeurd. Doorgaan naar Unit 4 (documentation): Functional Design en NFR stages worden overgeslagen (geen business logic / geen nieuwe NFR's voor documentatiewerk), rechtstreeks naar Code Generation voor deze unit."
|
||||
|
||||
**Context**: Build and Test stage afgesloten voor Units 1-3; Unit 4 (documentation) gestart
|
||||
|
||||
---
|
||||
|
||||
## Gap Found & Fixed — Missing Availability Migration
|
||||
|
||||
**Timestamp**: 2026-07-01T00:15:00Z
|
||||
|
||||
**User Input**: (discovered during Unit 4 documentation prep, no direct user input)
|
||||
|
||||
**AI Response**: "Ontdekt dat `SlpModularCms.Modules.Availability` geen EF Core migratie had voor de nieuwe `MasterRegistration`-entiteit (Unit 2), terwijl `AvailabilityModule.UseModule` wel `Database.Migrate()` aanroept. Zonder migratie zou de `AvailabilityMasterRegistrations`-tabel nooit worden aangemaakt op een echte database, wat de master-registratie-flow zou breken. Gegenereerd: `dotnet ef migrations add InitialCreate --project src/SlpModularCms.Modules.Availability --startup-project src/SlpModularCms.Api --context AvailabilityDbContext`. Solution build geverifieerd na toevoeging — nog steeds succesvol."
|
||||
|
||||
**Context**: Build and Test — gap gevonden na goedkeuring; gefixt vóór Unit 4 start
|
||||
|
||||
---
|
||||
|
||||
## Code Generation Unit 4 — Plan Created
|
||||
|
||||
**Timestamp**: 2026-07-01T00:20:00Z
|
||||
|
||||
**AI Response**: "Code generation plan aangemaakt voor Unit 4 (documentation): 5 stappen — README.md Master CMS Module sectie, migraties-sectie uitbreiden, productie-setup uitbreiden, frontend/README.md vervangen, state bijwerken. Wachten op goedkeuring."
|
||||
|
||||
**Context**: Code Generation Unit 4 Part 1 (Planning) afgerond; wachten op plan-goedkeuring
|
||||
|
||||
---
|
||||
|
||||
## Correction — Lint Baseline Was Contaminated
|
||||
|
||||
**Timestamp**: 2026-07-01T00:25:00Z
|
||||
|
||||
**AI Response**: "Tijdens appsettings-mapping (dotnet-appsettings skill) opnieuw geverifieerd of de 6 lint-problemen echt pre-existing waren. De eerdere check gebruikte `git checkout c156107 -- .` in de werkende frontend-map, wat bestanden die pas bij HEAD zijn toegevoegd (o.a. AddCmsInstanceDialog.tsx, SetStatusDialog.tsx) niet verwijdert — de baseline-meting was dus besmet. Opnieuw gemeten via een schone `git worktree` op c156107 + verse `npm install`: echte pre-existing baseline = 4 problemen (niet 6). De overige 2 (AddCmsInstanceDialog.tsx error, SetStatusDialog.tsx warning) zijn wel degelijk door Unit 3 van deze feature geïntroduceerd. build-and-test-summary.md gecorrigeerd; alle 6 items vastgelegd in de nieuwe tech-debt-backlog feature (TD-002/TD-003) per gebruikersbeslissing, i.p.v. direct gefixt."
|
||||
|
||||
**Context**: Zelfcorrectie tijdens Unit 4 voorbereiding; geen impact op Build & Test goedkeuring (gebruiker had al ingestemd om afwijkingen in een tech-debt feature te verzamelen)
|
||||
|
||||
---
|
||||
|
||||
## MasterModuleOptions Dead Config — Captured as Tech Debt
|
||||
|
||||
**Timestamp**: 2026-07-01T00:20:00Z
|
||||
|
||||
**User Input**: "Laat ze staan en documenteer ze als unused. Maak ook een nieuwe feature aan waar je dit in verwerkt om te fixen dat ze niet worden gebruikt. Als je meer issues vindt gooi die dan ook in deze feature. Maak het dus eigenlijk een soort tech debt feature. Net als de gefaalde tests bij de Build & Test check die je zojuist gedaan hebt. Die tech debt feature kan ik dan later oppakken. Voor nu doorgaan met unit 4"
|
||||
|
||||
**AI Response**: "Nieuwe feature 'tech-debt-backlog' aangemaakt met TD-001 (dode CacheMinutes/ApiKey properties op MasterModuleOptions). Doorgaan met Unit 4 appsettings-mapping: alleen de 3 daadwerkelijk gebruikte properties (IntegrityCheckIntervalMinutes, HttpTimeoutSeconds, MasterUrl) worden in de appsettings-bestanden gedocumenteerd."
|
||||
|
||||
**Context**: Beslissing genomen tijdens Unit 4 voorbereiding (dotnet-appsettings skill); zie aidlc-docs/features/tech-debt-backlog/ voor details
|
||||
|
||||
---
|
||||
|
||||
## Code Generation Unit 4 — Complete
|
||||
|
||||
**Timestamp**: 2026-07-01T00:35:00Z
|
||||
|
||||
**AI Response**: "Unit 4 (documentation) code generation afgerond: README.md uitgebreid met 'Master CMS Module' sectie, migraties-sectie en productie-sectie; frontend/README.md vervangen (stond nog op Vite-boilerplate); MasterModule config-sectie toegevoegd aan appsettings.json + appsettings.Development.json (ontbrak volledig, ontdekt via dotnet-appsettings skill). Solution build geverifieerd — nog steeds succesvol. aidlc-state.md bijgewerkt: alle 4 units compleet."
|
||||
|
||||
**Context**: Code Generation Unit 4 Part 2 (Generation) afgerond; wachten op goedkeuring
|
||||
|
||||
---
|
||||
|
||||
## Code Generation Unit 4 — Approved / Workflow Complete
|
||||
|
||||
**Timestamp**: 2026-07-01T00:40:00Z
|
||||
|
||||
**User Input**: "Doorgaan naar de volgende fase"
|
||||
|
||||
**AI Response**: "Unit 4 (documentation) goedgekeurd — dit was de laatste unit. Operations-fase is een placeholder voor deze feature, dus aidlc-state.md en active-features.md bijgewerkt naar Complete. Sluitsamenvatting gepresenteerd."
|
||||
|
||||
**Context**: Alle 4 units (master-backend, slave-availability-extension, frontend-cms-page, documentation) compleet; Build and Test compleet; workflow voor master-cms-module afgerond
|
||||
|
||||
---
|
||||
|
||||
## Build and Test Stage (Units 1-3)
|
||||
|
||||
**Timestamp**: 2026-07-01T00:00:00Z
|
||||
|
||||
**User Input**: "hervat de master-cms module feature. Waar zijn we gebleven. moet ik nog vragen beantwoorden voor we verder gaan of iets goedkeuren?" — followed by choosing "Build & Test eerst" when asked how to proceed.
|
||||
|
||||
**AI Response**: "Resumed feature; confirmed no outstanding unanswered questions. Ran `dotnet build`/`dotnet test` (193 tests pass) and `npm run build`/`npm run lint`/`npm run test` for the frontend. Found and fixed a TypeScript build break in `useUpdateCmsInstanceStatus.ts` caused by an `@tanstack/react-query` v5.101 signature change (forwarded onSuccess args with a rest parameter instead of a fixed 3-arg call). Frontend tests: 209/209 pass. Frontend lint: 6 pre-existing issues (5 errors, 1 warning), confirmed identical in count to the pre-feature baseline commit `c156107` — none introduced by this feature, left unfixed as out of scope. Generated build-instructions.md, unit-test-instructions.md, integration-test-instructions.md, performance-test-instructions.md, build-and-test-summary.md."
|
||||
|
||||
**Context**: Build and Test stage executed for Units 1-3 (master-backend, slave-availability-extension, frontend-cms-page); Unit 4 (documentation) remains outstanding
|
||||
|
||||
---
|
||||
|
||||
**Build Status**: Success
|
||||
|
||||
**Test Status**: Pass (193 backend + 209 frontend = 402 automated tests)
|
||||
|
||||
**Files Generated**:
|
||||
- build-instructions.md
|
||||
- unit-test-instructions.md
|
||||
- integration-test-instructions.md
|
||||
- performance-test-instructions.md
|
||||
- build-and-test-summary.md
|
||||
|
||||
---
|
||||
|
||||
## Initial Request — Workspace Detection
|
||||
|
||||
**Timestamp**: 2026-06-26T00:00:00Z
|
||||
|
||||
+52
@@ -0,0 +1,52 @@
|
||||
# Build and Test Summary
|
||||
|
||||
## Build Status
|
||||
- **Build Tool**: .NET SDK 10 (backend), Vite + tsc (frontend)
|
||||
- **Build Status**: Success (after one fix — see below)
|
||||
- **Build Artifacts**: `src/**/bin/Debug/net10.0/*.dll`, `frontend/dist/`
|
||||
- **Build Time**: ~15s backend, ~5s frontend
|
||||
|
||||
### Fixes Applied During Build Verification
|
||||
1. `frontend/src/api/useUpdateCmsInstanceStatus.ts` failed `tsc` because the installed `@tanstack/react-query@5.101.0` mutation `onSuccess` callback signature gained a 4th `context` parameter, and the code was manually forwarding only 3 args to the consumer callback. Fixed by forwarding all trailing args with a rest parameter (`...rest`). No behavior change — this is a type-signature compatibility fix, not a logic change.
|
||||
2. **Missing EF Core migration** — `SlpModularCms.Modules.Availability` had no migration for the `MasterRegistration` entity added in Unit 2, even though `AvailabilityModule.UseModule` calls `Database.Migrate()`. On a real database this meant the `AvailabilityMasterRegistrations` table would never be created, breaking the master registration flow end-to-end. Generated via `dotnet ef migrations add InitialCreate --project src/SlpModularCms.Modules.Availability --startup-project src/SlpModularCms.Api --context AvailabilityDbContext`.
|
||||
|
||||
## Test Execution Summary
|
||||
|
||||
### Unit Tests — Backend (.NET)
|
||||
- **Total Tests**: 193
|
||||
- **Passed**: 193
|
||||
- **Failed**: 0
|
||||
- **Status**: Pass
|
||||
- Breakdown: Core.Tests (45), Modules.Identity.Tests (46), Modules.Availability.Tests (60), Modules.Master.Tests (42)
|
||||
|
||||
### Unit Tests — Frontend (Vitest)
|
||||
- **Total Tests**: 209 (34 test files)
|
||||
- **Passed**: 209
|
||||
- **Failed**: 0
|
||||
- **Status**: Pass
|
||||
|
||||
### Integration Tests
|
||||
- **Test Scenarios**: 4 documented in `integration-test-instructions.md` (registration handshake, status push + middleware enforcement, fail-open on push failure/slave restart, frontend CMS page end-to-end)
|
||||
- **Status**: Manual — no automated cross-process harness exists in this codebase; scenarios are documented for manual verification. Underlying logic for each scenario is covered by the unit test suites above.
|
||||
|
||||
### Performance Tests
|
||||
- **Status**: N/A — no explicit performance SLA defined in NFR Requirements. Architectural review confirms the master-gate check is a zero-I/O in-memory field read (documented in `performance-test-instructions.md`).
|
||||
|
||||
### Additional Tests
|
||||
- **Contract Tests**: N/A — no separate service contract test suite; API shape covered by controller/integration unit tests
|
||||
- **Security Tests**: N/A for this stage — API key handling, Data Protection, and auth bypass-prefix design were validated during NFR Design/Requirements review, not re-tested here
|
||||
- **E2E Tests**: N/A — no browser-automation E2E suite in this codebase; frontend interactions covered by Vitest component tests + React Testing Library
|
||||
|
||||
### Lint (Frontend)
|
||||
- `npm run lint`: 6 problems (5 errors, 1 warning). Re-verified with a clean `git worktree` checkout of `c156107` (the commit before this feature's frontend work) plus a fresh `npm install` — an earlier same-tree `git checkout -- .` comparison had been contaminated by files that only exist at HEAD, giving a false "all pre-existing" reading.
|
||||
- **4 pre-existing** (confirmed via the clean baseline): `badge.tsx:32`, `InviteUserDialog.tsx` (×2), `SettingsPage.tsx:39`.
|
||||
- **2 newly introduced by this feature's Unit 3**: `AddCmsInstanceDialog.tsx:55` (error), `SetStatusDialog.tsx:72` (warning) — same underlying pattern as the pre-existing findings.
|
||||
- All 6 items logged to the new `tech-debt-backlog` feature (`aidlc-docs/features/tech-debt-backlog/inception/requirements/backlog.md`, TD-002/TD-003) per user decision (2026-07-01) rather than fixed in-flight, to avoid blocking Unit 4.
|
||||
|
||||
## Overall Status
|
||||
- **Build**: Success
|
||||
- **All Tests**: Pass (402 automated tests: 193 backend + 209 frontend)
|
||||
- **Ready for Operations**: Yes
|
||||
|
||||
## Next Steps
|
||||
Proceed to Operations phase (placeholder) — or, per the execution plan, Unit 4 (documentation) is still outstanding before the feature is fully complete.
|
||||
+32
@@ -0,0 +1,32 @@
|
||||
# Build Instructions
|
||||
|
||||
## Prerequisites
|
||||
- **Build Tool**: .NET SDK 10 (backend), Node.js + npm/pnpm (frontend)
|
||||
- **Dependencies**: NuGet packages (restored automatically), npm packages in `frontend/`
|
||||
- **Environment Variables**: None required for build
|
||||
- **System Requirements**: Windows/Linux/macOS, .NET 10 runtime
|
||||
|
||||
## Build Steps
|
||||
|
||||
### 1. Backend — Install Dependencies & Build
|
||||
```bash
|
||||
dotnet build SlpModularCms.sln
|
||||
```
|
||||
|
||||
### 2. Frontend — Install Dependencies & Build
|
||||
```bash
|
||||
cd frontend
|
||||
npm install
|
||||
npm run build # tsc -b && vite build
|
||||
```
|
||||
|
||||
## Verify Build Success
|
||||
- **Backend**: `Build succeeded. 0 Error(s)` — all 9 projects compile (Core, Modules.Identity, Modules.Availability, Modules.Master, Api, plus 4 test projects)
|
||||
- **Frontend**: Vite produces a `dist/` bundle with no TypeScript errors
|
||||
- **Build Artifacts**: `src/**/bin/Debug/net10.0/*.dll`, `frontend/dist/`
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### TypeScript build fails with mutation callback arity errors
|
||||
- **Cause**: `@tanstack/react-query` v5.101 changed the `onSuccess` mutation callback signature to include a 4th `context` parameter. Manually calling `options?.onSuccess?.(data, variables, context)` with only 3 args now under-supplies the callback's expected arity.
|
||||
- **Solution**: Forward all trailing callback args with a rest parameter, e.g. `onSuccess: (data, variables, ...rest) => { ...; options?.onSuccess?.(data, variables, ...rest); }`. Fixed in `frontend/src/api/useUpdateCmsInstanceStatus.ts`.
|
||||
+82
@@ -0,0 +1,82 @@
|
||||
# Integration Test Instructions
|
||||
|
||||
## Purpose
|
||||
Verify that the three units of the Master CMS Module work together: the Master module (Unit 1), the slave-side Availability extension (Unit 2), and the `/cms` frontend page (Unit 3).
|
||||
|
||||
## Test Scenarios
|
||||
|
||||
### Scenario 1: Owner Adds a Slave — Master Pushes Registration (Unit 1 → Unit 2)
|
||||
- **Description**: The Owner registers a slave CMS from the Master `/cms` page; the Master generates an API key and pushes registration to the slave.
|
||||
- **Setup**: Run two instances of the API — one configured as Master (`SlpModularCms.Modules.Master` enabled), one as Slave (`SlpModularCms.Modules.Availability` running, reachable at a known URL).
|
||||
- **Test Steps**:
|
||||
1. On the Master, call `POST /api/v1/CmsInstances` with the slave's URL.
|
||||
2. `CmsInstanceService` generates an API key, stores it (Data-Protection-encrypted) in `CmsInstance`, and calls `ISlaveApiClient.RegisterMasterAsync` which `POST`s to the slave's `/api/v1/master/register` with the `X-Master-Api-Key` header.
|
||||
3. Query the Master's `GET /api/v1/CmsInstances` list endpoint.
|
||||
4. Query the slave's `GET /api/v1/master/registered-url` (with the same header) to confirm it stored the registration.
|
||||
- **Expected Results**: The new instance appears in the Master's `CmsInstance` list (API key never included in the DTO); the slave's `MasterRegistration` table stores the Master's URL and the Data-Protection-encrypted API key.
|
||||
- **Cleanup**: Stop both instances; clear both DBs if reused.
|
||||
|
||||
### Scenario 2: Master Sets Slave to Inactive → Slave Enforces via Two-Phase Middleware (Unit 1 → Unit 2)
|
||||
- **Description**: Owner disables a slave from the Master `/cms` page; the Master pushes the new status to the slave, whose `AvailabilityMiddleware` blocks CMS requests.
|
||||
- **Setup**: Both instances running and registered (per Scenario 1).
|
||||
- **Test Steps**:
|
||||
1. On the Master, call `PUT /api/v1/CmsInstances/{id}/status` with `Inactive`.
|
||||
2. Confirm the Master's `SlaveApiClient` pushes the status to the slave synchronously as part of the same request (`SlaveContactSuccess` in the response).
|
||||
3. Send a request to the slave's CMS route.
|
||||
- **Expected Results**: Slave's static `_masterIsAvailable` flag flips immediately on push; slave responds with `503` and the extended response body signaling master-controlled unavailability; frontend on the slave redirects to the disable message.
|
||||
- **Cleanup**: Set status back to `Active` on the Master.
|
||||
|
||||
### Scenario 3: Fail-Open on Master Unreachable or Slave Restart (Unit 1 & Unit 2)
|
||||
- **Description**: The slave gate must never hard-fail when it cannot reach the Master.
|
||||
- **Setup A (push failure)**: Registered slave; stop the Slave instance, then call the status-update endpoint on the Master.
|
||||
- **Test Steps A**:
|
||||
1. Stop the Slave process.
|
||||
2. On the Master, call `PUT /api/v1/CmsInstances/{id}/status` with `Inactive`.
|
||||
3. Inspect the Master's response body and `CmsInstance.LastIntegrityCheckFailedAt`.
|
||||
- **Expected Results A**: The DB status change is NOT rolled back; response reports `SlaveContactSuccess = false`; `IntegrityCheckBackgroundService` will retry and update `LastIntegrityCheckFailedAt` on its next interval (`IntegrityCheckIntervalMinutes`, default 60).
|
||||
- **Setup B (slave restart)**: Restart the Slave process while the Master is unreachable.
|
||||
- **Test Steps B**:
|
||||
1. Stop both Master and Slave.
|
||||
2. Start only the Slave.
|
||||
3. Send a request to the slave's CMS route immediately after startup.
|
||||
- **Expected Results B**: `_masterIsAvailable` defaults to `true` on process start (fail-open), so the slave is reachable even before the Master pushes a fresh status.
|
||||
|
||||
### Scenario 4: Frontend CMS Page End-to-End (Unit 3 → Unit 1)
|
||||
- **Description**: Owner manages slave CMS instances through the `/cms` page.
|
||||
- **Setup**: Master API running; frontend dev server pointed at it (`npm run dev`); logged in as Administrator.
|
||||
- **Test Steps**:
|
||||
1. Navigate to `/cms`.
|
||||
2. Add a new CMS instance via `AddCmsInstanceDialog`.
|
||||
3. Confirm it appears in `CmsInstanceList`.
|
||||
4. Open `SetStatusDialog` and toggle its status.
|
||||
- **Expected Results**: List refreshes via TanStack Query invalidation after each mutation; API key is never shown in the list response (per NFR).
|
||||
|
||||
## Setup Integration Test Environment
|
||||
|
||||
### 1. Start Required Services
|
||||
```bash
|
||||
# Terminal 1 — Master instance
|
||||
dotnet run --project src/SlpModularCms.Api --urls http://localhost:5001
|
||||
|
||||
# Terminal 2 — Slave instance (separate DB, MasterUrl pointing at Terminal 1)
|
||||
dotnet run --project src/SlpModularCms.Api --urls http://localhost:5002
|
||||
```
|
||||
|
||||
### 2. Configure Frontend
|
||||
```bash
|
||||
cd frontend
|
||||
npm run dev # defaults to Master instance per vite proxy config
|
||||
```
|
||||
|
||||
## Run Integration Tests
|
||||
These scenarios are currently **manual** (no automated cross-process integration test harness exists in this codebase). Automated coverage for the underlying units (registration logic, middleware two-phase check, cache/fallback, frontend mutations) is provided by the unit test suites listed in `unit-test-instructions.md`.
|
||||
|
||||
### Verify Service Interactions
|
||||
- Check Master logs for registration and status-update requests
|
||||
- Check Slave logs for `MasterAvailabilityService` pull attempts and cache hits/misses
|
||||
- Check browser dev tools network tab for `/api/v1/CmsInstances` calls from the frontend
|
||||
|
||||
### Cleanup
|
||||
```bash
|
||||
# Stop both dotnet run processes (Ctrl+C)
|
||||
```
|
||||
+40
@@ -0,0 +1,40 @@
|
||||
# Performance Test Instructions
|
||||
|
||||
## Purpose
|
||||
Validate that the master-controlled availability gate does not introduce meaningful request latency on the slave, per NFR-PERF-01/PERF-02 (`aidlc-docs/features/master-cms-module/construction/slave-availability-extension/nfr-requirements/nfr-requirements.md`).
|
||||
|
||||
## Performance Requirements
|
||||
No explicit throughput/latency SLA was defined during NFR Requirements for this feature. The design goal instead is architectural:
|
||||
- **PERF-01**: The slave's master-gate check reads a `volatile` static in-memory field — zero async overhead, zero DB call per request.
|
||||
- **PERF-02**: Only the local availability gate touches the DB, unchanged from pre-existing behavior (1s cache per `AvailabilityOptions.StatusCacheSeconds`).
|
||||
|
||||
## Setup Performance Test Environment
|
||||
|
||||
### 1. Prepare Test Environment
|
||||
```bash
|
||||
dotnet run --project src/SlpModularCms.Api --urls http://localhost:5002 --environment Production
|
||||
```
|
||||
|
||||
### 2. Configure Test Parameters
|
||||
- **Test Duration**: 60 seconds
|
||||
- **Virtual Users**: 50 concurrent
|
||||
- **Target endpoint**: Any slave CMS route protected by `AvailabilityMiddleware`
|
||||
|
||||
## Run Performance Tests
|
||||
|
||||
### 1. Baseline (master-gate disabled / no `MasterRegistration` configured)
|
||||
```bash
|
||||
k6 run --vus 50 --duration 60s baseline-script.js
|
||||
```
|
||||
|
||||
### 2. With Master-Gate Enabled (registered slave, `_masterIsAvailable = true`)
|
||||
```bash
|
||||
k6 run --vus 50 --duration 60s gated-script.js
|
||||
```
|
||||
|
||||
### 3. Analyze Performance Results
|
||||
- **Expected**: p95 latency delta between baseline and gated runs should be negligible (sub-millisecond), since the gate check is a single `volatile` field read with no I/O.
|
||||
- **Bottlenecks**: If a measurable delta appears, verify no accidental DB or network call was introduced into `AvailabilityMiddleware`'s master-gate branch.
|
||||
|
||||
## Performance Optimization
|
||||
Not applicable at this time — no bottleneck identified in code review or NFR design. Revisit only if production monitoring shows gate-related latency.
|
||||
+33
@@ -0,0 +1,33 @@
|
||||
# Unit Test Execution
|
||||
|
||||
## Run Backend Unit Tests
|
||||
```bash
|
||||
dotnet test SlpModularCms.sln --no-build
|
||||
```
|
||||
|
||||
### Expected Results
|
||||
| Test Project | Tests | Result |
|
||||
|---|---|---|
|
||||
| SlpModularCms.Core.Tests | 45 | Pass |
|
||||
| SlpModularCms.Modules.Identity.Tests | 46 | Pass |
|
||||
| SlpModularCms.Modules.Availability.Tests | 60 | Pass |
|
||||
| SlpModularCms.Modules.Master.Tests | 42 | Pass |
|
||||
| **Total** | **193** | **All Pass** |
|
||||
|
||||
## Run Frontend Unit Tests
|
||||
```bash
|
||||
cd frontend
|
||||
npm run test -- --run
|
||||
```
|
||||
|
||||
### Expected Results
|
||||
- **Test Files**: 34 passed (34)
|
||||
- **Tests**: 209 passed (209)
|
||||
- `Not implemented: Window's scrollTo()` messages are jsdom environment noise, not failures
|
||||
|
||||
## Fix Failing Tests
|
||||
If tests fail:
|
||||
1. Review console output for the failing test name and assertion
|
||||
2. For backend: check the relevant module's test project under `src/`
|
||||
3. For frontend: check `frontend/src/**/*.test.ts(x)`
|
||||
4. Rerun the specific test project/file until green
|
||||
+41
@@ -0,0 +1,41 @@
|
||||
# Code Generation Plan — Unit 4: documentation
|
||||
|
||||
## Unit Context
|
||||
- **Scope**: Update `README.md` (root) with a Master CMS Module section covering the new module, migrations, and production env vars; replace the default Vite template `frontend/README.md` was never actually replaced by Unit 3 and still contains boilerplate — bring it in line with the rest of the documented feature set.
|
||||
- **Depends on**: Units 1-3 (master-backend, slave-availability-extension, frontend-cms-page) — documents their final, built-and-tested patterns.
|
||||
- **No new code**: Documentation only; no business logic, no NFRs, no tests. Functional Design / NFR Requirements / NFR Design were correctly skipped for this unit.
|
||||
|
||||
## Steps
|
||||
|
||||
- [x] **Step 1 — Root README: Add "Master CMS Module" section**
|
||||
Add a new `## Master CMS Module` section to `README.md` after the existing "Nieuwe Module Toevoegen" section, covering:
|
||||
- What the module does (Owner registers/manages slave CMS instances; slaves enforce master-controlled availability)
|
||||
- Architecture summary: `SlpModularCms.Modules.Master` (per-module `MasterDbContext`), extended `SlpModularCms.Modules.Availability` (slave-side `MasterRegistration` + two-phase `AvailabilityMiddleware`)
|
||||
- Registration flow: Owner adds a slave URL via `/cms` → Master generates an API key → Master pushes registration to the slave's `/api/v1/master/register` (`X-Master-Api-Key` header)
|
||||
- Status flow: Owner toggles status on Master → Master pushes to slave synchronously → fail-open on push failure (DB change not rolled back) → `IntegrityCheckBackgroundService` retries/reconciles on `IntegrityCheckIntervalMinutes` (default 60)
|
||||
- Fail-open behavior: slave defaults `_masterIsAvailable = true` at startup; no TTL on cached status
|
||||
|
||||
- [x] **Step 2 — Root README: Extend "Database Migraties" section**
|
||||
Add a subsection noting that `SlpModularCms.Modules.Master` and `SlpModularCms.Modules.Availability` are per-module `DbContext`s with their own migrations, applied automatically at startup via `Database.Migrate()`. Document the exact commands:
|
||||
```powershell
|
||||
dotnet ef migrations add <Naam> --project src\SlpModularCms.Modules.Master --startup-project src\SlpModularCms.Api
|
||||
dotnet ef migrations add <Naam> --project src\SlpModularCms.Modules.Availability --startup-project src\SlpModularCms.Api --context AvailabilityDbContext
|
||||
```
|
||||
Note the `--context` requirement for the Availability project (it now hosts two logical concerns sharing one `AvailabilityDbContext`, but `dotnet ef` needs disambiguation because the API composes multiple `DbContext` types across modules).
|
||||
|
||||
- [x] **Step 3 — Root README: Extend "Productie Setup" section**
|
||||
Add the new production-relevant configuration:
|
||||
- `MasterModule` options actually consumed by the code (bound from config section `MasterModule`): `IntegrityCheckIntervalMinutes` (default 60), `HttpTimeoutSeconds` (default 10), `MasterUrl`. **Revised during execution**: `CacheMinutes` and `ApiKey` are declared on `MasterModuleOptions` but never read anywhere in the codebase (verified via `dotnet-appsettings` skill pass) — they were superseded by Unit 2's actual design (per-instance encrypted keys, no-TTL cache). Left undocumented here per user decision; tracked as TD-001 in the new `tech-debt-backlog` feature instead of documenting dead config as if live.
|
||||
- **Data Protection key ring warning** (per NFR tech-stack-decisions.md): the API key encryption uses ASP.NET Core Data Protection with the default file-system key store. For containerized/multi-instance deployments, configure a persistent key ring (`PersistKeysToDbContext`, `PersistKeysToAzureBlobStorage`, etc.) — otherwise a container restart makes all stored `ApiKey` values undecryptable, breaking master↔slave communication until instances are re-added.
|
||||
- **Added during execution**: actual `MasterModule` config section added to `appsettings.json` and `appsettings.Development.json` (was completely missing before this unit, discovered via the `dotnet-appsettings` skill pass).
|
||||
|
||||
- [x] **Step 4 — Replace `frontend/README.md`**
|
||||
Replace the default Vite/React template content with a short pointer document: describe the frontend briefly and redirect to the root `README.md`'s "Frontend Development (CMS Admin UI)" section, which already documents setup, scripts, and configuration in full. Avoids duplicating content that already exists and stays in sync.
|
||||
|
||||
- [x] **Step 5 — Update feature state**
|
||||
Mark Unit 4 (documentation) Code Generation complete in `aidlc-docs/features/master-cms-module/aidlc-state.md`; update `aidlc-docs/active-features.md` status.
|
||||
|
||||
## Deviations From Plan (logged during execution)
|
||||
- **Missing EF migration found & fixed**: `SlpModularCms.Modules.Availability` had no migration for `MasterRegistration` (Unit 2 gap). Generated during Build & Test, before this unit started — see `aidlc-docs/features/master-cms-module/construction/build-and-test/build-and-test-summary.md`.
|
||||
- **Lint baseline correction**: the "all pre-existing" claim for frontend lint findings in the Build & Test summary was based on a contaminated comparison; corrected via a clean `git worktree` checkout. 2 of the 6 lint findings are new (Unit 3); all 6 moved to `tech-debt-backlog` (TD-002/TD-003) rather than fixed in-flight, per user decision.
|
||||
- **appsettings gap found & fixed**: `MasterModule` config section was entirely absent from `appsettings.json`/`appsettings.Development.json` despite `MasterModuleOptions.BindConfiguration("MasterModule")` in code. Added both files during this unit's execution (see Step 3).
|
||||
@@ -0,0 +1,34 @@
|
||||
# AI-DLC State Tracking
|
||||
|
||||
## Project Information
|
||||
- **Feature Name**: Tech Debt Backlog
|
||||
- **Feature Slug**: tech-debt-backlog
|
||||
- **Project Type**: Brownfield
|
||||
- **Start Date**: 2026-07-01T00:00:00Z
|
||||
- **Current Stage**: INCEPTION - Backlog captured, not yet triaged/prioritized
|
||||
- **Branch**: unknown
|
||||
|
||||
## Workspace State
|
||||
- **Existing Code**: Yes
|
||||
- **Reverse Engineering Needed**: No (artifacts exist in `aidlc-docs/_shared/reverse-engineering/`)
|
||||
- **Workspace Root**: K:\Development\Projects\SlpModularCms
|
||||
|
||||
## Code Location Rules
|
||||
- **Application Code**: Workspace root (NEVER in aidlc-docs/)
|
||||
- **Feature Documentation**: aidlc-docs/features/tech-debt-backlog/ only
|
||||
- **Shared Artifacts**: aidlc-docs/_shared/
|
||||
|
||||
## Language Configuration
|
||||
- **Documentation Language**: English
|
||||
- **Conversation Language**: Dutch (User Language)
|
||||
|
||||
## Purpose
|
||||
|
||||
A running backlog of small, non-blocking issues discovered incidentally while working on other features (dead config, pre-existing lint findings, etc.). Items are captured here instead of fixed in-flight so they don't block the feature where they were found. Pick up and triage when convenient.
|
||||
|
||||
## Stage Progress
|
||||
|
||||
### 🔵 INCEPTION PHASE
|
||||
- [x] Workspace Detection — Complete (feature created ad-hoc during master-cms-module Build & Test)
|
||||
- [ ] Requirements Analysis — Backlog list captured in `inception/requirements/backlog.md`; not yet prioritized or scoped into units
|
||||
- [ ] Everything else — Not started; pick up when the user chooses to work this feature
|
||||
@@ -0,0 +1,13 @@
|
||||
# Audit Log — Tech Debt Backlog
|
||||
|
||||
## Initial Request — Feature Created
|
||||
|
||||
**Timestamp**: 2026-07-01T00:00:00Z
|
||||
|
||||
**User Input**: "Laat ze staan en documenteer ze als unused. Maak ook een nieuwe feature aan waar je dit in verwerkt om te fixen dat ze niet worden gebruikt. Als je meer issues vindt gooi die dan ook in deze feature. Maak het dus eigenlijk een soort tech debt feature. Net als de gefaalde tests bij de Build & Test check die je zojuist gedaan hebt. Die tech debt feature kan ik dan later oppakken. Voor nu doorgaan met unit 4"
|
||||
|
||||
**AI Response**: "Nieuwe feature 'tech-debt-backlog' aangemaakt als lichtgewicht backlog (geen volledige inception-cyclus doorlopen, gezien het doel puur registratie is voor latere oppak). Backlog vastgelegd in inception/requirements/backlog.md met 3 items: TD-001 (dode MasterModuleOptions properties), TD-002 (4 pre-existing frontend lint findings, geverifieerd via git worktree checkout van commit c156107 met schone npm install), TD-003 (2 nieuwe lint findings geïntroduceerd door master-cms-module Unit 3, bewust hierheen verplaatst i.p.v. direct gefixt). Toegevoegd aan active-features.md."
|
||||
|
||||
**Context**: Feature aangemaakt tijdens master-cms-module sessie; geen actieve executie gestart, puur registratie voor later
|
||||
|
||||
---
|
||||
@@ -0,0 +1,49 @@
|
||||
# Tech Debt Backlog
|
||||
|
||||
Items discovered incidentally while working on other features. Not yet prioritized. Each item lists where it was found and what "done" looks like.
|
||||
|
||||
---
|
||||
|
||||
## TD-001: Dead config properties on `MasterModuleOptions`
|
||||
|
||||
**Found during**: `master-cms-module` — Build & Test / appsettings mapping (2026-07-01)
|
||||
|
||||
**Location**: `src/SlpModularCms.Modules.Master/Options/MasterModuleOptions.cs`
|
||||
|
||||
**Issue**: `CacheMinutes` and `ApiKey` are declared on the options POCO and were originally designed (per `aidlc-docs/features/master-cms-module/construction/master-backend/functional-design/domain-entities.md`) as slave-side settings for Unit 2 (slave-availability-extension) to consume. When Unit 2 was actually implemented, it used a different pattern instead — per-instance Data-Protection-encrypted API keys pushed from the Master, and a no-TTL in-memory cache (`REL-02` in the Availability NFR requirements) rather than a configurable `CacheMinutes`. As a result, neither property is read anywhere in the codebase.
|
||||
|
||||
**Done looks like**: Either remove both properties from `MasterModuleOptions` (and any corresponding appsettings documentation), or — if a future feature revives the pull/TTL model — wire them up for real. Confirm via `grep -rn "CacheMinutes\|Options.Value.ApiKey" src/` that nothing reads them before removing.
|
||||
|
||||
---
|
||||
|
||||
## TD-002: Pre-existing frontend lint errors (react-hooks plugin)
|
||||
|
||||
**Found during**: `master-cms-module` — Build & Test (2026-07-01), confirmed pre-existing via `git worktree` checkout of commit `c156107` (the commit immediately before this feature's frontend work) with a clean `npm install`
|
||||
|
||||
**Issues** (4 total — 4 errors, 0 warnings at that baseline):
|
||||
1. `frontend/src/components/ui/badge.tsx:32` — `react-refresh/only-export-components`: the file exports both a component and a non-component value (likely `badgeVariants`), breaking Fast Refresh. Fix: move the shared constant/function to a separate file.
|
||||
2. `frontend/src/components/users/InviteUserDialog.tsx` — two related findings in the same `useEffect`:
|
||||
- `react-hooks/set-state-in-effect`: `setStep(1)` (and sibling `setState` calls) run synchronously inside a `useEffect` that resets dialog state on close.
|
||||
- `react-hooks/immutability`: `reset()` (from `useForm`) is referenced in the effect body before its `const { reset } = useForm(...)` declaration further down the component — works today due to hoisting/closure timing but is flagged as fragile.
|
||||
3. `frontend/src/pages/SettingsPage.tsx:39` — `react-hooks/set-state-in-effect`: `setSelectedMode`/`setReason` run synchronously inside a `useEffect` that syncs local form state from a query result (`availability`).
|
||||
|
||||
**Done looks like**: Refactor each flagged effect per the React docs' "you might not need an effect" guidance (react.dev/learn/you-might-not-need-an-effect) — e.g. compute derived state during render, or move the reset logic into the `onOpenChange`/event handler instead of an effect. For `badge.tsx`, split the non-component export into its own module. Re-run `npm run lint` in `frontend/` until clean.
|
||||
|
||||
---
|
||||
|
||||
## TD-003: New lint findings introduced by `master-cms-module` Unit 3 (same pattern as TD-002)
|
||||
|
||||
**Found during**: `master-cms-module` — Build & Test (2026-07-01). These were introduced by this feature's own Unit 3 (frontend-cms-page) code, but deferred here per explicit user decision (2026-07-01: "Laat ze staan... gooi die dan ook in deze feature") rather than fixed in-flight, to avoid blocking Unit 4.
|
||||
|
||||
**Issues** (2 total — 1 error, 1 warning):
|
||||
1. `frontend/src/components/cms/AddCmsInstanceDialog.tsx:55` — `react-hooks/set-state-in-effect`: `setServerError(null)` (and sibling calls) run synchronously inside the dialog's close-reset `useEffect`. Same pattern as TD-002 item 2.
|
||||
2. `frontend/src/components/cms/SetStatusDialog.tsx:72` — `react-hooks/incompatible-library` (warning): `watch()` from `react-hook-form`'s `useForm()` is used directly; React Compiler can't safely memoize it, so compilation is skipped for this component/hook.
|
||||
|
||||
**Done looks like**: Same remediation approach as TD-002 item 2 for the `AddCmsInstanceDialog.tsx` finding. For `SetStatusDialog.tsx`, either accept the compiler skipping memoization for this component (likely fine, low-traffic dialog) or replace `watch('status')` with a subscription-based pattern (`useWatch`) if it becomes a proven perf issue.
|
||||
|
||||
---
|
||||
|
||||
## Notes
|
||||
|
||||
- None of these block functionality — `npm run build` and all test suites pass regardless.
|
||||
- TD-002 and TD-003 share the same underlying pattern (`setState` in a mount/close-reset effect) — worth fixing as one pass across all four files rather than one-by-one, once picked up.
|
||||
Reference in New Issue
Block a user