# CLAUDE.md — Klarbild Arbeitsanweisung für den bauenden Agenten. Führend: `01-anforderungen.md` (Was), `06-technik-und-api.md` (Wie), `03-datenmodell-api.md` (Schema/Endpunkte), `07-repo-und-deployment.md` (Struktur/Deploy). Diese Docs liegen im Handover-Ordner `Imagetool-Lea/` (00,01,03,06,07; 02/04/05 stehen noch aus). ## Stack (fest) Astro 5 (`@astrojs/node`, `output: server`) + React-Inseln · Postgres · S3 (MinIO) · pg-boss (Worker im selben Prozess, `worker.ts`) · sharp · grammY · argon2 · AES-256-GCM. Kein Tailwind. OKLCH-Tokens in `src/styles/tokens.css`. Gitea → Coolify → Hetzner. ## Konventionen - Commits **englisch**, `feat:`/`fix:`, **ein Commit je Bauschritt** (kein Riesen-Commit). - Migrationen als nummerierte SQL in `migrations/`, beim Start automatisch (kein ORM-Push). - **Niemals committen:** OpenRouter-Key, Picdrop-Zugang, Telegram-Token, SESSION_SECRET. Vor Push prüfen: `git log -p | grep -iE "sk-or-|password|token"`. - Bild-API: **`POST https://openrouter.ai/api/v1/images`** (nicht chat/completions). `aspect_ratio` **oder** `resolution`, nie beides. `background:"transparent"` fürs Freistellen. `usage.cost` je Position speichern → echter Kostendeckel. - Pipeline lokal mit **sharp**: `px = round(cm/2.54*dpi)`, `fit:'cover', position:'attention'`, `withMetadata({ density: dpi })`. Sticker-Kontur aus Alpha (Dilatation), ohne Modell. - Fortschritt per Polling (2s) oder SSE, **kein WebSocket**. ## Bau-Reihenfolge (je Schritt ein Commit) 1. **Fundament** (fertig): Struktur, `001_init.sql`, db/crypto/auth/storage/openrouter, Middleware, `/api/health`, Login, Seeds, Dockerfile, Tokens. 2. **Bildkern:** `pipeline.ts` (sharp, Formatberechnung, Kontur), `queue.ts` + `worker.ts` (pg-boss), Verarbeitungskette je Position, Dateinamen-Vorschlag. 3. **Studio-UI:** Upload (Datei/DnD/Paste, HEIC, 100 Bilder), Rezept-Builder + Gültigkeitsregeln, Format + Beschnitt-Vorschau, Queue-Ansicht, Ergebnisse (Vorher/Nachher, Download/ZIP). 4. **Bibliothek/Ordner/Druck/Freigabelinks.** 5. **Picdrop** (`picdrop.ts` FTPS/SFTP) + **Sticker-Kontur**. 6. **Admin** (Key/Picdrop/Modelle/Nutzer/Statistik/Kostendeckel/Voreinstellungen). 7. **Telegram** (`telegram.ts` grammY-Webhook) — **vollwertiger Website-Ersatz**. 8. **Tutorial/How-to (Seite + PDF), PWA.** 9. **Deploy + 10 Nachweise (07 §6)** + Reviews (design-taste-frontend, ui-ux-design-pro, code-review). ## Infra (angelegt) - Repo: `till/klarbild` (privat, Gitea). - Coolify-Projekt **klarbild** `g7qykmucnh9kckoqvjnppgsq`, Env production `v653gw0as7ty44p87m2aj7vz`, Server CX33. - Postgres `nrddt6fyb86lok7nojjcb57v` (DB/User `klarbild`), interner Host = DB-UUID:5432. - MinIO: als Compose-Dienst (steht noch aus, S3_* in .env). - Telegram-Token vorhanden (Prototyp @Klarbildbot läuft per Polling bis Umschaltung auf Webhook). ## Nachweis „fertig" (07 §6) — erst danach „lauffähig" melden docker build ok · /api/health grün · beide Logins, Lea ohne /admin · Poster 30×40 = exakt 3543×4724 @300dpi · Sticker mit Alpha + weißer Kontur · 20er-Stapel überlebt Browser-Neustart · Position einzeln wiederholbar · Picdrop-Test grün · 20 Bilder an Bot → ein Auftrag, eine Rückmeldung · Kostendeckel greift.