Whole-branch review — fix/r1-allday-week-and-edit @ 55b6575 vs origin/main 5b9f0b6
Reviewed by Claude Fable 5.1 (claude-fable-5-1), session 21a32889, as the AGENTS.md whole-branch reviewer. One diff, scratch worktree, branch not edited.
VERDICT: APPROVE-WITH-NITS
What I checked and how
- B8 fixed at the root. The week grid is now rows of one CSS grid (heads, one optional all-day row, then
cal-hours+ sevencal-column), so nothing above a column can offset it.cal-column-headleftcal-hours, so the gutter no longer needs the head's height to line up. Day view keeps its own all-day strip ([cal-allday]unchanged) and only gains theshortmarker. Every chip still prints time and title, so the one-line layout does not lean on colour (AGENTS.md). - B9 fixed at the root. All-day events render
field-datewith the stored bare dates; timed events keepfield-datetime. Scriptless floor holds:readEventForm→formTimeaccepts either shape. - Time-zone correctness of the parse change (
handlers_event_form.go:119). No instant is ever formed:formTimeonly slices or appends a wall-clock STRING. Under All day,2026-09-23T23:30→2026-09-23is the date part of what was typed in the form's own zone (the person's, or the booked event's hiddentz), no UTC round trip, so it cannot land on the wrong day west of Greenwich; the validator then clearstzas the rule requires. Without All day, a bare date →T00:00is midnight in that sametz, resolved byToUTClike any typed midnight (the DST-gap rule inclock.goapplies, as it would to a typed one). Timed events with a normal datetime pass through untouched (len == 16), and an all-day bare date passes through untouched — only the two mismatched shapes are rewritten; anything else still reaches the validator to be refused. - Tests exercise the fix — verified, not trusted. I copied
allday_views_test.goonto clean origin/main: all four fail there (0 all-day cells; noshortmarker;type="datetime-local"on the all-day edit form; 422 on the toggle). I copiedplaywright_week_test.go+week.mjsonto clean main withnode_modulessymlinked from meet: it fails with exactly the audit's numbers (column tops 228/228/270…, 10:00 chip at 750 vs label line 708, 5px-tall title,input.value"" with and without JS). On the branch:make ciexit 0, no cached packages, the four new tests shown RUNning with-v;go test -tags browser -run InARealBrowserpasses all three browser tests (booking, quick add, week) including the JS-off pass. - Regressions elsewhere.
AnyAllDayis week-only;PlacedChip.Shortis additive;formTimeis used only byreadEventForm, shared by create and update — both covered. No migrations. - Pre-existing flake
TestTransientControlFailureAtBootRecoversreproduced on clean main (1 of 3 runs); unrelated to this branch.
Findings (none blocking)
- Medium nit —
handlers_event_form.go:119,formTimeunder All day truncates the END down. The commonest toggle — open a 10:00–11:00 event, tick All day, save — submits…T10:00/…T11:00, both truncate to the same date, and the validator answers 422 "An all-day event ends on the following day." (I probed it: 422.) It was a 422 before too, so no regression, but the discussion says ticking All day "always failed" and now works — it works only for multi-day events. Worse,7th 10:00 → 8th 17:00becomes7th → 8thexclusive, i.e. the event no longer covers the 8th (probed: stored end2026-10-08). Suggested fix: for the END only, round UP to the next date when the time part is not00:00(ceil), so 10:00–11:00 becomes one day and 7th–8th 17:00 becomes two. AGENTS.md prefers refusing over silently correcting, so if you would rather not ceil, then the same-day case should at least be turned into a validation message that says what to do ("Set Ends to the following day"). - Nit —
week.html.cal-column-headisposition: stickyand now a direct grid child; the all-day row is not sticky, so on scroll it slides under the heads. Fine, and probably what you want, but the 48remmin-inline-sizefallback should be looked at on a phone once, since the row now spans eight cells. - Nit —
viewdata.go:150.Shortis a per-chip layout decision computed fromHeightPct/100*(dayEnd-dayStart), which on a 23/25-hour DST day is right (it uses the real span, not 24h) — worth a two-word note in the comment so nobody "fixes" it to< 1hfrom the event's own duration. - Housekeeping.
node_modules(symlink) is untracked in my scratch tree; confirm it is not in the branch (it is not —git diff --name-onlyshows none) and that.gitignorecovers it before anyone runsmake browserin the shared checkout.