Prepares the single-host layout for deployment. The customer's public website moves from wwwroot/ to wwwroot/web/, so a CMS deploy can no longer overwrite content it does not own: with the website in its own directory, the release directory can be swapped without touching it. Each front-end gets its own file provider, and both tolerate a missing directory at startup — a fresh deployment has no website until a separate workspace deploys one, and the CMS must still serve /admin and the API. When the website's index.html is absent, an embedded placeholder is served instead of a 404, which also doubles as proof the CMS itself is running. The placeholder is embedded in the assembly rather than shipped into wwwroot/web/, because that directory is owned and overwritten by the website workspace. Adds GET /health for uptime monitoring. It reports infrastructure liveness only and is deliberately NOT the same thing as /api/v1/Availability/status or /api/v1/System/capabilities: those are CMS domain state that also serve the master/slave protocol. A healthy instance can be switched off by design, and a switched-on instance can be unhealthy, so conflating them would alert on business state and stay silent on real outages. /health is on the availability gate's bypass list for the same reason. Fixes a real defect in the gate's admin bypass. It parsed the bearer token with ReadJwtToken, which reads claims without verifying the signature, so an unauthenticated caller could forge an unsigned token carrying an Owner role claim and bypass the gate that suspends a customer's site. Protected endpoints still rejected them, so nothing leaked — but the gate itself was bypassable. The token is now fully validated against the same parameters as the bearer scheme, resolved from one shared source so the two cannot drift apart. Host wiring for these changes lands with the data-durability commit, since both units touch the same lines of Program.cs. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01HHoJpxYXzHACSQguHrC5fw
2.1 KiB
2.1 KiB
Functional Design Plan — U1 Hosting & Serving
Unit: U1 Hosting & Serving Round: R1 (with U2 Data Durability) Requirements: FR-07, FR-10, FR-24 Components: C-04, C-10, C-13, U1 portion of C-16
Step 1: Analyze unit context
- Read the U1 definition from
unit-of-work.md - Read the requirement assignment from
unit-of-work-story-map.md - Read the carried-in design items — § 5.2 pipeline ordering, missing-directory startup behaviour
Step 2: Design static-file serving behaviour
- Define mount registration order and request-path resolution for the two mounts
- Define default-file handling per mount
- Define SPA fallback precedence between
/admin/{*path:nonfile}and{*path:nonfile} - Define behaviour when
wwwroot/web/is absent at startup - Define behaviour when
wwwroot/web/exists but has noindex.html - Define trailing-slash handling for
/admin - Confirm directory browsing stays disabled
Step 3: Design the health endpoint
- Define the response contract for healthy and unhealthy states
- Confirm no dependency probing is performed
- Define behaviour while the instance is availability-disabled
- Define what the endpoint must never expose
Step 4: Design the availability-gate changes
- Define the
/healthbypass placement within the existing prefix list - Resolve the FR-24 implementation approach — pipeline ordering versus in-middleware validation
- Define admin-bypass behaviour for valid, forged, expired and absent tokens
- Confirm the preserved behaviour: a valid Owner or Administrator token still bypasses the gate
Step 5: Define business rules
- Enumerate path-resolution rules with precedence
- Enumerate health-reporting rules
- Enumerate admin-bypass rules
- Identify error and edge-case scenarios
Step 6: Generate artifacts
- Generate
business-logic-model.md - Generate
business-rules.md - Generate
domain-entities.md - Validate all diagrams against the Mermaid standards
- Verify Security Baseline compliance for this unit's design