# Redundancy Review ## Summary Kochwas exhibits significant duplication in API endpoint handlers across 22 endpoints, with copy-pasted parameter parsing (parseId/parsePositiveInt) in 8+ files, repeated error-handling patterns in fetch wrappers across 5+ Svelte components, and schema validation blocks that could be consolidated. ## HIGH severity ### Duplicated parseId / parsePositiveInt helpers across API endpoints - **Sites**: /api/recipes/[id]/+server.ts:51-54, /api/recipes/[id]/favorite/+server.ts:9-13, /api/recipes/[id]/rating/+server.ts:14-18, /api/recipes/[id]/cooked/+server.ts:10-14, /api/recipes/[id]/comments/+server.ts:14-18, /api/profiles/[id]/+server.ts:9-13, /api/domains/[id]/+server.ts:19-23, /api/wishlist/[recipe_id]/+server.ts:9-13 - **Pattern**: Eight API endpoints independently define nearly identical parameter-parsing functions that validate positive integers from route params. - **Suggestion**: Extract to src/lib/server/api-helpers.ts with parsePositiveIntParam(raw, field) returning the number or throwing via SvelteKit error(). ### Copy-pasted fetch error-handling + alert pattern in Svelte components - **Sites**: /recipes/[id]/+page.svelte:76-87, /recipes/[id]/+page.svelte:253-265, /admin/domains/+page.svelte:31-48, /admin/domains/+page.svelte:67-87, /admin/profiles/+page.svelte:30-44 - **Pattern**: Five component functions repeat identical 6-line blocks: await fetch(); if not ok, parse JSON, show alert with body.message or HTTP status. - **Suggestion**: Create src/lib/client/api-fetch-wrapper.ts with asyncFetch(url, init, actionTitle) that wraps fetch, error handling, and alertAction. ## MEDIUM severity ### Repeated Zod schema validation + error pattern across API endpoints - **Sites**: /api/recipes/[id]/+server.ts, /api/recipes/[id]/favorite/+server.ts, /api/recipes/[id]/rating/+server.ts, /api/recipes/[id]/cooked/+server.ts, /api/recipes/[id]/comments/+server.ts, /api/profiles/+server.ts, /api/domains/[id]/+server.ts, /api/wishlist/+server.ts - **Pattern**: Every endpoint defines schemas locally with safeParse() followed by identical error handling: if not success, error 400 Invalid body. 12+ endpoints repeat this 3-4 line pattern. - **Suggestion**: Create src/lib/server/schemas.ts with common validators and validateBody(body, schema) helper that centralizes the error throw. ### Recipe scaling / ingredient manipulation scattered without consolidation - **Sites**: /lib/recipes/scaler.ts:10-16, /lib/server/parsers/ingredient.ts:42-68, /lib/components/RecipeEditor.svelte:144-149, /lib/components/RecipeEditor.svelte:156-175 - **Pattern**: RecipeEditor re-implements parseQty and ingredient assembly (raw_text building) instead of importing parseIngredient from server parser. Logic is nearly identical in two places. - **Suggestion**: Expose parseIngredient as shared client code or create src/lib/shared/ingredient-utils.ts; import into component to avoid duplication. ### Profile not-selected alert pattern duplicated 4x in same component - **Sites**: /recipes/[id]/+page.svelte:124-131, :143-150, :166-173, :188-195 - **Pattern**: Four action functions (setRating, toggleFavorite, logCooked, addComment) all open with identical 7-line guard checking active profile and showing same alert message. - **Suggestion**: Extract requireProfile() helper in src/lib/client/profile.svelte that performs the alert and returns boolean; replace all four guard clauses. ## LOW severity ### WakeLock error handling try-catch pattern - **Sites**: /recipes/[id]/+page.svelte:318-327, :332-338 - **Pattern**: Both functions independently have try-catch that silently swallows errors. Identical empty catch pattern duplicated. - **Suggestion**: Cosmetic - document once or combine into manageWakeLock(action) wrapper. ### Migration cache-clearing pattern (historical only) - **Sites**: /db/migrations/008_thumbnail_cache_drop_unknown.sql, /db/migrations/010_thumbnail_cache_rerun_negatives.sql - **Pattern**: Two consecutive migrations both DELETE from thumbnail_cache due to feature iteration. Not a bug, just historical stacking. - **Note**: Safe to leave as-is. ### Test fixture duplication: baseRecipe helper - **Sites**: /tests/integration/recipe-repository.test.ts:22-42 - **Pattern**: baseRecipe factory defined locally; likely duplicated in other tests. - **Suggestion**: Move to tests/fixtures/recipe.ts and import everywhere. ### API error message language inconsistency - **Sites**: /api/recipes/[id]/image/+server.ts (German), all others (English) - **Pattern**: Image endpoint uses German error messages; all other endpoints use English. - **Suggestion**: Standardize to German or English for consistent UX. --- ## Notes Strong separation of concerns observed in repositories and parsers. Type definitions well-centralized in src/lib/types.ts. No major SQL redundancy beyond historical migrations. Primary improvement opportunities are parameter validation, error handling, and component fetch logic consolidation.