# Plan: Anhang-Upload (Foto · PDF · Text) als Kontext für die Sprach-KI

Stand: 2026-08-08 · Status: **Phase 1 komplett (1a→1c)** · zweigeteilt (Jetzt / Go-Live)

> **Fortschritt (fertig):**
> - **1a** Upload + Polling + Status/Fortschritt verdrahtet. `AnhangBox` (DesignSystem) im Briefing
>   (nur ohne Bericht) + Bericht/Entwurf; Foto via PhotosPicker, PDF/Text via fileImporter, mehrere.
>   `POST /visits/:id/anhang` (`dateien[]`, max 10 · 20 MB) + `GET …/anhang/status`.
> - **1b** Echte Extraktion (Text passthrough, PDF via pdf-parse, Foto via Claude Vision). Status je
>   Datei **live** (Poll-Budget ~2 Min), Fortschrittsbalken läuft real. Per curl verifiziert.
> - **1c** Voice-Grounding (Briefing/Doku/Verfeinern kennen die Anhänge) + Report-`anhaenge[]` →
>   iOS zeigt „Anhänge"-Karte (Dateiname · Typ · Kurzfassung); Fakten fließen in die `zusammenfassung`.
> **Offen:** nur noch der Geräte-/Live-Test des Voice-Groundings (Worker neu gestartet).

## Ziel
Der AD hängt **vor der Doku** (aus dem Briefing) oder **an einem Entwurf-Bericht** einen oder
**mehrere Anhänge** an – **Foto, PDF oder Textdatei**. Das Backend extrahiert den Inhalt, und der
steht der **Sprach-KI** genauso wie das Briefing als **Kontext** bereit: bereits festgehaltene Themen
fragt sie nicht erneut ab, und der Inhalt **fließt in die Berichts­zusammenfassung**.

---

## Phase 1 – JETZT (kein Audio, keine In-App-Aufnahme)

### Scope-Grenze
- **Nur Upload** vorhandener Dateien über die **Standard-Picker** – nichts wird in der App aufgenommen.
- Typen: **Foto** (Fotobibliothek), **PDF**, **Textdatei**. **Kein Audio → kein STT-Provider nötig.**
- **Mehrere Anhänge** pro Besuch möglich (v. a. Fotos).

### iOS-Platzierung (entschieden)
- **Briefing:** **unter den drei Boxen** eine **weitere Box über die volle Breite** mit **Plus-Symbol**.
- **Besuchsbericht:** **unter den vier Boxen** dieselbe Box – **gleiche Höhe**, volle Breite, Plus-Symbol.
- **Tap** auf die Box → Auswahl **Foto** oder **Datei**:
  - **Foto** → `PHPickerViewController` (`selectionLimit = 0` = mehrere), Filter `.images`.
  - **Datei** → `UIDocumentPickerViewController`, `allowsMultipleSelection = true`,
    Typen `[.pdf, .plainText, .text]`.
- Nach der Auswahl: **Dateinamen/Titel werden in der Box gelistet** (mehrzeilig, je Anhang eine Zeile,
  mit kleinem Typ-Icon 📷/📄/📝 und „×" zum Entfernen). Leerzustand = Plus + „Anhang hinzufügen".
- **Upload:** multipart an das Backend, direkt nach Auswahl.
- **Fortschritt:** derselbe **obere Balken** wie bei der Report-Generierung; Screen pollt den Status.
- **Zustände je Anhang:** „lädt hoch" → „wird analysiert (Balken)" → „bereit" (grüner Haken).

### Backend (Phase 1)
- **Endpunkt** `POST /visits/:id/anhang` (multipart, **mehrere** Dateien) → speichert unter
  `data/visits/<id>/anhaenge/` + stößt Extraktion an. `GET /visits/:id/anhang/status` (Polling wie `/report`).
- **Extraktions-Agent** (`packages/agent`, neuer Schritt `extrahiereAnhang(datei, typ) → AnhangKontext`):
  - **Text** → passthrough.
  - **PDF** → Text extrahieren (`pdf-parse`/`pdfjs`).
  - **Foto** → Vision/OCR (Kernpunkte + erkannter Text). Provider EU-konform wählen.
  - Ergebnis je Besuch als **`anhang-kontext.json`**: Kurz-Zusammenfassung + Kernpunkte je Anhang
    (+ optional erkannte Objekte). Neues **Zod-Schema** in `packages/schemas`.
- **Voice-Grounding:** Worker lädt beim **Doku-/Verfeinerungs**-Gespräch `anhang-kontext.json` und gibt
  ihn dem Agenten mit (analog Briefing/bestehender Bericht).
- **Report-Bezug:** Anhang-Kontext geht in die **Extraktion Phase 2** → fließt in `zusammenfassung`
  (und ggf. neue Objekte). Report-Schema optional um `anhaenge: [...]` (Kurzfassung/Herkunft) erweitern.

### Verify (Phase 1)
- Upload mehrerer Fotos + 1 PDF am Briefing → Dateinamen erscheinen in der Box, Balken läuft, Status „bereit".
- Voice-Gespräch fragt einen im Anhang belegten Punkt **nicht** erneut ab.
- Der Anhang-Inhalt taucht in der `zusammenfassung` des Berichts auf.
- Backend-Tests (Zod-Schema `anhang-kontext`, Extraktion Text/PDF) grün.

---

## Phase 2 – GO-LIVE (später)

- **Audio:** Import **und** In-App-Aufnahme (`AVAudioRecorder`) → **STT** (EU: Whisper-Self-Host /
  Deepgram-EU / xAI). Audio nach Extraktion löschen (Kosten/Residenz).
- **Getippte Notiz** direkt in der App (kleiner Composer) als eigener Anhang-Typ.
- **Anhang-Herkunft im Bericht** sichtbar (Feld `anhaenge` mit Vorschau), inkl. Öffnen/Löschen.
- **Persistenz/Offline:** Anhänge lokal (SwiftData) cachen + Upload-Queue offline (wie Freigabe-Queue).
- **Vorschau in der App:** Thumbnail/Quick-Look pro Anhang.

---

## Mockups
Siehe [docs/mockups-anhang-upload.html](../docs/mockups-anhang-upload.html) – Platzierung der
Plus-Box (Briefing/Bericht) + oberer Analyse-Balken.
