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:
@@ -15,8 +15,8 @@ import (
|
||||
"code.cubecraftlabs.com/Maniacs_Mansion/Meal-Quest/internal/store"
|
||||
)
|
||||
|
||||
// PassedLimit is how many of the most recently passed Side quests the
|
||||
// household context holds.
|
||||
// PassedLimit is how many of the most recently passed names (Side quests
|
||||
// passed and dinners a Rotation check dropped) the household context holds.
|
||||
const PassedLimit = 60
|
||||
|
||||
// PlanWeeks is how many ISO weeks of plans, ending with the current week,
|
||||
@@ -34,8 +34,8 @@ type HouseholdContext struct {
|
||||
Regulars []RegularDinner
|
||||
// QuestLog holds the Quest log dinner names, in name order.
|
||||
QuestLog []string
|
||||
// Passed holds the names of the most recently passed Side quests,
|
||||
// oldest first.
|
||||
// Passed holds the most recently passed names, oldest first: Side
|
||||
// quests passed and dinners a Rotation check dropped ("Not for us").
|
||||
Passed []string
|
||||
// Plans are the planned dinners of the last PlanWeeks weeks, oldest
|
||||
// first.
|
||||
@@ -137,7 +137,7 @@ func readContext(ctx context.Context, st *store.Store, now time.Time) (h Househo
|
||||
h.QuestLog = append(h.QuestLog, d.Name)
|
||||
}
|
||||
|
||||
passed, err := q.ListRecentDeclinedNames(ctx, PassedLimit)
|
||||
passed, err := q.ListRecentPassedNames(ctx, PassedLimit)
|
||||
if err != nil {
|
||||
return h, fmt.Errorf("read passed Side quests: %w", err)
|
||||
}
|
||||
|
||||
@@ -30,8 +30,9 @@ type SideQuestsRequest struct {
|
||||
Needed int
|
||||
// Pending holds the names of the Side quests not yet tried or passed.
|
||||
Pending []string
|
||||
// Declined holds the name of every passed Side quest, not only the
|
||||
// recent ones Context holds.
|
||||
// Declined holds every passed name — each passed Side quest and each
|
||||
// dinner a Rotation check dropped — not only the recent ones Context
|
||||
// holds.
|
||||
Declined []string
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user