Timeline × Lesereisen: cross-epic synergies — promotion seam + mutual reference (avoid duplicate curation) #785
Reference in New Issue
Block a user
Delete Branch "%!s()"
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?
Milestones: #14 Zeitstrahl — Family Timeline · #13 Lesereisen (Reading Journeys)
Relates to: #774 (TimelineEvent entity), #775 (TimelineEvent CRUD), #781 (curator event forms), #778 (shared dateLabel helper) · #750 (GeschichteType/JourneyItem), #751 (JourneyItem CRUD), #753 (Journey editor)
Status: design-the-seam-now, build-post-MVP. Has open decisions — see "Decisions to resolve".
Why this issue exists
Two in-flight epics both wrap curated documents + narrative + persons:
timeline/domain): a time-anchored cluster of letters — title, type (PERSONAL/HISTORICAL),eventDate+DatePrecision, shortdescription, ManyToManydocuments/persons.GeschichteType.JOURNEYsubtype ofGeschichte— an ordered sequence ofJourneyItems with interludes (Zwischentexte), drag-reorder, rich narrative.This issue records the boundary decision (they are not duplicates) and the small seams that make them reinforce each other instead of drifting into two half-overlapping curation tools.
Verdict: complementary primitives — do NOT merge
The timeline design spec already keeps the
timeline/domain "deliberately separate from the in-flight Lesereisen/Geschichte work." That is correct and should stand.timeline/domainGeschichteType.JOURNEY(extendsGeschichte)eventDate+DatePrecision)JourneyItem.sortOrder)JourneyItemsdescription TEXT)WRITE_ALLBLOG_WRITEA TimelineEvent is a dot/span in time; a Lesereise is a path through pages. Merging would force an event to carry ordering + interludes it doesn't want, and a journey to carry a date axis it doesn't have (duplication-by-over-generalization).
Boundary rule (the actual anti-duplication guard)
The overlap hides in the event
description. If it grows into rich text with commentary between letters, we've reinvented a Journey inside a TimelineEvent.This rule is already reflected in #781 (description = optional plain textarea, not rich text). Keep it.
Proposed synergies (scoped)
S1 — Shared UI primitives (already in motion; just don't fork)
Both editors descend from
GeschichteEditor. The Journey editor (#753) = GeschichteEditor + ordering + interludes; the TimelineEvent editor (#781) = GeschichteEditor + date/precision, reusing the sameDocumentMultiSelect+PersonMultiSelectand the sharedDatePrecisionField(#781) /dateLabelhelper (#778). Action: no second picker, no second date primitive — verify both editors consume the shared components rather than re-implementing. (Largely covered by #781/#753; this is a cross-check, not new code.)S2 — Promotion seam: TimelineEvent → "Als Lesereise kuratieren" (primary value)
The timeline naturally discovers clusters ("24 Feldpost 1915"). Add an action on a TimelineEvent (event card and/or
/zeitstrahl/events/[id]/edit) → opens the Journey editor pre-filled with the event'sdocuments, ordered bydocumentDate. The curator then reorders + adds interludes. Funnel: discover-in-time (Zeitstrahl) → narrate-as-path (Lesereise).?documentId=prefill idiom (Journey editor /geschichten/new), extended to accept multiple ids (e.g.?documentIds=a,b,cor a transient seed) indocumentDateorder.S3 — Mutual reference (TimelineEvent ↔ Geschichte/Journey)
A nullable reference so the two can point at each other:
S4 — Lesereise as a timeline marker (discovery) (optional, later)
A Journey's items carry dates; the assembly endpoint (#777) could surface a Journey as a single marker on
/zeitstrahl(placed at its earliest item date) → tap → reader. Makes the Zeitstrahl a discovery surface for journeys. Lowest priority of the four.Decisions to resolve (needs-discussion)
TimelineEvent.geschichteIdnullable FK → Geschichte; (b) reuseGeschichte.documents↔event overlap with no FK (derive the link); (c) a small join table for many-to-many event↔journey. Leaning (a) — simplest, one direction is enough for MVP.WRITE_ALL, journeys areBLOG_WRITE. If the same people curate both, align the gates (likely bothBLOG_WRITE, or document why they differ). Cross-epic decision — owners of #775 and #751 should agree.?documentId=to a multi-id seed in date order, vs. a one-shot "create journey from these N documents" server action. Affects #753.Scope / non-goals
TimelineEvent; adding a date axis orDatePrecisiontoGeschichte; S4 (deferred). Do not generalize a shared "curated collection" super-entity.Dependencies
Blocked until both sides have entities + editors: #774, #775, #781 (timeline) and #750, #751, #753 (lesereisen). Best picked up after both editors exist so the promotion seam targets real routes.
Acceptance criteria (Given-When-Then)
documentDate, and saving creates aJOURNEY-type Geschichte. (S2)TimelineEvent.description, when edited, then it remains plain text (no rich-text/interlude affordances) — the boundary rule holds.TimelineEventandGeschichte/JourneyItemremain distinct tables.Task checklist (after decisions resolved)
needs-discussionuntil then).DocumentMultiSelect/PersonMultiSelect/DatePrecisionField/dateLabel— file follow-ups if either forks.?documentId=handling per Decision 4).timeline/andgeschichte/) + DB-diagram update.