Files
slp-modular-cms/aidlc-docs/features/slpsoftware-api/construction/slpsoftware-client-setup/code/summary.md
T
SluijsensandClaude Sonnet 5 fa389e42ee
Continuous Integration / config (pull_request) Successful in 11s
Continuous Integration / changes (pull_request) Successful in 21s
Continuous Integration / backend-build (pull_request) Successful in 6m10s
Continuous Integration / vulnerability-scan (pull_request) Successful in 4m59s
Continuous Integration / frontend-prepare (pull_request) Successful in 1m27s
Continuous Integration / backend-test (pull_request) Failing after 7m48s
Continuous Integration / frontend-build (pull_request) Successful in 2m5s
Continuous Integration / frontend-test (pull_request) Successful in 4m24s
Continuous Integration / frontend-lint (pull_request) Successful in 2m0s
Continuous Integration / publish-test (pull_request) Skipped
Continuous Integration / publish-production (pull_request) Skipped
Continuous Integration / deploy-test (pull_request) Skipped
Continuous Integration / deploy-production (pull_request) Skipped
Adds SlpModularCms.Api.SlpSoftware and extracts shared CmsHost composition
Unit 1 of the slpsoftware-api feature (FR-1/FR-2/FR-3): a new Client project
in the Clients solution folder, intended to eventually become the deployed
API for test.slpsoftware.nl/slpsoftware.nl, hosting the same four modules as
SlpModularCms.Api plus a future Offerings module.

- Extracts SlpModularCms.Api/Program.cs's hosting-pipeline composition into
  SlpModularCms.Core.Hosting.CmsHost (ConfigureServices/ConfigurePipeline),
  shared by both Client projects so they cannot drift apart
- Moves StaticContentExtensions.cs + WebsitePlaceholder.html from Api into
  Core, since CmsHost cannot live in Api but Core cannot depend on Api
- Adds SlpModularCms.Api.SlpSoftware with its own isolated local dev database
  and dev ports (5286/7223, distinct from Api's and Api.Slave's)
- Adds SlpModularCms.Api.Tests with WebApplicationFactory-based pipeline
  regression tests (security headers, health check, SPA fallback, rate
  limiting), scoped to Api per NFR Design
- Adds a frontend dev:slpsoftware pnpm script mirroring dev:slave
- Fixes GlobalExceptionHandler logging routine 401s (e.g. an expired/missing
  refresh token) as unhandled errors -- pre-existing, unrelated to this
  feature's own scope, found while testing the new instance

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FWyStNL2ZsjrS7FLd7xvvN
2026-08-02 01:28:39 +02:00

6.9 KiB

Code Generation Summary — Unit: SlpSoftware Client Setup

Moved (brownfield relocation, Step 1)

  • src/SlpModularCms.Api/Extensions/StaticContentExtensions.cssrc/SlpModularCms.Core/Hosting/StaticContentExtensions.cs (namespace SlpModularCms.Api.ExtensionsSlpModularCms.Core.Hosting; embedded-resource name updated to match)
  • src/SlpModularCms.Api/Extensions/WebsitePlaceholder.htmlsrc/SlpModularCms.Core/Hosting/WebsitePlaceholder.html
  • Deleted the now-empty src/SlpModularCms.Api/Extensions/ directory

Created

  • src/SlpModularCms.Core/Hosting/CmsHostOptions.cs — empty extension-point class (NFR Design Pattern 2)
  • src/SlpModularCms.Core/Hosting/CmsHost.csConfigureServices/ConfigurePipeline, the shared composition both Client projects call
  • src/SlpModularCms.Api.SlpSoftware/ — new Client project: .csproj, Program.cs, appsettings.json, appsettings.Development.json (own isolated local dev database, Infrastructure Design Q1 = B), Properties/launchSettings.json (ports 5286/7222, distinct from Api's 5284/7221 so both can run simultaneously)
  • src/SlpModularCms.Api.Tests/ — new test project: .csproj, PipelineTests.cs (4 tests: /health reachable, required security headers present on an HTML response with HSTS's Development-only absence explicitly asserted, /admin fallback 404s correctly with no build present, the sentry-tunnel rate limiter engages past its configured permit limit)

Modified

  • src/SlpModularCms.Api/Program.cs — rewritten to the thin form calling CmsHost.ConfigureServices/ConfigurePipeline; no behavior change
  • src/SlpModularCms.Api/SlpModularCms.Api.csproj — removed the WebsitePlaceholder.html embedded-resource item (moved to Core)
  • src/SlpModularCms.Core/SlpModularCms.Core.csproj — added the WebsitePlaceholder.html embedded-resource item
  • SlpModularCms.sln — added SlpModularCms.Api.SlpSoftware (nested under Clients) and SlpModularCms.Api.Tests (nested directly under Tests, mirroring Core.Tests's placement)
  • README.md — documented the new project, CmsHost, and the local dev database isolation

Not Created (explicit N/A, per the plan)

  • No Program.Coverage.cs for Api.SlpSoftware — no pipeline tests target it in this unit (Q1 = C)
  • No appsettings.local.json for Api.SlpSoftware — git-ignored, personal-per-developer, created locally when needed
  • No API/Repository layer code, no database migrations — this unit has neither (Unit 2 "Offerings" does)
  • No .gitea/workflows/*.yaml or Gitea Actions variable changes — Operations-phase scope (D-7/D-15)

Post-Completion Fix: Dev Port Collision + Frontend Dev Script

Prompted by a user question about a frontend pnpm dev:slpsoftware script, investigation surfaced a real bug: Api.SlpSoftware's launchSettings.json had been assigned HTTPS port 7222, which is already SlpModularCms.Api.Slave's port (confirmed via frontend/.env.example and Api.Slave/Properties/launchSettings.json). Fixed:

  • src/SlpModularCms.Api.SlpSoftware/Properties/launchSettings.json — HTTPS port 7222 → 7223 (HTTP 5286 unchanged, already free)
  • src/SlpModularCms.Api.SlpSoftware/appsettings.Development.jsonMasterModule:MasterUrl updated to match (https://localhost:7223)
  • README.md — corrected port note, with an explicit call-out of the 7222 collision reason

Added (frontend, not part of the original per-unit plan, but a direct, symmetrical follow-up to the port fix):

  • frontend/package.jsondev:slpsoftware script (vite --mode slpsoftware --port 5175), mirroring dev:slave
  • frontend/.env.example — documented the .env.slpsoftware.local pattern (VITE_API_BASE_URL=https://localhost:7223, VITE_APP_TITLE=SlpModularCms (SlpSoftware))

Post-Completion Fix: CORS Origin Mismatch Blocked the Setup Page

Api.SlpSoftware/appsettings.Development.json's Cors:AllowedOrigins had been copied from Api's own file verbatim, listing localhost:5173 — but pnpm dev:slpsoftware serves the frontend on port 5175. The mismatch caused the frontend's /api/v1/Setup/status check to fail on CORS, and router.tsx's InitGuard fails open toward the login page (not setup) on any fetch error — so the setup page never appeared, even against a genuinely empty database (verified directly via the local MariaDB, not assumed). Fixed: Cors:AllowedOrigins now lists localhost:5175.

Post-Completion Fix: GlobalExceptionHandler Logged Expected 401s as Errors

Pre-existing bug, unrelated to this feature's own scope (not introduced by the CmsHost extraction) but surfaced by testing the new instance: src/SlpModularCms.Core/Exceptions/GlobalExceptionHandler.cs logged every exception at LogError before mapping it to a status code, so a routine UnauthorizedException (e.g. an invalid/missing refresh token — the normal state for a fresh, never-logged-in session) was indistinguishable from a genuine unhandled 500 in the console and in Sentry. Fixed: exceptions that map to a status below 500 now log at LogWarning; only genuinely unmapped exceptions (500) log at LogError. Affects every Client project equally (Api, Api.Slave, Api.SlpSoftware), not just this feature. No existing test asserted log level; full suite reran green (196 + 4).

Build and Test Verification (Step 13.5)

Two real build fixes were needed and applied during this step (not deviations from the plan — the plan didn't anticipate these, since they only surface once the code actually compiles):

  1. SlpModularCms.Core.csproj was missing a Scalar.AspNetCore package reference — CmsHost.ConfigurePipeline calls MapScalarApiReference(), which moved into Core along with the rest of the pipeline composition but the package reference hadn't followed it. Added.
  2. CmsHost.cs and the moved StaticContentExtensions.cs were missing explicit using Microsoft.Extensions.Hosting; / using Microsoft.Extensions.DependencyInjection;Core is an Microsoft.NET.Sdk project (not Sdk.Web), so it does not get ASP.NET Core's implicit usings the way Api (Sdk.Web) did. Added both.

After both fixes:

  • Build: Success (full solution, all 13 projects)
  • SlpModularCms.Core.Tests: 196 passed, 0 failed — no regression from the Step 1 file move
  • SlpModularCms.Api.Tests (new): 4 passed, 0 failed — /health reachable, required security headers present on an HTML response (with HSTS's Development-only absence correctly asserted, not overlooked), /admin fallback 404s correctly with no build present, the sentry-tunnel rate limiter engages past its configured permit limit

Local environment note: running the new tests required a local MariaDB (the same one Api itself needs to run, per the README). It was stopped; started it via podman machine start + podman start mariadb for this verification, and left both running afterward for continued local development (including Unit 2 "Offerings").