NFR Design for U3 and U4. Two decisions the earlier stages had deliberately left open, plus four risks the functional design did not name. OPEN-01 closed: the correlation ID is the W3C trace ID from the ambient Activity, with TraceIdentifier as the fallback. It propagates across the master/slave boundary via traceparent, which TraceIdentifier cannot do at all, and it is the same value ProblemDetails already returns to the client. REF-U3-01 raised: BR-U3-22's Umami-origin startup warning cannot work. The backend never sees VITE_UMAMI_WEBSITE_ID, so the check would either always warn or never warn. Withdrawn from U3 and replaced by a blocking U5 CI gate that compares the frontend build variable against that environment's CSP origins, where both values are visible. Four additions beyond the functional design: - Set-Cookie added to the scrub list; the login response issues the refreshToken there, so scrubbing only the request cookie protects nothing - SetBeforeSendTransaction alongside SetBeforeSend; transactions carry request data too - OnRejected on the rate limiter; today a 429 leaves no trace anywhere - FlushAsync before the migration-failure rethrow, or the one Critical event in the system dies with the process Two traps recorded with tests attached: Sentry groups log events by message template, so interpolated messages make FR-19's rate-based alert rules unimplementable while appearing to work; and DefaultHttpContext.Response .OnStarting is a no-op, so the obvious middleware test asserts nothing. Three values chosen rather than escalated, each one line to change and all three listed for review at the end of U4's pattern document: JSON console outside Development, TracesSampleRate 0.1, tunnel cap 200 KB. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01HHoJpxYXzHACSQguHrC5fw
108 lines
9.2 KiB
Markdown
108 lines
9.2 KiB
Markdown
# AI-DLC State Tracking
|
||
|
||
## Project Information
|
||
- **Feature Name**: Gitea Deployment Workflow
|
||
- **Feature Slug**: gitea-deployment-workflow
|
||
- **Project Type**: Brownfield
|
||
- **Start Date**: 2026-07-27T00:00:00Z
|
||
- **Current Stage**: CONSTRUCTION - Round 2, NFR Design complete for U3 + U4 (awaiting approval)
|
||
- **Branch**: feature/gitea-deployment-workflow
|
||
|
||
## Workspace State
|
||
- **Existing Code**: Yes
|
||
- **Reverse Engineering Needed**: Completed — full rerun on 2026-07-27 (user chose Q3 = B)
|
||
- **Workspace Root**: K:\Development\Projects\SlpModularCms
|
||
|
||
## Reverse Engineering Status
|
||
- [x] Reverse Engineering — Completed on 2026-07-27
|
||
- **Artifacts Location**: aidlc-docs/_shared/reverse-engineering/ (all 8 artifacts regenerated + timestamp)
|
||
- **Verified by execution**: Release build 0 errors / 50 warnings; 219 backend tests pass; 213 frontend tests pass; `pnpm run lint` **fails** (5 errors, 1 warning); 2 high-severity transitive package advisories
|
||
|
||
## Code Location Rules
|
||
- **Application Code**: Workspace root (NEVER in aidlc-docs/)
|
||
- **Feature Documentation**: aidlc-docs/features/gitea-deployment-workflow/ only
|
||
- **Shared Artifacts**: aidlc-docs/_shared/
|
||
- **Structure patterns**: See code-generation.md Critical Rules
|
||
|
||
## Language Configuration
|
||
- **Documentation Language**: English
|
||
- **Conversation Language**: User Language (Dutch)
|
||
|
||
## Extension Configuration
|
||
| Extension | Enabled | Decided At |
|
||
|---|---|---|
|
||
| Security Baseline | Yes (blocking) | Requirements Analysis |
|
||
| Property-Based Testing | No | Requirements Analysis |
|
||
|
||
## Operations Configuration
|
||
- **Include Operations Phase**: Yes
|
||
- **Decided At**: Requirements Analysis
|
||
|
||
## Scope Decisions (from feature-selection.md)
|
||
- **Public website**: documentation/instructions only — where the website build lands in `wwwroot/`, how it coexists with `wwwroot/admin/`, and what a per-website workspace must deliver. The website's own build/deploy workflow stays out of scope (Q4 = A).
|
||
- **Environments**: local, test, production only.
|
||
- **Observability stack**: UptimeRobot (uptime), Umami (analytics), console logging + Sentry (logging/errors).
|
||
- **Deployment constraint**: upload as a published .NET application; no server configuration may be required.
|
||
- **Reference**: existing working Gitea Actions setup at `K:\Development\SlpSoftware\Projects\SlpSoftware` (React/Vite) is the starting point.
|
||
- **Health check endpoint**: IN SCOPE (decided 2026-07-27). **Liveness only** — `AddHealthChecks()` + `MapHealthChecks("/health")`, no package needed and **no database check** (Q17 = A / D-21, superseding the earlier note that `AddDbContextCheck` might be included). `/health` must be added to `AvailabilityMiddleware._bypassPrefixes` so the availability gate cannot return 503 for it. Health = infrastructure liveness; Availability/capabilities = CMS domain state — these stay strictly separate.
|
||
|
||
> **Note**: this section records the earliest scope decisions. The authoritative and complete decision set is `inception/requirements/requirements.md` § 3 (D-01…D-32) — in particular, Q4 = C changed the public website from living directly in `wwwroot/` to `wwwroot/web/`.
|
||
|
||
## Stage Progress
|
||
|
||
### INCEPTION
|
||
- [x] Workspace Detection — Complete
|
||
- [x] Reverse Engineering — Complete, approved 2026-07-27 (full rerun of all 8 `_shared/` artifacts)
|
||
- [x] Requirements Analysis — Complete, approved 2026-07-27. 24 FRs (FR-24 added at Application Design), 10 NFRs, 32 decisions, 7 assumptions, 4 open items, 4 documented security deviations. Two question rounds: `requirement-verification-questions.md` (25 Q) and `requirement-clarification-questions.md` (5 Q).
|
||
- [x] User Stories — **SKIP** (infrastructure/operations work; no new end-user functionality or persona. Offered at Requirements Analysis approval, not requested.)
|
||
- [x] Workflow Planning — Complete, approved 2026-07-27. Artifact: `inception/plans/execution-plan.md`
|
||
- [x] Application Design — Complete, approved 2026-07-27. 14 code components (9 new, 5 modified) + 2 workflow components. Artifacts in `inception/application-design/`. Two composition conflicts found and carried to Unit 2. Added FR-24, closed OPEN-02.
|
||
- [x] Units Generation — Complete (awaiting approval). 7 units in 4 execution rounds. Artifacts: `unit-of-work.md`, `unit-of-work-dependency.md`, `unit-of-work-story-map.md`
|
||
|
||
### CONSTRUCTION
|
||
Units finalised at Units Generation (see `inception/application-design/unit-of-work.md`):
|
||
U1 Hosting & Serving · U2 Data Durability · U3 Security Headers & CSP · U4 Observability · U5 CI Workflow & Gates · U6 Deploy Workflow · U7 Documentation
|
||
|
||
Execution rounds (Q4 = B): **R1** = U1 + U2 · **R2** = U3 + U4 · **R3** = U5 + U6 · **R4** = U7. One commit per unit; single PR at the end (Q6 = A).
|
||
|
||
- [x] Functional Design — **EXECUTE for U1, U2, U3, U4**; SKIP for U5, U6, U7. **U1 ✅ U2 ✅** approved 2026-07-27 · **U3 ✅ U4 ✅** 2026-07-28
|
||
- [ ] NFR Requirements — **SKIP (all units)** — already comprehensively captured in `requirements.md` § 5 and § 6
|
||
- [x] NFR Design — **EXECUTE for U3, U4**; SKIP for the rest. *Deliberate deviation from the default NFR-Requirements/NFR-Design coupling — rationale in the execution plan.* **U3 ✅ U4 ✅** 2026-07-28 — 11 patterns for U3, 10 for U4. Closed OPEN-01; raised REF-U3-01
|
||
- [ ] Infrastructure Design — **EXECUTE for U6, U7**; SKIP for the rest
|
||
- [~] Code Generation — **EXECUTE** (all 7 units, each built and tested before its completion message). **U1 ✅ U2 ✅** generated and verified 2026-07-27 — build 0 errors, 253 backend tests pass (was 219)
|
||
- [ ] Build and Test — **EXECUTE**
|
||
|
||
### OPERATIONS
|
||
- [ ] Deployment Setup — **EXECUTE**
|
||
- [ ] Monitoring Setup — **EXECUTE**
|
||
- [ ] Production Readiness Validation — **EXECUTE** (includes the `dotnet-appsettings` compliance gate)
|
||
|
||
## Execution Plan Summary
|
||
- **Risk Level**: High — three destructive-and-silent failure modes (customer website loss, Data Protection key-ring loss, automatic migration against production)
|
||
- **Stages to Execute**: Functional Design (×4: U1–U4), NFR Design (×2: U3, U4), Infrastructure Design (×2: U6, U7), Code Generation (×7), Build and Test, Deployment Setup, Monitoring Setup, Production Readiness Validation
|
||
- **Stages to Skip**: User Stories (no end-user functionality), NFR Requirements (already captured), plus per-unit skips as listed above
|
||
|
||
## Current Status
|
||
- **Lifecycle Phase**: CONSTRUCTION
|
||
- **Current Stage**: Round 2 — NFR Design complete for U3 Security Headers & CSP and U4 Observability
|
||
- **Next Stage**: Code Generation for U3 + U4
|
||
- **Status**: Awaiting NFR Design approval. Round 1 (U1 + U2) code approved and committed 2026-07-28
|
||
|
||
## Round 2 Design Record (2026-07-28)
|
||
- Functional Design U3 + U4 complete and committed (`357d395`)
|
||
- NFR Design U3 — `construction/u3-security-headers/nfr-design/` — 11 patterns. All new types in `Core/Hosting/Security/`, so `Core.Tests` can reach them (avoids repeating U1's Step 11 deviation)
|
||
- NFR Design U4 — `construction/u4-observability/nfr-design/` — 10 patterns. `Sentry.AspNetCore` 6.8.0 into `Core`; `@sentry/react` ^10.68.0 into `frontend`
|
||
- **OPEN-01 CLOSED**: correlation ID = W3C trace ID from the ambient `Activity`, `TraceIdentifier` as fallback. Rationale: propagates master→slave via `traceparent`, and equals the `traceId` ASP.NET Core's `ProblemDetails` already returns
|
||
- **REF-U3-01 raised**: BR-U3-22's Umami-origin startup warning is **not implementable** — the backend cannot read `VITE_UMAMI_WEBSITE_ID`. Withdrawn from U3 and replaced by a **blocking U5 CI gate** comparing the frontend build variable against that environment's `SecurityHeaders:AllowedScriptOrigins`
|
||
- **Additions beyond the functional design**, each with rationale in the pattern docs: `Set-Cookie` added to the scrub list; a `sentry-tunnel` rate limiter; `OnRejected` on the existing rate limiter (today a `429` leaves no trace anywhere); `SentrySdk.FlushAsync` before the migration-failure rethrow (otherwise the one `Critical` event dies with the process)
|
||
- **Three defaults chosen rather than escalated** (each one line to change, listed at the end of U4's pattern doc): JSON console outside Development, `TracesSampleRate` 0.1, tunnel cap 200 KB
|
||
- U4 modifies two files from already-committed units — `DatabaseMigrationExtensions` (U2) and `AdminTokenValidator` (U1). Both additive; to be named in the U4 commit message
|
||
|
||
## Round 1 Verification Record (2026-07-27)
|
||
- `dotnet build SlpModularCms.sln -c Release` — 0 errors
|
||
- Backend tests — **253 passed, 0 failed** (Core 83, Availability 82, Identity 37, Master 51); baseline was 219
|
||
- New EF migration `20260727203036_AddDataProtectionKeys` — verified purely additive
|
||
- Embedded placeholder resource name verified against the compiled assembly manifest
|
||
- **Carried to phase-level Build and Test**: composed-startup behaviour that needs a running host and a real database — `/admin` trailing-slash redirect, 404-vs-HTML for missing assets, SPA fallback and placeholder resolution, `/health` while availability-disabled, `MigrateCoreDatabase` against SQL Server, and both hosts starting
|
||
- **Deviation**: U1 plan Step 11 (`StaticContentTests`) not implemented — the code lives in `SlpModularCms.Api`, which has no test project by convention; behaviour carried to Build and Test instead. Recorded in the unit's `generation-summary.md`
|