brackt/app/routes.ts

130 lines
4.9 KiB
TypeScript
Raw Normal View History

import { type RouteConfig, index, route } from "@react-router/dev/routes";
export default [
index("routes/home.tsx"),
route("i/:inviteCode", "routes/i.$inviteCode.tsx"),
route("leagues/new", "routes/leagues/new.tsx"),
route("leagues/:leagueId", "routes/leagues/$leagueId.tsx"),
route("leagues/:leagueId/settings", "routes/leagues/$leagueId.settings.tsx"),
route(
"leagues/:leagueId/upcoming-events",
"routes/leagues/$leagueId.upcoming-events.tsx"
),
route(
"leagues/:leagueId/sports-seasons/:sportsSeasonId",
"routes/leagues/$leagueId.sports-seasons.$sportsSeasonId.tsx"
),
route(
"leagues/:leagueId/draft/:seasonId",
"routes/leagues/$leagueId.draft.$seasonId.tsx"
),
route(
"leagues/:leagueId/draft-board/:seasonId",
"routes/leagues/$leagueId.draft-board.$seasonId.tsx"
),
route(
"leagues/:leagueId/standings/:seasonId",
"routes/leagues/$leagueId.standings.$seasonId.tsx"
),
route(
"leagues/:leagueId/standings/:seasonId/teams/:teamId",
"routes/leagues/$leagueId.standings.$seasonId.teams.$teamId.tsx"
),
route("teams/:teamId/settings", "routes/teams/$teamId.settings.tsx"),
route("api/webhooks/clerk", "routes/api/webhooks/clerk.ts"),
route("api/queue/add", "routes/api/queue.add.ts"),
route("api/queue/remove", "routes/api/queue.remove.ts"),
route("api/queue/clear", "routes/api/queue.clear.ts"),
route("api/queue/reorder", "routes/api/queue.reorder.ts"),
route("api/draft/make-pick", "routes/api/draft.make-pick.ts"),
route("api/draft/start", "routes/api/draft.start.ts"),
route("api/draft/pause", "routes/api/draft.pause.ts"),
route("api/draft/resume", "routes/api/draft.resume.ts"),
route("api/draft/force-autopick", "routes/api/draft.force-autopick.ts"),
route("api/draft/force-manual-pick", "routes/api/draft.force-manual-pick.ts"),
route("api/draft/replace-pick", "routes/api/draft.replace-pick.ts"),
route("api/draft/rollback", "routes/api/draft.rollback.ts"),
route("api/draft/adjust-time-bank", "routes/api/draft.adjust-time-bank.ts"),
route("api/autodraft/update", "routes/api/autodraft.update.ts"),
route("api/seasons/:seasonId/draft", "routes/api/seasons.$seasonId.draft.ts"),
route("user-profile", "routes/user-profile.tsx"),
route("how-to-play", "routes/how-to-play.tsx"),
route("rules", "routes/rules.tsx"),
route("support", "routes/support.tsx"),
route("upcoming-events", "routes/upcoming-events.tsx"),
route("test-socket", "routes/test-socket.tsx"),
// Admin routes
route("admin", "routes/admin.tsx", [
index("routes/admin._index.tsx"),
route("sports", "routes/admin.sports.tsx"),
route("sports/new", "routes/admin.sports.new.tsx"),
route("sports/:id", "routes/admin.sports.$id.tsx"),
route("sports-seasons", "routes/admin.sports-seasons.tsx"),
route("sports-seasons/new", "routes/admin.sports-seasons.new.tsx"),
route("sports-seasons/:id", "routes/admin.sports-seasons.$id.tsx"),
route(
"sports-seasons/:id/participants",
"routes/admin.sports-seasons.$id.participants.tsx"
),
route(
"sports-seasons/:id/events",
"routes/admin.sports-seasons.$id.events.tsx"
),
route(
"sports-seasons/:id/events/:eventId",
"routes/admin.sports-seasons.$id.events.$eventId.tsx"
),
route(
"sports-seasons/:id/events/:eventId/bracket",
"routes/admin.sports-seasons.$id.events.$eventId.bracket.tsx"
),
Add CS2 Major Qualifying Points simulator and stage management (#260) * Add CS2 Major qualifying points simulator Implements a full CS2 Major tournament simulator with: - 3-stage Swiss format (Opening Bo1, Elimination Bo1/Bo3, Decider all Bo3) + Champions Stage 8-team single-elimination (QF Bo3, SF Bo3, GF Bo5) - Monte Carlo simulation (10,000 iterations) accumulating QP across 2 majors/season - Sampled 24-team field per iteration: top 12 guaranteed, remaining weighted by 1/rank - Stage 3 exits (placements 9-16) sub-ranked by W-L record (2-3 > 1-3 > 0-3) - Stage assignments stored per-event so actual field composition drives simulation - Admin CS Elo form for entering team Elo + HLTV world rankings - Admin CS2 stage setup page for assigning teams to stages and tracking advancement - Database migration: cs2_major_qualifying_points enum value + cs2_major_stage_results table - 24 unit tests covering all exported pure functions https://claude.ai/code/session_019w21Nkf5TvTZHH6oVHaQXR * Consolidate Elo + ranking input into generic elo-ratings page The darts-elo and cs-elo pages were unreachable from the admin nav, which always links to the generic elo-ratings page. Extended elo-ratings to conditionally show world ranking fields for simulator types that need it (darts_bracket, cs2_major_qualifying_points), then deleted the redundant sport-specific pages. https://claude.ai/code/session_019w21Nkf5TvTZHH6oVHaQXR * Consolidate server postgres connections into one shared pool Four separate postgres() clients were open simultaneously (app, timer, snapshots, socket), each defaulting to 10 connections, exhausting the database's max_connections limit. Replaced with a single shared lazy- initialized client in server/db.ts using a Proxy to defer the DATABASE_URL check until first use (preserving test compatibility). Also bumps the CS2 Champions Stage stochastic test from 200 → 1000 iterations to eliminate flakiness. https://claude.ai/code/session_019w21Nkf5TvTZHH6oVHaQXR * Fix and() bug and add Swiss loop safety guard - cs2-major-stage.ts: markCs2StageEliminations and setCs2FinalPlacements were using JS && instead of Drizzle and(), causing WHERE to filter only by participantId (not scoringEventId), which would update rows across all events instead of just the target event - cs-major-simulator.ts: add break guard in simulateSwiss while loop to prevent infinite loop if pairGroups returns no pairs https://claude.ai/code/session_019w21Nkf5TvTZHH6oVHaQXR * Fix all remaining code review issues - cs2-major-stage.ts: use schema column reference for stageEliminated in markCs2StageEliminations instead of raw SQL string - cs-major-simulator.ts: simulateOneMajor now locks in known stage results when a stage is complete (8 recorded eliminations), only simulating the remaining stages during live events - admin event page: add CS2 Stage Setup button for cs2_major_qualifying_points simulator types; expose simulatorType in server loader type cast - cs2-setup.tsx: replace document.getElementById DOM manipulation with React state (eliminatedChecked map) for checkbox show/hide logic; remove unused stageMap and unassignedParticipants variables https://claude.ai/code/session_019w21Nkf5TvTZHH6oVHaQXR * Fix oxlint errors: non-null assertions, sort→toSorted, unused vars - cs-major-simulator.ts: replace 5 non-null assertions (!) with safe optional chaining / if-guards; replace 6 .sort() with .toSorted() - cs2-major-stage.ts: remove unused `inArray` import - cs2-setup.tsx: remove unused `assignedIds` variable https://claude.ai/code/session_019w21Nkf5TvTZHH6oVHaQXR * Fix flaky Champions Stage stochastic test The makeTeams(8) helper creates only a 70-pt Elo spread (1800→1730). With the Champions Stage bracket math this gives team-0 a ~19.6% win rate — right at the 0.2 threshold, causing the test to fail ~63% of the time in CI despite 1000 iterations. Use 100-pt steps (1800→1100) instead, giving team-0 a ~40% win rate and raising the assertion threshold to 0.25 for a clear safety margin. https://claude.ai/code/session_019w21Nkf5TvTZHH6oVHaQXR --------- Co-authored-by: Claude <noreply@anthropic.com>
2026-04-05 13:40:05 -07:00
route(
"sports-seasons/:id/events/:eventId/cs2-setup",
"routes/admin.sports-seasons.$id.events.$eventId.cs2-setup.tsx"
),
feat: implement Expected Value System with ICM probability calculator Implements Phase 5.2 of the EV system with Harville-Malmuth Independent Chip Model for calculating participant placement probabilities from futures odds. ## Key Features ### ICM Probability Calculator - Implements Harville-Malmuth method for distributing probabilities - Converts American odds to championship probabilities - Generates P(1st) through P(8th) for all participants - Column-normalized: each placement sums to 100% across all teams - Works with any number of participants (not limited to 8) ### Admin UI - Futures Odds Entry - Enter American odds (e.g., +550, -200) for championship futures - Live preview of ICM-calculated probability distributions - Displays all 8 placement probabilities - Persists odds for editing on subsequent visits - Automatic probability normalization (removes bookmaker vig) ### Database Schema Updates - Renamed participant_expected_values.season_id → sports_season_id - Updated foreign key to reference sports_seasons instead of seasons - Added source_odds field to store original futures odds - Migration 0025: Column rename and FK update - Migration 0026: Add source_odds field ### Model Layer - participant-expected-value: CRUD operations for probability distributions - Supports multiple probability sources (manual, futures_odds, elo_simulation) - Automatic EV calculation based on league scoring rules - Probability validation and normalization ### Service Layer - icm-calculator: Harville-Malmuth probability distribution - probability-engine: Odds conversion and Elo utilities (for future use) - bracket-simulator: Monte Carlo simulation (for future hybrid approach) - ev-calculator: Expected value computation from probabilities ## Technical Details - Uses exponential decay favoring top positions for strong teams - Preserves championship probability ordering in final distributions - Row sums vary (strong teams ~100%, weak teams lower) - All probabilities between 0-1, mathematically valid - Comprehensive test suite: 97 tests passing ## Future Enhancements - Hybrid approach: ICM pre-playoffs, bracket simulation during playoffs - Integration with league-specific scoring rules - Historical probability tracking for accuracy analysis 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-17 22:19:46 -08:00
route(
"sports-seasons/:id/expected-values",
"routes/admin.sports-seasons.$id.expected-values.tsx"
),
route(
"sports-seasons/:id/futures-odds",
"routes/admin.sports-seasons.$id.futures-odds.tsx"
),
route(
"sports-seasons/:id/elo-ratings",
"routes/admin.sports-seasons.$id.elo-ratings.tsx"
),
route(
"sports-seasons/:id/surface-elo",
"routes/admin.sports-seasons.$id.surface-elo.tsx"
),
Add golf qualifying points simulator (Plackett-Luce Monte Carlo) (#223) * Add golf QP simulator with Plackett-Luce model, fixes #120 - New `participant_golf_skills` table (migration 0061) for SG: Total and per-major American odds per player/season - New `app/models/golf-skills.ts` with getGolfSkillsMap, getGolfSkillsForSeason, batchUpsertGolfSkills - Full `GolfSimulator` implementation replacing the TODO stub: Plackett-Luce ranking model (PL_BETA=1.5, FIELD_SIZE=156), 10k Monte Carlo iterations, awards QP by finishing position, ranks by total QP across all 4 majors - New admin route `sports-seasons/:id/golf-skills` with bulk CSV import, fuzzy name matching, per-player SG + per-major odds inputs; saves skills and auto-runs simulation on submit - Simulator dropdown on sport admin sorted alphabetically; renamed to "Golf Qualifying Points Monte Carlo" - Golf Skills button shown on sports season admin when simulator type is golf_qualifying_points - Extract normalizeName/diceCoefficient to shared `app/lib/fuzzy-match.ts`, removing duplication from surface-elo and golf-skills routes - Parallelize 4 DB queries in GolfSimulator.simulate() with Promise.all - O(1) field array removal via swap-to-end + pop (was O(N) splice) - Fix source tag: performance_model (not elo_simulation) for SG-based model - 23 unit tests covering americanToImplied, getMajorOddsKey, resolveSkill, simulateMajor, and Monte Carlo calibration properties Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * Fix oxlint errors: no-non-null-assertion and eqeqeq Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-24 21:46:02 -07:00
route(
"sports-seasons/:id/golf-skills",
"routes/admin.sports-seasons.$id.golf-skills.tsx"
),
route(
"sports-seasons/:id/standings",
"routes/admin.sports-seasons.$id.standings.tsx"
),
route(
"sports-seasons/:id/regular-standings",
"routes/admin.sports-seasons.$id.regular-standings.tsx"
),
User/chris/ev f1 framework (#93) * feat: EV simulation framework with F1 Monte Carlo simulator - Add EV snapshot tables (participant_ev_snapshots, team_ev_snapshots) and simulation_status column on sports seasons - Add ev-snapshot model with upsert and history query functions - Add simulator framework: types, bracket/F1/golf simulators, registry - F1 simulator: vig-removed ICM weighted draw (pre-season) + race-by-race Monte Carlo from current standings (in-season); per-position column normalization to prevent floating-point EV drift - Add admin simulate route and Run Simulation button on sports season page - Rework futures-odds admin page to save odds then run simulation in one action - Remove recalculate-probabilities route (superseded by simulate route) - Remove EV trend chart panel and associated DB queries Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * feat: map simulators to sports via simulatorType field Adds a `simulator_type` enum column to the `sports` table so each sport can be assigned a specific simulation algorithm rather than deriving it from the sports season's scoring pattern. - Add `simulatorTypeEnum` (f1_standings, indycar_standings, golf_qualifying_points, playoff_bracket) + `simulatorType` nullable column on `sports` table; migration 0037 - Rewrite simulator registry to key off `SimulatorType` instead of `ScoringPattern`; indycar_standings shares F1Simulator for now - `findSportsSeasonById` now returns `SportsSeasonWithSport` so callers have typed access to `sport.simulatorType` - Simulate and futures-odds actions read `sport.simulatorType`; guard fires before setting `simulationStatus: running` - Admin sport edit page gains a Simulator Type dropdown Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-09 15:34:31 -07:00
route(
"sports-seasons/:id/simulate",
"routes/admin.sports-seasons.$id.simulate.tsx"
),
route("participants", "routes/admin.participants.tsx"),
route("templates", "routes/admin.templates.tsx"),
route("templates/new", "routes/admin.templates.new.tsx"),
route("templates/:id", "routes/admin.templates.$id.tsx"),
route("data-sync", "routes/admin.data-sync.tsx"),
route("standings-snapshots", "routes/admin.standings-snapshots.tsx"),
]),
route(
"api/admin/export-sports-data",
"routes/api.admin.export-sports-data.ts"
),
] satisfies RouteConfig;