Skip to content

feat(schedule): add configurable day-start hour - #463

Open
chiptus wants to merge 3 commits into
mainfrom
feat-86/festival-day-start-hour
Open

chiptus wants to merge 3 commits into
mainfrom
feat-86/festival-day-start-hour

Conversation

@chiptus

@chiptus chiptus commented Aug 29, 2026

Copy link
Copy Markdown
Owner

Adds festivals.day_start_hour (0-23, default 0) so a festival can fold post-midnight sets into the previous festival day instead of always splitting at exact midnight. Widens the existing day-key seam (getFestivalDayKey/formatDayOnly) and threads the cutoff through schedule grouping, the day filter, the days reveal level, and the horizontal timeline's day boundaries/jump targets.

Closes #86

Verification

  • Set a festival's day-start hour to 0 (default): schedule list, timeline, day filter, and reveal-level day labels render identically to before.
  • Set a festival's day-start hour to 6 in the festival edit dialog: a ~02:00 set moves under the previous festival day in both the list and the horizontal timeline; the day filter and the days-reveal display agree; the day header reads the previous date.
  • Confirm the day filter dropdown offers the shifted day as an option (not just the edition's raw calendar-date range).
  • pnpm run typecheck, pnpm run lint, pnpm exec vitest run, and pnpm run build all pass.

Note: the issue's spec mentioned following "the existing react-hook-form pattern" in the festival edit dialog, but that dialog (FestivalDialog.tsx) actually uses plain useState, not react-hook-form — the new field follows the file's actual existing pattern instead.


Generated by Claude Code

claude added 2 commits August 29, 2026 16:09
Add festivals.day_start_hour (0-23, default 0) so a festival can fold
post-midnight sets into the previous festival day instead of always
splitting at exact midnight. Widens the existing day-key seam
(getFestivalDayKey/formatDayOnly) and threads the cutoff through
schedule grouping, the day filter, the days reveal level, and the
horizontal timeline's day boundaries/jump targets. Admin can set the
cutoff in the festival edit dialog.

Closes #86
…lter

Self-review follow-up on the day-start-hour change: extract the
repeated "shift by cutoff" and "day-key -> boundary instant" logic
into shared timeUtils helpers instead of duplicating it across three
timeline modules, and make DayFilterSelect's day options honor the
cutoff too (a pre-cutoff set on the edition's first calendar day can
fold onto the previous day's key, which the filter dropdown needs to
offer).
Copilot AI lite review requested due to automatic review settings August 29, 2026 16:17
@vercel

vercel Bot commented Aug 29, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
upline Ready Ready Preview Sep 13, 2026 6:36am UTC

@chiptus chiptus added the agent:pr label Aug 29, 2026 — with Claude
@github-actions

github-actions Bot commented Aug 29, 2026

Copy link
Copy Markdown

Deploy → stagingworkflow run
Last updated: 2026-09-13 06:36:19 UTC

  • ⏭️ DB migrations skipped (no changes)
  • ⏭️ Edge functions skipped (no changes)
  • ⏭️ Type generation skipped (no changes)

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

The current dayStartHour implementation in src/lib/timeUtils.ts shifts instants in UTC before timezone formatting, which can misclassify festival days around DST transitions.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Pull request overview

Adds a per-festival day_start_hour cutoff (defaulting to midnight) so post-midnight sets can be grouped/labelled under the previous “festival day”, and threads that cutoff through schedule grouping, day filtering, reveal-level day labels, and the horizontal timeline’s day boundaries/jump behavior.

Changes:

  • Adds festivals.day_start_hour (0–23, default 0) to the database schema and Supabase generated types, and wires it into festival create/update flows and the admin festival edit dialog.
  • Extends the “festival day key” seam (getFestivalDayKey / formatDayOnly) and propagates dayStartHour through schedule list/timeline grouping, timeline geometry/boundaries/jump targets, and active-day detection.
  • Reworks day-filter option generation to include a leading shifted day when a cutoff is configured, and adds unit tests across the updated time/day utilities.
File summaries
File Description
supabase/migrations/20260829160000_add_festival_day_start_hour.sql Adds day_start_hour column + range check constraint on festivals.
src/routes/festivals/$festivalSlug/editions/$editionSlug/schedule/timeline.tsx Passes festival.day_start_hour into schedule/timeline data and container.
src/routes/festivals/$festivalSlug/editions/$editionSlug/schedule/list.tsx Threads dayStartHour through list schedule grouping and memo deps.
src/pages/SetDetails/SetInfoCard.tsx Uses formatDayOnly(..., day_start_hour) for reveal-level day display.
src/pages/SetDetails/NonMusicSetDetail/NonMusicSetBanner.tsx Uses formatDayOnly(..., day_start_hour) for reveal-level day display.
src/pages/SetDetails/MultiArtistSetInfoCard.tsx Uses formatDayOnly(..., day_start_hour) for reveal-level day display.
src/pages/EditionView/tabs/VoteTab/SetCard/SetMetadata.tsx Uses formatDayOnly(..., day_start_hour) for reveal-level day display.
src/pages/EditionView/tabs/ScheduleTab/horizontal/timeScaleGeometry.ts Makes date-change detection use festival-day keys with dayStartHour.
src/pages/EditionView/tabs/ScheduleTab/horizontal/timeScaleGeometry.test.ts Adds unit test for cutoff folding behavior in date-change detection.
src/pages/EditionView/tabs/ScheduleTab/horizontal/TimeScaleContainer.tsx Adds dayStartHour prop and passes it to TimeScale.
src/pages/EditionView/tabs/ScheduleTab/horizontal/TimeScale.tsx Passes dayStartHour to computeDateChanges.
src/pages/EditionView/tabs/ScheduleTab/horizontal/TimelineToolbar.tsx Threads dayStartHour into day jump controls.
src/pages/EditionView/tabs/ScheduleTab/horizontal/TimelineOverview.tsx Threads dayStartHour into day-boundary calculation.
src/pages/EditionView/tabs/ScheduleTab/horizontal/TimelineContainer.tsx Adds dayStartHour prop and threads into scroll sync / overview / scale.
src/pages/EditionView/tabs/ScheduleTab/horizontal/DayJumpButtons.tsx Passes dayStartHour into getDayJumpMoment.
src/pages/EditionView/tabs/ScheduleTab/DayFilterSelect.tsx Switches to buildDayFilterOptions(...) and includes festival cutoff.
src/pages/admin/festivals/FestivalDialog.tsx Adds admin UI input for day_start_hour with clamping (0–23).
src/lib/timeUtils.ts Extends festival-day key/label utilities and introduces festivalDayStart.
src/lib/timeUtils.test.ts Adds tests for cutoff behavior in getFestivalDayKey and formatDayOnly.
src/lib/timelineOverviewGeometry.ts Uses festivalDayStart for boundary placement with cutoff support.
src/lib/timelineOverviewGeometry.test.ts Adds/updates tests for cutoff-aware boundary placement.
src/lib/timelineMountMoment.ts Makes timeline mount moment resolve day-start using cutoff-aware boundary.
src/lib/timelineMountMoment.test.ts Adds tests for cutoff-aware mount moment behavior.
src/lib/timelineDayJump.ts Makes day jump fallback use cutoff-aware day start instead of midnight.
src/lib/timelineDayJump.test.ts Adds test for cutoff-aware day jump fallback.
src/lib/dayFilterOptions.ts New helper to build day-filter options, adding leading shifted day if needed.
src/lib/dayFilterOptions.test.ts Unit tests for new day-filter option builder behavior.
src/integrations/supabase/types.ts Updates generated DB types to include festivals.day_start_hour.
src/hooks/useTimelineScrollSync.ts Threads dayStartHour into timeline mount-moment resolution.
src/hooks/useScheduleData.ts Uses cutoff-aware festival day keys when grouping sets into schedule days.
src/hooks/useActiveTimelineDay.ts Uses cutoff-aware day jump moments when computing active day offsets.
src/api/festivals/useUpdateFestival.ts Allows updating day_start_hour via mutation typing.
src/api/festivals/useCreateFestival.ts Allows setting day_start_hour on create via mutation typing.
docs/adr/0002-festival-timezone-display.md Updates ADR to reflect the now-implemented configurable cutoff.
Review details

Suppressed comments (1)

src/lib/timeUtils.ts:208

  • dayStartHour is defined in the festival's timezone, but the current implementation shifts the UTC instant with subHours before formatting in the target timezone. Around DST transitions this can produce the wrong festival-day key (e.g., after a spring-forward, subtracting N hours in UTC can subtract N±1 hours in local time), misgrouping sets and timeline day boundaries.
// festival's day rather than the viewer's. `dayStartHour` (0-23, the
// festival's configured day-start cutoff) shifts the instant back by that
// many hours first, so sets before the cutoff fold into the previous
// festival day instead of splitting at exact midnight.
  • Files reviewed: 34/34 changed files
  • Comments generated: 1
  • Review effort level: Lite

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread src/lib/timeUtils.ts
@github-actions

github-actions Bot commented Aug 29, 2026

Copy link
Copy Markdown

Playwright test results

passed  65 passed

Details

stats  65 tests across 21 suites
duration  1 minute, 29 seconds
commit  4bd6757

…start-hour

# Conflicts:
#	src/api/festivals/useUpdateFestival.ts
#	src/pages/EditionView/tabs/VoteTab/SetCard/SetMetadata.tsx
#	src/pages/SetDetails/MultiArtistSetInfoCard.tsx
#	src/pages/SetDetails/NonMusicSetDetail/NonMusicSetBanner.tsx
#	src/pages/SetDetails/SetInfoCard.tsx
chiptus pushed a commit that referenced this pull request Sep 13, 2026
Replaces the two lifecycle labels with a single `agent` label whose
stage is read off the issue's native Linear status (In Progress while
claimed, In Review once the PR is open) instead of a second label.
Retired agent:wip/agent:pr in Linear (team UPL) and migrated the one
live issue carrying agent:pr (UPL-7, open PR #463) to
the new scheme. Also updates the setup-chiptus-env Linear template to
match; the GitHub template is unchanged since GitHub issues have no
native per-issue status to borrow.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HFNqcr5d2EN6T6TkTc8WBd
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Configurable festival "day end" hour so post-midnight sets group with the previous night

3 participants