Files
beh-rde-brief/FEATURES.md
T
JUSNandClaude Opus 5.5 6a7f35eb19 Praesentation MBE 29.10.: Handzettel, Musterbrief, Doku
- marketing/praesentation-mbe/handzettel: A4 zum Dalassen (Testzugang
  1 Monat, bis 100 Briefe), QR-Code wird nach Anlegen des Codes eingetragen
- musterbrief-auslaenderbehoerde: erfundene Behoerde/Person, zum Ausdrucken
  und Live-Fotografieren (Frist + Termin + Telefon + Fachbegriffe)
- Testphase im Preisblatt auf 1 Monat + Auswertungsgespraech
- FEATURES.md: Handy<->PC, Einrichtungs-Codes, lokal testen

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-22 18:46:29 +02:00

338 lines
15 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# BehördenKlar — Überblick für Claude
> Stand: 22.10.2026. Diese Datei beschreibt, **was es gibt**.
> Für Release-Stand und offene Aufgaben siehe die Projekt-Erinnerung.
> Für Arbeitsregeln siehe `AGENTS.md` (Expo-Docs vor Code lesen!).
## Worum es geht
BehördenKlar macht **schwierige Post verständlich**: Brief fotografieren →
Klartext in einfacher Sprache (Niveau A2/B1) → Frist erkennen → richtig reagieren.
Nicht nur Ämter, sondern auch **Versicherung, Vermieter, Bank, Inkasso**. Die
Positionierung wurde am 19.09. bewusst verbreitert — weg vom „Hartz-IV"-Bild,
aber ohne die Spezialisierung aufzugeben (das ist der einzige Vorteil gegenüber
DeepL/ChatGPT).
**Zielgruppe:** Menschen, denen Amtsdeutsch schwerfällt — Muttersprachler mit
Leseschwierigkeiten ebenso wie Zugewanderte. Seit der Verbreiterung auch
Selbständige.
**Betreiber:** Webklar GbR (Justin Klein, Kenso Grimm), Kleinunternehmer § 19 UStG
— **keine Umsatzsteuer ausweisen!**
---
## Was BehördenKlar kann, was ein Übersetzer nicht kann
Der Unterschied zu DeepL, Google Translate oder ChatGPT ist **nicht** die
Übersetzung. Es ist, dass aus einem Foto **strukturierte Daten** werden, mit
denen die App dann selbst weiterarbeitet.
### 1. Die KI liest Termine und Fristen heraus — als echte Daten
Nicht als Fließtext, sondern als Felder, mit denen sich rechnen lässt:
| Feld | Was |
|---|---|
| `frist` | Datum (ISO) **+ was konkret zu tun ist** |
| `termin` | Datum, **Uhrzeit**, **Ort** |
| `brieftyp` · `absender` | Wer schreibt, worum geht es |
| `checkliste` | konkrete To-dos |
| `antwort_noetig` | muss überhaupt geantwortet werden? |
| `antwort_optionen` | welche Antworten kommen infrage |
| `fachbegriffe` | schwere Wörter + Erklärung |
**Sicherheitsregel im Prompt:** *„Wenn du ein Datum nicht sicher lesen kannst,
lass das Feld null — erfinde niemals Daten."* Ein halluziniertes Frist-Datum wäre
schlimmer als gar keins.
### 2. Erinnerungen werden **automatisch** gestellt
Sofort nach der Analyse, **ohne dass der Nutzer irgendetwas tut**
(`ScanScreen` → `planeErinnerungen`). Pro Brief bis zu **vier** Benachrichtigungen:
- **3 Tage** und **1 Tag** vor der **Frist**
- **3 Tage** und **1 Tag** vor dem **Termin**
Jeweils morgens um 9 Uhr, mit dem konkreten Text: *„Frist in 3 Tagen: Jobcenter —
bis 30.09.: Unterlagen einreichen"*.
**Das ist das eigentliche Produktversprechen:** Man muss nichts mehr im Kopf
behalten. Ein Übersetzer sagt dir, was dasteht. BehördenKlar meldet sich von
selbst, bevor es zu spät ist.
### 3. Frist und Termin in den Kalender — auch im Web
**App:** `AnalyseScreen` → `terminZumKalender`, auf Tastendruck.
**Web (seit 27.09.):** Nach der Analyse erscheint direkt unter der Frist
„📅 In meinen Kalender eintragen". Der Browser erzeugt eine `.ics`-Datei mit
Frist **und** Termin, jeweils mit Erinnerung **3 Tage und 1 Tag vorher**. Die
Datei entsteht auf dem Gerät und wird **nirgends hochgeladen** — die Erinnerungen
stellt danach der Kalender des Handys selbst. Funktioniert ohne App und ohne Konto.
Details, die schiefgehen können und abgesichert sind:
- Zeilen nach **Bytes** gefaltet (RFC 5545: max. 75), nicht nach Zeichen —
Arabisch/Tigrinya brauchen 2–4 Byte pro Zeichen
- Termin um 23:30 endet korrekt am **nächsten** Tag
- Uhrzeit ohne Zeitzone („Wanduhrzeit") = Ortszeit des Geräts
- Titel und Erinnerungstext ohne deutsche Wörter: Symbol + Datum versteht jeder,
die `aktion` kommt schon in der Sprache des Nutzers
**Bewusst nicht vollautomatisch:** Ungefragt in einen fremden Kalender zu
schreiben, wäre übergriffig.
### 3b. Anruf-Hilfe (Web, seit 27.09.)
Die KI liest `kontakt` aus dem Brief — Telefon, Ansprechpartner, Aktenzeichen,
Sprechzeiten — und schreibt einen **Spickzettel** mit 3–5 Sätzen für das Telefonat.
- Telefonnummer als **Anruf-Knopf** (`tel:`)
- Aktenzeichen **hervorgehoben** — danach wird am Telefon zuerst gefragt
- Jeder Satz **auf Deutsch** (so wird er gesagt) und darunter in der Sprache
des Nutzers (damit er versteht, was er sagt)
**Regel im Prompt:** Kontaktdaten nur, wenn sie **wörtlich** im Brief stehen.
Getestet mit einem Brief ohne Telefonnummer → `telefon: null`, nichts erfunden.
Eine falsche Nummer wäre schlimmer als keine.
### 3c. Handy ↔ PC — für die Beratung (seit 22.10.)
Ein QR-Code verbindet zwei Geräte, **Ende-zu-Ende verschlüsselt** (AES-256-GCM).
Schlüssel und Übergabe-ID stehen hinter dem `#` der Adresse, gehen also nie an
einen Server. Der Worker hält nur Chiffrat, höchstens 15 Minuten
(Durable Object `Uebergabe`, Route `/uebergabe/<id>[/<fach>]`).
| Art (`a=`) | Wer zeigt den QR | Was passiert |
|---|---|---|
| `k` Kamera | PC: „Lieber mit dem Handy fotografieren" | Handy fotografiert, Ergebnis erscheint am PC **auf Deutsch** und am Handy **in der Muttersprache** (`auchDeutsch` → Worker analysiert deutsch und übersetzt mit Haiku, kostet 1 Analyse). Guthaben des PCs gilt am Handy nur für diese Sitzung. |
| `m` Mitnehmen | PC: „Ergebnis aufs Handy mitnehmen" | Ergebnis landet auf dem Handy (Browser) bzw. im App-Archiv, einmal abholbar |
| `g` Guthaben | PC: „Auch auf dem Handy nutzen" | Guthaben/Einrichtungs-Zugang dauerhaft aufs Handy (Browser) |
Gleiches Päckchen-Format in `webseite/uebergabe.js` und `src/services/uebergabe.ts`
(IV‖Chiffrat‖Tag, base64url) — Test: `src/utils/__tests__/uebergabe.test.ts`.
**App:** Brief → „Am Computer zeigen" (`a=k`), Archiv → „Vom Computer übernehmen"
(`a=m`), Bildschirm `VerbindenScreen` mit QR-Scanner und Link-Einfügen als Ersatz.
### 3d. Einrichtungs-Codes für Beratungsstellen (seit 22.10.)
Die Einrichtung zahlt, Ratsuchende nicht. Ein Code (z. B. `MBE-K7QX`) zeigt auf
ein Guthaben wie beim Kauf, mit Name und Ablaufdatum. Einlösen per Link
`behoerdenklar.de/demo?code=…` oder Eingabefeld; Banner „Kostenlos über …".
Verwalten mit `node tools/einrichtungs-code.js neu|stand|aufladen|verlaengern`.
Falsche Codes: max. 10 pro IP und Tag.
### 4. Ampel statt Datum
Rot ≤ 7 Tage, gelb ≤ 21, sonst grün. Die Startseite sortiert nach
**Dringlichkeit**, nicht nach Eingang — man sieht sofort, was brennt.
### 5. Antwort-Entwurf
Die KI schlägt vor, *ob* geantwortet werden muss und *welche* Antworten infrage
kommen. Der `AntwortScreen` führt in drei Schritten zum fertigen Text, als PDF
oder zum Teilen.
### 6. Fachbegriffe bleiben deutsch
Bei der Übersetzung wird **nur die Erklärung** übersetzt, der deutsche Begriff
bleibt stehen. Sonst findet man ihn im Original-Brief nicht wieder. Dazu ein
**Amts-Wörterbuch, das offline funktioniert**.
### 7. Ohne Konto, verschlüsselt
Kein Login, keine Registrierung. Briefe liegen AES-256-GCM-verschlüsselt auf dem
Gerät, Schlüssel im SecureStore. Optional App-Sperre und Auto-Löschen nach
30 oder 90 Tagen.
---
## Die drei Teile
| Teil | Was | Wo |
|---|---|---|
| **App** | Vollprodukt, iOS zuerst | `src/`, Expo SDK 57 |
| **Webseite** | Landingpages, Demo, Ratgeber, Bezahlung | `webseite/` → Cloudflare Pages |
| **Worker** | Proxy zur KI, Bezahlung, Limits | `proxy/` → Cloudflare Workers |
Der Worker steht dazwischen, damit **kein API-Schlüssel je auf ein Gerät kommt**.
---
## App (`src/`)
### Bildschirme
| Datei | Zweck |
|---|---|
| `FristenScreen` | Start — Briefe nach **Dringlichkeit**, nicht nach Datum. Countdown-Karte für die nächste Frist |
| `ScanScreen` | Foto oder PDF aufnehmen, verkleinern, hochladen |
| `AnalyseScreen` | Ergebnis: Kernaussage, Erklärung, Ampel, To-do-Liste, Fachbegriffe |
| `AntwortScreen` | Antwort-Assistent in 3 Schritten, Ausgabe als PDF oder zum Teilen |
| `ArchivScreen` | Alle Briefe, verschlüsselt |
| `GlossarScreen` | Amts-Wörterbuch, funktioniert **offline** |
| `EinstellungenScreen` | App-Sperre, Auto-Löschen, Aktions-Code |
| `ConsentScreen` | Einwilligung vor dem ersten Scan (Art. 9 DSGVO) |
Navigation: untere Leiste **Fristen · Scannen (FAB) · Archiv**.
### Funktionen
- **Ampel:** rot ≤ 7 Tage, gelb ≤ 21, sonst grün (`utils/ampel.ts`)
- **27 Zielsprachen** (`types.ts` → `SPRACHEN`), nach Größe der Sprachgemeinschaft
in Deutschland sortiert. Mit `rtl`-Flag für Arabisch, Farsi, Urdu, Paschtu —
ohne das wurden diese Schriften falsch linksbündig dargestellt.
**Der deutsche Fachbegriff bleibt deutsch**, nur seine Erklärung wird übersetzt
(man muss ihn im Brief wiederfinden).
- **Verschlüsseltes Archiv:** AES-256-GCM, Schlüssel im SecureStore (`krypto.ts`)
- **App-Sperre:** Face ID / Geräte-Code, plus Sichtschutz im App-Umschalter
- **Auto-Löschen** nach 30 oder 90 Tagen (`aufbewahrung.ts`)
- **Kalender + Erinnerungen** — siehe oben, das ist das Kernstück
(`kalender.ts`, `erinnerungen.ts`)
- **Vorlesen** über die Gerätestimme — fehlt sie für eine Sprache, passiert nichts
(abgefangen, kein Absturz)
- **3 Gratis-Analysen** (`GRATIS_ANALYSEN` in `storage.ts`), mit Aktions-Code
`FRUEHSTART` sind es 5
- **Kein Konto, kein Login.** Bewusste Entscheidung.
### Modelle
| Zweck | Modell |
|---|---|
| Brief-Analyse (Vision) | `claude-sonnet-5` |
| Übersetzung, Antwort-Entwürfe | `claude-haiku-4-5` |
Getrennt, weil die Analyse Qualität braucht und der Rest nicht — spart etwa
60 % der Kosten pro Brief.
---
## Webseite (`webseite/`)
- **28 Sprachen** (Deutsch + 27). **Nicht von Hand pflegen** — siehe Generator unten.
- **`/demo`** — 2 Gratis-Analysen im Browser, ohne Konto. Mit **Sprachauswahl**:
die Erklärung kommt in der gewählten Sprache.
- **Bezahlung** auf Startseite, Demo-Seite und **allen 27 Sprachseiten**
- **13 Ratgeber** unter `/ratgeber/` — Jobcenter, Finanzamt, Ausländerbehörde,
Widerspruch, Nebenkosten, Versicherung, Inkasso, Bußgeld, Kündigung u. a.
Jeder mit FAQ-Schema und Musterbrief.
- **4 Rechtsseiten:** AGB, Widerruf, Impressum, Datenschutz (alle `noindex`)
- **Warteliste** über Brevo (Double-Opt-in)
### Sprachseiten-Generator — WICHTIG
```bash
node tools/sprachseiten/build.js
```
Erzeugt **alle 27 Sprachseiten** aus `vorlage.html` + `texte.js`, pflegt hreflang
und Sprachwähler in der handgemachten `index.html` nach und schreibt die
`sitemap.xml`.
**Einzelne Sprachdateien niemals direkt bearbeiten** — sie werden überschrieben.
Änderungen gehören in `vorlage.html` (Aufbau) oder `texte.js` (Texte).
> Die Übersetzungen stammen von Claude. Bei Tigrinya, Somali, Paschtu und
> Kurdisch sollte vor größerer Werbung jemand mit Muttersprache gegenlesen.
---
## Worker (`proxy/src/index.ts`)
| Route | Zweck |
|---|---|
| `/` | App-Proxy zur Anthropic-API (Modell-Whitelist, Tageslimits) |
| `/demo` | Web-Demo — Turnstile, Gratis-Kontingent, **Zielsprache**, Guthaben |
| `/kaufen` | Stripe-Bezahlseite erzeugen |
| `/kauf-status` | Nach Rückkehr: Zahlung prüfen, Guthaben freischalten |
| `/stripe-webhook` | Sicherungsnetz + Wiederherstellungs-Mail |
| `/code` | Einrichtungs-Code einlösen → signiertes Guthaben-Token |
| `/uebergabe/<id>` | Handy ↔ PC: verschlüsselte Päckchen (Durable Object, 15 Min.) |
### Bezahlung (LIVE, echtes Geld)
- **Guthaben statt Abo:** 5 Analysen 2,99 € · 15 Analysen 6,99 €
- **Ohne Konto:** Guthaben liegt server-seitig in KV (`wallet:<id>`), der Browser
bekommt einen **signierten Nachweis** (HMAC). Die Zahl im Browser ist nur
Anzeige — gerechnet wird auf dem Server.
- **Wiederherstellung** per E-Mail-Link (`?wallet=…`) — wirkt wie ein Gutscheincode
- **Pflicht-Häkchen** = Widerrufsverzicht nach § 356 Abs. 5 BGB
- **Kartenzahlung fest vorgegeben** (`payment_method_types[0]=card`). Schaltet
Stripe Link ab — das zeigte eine englische Ansicht mit winzigem
„Pay without Link", eine Sackgasse für die Zielgruppe.
⚠️ Solange das gesetzt ist, erscheinen **keine** weiteren Methoden. Wer PayPal
will: erst im Dashboard freischalten, **dann** hier ergänzen — sonst scheitert
der Kauf komplett.
- **Bezahlseite in der Nutzersprache** über `locale`. Nur Sprachen aus
`STRIPE_SPRACHEN` werden geschickt; ein unbekannter Wert lässt Stripe die
Session mit 400 ablehnen.
### Schutz vor Missbrauch
| Schutz | Wert |
|---|---|
| Turnstile | Sitekey `0x4AAAAAAESi2p41B915R4hW` (an die Domain gebunden!) |
| App: pro Gerät / pro IP | 20 / 100 pro Tag |
| Demo: Gesamtbudget / pro IP | 100 / 8 pro Tag |
| Origin-Prüfung | nur `behoerdenklar.de` darf kaufen |
### Secrets (`npx wrangler secret put …`)
`ANTHROPIC_API_KEY` · `STRIPE_SECRET_KEY` (`rk_live_`, eingeschränkt) ·
`STRIPE_WEBHOOK_SECRET` · `TOKEN_SIGNING_SECRET` · `TURNSTILE_SECRET_KEY` ·
`BREVO_API_KEY`
**Niemals in den Chat oder in Dateien.** Ist zweimal passiert, beide Male musste
rotiert werden.
---
## Befehle
```bash
npm run pruefung # Gesundheits-Check — nach JEDEM Deploy
npm test # 43 Tests
npx tsc --noEmit # Typen
node tools/sprachseiten/build.js # Sprachseiten neu bauen
```
**Lokal testen** (ohne live zu gehen): in `/Users/homefolder/Behörden_App/.claude/launch.json`
`proxy-worker` (Port 8799, `.dev.vars` mit `LOKAL_TEST=1` und Turnstile-Testschlüssel)
+ `webseite` (Port 4173) starten, dann `http://localhost:4173/demo.html`. Auf
localhost nimmt die Seite automatisch den lokalen Worker und den Test-Sitekey.
**Deploy:**
```bash
cd proxy && npx wrangler deploy # Worker
cd proxy && npx wrangler pages deploy ../webseite --project-name behoerdenklar --commit-dirty=true # Webseite
```
**Committen ist nicht veröffentlichen** — nur Deployen macht live. Das wurde
schon einmal verwechselt, die Google-Verifizierung lag wochenlang nur im Git.
**Nach jedem Commit auf beide Remotes pushen:**
`git push origin main && git push gitea main`
### `npm run pruefung`
Prüft in ~30 Sekunden zehn Bereiche — jeder war schon einmal **still** kaputt:
abgeschnittene Zeilen `[...]`, Warteliste-Formular, JSON-LD, tote Dateiverweise,
Preis-IDs, Sitemap-Adressen, Kauf, Webhook-Secret, KI-Schlüssel, Turnstile.
Hintergrund: Das Warteliste-Formular war **sechs Wochen** kaputt, ohne dass
etwas Alarm geschlagen hätte.
---
## Fallen, die schon zugeschnappt sind
- **Ein Werkzeug kürzte Zeilen auf 200 Zeichen** und hängte `[...]` an. Traf die
Brevo-Formular-Adresse → Anmeldungen gingen ins Leere. `npm run pruefung`
findet das.
- **Turnstile ist an die Domain gebunden.** Nach dem Domain-Umzug blockierte das
alte Widget die Demo.
- **Der Anthropic-Schlüssel wurde zweimal ohne Zutun ungültig.** Die App war
tagelang kaputt, bevor es auffiel.
- **Die Web-Demo konnte lange nur Deutsch** — während 27 Sprachseiten
Übersetzung versprachen. Immer prüfen, ob das Produkt hält, was die Seite sagt.
- **expo-image-picker meldet standardmäßig `RECORD_AUDIO` an.** Abgeschaltet über
`microphonePermission: false`; die App nimmt nur Fotos auf.
---
## Rechtliches
AGB, Widerrufsbelehrung, Datenschutz und Impressum sind **live** und auf Webklar
GbR ausgestellt. Sie sind **Entwürfe von Claude** — eine anwaltliche oder
IHK-Prüfung steht aus.
**Kleinunternehmer § 19 UStG:** nirgends „inkl. USt." schreiben. Die Steuernummer
gehört nicht ins öffentliche Impressum.
Der Wiederherstellungs-Link wirkt wie ein Gutscheincode — wer ihn hat, nutzt das
Guthaben. Steht so in den AGB.
**Keine Rechtsberatung.** Steht in jedem Ratgeber, in der App und in den AGB —
das muss so bleiben.