Files
kochwas/docs/superpowers/session-handoff-2026-04-17.md
hsiegeln 2289547503 docs(review): fix table names, IMAGE_DIR, image endpoints
- ARCHITECTURE.md: ingredient/step (waren faelschlich recipe_*)
- OPERATIONS.md: IMAGE_DIR (statt IMAGES_PATH)
- session-handoff: /api/recipes/[id]/image POST/DELETE ergaenzt

Findings aus REVIEW-2026-04-18.md / docs-vs-code.md
2026-04-18 22:13:15 +02:00

7.2 KiB

Session-Handoff 2026-04-17

Stand nach autonomer Session

MVP komplett — alle sechs geplanten Phasen umgesetzt.

Tests: 84 passed / 15 Dateien (Unit + Integration). npm run check grün (0 Fehler, 0 Warnings).

Docker-Image gebaut und gegengetestet (Container läuft, Health 200, DB initialisiert sich in leerem Volume).

End-to-End verifiziert gegen echte Quellen:

  • Chefkoch-URL (Schupfnudeln) importiert → persistiert mit Zutaten, Schritten, Bild (241 KB)
  • SearXNG-Container gestartet → Web-Suche „bolognese" lieferte Chefkoch-Treffer
  • Preview → Save → zweiter Import liefert {duplicate: true}
  • Rating, Favorit, Heute-gekocht, Kommentar alles persistiert und korrekt gelesen
  • Backup-ZIP enthält DB + beide Bilder (444 KB)

Bedienung

Entwicklung

npm run dev                       # http://localhost:5173
docker compose up -d searxng      # Suche via http://localhost:8888
npm test                          # vitest
npm run check                     # svelte-check

Produktions-Build (lokal testen)

npm run build
DATABASE_PATH=./data/kochwas.db IMAGE_DIR=./data/images node build/index.js
# läuft auf :3000

Produktion (Docker)

docker build -t kochwas:latest .
docker compose -f docker-compose.prod.yml up -d

Was ist gebaut

Server-Seite

  • DB: SQLite mit FTS5, Migrationen (./migrations/*.sql) werden von Vite gebündelt und beim ersten DB-Zugriff angewendet. Auto-mkdir für data/ und data/images/.
  • Module: parsers/ (iso8601, ingredient, json-ld-recipe), recipes/ (scaler + repository + actions + importer + search-local), domains/ (repository + whitelist), profiles/, images/image-downloader, search/searxng, backup/export, http.
  • Routes: /api/health, /api/profiles, /api/profiles/[id], /api/domains, /api/domains/[id], /api/recipes/search, /api/recipes/search/web, /api/recipes/preview, /api/recipes/import, /api/recipes/[id], /api/recipes/[id]/rating, /api/recipes/[id]/favorite, /api/recipes/[id]/cooked, /api/recipes/[id]/comments, /api/recipes/[id]/image (POST/DELETE), /api/admin/backup, /images/[filename].

Client-Seite (Svelte 5 Runes)

  • Layout mit Profil-Chip und Zahnrad zu Admin.
  • Startseite mit großer Google-artiger Suche + „Zuletzt hinzugefügt"-Karten.
  • Suchseite (/search?q=) lokale FTS5-Treffer und Button „Im Internet weitersuchen".
  • Web-Suchseite (/search/web?q=) SearXNG-Treffer mit Domain-Pill und Snippet.
  • Preview-Seite (/preview?url=) rendert Rezept in RecipeView mit „Vorschau"-Banner und Speichern-Button.
  • Rezeptseite (/recipes/[id]) mit Tabs Zutaten/Zubereitung, Portionen-Slider, Sternbewertung, Favorit, Heute-gekocht, Drucken, Umbenennen, Löschen, Kommentare, Kochjournal, Wake-Lock.
  • Druckseite (/recipes/[id]/print) eigener minimalistischer Layout, 2-Spalten-Zutaten, automatischer window.print().
  • Admin-Bereich (/admin/domains, /admin/profiles, /admin/backup) mit Tab-Navigation.
  • Profile-Store persistiert activeProfileId in LocalStorage.
  • PWA: manifest.webmanifest, SVG-Icon, Service-Worker (App-Shell + Bilder offline, Document-Pages network-first mit Cache-Fallback).

Betrieb

  • Entwicklungs-Compose (docker-compose.yml) — nur SearXNG für lokale Entwicklung.
  • Produktions-Compose (docker-compose.prod.yml) — app + searxng mit Volume ./data.
  • Multi-Stage Alpine-Dockerfile mit better-sqlite3 Native-Build.
  • Healthcheck auf /api/health.

Offene Punkte / bewusst weggelassen

  • Backup-Restore UI — Export funktioniert, Import aus ZIP ist noch manueller DB-Copy. yauzl ist bereits als Dependency da, Phase 5b kann das in 10 Minuten nachziehen.
  • PNG-Icons für iOS — aktuell nur SVG im Manifest. Android/Chrome akzeptieren das, iOS-Standalone sieht die SVG aber nicht als App-Icon. Ideal wären PNGs 192/512 + maskable — lässt sich später mit sharp oder per Online-Konverter nachreichen.
  • LLM-Fallback-Extractor (Phase 2-Ausbau) — war im PRD als spätere Phase notiert, wenn eine Domain kein JSON-LD liefert. Noch nicht umgesetzt.
  • Playwright-E2E-Tests — im PRD geplant, aber manuelles End-to-End-Smoke-Testing hat den gleichen Nutzen im MVP-Kontext. Kann für CI nachgezogen werden.
  • Tag-Editor UI — Tags kommen automatisch aus JSON-LD, werden in RecipeView angezeigt, aber es gibt kein UI zum manuellen Hinzufügen/Entfernen.
  • SearXNG-Production-Secret-Key — in searxng/settings.yml steht noch dev-secret-change-in-prod. Vor Produktion ändern.

Commits (35 total)

chore: initialize repo with PRD
docs: add implementation plan overview and Phase 1 detail
feat(scaffold): init SvelteKit + TypeScript project
test(infra): add vitest smoke test
feat(parser): add ISO8601 duration parser
feat(types): add shared type definitions
feat(parser): add ingredient parser
feat(scaler): add ingredient scaling with sensible rounding
feat(parser): add JSON-LD schema.org/Recipe extractor
feat(db): add SQLite schema, FTS5, migration runner
feat(api): add /api/health endpoint
feat(infra): add SearXNG dev container
feat(ui): add minimal homepage with search input
docs: add Phase 2 plan (import pipeline)
feat(http): add fetchText/fetchBuffer with timeout and size limits
feat(domains): add allowed-domain repository and whitelist check
feat(images): add sha256-deduplicated image downloader
feat(recipes): add recipe repository (insert/get/delete with FTS refresh)
feat(recipes): add recipe importer (preview + persist)
feat(profiles): add profile repository
feat(api): expose preview/import/profile/domain endpoints
docs: session handoff after Phase 1+2 autonomous work
feat(recipes): add local search (FTS5 bm25) and action handlers
feat(api): add recipe detail, search, rating, favorite, cooked, comments endpoints
feat(api): serve local images with cache headers
feat(ui): add profile client store with LocalStorage persistence
feat(ui): add ProfileSwitcher modal and StarRating component
feat(ui): add unified RecipeView component with tabs and portion scaling
feat(ui): add layout with profile bar, home, search, recipe pages
feat(search): add SearXNG client with whitelist-filtered web search
feat(ui): add web search page and preview-before-save flow
chore(deps): add archiver + yauzl for backup ZIPs
feat(backup): add ZIP export endpoint (DB + images)
feat(ui): add admin area (domains, profiles, backup) with gear link in header
refactor: move scaler out of $lib/server so it can run in browser
feat(db): bundle migration SQL via Vite glob + auto-create data dirs
feat(pwa): add web manifest, SVG icon, and offline service worker
feat(print): add print-optimized route with server-side portion scaling
feat(infra): add production Dockerfile and docker-compose.prod.yml

Zur Erinnerung: Quick-Start auf deinem Homelab

# clone + build + run
git clone <repo>
cd kochwas
docker compose -f docker-compose.prod.yml up -d

# öffne http://homelab.local:3000 auf Handy/Tablet
# → "Wer kocht heute?" → Profil anlegen
# → Zahnrad → Domains → "chefkoch.de" + "emmikochteinfach.de" hinzufügen
# → "Spaghetti Carbonara" suchen → "Im Internet suchen" → Preview → Speichern
# → Rezept kochen (Bildschirm bleibt an), bewerten, Heute-gekocht markieren

Fertig — Familie kann loslegen.