* Fix flex spot count in draft room Teams Drafted view
The flexSpots column in the database defaults to 0 and was never
populated, causing the Teams Drafted grid to always show "0 of 0 flex".
Calculate numFlexPicks dynamically in the loader as
max(0, draftRounds - seasonSports.length) so teams see the correct
flex count (e.g. 7 rounds - 5 sports = 2 flex).
https://claude.ai/code/session_01CSzF4aWuyppGBDqM4MJmhc
* Clean up draft room flex calculation area
- Fix bug: force pick dialog now uses its own isolated search/sport
filter state so it no longer mutates the main participants tab filters
- TeamsDraftedGrid: remove dead first pass in flexPicksByTeam memo,
trim season prop to numFlexPicks only, drop unused type field from
picks sport shape
- Loader: derive userAutodraftSettings from already-loaded
autodraftSettings list, eliminating a redundant DB query
- Extract shared transformedPicks, transformedParticipants, and
seasonSportsData into their own useMemos so both eligibility memos
reuse them instead of duplicating the work
- Memoize draftGrid, draftedParticipantIds, and uniqueSports which
were being recomputed on every render
https://claude.ai/code/session_01CSzF4aWuyppGBDqM4MJmhc
---------
Co-authored-by: Claude <noreply@anthropic.com>
* Add push notifications implementation plan
Documents the approach for adding a browser Notification API toggle
to the draft page sidebar, including files to create/modify and
edge cases to handle.
https://claude.ai/code/session_0149MvVUYDY6pFUAV1fL4K69
* Add browser push notifications toggle to draft page
Adds a Notifications toggle in the draft sidebar (below Autodraft)
that uses the Browser Notification API to alert users when a pick is
made or when it's their turn, while the tab is not focused.
- New useDraftNotifications hook for state, permission, and localStorage
- New NotificationSettings component with Switch toggle
- Fires "It's your turn to pick!" when the next pick is the user's
- Fires "{Team} picked {Player}" for all other picks
- Gracefully hides toggle when Notification API is unavailable
https://claude.ai/code/session_0149MvVUYDY6pFUAV1fL4K69
* Fix all code review issues with push notifications
- Extract snake draft order calculation to shared getTeamForPick()
helper in lib/draft-order.ts, removing the duplicated logic
- Fix notification firing on user's own picks (guard with team id check)
- Fix notification firing after draft is complete (early return)
- Use a ref for sendNotification to prevent full socket handler
re-registration every time the toggle is changed
- Add permission drift listener via Permissions API so the UI reacts
if the user revokes notification permission in browser settings
- Add SSR guard for document.hidden in sendNotification
- Remove redundant isSupported prop from NotificationSettings;
derive unsupported state from permissionState === "unsupported"
- Move NotificationSettings out of QueueSection prop-drilling path;
render it via a new settingsSection slot on DraftSidebar instead
https://claude.ai/code/session_0149MvVUYDY6pFUAV1fL4K69
* Fix second round of notification code review issues
- Add My Turn Only / All Picks mode granularity so users can choose
to only be notified when it's their pick, or for every pick
- Remove double top-border by stripping leftover border-t/pt-4/mt-4
wrapper from NotificationSettings (now provided by DraftSidebar)
- Remove unused isSupported from hook return value
- Add n.onclick = () => window.focus() so clicking a notification
brings the draft tab back into focus
- Scope localStorage keys to userId to avoid shared-browser conflicts
(keys now: draftNotifications-{userId}-{seasonId})
- Add notificationsModeRef alongside sendNotificationRef so mode
changes don't trigger full socket handler re-registration
https://claude.ai/code/session_0149MvVUYDY6pFUAV1fL4K69
---------
Co-authored-by: Claude <noreply@anthropic.com>
* Hide EV column from draft board available participants table
https://claude.ai/code/session_016oJK1gmWZ48YWEZmVqm6f9
* Clean up dead expectedValue references after hiding EV column
- Remove expectedValue from AvailableParticipantsSection interface
- Remove EV column from Force Manual Pick commissioner dialog
- Remove expectedValue from participants loader SELECT and parsing step
- Retain ORDER BY expectedValue for default sort order
https://claude.ai/code/session_016oJK1gmWZ48YWEZmVqm6f9
---------
Co-authored-by: Claude <noreply@anthropic.com>
* feat: sync odds-based EV to participants table for draft room ranking
When admin enters futures odds or manual probabilities, the calculated EV
is now synced from participantExpectedValues to participants.expectedValue.
This closes the gap where EVs were calculated but never reflected in the
draft room ranking. Also changes expectedValue from integer to decimal(10,2)
for better precision, and displays "—" for participants with no odds data.
https://claude.ai/code/session_01JWG2zg2EMzCn6RgEufPC1T
* fix: correct expectedValue type to string in participants route
Missed instance of `expectedValue: 0` (number) that failed typecheck
after schema change from integer to decimal.
https://claude.ai/code/session_01JWG2zg2EMzCn6RgEufPC1T
---------
Co-authored-by: Claude <noreply@anthropic.com>
- ICM tests: fix single participant, zero probabilities, and 2-participant
tests to account for simulation only filling min(participants, 8) positions
- TeamScoreBreakdown tests: use getAllByText for "150.0" which now appears
in both the header and the Actual Points summary card
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add FIFA_48 bracket template with 12 groups of 4, knockout stage of 32
- Add tournament groups schema, model, and GroupStageDisplay component
- Add projected/expected value scoring to standings and team breakdowns
- Add docker-compose for local PostgreSQL development
- Move DRAFT_ORDER_IMPLEMENTATION.md to plans directory
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Added recharts dependency to package.json for data visualization.
- Implemented PointProgressionChart component to display team point progression over time.
- Updated scoring-system.md to reflect completion of historical views and added implementation notes.
- Created unit tests for PointProgressionChart to ensure correct rendering and data handling.
- Developed season completion detection and percentage calculation functions in season-helpers.server.ts.
- Added tests for season completion logic and point progression data formatting.
- Enhanced league loader to fetch necessary data for current season and teams.
- Created `TeamScoreBreakdown` component to display all drafted participants, their placements, and points.
- Added new route for team breakdown at `/leagues/:leagueId/standings/:seasonId/teams/:teamId`.
- Enhanced `getTeamScoreBreakdown` model to include `sportsSeasonId` for grouping.
- Updated `StandingsTable` to include clickable team name links.
- Added functionality to finalize brackets in playoff events, including error handling and recalculating standings.
- Implemented tests for `TeamScoreBreakdown` component to ensure proper rendering and functionality.
- Updated routing to support new team breakdown feature and ensure seamless navigation.
- Added a new route for league standings: `/leagues/:leagueId/standings/:seasonId`
- Implemented the `StandingsTable` component to display team standings with ranking, points, and placement breakdown.
- Integrated tiebreaker logic for ranking teams based on total points and placements.
- Enhanced the league home page with a link to view standings.
- Updated scoring system documentation to reflect the new standings features.
- Added comprehensive tests for tiebreaker logic and `StandingsTable` component.
- Created shared types for standings to be used in both server and client code.
- Added `QualifyingPointsStandings` component to display standings based on qualifying points.
- Introduced scoring rules and projected points calculation for participants.
- Implemented tie handling for rankings and displayed appropriate UI elements based on finalization status.
- Created tests for qualifying points configuration, accumulation logic, ranking logic, and scoring workflow.
- Developed scoring calculator tests to validate fantasy points conversion from qualifying points.
- Established qualifying points management functions including initialization, retrieval, updating, and resetting of points.
- Added a comprehensive plan for bracket expansion, including support for 4, 8, 16, 32, and 68 team formats.
- Introduced a template-based bracket system with predefined templates for NCAA March Madness, NFL Playoffs, NBA Playoffs, and simple brackets.
- Updated UI flow for bracket creation, allowing admins to select templates and assign participants flexibly.
- Enhanced database schema to accommodate new scoring rules and bracket templates.
- Proposed updates to scoring logic to handle non-scoring rounds and participant placements correctly.
- Documented implementation phases for gradual rollout of new features.
- Addressed critical bugs in the playoff event processing and scoring logic, ensuring proper advancement and scoring rules across multiple leagues.
- Created ScoringRulesEditor component with 8 placement point inputs
- Added scoring-types.ts for shared client/server types
- Integrated scoring rules into league settings page
- Integrated scoring rules into league creation form
- Added validation for point values (0-1000 range)
- Disabled editing in settings after draft starts
- Included helpful tips and preview display
Phase 1.3 complete
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Added AvailableParticipantsSection for participant search and filtering.
- Created DraftGridSection for displaying the draft grid with team timers and context menu.
- Developed QueueSection for managing participant queue and autodraft settings.
- Introduced RecentPicksSection to show recent draft picks.
- Implemented TeamsDraftedGrid to visualize drafted participants by team and sport.
- Added collapsible UI components for better layout management.
- Established tabbed navigation for draft board, recent picks, and teams drafted.
- Enhanced responsiveness for mobile and desktop views.
- Updated styles for a cohesive design across components.