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
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:
+21
@@ -0,0 +1,21 @@
|
||||
# Logical Components — Unit: SlpSoftware Client Setup
|
||||
|
||||
## Component: Pipeline Regression Test Suite
|
||||
|
||||
**Type**: Test project / test fixture (new logical component, no runtime footprint in production).
|
||||
|
||||
**Scope**: Targets `SlpModularCms.Api` only (Q1 = C). Exact host project (new `SlpModularCms.Api.Tests` vs. extending `SlpModularCms.Core.Tests`) is a Code Generation Planning decision — this stage fixes *what* it tests and *against which project*, not its exact file location.
|
||||
|
||||
**Integration pattern**: `Microsoft.AspNetCore.Mvc.Testing`'s `WebApplicationFactory<TEntryPoint>`, using `Api`'s own `Program.cs` as the entry point (requires `Api`'s `Program.cs` to be accessible to the test project via the standard `InternalsVisibleTo`/top-level-statement partial-class pattern, if not already the case for other reasons).
|
||||
|
||||
## Component: `CmsHostOptions`
|
||||
|
||||
**Type**: Plain options object (new), living in `SlpModularCms.Core.Hosting` alongside `CmsHost`.
|
||||
|
||||
**Shape at this stage**: empty (Q2 = B) — see nfr-design-patterns.md Pattern 2.
|
||||
|
||||
**Consumers**: `SlpModularCms.Api/Program.cs` and `SlpModularCms.Api.SlpSoftware/Program.cs`, both constructing a default instance.
|
||||
|
||||
## No Other New Logical Components
|
||||
|
||||
This unit does not introduce queues, caches, circuit breakers, or any other infrastructure component — it is a composition/extraction of existing pieces plus the one new options object above.
|
||||
+25
@@ -0,0 +1,25 @@
|
||||
# NFR Design Patterns — Unit: SlpSoftware Client Setup
|
||||
|
||||
## Pattern 1: Pipeline Regression Test, Scoped to `Api` (NFR-CS-01)
|
||||
|
||||
**Decision** (Q1 = C): the new `WebApplicationFactory`-based integration tests target **`SlpModularCms.Api` only**. `SlpModularCms.Api.SlpSoftware` is not separately pipeline-tested in this unit — it inherits confidence transitively through the shared `CmsHost.ConfigureServices`/`ConfigurePipeline` code path that both projects call identically.
|
||||
|
||||
**Pattern**: a single `WebApplicationFactory<TEntryPoint>`-based test fixture, pointed at `Api`, asserting on real HTTP responses:
|
||||
- Security headers present (CSP, HSTS, X-Content-Type-Options, X-Frame-Options, Referrer-Policy) — CSP presence and required directives only, not the exact Umami/Sentry exceptions (those are `Api`-specific configuration, unrelated to `CmsHost` correctness).
|
||||
- `/health` returns success.
|
||||
- A non-file `/admin/*` route resolves to the admin SPA's `index.html`.
|
||||
- A burst of requests against a rate-limited route eventually receives a `429`.
|
||||
|
||||
**Accepted trade-off**: if a future change to `CmsHost` behaves differently under `Api.SlpSoftware`'s specific module composition (Offerings module present) than under `Api`'s, this test suite alone would not catch it. This is an accepted gap per the user's decision, not an oversight — full end-to-end coverage of `Api.SlpSoftware` itself is covered later by the feature-wide Build and Test phase once Unit 2 exists.
|
||||
|
||||
## Pattern 2: `CmsHostOptions` as an Empty Extension Point (NFR-CS-02)
|
||||
|
||||
**Decision** (Q2 = B): `CmsHostOptions` is introduced as a genuinely empty class (or, in C# terms, a class with zero properties, or `internal sealed record CmsHostOptions;` — exact syntax decided at Code Generation) — a placeholder in the method signature, not a placeholder-with-a-guess-field.
|
||||
|
||||
**Pattern**: standard **Options Object** pattern, sized for its current job (nothing) rather than a speculative future job. Both `Api` and `Api.SlpSoftware` construct `new CmsHostOptions()` and pass it to `CmsHost.ConfigureServices(builder, options)` / `ConfigurePipeline(app, orchestrator, options)`. When a real per-project difference appears later, a property is added to this one class rather than changing either method's signature again.
|
||||
|
||||
**Constraint carried forward** (from NFR-CS-02 / tech-stack-decisions.md): whatever is eventually added to `CmsHostOptions`, it must never affect `DataProtectionExtensions.ApplicationDiscriminator` — that stays the hardcoded `"SlpModularCms"` constant regardless.
|
||||
|
||||
## Pattern 3: Security — Verification, Not New Design (NFR-CS-03)
|
||||
|
||||
No new security pattern is introduced by this unit. The applicable pattern is "prove equivalence," fully covered by Pattern 1's regression tests. No additional logical components (WAF, extra middleware, etc.) are needed.
|
||||
Reference in New Issue
Block a user