Competition
Object type
Implements: Entity
Fields
Section titled “Fields”| Field | Args | Type | Description |
|---|---|---|---|
id | — | ID! required | — |
name | — | String! required | — |
displayName | — | String | Operator-curated display name (competitions.display_name) — editable via updateCompetition. |
shortName | — | String | — |
code | — | String | — |
competitionType | — | String! required | — |
season | — | String | — |
startDate | — | Date | — |
endDate | — | Date | — |
status | — | String! required | — |
country | — | String | — |
version | — | Int! required | Optimistic-locking version (competitions.version) — pass as expectedVersion on updateCompetition. |
sportId | — | ID! required | — |
createdAt | — | DateTime! required | When the competition row was first inserted (competitions.created_at). |
aliases | — | [ParticipantAlias!]! required | Empty — competitions are not part of the M22 participant merge flow, but Entity requires the field. |
playerRankings | season: String | [FootballPlayerRankingTable!]! required | Top-player leaderboards for this competition — Opta F34 (POD-729). One table per metric, per season. Empty for the great majority of competitions: F34 reaches only the 8 that are event-entitled. Pass season to scope to one season’s leaderboards; omit it for every season held. The argument matters because a competition accumulates seasons here even though the competition ROW does not — see playerRankingSeasons. Deliberately NOT called standings: a football league table (standing_type='LEAGUE_TABLE') is a different thing that will live beside this, and returning both from one field would make callers filter a heterogeneous array by a type string to find either. |
playerRankingSeasons | — | [String!]! required | The seasons this competition actually holds player rankings for, newest first — what a season selector should be populated from. This exists because competitionSeasons CANNOT answer the question for football: that query projects season CHILD rows off the competition spine, which only the EnetPulse sports have. A football competition is a single flat row, so competitionSeasons returns [] for every one of them. Competition.season is no substitute either — it is written once at mint and never updated, so it freezes at whichever season the competition was first seen in. Derived from the rankings themselves, so it can only ever report seasons that really have data. |
leagueTable | season: String | [FootballLeagueTable!]! required | The league table(s) for this competition — Opta F3 (POD-838). SEVERAL for a grouped competition: CONMEBOL Sudamericana publishes eight groups and MLS two conferences, each its own ladder with its own positions, so they are never merged. Pass season to scope to one season; omit it for every season held, newest first. The argument is not optional in practice for a UI — a competition accumulates seasons here even though the competition ROW does not, and two seasons of the same league share the name League Table. The generic standingsForSeason has no season filter at all, so it interleaves them; that is exactly why this typed field exists rather than callers reading the generic one. |
leagueTableSeasons | — | [String!]! required | The seasons this competition actually holds a league table for, newest first — what a season selector should be populated from. Exists for the same reason as playerRankingSeasons: competitionSeasons projects season CHILD rows off the EnetPulse spine and returns [] for every football competition, and Competition.season is written once at mint and freezes there. NOTE — the internal Standings tab deliberately does NOT read this field, and that is not an oversight to be tidied up later. The tab shows tables at BOTH scopes: season-scoped (standingsForSeason) and stage-scoped (competitionStages.standings, which is the only place EnetPulse puts basketball’s conference tables). It therefore derives its season list from the tables it actually rendered, across both scopes, where this field covers league tables only. Pointing the tab here would silently drop the stage-scoped seasons. So the duplication is intentional and the two are not the same rule. This field is the CUSTOMER API’s season selector for league tables; the tab’s derivation is a superset for one internal surface. If a future change makes the scopes converge, collapse them then — deliberately. |