Files
SluijsensandClaude Sonnet 5 0447993181 Completes local-dev-master-slave-setup: dual-instance frontend tooling, module-capability gating, and master/slave protocol self-healing fixes
Frontend (Unit 2 completion): dual dev-server tooling (pnpm dev:slave,
pnpm dev:all), per-instance browser tab titles, and a backend
capability check (SystemController + useSystemCapabilities +
ModuleGuard) so a Master-only page is hidden on a slave instance
instead of assuming every backend has every module.

Master/slave protocol fixes surfaced by actually running master and
slave side by side locally:
- Deactivating a CMS instance (Inactive) now releases the slave's
  master gate instead of leaving it stuck on its last pushed status.
- The periodic integrity check now also re-pushes status to every
  reachable slave (previously URL-verification only) and runs once
  immediately on startup.
- Added the originally-specified (but never implemented) slave-pull
  path: a slave now periodically polls its own status from the master
  (GET /api/v1/SlaveStatus) and fails open to Available if the master
  is unreachable for too long, complementing the existing push.
- The slave's own Settings page can no longer "successfully" change
  local availability while the master controls it; it's now locked
  with an explanatory banner and the backend rejects the write with
  409 instead of silently no-op'ing it.
- CMS instance status badges now match the dashboard's color/icon
  styling instead of a plain grey badge.

Also corrected the master-cms-module design docs to match this
as-built behavior, and flagged (without a full rewrite) a larger,
pre-existing divergence between its inception-stage application
design and what construction actually built.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-04 19:53:52 +02:00

7.3 KiB

Code Generation Summary — Unit 1: Backend Dual-Instance Hosting

Created

  • src/SlpModularCms.Core/Hosting/ModuleOrchestrator.cs
  • src/SlpModularCms.Core/Hosting/ServiceCollectionExtensions.cs
  • src/SlpModularCms.Core/Hosting/ApiPrefixConvention.cs
  • src/SlpModularCms.Api.Slave/SlpModularCms.Api.Slave.csproj
  • src/SlpModularCms.Api.Slave/Program.cs
  • src/SlpModularCms.Api.Slave/appsettings.json
  • src/SlpModularCms.Api.Slave/appsettings.Development.json
  • src/SlpModularCms.Api.Slave/appsettings.local.json.example
  • src/SlpModularCms.Api.Slave/Properties/launchSettings.json
  • src/SlpModularCms.Core.Tests/Hosting/ApiPrefixConventionTests.cs (relocated from Modules.Identity.Tests)
  • src/SlpModularCms.Core.Tests/Hosting/ModuleOrchestratorTests.cs (relocated from Modules.Identity.Tests)

Modified

  • src/SlpModularCms.Core/SlpModularCms.Core.csproj — added Asp.Versioning.Mvc and Microsoft.AspNetCore.OpenApi package references
  • src/SlpModularCms.Api/Program.csusing statements updated to SlpModularCms.Core.Hosting (no logic change)
  • src/SlpModularCms.Modules.Identity.Tests/SlpModularCms.Modules.Identity.Tests.csproj — removed ProjectReference to SlpModularCms.Api (no longer needed; the only tests using it were relocated to Core.Tests)
  • SlpModularCms.sln — added SlpModularCms.Api.Slave project entry, build configurations, and solution-folder nesting under src

Deleted

  • src/SlpModularCms.Api/Infrastructure/ModuleOrchestrator.cs (moved to Core)
  • src/SlpModularCms.Api/Extensions/ServiceCollectionExtensions.cs (moved to Core)
  • src/SlpModularCms.Api/Infrastructure/ApiPrefixConvention.cs (moved to Core)
  • src/SlpModularCms.Modules.Identity.Tests/Infrastructure/ModuleOrchestratorTests.cs (relocated to Core.Tests/Hosting/)
  • src/SlpModularCms.Modules.Identity.Tests/Infrastructure/ApiPrefixConventionTests.cs (relocated to Core.Tests/Hosting/)

Notes / Deviations from Plan

  • Discovered during generation that SlpModularCms.Modules.Identity.Tests referenced SlpModularCms.Api solely to test ModuleOrchestrator/ApiPrefixConvention — an existing layering quirk, not something this feature introduced. Since those classes now live in Core, their tests were relocated to Core.Tests/Hosting/ (which already references Core and already has all needed test packages: FluentAssertions, NSubstitute, xunit). This removed the odd cross-project test dependency as a side effect.
  • ServiceCollectionExtensions.cs needed explicit using Microsoft.Extensions.Configuration;, using Microsoft.Extensions.DependencyInjection;, using Microsoft.AspNetCore.Builder;, and using Microsoft.AspNetCore.Http; after the move — SlpModularCms.Api is a Microsoft.NET.Sdk.Web project (implicit ASP.NET Core usings), while SlpModularCms.Core is a plain Microsoft.NET.Sdk project, so these weren't implicitly available.
  • Left Asp.Versioning.Mvc and Microsoft.AspNetCore.OpenApi package references in place on SlpModularCms.Api.csproj even though they're now also referenced transitively via Core — removing them was optional per the plan and the build succeeds either way; left as-is to minimize unrelated diff.

Verification Performed

  • dotnet build SlpModularCms.sln — succeeds, no errors.
  • dotnet test SlpModularCms.sln — all 4 existing test projects pass unchanged: Core.Tests (54), Modules.Availability.Tests (60), Modules.Identity.Tests (37), Modules.Master.Tests (42).
  • Manually ran dotnet run --launch-profile https in both SlpModularCms.Api and SlpModularCms.Api.Slave:
    • Master (SlpModularCms.Api): discovers and loads all 3 modules — Availability, Identity, Master.
    • Slave (SlpModularCms.Api.Slave): discovers and loads exactly 2 modules — Availability, Identity. Master is correctly excluded.
  • Full end-to-end run (requiring a real local SQL Server/localdb instance and manual "Add CMS Instance" registration) is deferred to Build and Test / Unit 2, per the plan.

Follow-up: Real appsettings.local.json for the Slave (user request)

The user reported the slave's connection string looked wrong and asked for a real src/SlpModularCms.Api.Slave/appsettings.local.json (gitignored, mirroring src/SlpModularCms.Api/appsettings.local.json's credentials but with its own database). Created with Database=SlpModularCmsSlave (vs. master's SlpModularCms), same Server=127.0.0.1,1433;User ID=sa;Password=... credentials and same JwtSettings.Secret. Verified via git check-ignore that it's not tracked.

Verified working: running dotnet run --launch-profile https --no-build in SlpModularCms.Api.Slave with this file present successfully connected to the local SQL Server, created the SlpModularCmsSlave database, and applied EF Core migrations (CREATE DATABASE, __EFMigrationsHistory setup, migration application) — confirming the connection string is correct. This environment does have a reachable SQL Server at 127.0.0.1:1433, unlike assumed earlier in Build and Test.

Known issue hit during this verification, not related to the fix: a subsequent attempt to run both master and slave simultaneously hit Failed to bind to address ... address already in use on both :7221 and :7222 — leftover dotnet run child processes from earlier manual verification steps in this session likely survived their parent timeout calls and are still holding those ports. This is a session/environment artifact, not a defect in the generated code. Resolved: user closed their own processes and confirmed via Get-CimInstance/Get-NetTCPConnection that no SlpModularCms processes or listeners remained on ports 7221/7222/5284/5285.

Follow-up: Slave Database Migration Gap (discovered while checking migration status)

User asked whether the necessary migrations exist and both databases are up to date. Checked via dotnet ef migrations list for every DbContext/startup-project combination:

Database Context Status before fix
SlpModularCms (master) ApplicationDbContext (Core/Identity) Applied (2/2)
SlpModularCms (master) AvailabilityDbContext Applied (1/1)
SlpModularCms (master) MasterDbContext Applied (1/1)
SlpModularCmsSlave (slave) AvailabilityDbContext Applied (1/1) — auto-migrated via Database.Migrate() in AvailabilityModule.UseModule
SlpModularCmsSlave (slave) ApplicationDbContext (Core/Identity) 2 migrations pendingSlpModularCms.Core's ApplicationDbContext is never auto-migrated (only Modules.Availability and Modules.Master call Database.Migrate() in their UseModule); it always requires the manual dotnet ef database update step documented in root README.md, and nobody had run it yet for the new slave database.

Fixed: ran dotnet ef database update --project src/SlpModularCms.Core --startup-project src/SlpModularCms.Api.Slave --context ApplicationDbContext. Re-checked with migrations list — both 20260612191736_InitialCreate and 20260619130625_AddsDisplayName now show as applied (no (Pending) marker). Slave database is now fully up to date.

Documentation fix: added a note + the exact command to the "Lokaal Master + Slave Draaien (Dev)" runbook in root README.md, right after the slave-startup instructions, so this doesn't get missed again by whoever (re)creates the slave database.