Feature 14 integration fix: revalidate the draft pool, refuse duplicate week dinners, refresh the Quest log (#122)
CI / ci (push) Successful in 3m43s
CI / ci (pull_request) Successful in 3m55s

Co-authored-by: orchestrator-agent <20+orchestrator-agent@code.cubecraftcreations.com>
This commit was merged in pull request #122.
This commit is contained in:
2026-10-07 16:30:03 -04:00
committed by approver_agent
parent 955613941f
commit 76a2b611c8
8 changed files with 168 additions and 22 deletions
+25
View File
@@ -972,6 +972,31 @@ describe.each([
expect(screen.queryByRole('dialog')).not.toBeInTheDocument()
await waitFor(() => expect(posts(fetchMock)).toEqual([`${DRAFT} {}`]))
})
it('reads the Quest log again once a draft finishes, dropping the dinners it planned', async () => {
let plan = planBody('draft')
let job = draftJob('running')
let questLog = [dinner('q1', 'Lemon orzo', 'easy', 25)]
stubServer({
...lists,
[`GET ${THIS_WEEK}`]: () => jsonResponse(200, plan),
[`POST ${DRAFT}`]: () => jsonResponse(202, { jobId: 'j1' }),
[`GET ${JOB}`]: () => jsonResponse(200, job),
[`GET ${QUEST_LOG}`]: () => jsonResponse(200, { dinners: questLog }),
})
await renderPage()
const list = await screen.findByRole('list', { name: layout === 'desktop' ? 'Quest log' : 'Quest log dinners' })
expect(await within(list).findByText('Lemon orzo')).toBeInTheDocument()
fireEvent.click(screen.getByRole('button', { name: 'Rebuild week' }))
expect(await screen.findByRole('region', { name: 'Drafting this week' })).toBeInTheDocument()
plan = planBody('draft', ['Lemon orzo', ...NAMES.slice(1)])
questLog = []
job = draftJob('succeeded')
const week = await screen.findByRole('list', { name: 'Dinners this week' }, { timeout: 3000 })
expect(await within(week).findByText('Lemon orzo', {}, { timeout: 3000 })).toBeInTheDocument()
await waitFor(() => expect(within(list).queryByText('Lemon orzo')).not.toBeInTheDocument())
})
})
// Dragging a dinner from desktop's panel or tablet's strip onto a day swaps
+5 -1
View File
@@ -2,6 +2,7 @@ import { useQueryClient } from '@tanstack/react-query'
import { CalendarDays, Check, ChevronLeft, ChevronRight, Plus, RefreshCw, ShoppingCart } from 'lucide-react'
import { useEffect, useId, useMemo, useState, type ReactNode } from 'react'
import { useJob } from '../api/index.ts'
import { QUEST_LOG_KEY } from '../discover/api.ts'
import { Confirm } from '../settings/LeaveGuard.tsx'
import { methodLabels } from '../settings/RegularsSettingsPage.tsx'
import { formatClockTime, useHouseholdSettings } from '../settings/api.ts'
@@ -57,6 +58,7 @@ const draftFailures: Record<string, string> = {
ai_failed: "The AI assistant couldn't draft it.",
confirm_required: 'The plan was pushed to Calendar while it was drafting.',
plan_changed: 'The plan was edited while it was drafting.',
pool_changed: 'A dinner it picked was archived, tried or planned for another week while it was drafting.',
internal_error: 'Something went wrong on the server.',
}
@@ -239,12 +241,14 @@ function WeekBoard({
// Once the job ends the plan is read again: a succeeded draft is followed
// until that read lands; a failed one stays shown, and may have met a
// plan changed meanwhile.
// plan changed meanwhile. The Quest log is read again too, as after a
// swap: the draft may have planned some of it.
const [readJobId, setReadJobId] = useState<string | null>(null)
const ended = job.status === 'succeeded' || job.status === 'failed'
useEffect(() => {
if (!ended) return
let active = true
void queryClient.invalidateQueries({ queryKey: QUEST_LOG_KEY })
void queryClient.invalidateQueries({ queryKey: planKey(weekStart) }).then(() => {
if (active) setReadJobId(jobId)
})