Introduces the SDD root: a v1.0.0 constitution and machine-readable AGENTS.md grounded in the project's real conventions; six EARS-aware persona spec-review checklists that cross-reference .claude/personas/; feature-spec/ADR/threat-model/ api-contract templates; a fully worked _example feature; a living RTM; and an adrs/ pointer that reuses the existing docs/adr/ archive. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
3.2 KiB
3.2 KiB
Requirements Traceability Matrix (RTM)
Living document. One row per
REQ-NNNacross all in-flight and shipped features. It links a requirement to the design that realises it, the code that implements it, and the test(s) that prove it — so any requirement can be traced end to end, and any orphan (a requirement with no test, or a test with no requirement) is visible.
How to update
- When a
spec.mdis approved, copy its## Traceabilityrows here withStatus: Planned. - As tasks land, fill
Implementation File(s)and flipStatus→In progress→Done. REQ-IDs are scoped per feature, so always qualify with the Feature column —REQ-001in avatar is notREQ-001in another feature.- The
sdd-gate.ymlCI job (traceability-check) warns (non-blocking, for now) when aspec.mdcontains aREQ-NNNthat does not appear in this file. Keep it in sync to keep the warning quiet; it flips to blocking once adoption settles (see the workflow's TODO).
Status legend
Planned · In progress · Done · Deferred
Matrix
| REQ-ID | Requirement Summary | Feature | Design Artifact | Implementation File(s) | Test(s) | Status |
|---|---|---|---|---|---|---|
| REQ-001 | Store avatar at avatars/{userId}, overwrite |
profile-picture-upload (_example) | features/_example/design.md; adr-001 | UserService (planned) |
UserServiceAvatarTest#storesUnderUserKey, #replaceLeavesNoOrphan |
Planned |
| REQ-002 | Upload self avatar → 200 + avatarUrl | profile-picture-upload (_example) | features/_example/design.md; api-contract.yaml | UserAvatarController, UserService (planned) |
UserAvatarControllerTest#uploadReturnsAvatarUrl |
Planned |
| REQ-003 | Delete self avatar → avatarUrl null | profile-picture-upload (_example) | features/_example/api-contract.yaml | UserAvatarController (planned) |
UserAvatarControllerTest#deleteClearsAvatar |
Planned |
| REQ-004 | No avatar → null + initials placeholder | profile-picture-upload (_example) | features/_example/design.md | UserProfileView, avatar component (planned) |
avatar-placeholder.svelte.spec.ts |
Planned |
| REQ-005 | ADMIN_USER may delete others' avatar | profile-picture-upload (_example) | features/_example/api-contract.yaml | UserAvatarController (planned) |
UserAvatarControllerTest#adminDeletesOthersAvatar |
Planned |
| REQ-006 | Unauthenticated → 401, store nothing | profile-picture-upload (_example) | features/_example/threat-model.md | SecurityConfig, controller (planned) |
UserAvatarControllerTest#unauthenticatedReturns401 |
Planned |
| REQ-007 | Non-image → 400 UNSUPPORTED_FILE_TYPE | profile-picture-upload (_example) | features/_example/design.md | UserService (planned) |
UserAvatarControllerTest#rejectsNonImage |
Planned |
| REQ-008 | Over 2 MB → 400 AVATAR_TOO_LARGE | profile-picture-upload (_example) | features/_example/design.md | UserService, ErrorCode (planned) |
UserAvatarControllerTest#rejectsOversize |
Planned |
| REQ-009 | Non-admin on others → 403 FORBIDDEN | profile-picture-upload (_example) | features/_example/threat-model.md | UserAvatarController (planned) |
UserAvatarControllerTest#nonAdminForbiddenOnOthers |
Planned |