docs(legibility): add 18 per-domain README.md files (DOC-6)

Backend (9): document, person, tag, user, geschichte, notification,
ocr, audit, dashboard.
Frontend (8): document, person, tag, user, geschichte, notification,
ocr, shared.
OCR service (1): ocr-service/README.md.

Each README covers: what the domain owns, explicit non-ownership,
public surface (verified by grep against the codebase), internal
layout, and cross-domain dependencies.

Closes #400
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Marcel
2026-05-05 23:11:49 +02:00
committed by marcel
parent a3c17750cd
commit a1b89670c0
18 changed files with 678 additions and 0 deletions

View File

@@ -0,0 +1,36 @@
# document (frontend)
UI for the archive's core concept: viewing, uploading, editing, searching, bulk-selecting, and transcribing documents.
## What this domain owns
Components: `DocumentRow`, `DocumentThumbnail`, `DocumentTopBar`, `DocumentViewer`, `DocumentMetadataDrawer`, `DocumentEditLayout`, `DocumentStatusChip`, `UploadZone`, `BulkSelectionBar`, `BulkDropZone`.
Utilities: `search.ts` (search-param helpers), `filename.ts` (filename formatting), `documentStatusLabel.ts` (i18n label mapping), `validateFile.ts` (upload validation), `groupDocuments.ts` (list grouping).
Sub-folders: `annotation/`, `transcription/`, `viewer/`.
## What this domain does NOT own
- Person typeahead — `person/PersonTypeahead.svelte` (cross-domain import, allowed by ESLint rule)
- Tag input — `tag/TagInput.svelte` (cross-domain import, allowed)
- Shared discussion — `shared/discussion/` (comment/mention editor)
## Key components
| Component | Route used in | Notes |
| --------------------------- | ---------------------------------- | ------------------------------------ |
| `DocumentRow.svelte` | `/` (search results), admin queues | Compact document card with thumbnail |
| `DocumentViewer.svelte` | `/documents/[id]` | PDF/image inline viewer |
| `DocumentEditLayout.svelte` | `/documents/[id]/edit` | Full edit form with sticky save bar |
| `UploadZone.svelte` | `/documents/new`, bulk upload | Drag-and-drop file drop area |
| `BulkSelectionBar.svelte` | `/documents` bulk mode | Multi-select action bar |
## Cross-domain imports
- `person/PersonTypeahead.svelte` — sender / receiver selection
- `tag/TagInput.svelte` — tag chip input
- `ocr/OcrProgress.svelte` — job status indicator in the document header
- `shared/primitives/BackButton.svelte`, `shared/discussion/` — shared UI
## Backend counterpart
`backend/src/main/java/org/raddatz/familienarchiv/document/README.md`

View File

@@ -0,0 +1,34 @@
# geschichte (frontend)
UI for family stories: the rich-text editor, story cards, and story list view.
## What this domain owns
Components: `GeschichteEditor.svelte`, `GeschichtenCard.svelte`.
## What this domain does NOT own
- Comment/discussion UI — shared via `shared/discussion/` (same component used for document comments)
- Person display — `person/PersonChip.svelte` is used inside story content (cross-domain import)
- Document display — document references in stories use components from `document/`
## Key components
| Component | Used in | Notes |
| ------------------------- | -------------------------------------------- | ------------------------------------------------------------------ |
| `GeschichteEditor.svelte` | `/geschichten/new`, `/geschichten/[id]/edit` | Rich-text editor with person/document @-mentions and inline embeds |
| `GeschichtenCard.svelte` | `/geschichten` (list), dashboard | Story preview card with cover image and publish status |
## Audience note
The `/geschichten` route primarily serves readers (younger family members on mobile). Cards must have ≥ 44 px touch targets. Status must not rely on color alone.
## Cross-domain imports
- `person/PersonChip.svelte` — inline person references in story content
- `document/DocumentThumbnail.svelte` — inline document references
- `shared/discussion/` — comment thread below published stories
## Backend counterpart
`backend/src/main/java/org/raddatz/familienarchiv/geschichte/README.md`

View File

@@ -0,0 +1,36 @@
# notification (frontend)
Bell-icon dropdown and real-time SSE connection for in-app notifications.
## What this domain owns
Components: `NotificationBell.svelte`, `NotificationDropdown.svelte`.
Utilities: `notifications.svelte.ts` (Svelte 5 reactive store), `notifications.ts` (API helpers).
## What this domain does NOT own
- SSE infrastructure — the backend's `SseEmitterRegistry` manages the server-side emitter. The frontend establishes one `EventSource` connection per session. Connection management lives in `notifications.svelte.ts`.
- Notification content rendering — notification payloads contain a `contextUrl`; the frontend navigates there on click.
## Key design: SSE connection
The SSE path is **backend → browser directly** (not proxied through SvelteKit SSR). The `EventSource` connects to `/api/notifications/stream`. On receive, the reactive store updates the unread count and the bell dropdown in real time.
```
Backend SseEmitterRegistry → /api/notifications/stream → EventSource in browser
```
## Key components
| Component | Used in | Notes |
| ----------------------------- | ----------------------------- | --------------------------------------------------------- |
| `NotificationBell.svelte` | global nav (`+layout.svelte`) | Bell icon with unread badge; opens `NotificationDropdown` |
| `NotificationDropdown.svelte` | global nav | Scrollable list of recent notifications with mark-read |
## Cross-domain imports
- `shared/primitives/` — icon, button primitives only
## Backend counterpart
`backend/src/main/java/org/raddatz/familienarchiv/notification/README.md`

View File

@@ -0,0 +1,27 @@
# ocr (frontend)
UI for OCR job management, progress display, and sender-model training in the admin/enrichment panel.
## What this domain owns
Components: `OcrProgress.svelte`, `OcrTrigger.svelte`, `OcrTrainingCard.svelte`, `SegmentationTrainingCard.svelte`, `TrainingHistory.svelte`.
Utilities: `translateOcrProgress.ts` (progress-state → display-string mapping), `training.ts` (training API helpers).
## What this domain does NOT own
- OCR processing — all text recognition runs in the Python `ocr-service/` container. The frontend shows job state; it does not run OCR.
- Transcription block display — rendered by `document/transcription/` components.
## Key components
| Component | Used in | Notes |
| --------------------------------- | ----------------------------- | -------------------------------------------------------- |
| `OcrProgress.svelte` | document header, enrich panel | Progress bar and status label for an active OCR job |
| `OcrTrigger.svelte` | enrich panel, document detail | Button to start an OCR job; disabled when one is running |
| `OcrTrainingCard.svelte` | `/admin/ocr` | Trigger sender-model training; shows training history |
| `SegmentationTrainingCard.svelte` | `/admin/ocr` | Trigger segmentation training |
| `TrainingHistory.svelte` | `/admin/ocr` | List of past training runs with status |
## Backend counterpart
`backend/src/main/java/org/raddatz/familienarchiv/ocr/README.md`

View File

@@ -0,0 +1,37 @@
# person (frontend)
UI for historical family members: typeahead selection, chip display, hover cards, genealogy graph, relationship management.
## What this domain owns
Components: `PersonTypeahead.svelte`, `PersonMultiSelect.svelte`, `PersonChip.svelte`, `PersonChipRow.svelte`, `PersonHoverCard.svelte`, `PersonTypeBadge.svelte`, `PersonTypeSelector.svelte`.
Utilities: `personFormat.ts` (full-name formatting), `personLifeDates.ts` (birth/death display), `person-validation.ts` (form validation), `personHoverCard.ts` (hover-card controller).
Sub-folders: `genealogy/` (Stammbaum view components), `relationship/` (relationship graph components).
## What this domain does NOT own
- Document content — displayed in `document/`
- AppUser accounts — managed in `user/`
## Key components
| Component | Used in | Notes |
| -------------------------- | ----------------------------------------- | ----------------------------------------------------------------------------------- |
| `PersonTypeahead.svelte` | document edit, geschichte, search filters | Single-person selector with debounced typeahead. Exported for use by other domains. |
| `PersonMultiSelect.svelte` | document edit (receivers) | Chip-based multi-person selector |
| `PersonChip.svelte` | document rows, conversation view | Compact display chip with link and hover card |
| `PersonHoverCard.svelte` | person chips | Floating card with person summary on hover |
## Cross-domain imports
- `shared/primitives/` — generic UI primitives
- `shared/hooks/useTypeahead.svelte.ts` — typeahead keyboard/focus logic
## Accessibility notes
- `PersonChip` focus ring: `focus-visible:ring-2 focus-visible:ring-brand-navy`
- `PersonTypeahead` dropdown navigable via keyboard (↑↓ Enter Escape)
## Backend counterpart
`backend/src/main/java/org/raddatz/familienarchiv/person/README.md`

View File

@@ -0,0 +1,40 @@
# shared (frontend)
Cross-domain utilities and UI primitives. Any file here is consumed by two or more domain folders and has no domain identity of its own.
## Admission criteria (what belongs here)
A file belongs in `shared/` if it meets **all three** conditions:
1. No domain identity — it does not represent a `Document`, `Person`, `Tag`, etc.
2. Consumed by ≥ 2 domain folders — or is framework infrastructure that every domain depends on.
3. Generic — could work in a different SvelteKit project with zero business-logic changes.
If any condition fails, the file belongs in the domain folder of its primary consumer.
## What this folder owns
| Sub-folder / file | Purpose |
| ----------------- | ----------------------------------------------------------------------------------------------------------------------------------- |
| `api.server.ts` | Typed `openapi-fetch` client factory — the standard entry point for all backend API calls in server-side load functions and actions |
| `errors.ts` | Mirror of the backend `ErrorCode` enum + `getErrorMessage()` → Paraglide i18n key mapping |
| `types.ts` | Cross-domain TypeScript interfaces |
| `utils.ts` | Pure utility functions (date formatting, sorting, debounce) |
| `relativeTime.ts` | Human-relative time formatting (`"2 days ago"`) |
| `primitives/` | Generic UI components: `BackButton.svelte`, form inputs, pagination, layout shells |
| `discussion/` | Comment/mention editor shared by `document/` and `geschichte/` |
| `dashboard/` | Family Pulse widget and recent-activity components assembled in the `/` route |
| `hooks/` | Svelte 5 reactive hooks: `useTypeahead`, `useUnsavedWarning` |
| `services/` | Generic client-side service helpers |
| `actions/` | Shared SvelteKit form action utilities |
| `server/` | Server-only shared utilities (load function helpers) |
| `help/` | Coach marks and empty-state components used across multiple domains |
## What does NOT belong here
- Components owned by one domain — move to that domain's folder.
- Domain-specific business logic — even if shared, it belongs in the owning domain's public surface.
## Adding to shared/
If you need to add a file here, confirm it meets all three admission criteria. If it's domain-adjacent, check whether the owning domain should export it as part of its public surface instead.

View File

@@ -0,0 +1,28 @@
# tag (frontend)
UI for hierarchical document categories: tag chip lists, tag input with typeahead, and the admin tag-tree editor.
## What this domain owns
Components: `TagInput.svelte`, `TagChipList.svelte`, `TagParentPicker.svelte`.
## What this domain does NOT own
- Tag data management — CRUD is handled via the backend `tag/` domain
- Document association — adding/removing tags from documents is in `document/`
## Key components
| Component | Used in | Notes |
| ------------------------ | --------------------------- | -------------------------------------------------------------------------------------------------------------------------------- |
| `TagInput.svelte` | document edit form | Multi-tag chip input with typeahead. Supports free-text creation and selecting existing tags. Exported for use by other domains. |
| `TagChipList.svelte` | document rows, detail pages | Read-only display of a tag set |
| `TagParentPicker.svelte` | admin tag editor | Tree-aware parent selection |
## Cross-domain imports
- `shared/hooks/useTypeahead.svelte.ts` — shared typeahead logic for `TagInput`
## Backend counterpart
`backend/src/main/java/org/raddatz/familienarchiv/tag/README.md`

View File

@@ -0,0 +1,28 @@
# user (frontend)
UI for account management: profile editing, password change, and permission group management in the admin panel.
## What this domain owns
Components: `UserProfileSection.svelte`, `UserPasswordSection.svelte`, `UserGroupsSection.svelte`.
## What this domain does NOT own
- `Person` records — historical family members are entirely separate from login accounts. A user editing their profile is an `AppUser`; the historical persons in documents are `Person` entities. They are never linked.
- User list or admin creation UI — those live in the `/admin` route, which assembles views from multiple domains.
## Key components
| Component | Used in | Notes |
| ---------------------------- | --------------------------- | ------------------------------------ |
| `UserProfileSection.svelte` | `/settings` or profile page | Display name, email editing |
| `UserPasswordSection.svelte` | `/settings` | Password change form |
| `UserGroupsSection.svelte` | `/admin` | Per-user permission group assignment |
## Cross-domain imports
- `shared/primitives/` — generic UI primitives only
## Backend counterpart
`backend/src/main/java/org/raddatz/familienarchiv/user/README.md`