feat(timeline): root-tag color chip on /zeitstrahl letter cards (Datum mode) #838
Reference in New Issue
Block a user
Delete Branch "feat/issue-835-zeitstrahl-tag-chip"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Closes #835.
Adds the root-tag color chip to
/zeitstrahlletter cards (Datum mode): a thin vertical slice that enrichesTimelineEntryDTOwith each letter's primary root tag (id + name + color token) and renders one chip onLetterCard. No new table, migration, or endpoint;GET /api/timelinestaysREAD_ALL.What & how
TagService.resolveRootTags(tags) -> Map<id, RootTag>walks each tag to its root via the existing recursive-CTEfindAncestorIds, memoized per distinct tag + one batchedfindAllById(no per-letter N+1). Cross-domain access via the service, not the repo (constitution §1.3).TimelineEntryDTOgains nullablerootTagId/rootTagName/rootTagColor(LETTER-only; deliberately not@Schema(requiredMode = REQUIRED)), assembled in-transaction (ADR-036) — id + name + token only, never a serializedTag. The primary tag is the root ancestor of the letter's alphabetically-first assigned tag (#827 Resolved Decision 3, confirmed with the maintainer).TagChip.svelte(aria-hidden colored square viavar(--c-tag-{token}), neutral when null; escaped name; sr-onlytimeline_tag_chip_labelprefix; inline truncation so a long name never forces horizontal scroll at 320px).LetterCardrenders it beneath the meta line, so it appears wherever aLetterCarddoes (global timeline + expandedYearLetterStrip).api.ts;timeline_tag_chip_labeladded in de/en/es.Requirements → tests (REQ-001..014, all
Donein.specify/rtm.md)TimelineServiceTest(DTO population, untagged → null, deterministic single primary)TagServiceTest+TagServiceIntegrationTest(real-Postgres CTE walk, memoized no-N+1, null color)TagChip.svelte.spec.ts+LetterCard.svelte.spec.tsYearLetterStripmessages.spec.ts(key parity de/en/es)READ_ALLcontroller path; no new endpoint/ErrorCode; assembly logs UUIDs onlyVerification
TagServiceTest(52),TagServiceIntegrationTest(2),TimelineServiceTest(28),TimelineEventServiceTest(26),TimelineControllerTest(8) all green;mvnw clean package -DskipTestsOK.TagChip(6),LetterCard(14),messages(7), + TimelineView/YearBand/YearLetterStrip (32) green;svelte-checkadds no errors in touched files;@html/hex grep gates clean.Coordination
LetterCardchrome (already onmain).TagServiceresolver that #827 (Ereignis/Thema regroup) will consume — #827's REQ-005 should descope to add onlylinkedEventId.🤖 Generated with Claude Code
TagChip renders a letter's primary root tag as a small rounded pill — a decorative aria-hidden colored square (var(--c-tag-{token}), neutral when the color is null) plus the escaped tag name, prefixed by the sr-only theme label so color is never the only cue. Truncation is set inline so a long name ellipsizes without forcing the card into horizontal scroll, and the full name stays reachable via the chip title. Timeline-local by design — lib/timeline may not import lib/tag (eslint boundary). Refs #835 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>Two cleanups flagged in review, both behaviour-preserving: - collapse the {#if color}/{:else} square-marker branches (identical but for the neutral fill) into one element via class:bg-ink-3={!color}; squareStyle is already empty when color is null, so no var(--c-tag-) leaks into the neutral chip. - drop the redundant `truncate` class from the name span — the inline overflow/ellipsis trio (kept so it applies before the stylesheet loads, REQ-008a) already expresses exactly what `truncate` would. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>marcel referenced this pull request2026-06-14 18:19:09 +02:00
marcel referenced this pull request2026-06-14 18:19:37 +02:00
marcel referenced this pull request2026-06-14 18:19:56 +02:00
marcel referenced this pull request2026-06-14 18:20:13 +02:00
marcel referenced this pull request2026-06-14 18:20:37 +02:00
marcel referenced this pull request2026-06-14 18:20:58 +02:00
marcel referenced this pull request2026-06-14 18:27:57 +02:00
marcel referenced this pull request2026-06-14 18:28:33 +02:00
marcel referenced this pull request2026-06-14 18:29:17 +02:00