U7 — tells a website builder what they need to know

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).
This commit is contained in:
2026-07-28 16:30:19 +02:00
parent 9f4ae475e7
commit 88770c5bd0
6 changed files with 258 additions and 6 deletions
@@ -1148,3 +1148,36 @@ by Infrastructure Design. U5 carries REF-U3-01's Umami origin gate plus FR-21 an
**Context**: CONSTRUCTION — Round 3 — U5 Code Generation complete, presenting completion message
---
## Code Generation — U5 (Approved) / Round 3 Closed
**Timestamp**: 2026-07-28T01:45:00Z
**User Input**: "Continue to Next Stage"
**AI Response**: "U5 approved and committed (9f4ae47). Round 3 (U5 + U6) is now closed. Correcting the completion message's stated next step: Build and Test runs after ALL 7 units per the workflow's own rule, and U7 (Repository Documentation, Round 4) has not been generated yet — proceeding to Round 4 instead of Build and Test."
**Context**: CONSTRUCTION — Round 3 closed; entering Round 4 (U7)
---
## Code Generation Plan — U7 Repository Documentation (Planning)
**Timestamp**: 2026-07-28T01:50:00Z
**User Input**: "(implicit — continuing after Round 3 closed)"
**AI Response**: "Created code generation plan for U7 (4 steps: WEBSITE_WORKSPACE.md contract, README.md updates, frontend/.env.example updates, accuracy verification against actual U1-U6 code). Presenting for approval before generation."
**Context**: CONSTRUCTION — Round 4 — U7 Code Generation Part 1, awaiting plan approval
---
## Code Generation — U7 Repository Documentation (Complete)
**Timestamp**: 2026-07-28T02:00:00Z
**User Input**: "(implicit — plan approved, generation executed)"
**AI Response**: "Created WEBSITE_WORKSPACE.md (the FR-09 contract). Updated README.md's Production Setup section: new wwwroot/web/ layout with placeholder-on-missing behaviour, /health documented and distinguished from Availability/status, Build & Publish rewritten around the actual CI/CD pipeline, and — most notably — removed the now-outdated manual key-ring-configuration instruction since U2 already made it automatic. Updated frontend/.env.example with the same-origin default explanation and new observability variables. Verified every claim against actual U1-U6 source rather than the design record. No C# test project applies (documentation-only unit)."
**Context**: CONSTRUCTION — Round 4 — U7 Code Generation complete, presenting completion message
---
@@ -0,0 +1,63 @@
# 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
- [x] Step 1: Create `WEBSITE_WORKSPACE.md` at the repository root — the website workspace contract
(FR-09): target path `wwwroot/web/` and required structure (must include `index.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 own `index.html`; paths with a
file extension 404 if missing), calling `/api/v1` same-origin with relative URLs (no CORS needed),
which CSP policy applies to the public website (`Relaxed`, the default policy — `/admin`,
`/api/v1` and `/health` get `Strict`) and what that permits, and how to include the Umami
tracking script
- [x] Step 2: Update `README.md`
- New `wwwroot` layout: `/``wwwroot/web/` (customer website, deployed separately, persists
across releases), `/admin``wwwroot/admin/` (this repo's admin SPA), link to
`WEBSITE_WORKSPACE.md` for the full contract
- `/health` endpoint: what it proves (process liveness only) and what it explicitly does not mean
(not the same as `Availability/status` or `System/capabilities`)
- Production setup section rewritten for what U1U6 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 wires `PersistKeysToDbContext` by default)
- New runtime configuration environment variables introduced by U3/U4: `SecurityHeaders__*`,
`Observability__SentryDsn`, plus the frontend's `VITE_SENTRY_DSN` / `VITE_UMAMI_SCRIPT_URL` /
`VITE_UMAMI_WEBSITE_ID`
- [x] Step 3: Update `frontend/.env.example`
- Document the same-origin default: an absent or empty `VITE_API_BASE_URL` now 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
- [x] 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 U1U6 source:
`Program.cs` fallback/placeholder wiring, `SlpModularCms.Api.csproj`'s `BuildAndCopyAdminFrontend`
and embedded `WebsitePlaceholder.html`, `AvailabilityMiddleware._bypassPrefixes`, U2's
`MigrateCoreDatabase()` fail-fast and `PersistKeysToDbContext` discriminator, U3's
`PathPolicies` fail-at-startup and `Relaxed`/`Strict` split in `appsettings.json`, U4's
Sentry/Umami absent-is-supported behaviour, U6's `linux-arm64` framework-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
## 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 U1U6" |
@@ -0,0 +1,45 @@
# Code Generation Summary — U7 Repository Documentation
**Date**: 2026-07-28
## Files Created
- `WEBSITE_WORKSPACE.md` — the website workspace contract (FR-09): target path, required structure,
forbidden/reserved paths, SPA-fallback behaviour, same-origin `/api/v1` calls, applicable CSP
policy, Umami inclusion, and why the atomic release switch can't touch it
## Files Modified
- `README.md` — "Productie Setup" section rewritten:
- `/` now documented as `wwwroot/web/`, linking to `WEBSITE_WORKSPACE.md`; noted that a missing
`wwwroot/web/` at startup serves a built-in placeholder rather than failing
- New `/health` row and a dedicated "Health-check endpoint" subsection distinguishing liveness
from `Availability/status` / `System/capabilities`
- "Build & Publish" rewritten around the actual Gitea Actions pipeline (push → automatic test
deploy, `workflow_dispatch` + flag → production) instead of a bare manual `dotnet publish`
- New runtime configuration entries: `Observability__SentryDsn`,
`SecurityHeaders__AllowedScriptOrigins__0` / `AllowedConnectOrigins__0`
- **§2a rewritten**: removed the outdated instruction to manually configure a persistent Data
Protection key ring — U2 already made this automatic (`PersistKeysToDbContext` with an explicit
discriminator), so the README no longer tells the reader to do work that's already done
- **§3 rewritten**: documented the automatic, fail-fast `ApplicationDbContext` migration at
startup and the pre-production backup, replacing the old "can be handled via a CI/CD pipeline"
hand-wave with what's actually built
- `frontend/.env.example` — documented the same-origin default for `VITE_API_BASE_URL`; added
`VITE_SENTRY_DSN`, `VITE_APP_ENV`, `VITE_UMAMI_SCRIPT_URL`, `VITE_UMAMI_WEBSITE_ID`, each noted as
optional
## Verification (Step 13.5 — this unit's own check)
No code, no test project — this is a documentation-only unit (same as its "no components" listing
in `unit-of-work.md`). Every factual claim was checked directly against source rather than against
the design record (see Step 4 in the code generation plan for the full checklist): `Program.cs`,
`SlpModularCms.Api.csproj`, `AvailabilityMiddleware`, U2's Data Protection extensions, U3's
`SecurityHeadersOptions` validation, U4's Sentry/Umami configuration, and U6's infrastructure design
for the publish/deploy specifics. No discrepancies found.
## Deferred to Operations (not built here, by design — Q8 of Requirements = A)
- Host setup instructions, the rollback procedure, and the FTPS switch path (FR-23)
- Actual Gitea variable/secret values
- UptimeRobot, Sentry alert rules, and the `dotnet-appsettings` compliance gate