Files
slp-modular-cms/aidlc-docs/features/slpsoftware-api/construction/slpsoftware-client-setup/nfr-requirements/nfr-requirements.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

4.1 KiB

NFR Requirements — Unit: SlpSoftware Client Setup

NFR-CS-01 — Pipeline-Level Regression Test Coverage (Reliability / Testability)

Requirement: The CmsHost extraction MUST be verified by new automated integration tests that exercise the actual HTTP pipeline, not unit tests of individual option classes.

Rationale: Investigated the existing test suite before deciding (per the user's conditional answer to Q1 — "A if sufficient coverage exists, otherwise B"). Found:

  • Zero usages of WebApplicationFactory anywhere in the solution.
  • SlpModularCms.Core.Tests/Hosting/* tests (SecurityHeadersOptionsValidationTests, PathPolicyResolverTests, DeployedConfigurationTests, SecurityEventsTests) are unit-level — they test option/handler classes in isolation, not the composed pipeline.
  • No dedicated Api.Tests project exists.

Existing coverage does not verify that security headers are actually present on a real response, that /health is reachable, that the SPA fallback resolves /admin/* routes, or that the rate limiter engages — all pipeline-composition behavior that CmsHost must reproduce exactly from today's Api/Program.cs. Per the decision rule in the user's own answer, this resolves to Option B.

Scope for Code Generation: New WebApplicationFactory-based integration tests asserting, at minimum:

  • Required security headers (CSP, HSTS, X-Content-Type-Options, X-Frame-Options, Referrer-Policy) are present on a representative response.
  • /health returns a successful liveness response.
  • A non-file /admin/* route resolves to the admin SPA's index.html (SPA fallback).
  • The rate limiter is active (a burst of requests eventually receives a rate-limited response).

These tests become a permanent regression guard for both Api and Api.SlpSoftware, not a one-time check discarded after this feature.

NFR-CS-02 — CmsHost Extensibility (Maintainability)

Requirement: CmsHost.ConfigureServices/ConfigurePipeline accept a CmsHostOptions parameter, even though both current call sites (Api, Api.SlpSoftware) will pass equivalent values today.

Rationale: Decision Q2 = B — proactive extensibility preferred over strict YAGNI for this specific extraction point, since it's the one place both current and future Client projects funnel through.

Constraint found during investigation: SlpModularCms.Core.Hosting.DataProtectionExtensions.ApplicationDiscriminator is a deliberate hardcoded constant ("SlpModularCms"), with an explicit existing code comment stating it must never become configurable — a mismatched discriminator between instances silently breaks stored Data Protection values (see NFR-CS-02 note in tech-stack-decisions.md). CmsHostOptions MUST NOT expose anything that changes the Data Protection application name. This constraint carries forward into Code Generation Planning for this unit.

NFR-CS-03 — No New Security Surface (Security Baseline continuity)

Requirement: This unit introduces no new attack surface — no new module, no new business logic, no new endpoints. Its only Security Baseline obligation is that NFR-CS-01's regression tests actually prove the existing security posture (headers, rate limiting, Data Protection, Sentry-based logging) is unchanged after the extraction.

Rationale: Confirmed against requirements.md's Security Compliance table, where every rule applicable to the hosting/pipeline layer (SECURITY-01, 03, 04, 09, 10, 14, 15) is marked "Pre-existing, unchanged" — this unit's job is to keep that true, not to add anything new.

Out of Scope for This Unit

  • Database technology/connection changes — none; Api.SlpSoftware uses its own environment-specific connection string via the existing dotnet-appsettings pattern, same as Api/Api.Slave today. No new decision needed.
  • Scalability/performance targets — unchanged from today's Api; this unit doesn't add load, it re-composes existing middleware.
  • Availability/disaster-recovery — unchanged; no new infrastructure introduced by this unit (Infrastructure Design for this unit, next stage, covers whether Api.SlpSoftware as a deployment target needs anything new).