WEBSITE_WORKSPACE.md, plus the parts of the README that were still describing the old layout or a manual step the code doesn't need anymore (the key-ring paragraph, mainly - that one was actively wrong now, not just stale).
3.9 KiB
Code Generation Plan — U7 Repository Documentation
Unit Context
- Unit: U7 Repository Documentation (Documentation-only — no components, no code)
- Requirements: FR-09
- Depends on: U6 (settled host layout —
unit-of-work-dependency.md: "U6 before U7 — documentation cannot precede the layout it documents") - No Functional/NFR/Infrastructure Design, no test project: per the execution plan, this unit goes straight to Code Generation
- Scope split (Q8 of Requirements = A): repository documentation here; operational documents (host setup, rollback, FTPS switch) belong to the Operations phase, not this unit
Steps
-
Step 1: Create
WEBSITE_WORKSPACE.mdat the repository root — the website workspace contract (FR-09): target pathwwwroot/web/and required structure (must includeindex.html), forbidden paths (wwwroot/admin/, the application root), reserved paths (/admin,/api/v1,/health), SPA-fallback behaviour (non-file paths fall back to the website's ownindex.html; paths with a file extension 404 if missing), calling/api/v1same-origin with relative URLs (no CORS needed), which CSP policy applies to the public website (Relaxed, the default policy —/admin,/api/v1and/healthgetStrict) and what that permits, and how to include the Umami tracking script -
Step 2: Update
README.md- New
wwwrootlayout:/→wwwroot/web/(customer website, deployed separately, persists across releases),/admin→wwwroot/admin/(this repo's admin SPA), link toWEBSITE_WORKSPACE.mdfor the full contract /healthendpoint: what it proves (process liveness only) and what it explicitly does not mean (not the same asAvailability/statusorSystem/capabilities)- Production setup section rewritten for what U1–U6 actually built: CI/CD via Gitea Actions
(
continuous_integration.yaml→deploy-scp.yaml), atomic release switching, and the Data Protection key ring being automatic now (removing the old manual "you must configure a persistent key ring" instruction, since U2 already wiresPersistKeysToDbContextby default) - New runtime configuration environment variables introduced by U3/U4:
SecurityHeaders__*,Observability__SentryDsn, plus the frontend'sVITE_SENTRY_DSN/VITE_UMAMI_SCRIPT_URL/VITE_UMAMI_WEBSITE_ID
- New
-
Step 3: Update
frontend/.env.example- Document the same-origin default: an absent or empty
VITE_API_BASE_URLnow means same-origin (the production default, since the SPA and API are served by one process); explicit absolute URLs still work unchanged for local development - Add the new observability variables:
VITE_SENTRY_DSN,VITE_APP_ENV,VITE_UMAMI_SCRIPT_URL,VITE_UMAMI_WEBSITE_ID, each documented as optional/absent-is-supported
- Document the same-origin default: an absent or empty
-
Step 4: Verify documentation accuracy against the code as built (Definition of Done)
- Cross-checked every path, config key and behaviour claim against the actual U1–U6 source:
Program.csfallback/placeholder wiring,SlpModularCms.Api.csproj'sBuildAndCopyAdminFrontendand embeddedWebsitePlaceholder.html,AvailabilityMiddleware._bypassPrefixes, U2'sMigrateCoreDatabase()fail-fast andPersistKeysToDbContextdiscriminator, U3'sPathPoliciesfail-at-startup andRelaxed/Strictsplit inappsettings.json, U4's Sentry/Umami absent-is-supported behaviour, U6'slinux-arm64framework-dependent publish and atomic release switch. No discrepancies found between the design record and what was actually built — all documentation claims verified directly against source
- Cross-checked every path, config key and behaviour claim against the actual U1–U6 source:
Story / Requirement Traceability
| Step | Covers |
|---|---|
| 1 | FR-09 |
| 2 | FR-07, FR-08, FR-10 (documented, not re-implemented), FR-12 (key ring note) |
| 3 | FR-13, FR-14, FR-15, FR-16 (documented, not re-implemented) |
| 4 | Definition of Done: "documentation is accurate against the code as built in U1–U6" |