81 lines
6.6 KiB
Markdown
81 lines
6.6 KiB
Markdown
# Kochwas — Hinweise für Claude (Fortsetzung nach Session-Neustart)
|
|
|
|
> **Lies mich zuerst.** Wenn du eine neue Session öffnest und hier weiterarbeitest, steht hier das Wesentliche. Tiefer: `docs/ARCHITECTURE.md` (Code) und `docs/OPERATIONS.md` (Deployment).
|
|
|
|
## Was das ist
|
|
Selbstgehostete Rezept-PWA für die Familie Siegeln. Erreichbar unter `https://kochwas.siegeln.net`. Deutschsprachiges UI, ohne Login, Profile werden per Klick gewählt. Läuft in Docker auf einem Raspberry Pi 5 (arm64).
|
|
|
|
## Wichtigste Gotchas (wiederkehrende Stolpersteine)
|
|
|
|
| Thema | Regel |
|
|
|---|---|
|
|
| **Node-Binding** | `better-sqlite3` ist **synchron** und native — im `Dockerfile` gibt es einen Build-Stage, der das Native-Module explizit für arm64 baut. |
|
|
| **Healthcheck** | Muss `127.0.0.1` verwenden, nicht `localhost`. Node bindet nur IPv4; `localhost` wird oft zu `::1` aufgelöst und der Check schlägt fehl. Traefik filtert unhealthy Container raus → kein Routing, kein ACME. |
|
|
| **SearXNG Bot-Detection** | Bei Requests aus dem Docker-Netzwerk müssen `X-Forwarded-For: 127.0.0.1` und `X-Real-IP: 127.0.0.1` im Header stehen (`src/lib/server/http.ts` `extraHeaders`). Sonst 403. |
|
|
| **Traefik Cloudflare-Token** | Token muss `Edit zone DNS` Berechtigung für `siegeln.net` haben. Expired Tokens → DNS-Challenge failt → Let's-Encrypt-Rate-Limit nach 5 Versuchen in 1 h. |
|
|
| **Wildcard-Cert** | Für neue Subdomains auf siegeln.net sollten die Labels das Wildcard nutzen, nicht per-Host-Cert: `tls.domains[0].main=siegeln.net` + `sans=*.siegeln.net`. |
|
|
| **Migrations** | Werden via Vite `import.meta.glob('./migrations/*.sql', {eager, query:'?raw'})` gebundelt. Neue Migration einfach als `00N_name.sql` ablegen, kein Copy-in-Dockerfile nötig. |
|
|
| **$lib/server in Client** | Svelte-Import aus `$lib/server/*` in einem `.svelte`-Komponenten-Script bricht den Build. Pures JS/TS, das beidseitig funktioniert (z. B. Portionen-Scaler), gehört nach `$lib/`, nicht `$lib/server/`. |
|
|
| **Preview-Bilder** | `recipe.image_path` kann **absolute URL** (Preview-Modus) oder **lokaler Filename** sein. `RecipeView.svelte` prüft mit `/^https?:\/\//i`. |
|
|
| **Service Worker nur ab HTTPS** | `npm run dev` liefert HTTP → SW registriert nicht. Für PWA-Tests `npm run build && npm run preview` (localhost) oder Prod-Docker. |
|
|
| **Icon-Rendering** | `npm run render:icons` rendert `icon-192.png` + `icon-512.png` aus `static/icon.svg`. Nur nach SVG-Änderung erneut ausführen + committen. |
|
|
| **Gemini-Key fehlt** | Wenn `GEMINI_API_KEY` leer ist, rendert das Layout das Camera-Icon nicht, und `/new/from-photo` antwortet mit 503 (`+page.server.ts`-Gate). Graceful Degradation — kein Zombie-Button. |
|
|
| **sharp + libheif** | Im `Dockerfile`-Builder-Stage ist `vips-dev` nötig, damit `sharp` HEIC-Input (iOS) lesen kann. Runtime-Stage braucht nix zusätzlich (sharp bringt libvips prebuilt mit). |
|
|
|
|
## Dateien, die man typischerweise anfasst
|
|
|
|
- `src/routes/+page.svelte` — Startseite mit Live-Search + Quote
|
|
- `src/routes/+layout.svelte` — Header, mobile expand, Dropdown-Search auf Rezeptseiten
|
|
- `src/routes/recipes/[id]/+page.svelte` — Rezept-Detail mit allen Actions (Rating, Favorit, Cooked, Wunschliste, Kommentar, Umbenennen, Löschen)
|
|
- `src/routes/preview/+page.svelte` — importierte Vorschau vor dem Speichern
|
|
- `src/routes/new/from-photo/+page.svelte` — Foto-Rezept-Magie (Picker → Spinner → vorbefüllter Editor)
|
|
- `src/lib/server/ai/` — Gemini-Client, Prompt-Schema, image-preprocess, rate-limit, description-phrases
|
|
- `src/lib/components/RecipeView.svelte` / `RecipeEditor.svelte` — Lesen/Edit-Mode des Rezepts. Editor ist in Sub-Components aufgeteilt: `IngredientRow`, `StepList`, `ImageUploadBox`, `TimeDisplay` (+ shared types `recipe-editor-types.ts`)
|
|
- `src/lib/server/search/searxng.ts` — Web-Suche + Thumbnail-Enrichment + SQLite-Cache
|
|
- `src/lib/server/recipes/importer.ts` — JSON-LD → Recipe, orchestriert Bild-Download
|
|
- `src/lib/server/db/migrations/*.sql` — Schema; bei Änderung immer **neue** Migration statt bestehende bearbeiten
|
|
- `src/service-worker.ts` — Service-Worker-Orchestrator (Shell-Cache + Pre-Cache + SWR)
|
|
- `src/lib/sw/` — reine Logik (Cache-Strategy-Entscheider, Diff-Manifest) für Unit-Tests
|
|
- `src/lib/client/*.svelte.ts` — Frontend-Stores (Search, Network, Sync-Status, Toast, Install-Prompt, Wishlist, PWA, Profile, Confirm, Search-Filter)
|
|
- `tests/e2e/remote/` — Playwright gegen `kochwas-dev.siegeln.net` (CRUD erlaubt; workers:1, serviceWorkers:block)
|
|
|
|
## Arbeitsweise (wie wir es machen)
|
|
|
|
- **Terse Antworten auf Deutsch**; Code-Kommentare auf Englisch, sparsam.
|
|
- **Commits** kleinteilig, deutscher Body, englische Zeile, Subject unter 72 Zeichen.
|
|
- **Tests nach jeder Änderung**: `npm test` (vitest) + `npm run check` (svelte-check). Beides muss grün sein, bevor gepusht wird.
|
|
- **Push nach jedem Commit**, außer der Nutzer sagt explizit nein. CI baut dann das arm64-Image und published es nach `gitea.siegeln.net/claude/kochwas:latest`.
|
|
- **Keine Backwards-Compat-Krücken** für nicht-ausgelieferten Code. Direkt refactoren, alte Signaturen raus.
|
|
- **Nie mit `--no-verify`** committen. Wenn ein Hook fehlschlägt, den echten Grund beheben.
|
|
|
|
## Quickstart
|
|
|
|
```bash
|
|
npm install # erstes Mal
|
|
npm run dev # lokal auf http://localhost:5173
|
|
npm test # volle Vitest-Suite
|
|
npm run check # svelte-check Types
|
|
npm run format # Prettier
|
|
```
|
|
|
|
Lokaler Docker-Test des Prod-Builds:
|
|
```bash
|
|
docker compose -f docker-compose.prod.yml up --build
|
|
```
|
|
|
|
## Was NICHT tun
|
|
|
|
- Keine neuen Top-Level-Docs erzeugen, wenn ein bestehendes Dokument (Specs, Plans, ARCHITECTURE, OPERATIONS) passt.
|
|
- Keine Emojis in Code/Commits — außer UI-Icons (🍽️, ⚙️, 🥘 etc.) sind explizit im UX-Design.
|
|
- Keine `alert()`/`confirm()` — wir haben `alertAction()` / `confirmAction()` in `src/lib/client/confirm.svelte.ts`.
|
|
- Keine hardcoded `localhost` in Healthchecks → `127.0.0.1`.
|
|
- Keinen sensiblen Output in Commits (Cloudflare-Tokens, acme.json).
|
|
|
|
## Offene Themen / Stand
|
|
|
|
Siehe die Plan-Dateien unter `docs/superpowers/plans/*.md` für abgeschlossene Implementierungs-Phasen (v1.0 Foundations → v1.1 Offline-PWA → Post-Review-Roadmap → Search-State-Store → Editor-Split → Ingredient-Sections = v1.2). Was als „Later" markiert ist, ist nicht beauftragt.
|
|
|
|
## Auto-Memory (lokal, nicht im Repo)
|
|
|
|
Persönliche Präferenzen / projektspezifische Entscheidungen landen in deinem Auto-Memory unter `~/.claude/projects/C--Users-Hendrik-Documents-projects-kochwas/memory/`. Der aktuelle Index (`MEMORY.md`) hält fest: Deployment-Target, Registry. Bei Bedarf erweitern — nicht in dieser Datei dokumentieren, da sie versioniert ist.
|