- Fix UTC midnight rollover bug: server now queries from yesterday UTC
as a buffer; UpcomingCalendarPanel filters to local-today client-side
via useEffect + Intl.DateTimeFormat, removing the need for any
cookie or server-side timezone detection
- Cap homepage and league page panels at 6 events with a "View all" link
- Add /upcoming-events page (60-day view across all leagues)
- Add /leagues/:leagueId/upcoming-events page (60-day per-league view)
- Add emptyMessage prop to UpcomingCalendarPanel for context-specific copy
- Change getUpcomingEventsForDraftedParticipants to accept pre-computed
date strings instead of Date objects
fixes#213
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
* Add oxlint and fix all lint errors
- Install oxlint, add .oxlintrc.json with rules for TypeScript/React
- Add npm run lint / lint:fix scripts
- Add Claude PostToolUse hook to run oxlint on every edited file
- Fix 101 errors: unused vars/imports, eqeqeq, prefer-const, no-new-array
- Fix no-array-index-key (use stable keys or suppress positional cases)
- Fix exhaustive-deps missing dependency in useEffect
- Promote exhaustive-deps and no-array-index-key to errors
- Fix Map.get() !== null bug in $leagueId.server.ts (should be !== undefined)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* Fix no-explicit-any warnings and upgrade tsconfig to ES2023
- Replace all `any` types with proper types or `unknown` across ~20 files
- Add typed socket payload interfaces in draft route and useDraftSocket
- Use any[] with eslint-disable for socket.io callbacks (legitimate escape hatch)
- Bump all tsconfigs from ES2022 → ES2023 to support toSorted/toReversed
- Fix cascading type errors uncovered by removing any: Map.get narrowing,
participant relation types, ChartDataPoint, Partial<NewSeason> indexing
- Add ParticipantResultWithParticipant type to participant-result model
- Fix test fixtures to match updated interfaces (DraftCell, ParticipantResult)
- Fix duplicate getQPStandings import in sportsSeasonId.server.ts
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* Promote no-explicit-any to error
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
- New `event_starts_at timestamptz` column on `scoring_events`; backfilled
from `event_date` (midnight UTC) via migration for all existing rows
- Admin create/edit forms consolidated from separate Date + Time inputs into
a single `datetime-local` field; server derives `eventDate` from the UTC
date portion of `eventStartsAt` so calendar-window queries continue to work
- Edit form pre-fill computed client-side via useEffect to avoid server-timezone
mismatch for non-UTC admins
- Sort fix: replaced `eventDate ?? earliestGameTime.split("T")[0]` with
`toEventSortKey` helper that prefers `earliestGameTime ?? eventDate` so
bracket events with only per-game timestamps sort in the correct calendar position
- DB sort queries updated to use `eventStartsAt` as a tiebreaker after `eventDate`
- F1/IndyCar/golf events now populate `earliestGameTime` from `eventStartsAt`,
giving time display in `UpcomingCalendarPanel`
- Bulk import gains optional `HH:MM` (UTC) third column
- New unit tests for `toEventSortKey` and `eventStartsAt` model behavior
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
* Show leagues where user is a member regardless of team assignment
The homepage now uses a union query to show leagues where the user
either has a team in the current season OR is a commissioner. Previously,
commissioners without a team could not see their leagues on the homepage.
https://claude.ai/code/session_01E3ugKTfatkEc5TcDGXvHiW
* Fix stale empty state card title in home route
Update 'No Active Leagues' to 'No Leagues' to match the updated
description which is now about membership rather than active seasons.
https://claude.ai/code/session_01E3ugKTfatkEc5TcDGXvHiW
* Fix union import: use two queries with JS deduplication
drizzle-orm 0.36.x does not export a standalone union() function.
Replace with two awaited queries merged via a Map (dedup by id),
then sorted by createdAt descending in JS.
https://claude.ai/code/session_01E3ugKTfatkEc5TcDGXvHiW
---------
Co-authored-by: Claude <noreply@anthropic.com>