docs(rtm): trace #842 timeline-curator-affordances + i18n parity guard
All checks were successful
CI / Unit & Component Tests (pull_request) Successful in 5m38s
CI / OCR Service Tests (pull_request) Successful in 26s
CI / Backend Unit Tests (pull_request) Successful in 6m35s
CI / fail2ban Regex (pull_request) Successful in 52s
CI / Semgrep Security Scan (pull_request) Successful in 24s
CI / Compose Bucket Idempotency (pull_request) Successful in 1m9s
SDD Gate / RTM Check (pull_request) Successful in 17s
SDD Gate / Contract Validate (pull_request) Successful in 30s
SDD Gate / Constitution Impact (pull_request) Successful in 16s
All checks were successful
CI / Unit & Component Tests (pull_request) Successful in 5m38s
CI / OCR Service Tests (pull_request) Successful in 26s
CI / Backend Unit Tests (pull_request) Successful in 6m35s
CI / fail2ban Regex (pull_request) Successful in 52s
CI / Semgrep Security Scan (pull_request) Successful in 24s
CI / Compose Bucket Idempotency (pull_request) Successful in 1m9s
SDD Gate / RTM Check (pull_request) Successful in 17s
SDD Gate / Contract Validate (pull_request) Successful in 30s
SDD Gate / Constitution Impact (pull_request) Successful in 16s
Add REQ-001..011 rows for the timeline-curator-affordances feature (all Done) and a messages.spec parity guard pinning timeline_add_event + person_add_event across de/en/es. REQ-010/011 cite the existing #781 new-event route + its 403 guard test (no new production code). Refs #842 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -183,3 +183,14 @@
|
||||
| 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 |
|
||||
| REQ-001 | WRITE_ALL viewer → "Ereignis hinzufügen" link to /zeitstrahl/events/new in the wrapping Zeitstrahl header | #842 | timeline-curator-affordances | `frontend/src/routes/zeitstrahl/+page.svelte`, `frontend/messages/{de,en,es}.json` | `zeitstrahl/page.svelte.spec.ts#renders the add-event CTA in a wrapping header when the viewer can write` | Done |
|
||||
| REQ-002 | viewer without WRITE_ALL → no add-event affordance on /zeitstrahl | #842 | timeline-curator-affordances | `frontend/src/routes/zeitstrahl/+page.svelte` | `zeitstrahl/page.svelte.spec.ts#renders no add-event CTA when the viewer cannot write` | Done |
|
||||
| REQ-003 | WRITE_ALL viewer → person-page "Ereignis für diese Person" link to /zeitstrahl/events/new?personId={id} | #842 | timeline-curator-affordances | `frontend/src/routes/persons/[id]/PersonCard.svelte`, `frontend/messages/{de,en,es}.json` | `PersonCard.svelte.spec.ts#shows an add-event link pre-seeded with the person to a curator` | Done |
|
||||
| REQ-004 | viewer without WRITE_ALL → no add-event affordance on /persons/{id} | #842 | timeline-curator-affordances | `frontend/src/routes/persons/[id]/PersonCard.svelte` | `PersonCard.svelte.spec.ts#renders no add-event link to a reader` | Done |
|
||||
| REQ-005 | WRITE_ALL → EventPill edit link /zeitstrahl/events/{eventId}/edit for a curated PERSONAL event | #842 | timeline-curator-affordances | `frontend/src/lib/timeline/EventPill.svelte` | `EventPill.svelte.spec.ts#shows an edit affordance for a curated PERSONAL event when canWrite is true` | Done |
|
||||
| REQ-006 | WRITE_ALL → WorldBand edit link /zeitstrahl/events/{eventId}/edit for a curated HISTORICAL event (new inline ✎) | #842 | timeline-curator-affordances | `frontend/src/lib/timeline/WorldBand.svelte` | `WorldBand.svelte.spec.ts#shows an edit affordance for a curated HISTORICAL event when canWrite is true`, `#mirrors the EventPill pencil` | Done |
|
||||
| REQ-007 | viewer without WRITE_ALL → neither EventPill nor WorldBand renders an edit link | #842 | timeline-curator-affordances | `frontend/src/lib/timeline/EventPill.svelte`, `frontend/src/lib/timeline/WorldBand.svelte` | `EventPill.svelte.spec.ts#renders no edit affordance for a curated PERSONAL event when canWrite is false`, `WorldBand.svelte.spec.ts#renders no edit affordance for a curated HISTORICAL event when canWrite is false`, `TimelineView.svelte.spec.ts#renders no edit links in either path when canWrite is false` | Done |
|
||||
| REQ-008 | derived OR null eventId → no edit link regardless of permission (contract preserved) | #842 | timeline-curator-affordances | `frontend/src/lib/timeline/EventPill.svelte`, `frontend/src/lib/timeline/WorldBand.svelte` | `EventPill.svelte.spec.ts#shows no edit affordance when eventId is null even with canWrite`, `#shows no edit affordance for a derived event even with canWrite`, `WorldBand.svelte.spec.ts#shows no edit affordance when eventId is null even with canWrite` | Done |
|
||||
| REQ-009 | TimelineView threads canWrite through the year-band path and the undated bucket (identical gate) | #842 | timeline-curator-affordances | `frontend/src/lib/timeline/TimelineView.svelte`, `frontend/src/lib/timeline/YearBand.svelte` | `TimelineView.svelte.spec.ts#threads canWrite to a curated event in both a year band and the undated bucket`, `#threads canWrite to a curated HISTORICAL world band in both paths` | Done |
|
||||
| REQ-010 | person add-event opens #781 create form prefilled with the person, returns to /persons/{id} on save | #842 | timeline-curator-affordances | `frontend/src/routes/persons/[id]/PersonCard.svelte`, `frontend/src/routes/zeitstrahl/events/new/+page.server.ts` (#781) | `PersonCard.svelte.spec.ts#shows an add-event link pre-seeded with the person to a curator` (URL), `zeitstrahl/events/new/page.server.spec.ts#redirects to /persons/{id} when originPersonId is a valid UUID` (#781) | Done |
|
||||
| REQ-011 | non-curator direct nav to /zeitstrahl/events/new or /{id}/edit → 403 (existing #781 route guard, regression) | #842 | timeline-curator-affordances | `frontend/src/routes/zeitstrahl/events/new/+page.server.ts` (#781, unchanged) | `zeitstrahl/events/new/page.server.spec.ts#throws 403 for an authenticated user without WRITE_ALL` | Done |
|
||||
|
||||
@@ -123,4 +123,14 @@ describe('message key parity', () => {
|
||||
expect(en.timeline_filter_trigger_active).toContain('{count}');
|
||||
expect(es.timeline_filter_trigger_active).toContain('{count}');
|
||||
});
|
||||
|
||||
// #842: the two curator-affordance CTA labels (Zeitstrahl header + person page)
|
||||
// are Paraglide keys present in every locale; the edit pencils reuse btn_edit.
|
||||
it('curator-affordance CTA keys are present in all locales (#842)', () => {
|
||||
for (const key of ['timeline_add_event', 'person_add_event']) {
|
||||
expect(de, `missing key in de: ${key}`).toHaveProperty(key);
|
||||
expect(en, `missing key in en: ${key}`).toHaveProperty(key);
|
||||
expect(es, `missing key in es: ${key}`).toHaveProperty(key);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user