This document groups the integrity rules, discarded artifacts, and season-related constraints extracted from the original schema v2 design document.
| Legacy table | Design name | File | Reason |
|---|---|---|---|
match_statistics |
(discarded) | src/db/schema/match_statistics.ts |
Zero reads/writes in app code. Irrelevant for W/D/L scoring. |
point_adjustments |
(discarded) | src/db/schema/point_adjustments.ts |
Zero reads/writes in app code. |
team_transfer_availability |
(discarded) | src/db/schema/team_transfer_availability.ts |
Derivable from existing data. |
Precondition: A fresh grep against the entire repo confirmed 0 reads and 0 writes
per table before exclusion.
| Table | Column | Reason |
|---|---|---|
fantasy_league_participants |
currentPosition |
Duplicated; lives in fantasy_rankings |
fantasy_league_participants |
totalPoints |
Duplicated; lives in fantasy_teams.totalPoints |
fantasy_roster_entries (was fantasy_team_players) |
weeklyPoints |
Grep confirms nothing writes it |
fantasy_roster_entries (was fantasy_team_players) |
totalPoints |
Grep confirms nothing writes it |
fantasy_roster_entries (was fantasy_team_players) |
points |
Grep confirms nothing writes it |
fantasy_roster_entries (was fantasy_team_players) |
isActive |
Moved to window_lineups.is_active |
fantasy_leagues |
maxTeamsPerParticipant |
Deceptive — see §4 evaluation below |
These constraints are already defined and exported in the current schema but never applied to the database. They encode integrity invariants the team identified — they are activated as-is in schema v2:
| Source File | Constraint | Purpose |
|---|---|---|
active_rosters_history.ts |
sequential_versions |
UNIQUE (roster_id, version) |
active_rosters_history.ts |
games_played_limit |
Subquery check |
active_rosters_history.ts |
valid_status_transitions |
ACTIVE→DEACTIVATED→TRANSFERRED |
active_rosters_history.ts |
valid_transfer_refs |
TRANSFERRED requires transfer_history_id |
active_rosters_history.ts |
version_sequence |
Sequential version numbering |
point_calculation_events.ts |
match_id_required_for_match_events |
— |
point_calculation_events.ts |
valid_point_category |
BASE/BONUS/PENALTY consistency |
point_calculation_events.ts |
valid_status_transitions |
PENDING→CONFIRMED→DISPUTED→ADJUSTED |
fantasy_team_window_points.ts |
unique_team_window_points |
UNIQUE (fantasy_team_id, window_id) |
fantasy_team_window_points.ts |
points_calculation_check |
total = base + bonus - penalty |
fantasy_team_window_points.ts |
base_points_match_events |
Subquery check |
fantasy_team_window_points.ts |
bonus_points_match_events |
Subquery check |
fantasy_team_window_points.ts |
penalty_points_match_events |
Subquery check |
fantasy_team_window_points.ts |
valid_status_transitions |
PROVISIONAL/FINAL |
fantasy_team_window_points.ts |
unique_rank_per_window |
EXCLUDE on btree |
transfer_requests.ts |
valid_priority_range |
Priority 1-3 |
transfer_requests.ts |
valid_user_order_range |
User order 1-3 |
transfer_requests.ts |
unique_priority_per_window |
UNIQUE per team/window |
transfer_requests.ts |
unique_user_order_per_window |
UNIQUE per team/window |
transfer_requests.ts |
requests_per_window_limit |
≤3 per team per window |
Note: The active_rosters_history constraints reference a table that is being replaced by
window_lineups. These constraints should be re-evaluated and ported to window_lineups during
the migration.
Applied. Fantasy leagues are now explicitly tied to a season via fantasy_leagues.season.
Problem: The current code uses getCurrentSeasonYear() — a global function that returns the
current year's season based on the calendar month. This means:
draft_settings.active_season and point calculation's season can disagreeSolution: fantasy_leagues.season is the single source of truth. The constraint chain:
fantasy_leagues.season = 2025
├── fantasy_league_game_limits → soccer_leagues WHERE season = 2025
├── draft_settings reads season from fantasy_leagues (removes active_season)
└── point_calculation filters matches WHERE soccer_leagues.season = fantasy_leagues.season
Code changes required:
| File | Current | Proposed |
|---|---|---|
point-calculation.ts:49 |
getCurrentSeasonYear() |
Read from fantasy_leagues.season |
point-calculation.ts:230 |
getCurrentSeasonYear() |
Read from fantasy_leagues.season |
point-calculation.ts:536 |
getCurrentSeasonYear() |
Read from fantasy_leagues.season |
draft/[leagueId]/pick.ts:164 |
currentSettings.activeSeason |
fantasy_leagues.season |
draft/[leagueId]/auto-pick.ts:217 |
currentSettings.activeSeason |
fantasy_leagues.season |
publicLeagueService.ts:265 |
activeSeason: currentSeason |
season: getCurrentSeasonYear() |
Constraints added:
fantasy_leagues.season — CHECK constraint: season >= 2020 AND season <= 2100fantasy_league_game_limits — CHECK constraint: soccer league season must match fantasy league seasonsoccer_leagues — UNIQUE constraint: (api_id, season)