Files
familienarchiv/.specify/rtm.md
Marcel fa8a734f96
All checks were successful
CI / Unit & Component Tests (pull_request) Successful in 3m33s
CI / OCR Service Tests (pull_request) Successful in 24s
CI / Backend Unit Tests (pull_request) Successful in 4m37s
CI / fail2ban Regex (pull_request) Successful in 43s
CI / Semgrep Security Scan (pull_request) Successful in 21s
CI / Compose Bucket Idempotency (pull_request) Successful in 1m7s
SDD Gate / RTM Check (pull_request) Successful in 15s
SDD Gate / Contract Validate (pull_request) Successful in 24s
SDD Gate / Constitution Impact (pull_request) Successful in 17s
docs(sdd): mark #778 RTM rows Done with real test names
Flip REQ-001..006 for the timeline date-label feature from Planned to Done and
fill the implementing files plus the concrete dateLabel.spec.ts test names that
prove each requirement.

Closes #778
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-13 13:18:19 +02:00

4.9 KiB
Raw Blame History

Requirements Traceability Matrix (RTM)

Living document. One row per REQ-NNN across all in-flight and shipped features. The spec itself lives in the Gitea issue (issue-only — there is no committed spec.md); this matrix is the part of the spec that is committed: it links each requirement to its issue, the code that implements it, and the test(s) that prove it — so any requirement traces end to end, and any orphan (a requirement with no test) is visible on main.

How to update

  1. When a feature's issue is approved (via /review-issue), add one row per REQ-NNN with the Issue set to the Gitea issue number and Status: Planned. Commit these rows on the feature branch (they merge with the feature's PR).
  2. As tasks land, fill Implementation File(s) + Test(s) and flip StatusIn progressDone.
  3. REQ-IDs are scoped per feature, so always read them together with the Issue column — REQ-001 for issue #142 is not REQ-001 for issue #150.
  4. The sdd-gate.yml CI job (rtm-check) warns (non-blocking, for now) when a row is missing its Issue or Test(s). It flips to blocking once adoption settles (see the workflow's TODO).

Status legend

Planned · In progress · Done · Deferred

Matrix

REQ-ID Requirement Summary Issue Feature Implementation File(s) Test(s) Status
REQ-001 Store avatar at avatars/{userId}, overwrite #example profile-picture-upload (_example) UserService (planned) UserServiceAvatarTest#storesUnderUserKey, #replaceLeavesNoOrphan Planned
REQ-002 Upload self avatar → 200 + avatarUrl #example profile-picture-upload (_example) UserAvatarController, UserService (planned) UserAvatarControllerTest#uploadReturnsAvatarUrl Planned
REQ-003 Delete self avatar → avatarUrl null #example profile-picture-upload (_example) UserAvatarController (planned) UserAvatarControllerTest#deleteClearsAvatar Planned
REQ-004 No avatar → null + initials placeholder #example profile-picture-upload (_example) UserProfileView, avatar component (planned) avatar-placeholder.svelte.spec.ts Planned
REQ-005 ADMIN_USER may delete others' avatar #example profile-picture-upload (_example) UserAvatarController (planned) UserAvatarControllerTest#adminDeletesOthersAvatar Planned
REQ-006 Unauthenticated → 401, store nothing #example profile-picture-upload (_example) SecurityConfig, controller (planned) UserAvatarControllerTest#unauthenticatedReturns401 Planned
REQ-007 Non-image → 400 UNSUPPORTED_FILE_TYPE #example profile-picture-upload (_example) UserService (planned) UserAvatarControllerTest#rejectsNonImage Planned
REQ-008 Over 2 MB → 400 AVATAR_TOO_LARGE #example profile-picture-upload (_example) UserService, ErrorCode (planned) UserAvatarControllerTest#rejectsOversize Planned
REQ-009 Non-admin on others → 403 FORBIDDEN #example profile-picture-upload (_example) UserAvatarController (planned) UserAvatarControllerTest#nonAdminForbiddenOnOthers Planned
REQ-001 Render dated entry via shared formatDocumentDate (de/en/es) #778 timeline-date-label frontend/src/lib/timeline/dateLabel.ts dateLabel.spec.ts renders a DAY date localized in German, renders a SEASON date with the German season word, delegates a same-year RANGE to formatDocumentDate Done
REQ-002 Non-UNKNOWN + non-empty date → shared label, raw=null, getLocale() #778 timeline-date-label frontend/src/lib/timeline/dateLabel.ts dateLabel.spec.ts renders a DAY date localized in German, renders a DAY date localized in English Done
REQ-003 UNKNOWNnull (no chip) #778 timeline-date-label frontend/src/lib/timeline/dateLabel.ts dateLabel.spec.ts returns null for UNKNOWN precision even with a date, returns null for UNKNOWN precision without a date Done
REQ-004 null/undefined/'' eventDate → null, no formatter call #778 timeline-date-label frontend/src/lib/timeline/dateLabel.ts dateLabel.spec.ts returns null for APPROX with a null eventDate, without calling the formatter, returns null for DAY with an empty-string eventDate, treats undefined eventDateEnd identically to null for RANGE Done
REQ-005 No rendering logic outside documentDate.ts #778 timeline-date-label frontend/src/lib/timeline/dateLabel.ts (façade) dateLabel.spec.ts delegates a same-year RANGE to formatDocumentDate (asserts byte-identical delegation) Done
REQ-006 timeline in coverage include (80% branch gate) #778 timeline-date-label frontend/vite.config.ts coverage include now lists src/lib/timeline/**; covered by all dateLabel.spec.ts cases Done