docs(rtm): trace #780 timeline-layer-filter requirements
Add the ten REQ-001…REQ-010 rows for the /zeitstrahl layer filter, each linked to its implementation file(s) and test(s), all Done. Refs #780 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -173,3 +173,13 @@
|
|||||||
| REQ-012 | chip renders wherever a LetterCard renders (global timeline + expanded YearLetterStrip) | #835 | zeitstrahl-tag-chips | `frontend/src/lib/timeline/LetterCard.svelte` | `LetterCard.svelte.spec.ts#renders the chip inside an expanded YearLetterStrip too` | Done |
|
| REQ-012 | chip renders wherever a LetterCard renders (global timeline + expanded YearLetterStrip) | #835 | zeitstrahl-tag-chips | `frontend/src/lib/timeline/LetterCard.svelte` | `LetterCard.svelte.spec.ts#renders the chip inside an expanded YearLetterStrip too` | Done |
|
||||||
| REQ-013 | sr-only theme label is a Paraglide key present in de/en/es | #835 | zeitstrahl-tag-chips | `frontend/messages/{de,en,es}.json` | `messages.spec.ts#zeitstrahl tag-chip label key is present in all locales` | Done |
|
| REQ-013 | sr-only theme label is a Paraglide key present in de/en/es | #835 | zeitstrahl-tag-chips | `frontend/messages/{de,en,es}.json` | `messages.spec.ts#zeitstrahl tag-chip label key is present in all locales` | Done |
|
||||||
| REQ-014 | GET /api/timeline stays read-only (READ_ALL); no new endpoint/ErrorCode/IDOR; assembly logs UUIDs only | #835 | zeitstrahl-tag-chips | `timeline/TimelineController` (unchanged), `timeline/TimelineService` | `TimelineControllerTest#returns_200_with_read_all_permission`, `#returns_403_when_authenticated_without_read_all` (unchanged path); no tag names logged (review) | Done |
|
| REQ-014 | GET /api/timeline stays read-only (READ_ALL); no new endpoint/ErrorCode/IDOR; assembly logs UUIDs only | #835 | zeitstrahl-tag-chips | `timeline/TimelineController` (unchanged), `timeline/TimelineService` | `TimelineControllerTest#returns_200_with_read_all_permission`, `#returns_403_when_authenticated_without_read_all` (unchanged path); no tag names logged (review) | Done |
|
||||||
|
| REQ-001 | TimelineFilters is presentation-only (3 $bindable layer booleans + onChange); no goto/url.searchParams/api.GET/fetch | #780 | timeline-layer-filter | `frontend/src/lib/timeline/TimelineFilters.svelte` | `TimelineFilters.svelte.spec.ts#renders the three layer toggles with accessible names`, `#reflects a layer as pressed and flips it, firing onChange`; `timelineFilterBoundary.spec.ts` | Done |
|
||||||
|
| REQ-002 | route derives a client-side $derived filtered view, passes it to TimelineView; no goto/fetch on toggle | #780 | timeline-layer-filter | `frontend/src/routes/zeitstrahl/+page.svelte`, `frontend/src/lib/timeline/timelineFilter.ts#filterTimeline` | `page.svelte.spec.ts#hides letter cards when the Letters layer is off ... with no fetch`; `timelineFilterBoundary.spec.ts` | Done |
|
||||||
|
| REQ-003 | Personal off → personal events (curated + derived life-events) hidden client-side | #780 | timeline-layer-filter | `frontend/src/lib/timeline/timelineFilter.ts#filterTimeline` | `timelineFilter.spec.ts#hides personal events — curated and derived`, `page.svelte.spec.ts#hides personal event cards` | Done |
|
||||||
|
| REQ-004 | Historical off → historical event entries hidden client-side | #780 | timeline-layer-filter | `frontend/src/lib/timeline/timelineFilter.ts#filterTimeline` | `timelineFilter.spec.ts#hides HISTORICAL events`, `page.svelte.spec.ts#hides historical event cards` | Done |
|
||||||
|
| REQ-005 | Letters off → letter entries hidden client-side | #780 | timeline-layer-filter | `frontend/src/lib/timeline/timelineFilter.ts#filterTimeline` | `timelineFilter.spec.ts#hides LETTER entries`, `page.svelte.spec.ts#hides letter cards` | Done |
|
||||||
|
| REQ-006 | zero visible → filter empty-state + one-click reset below the open bar (never blank, never generic empty) | #780 | timeline-layer-filter | `frontend/src/routes/zeitstrahl/+page.svelte`, `frontend/src/lib/timeline/timelineFilter.ts#filterTimeline` | `page.svelte.spec.ts#shows the filtered-empty message + reset below the open bar`, `timelineFilter.spec.ts#drops year bands that become empty` | Done |
|
||||||
|
| REQ-007 | sticky "Filter (N aktiv)" trigger; N from isDefaultState/hiddenLayerCount; 44px target | #780 | timeline-layer-filter | `frontend/src/lib/timeline/timelineFilter.ts`, `frontend/src/lib/timeline/TimelineFilters.svelte` | `timelineFilter.spec.ts#isDefaultState`, `#hiddenLayerCount`; `TimelineFilters.svelte.spec.ts#shows a plain trigger ... and a count`, `#gives the trigger a 44px touch target` | Done |
|
||||||
|
| REQ-008 | reset text button restores all layers on; visibility tracks a $derived any-layer-off flag | #780 | timeline-layer-filter | `frontend/src/lib/timeline/TimelineFilters.svelte` | `TimelineFilters.svelte.spec.ts#hides the reset button by default and restores all layers when activated` | Done |
|
||||||
|
| REQ-009 | prefers-reduced-motion → slide duration 0 (matchMedia guard reused from documents/[id]/+page.svelte:57) | #780 | timeline-layer-filter | `frontend/src/lib/timeline/TimelineFilters.svelte` | manual reduced-motion check + svelte-autofixer/code review (guard reused, only the slide `duration` zeroed) | Done |
|
||||||
|
| REQ-010 | 8 timeline_filter_* keys in de/en/es; trigger vs trigger_active({count}) distinct | #780 | timeline-layer-filter | `frontend/messages/{de,en,es}.json` | `messages.spec.ts#zeitstrahl layer-filter keys are present in all locales (#780 REQ-010)` | Done |
|
||||||
|
|||||||
Reference in New Issue
Block a user