Files
kochwas/docs/superpowers/session-handoff-2026-04-17.md
2026-04-17 15:13:43 +02:00

4.2 KiB

Session-Handoff 2026-04-17

Stand nach autonomer Session

Phasen abgeschlossen: 1 (Foundations) + 2 (Import Pipeline) — geplant waren für die 2h-Session eigentlich nur die Foundations.

Tests: 65 passed / 12 Dateien (Unit + Integration). npm run check grün.

End-to-End smoke-getestet mit echter Chefkoch-URL: Rezept wurde geladen, geparst, Bild heruntergeladen, in SQLite gespeichert. Zweiter Import derselben URL liefert { duplicate: true }.

Erste Schritte zum Testen

cd C:/Users/Hendrik/Documents/projects/kochwas
npm run dev        # läuft auf http://localhost:5173 (oder 5174/5175 wenn belegt)

In einem zweiten Terminal:

# Health
curl http://localhost:5173/api/health

# Profil anlegen
curl -X POST -H "content-type: application/json" \
  -d '{"name":"Hendrik","avatar_emoji":"🍳"}' \
  http://localhost:5173/api/profiles

# Chefkoch zur Whitelist hinzufügen
curl -X POST -H "content-type: application/json" \
  -d '{"domain":"chefkoch.de","display_name":"Chefkoch"}' \
  http://localhost:5173/api/domains

# Rezept importieren
curl -X POST -H "content-type: application/json" \
  -d '{"url":"https://www.chefkoch.de/rezepte/4094871643016343/Selbstgemachte-Schupfnudeln.html"}' \
  http://localhost:5173/api/recipes/import

SearXNG-Container für Phase 4:

docker compose up -d searxng    # JSON-API auf http://localhost:8888/search?q=...&format=json
docker compose down

Was ist gebaut

Phase 1 — Foundations

  • SvelteKit 2 + TypeScript strict + Node-Adapter
  • SQLite-Schema mit FTS5 (alle Tabellen aus dem PRD)
  • Migrationen ausgeführt beim ersten DB-Zugriff
  • Parser: ISO8601-Duration, Zutaten, schema.org/Recipe JSON-LD
  • Skalierer mit vernünftiger Rundung
  • Gemeinsame Types (src/lib/types.ts)
  • Health-Endpoint /api/health
  • Startseite mit Suchfeld (Formular-Submit auf /search, Route folgt in Phase 3)
  • Docker-Compose für SearXNG (dev)
  • .gitattributes für LF-Line-Endings (Windows-friendly)

Phase 2 — Import Pipeline

  • HTTP-Wrapper mit Timeout + Max-Size + UA
  • Whitelist-Domain-Repository + isDomainAllowed
  • Image-Downloader (SHA256-Dateinamen, dedupliziert, best-effort)
  • Recipe-Repository (insert/get/delete mit FTS-Refresh via Trigger)
  • Recipe-Importer (previewRecipe, importRecipe, Idempotenz)
  • Profile-Repository
  • API-Endpoints: /api/profiles (GET/POST/PATCH/DELETE), /api/domains (GET/POST/DELETE), /api/recipes/preview (GET), /api/recipes/import (POST)
  • ImporterError mit Codes (DOMAIN_BLOCKED → 403, NO_RECIPE_FOUND → 422, etc.)

Offen für Phase 3+ (noch nicht geplant im Detail)

  • UI: RecipeView-Komponente, /search-Seite, Profile-Switcher, /recipes/[id]-Ansicht
  • Rating / Favoriten / Kochjournal / Kommentare — Endpunkte + UI
  • Drucken, Umbenennen, Löschen in der UI
  • SearXNG-Anbindung + Preview-Flow
  • Admin-Seiten (/admin/domains, /admin/profiles, /admin/backup)
  • PWA: Service-Worker, Wake-Lock, Install-Prompt
  • Produktions-Docker-Image
  • E2E-Tests mit Playwright (Mobile-Emulation)

Details später — die Overview-Datei docs/superpowers/plans/2026-04-17-kochwas-overview.md listet die Phasen.

Commits dieser Session

21 Commits auf main. git log --oneline zeigt den vollständigen Verlauf. Jeder Commit ist atomar (eine Funktion / ein Feature / ein Testblock).

Dinge, die aufgefallen sind

  • Fixtures: Die URLs, die ich im Plan angenommen hatte (Carbonara auf Chefkoch, Zucchinipuffer auf Emmi), waren beide 404. Ersetzt durch „Selbstgemachte Schupfnudeln" (Chefkoch) und „Bolognese-Rezept" (Emmi). Tests wurden entsprechend angepasst.
  • better-sqlite3 ist nativ — Windows-Binary wird beim npm install gebaut. Das dauerte etwa 10s, lief aber durch.
  • SvelteKit-Port springt auf 5174/5175, falls 5173 belegt ist. Nicht kritisch, nur gut zu wissen.
  • FTS5-Trigger: die Ingredient-/Tag-Änderungen triggern nur updated_at auf recipe, nicht direkt FTS. Das recipe AFTER UPDATE-Trigger baut dann ingredients_concat und tags_concat neu. In insertRecipe wird deshalb am Ende UPDATE recipe SET title = title WHERE id = ? ausgelöst, damit der Trigger feuert.
  • data/ ist in .gitignore, enthält kochwas.db + images/. Nach dem Smoke-Test wieder vorhanden mit dem ersten Rezept.