Add the Rotation check: MarkTried and keep/drop decisions
Per D-021, plan.MarkTried(date) moves every Quest log dinner planned on
a household-local date (any plan status) to tried and opens a pending
rotation_reviews row; a dinner already checked for the date is left as
it is, so it is idempotent and never re-marks a dinner returned to the
Quest log.
GET /api/v1/rotation-reviews lists the pending checks as
{dinner {id, name, photo}, plan_date}. POST
/api/v1/dinners/{id}/rotation-review {decision} applies keep (Regular,
origin kept), drop ("Not for us", archived) or not_made ("We didn't
make it", back to the Quest log), closing the check with decided_at and
the session's updated_by; a second decision is 409 no_pending_review.
A dropped dinner's name joins the passed names: ListDeclinedSuggestionNames
and ListRecentDeclinedNames become ListPassedNames and
ListRecentPassedNames, which also read Rotation checks decided drop, so
the Side quest dedupe and household context never suggest it again.
A static test guards that keep is the only path to Regular: every query
writing dinners.status and every use of the regular status is reviewed.
Maestro: a1887d1c-c405-478c-ac7d-8cb8b40d280d
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -364,6 +364,26 @@ automatic** (D-021).
|
||||
`is_new`, moves a `synced` plan to `changed`, and answers 200 with the
|
||||
plan. A date outside the week is 400 `invalid_date`, an unknown dinner or
|
||||
a week with no plan 404, and any other dinner 409 `dinner_not_plannable`.
|
||||
- Rotation check (`plan.Service`, D-021). `MarkTried(date)`, which the
|
||||
`rotation_check` schedule calls for the household-local day just past,
|
||||
moves every `quest_log` dinner planned on that date, on a plan of any
|
||||
status, to `tried` and opens a `pending` `rotation_reviews` row for it;
|
||||
a dinner already checked for that date is left as it is, so it is
|
||||
idempotent. `GET /api/v1/rotation-reviews` returns `{reviews}`, the
|
||||
pending checks whose dinner is still tried, oldest `plan_date` first,
|
||||
each `{dinner: {id, name, photo}, plan_date}`. `POST
|
||||
/api/v1/dinners/{id}/rotation-review` takes `{decision}`: `keep` makes
|
||||
the dinner a Regular, `drop` ("Not for us") archives it and `not_made`
|
||||
("We didn't make it") returns it to the Quest log; its origin is kept.
|
||||
The check is closed with `decided_at` and the session's `updated_by`,
|
||||
and the answer is `{dinner, plan_date, decision, dinner_status,
|
||||
decided_at, updated_by}`. Any other decision is 400 `invalid_decision`,
|
||||
an unknown dinner 404, a dinner with no pending check (including a
|
||||
second decision) 409 `no_pending_review`, and one no longer tried 409
|
||||
`dinner_not_tried`. Keep is the only path from tried to Regular. A
|
||||
dropped dinner's name joins the passed names (`ListPassedNames`) the
|
||||
Side quest dedupe and household context use, so it is never suggested
|
||||
again.
|
||||
- `/health` — liveness.
|
||||
- Everything else serves the embedded PWA with SPA fallback.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user