diff --git a/docs/ARCHITECTURE.md b/docs/ARCHITECTURE.md index 1b54eacf..540a9728 100644 --- a/docs/ARCHITECTURE.md +++ b/docs/ARCHITECTURE.md @@ -38,7 +38,7 @@ Both stacks are organised **package-by-domain**: each domain owns its entities, **`user`** — login accounts and permission groups. Owns `AppUser`, `UserGroup`, invite tokens. Does NOT own `Person` records. Cross-domain deps: `audit` (user management events). -**`geschichte`** — family stories. Owns `Geschichte` (`DRAFT → PUBLISHED` lifecycle). Cross-domain deps: `person`, `document` (linked entities in the story body). +**`geschichte`** — family stories and Lesereisen. Owns `Geschichte` (`DRAFT → PUBLISHED` lifecycle) and `JourneyItem` (ordered stops in a JOURNEY-type Geschichte). Two subtypes: `STORY` (prose) and `JOURNEY` (curated document sequence). Cross-domain deps: `person` (linked persons), `document` (via `JourneyItem.document_id`, ON DELETE SET NULL). **`notification`** — in-app messages. Owns `Notification`. Delivers via `SseEmitterRegistry` (live) and persisted rows (bell dropdown). Cross-domain deps: `user` (recipient), `document` (context). diff --git a/docs/GLOSSARY.md b/docs/GLOSSARY.md index d7f05bb7..7dd3419a 100644 --- a/docs/GLOSSARY.md +++ b/docs/GLOSSARY.md @@ -149,7 +149,11 @@ _See also [Chronik](#chronik-internal)._ **Chronik** `[internal]` — the conceptual and code-level name for the unified activity feed (per ADR-003 `003-chronik-unified-activity-feed.md`). Used in code, architecture documents, and ADRs. The user-facing label for the same concept is [Aktivität](#aktivitat--aktivitaten-user-facing). -**Geschichte** (`Geschichte`) `[user-facing]` — a narrative story or article published in the archive, linking `Person`s and `Document`s. Lifecycle: `DRAFT → PUBLISHED` (see `GeschichteStatus`). DRAFT stories are hidden from users without the `BLOG_WRITE` permission. +**Geschichte** (`Geschichte`) `[user-facing]` — a narrative story or curated document journey published in the archive. Two subtypes: `STORY` (free-form prose linking `Person`s) and `JOURNEY` (a *Lesereise* — an ordered sequence of `JourneyItem`s). Lifecycle: `DRAFT → PUBLISHED` (see `GeschichteStatus`). DRAFT stories are hidden from users without the `BLOG_WRITE` permission. + +**JourneyItem** (`JourneyItem`, table `journey_items`) `[internal]` — a single stop in a *Lesereise* (`Geschichte` with `type=JOURNEY`). Either document-backed (`document_id IS NOT NULL`) or a note-only interlude (`note IS NOT NULL`). Ordered by `position` (gaps of 1000 leave room for drag-reorder). A CHECK constraint ensures at least one of `document_id` or `note` is present. The FK to `documents` uses `ON DELETE SET NULL`, so deleting a document preserves the item (with `document_id = null`). + +**Lesereise** `[user-facing]` — a curated reading journey through a sequence of family documents, optionally annotated with editorial notes. Implemented as a `Geschichte` with `type=JOURNEY`. The reader UI (follow-on issue) renders items as a sequential reading experience. **Notification** (`Notification`) — an in-app message delivered to an `AppUser`. No email or SMS delivery exists today. Delivered via Server-Sent Events (`SseEmitterRegistry`) and persisted in the `notifications` table. diff --git a/docs/architecture/db/db-relationships.puml b/docs/architecture/db/db-relationships.puml index 82056761..571bc61f 100644 --- a/docs/architecture/db/db-relationships.puml +++ b/docs/architecture/db/db-relationships.puml @@ -66,7 +66,7 @@ package "Supporting" { entity audit_log entity geschichten entity geschichten_persons - entity geschichten_documents + entity journey_items } ' Auth relationships @@ -129,7 +129,7 @@ audit_log }o--o| documents : document_id geschichten }o--o| app_users : author_id geschichten_persons }o--|| geschichten : geschichte_id geschichten_persons }o--|| persons : person_id -geschichten_documents }o--|| geschichten : geschichte_id -geschichten_documents }o--|| documents : document_id +journey_items }o--|| geschichten : geschichte_id (ON DELETE CASCADE) +journey_items }o--o| documents : document_id (ON DELETE SET NULL) @enduml