# Recipe Manager — Image Import & Backend Hardening Execution Board

Created: 2026-03-27  
Owner: Main Orchestrator  
Status: READY

## Objective
Ship a reliable URL import pipeline that returns high-quality `image_url` values and harden backend safety/perf around migrations, search, and TypeScript correctness.

## Current Repo Reality (Baseline)
- `POST /api/import/url` is currently a stub returning `{ draft_recipe: null }` (`src/backend/routes/import.ts`).
- URL fetch + JSON-LD extraction foundation exists (`src/backend/services/UrlImportService.ts`) but is not wired to route.
- Schema.org/heuristic parser services are minimal and weakly typed (`any` heavy).
- `image_url` exists in schema/repository/routes/seed (`schema.sql`, `RecipeRepository`, `recipes.ts`), but no explicit image validation/fallback policy.
- Runtime migration helper exists (`applyRuntimeMigrations`) with no direct migration tests.
- Search currently uses `%LIKE%` joins across recipes/ingredients/tags; indexes are limited and query plan unverified.
- TS strict mode is on, but `any` and contract drift remain in backend/frontend types.

## Release Gate (Done Definition)
- [ ] `/api/import/url` performs real fetch/parse flow and returns non-empty `draft_recipe` for supported pages.
- [ ] Image extraction ranking + URL validation policy is implemented and tested.
- [ ] Runtime migration behavior is covered by tests for pre/post `image_url` schemas.
- [ ] Search performance/query behavior validated with index and query-shape improvements.
- [ ] TS hygiene pass removes prioritized unsafe `any` in import/search pathways.

---

## Task Backlog

### T01 — Import Route Orchestration (Wire Real Pipeline)
Priority: P0  
Owner: agent-import-core  
Dependencies: none

Deliverables:
- Replace stub in `src/backend/routes/import.ts` with real pipeline:
  - validate URL input via zod
  - call `UrlImportService.fetchFromUrl`
  - parse JSON-LD blocks and select recipe candidate
  - fallback to heuristic parser when schema parse fails
  - return structured `UrlImportResult` payload expected by frontend (`draft_recipe`, `source_url`, parse metadata)
- Error mapping from `UrlImportError` to stable HTTP/API errors for UI (`timeout`, `network`, `unsupported content`, parse failure).

Acceptance:
- [ ] Import route no longer returns hardcoded null draft.
- [ ] `src/backend/tests/import.test.ts` includes success + invalid URL + timeout/network/content-type failures.
- [ ] Frontend import page can reach “review” stage from at least one fixture HTML sample.

---

### T02 — Schema.org Image Extraction Quality Pass
Priority: P0  
Owner: agent-import-parser  
Dependencies: T01

Deliverables:
- Refactor `SchemaOrgRecipeParserService` to support common image variants:
  - string URL
  - array of URLs
  - array/object entries with `url`, `contentUrl`, `thumbnailUrl`
  - `@graph` recipe object selection when JSON-LD block is graph-shaped
- Add image candidate ranking (prefer HTTPS, largest/default image over tiny thumbnails when width/height available).
- Return normalized draft with stable `image_url` candidate.

Acceptance:
- [ ] Parser tests added with fixtures for at least 5 JSON-LD image shapes.
- [ ] For each fixture, expected top `image_url` is asserted.
- [ ] No parser path throws on malformed/partial image fields; degrades gracefully.

---

### T03 — Image URL Validation & Fallback Policy
Priority: P0  
Owner: agent-import-hardening  
Dependencies: T02

Deliverables:
- Implement central image URL sanitizer/validator utility (new service module):
  - allow `http/https` only (or strict `https` with optional downgrade rule)
  - reject `data:`, `javascript:`, blob/non-web URLs
  - trim + normalize empty values to `null`
  - optional host allow/deny controls (documented default policy)
- Integrate validator in:
  - import parsing output
  - recipe create/update flows (`routes/recipes.ts` + repository normalization layer)
- Define fallback order for import draft image:
  1) validated schema.org image
  2) validated heuristic image
  3) null (no placeholder persisted)

Acceptance:
- [ ] Unit tests cover allow/reject matrix for image URLs.
- [ ] Creating/updating recipe with invalid image URL is predictably rejected or nulled per policy.
- [ ] Policy documented in `docs/api.md` (import + recipe payload behavior).

---

### T04 — Migration Coverage for `recipes.image_url`
Priority: P1  
Owner: agent-db-safety  
Dependencies: none (can run parallel to T02/T03)

Deliverables:
- Add migration tests for `applyRuntimeMigrations`:
  - DB with no `recipes` table (no-op)
  - DB with `recipes` but no `image_url` (column added)
  - DB already containing `image_url` (idempotent)
- Add integration check around `migrate.ts`/`database.ts` startup path to ensure migration executes before repository usage.

Acceptance:
- [ ] Dedicated test file exists under `src/backend/tests` (or `src/backend/db/__tests__`).
- [ ] Tests assert column presence via `PRAGMA table_info(recipes)`.
- [ ] Re-running migration tests proves idempotence.

---

### T05 — Import Contract Alignment (Frontend/Backend Types)
Priority: P1  
Owner: agent-contracts  
Dependencies: T01

Deliverables:
- Define shared import response contract (backend + frontend) for:
  - `draft_recipe`
  - `source_url`
  - parse provenance (`schema_org_used`, `heuristic_used`, warning list)
- Align frontend `UrlImportResult` and backend route payload to avoid required-field mismatch.
- Ensure `image_url` is represented consistently in frontend recipe interfaces where used by UI components.

Acceptance:
- [ ] TypeScript build/test passes without contract casts for import payload.
- [ ] Import UI displays parse metadata without runtime undefined errors.
- [ ] `frontend/src/types/*` and backend response shape are synchronized.

---

### T06 — Search Query + Index Optimization
Priority: P1  
Owner: agent-data-perf  
Dependencies: none

Deliverables:
- Review/adjust recipe search query shape in `RecipeRepository.findAll/count` to reduce costly wide joins where possible.
- Add/validate indexes to support current search/filter path (evaluate at minimum):
  - `recipes(created_at)` for default order
  - `recipe_tags(recipe_id)` complementing existing `recipe_tags(tag_id)`
  - optional composite/index refinements based on `EXPLAIN QUERY PLAN`
- Capture query plan before/after on seeded dataset.

Acceptance:
- [ ] Query plan evidence saved under `docs/perf/search-query-plan.md`.
- [ ] Search + tag filter behavior unchanged functionally (existing tests still pass).
- [ ] Measured improvement or justified no-op documented.

---

### T07 — TS Hygiene Pass (Import/Data Path First)
Priority: P2  
Owner: agent-ts-hygiene  
Dependencies: T01, T05

Deliverables:
- Remove high-risk `any` from import/parser/repository hot paths:
  - `SchemaOrgRecipeParserService`
  - `RecipeRepository` filter destructuring
  - import-related tests/types
- Introduce narrow helper types/guards for JSON-LD blocks instead of raw `any`.
- Keep broader orchestrator generics untouched unless directly impacted.

Acceptance:
- [ ] No `any` remains in import route + parser services.
- [ ] Repository filter casts no longer use `filters as any`.
- [ ] `npm run build` passes with strict mode unchanged.

---

### T08 — Docs + Runbook Truth Sync
Priority: P2  
Owner: agent-docs-sync  
Dependencies: T01, T03, T05

Deliverables:
- Update stale API/import docs to match actual payloads and behavior (`docs/api.md`, relevant README sections).
- Document known import limits and expected failure messages.
- Add “how to add parser fixture” note for future maintainers.

Acceptance:
- [ ] Docs describe real import endpoint behavior (not aspirational).
- [ ] Example request/response includes `image_url` handling rules.
- [ ] No references to removed/incorrect field names in import examples.

---

## Wave Plan (Execution Order)

### Wave 1 — Restore Functional Import Core
- T01 (route orchestration)

### Wave 2 — Image Quality + Safety
- T02 (schema image extraction)
- T03 (validation/fallback policy)
- T05 (contract alignment)

### Wave 3 — Backend Hardening in Parallel
- T04 (migration coverage)
- T06 (search/index optimization)

### Wave 4 — Cleanup + Stability
- T07 (TS hygiene)
- T08 (docs truth sync)

## Dependency Notes
- T03 depends on T02 because sanitizer policy should apply to ranked image candidates.
- T05 depends on T01 because real response shape must exist before contract lock.
- T07 should start after T01/T05 to avoid churn from contract refactors.

## Recommended Starting Order (Concrete)
1. **T01** — unblock real import behavior and expose true integration issues.
2. T02 — improve image extraction quality where import currently underperforms.
3. T03 — enforce URL safety/normalization policy.
4. T05 — lock backend/frontend import contract and image fields.
5. Parallel: T04 + T06.
6. T07 then T08.

## First Task to Launch
**Launch T01 — Import Route Orchestration (Wire Real Pipeline).**  
Reason: it converts a stubbed endpoint into executable behavior and creates the integration baseline needed by every downstream image-quality and hardening task.

## Reporting Protocol (for each task)
1) task id  
2) files changed  
3) tests added/updated + command output  
4) blockers/risks  
5) ready-for-review flag
