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:
36
frontend/src/lib/document/README.md
Normal file
36
frontend/src/lib/document/README.md
Normal 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`
|
||||
34
frontend/src/lib/geschichte/README.md
Normal file
34
frontend/src/lib/geschichte/README.md
Normal 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`
|
||||
36
frontend/src/lib/notification/README.md
Normal file
36
frontend/src/lib/notification/README.md
Normal 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`
|
||||
27
frontend/src/lib/ocr/README.md
Normal file
27
frontend/src/lib/ocr/README.md
Normal 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`
|
||||
37
frontend/src/lib/person/README.md
Normal file
37
frontend/src/lib/person/README.md
Normal 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`
|
||||
40
frontend/src/lib/shared/README.md
Normal file
40
frontend/src/lib/shared/README.md
Normal 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.
|
||||
28
frontend/src/lib/tag/README.md
Normal file
28
frontend/src/lib/tag/README.md
Normal 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`
|
||||
28
frontend/src/lib/user/README.md
Normal file
28
frontend/src/lib/user/README.md
Normal 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`
|
||||
Reference in New Issue
Block a user