Files
MealQuest/migrations/queries/dinners.sql
T
dev_agentandClaude Opus 5.5 f4bed5d82d
CI / ci (push) Successful in 2m25s
CI / ci (pull_request) Successful in 2m20s
Fail interrupted groundings at boot and bound hand grounding
At boot, after the job runner fails the jobs a previous process left
running, FailInterruptedGroundings sets every dinner still pending with
no ground_dinner job queued or running to failed (interrupted). A crash
mid-job, or between saving a dinner and enqueuing its job, no longer
leaves the dinner pending forever.

A search failure on recipe-candidates or ground now logs only the reason
code search_failed, never the wrapped error, which may quote the
provider; the response stays redacted.

When the grounding job cannot be enqueued, POST /dinners answers 201
with the saved dinner failed (grounding_error) and grounding_job_id
null, instead of a 500 that hid the dinner it had created.

Grounding a candidate or link by hand runs under a 90-second deadline
(fetch, photo, normalize_recipe); past it the request answers 504
ground_timeout and the dinner is unchanged.

Maestro task: 0cbaa5bf-8be4-4cbd-aab2-891e7f1bc2b5

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-06 16:30:53 -04:00

129 lines
3.1 KiB
SQL

-- name: CreateDinner :one
INSERT INTO dinners (
id, name, normalized_name, status, origin, method, minutes_total,
difficulty, cuisine, is_favorite, recipe_id, recipe_url, photo_id,
grounding_status, updated_by, created_at, updated_at
) VALUES (
?, ?, ?, ?, ?, ?, ?,
?, ?, ?, ?, ?, ?,
?, ?, ?, ?
)
RETURNING *;
-- name: GetDinner :one
SELECT * FROM dinners
WHERE id = ?;
-- name: ListDinnersByStatus :many
SELECT * FROM dinners
WHERE status = ?
ORDER BY normalized_name, id;
-- name: ListUnarchivedDinners :many
-- Every dinner a new or renamed dinner must not repeat.
SELECT * FROM dinners
WHERE status <> 'archived'
ORDER BY id;
-- name: UpdateDinner :one
-- An unknown id returns sql.ErrNoRows.
UPDATE dinners
SET name = ?,
normalized_name = ?,
status = ?,
origin = ?,
method = ?,
minutes_total = ?,
difficulty = ?,
cuisine = ?,
recipe_id = ?,
photo_id = ?,
grounding_status = ?,
updated_by = ?,
updated_at = ?
WHERE id = ?
RETURNING *;
-- name: ArchiveDinner :one
-- An unknown id returns sql.ErrNoRows.
UPDATE dinners
SET status = 'archived',
updated_by = ?,
updated_at = ?
WHERE id = ?
RETURNING *;
-- name: SetDinnerFavorite :one
-- An unknown id returns sql.ErrNoRows.
UPDATE dinners
SET is_favorite = ?,
updated_by = ?,
updated_at = ?
WHERE id = ?
RETURNING *;
-- name: ToggleDinnerFavorite :one
-- An unknown id returns sql.ErrNoRows.
UPDATE dinners
SET is_favorite = 1 - is_favorite,
updated_by = ?,
updated_at = ?
WHERE id = ?
RETURNING *;
-- name: GroundDinner :one
-- Records a dinner's grounding (grounded or manual) and clears any
-- grounding_error. An unknown id returns sql.ErrNoRows.
UPDATE dinners
SET recipe_id = ?,
photo_id = ?,
method = ?,
minutes_total = ?,
difficulty = ?,
grounding_status = ?,
grounding_error = NULL,
updated_by = ?,
updated_at = ?
WHERE id = ?
RETURNING *;
-- name: GroundPendingDinner :execrows
-- Records the background grounding of a dinner still pending; a dinner
-- grounded some other way meanwhile is left as it is (0 rows).
UPDATE dinners
SET recipe_id = ?,
photo_id = ?,
method = ?,
minutes_total = ?,
difficulty = ?,
grounding_status = 'grounded',
grounding_error = NULL,
updated_at = ?
WHERE id = ? AND grounding_status = 'pending';
-- name: FailPendingDinnerGrounding :execrows
-- Records why the background grounding of a dinner still pending failed; a
-- dinner grounded some other way meanwhile is left as it is (0 rows).
UPDATE dinners
SET grounding_status = 'failed',
grounding_error = ?,
updated_at = ?
WHERE id = ? AND grounding_status = 'pending';
-- name: FailOrphanedPendingDinnerGroundings :execrows
-- Fails every dinner still pending whose grounding job is no longer queued
-- or running: the process stopped before the job, or before its handler
-- recorded a result. Run at boot, after the job runner fails the jobs a
-- previous process left running.
UPDATE dinners
SET grounding_status = 'failed',
grounding_error = sqlc.arg(grounding_error),
updated_at = sqlc.arg(updated_at)
WHERE grounding_status = 'pending'
AND NOT EXISTS (
SELECT 1 FROM jobs
WHERE jobs.kind = sqlc.arg(kind)
AND jobs.status IN ('queued', 'running')
AND json_extract(jobs.payload, '$.dinner_id') = dinners.id
);