League / Series Management
En resumen
Season-long league management for inter-club, inter-district, and individual leagues with configurable divisions, hierarchy, fixtures, composite match days (Bundesliga 3 sub-matches, France D1N 9 parties), promotion/relegation, multi-phase seasons, transfer quarantine, and per-league court and substitution rules.
Cómo funciona
A league is created with divisions, tiers, and pools configured per tenant. Each league declares its league_type (inter_club, individual, mixed) and scope (club, district, region) — district/region leagues require district_id on every team and block duplicate districts in the same division. Team rosters carry a max-players-per-season cap (Germany Bundesliga = 10) validated on register and update.
A registration_deadline gates roster changes inclusively; admins open registration via POST /leagues/{id}/open-registration (requires at least one division) and close it via POST /leagues/{id}/close-registration. Fixture generation produces home/away round-robin (single or double) using a home_venue_map. Composite match day is the league's secret sauce: the league declares a CompositeMatchDayConfig describing the format — Germany Bundesliga (1 triplette + 1 doublette + 1 mixed doublette), France D1N (3 triplettes + 3 doublettes + 3 tête-à-tête = 9 parties) — and each match day result is the sum of its sub-matches.
Player-count per sub-match is validated against GameFormat.players_per_team. Player eligibility runs four checks (roster, license active, not transferred, club match) and bulk-checks via POST /leagues/{id}/divisions/{level}/teams/{club_id}/check-eligibility before sub-matches are recorded. League standings drive promotion/relegation with configurable spots per tenant; tiebreakers cascade (Sweden: points → wins → klotskillnad → head-to-head → lottery), and championship brackets seed from final standings (rounds_total = 2 for home+away, duplicate brackets blocked with 409).
Multi-phase seasons let the format mutate between phases (round_robin → knockout → swiss → monrad), with carry-over points and transition criteria (top_n / threshold / all). League hierarchy chains parent_league_id and league_level so France D1N → D2N → D3N → DR → DD or Germany Bundesliga → Landesliga → Bezirksliga can be browsed as a tree. Transfer quarantine protects competitive integrity during active seasons (configurable scope: tenant, player_league, or none).
Player statistics expose top scorers and most wins via /leagues/{id}/player-statistics with public mirrors. Substitution constraints (Spain Liga Nacional reserves locked to a sub-match), promotion via standalone tournament (Germany Aufstiegsrunde), and court specification enforcement (Spain pista cerrada 50/100 cm rules) are configured per league.
Capacidades clave
- Inter-club, individual, mixed, and district/region leagues with hierarchy (parent_league_id, league_level)
- Composite match day (Bundesliga 3 sub-matches, France D1N 9 parties) with per-format roster validation
- Configurable promotion/relegation, tiebreakers, and championship brackets seeded from standings
- Multi-phase seasons (round_robin → knockout → swiss → monrad) with carry-over and transition criteria
- Player eligibility (roster, license, transfer, club) checked before sub-match recording
- Transfer quarantine, max-players-per-season caps, and registration-deadline enforcement
- Per-league substitution constraints, court specifications, and standalone-tournament promotion paths
En la práctica
A German Landesverband admin opens its Landesliga, registers eight clubs into Division 1 with rosters of 10 players each, and triggers fixture generation. The system produces 14 match days using composite format (1 triplette + 1 doublette + 1 mixed doublette), respecting home venues. On match day 5 a club tries to field a player who transferred clubs in October; eligibility check returns not_transferred = false and blocks the sub-match.
After the regular season, the top finisher enters the Aufstiegsrunde standalone tournament where 10 Landesmeister play round-robin; the top 4 promote to Bundesliga. The relegated team carries no points into next season's lower division.
Funcionalidades de este subsistema
21| ID | Status | Funcionalidades |
|---|---|---|
| F04.08.01 | Entregado | League creation (divisions, tiers, pools) — configurable per tenant — PL-F0408a ✅ PL-F0408a |
| F04.08.02 | Entregado | Promotion/relegation rules (automatic + playoff, configurable spots per tenant) — PL-F0408a ✅ PL-F0408a |
| F04.08.03 | Entregado | Home/away fixture generation (round-robin, single or double) — PL-F0408a ✅ PL-F0408a |
| F04.08.04 | Entregado | Configurable tiebreaker rules per tenant — Sweden: points → wins → klotskillnad → head-to-head → lottery. Other nations may differ. — PL-F0408a ✅ PL-F0408a |
| F04.08.05 | Entregado | Match postponement and rescheduling with audit trail + tenant deadline enforcement — PL-F0408a ✅ PL-F0408a |
| F04.08.06 | Entregado | Season results archive with public endpoints and cross-league search — PL-F0408a ✅ PL-F0408a |
| F04.08.07 | Entregado | Team roster with max players per season — configurable per tenant (e.g., Germany Bundesliga: max 10 players per team per season). max_players_per_team på League, valideras vid register_team + update_roster. — PL-F0408b ✅ PL-F0408b |
| F04.08.08 | Entregado | League registration deadline and team enrollment. registration_deadline på League (date, optional). POST /leagues/{id}/open-registration (setup→registration, kräver minst en division), POST /leagues/{id}/close-registration (registration→active). Deadline kontrolleras inklusivt vid teamregistrering och roster-uppdatering. — PL-F0408b ✅ PL-F0408b |
| F04.08.09 | Entregado | Composite match day — a league match day consists of multiple sub-matches. Configurable format per league: Germany Bundesliga (1 triplette + 1 doublette + 1 mixed doublette), France D1N (3 triplettes + 3 doublettes + 3 tête-à-tête = 9 parties), Denmark (similar). Match day result = sum of sub-match results. CompositeMatchDayConfig stöder name/description; spelarantal per sub-match valideras mot GameFormat.players_per_team; GET /leagues/{id}/match-day-summary med round_number-filter. — PL-F0408b ✅ PL-F0408b |
| F04.08.10 | Entregado | Player eligibility per match (registered in roster, not suspended, not transferred). Service check_player_eligibility() med 4 kontroller: roster, license_active, not_transferred, club_match. Bulk-endpoint POST /leagues/{id}/divisions/{level}/teams/{club_id}/check-eligibility. Eligibilitetsfel blockerar sub-match-recordning. — PL-F0408b ✅ PL-F0408b |
| F04.08.11 | Entregado | League statistics (top scorers, most wins, etc.). GET /leagues/{id}/player-statistics med sort_by (total_points_scored/matches_won/sub_matches_won/matches_played) och division_level-filter. Publik spegling GET /public/leagues/{id}/player-statistics. — PL-F0408b ✅ PL-F0408b |
| F04.08.12 | Entregado | Inter-club league (clubs send teams). league_type (inter_club/individual/mixed) på League. Inter_club: klubbar valideras mot Club-samlingen, en klubb kan ej registreras i flera divisioner i samma liga (409), holdfællesskab via club_ids (2+ klubbar som ett lag). GET /leagues/?league_type= filter. — PL-F0408b ✅ PL-F0408b |
| F04.08.13 | Entregado | Inter-region/district league (regional all-star teams or district series). scope (club/district/region) och district_id på League; district_id på LeagueTeam; validering att district_id krävs vid teamregistrering i district/region-liga; duplikat-district i samma division blockeras (409). — PL-F0408c ✅ PL-F0408c |
| F04.08.14 | Entregado | Playoff generation from league standings. championship-bracket-typ; seeded_from_standings; rounds_total (2 = hem+borta); seed_from_phase; duplikat-bracket skyddas (409). — PL-F0408c ✅ PL-F0408c |
| F04.08.15 | Entregado | League calendar with venue rotation. GET /leagues/{id}/calendar (rounds grupperade med fixture-detaljer, from_date/to_date-filter); GET /public/leagues/{id}/calendar (utan auth); home_venue_map vid fixture-generering. — PL-F0408c ✅ PL-F0408c |
| F04.08.16 | Entregado | League hierarchy — national league feeds into regional/district leagues. parent_league_id/league_level på League; LeagueHierarchyLevel i TenantConfig.LeagueConfig; GET /leagues/hierarchy-tree (rekursivt träd per tenant); GET /leagues/{id}/hierarchy (per-liga vy). Konfigurerbart per tenant (France: D1N→D2N→D3N→DR→DD, Germany: Bundesliga→Landesliga→Bezirksliga). — PL-F0408c ✅ PL-F0408c |
| F04.08.17 | Entregado | Transfer quarantine during active league — configurable: transfer_quarantine_scope (tenant/player_league/none) i TenantConfig.LeagueConfig. GET /leagues/{id}/transfer-quarantine-status per spelare. Karantänlogik integrerad i transfer-flödet. — PL-F0408c ✅ PL-F0408c |
| F04.08.18 | Entregado | Multi-phase league season — format_type (round_robin/knockout/swiss/monrad), points_for_win/draw/loss-override, carry_over_points, transition_criteria (top_n/threshold/all) per fas. POST /leagues/{id}/phases/{n}/transition med kvalificerade/eliminerade lag i svar. — PL-F0408c ✅ PL-F0408c |
| F04.08.19 | Entregado | Promotion via standalone tournament — configurable: promotion determined by a separate tournament (Germany: Aufstiegsrunde where 10 Landesmeister play round-robin, top 4 promote to Bundesliga). Distinct from in-league promotion. — PL-F0408d ✅ PL-F0408d |
| F04.08.20 | Entregado | Substitution constraints per league — configurable: reserve players locked to specific sub-match after insertion (Spain: Liga Nacional), maximum reserves per match day, substitution registration deadline. — PL-F0408d ✅ PL-F0408d |
| F04.08.21 | Entregado | Court specification enforcement per league — configurable: minimum court dimensions, closed court rules (Spain: pista cerrada 50cm from sideline, 1m from backline). Validated at venue assignment. — PL-F0408d ✅ PL-F0408d |
Subsistemas relacionados
Partes interesadas que necesitan este subsistema
Aparece en 2 análisis de partes interesadas