# Geschichten — Personenverknüpfung

Entdeckung verlinkter Geschichten über die Personendetailseite. Lesende, die nach Franz Raddatz suchen, finden automatisch alle veröffentlichten Geschichten, die ihn erwähnen — als neue Karte am Ende der rechten Spalte.

Familienarchiv
Final Spec
2026-05-02 · @leonievoss
P

## Personen-Entdeckung

Neugierige Leserinnen und Leser suchen Personen und finden dort alle Geschichten, die über sie erzählt wurden — ohne separaten Suchlauf.

/persons/[id] · +page.svelte rechte Spalte · GeschichtenCard.svelte
Konzept

Die Personendetailseite hat bereits eine informationsdichte rechte Spalte: Briefpartner, Beziehungen, gesendete und empfangene Briefe. Die Geschichten-Karte wird ganz am Ende dieser Spalte angehängt — sie erscheint nur, wenn mindestens eine veröffentlichte Geschichte diese Person erwähnt. Ist keine vorhanden, fehlt die Karte vollständig; kein Leerszustand, keine Platzhalter.

Innerhalb der Karte gilt das redaktionelle Listen-Layout: Metadaten links (Avatar, Autorenname, Datum), Titel und Ausschnitt rechts — konsistent mit der /geschichten-Übersichtsseite. BLOG_WRITERs sehen im Karten-Header einen Schnellzugriff, um eine neue Geschichte mit dieser Person vorauszufüllen.

Die Karte ist bewusst passiv: Sie zeigt, was andere über diese Person geschrieben haben. Sie ist kein Aufruf zum Schreiben, sondern ein stiller Hinweis auf vorhandene Erinnerungen.

Screens

### P-1 — /persons/[id] · Geschichten-Karte in der rechten Spalte

P-1

Vollständige Personendetailseite mit der neuen Geschichten-Karte am Ende der rechten Spalte. Franz Raddatz hat drei veröffentlichte Geschichten, die ihn erwähnen.

Desktop · 1040px — Zweispaltiges Layout (35 % / 65 %), Karte erscheint als letztes Element rechts.

Desktop · 1040px
← Zurück
FR
Franz Raddatz
* 14. März 1898 in Breslau † 7. Nov. 1952 in Hamburg
✏
Briefschreiber, Gutsverwalter
Namensvarianten
Franz François F. Raddatz Franzl
Briefpartner
EM
Emma Müller 34 Briefe
HK
Heinrich Kohl 18 Briefe
GR
Gertrud Raddatz 11 Briefe
Beziehungen
EM
Emma Müller Ehefrau
KR
Klaus Raddatz Sohn
Verfasste Briefe (47)
12. Juli 1938Brief an Emma Müller
3. März 1937Brief an Heinrich Kohl
18. Okt. 1935Brief an Gertrud Raddatz
+ 44 weitere anzeigen
Erhaltene Briefe (23)
14. Aug. 1938Brief von Emma Müller
7. Apr. 1936Brief von Heinrich Kohl
Geschichten
+ Geschichte schreiben
MR
Maria Raddatz
14. März 2025
Der Sommer in Breslau
Oma erzählte oft vom letzten Sommer vor dem Krieg, als die Familie noch vollständig zusammen war…
KR
Klaus Raddatz
2. Jan. 2025
Wie Opa Franz den Hof rettete
Es war ein kalter November, als der Notar anklopfte. Opa hatte nur wenige Stunden Zeit…
GK
Gertrud Koch
18. Okt. 2024
Die Hochzeit im Krieg
1943, mitten im Chaos — Emma bestand darauf, dass das Fest stattfand…

#### P-1 · Implementation Reference

Element | Wert / Klasse | Hinweis
--- | --- | ---
Karten-Wrapper
Geschichten-Karte | `mt-6 bg-white shadow-sm border border-brand-sand rounded-sm p-6` | Identisches Pattern wie alle anderen rechten Spalten-Karten
Karten-Header | `flex items-center justify-between mb-5` |
Section-Heading | `text-xs font-bold uppercase tracking-widest text-gray-400` | Projekt-Standard, identisch mit anderen Karten
"+ Geschichte schreiben" | `text-[10px] text-turquoise font-semibold hover:underline` | Link zu `/geschichten/new?personId={id}`, nur mit BLOG_WRITE
Redaktionelle Liste (Stories)
Listen-Wrapper | `flex flex-col divide-y divide-brand-sand` |
Story-Zeile | `flex gap-3 py-3 first:pt-0 last:pb-0` | min-h-[44px] auf Mobile (Touch-Target WCAG 2.2)
Meta-Spalte | `w-[72px] shrink-0 flex flex-col gap-0.5` | Feste Breite, kein Overflow
Autoren-Avatar | `w-6 h-6 rounded-full text-[9px] font-bold text-white flex items-center justify-center` | `personAvatarColor(author.id)` aus existierendem Util
Autorenname | `font-sans text-[10px] font-semibold text-ink leading-tight` |
Datum | `font-sans text-[10px] text-ink-3` | `formatDate(publishedAt)`
Story-Titel (Link) | `block font-serif text-[12px] text-ink hover:text-primary hover:underline leading-snug` | Link zu `/geschichten/{id}`
Ausschnitt | `font-sans text-[10px] text-ink-3 line-clamp-1 mt-0.5` | Erste ~80 Zeichen des body-Texts (HTML-Tags gestripped)
Karten-Footer
"Alle Geschichten"-Link | `mt-3 block font-sans text-[10px] text-ink-3 hover:text-primary` | Nur wenn `geschichten.length >= 3`. Link: `/geschichten?personId={id}`
Konditionelles Rendering
Karte sichtbar | `{#if geschichten.length > 0}` | Kein Leerszustand — Stille ist korrekt (US-BLOG-005)
Max. angezeigte Geschichten | 3 in der Karte | Server-seitig mit `&limit=3` limitieren

### P-2 — Mobile · Geschichten-Karte gestapelt

P-2

Auf Mobile kollabiert das 2-Spalten-Layout zu einer einzigen Spalte. Die Geschichten-Karte erscheint unter allen anderen Karten — genau in der Reihenfolge der Desktop-Ansicht von oben nach unten.

Mobile · 320px — SingleColumn, vollbreite Karten. Jede Geschichten-Zeile hat min-h-[44px] als Touch-Target.

Mobile · 320px (nach unten gescrollt)
9:41●●●
← Personen
… PersonCard · Namensvarianten · Briefpartner · Beziehungen · Briefe …
Geschichten
+ Geschichte schreiben
MR
Maria Raddatz
14. März 2025
Der Sommer in Breslau
Oma erzählte oft vom letzten Sommer vor dem Krieg…
KR
Klaus Raddatz
2. Jan. 2025
Wie Opa Franz den Hof rettete
Es war ein kalter November, als der Notar anklopfte…
GK
Gertrud Koch
18. Okt. 2024
Die Hochzeit im Krieg
1943, mitten im Chaos — Emma bestand darauf…

### P-3 — Keine Geschichten — Karte fehlt (Stille)

P-3

Wenn keine veröffentlichten Geschichten diese Person erwähnen, erscheint die Karte nicht. Kein Leerszustand, keine Platzhalter — die Seite endet einfach bei den erhaltenen Briefen.

🔇

Stille ist korrekt — US-BLOG-005 schreibt explizit vor: „Given a document has no published stories, when I view the document detail page, then no 'Geschichten' section is shown (no empty state needed — silence is correct)." Das gilt analog für die Personenseite. Die Karte wird nur gerendert, wenn `geschichten.length > 0`. Keine leere Karte, kein „Noch keine Geschichten"-Text, kein Aufruf zum Schreiben an Lesende.

## Implementation Guide — Personen-Entdeckung

### 1. Backend-Änderungen

Endpunkt | Änderung | Hinweis
--- | --- | ---
`GET /api/geschichten?personId={id}&status=PUBLISHED&limit=3` | Neuer Filter-Parameter | Nur PUBLISHED zurückgeben, auch ohne BLOG_WRITE. Limit serverseitig.
`GET /api/persons/{id}` Loader | Mitladen der Geschichten | Im `+page.server.ts` parallel zu sentDocuments laden.

### 2. Frontend-Änderungen

- `persons/[id]/+page.server.ts` — geschichten parallel laden, in pageData exponieren
- `persons/[id]/+page.svelte` — `GeschichtenCard` am Ende der rechten Spalte rendern (`mt-6`), nur wenn `data.geschichten.length > 0`
- Neues Shared-Component: `$lib/components/GeschichtenCard.svelte`

### 3. GeschichtenCard.svelte — Props

Prop | Typ | Verwendung
--- | --- | ---
`geschichten` | `Geschichte[]` | Die Geschichten-Liste (max. 3 vom Server)
`personId` | `string | undefined` | Für "alle anzeigen"- und "schreiben"-Link
`canWrite` | `boolean` | Steuert "+ Geschichte schreiben" Sichtbarkeit

### 4. Wiederverwendbare Utilities

- `personAvatarColor(id)` — bereits vorhanden in `$lib/utils/personFormat.ts`
- `formatDate(date)` — bereits vorhanden in `$lib/utils/date.ts`
- Story-Ausschnitt: HTML-Tags aus `body` strippen, erste 80 Zeichen nehmen

### 5. Barrierefreiheit

- Alle Story-Links haben beschreibenden Text (Titel der Geschichte)
- Touch-Targets auf Mobile: `min-h-[44px]` je Zeile (WCAG 2.2)
- "+ Geschichte schreiben"-Link hat ausreichend Kontrast: Turquoise (#00C7B1) auf Weiß = 2.8:1 — für diesen kleinen UI-Hinweis akzeptabel, aber kein Body-Text
- Strukturell: Die Karte ist eine `<section>` mit `aria-labelledby` auf die Überschrift

### 6. Kein eigener Leerszustand

Die Komponente wird nur gerendert, wenn `geschichten.length > 0`. Keine leere Karte, kein Platzhaltertext, kein Aufruf zum Schreiben an Lesende ohne BLOG_WRITE-Berechtigung. Stille ist das korrekte Design für fehlende Geschichten.