Files
kochwas/docs/superpowers/review/OPEN-ISSUES-NEXT.md

167 lines
9.0 KiB
Markdown
Raw Permalink Normal View History

# Open Issues — Stand nach Review-Fixes
**Datum:** 2026-04-18 (Nacht-Session)
**Branch:** `review-fixes-2026-04-18`
**Baseline:** REVIEW-2026-04-18.md + 4 Sub-Reports vom Morgen
**Tests:** 184/184 grün (Baseline waren 158, +26 neue Tests)
**svelte-check:** 0 Errors, 10 Warnings (alle pre-existing in `RecipeEditor.svelte` / `recipes/[id]/+page.svelte`)
**Build:** `npm run build` erfolgreich
**Smoke-Test:** `npm run preview` + curl auf `/api/health`, `/api/profiles`, `/api/recipes/abc` (400), `/api/wishlist` mit invalider Body (400 + issues) — alle Endpunkte verhalten sich korrekt
---
## Was wurde gemacht (8 Commits)
| Commit | Inhalt | Verifikation |
|---|---|---|
| `2289547` | docs(review): table names, IMAGE_DIR, image endpoints | grep auf alte Namen → 0 |
| `830c740` | refactor(constants): SW-Timing-Konstanten, RequestShape/ManifestDiff intern, Image-Endpoint EN | tests + check grün |
| `739cc2d` | feat(server): api-helpers.ts (parsePositiveIntParam, validateBody, ErrorResponse) | 13 neue Tests |
| `ff293e9` | refactor(api): 13 +server.ts handler auf api-helpers (-67 Zeilen netto) | 171/171 |
| `30a447a` | refactor(client): requireProfile() + asyncFetch wrapper | 5 + 4 Sites umgestellt |
| `60c8352` | docs(searxng): Intent-Kommentar fuer Prod-Logs | — |
| `6d9e79d` | feat(parser): Unicode-Brueche + Mengen-Plausibilitaet | 13 neue Tests |
| `31c6e5c` | refactor(server): IMAGE_DIR/DATABASE_PATH zentralisieren + Doku-Drift | grep auf alte Pattern → 0 |
Net: 31 Files, +626/-272.
### Re-Review per 4 paralleler Explore-Agenten — Beweis
**Dead-Code (HIGH-Confidence):** Alle vorherigen Findings resolved. RequestShape + ManifestDiff sind nur noch interne Types. yauzl ist explizit als Phase 5b markiert (in `session-handoff-2026-04-17.md` und `ARCHITECTURE.md:33`). Kein neuer toter Code durch die Refactors.
**Redundancy (HIGH-Confidence):** 0 verbleibende `function parseId`/`parsePositiveInt`-Definitionen in `src/routes/api/`. 0 verbleibende `safeParse(...) + manueller error(400)`-Blöcke. Der gerade behobene `IMAGE_DIR`-Drift war 6× im Code und 1× in `db/index.ts`. Verbleibende kleine Pattern siehe unten.
**Structure:** Constants-Extraktion + API-Error-Shape-Standardisierung erledigt. Ingredient-Parser-Edge-Cases mit 13 Tests abgesichert. Große Pages bleiben groß (siehe „Bewusst verschoben").
**Docs-vs-Code:** Alle drei Original-Findings behoben. Zwei kleine zusätzliche Mismatches (149→150 Quote-Count, search/-Route gar nicht existent) heute gleich mitgenommen.
---
## ⚠ Verbleibende Items — bewusst verschoben mit Begründung
### A. Refactor B — Search-State-Store extrahieren (HIGH, halber Tag)
**Wo:** `src/routes/+page.svelte` (808 Zeilen, 20+ `$state`-Vars), `src/routes/+layout.svelte` (678 Zeilen, dupliziert das Header-Search-Dropdown).
**Vorschlag:** `src/lib/client/search.svelte.ts` mit `search()`, `loadMore()`, `clear()` und reaktivem `query / hits / loading / error`-Zustand.
**Warum nicht heute:**
1. Touch in zwei der drei größten Files der Codebase (808L + 678L)
2. Bricht Frontend-Verhalten subtil, wenn Reactive-Glue zwischen Layout-Search und Page-Search nicht 1:1 übernommen wird
3. UAT-pflichtig (Live-Suche, Empty-State, Web-Suche-Fallback) — ohne UAT-Slot zu riskant
4. Kein automatisches Test-Sicherheitsnetz für die UI-Layer
**Empfehlung:** Eigene Phase mit `/gsd-discuss-phase` und Smoke-UAT vor dem Mergen. Anschließend `/gsd-execute-phase` mit Browser-Check pro Wave.
---
### B. Refactor C — RecipeEditor / RecipeView in Sub-Components zerlegen (MEDIUM, halber Tag)
**Wo:** `src/lib/components/RecipeEditor.svelte` (630L), `RecipeView.svelte` (398L).
**Kandidaten:** `IngredientRow.svelte`, `StepList.svelte`, `TimeDisplay.svelte`, `ImageUploadBox.svelte`.
**Warum nicht heute:**
- REVIEW-2026-04-18.md sagt explizit: *"Aber: keine Eile, solange niemand sonst drin arbeitet."*
- Solange der Owner allein entwickelt, ist 630L pro Komponente kein Blocker.
- Tests gibt es nur indirekt (über Importer-Tests und Unit-Tests der Parser).
**Empfehlung:** Spätere Phase, falls eine zweite Person mitarbeitet oder wenn Editor-Bug-Hunting zu schwierig wird. Vorher zumindest die 10 pre-existing svelte-check WARNINGs in `RecipeEditor.svelte` fixen — die sind schon flackrige Reactive-Patterns (`$derived` statt `$state` für abgeleitete Werte).
---
### C. SearXNG Rate-Limit Recovery (MEDIUM, 1-2 h)
**Wo:** `src/lib/server/search/searxng.ts`.
**Was fehlt:** Bei 429/403 wird zwar geloggt, aber kein Backoff oder `isStale`-Flag. Folgesuchen liefern alten Cache, der User merkt nichts.
**Empfehlung:** Eigene Phase. Drei mögliche Zutaten: (1) `lastFailureAt`-Map per Domain, (2) exponentieller Backoff, (3) `isStale: boolean` im Response, das die UI als „Ergebnisse evtl. veraltet" anzeigt.
---
### D. Service-Worker Zombie-Cleanup unter Last testen (MEDIUM, 2-3 h)
**Wo:** `src/lib/client/pwa.svelte.ts` Zombie-Heuristik.
**Status:** 6 Unit-Tests existieren bereits (`tests/unit/pwa-store.test.ts`), die beide Pfade abdecken.
**Was offen ist:** Verhalten unter sehr langsamen Netzen (1500ms-Timeout könnte False-Positive triggern). Sehr edge-case, aber im REVIEW-Original als MEDIUM gelistet.
**Empfehlung:** Beim nächsten Service-Worker-Touch mit Throttling-DevTools-Profil testen. Kein eigener Sprint nötig.
---
### E. JSON-LD Parser Edge-Cases (MEDIUM, halbe Phase)
**Wo:** `src/lib/server/parsers/json-ld-recipe.ts` (402L).
**Was abgesichert ist:** Ingredient-Parser-Käfer (Unicode-Brüche, Bounds, Komma-Dezimal) sind heute mit 13 neuen Tests dicht.
**Was offen ist:** JSON-LD selbst hat Edge-Cases — null-Servings, Locale-spezifische Number-Formats, defekte `recipeIngredient`-Arrays.
**Empfehlung:** Wenn beim Importieren ein Bug auftaucht, gezielt einen Test schreiben. Kein Vorab-Sprint.
---
### F. Inline UI-Constants (LOW, 30 min)
**Wo:** `ConfirmDialog.svelte`, `ProfileSwitcher.svelte` etc. mit Hardcoded `z-index`, `border-radius: 999px`, kleinen Timeouts.
**Vorschlag:** `src/lib/theme.ts` mit `MODAL_Z_INDEX`, `POPOVER_Z_INDEX`, `PILL_RADIUS`.
**Warum nicht heute:** LOW-Severity, kein konkreter Bug damit verbunden, betrifft viele Files punktuell.
---
### G. wishlist/+page.svelte:38 — Profil-Guard mit individueller Message (LOW)
**Was:** Eine 7. Stelle hat das Profil-Guard-Pattern, aber mit eigenem Text („um mitzuwünschen"). `requireProfile()` akzeptiert aktuell keine Custom-Message.
**Empfehlung:** Entweder `requireProfile(message?)`-Variante einführen oder das Site so lassen — die Custom-Message ist dort wirklich Kontext-Information.
---
### H. RecipeEditor.svelte:54 + :83 — Bild-Upload/Delete mit inline `if (!res.ok)` (LOW)
**Was:** Image-Upload und -Delete im Editor nutzen noch das Pattern, das `asyncFetch` ersetzen sollte. Der Aufwand wäre 5 Minuten, aber RecipeEditor steckt in den 10 svelte-check-WARNINGs (siehe Refactor B-Notiz) — beim nächsten Touch der Datei mitnehmen.
---
### I. Pre-Existing svelte-check Warnings (10 Stück)
**Wo:** `RecipeEditor.svelte` (9× Zeilen 28, 97-102, 113, 121) + `recipes/[id]/+page.svelte` (1× Zeile 43).
**Was:** Pattern `let foo = recipe.bar` im Top-Level-Script — Svelte 5 will `$derived(recipe.bar)`. Aktuell snapshot-only.
**Risiko:** Bei In-Place-Mutation des Rezepts (z. B. nach PATCH) zeigt der Editor ggf. den alten Wert. **Tests fangen das nicht.**
**Empfehlung:** Kleine Phase „RecipeEditor auf $derived umstellen" — passt gut zur RecipeEditor-Subkomponentenphase (B oben), oder vorab alleine.
---
## 📌 Neu entdeckt in der zweiten Runde — alle behoben
| # | Fund | Severity | Status |
|---|---|---|---|
| 1 | `IMAGE_DIR` 6× dupliziert + `DATABASE_PATH` 2× | HIGH | ✅ `src/lib/server/paths.ts` |
| 2 | `ARCHITECTURE.md:34` — „49 Flachwitze" | MEDIUM | ✅ → 150 |
| 3 | `ARCHITECTURE.md:41``search/`-Route existiert nicht | LOW | ✅ entfernt |
---
## Empfohlene nächste Schritte
1. **PR mergen** sobald lokal abgenickt — der Branch enthält 8 atomische Commits, jeder einzeln revert-bar.
2. **Falls UAT erwünscht:** `npm run build && npm run preview`, dann manuell Profile-Switching, Rezept-Edit, Favoriten-Toggle, Wunschliste, Bild-Upload, Such-Pfade durchklicken. Erwartung: keine Verhaltensänderung gegenüber `main`.
3. **Phase „RecipeEditor reactive cleanup"** für die 10 svelte-check-Warnings (klein) — schließt Item I.
4. **Phase „Search-State-Store"** als nächste größere Phase — schließt Item A und drückt das größte Page-File spürbar runter.
5. yauzl/Phase 5b (ZIP-Backup-Restore) bleibt als ungeplant bis explizit gebraucht.
---
## Code-Quality Snapshot
| Metrik | Vorher | Nachher | Δ |
|---|---|---|---|
| Tests gesamt | 158 | 184 | +26 |
| Tests Files | 23 | 24 | +1 (api-helpers) |
| svelte-check Errors | 0 | 0 | — |
| svelte-check Warnings | 10 | 10 | — (alle pre-existing) |
| Build | ✓ | ✓ | — |
| Größte Datei (recipes/[id]/+page.svelte) | 757 | 725 | -32 |
| Größte Datei (+page.svelte) | 808 | 808 | — |
| API +server.ts Boilerplate | ca. 11 Zeilen pro Handler | ca. 4 Zeilen pro Handler | -64% |
| Duplizierte ENV-Defaults | 8 Sites | 1 Site | -7 |