6.1 KiB
6.1 KiB
Code Generation Plan — Unit 0: Backend Prerequisites
This plan defines all concrete steps to implement Unit 0 (backend prerequisites) safely in the brownfield .NET solution. Follow the numbered steps in order and check them off during execution.
Unit Context
- Unit: Unit 0 — Backend Prerequisites
- Type: .NET backend changes (API + Core + Module Identity)
- Stories (traceability):
- US-02 (partial) — Auth: secure refresh-token via httpOnly cookie
- US-06 (partial) — Session lifecycle: refresh & revoke
- US-07 (partial) — Error handling & API consistency
- Dependencies: None (prerequisite unit for all frontend integration)
- Related NFRs: NFR-U0-01..07 (security cookie, CORS, rate limiting, reliability, ProblemDetails, maintainability, tests)
Code Locations (brownfield)
- Application Code:
- src/SlpModularCms.Api/Program.cs
- src/SlpModularCms.Api/Extensions/ServiceCollectionExtensions.cs
- src/SlpModularCms.Modules.Identity/Controllers/AuthController.cs
- src/SlpModularCms.Core/Exceptions/GlobalExceptionHandler.cs
- src/SlpModularCms.Core/Exceptions/ApiErrorResponse.cs (to be removed/replaced)
- src/SlpModularCms.Core/Identity/Models/TokenResponse.cs
- src/SlpModularCms.Core/Identity/Models/IdentityRequests.cs (contains RefreshTokenRequest)
- src/SlpModularCms.Core/Identity/Services/IAuthService.cs
- src/SlpModularCms.Core/Identity/Services/AuthService.cs
- Configuration:
- src/SlpModularCms.Api/appsettings.json
- src/SlpModularCms.Api/appsettings.Development.json
- Tests:
- src/SlpModularCms.Core.Tests/Identity/* (extend where feasible)
- NEW: src/SlpModularCms.Modules.Identity.Tests/ (controller tests) [optional, recommended]
PART 1 — Planning Checklist
- Read all Unit 0 design artifacts (business-rules.md, nfr-requirements.md, nfr-design/*)
- Validate repository state and file presence against paths above
- Confirm appsettings three-file pattern (dotnet-appsettings skill) and add missing sections
PART 2 — Generation Steps (execute in order)
Step 1 — API Routing & CORS
- Update route on AuthController to
[Route("api/v1/auth")](currently[Route("[controller]")]) - Add
AddCmsCors()in ServiceCollectionExtensions to readCors:AllowedOriginsand configure explicit allowlist +AllowCredentials() - Register CORS BEFORE
UseAuthentication/UseAuthorizationin Program.cs pipeline - Add
Corssection to appsettings.json and appsettings.Development.json per logical-components.md
Step 2 — Rate Limiting (Global Middleware)
- Add
AddCmsRateLimiting()to register Fixed window (login: 5/min) and Sliding window (refresh: 20/min) - Register
UseRateLimiter()in Program.cs before CORS (per design ordering) - Ensure 429 responses include standard headers (Retry-After) where applicable
Step 3 — Refresh Token in httpOnly Cookie
- Modify
AuthController.Loginto setrefreshTokencookie (HttpOnly,Secure=request.IsHttpsin prod,SameSite=Strict, Path=/api/v1/auth) - Modify
AuthController.Refreshto read refresh token fromRequest.Cookies["refreshToken"](remove body model) - Modify
AuthController.Revoketo clear the cookie using same Path and expire to Epoch
Step 4 — Remove Request Body Model for Refresh
- Delete
RefreshTokenRequestfromIdentityRequests.cs - Update method signatures & usages accordingly
Step 5 — Service Contract Adjustments (AuthService/IAuthService)
- Change refresh flow contract to accept ONLY the refresh token (no access token in body)
- Implement repository lookup by refresh token and user, with rotation semantics intact
- Ensure reuse-detection logic (mark used, revoke all on reuse) remains functional
Step 6 — Response Model & Payload Alignment
- Update
TokenResponseto removeRefreshTokenfrom the response body - Extend response body to include:
accessToken,expiresAt, anduserobject:{ id, email, name, role, isActive } - Compute
nameasDisplayName ?? Email(see BR-U0-07) - Ensure controllers only return allowed fields; NEVER return the refresh token
Step 7 — Revoke Endpoint Authorization Policy
- Implement per BR-U0-05: remove
[Authorize]fromPOST /api/v1/auth/revoketo allow idempotent logout even if access token expired
Step 8 — ProblemDetails Migration (RFC 9457)
- Replace custom
ApiErrorResponsewith standardizedProblemDetailsinGlobalExceptionHandler - Map known exceptions to appropriate status codes (Unauthorized, 429, etc.)
- Remove/retire
ApiErrorResponseusages
Step 9 — Configuration (dotnet-appsettings)
- Add/verify
CorsandRateLimitingsections inappsettings.jsonandappsettings.Development.json - Do NOT store secrets; follow three-file pattern; add README notes for
appsettings.local.jsonoverrides
Step 10 — Tests
- Update/extend unit tests to cover:
- Cookie set on successful login/refresh
- Cookie cleared on revoke
- 401 when cookie missing on refresh
- Rate limit behavior (mock/stub)
- Optionally add
SlpModularCms.Modules.Identity.Testsfor controller-level tests; otherwise, add minimal WebApplicationFactory-based tests in an existing test project
Step 11 — Documentation & README
- Update backend README with local dev instructions (CORS origin, HTTPS dev certs, cookie behavior)
- Update cross-feature docs if affected (e.g., slp-modular-cms-api endpoints, auth flow)
Step 12 — Build & Smoke Verification
- Build solution
- Manual smoke test of auth endpoints: login → cookie present; refresh → cookie rotates; revoke → cookie cleared; CORS preflight succeeds
Story Traceability Matrix
- US-02 (partial): Steps 3–6
- US-06 (partial): Steps 3–7, 12
- US-07 (partial): Steps 8–12
Definition of Done (Unit 0)
- No refresh token in any response body
- Refresh token exclusively in httpOnly cookie
- CORS allowlist enforced and credentials enabled
- Global rate limiting active with configured windows
- ProblemDetails standardized for all auth-related errors
- Tests updated/added per NFR-U0-07
- README updated with local dev guidance