add document scanning design spec
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,81 @@
|
||||
# PTV11 Document Capture & Storage — Design Spec
|
||||
|
||||
**Goal:** Allow users to photograph or upload PTV11 documents and associate them with an Erstgespräch (sprechstunde). Multiple documents per Erstgespräch. Stored locally, viewable in-app.
|
||||
|
||||
**Architecture:** Thin IndexedDB wrapper for blob storage, separate from PGlite. No new SQL migrations. UI integrated into the existing ErstgespraechCard in the process stepper.
|
||||
|
||||
**Tech Stack:** IndexedDB (raw API), `<input type="file">` with native document scanner, `URL.createObjectURL()` for previews.
|
||||
|
||||
---
|
||||
|
||||
## Storage Layer
|
||||
|
||||
New module: `src/shared/hooks/dokument-store.ts`
|
||||
|
||||
Opens a dedicated IndexedDB database `tpf-dokumente` with a single object store `dokumente` (auto-increment key, indexed on `sprechstundeId`).
|
||||
|
||||
### Record Shape
|
||||
|
||||
```ts
|
||||
interface Dokument {
|
||||
id: number; // auto-incremented
|
||||
sprechstundeId: number;
|
||||
name: string; // original filename
|
||||
mimeType: string; // "image/jpeg", "application/pdf", etc.
|
||||
blob: Blob;
|
||||
erstelltAm: string; // ISO date
|
||||
}
|
||||
```
|
||||
|
||||
### API
|
||||
|
||||
- `saveDokument(sprechstundeId: number, file: File): Promise<number>` — store file, return id
|
||||
- `getDokumente(sprechstundeId: number): Promise<Dokument[]>` — all docs for an Erstgespräch
|
||||
- `deleteDokument(id: number): Promise<void>` — remove single doc
|
||||
- `deleteDokumenteForSprechstunde(sprechstundeId: number): Promise<void>` — cascade on Erstgespräch delete
|
||||
- `deleteAllDokumente(): Promise<void>` — for "delete all data" in settings
|
||||
|
||||
Plain async functions (not React hooks). Components call imperatively and manage their own state.
|
||||
|
||||
## UI Integration
|
||||
|
||||
### Location
|
||||
|
||||
Inside the existing `ErstgespraechCard` in `src/features/prozess/components/process-stepper.tsx`, below diagnosis/Dringlichkeitscode info.
|
||||
|
||||
### New Component
|
||||
|
||||
`src/features/prozess/components/dokument-liste.tsx`
|
||||
|
||||
Props: `{ sprechstundeId: number }`
|
||||
|
||||
Manages its own state: loads documents on mount, refreshes after add/delete.
|
||||
|
||||
### Upload
|
||||
|
||||
`<input type="file" accept="image/*,application/pdf" multiple>` styled as a button labeled "Dokument hinzufügen". On mobile this triggers the system picker which includes "Scan Documents" on iOS and camera/files on Android.
|
||||
|
||||
### Thumbnails
|
||||
|
||||
Grid of small previews:
|
||||
- Images: `URL.createObjectURL()` thumbnails
|
||||
- PDFs: generic PDF icon with filename
|
||||
|
||||
Each thumbnail has a delete button (X) with confirmation.
|
||||
|
||||
### Full-size Viewing
|
||||
|
||||
- Images: modal overlay, image scaled to fit viewport, tap outside or X to close
|
||||
- PDFs: open in new browser tab via `URL.createObjectURL()` (native PDF viewing)
|
||||
|
||||
## Cleanup Integration
|
||||
|
||||
- `deleteErstgespraech(id)` in `src/features/prozess/hooks.ts` also calls `deleteDokumenteForSprechstunde(id)`
|
||||
- `deleteAllData()` in `src/features/kontakte/hooks.ts` also calls `deleteAllDokumente()`
|
||||
- Scenario seeding unchanged — dev scenarios don't need documents
|
||||
|
||||
## Out of Scope
|
||||
|
||||
- PDF export integration (documents into the Absagenliste PDF) — deferred to a future sub-project
|
||||
- OCR / data extraction from PTV11
|
||||
- Cloud sync / backup of documents
|
||||
Reference in New Issue
Block a user