Adds SlpModularCms.Api.SlpSoftware and extracts shared CmsHost composition
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

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
This commit is contained in:
2026-08-02 01:28:39 +02:00
co-authored by Claude Sonnet 5
parent dcc82cdf62
commit fa389e42ee
51 changed files with 3119 additions and 127 deletions
@@ -0,0 +1,49 @@
# Unit of Work — SlpSoftware Production API
2 units (decision Q1 = A), named per Q2 = B.
---
## Unit 1: SlpSoftware Client Setup
**Scope**: FR-1, FR-2, FR-3. No user stories are directly attributed to this unit (decision Q3 = A) — it is a purely technical enabling unit with no persona-facing behavior of its own.
**Responsibilities**:
- Extract the composed hosting pipeline from `SlpModularCms.Api/Program.cs` into `SlpModularCms.Core.Hosting.CmsHost`, as two methods: `ConfigureServices(WebApplicationBuilder)` and `ConfigurePipeline(WebApplication, ModuleOrchestrator)` (AD-1).
- Repoint `SlpModularCms.Api/Program.cs` at the new shared methods, with **no behavior change** — its existing test suite must remain green.
- Create the new `SlpModularCms.Api.SlpSoftware` project under the `Clients` solution folder, referencing `SlpModularCms.Core`, `SlpModularCms.Modules.Identity`, `SlpModularCms.Modules.Availability`, and `SlpModularCms.Modules.Master` (per FR-2). **Does not yet reference `SlpModularCms.Modules.Offerings`** — that reference is added by Unit 2, since the Offerings project doesn't exist until Unit 2 creates it.
- Give `Api.SlpSoftware` its own `appsettings.json` / `appsettings.Development.json` / `appsettings.local.json` per the `dotnet-appsettings` skill's pattern (same as `Api`).
**Components owned** (from application-design/components.md): `CmsHost`, the `SlpModularCms.Api.SlpSoftware` project shell (its `Program.cs` and `.csproj`).
**Preliminary per-unit Construction assessment** (confirmed at each stage when reached, not decided here):
- Functional Design: likely **SKIP** — no new data model or business rule, purely a hosting-composition refactor.
- NFR Requirements / NFR Design: likely **EXECUTE** — the extraction must provably preserve `Api`'s existing security headers, rate limiting, Sentry, and Data Protection behavior (Security Baseline, D-11); this is exactly an NFR concern.
- Infrastructure Design: likely **EXECUTE**`Api.SlpSoftware` becoming a deployment target is new for this unit even though the underlying hosting infrastructure already exists (per the "when in doubt, execute" rule).
- Code Generation, Build and Test: **ALWAYS**.
---
## Unit 2: Offerings
**Scope**: FR-4, FR-5, FR-6, FR-7, FR-8. All 12 user stories (US-01 through US-12).
**Responsibilities**:
- Create `SlpModularCms.Modules.Offerings` (+ `SlpModularCms.Modules.Offerings.Tests`) following the existing module pattern: `Offering` entity, `OfferingsDbContext`, `IOfferingRepository`/`OfferingRepository`, `IOfferingsService`/`OfferingsService`, `OfferingsController`, `OfferingsModule` (per application-design/components.md and component-methods.md).
- Add the `<ProjectReference>` to `SlpModularCms.Modules.Offerings` in `SlpModularCms.Api.SlpSoftware.csproj` (this unit's responsibility, not Unit 1's — see plan rationale).
- Implement the public `GET /api/v1/offerings` and the admin CRUD + reorder actions, enforcing the featured-exclusivity rule (US-10) and soft-delete semantics (AD-5).
- No code changes for FR-8 (reference content) — the three current package values are already documented in requirements.md; the user enters them manually via the admin CRUD once built (decision D-5).
**Components owned**: `Offering`, `OfferingsDbContext`, `IOfferingRepository`/`OfferingRepository`, `IOfferingsService`/`OfferingsService`, `OfferingsController`, `OfferingsModule`.
**Preliminary per-unit Construction assessment**:
- Functional Design: likely **EXECUTE** — new data model (`Offering`) and non-trivial business rules (featured exclusivity, two reorder interactions, soft delete).
- NFR Requirements / NFR Design: likely **EXECUTE** — SECURITY-05 (input validation specifics) and the SECURITY-13 partial mitigation (soft delete) both need concrete design here.
- Infrastructure Design: likely **SKIP** — reuses the existing MariaDB / per-module-migration infrastructure with nothing new to map (per requirements.md's Security Compliance table, SECURITY-01 is "pre-existing, unchanged" for this module).
- Code Generation, Build and Test: **ALWAYS**.
---
## Dependency Summary
Unit 2 (Offerings) depends on Unit 1 (SlpSoftware Client Setup) — the `Api.SlpSoftware` project must exist before Unit 2 can add its project reference into it. Unit 1 must be built and verified (existing `Api` test suite green after the extraction) before Unit 2 starts, per the Module Update Strategy in `inception/plans/execution-plan.md`. See `unit-of-work-dependency.md` for the full matrix.