Problem
getFestivalPhase is deep and tested (ADR-0003), but mapping (edition, festival, now) into its 5-field input — including the draft/null defaulting policy — is copy-pasted with subtle differences at three call sites:
src/hooks/useFestivalPhase.ts:10-19 — defaults ?? "draft" / ?? null
src/routes/festivals/$festivalSlug/editions/$editionSlug.tsx:23-32 — trusts non-null columns
src/pages/admin/festivals/FestivalEdition.tsx:57-63 — defaults again
The seam between "an Edition row" and "phase input" has no adapter, so the defaulting policy is re-decided per caller.
Proposed deepening
One phaseInputFromEdition(edition, festival, now) adapter owning the null-defaulting policy; callers never re-list revealLevel/startDate/endDate/timezone/now. Smallest candidate — low-risk, strengthens an existing ADR-0003 seam.
Relations
Architecture note
Explore ticket from the 2026-07-13 architecture review (candidate 7, speculative). Design to be settled in a grilling session before implementation. Vocabulary per /codebase-design.
Problem
getFestivalPhaseis deep and tested (ADR-0003), but mapping(edition, festival, now)into its 5-field input — including the draft/null defaulting policy — is copy-pasted with subtle differences at three call sites:src/hooks/useFestivalPhase.ts:10-19— defaults?? "draft"/?? nullsrc/routes/festivals/$festivalSlug/editions/$editionSlug.tsx:23-32— trusts non-null columnssrc/pages/admin/festivals/FestivalEdition.tsx:57-63— defaults againThe seam between "an Edition row" and "phase input" has no adapter, so the defaulting policy is re-decided per caller.
Proposed deepening
One
phaseInputFromEdition(edition, festival, now)adapter owning the null-defaulting policy; callers never re-listrevealLevel/startDate/endDate/timezone/now. Smallest candidate — low-risk, strengthens an existing ADR-0003 seam.Relations
useSuspenseQuery) rewires the same call sites — coordinate, or let this ride along with Consolidate festival/edition reads onto useSuspenseQuery, delete FestivalEditionContext #152.Architecture note
Explore ticket from the 2026-07-13 architecture review (candidate 7, speculative). Design to be settled in a grilling session before implementation. Vocabulary per
/codebase-design.