Files
kochwas/docs/superpowers/review/REVIEW-2026-04-18.md
hsiegeln 10c43c4d4a
All checks were successful
Build & Publish Docker Image / build-and-push (push) Successful in 31s
docs(review): Deep-Code-Review 2026-04-18
Vier parallele Review-Passes (Dead-Code, Redundanzen, Struktur,
Docs-vs-Code) plus konsolidierter Hauptreport. Nur Dokumentation —
keine Code-Änderungen. Tests 158/158 grün beim Review-Start.

Haupt-Findings:
- ARCHITECTURE.md:55 nennt falsche Tabellennamen
  (recipe_ingredient/recipe_step statt ingredient/step)
- parseId in 9 API-Handlern dupliziert
- Page-Komponenten teils >750 Zeilen
- yauzl installiert aber ungenutzt (für Phase 5b reserviert)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-18 21:55:41 +02:00

8.1 KiB
Raw Permalink Blame History

Deep Code Review — Kochwas

Datum: 2026-04-18 Stand: commit 5283ab9 auf main Testsuite beim Start: 158/158 grün Scope: src/ (~97 Dateien), Migrations, Tests, Docker-Setup, alle Docs unter docs/


TL;DR

Der Code ist gesund. Keine toten Pfade, keine broken Features, keine strukturellen Fehlentscheidungen. Die vier auffälligsten Themen sind alle Natural-Growth-Pressure aus der v1.x-Phase, keine Fehler:

  1. Ein echter Doku-Bug: docs/ARCHITECTURE.md:55 sagt recipe_ingredient + recipe_step — die Tabellen heißen in Wirklichkeit ingredient / step (siehe 001_init.sql). 5-Minuten-Fix.
  2. API-Handler duplizieren parseId neunmal. Kandidat #1 für einen src/lib/server/api-helpers.ts.
  3. Page-Komponenten sind groß geworden (+page.svelte 808 Zeilen, recipes/[id]/+page.svelte 757 Zeilen). Solange du allein dran arbeitest: akzeptabel. Sobald jemand mitprogrammiert: refactor.
  4. yauzl / @types/yauzl sind installiert, aber nicht importiert. Reserviert für den noch fehlenden ZIP-Backup-Import. Entweder im Session-Handoff verankert lassen oder als Phase ziehen.

Keine Sicherheits- oder Performance-Probleme im Code-Review aufgetaucht. Keine Reviewer-Korrekturen an der Architektur-Grundlinie (Server/Client-Trennung, Repository-Pattern, Runes-Stores).


Quick-Wins (≤ 30 min pro Stück)

# Titel Aufwand Wert
1 ARCHITECTURE.md:55 auf ingredient + step korrigieren 2 min hoch (sonst debuggt jemand Geisterschema)
2 OPERATIONS.md:135 IMAGES_PATHIMAGE_DIR 2 min niedrig, aber trivial
3 parseId zentralisieren (src/lib/server/api-helpers.ts) 20 min hoch — 9 Call-Sites
4 Unit-Test für parseId-Helper 10 min hoch — fängt zukünftige Regressionen
5 requireProfile()-Helper in recipes/[id]/+page.svelte (Zeilen 124/143/166/188 räumen 4×7 Zeilen weg) 15 min mittel
6 Timeout-Magic-Numbers nach src/lib/constants.ts (1500 ms, 30-min SW-Poll) 10 min mittel
7 Deutsche Fehler-Texte in api/recipes/[id]/image/+server.ts englisch ziehen (Konsistenz) 5 min kosmetisch
8 Im Session-Handoff /api/recipes/[id]/image (POST/DELETE) nachtragen 5 min niedrig

Summe: unter 90 Minuten — und du hast den Großteil der Haut-Irritationen unten.


Größere Refactor-Kandidaten

A. API-Endpoints entkoppeln (HIGH, 12 Std)

Extrahiere src/lib/server/api-helpers.ts mit:

  • parsePositiveIntParam(raw: string, field: string): number — wirft via SvelteKit error(400, …)
  • validateBody<T>(body: unknown, schema: ZodSchema<T>): T — ersetzt die safeParse()-Loops in 8+ Handlern
  • gemeinsame ErrorResponse-Shape (aktuell mal {message}, mal {message, issues})

Nach dem Helper-Refactor sollten die Handler nur noch echtes Business-Logik enthalten und je 3050 Zeilen kürzer werden.

B. Search-State aus +page.svelte ziehen (HIGH, halber Tag)

+page.svelte trägt 20+ $state-Variablen (query, hits, webHits, searching, webError …) und duplizierte Search-UI in +layout.svelte. Vorschlag: src/lib/client/search.svelte.ts mit search(), loadMore(), clear(). Danach ist das Page-File halbiert und der Layout-Nav-Search nutzt denselben Store.

C. RecipeEditor / RecipeView in Sub-Components zerlegen (MEDIUM, halber Tag)

Kandidaten: IngredientRow.svelte, StepList.svelte, TimeDisplay.svelte, ImageUploadBox.svelte. Vorteile: isoliert testbar, wiederverwendbar in Preview-Seite. Aber: keine Eile, solange niemand sonst drin arbeitet.

D. Ingredient-Parser-Edge-Cases (HIGH, 23 Std)

Der Parser (src/lib/server/parsers/ingredient.ts) und seine Tests decken ASCII-Ganzzahlen + Dezimal + Brüche ab. Fehlt:

  • Unicode-Brüche (½, ⅓, ¼)
  • führende Nullen, wissenschaftliche Notation
  • Locale-Kommadezimal (deutsche Rezepte!)
  • 0-Portionen, negative Mengen

Parametrisierte Tests anlegen, dann Parser ggf. mit Zod-Refinement absichern.


Einzelbefunde im Detail

Dead Code

  • Unused Deps: yauzl, @types/yauzl (absichtlich für Phase 5b; Entscheidung treffen: behalten oder entfernen bis Phase kommt).
  • RequestShape (src/lib/sw/cache-strategy.ts:3) und ManifestDiff (src/lib/sw/diff-manifest.ts:4) sind exportiert, aber nur intern benutzt — export weg oder im Test importieren.
  • Alle 97 Source-Files erreichbar, keine orphan-Assets, keine TODO/FIXME/HACK-Marker, keine großen auskommentierten Blöcke.

Redundanzen

  • parseId/parsePositiveInt — 9 Sites: api/recipes/[id]/, …/favorite, …/rating, …/cooked, …/comments, …/image, api/profiles/[id]/, api/domains/[id]/, api/wishlist/[recipe_id]/
  • Fetch-try/catch-alert-Pattern in 5 Svelte-Komponenten: recipes/[id]/+page.svelte (2×), admin/domains/+page.svelte (2×), admin/profiles/+page.svelte
  • Zod-safeParse + gleicher Error-Throw in 12+ Endpoints
  • parseQty + Zutat-Reassembly in RecipeEditor dupliziert Logik aus parseIngredient — könnte über src/lib/shared/ geteilt werden
  • Profile-Guard (if (!profile.active) alert(…)) 4× identisch in recipes/[id]/+page.svelte

Struktur

  • Große Dateien: +page.svelte (808), recipes/[id]/+page.svelte (757), +layout.svelte (678), RecipeEditor (630), recipes/+page.svelte (539). Keine davon ist kaputt; alle sind Wachstum unter Last.
  • API-Error-Shape: mehrheitlich {message}, profiles/+server.ts gibt zusätzlich {issues} aus (Zod-Details). Festschreiben.
  • Store-Init-Races: profile.svelte.ts und search-filter.svelte.ts laden bei erstem Zugriff. Komponenten sehen ggf. Leer-State vor Fetch. Optional loading-Flag.
  • Konsolen-Logs: 6 Stück in Prod-Build (service-worker.ts 2×, searxng.ts 3×, sw-register.ts 1×). Vermutlich Absicht; als Dok-Kommentar festhalten oder in if (DEV)-Guards packen.
  • Svelte-5-Runes-Stores sind konsistent, keine God-Stores.
  • TypeScript: strict an, 0× any, 0× Server-Import-in-Client — bestätigt die CLAUDE.md-Regel.

Docs-vs-Code-Mismatches

Fundstelle Fix
ARCHITECTURE.md:55recipe_ingredient + recipe_step ingredient + step
OPERATIONS.md:135IMAGES_PATH IMAGE_DIR
session-handoff-2026-04-17.md:46 — fehlt /api/recipes/[id]/image (POST/DELETE) ergänzen
Alle Gotchas in CLAUDE.md ✓ verifiziert, stimmen
Alle Claims im offline-PWA-Spec ✓ verifiziert, alle in Code vorhanden

Was bleibt wie es ist

  • Migrationen: 001011 sind historisch sauber. 008 + 010 löschen beide den Thumbnail-Cache — Feature-Iteration, kein Bug. Keine bestehende Migration anfassen (das ist ohnehin die dokumentierte Regel).
  • Service-Worker: Zombie-Cleanup-Logik (pwa.svelte.ts) ist Kunst, aber funktioniert und ist kommentiert. Unit-Tests decken beide Zweige (Zombie vs alter SW) ab.
  • Repository-Pattern: Cleane Schichtung. Nicht refactoren.
  • Test-Suite: 23 Dateien, 158 Tests, volle Integration inkl. DB/HTTP/Import/SearXNG. Leichte Lücken bei Parser-Edge-Cases (siehe oben).

Ampel

Dimension Status
Architektur & Schichten 🟢 gesund
Dead Code 🟢 minimal
Redundanzen 🟡 adressierbar, nicht dringend
Datei-/Komponenten-Größen 🟡 zwei Pages ≥ 750L
Tests 🟢 stark, Edge-Cases ausbaufähig
Doku 🟡 1 inhaltlicher Fehler + 1 ENV-Tippfehler, sonst stabil
Sicherheit/Perf 🟢 keine Funde im statischen Review

Vorgeschlagene Reihenfolge

  1. Heute (10 min): Quick-Wins 1 + 2 (ARCHITECTURE-Tabellen, OPERATIONS-ENV).
  2. Nächste Session (2 h): api-helpers.ts + parseId-Consolidation + Tests (Refactor A).
  3. Bei Zeit: Search-State-Store (Refactor B) — bringt beim nächsten Feature sofort Dividende.
  4. Phase-5b: yauzl einsetzen ODER Deps entfernen.

Teilreports

Die vollständigen Agent-Befunde liegen daneben:

  • docs/superpowers/review/dead-code.md
  • docs/superpowers/review/redundancy.md
  • docs/superpowers/review/structure.md
  • docs/superpowers/review/docs-vs-code.md

Review-Metadaten: 4 parallele Explore-Agenten, jeweils read-only, Summen manuell gegen Code verifiziert (Line-Counts, Tabellen-Namen, ENV-Namen, parseId-Sites).