Skip to main content
Petanque Life
← Back to all features
04

Competition Management

403 features · 27 subsystems

End-to-end management of all petanque competitions: from calendar planning to results and rankings. Covers all formats (singles, doubles, triples), all levels (club to world championships), and all disciplines (petanque, jeu provencal, sport-boules).

Competition Calendar

F04.01
Planned
How it works
  • F04.01.01 Shipped

    Multi-level calendar (world, continental, national, regional, club) — PL-F0401a

    ✅ PL-F0401a
  • F04.01.02 Shipped

    Calendar event types (championship, open, league, friendly, training) — PL-F0401a

    ✅ PL-F0401a
  • F04.01.03 Shipped

    Date conflict detection across levels — PL-F0401a

    ✅ PL-F0401a
  • F04.01.04 Shipped

    Calendar approval workflow (regional > national > continental) — PL-F0401a

    ✅ PL-F0401a
  • F04.01.05 Shipped

    Public calendar view with filters (level, region, discipline, format) — PL-F0401b

    ✅ PL-F0401b
  • F04.01.06 Shipped

    Calendar subscription (iCal export, webcal://, ETag/If-Modified-Since, cursor pagination) — PL-F0401b, PL-T074

    ✅ PL-F0401b, PL-T074
  • F04.01.07 Shipped

    Season definition and management — PL-F0401b

    ✅ PL-F0401b
  • F04.01.08 Shipped

    Calendar notifications and reminders — PL-F0401b

    ✅ PL-F0401b

Tournament Setup

F04.02
Planned

> **Greenfield-ombyggnad (D-COMP m-1, `04caab5e.m-1`):** den rena Go/Postgres-backenden

How it works
  • F04.02.01 Shipped

    Tournament creation wizard (type, format, rules, venue, dates) — PL-F0402a

    ✅ PL-F0402a
  • F04.02.02 Shipped

    Competition formats (see F04.10 for full format catalog) — PL-F0402a

    ✅ PL-F0402a
  • F04.02.03 Shipped

    Disciplines: pétanque, jeu provençal, sport-boules — configurable per tenant — PL-F0402a

    ✅ PL-F0402a
  • F04.02.04 Shipped

    Configurable game formats per tenant — tête-à-tête, doublette, triplette, mixed doublette, mixed triplette + tenant-specific variants. Includes players per team, boules per player. — PL-F0402a

    ✅ PL-F0402a
  • F04.02.05 Shipped

    Configurable competition classes (spelklasser) per tenant — each federation defines its own age/gender classes with codes, age limits, and ranking eligibility. Examples: Sweden (M/YJ/J/Ö/D/V55/V65), France (Poussin→Vétéran), Germany (Minimes→Senioren), Spain (Benjamín→Veterano+Sub-23). Class is always age OR gender, never both combined. — PL-F0402a

    ✅ PL-F0402a
  • F04.02.06 Shipped

    Competition class = competition class + game format — the atomic unit is the combination, e.g., "Ös" (Open singles), "V65d" (Veteran 65 doubles). A competition event can have multiple competition classes. — PL-F0402a

    ✅ PL-F0402a
  • F04.02.07 Shipped

    Disability categories and adaptive rules — PL-F0402b

    ✅ PL-F0402b
  • F04.02.08 Shipped

    Points system configuration (per competition type) — PL-F0402b

    ✅ PL-F0402b
  • F04.02.09 Shipped

    Entry fee configuration — PL-F0402b

    ✅ PL-F0402b
  • F04.02.10 Shipped

    Maximum participants / team limits — PL-F0402b

    ✅ PL-F0402b
  • F04.02.11 Shipped

    Qualification criteria (ranking threshold, regional qualification) — PL-F0402b

    ✅ PL-F0402b
  • F04.02.12 Shipped

    Multi-day tournament scheduling — PL-F0402b

    ✅ PL-F0402b
  • F04.02.13 Shipped

    Competition regulation document attachment — PL-F0402c

    ✅ PL-F0402c
  • F04.02.14 Shipped

    Configurable competition levels per tenant — each federation defines its own levels (e.g., Sweden: internationell/nationell/regional/lokal/propaganda; France: international/national/régional/départemental/local/animation; Germany: A/B/C/D). Each level has: who can sanction it, ranking eligibility, ranking coefficient, required referee grade, venue requirements. — PL-F0402c. Rebuild — LIVE (D-FEDCONFIG d0601eb6.m-2): nivåer & sanktionsmatris administreras som data i federationskonfigurations-hubbens nivå-flik (#nivaer): tävlingsnivåstegen = rader i tenant_configs.sanction_matrix (kod, etikett, sanktionerande organ härlett ur nivådeklarationens can_sanction, ranking_eligible, opak licensindikation; "Other"-raden bär aldrig licenskrav) + org-nivådeklarationens autonomi-/kapabilitetsflaggor via GET/PUT /v1/tenant/levels (delad tenant_configs.version-linje, If-Match/412-flöde). Wizardens nivådropdown läser samma matris (parseLevels) — ändringar slår igenom utan omdeploy. Vy-spec: specs/admin/views/federationskonfiguration.md.

    ✅ d0601eb6.m-2.t-2
  • F04.02.15 Shipped

    Competition type classification — configurable per tenant: championship (SM/DM/VM), cup, open/concours, league, friendly, mêlée, propaganda/recruitment (license-free), inbjudningstävling, extern tävling — PL-F0402c

    ✅ PL-F0402c
  • F04.02.16 Shipped

    Multi-discipline event (same event hosts multiple competition classes as separate draws) — PL-F0402c

    ✅ PL-F0402c
  • F04.02.17 Shipped

    Multi-day scheduling with sessions (morning/afternoon) — PL-F0402c

    ✅ PL-F0402c
  • F04.02.18 Shipped

    Competition templates (save and reuse common setups) — PL-F0402c

    ✅ PL-F0402c
  • F04.02.19 Shipped

    Competition cloning (copy last year's tournament with new dates) — PL-F0402d

    ✅ PL-F0402d
  • F04.02.20 Shipped

    Sanction application workflow — club/district applies for sanction → relevant authority reviews (federation for national+, district for local) → district provides statement on regional applications → authority approves/rejects → sanction fee charged → competition listed in calendar. Configurable per level per tenant. — PL-F0402d

    ✅ PL-F0402d
  • F04.02.21 Shipped

    Sanction deadlines per level — configurable per tenant (e.g., Sweden: Aug 1 for int/nat, Sep 30 for regional, district decides for local) — PL-F0402d

    ✅ PL-F0402d
  • F04.02.22 Shipped

    Sanction quotas — configurable max per level per year (e.g., Sweden: ~7 int/nat, ~48 regional, max 4 parallel regionals). Blackout periods (e.g., no other events during SM). — PL-F0402d

    ✅ PL-F0402d
  • F04.02.23 Shipped

    Sanction fee per competition class — configurable per tenant (e.g., Sweden: 300 SEK/class, no fee for youth classes). Payable to district or federation. — PL-F0402d

    ✅ PL-F0402d
  • F04.02.24 Shipped

    Promotion/recruitment competition (propaganda) — license-free events for recruitment. Configurable: who can sanction (federation and/or district with quota), no ranking points, open to unlicensed players. — PL-F0402d

    ✅ PL-F0402d
  • F04.02.25 Shipped

    Ranking-capped competitions (concours promotionnel) — France: events restricted to players below a certain ranking level. Configurable ranking threshold per competition. Per-tenant RankingCapConfig med default/min/max cap och level-koppling. — PL-F0402e

    ✅ PL-F0402e
  • F04.02.26 Shipped

    Club-bound flag — if enabled, all players in a team must hold license in the same club. Violation = configurable penalty (disqualification, forfeit score, fine). club_bound_violation_penalty och club_bound_fine_amount på Competition. — PL-F0402e

    ✅ PL-F0402e
  • F04.02.27 Shipped

    Match time limit — configurable per tenant/level (e.g., Spain: 60 min, CEP: 75 min). Optional. CompetitionLevel.default_match_time_limit_minutes och default_throw_time_limit_seconds auto-populeras vid skapande. — PL-F0402e

    ✅ PL-F0402e
  • F04.02.28 Shipped

    Sanction revocation — authority can revoke sanction with mandatory reason, category, revoked_by. Auto-suspenderar tävling. Giltiga kategorier: rule_violation, safety_concern, venue_issue, federation_interest, organizer_misconduct, other. — PL-F0402e

    ✅ PL-F0402e

Tournament Discovery & Registration

F04.03
Planned

> **Greenfield-ombyggnad (D-COMP m-2, `04caab5e.m-2`):** den rena Go/Postgres-backenden

How it works
  • F04.03.01 Shipped

    Global tournament search (find competitions in any country) — PL-F0403a

    ✅ PL-F0403a
  • F04.03.02 Shipped

    Map-based tournament finder (search by location, radius, dates) — PL-F0403a

    ✅ PL-F0403a
  • F04.03.03 Shipped

    Filter by: country, region, format, discipline, team format, level, open/invitational — PL-F0403a

    ✅ PL-F0403a
  • F04.03.04 Shipped

    "Traveling player" mode (show tournaments near a destination + date range) — PL-F0403a

    ✅ PL-F0403a
  • F04.03.05 Shipped

    Tournament recommendations based on ELO level and preferences — PL-F0403a

    ✅ PL-F0403a
  • F04.03.06 Shipped

    Follow tournaments in other countries (get notifications) — PL-F0403b

    ✅ PL-F0403b
  • F04.03.07 Shipped

    Tournament detail page: rules, venue, entry fee, accommodation tips, language — PL-F0403b

    ✅ PL-F0403b
  • F04.03.08 Shipped

    "Open to foreign players" flag on tournaments (organizer marks this) — PL-F0403b

    ✅ PL-F0403b
  • F04.03.09 Shipped

    Cross-border entry requirements info (license validity, temporary license) — PL-F0403b

    ✅ PL-F0403b
  • F04.03.10 Shipped

    Temporary license / day pass for foreign players (federation configurable) — PL-F0403b

    ✅ PL-F0403b
  • F04.03.11 Shipped

    Tournament saved/wishlist (plan your tournament calendar) — PL-F0403c

    ✅ PL-F0403c
  • F04.03.12 Shipped

    Travel group finder (other players going to same tournament) — PL-F0403c

    ✅ PL-F0403c
  • F04.03.13 Shipped

    Online registration (individual and team) — PL-F0403c

    ✅ PL-F0403c
  • F04.03.14 Shipped

    Registration validation (license check, age category, ranking eligibility) — PL-F0403c

    ✅ PL-F0403c
  • F04.03.15 Shipped

    Registration payment integration (multi-currency for international) — PL-F0403c

    ✅ PL-F0403c
  • F04.03.16 Shipped

    Registration deadline management — PL-F0403d

    ✅ PL-F0403d
  • F04.03.17 Shipped

    Waiting list management — PL-F0403d

    ✅ PL-F0403d
  • F04.03.18 Shipped

    Late registration handling — PL-F0403d

    ✅ PL-F0403d
  • F04.03.19 Shipped

    Team composition validation (correct number of players, mixed rules) — PL-F0403d

    ✅ PL-F0403d
  • F04.03.20 Shipped

    Substitution rules and management — PL-F0403d

    ✅ PL-F0403d
  • F04.03.21 Shipped

    Registration confirmation and receipt — PL-F0403e

    ✅ PL-F0403e
  • F04.03.22 Shipped

    Bulk registration (club enters multiple teams) — PL-F0403e

    ✅ PL-F0403e
  • F04.03.23 Shipped

    Seeding based on rankings — PL-F0403e

    ✅ PL-F0403e
  • F04.03.24 Shipped

    Cross-border registration (register for tournament in another nation with valid license) — PL-F0403e

    ✅ PL-F0403e
  • F04.03.25 Shipped

    Registration language (show tournament info in player's language) — PL-F0403e

    ✅ PL-F0403e
  • F04.03.26 Shipped

    PublicationScope enum (PRIVATE/ORGNODE/TENANT/GLOBAL) on Competition — PL-T007

    ✅ PL-T007
  • F04.03.27 Shipped

    PUT /competitions/{id}/publication endpoint with audit log — PL-T007

    ✅ PL-T007
  • F04.03.28 Shipped

    GET /public/competitions/global cross-tenant public API (paginerad, cachad 15 min) — PL-T007

    ✅ PL-T007
  • F04.03.29 Shipped

    GET /public/tenants/{code}/competitions per-federation public listing — PL-T007

    ✅ PL-T007
  • F04.03.30 Shipped

    Scope filter on GET /competitions (query param scope=private

    tenant|orgnode|global) — PL-T007 | ✅ PL-T007
  • F04.03.31 Shipped

    GLOBAL scope requires federation-admin (club-admin 403 policy) — PL-T007

    ✅ PL-T007
  • F04.03.32 Shipped

    Competition visibility service with ORGNODE ancestor/descendant expansion — PL-T007

    ✅ PL-T007
  • F04.03.33 Shipped

    Backfill migration (existing competitions → TENANT scope) — PL-T007

    ✅ PL-T007
  • F04.03.34 Shipped

    Compound index (publication_scope, status, start_date) for queries — PL-T007

    ✅ PL-T007

Draw & Scheduling (Tirage au Sort)

F04.04
Planned

> **Greenfield-rebuild (D-COMP `04caab5e.m-3`, backend t-1):** F04.04 (lottning/tirage) +

How it works
  • F04.04.01 Shipped

    Automatic draw generation (randomized with seeding rules)

    ✅ PL-F0404a
  • F04.04.02 Shipped

    Separation rules (same club, same region in different groups)

    ✅ PL-F0404a
  • F04.04.03 Shipped

    Poule composition (balanced by ranking)

    ✅ PL-F0404a
  • F04.04.04 Shipped

    Bracket generation (single/double elimination)

    ✅ PL-F0404a
  • F04.04.05 Shipped

    Swiss-system pairing algorithm

    ✅ PL-F0404a
  • F04.04.12 Shipped

    Monrad pairing algorithm (Swiss variant, common in Scandinavia)

    ✅ PL-F0404b
  • F04.04.13 Shipped

    Mêlée random team draw (new random teams each round)

    ✅ PL-F0404b
  • F04.04.14 Shipped

    Super-mêlée draw (mixed player levels, partner rotation every round)

    ✅ PL-F0404b
  • F04.04.06 Shipped

    Court assignment optimization

    ✅ PL-F0404b
  • F04.04.07 Shipped

    Schedule generation (time slots per round)

    ✅ PL-F0404b
  • F04.04.08 Shipped

    Draw publication and notification

    ✅ PL-F0404c
  • F04.04.09 Shipped

    Manual draw adjustments (with audit trail)

    ✅ PL-F0404c
  • F04.04.10 Shipped

    Bye management (odd number of participants)

    ✅ PL-F0404c
  • F04.04.11 Shipped

    Re-draw capabilities (when teams withdraw)

    ✅ PL-F0404c

Match Management

F04.05
In progress

> **Greenfield-rebuild (D-COMP `04caab5e.m-4`, backend):** match-status-FSM (F04.05.03),

How it works
  • F04.05.01 Shipped

    Match score entry (by official, scorer, or team delegate) — PL-F0405a

    ✅ PL-F0405a
  • F04.05.02 Shipped

    Real-time score tracking — PL-F0405a

    ✅ PL-F0405a
  • F04.05.03 Shipped

    Match status tracking (scheduled, in progress, completed, suspended, forfeit) — PL-F0405a

    ✅ PL-F0405a
  • F04.05.04 Shipped

    Match timer — configurable: total match time limit (Spain: 60 min, CEP: 75 min) AND per-throw time limit (Spain: 30 seconds). Both optional and configurable per tenant/competition level. Distinct enforcement UI for each. — PL-F0405a

    ✅ PL-F0405a
  • F04.05.05 Shipped

    Match result confirmation (both teams or umpire) — PL-F0405a

    ✅ PL-F0405a
  • F04.05.06 Shipped

    Score dispute resolution workflow — PL-F0405a

    ✅ PL-F0405a
  • F04.05.07 Shipped

    Forfeit and withdrawal handling — PL-F0405b

    ✅ PL-F0405b
  • F04.05.08 Shipped

    Court change management — PL-F0405b

    ✅ PL-F0405b
  • F04.05.09 Shipped

    Match comments and incident reporting — PL-F0405b

    ✅ PL-F0405b
  • F04.05.10 Shipped

    Photo/video attachment to match records — PL-F0405b

    ✅ PL-F0405b
  • F04.05.11 Shipped

    Mène (end/round) tracking — score progression per mène within a match — PL-F0405b

    ✅ PL-F0405b
  • F04.05.12 Shipped

    Mène-level detail: which team scored, how many points, cochonnet position — PL-F0405b

    ✅ PL-F0405b
  • F04.05.13 Shipped

    Individual throw tracking (optional, for detailed analytics) — PL-F0405c

    ✅ PL-F0405c
  • F04.05.14 Shipped

    Throw type classification: point (portée/raspaille/donnée), tir (carreau/palet/raté) — PL-F0405c

    ✅ PL-F0405c
  • F04.05.15 Shipped

    Throw outcome recording: successful/missed, distance from cochonnet — PL-F0405c

    ✅ PL-F0405c
  • F04.05.16 Shipped

    Photo proof upload per mène (disputed measurements) — PL-F0405c

    ✅ PL-F0405c
  • F04.05.17 Shipped

    Match timeline view (mène-by-mène score progression) — PL-F0405c

    ✅ PL-F0405c
  • F04.05.18 Shipped

    Court Ops Console — live-board för marshal/jury president med color-coded threshold-flaggor och SSE-stream per event — PL-T223

    ✅ PL-T223
  • F04.05.19 Shipped

    Threshold alerts — warn/overrun/escalate (75/100/125 % default), tenant/event-config, audit-trail i CourtOpsAlert med ack-flow — PL-T223

    ✅ PL-T223
  • F04.05.20 Shipped

    Marshal broadcast — audience ∈ {all_marshals, all_teams, court_neighbors, next_up}, multi-lang body, F09.02-fan-out — PL-T223

    ✅ PL-T223
  • F04.05.21 Shipped

    Live rond-timer — server-auktoritativ nedräknings-FSM (not_started→running→paused⇄running→expired) styrd av arrangör/court-ops (start/paus/förläng/avsluta), timer-event på live-kanalen + nedräkning i app & publik scoreboard, expiry-tick med "spela klart sista rundan"-banner (v1 = in-app/SSE, ingen native push) — D-COMP-TIMER 1e481c39.m-1

    ✅ D-COMP-TIMER (backend t-1)
  • F04.05.22 Shipped

    Arrangörens "Tidtagning"-flik (admin/app/tavlingar/detalj?id=[id]&tab=tidtagning) — stor server-driven klocka + status ("Kör · startades … · Rond N · alla banor") + knapparna ▶ Starta / ⏸ Paus / +5 min / Avsluta rond, som anropar t-1:s capability-gejtade endpoints via den genererade klienten (If-Match/version). Expired-signal med ikon + text (NF-7). — D-COMP-TIMER 1e481c39.m-1 t-2

    ✅ D-COMP-TIMER (frontend t-2)
  • F04.05.23 Shipped

    Spelar-app-nedräkning (app/app/live/[comp]) — "Tid kvar MM:SS · Rond N" driven av den pollade live-snapshotten, klientlokal tick med server_time-skew-korrektion (NF-1); expiry-banner "Tiden är ute — spela klart sista rundan." reses klientlokalt när nedräkningen når 0 för en running-timer med last_end_on_expiry (eller vid server-flippad expired) — den pollande appen inväntar inte serverns expiry-tick (in-app/SSE, ingen native push); vid poll-tapp behålls senast kända nedräkning ("återansluter…", NF-8). — D-COMP-TIMER 1e481c39.m-1 t-2

    ✅ D-COMP-TIMER (frontend t-2)
  • F04.05.24 Shipped

    Publik scoreboard-nedräkning (web/app/d/[displayId], D-SCORE) — "Tid kvar · Rond N" ur den pollade /public/scoreboard/{id}-snapshotten, samma server-instant-nedräkning; utomhusläsbar display-variant. — D-COMP-TIMER 1e481c39.m-1 t-2

    ✅ D-COMP-TIMER (frontend t-2)
  • F04.05.25 Shipped

    Court Marshal-tavla — bana-centrerad tävlingsdags-trafikledning (GET/POST /v1/operator/court-marshal/{id}/{board\

    queue|call-up|clear|delays|delays/{did}/report|stream}). Ban-status-tavla som projicerar varje allokerad bana (härledd ur venue-courts/num_courts, aldrig hårdkodad) med tillstånd free|in_progress|done|delayed, KPI-rad, prioriterad klass-filtrerbar match-kö, upprop (tilldela ledig bana via schemaläggnings-substratet + registrera announcement m. kanaler/språk, race-säker + idempotent), clear-court, flagga-försening + rapportera-TD, SSE-ström. Skild från D-VENUE banstatus (FR-13). Backend i t-1; admin-tavla wire:ad i t-2 (admin ▸ tavlingsdags ▸ #marshal: KPI-rad, ban-status-kort, klass-filtrerbar kö, upprops- + delay-paneler, live-poll, a11y AA). — D-COMP-OPS 8a5db0fb.m-2 | ✅ D-COMP-OPS (backend t-1 · frontend t-2)
  • F04.05.26 Shipped

    Table Official-desk — tävlingsdags incheckningsdisk (GET/POST /v1/operator/table-official/{id}/{desk\

    check-in|bulk-check-in|day-of|no-show|escalate|stream}). Ett operativt lager ovanpå anmälnings- (registration), licens- (license) och betalnings- (payments) substraten som binder ihop tävlingsdagens flöde "välkomna → verifiera → checka in → ta betalt": disk-projektion (KPI-rad + incheckningslista med sök/filter/CSV, härledd ur riktiga anmälningar joinade mot licens-status valid|expired|blocked|unknown + betalnings-status paid|pending|none), licens-verifiering (läst ur D-MEMBER, aldrig fabricerat), incheckning + on-site-betalning (pay_on_site skapar en RIKTIG payments-rad markerad betald och länkar via registration.payment_ref, idempotent + race-säker), bulk-incheckning (hoppar över blocked/expired/redan), eskalera-spärr → head umpire, day-of walk-in-registrering (full klass → dokumenterat utfall, aldrig tyst överbokning), no-show/scratch (+ typad event/SSE-signal mot lottningen + TD), SSE-ström. Check-in-/no-show-tillstånd strikt additivt på registration (migration 00108). Skild från D-VENUE court-booking-checkin (FR-14). Backend i t-1; admin-disk wire:ad i t-2 (admin ▸ tavlingsdags ▸ #desk). — D-COMP-OPS 8a5db0fb.m-3 | ✅ D-COMP-OPS (backend t-1 · frontend t-2)
  • F04.05.27 Shipped

    Rules Reference — courtside sökbar regel-uppslagning (GET /v1/rules/{search\

    categories|articles/{id}|bundle|bundle/version|recent-changes|bookmarks}, POST/DELETE /v1/rules/bookmarks[/{id}]). Ett läs-lager över ett läs-optimerat regel-innehålls-substrat (migration 00109, seedat av seed-rules): nyckelordssök (artikelnummer/titel/brödtext/situation, trigram-index, p95 < 300 ms), chip-kategorier, artikeldetalj med tolkningar (FAQ|precedent|guidance) + genuina kors-referenser, flerspråkig uppslag med markerad språk-fallback (en/sv/fr/es/it), versionerad+checksummad offline-bundle (deterministisk version, olika tillämpligt innehåll → olika version), senaste-ändringar och actor-privata bokmärken (idempotent star/unstar). Bas-FIPJP delat (tenant_id IS NULL), nationell/regional variant tenant-scopad (aldrig läckt, 404 x-tenant), endast Approved exponeras. Pull-baserad (ingen SSE). Ny bred läs-capability rules:read (domarkår L1–L5/jury/spelare + tävlingsroller). Kanonisk regelkälla/authoring ägs av D-GOV (admin/regelverk, ostartad); denna task läser + seedar minimalt substrat. Skild från D-OFF/D-EDU utbildning (innehåll, ej kurs). — D-COMP-OPS 8a5db0fb.m-4 t-1 | ✅ D-COMP-OPS (backend t-1)
  • F04.05.28 Shipped

    Rules Reference — admin courtside-yta (tavlingsdags ▸ #regler). Wire:ar F04.05.27:s riktiga endpoints till admin-vyn admin/app/tavlingar/detalj/tavlingsdags/page.tsx (sedan D-ADMINAPP 94f74ebf.m-3.t-6 panelen *Regler* i vy-modulen packages/shared/src/views/competition/tavlingsdags med web- och native-renderare; tidigare RulesReference.tsx + lib/rules-reference.tsx hooks + lib/rules-reference-presenter.ts ren logik): sökpanel (fritextsök med debounce → /search, språkväljare en/sv/fr/es/it → ?lang, Offline-badge som speglar verklig manifest-version ur /bundle/version — aldrig hårdkodat datum), kategori-chips (/categories + "Alla"-reset → ?category), träfflista med härledd träffräknare + artikelnr/kategori/titel/utdrag, artikeldetalj (full regel + tolkningar/kors-refs ur /articles/{id}, markerad språk-fallback), samt sido-korten Snabb uppslagning · Flerspråkig · Bokmärken (GET/POST/DELETE /bookmarks) & senaste ändringar (/recent-changes). Ingen hårdkodad/placeholder-data (AC-14); tom/laddande/fel/403-lägen verkliga; pull-baserad (ingen SSE, FR-12). ALL åtkomst via delat transport-lager (rulesReferenceOps.*) — ingen rå fetch( (fetch-ratchet). A11y WCAG 2.2 AA (färg aldrig enda bäraren av kategori-/tolknings-/status-info, träffytor ≥44px, aria-live träffräknare). Terminologi "runda"/"Boulodrome"/å/ä/ö. #marshal (m-2), #desk (m-3) och referee-call-spegeln (m-1) orörda (NFR-7). E2e: tools/gate/rules-reference-e2e.mjs (verify.sh L4, RUN_UI). — D-COMP-OPS 8a5db0fb.m-4 t-2

    ✅ D-COMP-OPS (frontend t-2)

Results & Standings

F04.06
Planned

> **Rena Go/Postgres-ytan (D-COMP m-6, `04caab5e.m-6`) levererad.** Standings-beräkningen

How it works
  • F04.06.01 Shipped

    Real-time standings/leaderboard calculation

    ✅ PL-F0406a
  • F04.06.02 Shipped

    Tiebreaker rules (head-to-head, point difference, quotient)

    ✅ PL-F0406a
  • F04.06.03 Shipped

    Poule standings with all stats (W, L, PF, PA, PD, quotient)

    ✅ PL-F0406a
  • F04.06.04 Shipped

    Bracket progression (automatic advancement)

    ✅ PL-F0406a
  • F04.06.05 Shipped

    Final results publication

    ✅ PL-F0406a
  • F04.06.06 Shipped

    Result export (PDF, CSV, federation format)

    ✅ PL-F0406b
  • F04.06.07 Shipped

    Historical results archive

    ✅ PL-F0406b
  • F04.06.08 Shipped

    Public results page (embeddable)

    ✅ PL-F0406b
  • F04.06.09 Shipped

    Audit trail on all result entries and modifications

    ✅ PL-F0406b

Rankings

F04.07
Planned

> **Rebuild-status (D-RANK `4aaa301a.m-1`).** Ranking-fundamentet är byggt i Go/Postgres: de rena

How it works
  • F04.07.01 Shipped

    National ranking system per federation

    ✅ PL-F0407a
  • F04.07.02 Shipped

    World ranking (FIPJP)

    ✅ PL-F0407a
  • F04.07.03 Shipped

    Continental rankings

    ✅ PL-F0407a
  • F04.07.04 Shipped

    Configurable ranking algorithm per tenant — each federation defines: point scale per competition level × placement × number of participants, ranking coefficient/multiplier per level, max competitions counted per year, and whether ranking is per competition class (Sweden: separate list for Ös, Ds, V55s etc.)

    ✅ PL-F0407a
  • F04.07.05 Shipped

    Ranking per configurable dimension — separate rankings per: competition class (age/gender), game format, or combined. Configurable per tenant. A player can appear on multiple ranking lists.

    ✅ PL-F0407a
  • F04.07.06 Shipped

    Ranking history and progression charts

    ✅ PL-F0407a
  • F04.07.07 Shipped

    Configurable ranking validity — points expire after configurable period: Sweden 1 year from competition date, France 2 years, Germany 3 years with weighted decay (3×current + 2×previous + 1×two years ago)

    ✅ PL-F0407b
  • F04.07.08 Shipped

    Tournament category multipliers — configurable categories (e.g., Germany: A/B/C/D with multipliers 4/3/2/1; Sweden: point scale varies by level + participant count; France: coefficients per level)

    ✅ PL-F0407b
  • F04.07.09 Shipped

    Ranking publication and notification

    ✅ PL-F0407b
  • F04.07.10 Shipped

    Ranking-based qualification thresholds

    ✅ PL-F0407b
  • F04.07.11 Shipped

    Club/team rankings

    ✅ PL-F0407b
  • F04.07.12 Shipped

    Public ranking search and filtering

    ✅ PL-F0407b
  • F04.07.13 Shipped

    Global ELO rating system (skill-based, worldwide, format-independent) — PL-F0407c

    ✅ PL-F0407c
  • F04.07.14 Shipped

    ELO calculation per match result (win/loss margin affects change) — PL-F0407c

    ✅ PL-F0407c
  • F04.07.15 Shipped

    ELO K-factor configuration (higher for new players, lower for established) — PL-F0407c

    ✅ PL-F0407c
  • F04.07.16 Shipped

    ELO separate ratings per format (singles, doubles, triples) — PL-F0407c

    ✅ PL-F0407c
  • F04.07.17 Shipped

    ELO history and progression chart per player — PL-F0407c

    ✅ PL-F0407c
  • F04.07.18 Planned

    ELO-based matchmaking suggestions (balanced pairing) — PL-F0407c. Om-markerad 2026-09-26: [DONE] beskrev det AVVECKLADE systemet. I rebuilden bor lagsökningen i D-SOCIAL: m-1 (0154301b.m-1) levererar lagannons → svar → inbjudan → accept → lag (se F15.14 i 15-mobile-fan-experience.md). 0154301b.m-2 (2026-09-27): backend för smart matchning — nivån MÄTT som band ur D-RANK:s globala ELO, avståndet ur PostGIS, radiesökningen, förslagssvepet team_listing_match_sweep (föreslår, bildar aldrig ett lag) och GET /v1/me/social/suggestions + respond/dismiss; appytan *Smarta matchningar* i /socialt är milstolpens t-2. Regeln: docs/domain/social/README.md §Matchningsregeln.

    0154301b.m-1, 0154301b.m-2
  • F04.07.19 Shipped

    ELO leaderboards (global, continental, national, club) — PL-F0407d

    ✅ PL-F0407d
  • F04.07.20 Shipped

    Dual ranking display: Federation Points + Global ELO side by side — PL-F0407d

    ✅ PL-F0407d
  • F04.07.21 Shipped

    ELO updated from both official competitions and casual games — PL-F0407d

    ✅ PL-F0407d
  • F04.07.22 Shipped

    Partnership/team ELO (combined rating for regular partnerships) — PL-F0407d

    ✅ PL-F0407d

League / Series Management

F04.08
In progress

Season-long competitions where clubs/teams play regular fixtures.

How it works
  • F04.08.01 Shipped

    League creation (divisions, tiers, pools) — configurable per tenant — PL-F0408a

    ✅ PL-F0408a
  • F04.08.02 Shipped

    Promotion/relegation rules (automatic + playoff, configurable spots per tenant) — PL-F0408a

    ✅ PL-F0408a
  • F04.08.03 Shipped

    Home/away fixture generation (round-robin, single or double) — PL-F0408a

    ✅ PL-F0408a
  • F04.08.04 Shipped

    Configurable tiebreaker rules per tenant — Sweden: points → wins → klotskillnad → head-to-head → lottery. Other nations may differ. — PL-F0408a

    ✅ PL-F0408a
  • F04.08.05 Shipped

    Match postponement and rescheduling with audit trail + tenant deadline enforcement — PL-F0408a

    ✅ PL-F0408a
  • F04.08.06 Shipped

    Season results archive with public endpoints and cross-league search — PL-F0408a

    ✅ PL-F0408a
  • F04.08.07 Shipped

    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 Shipped

    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 Shipped

    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 Shipped

    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 Shipped

    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 Shipped

    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 Shipped

    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 Shipped

    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 Shipped

    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 Shipped

    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 Shipped

    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 Shipped

    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 Shipped

    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 Shipped

    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 Shipped

    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

National Team Selection

F04.09
Planned

> **I arrangörsappen (D-ADMINAPP `94f74ebf.m-13`, landslagsvågen):** hela F04.09 finns sedan m-13 också i

How it works
  • F04.09.01 Shipped

    Selection committee management — PL-F0409

    ✅ PL-F0409
  • F04.09.02 Shipped

    Selection criteria definition — PL-F0409

    ✅ PL-F0409
  • F04.09.03 Shipped

    Candidate pool tracking (ranking, performance, availability) — PL-F0409

    ✅ PL-F0409
  • F04.09.04 Shipped

    Team composition builder — PL-F0409

    ✅ PL-F0409
  • F04.09.05 Shipped

    Selection announcement workflow — PL-F0409

    ✅ PL-F0409
  • F04.09.06 Shipped

    National team history and records — PL-F0409

    ✅ PL-F0409

Competition Format Catalog

F04.10
Planned

All supported competition formats and their unique rules.

How it works
  • F04.10.01 Shipped

    Knockout / Elimination — single elimination, loser goes home — PL-F0410a

    ✅ PL-F0410a
  • F04.10.02 Shipped

    Double elimination — losers bracket, second chance — PL-F0410a

    ✅ PL-F0410a
  • F04.10.03 Shipped

    Consolation bracket (consolante) — separate bracket for first-round losers — PL-F0410a

    ✅ PL-F0410a
  • F04.10.04 Shipped

    Round-robin — everyone plays everyone — PL-F0410a

    ✅ PL-F0410a
  • F04.10.05 Shipped

    Poules + Knockout — group stage then elimination (most common) — PL-F0410a

    ✅ PL-F0410a
  • F04.10.06 Shipped

    Swiss system — paired by similar results, no elimination — PL-F0410a

    ✅ PL-F0410a
  • F04.10.07 Shipped

    Monrad system — Swiss variant (Scandinavian, strength-based pairing) — PL-F0410b

    ✅ PL-F0410b
  • F04.10.08 Shipped

    Mêlée — individual entry, random team draw each round, individual ranking — PL-F0410b

    ✅ PL-F0410b
  • F04.10.09 Shipped

    Super-mêlée — like mêlée but mixed levels, partner rotation every round — PL-F0410b

    ✅ PL-F0410b
  • F04.10.10 Shipped

    Marathon — continuous play all day, most wins/points wins — PL-F0410b

    ✅ PL-F0410b
  • F04.10.11 Shipped

    Américaine — doublette with partner change after each match (round-robin style) — PL-F0410b

    ✅ PL-F0410b
  • F04.10.12 Shipped

    Tête-à-tête integral — every player plays every other player — PL-F0410b

    ✅ PL-F0410b
  • F04.10.13 Shipped

    Championnat Tête-à-tête — singles championship (3 boules each)

    ✅ PL-F0410c ✅ PL-F0410c
  • F04.10.14 Shipped

    Championnat Doublette — doubles championship (3 boules each)

    ✅ PL-F0410c ✅ PL-F0410c
  • F04.10.15 Shipped

    Championnat Triplette — triples championship (2 boules each)

    ✅ PL-F0410c ✅ PL-F0410c
  • F04.10.16 Shipped

    Championnat Mixte — mixed doubles/triples (mandatory male+female)

    ✅ PL-F0410c ✅ PL-F0410c
  • F04.10.17 Shipped

    Championnat Combiné — combined competition (match play + shooting skills)

    ✅ PL-F0410c ✅ PL-F0410c
  • F04.10.18 Shipped

    Championnat des Clubs — inter-club championship (club sends multiple teams)

    ✅ PL-F0410c ✅ PL-F0410c
  • F04.10.19 Shipped

    Championnat des Nations — nation vs nation (national delegations)

    ✅ PL-F0410d ✅ PL-F0410d
  • F04.10.20 Shipped

    Tir de Précision — precision shooting at marked targets on court

    ✅ PL-F0410d ✅ PL-F0410d
  • F04.10.21 Shipped

    Tir de Précision scoring system (points per target zone hit)

    ✅ PL-F0410d ✅ PL-F0410d
  • F04.10.22 Shipped

    Tir de Précision court layout management (target positions per FIPJP rules)

    ✅ PL-F0410d ✅ PL-F0410d
  • F04.10.23 Shipped

    Tir Rapide — rapid shooting against the clock

    ✅ PL-F0410d ✅ PL-F0410d
  • F04.10.24 Shipped

    Tir Rapide timer integration (countdown per attempt)

    ✅ PL-F0410d ✅ PL-F0410d
  • F04.10.25 Shipped

    Tir Progressif — increasingly difficult targets (distance, angle, obstacles)

    ✅ PL-F0410e ✅ PL-F0410e
  • F04.10.26 Shipped

    Tir Progressif level progression and scoring

    ✅ PL-F0410e ✅ PL-F0410e
  • F04.10.27 Shipped

    Relais de Tir — team shooting relay (each player shoots in sequence)

    ✅ PL-F0410e ✅ PL-F0410e
  • F04.10.28 Shipped

    Shooting competition leaderboard (separate from match rankings)

    ✅ PL-F0410e ✅ PL-F0410e
  • F04.10.29 Shipped

    Shooting accuracy statistics per player (career, season, competition)

    ✅ PL-F0410e ✅ PL-F0410e
  • F04.10.30 Shipped

    Shooting competition as standalone event or embedded within combined championship

    ✅ PL-F0410e ✅ PL-F0410e
  • F04.10.31 Shipped

    Video replay integration for shooting competitions (analyze technique)

    ✅ PL-F0410f ✅ PL-F0410f
  • F04.10.32 Shipped

    National Championship (qualification pathway: club > regional > national)

    ✅ PL-F0410f ✅ PL-F0410f
  • F04.10.33 Shipped

    Continental Championship (e.g., European Championship) — national delegations

    ✅ PL-F0410f ✅ PL-F0410f
  • F04.10.34 Shipped

    World Championship — FIPJP sanctioned, all disciplines

    ✅ PL-F0410f ✅ PL-F0410f
  • F04.10.35 Shipped

    Cup / Coupe — knockout with seeding, often multi-round across weeks

    ✅ PL-F0410f ✅ PL-F0410f
  • F04.10.36 Shipped

    Grand Prix / Ranking tournament — open entry, high ranking points coefficient

    ✅ PL-F0410f ✅ PL-F0410f
  • F04.10.37 Shipped

    Challenge / Trophée — invitational tournament (organizer selects participants)

    ✅ PL-F0410g ✅ PL-F0410g
  • F04.10.38 Shipped

    Masters / Finale — end-of-season event for top-ranked players

    ✅ PL-F0410g ✅ PL-F0410g
  • F04.10.39 Shipped

    World Games — multi-sport event with petanque included

    ✅ PL-F0410g ✅ PL-F0410g
  • F04.10.40 Shipped

    Youth Championship — dedicated age-group championships (U13, U15, U18, U23)

    ✅ PL-F0410g ✅ PL-F0410g
  • F04.10.41 Shipped

    Veterans Championship — 55+, 65+ categories

    ✅ PL-F0410g ✅ PL-F0410g
  • F04.10.42 Shipped

    Para-Petanque Championship — disability classifications

    ✅ PL-F0410g ✅ PL-F0410g
  • F04.10.43 Shipped

    Women's Championship — dedicated women's events at all levels

    ✅ PL-F0410h ✅ PL-F0410h
  • F04.10.44 Shipped

    Championship series — multiple events, cumulative points determine overall winner

    ✅ PL-F0410h ✅ PL-F0410h
  • F04.10.45 Shipped

    Series calendar management (which events count)

    ✅ PL-F0410h ✅ PL-F0410h
  • F04.10.46 Shipped

    Series standings (running total across events)

    ✅ PL-F0410h ✅ PL-F0410h
  • F04.10.47 Shipped

    Best-of-N scoring (only top X results count)

    ✅ PL-F0410h ✅ PL-F0410h
  • F04.10.48 Shipped

    Series finale qualification (top N qualify for finale)

    ✅ PL-F0410h ✅ PL-F0410h
  • F04.10.49 Shipped

    Series sponsorship and branding per circuit

    ✅ PL-F0410i ✅ PL-F0410i
  • F04.10.50 Shipped

    Custom format builder (combine stages: poules → repechage → knockout)

    ✅ PL-F0410i ✅ PL-F0410i
  • F04.10.51 Shipped

    Stage transition rules (how many advance from each stage)

    ✅ PL-F0410i ✅ PL-F0410i
  • F04.10.52 Shipped

    Points-to-win configuration (11, 13, or custom per round/stage)

    ✅ PL-F0410i ✅ PL-F0410i
  • F04.10.53 Shipped

    Time limit per match/mène (configurable per competition)

    ✅ PL-F0410i ✅ PL-F0410i
  • F04.10.54 Shipped

    Tiebreaker configuration per format

    ✅ PL-F0410i ✅ PL-F0410i
  • F04.10.55 Shipped

    Format validation (ensure rules are internally consistent)

    ✅ PL-F0410j ✅ PL-F0410j
  • F04.10.56 Shipped

    Format preview (simulate a tournament with N teams to check flow)

    ✅ PL-F0410j ✅ PL-F0410j
  • F04.10.57 Shipped

    Composable Steg▸Fas system per competition class (D-COMP-SYS delta #1, ee51ed1f.m-1) — a class bears an ordered chain of stages, each an ordered pipeline of phases (poule/group/swiss_monrad/round_robin/snake/finals + team-formation select/melee/panache/vauclusienne; tiers A–E, consolante, barrage, semi_pool, multi-stage kval→final). t-1 [DONE]: pure per-fas engine (GenerateComposedDraw). t-2 [DONE]: data model (competition_stage/competition_phase, migration 00062), persistence, and the komponerings-API PUT/GET /v1/competitions/{id}/classes/{cid}/system. t-3 [DONE]: per-fas draw persisted end-to-end (POST …/draws stamps stage_id/phase_id; flat classes stay NULL — FR-9), fas-aware format/preview (unsaved system), and the traceability matrix vs spelsystem.astro. Scoring resolution = delta #2; wizard UI = delta #3. Docs: docs/domain/competition/steg-fas-model.md, docs/domain/competition/steg-fas-sparbarhetsmatris.md, specs/api/competition-compose-system.md, specs/api/competition-draw-per-phase.md.

    ✅ ee51ed1f.m-1
  • F04.10.58 Shipped

    Per-fas/steg/match/klass-poäng + avslutsvillkor (D-COMP-SYS delta #2, ee51ed1f.m-2) — poäng- och avslutsregler löses upp per fas/steg/match i stället för en global points_to_win. En tävling bär default_scoring (end_condition ∈ points \

    time_plus_end | fixed_ends, points_to_win, time_limit_min, ends_cap) som ärvs och kan åsidosättas på klass- (scoring_default), steg-, fas- och match-nivå (scoring_override), upplöst fält-för-fält längs kedjan match→fas→steg→klass→tävling. t-1 [DONE]: ren upplösnings-/validerings-/tir-kärna. t-2 [DONE]: additiv migration (00063), upplösning inläst ur bärarna, scoring_override-validering i PUT …/system (13|11|annat relaxat; time_plus_end utan tid → 422), avslutsvillkors-medveten confirm + mjuk-validerings-tröskel (score_above_<N>) mot riktig Postgres, och upplöst scoring_config på GET /v1/matches/{id}. t-3 [DONE]: Tir de précision-poängväg (5 stationer × 5 skott, 0–5/skott, total 0–25) + registrerings-API (POST /v1/matches/{id}/tir-shots, GET …/tir-result, GET /v1/competitions/{id}/classes/{cid}/tir-standings), append-only-korrigering, rangordning + tiebreak (fler 5:or → fler 4:or → …), och strikt separation tir↔klot (fel spelform mot fel väg → 422) bevisat mot riktig Postgres. Wizard-UI = delta #3. Docs: docs/domain/competition/scoring-resolution-model.md, docs/domain/competition/tir-de-precision-scoring.md, specs/api/competition-scoring-resolution.md, specs/api/competition-tir-precision.md. | ✅ ee51ed1f.m-2
  • F04.10.60 Shipped

    Format och regler är DATA — disciplin-scopad katalog + namngivna presets i tenant_configs (D-COMP-SYS delta #7, ee51ed1f.m-4) — den katalog av spelformat, systemtyper, fas-enum-domäner och poäng-/klot-regler (FIPJP Art.1) som tidigare låg hårdkodad i Go-maps (recognisedFormats, defaultBoules, validPhaseType, valid*, EndCondition-domänen, maxPointsToWin) är nu disciplin-scopad data i tenant_configs, seedad med en plattforms-baslinje och per-tenant överskrivningsbar — en flerdisciplin-federation (FRA: petanque + jeu_provencal, §N gap #7) bär en egen katalog per disciplin utan att de blandas. Ovanpå katalogen bär tenanten de namngivna presets (§D / spelsystem.astro rad 30–40) som data. t-1 [DONE]: ren datamodell (competition.Catalog/Preset) injicerad i validerarna. t-2 [DONE]: migration 00065 (system_catalog/presets-kolumnerna), disciplin-scopad seed, kant-resolver som injicerar den per-tenant-resolverade katalogen (samma anrop → olika utfall enbart pga data: {"format":"raffa"} → 200 för tenant med override, 422 för baslinje), och preset-läs-API GET /v1/competitions/presets?discipline= (auth-skyddat, tenant-scopat) som wizardens preset-väljare (delta #3) konsumerar — bevisat mot riktig Postgres, ingen Go-map är längre runtime-auktoritet (FR-5). Wizard-UI = delta #3; league-preset-komposition = D-LEAGUE (A-3). Docs: docs/domain/competition/format-katalog-presets-data.md, specs/api/competition-presets-catalog.md. D-FEDCONFIG d0601eb6.m-2 (t-1+t-3) — spelsystem-presets LIVE i federationskonfigurations-hubben: system_catalog/presets skrivbara via PUT /v1/tenant/config (strukturvalidering ValidatePresets/ValidateSystemCatalog, 422 fältpekat) och preset-fliken (#presets) i admin/federationskonfiguration hanterar hela livscykeln som DATA — aktivera/avaktivera (disabled på raden; server-side-filtrerad ur läs-API:t, "avaktivera samtliga" ⇒ tom wizard-lista, aldrig tyst baslinje-fallback), anpassa (kopia med ny key), skapa egen (minimal giltig komposition), ärlig "baslinje"-märkning + materialisering av HELA den upplösta disciplin-listan vid första redigeringen. Genomslag utan omdeploy i wizardens spelsystem-steg och /tavlingar/spelsystem. Vy-spec: specs/admin/views/federationskonfiguration.md.

    ✅ ee51ed1f.m-4 · d0601eb6.m-2.t-3
  • F04.10.61 Shipped

    7-stegs "Skapa tävling"-wizard + systemkatalog — backend-luckor (delta #3, ee51ed1f.m-5.t-1) — de sista mockup-fälten som saknade en backend-bärare stängs additivt (migration 00066, strikt additiv). competition bär nu de redaktionella Grunder-fälten num_courts/competition_director/contact_email/visibility (public\

    members_only|invited, skild från publication_scope) samt write-vägen för default_scoring (§K tävlings-standard, m-2). competition_class får require_license + write-vägen för m-3-constraints (min_age/max_age/gender_rule/squad_size/reserves_allowed) och scoring_default via POST/PATCH …/classes (tidigare bara läsprojektion). Nytt tenant-scopat läs-API GET /v1/competitions/system-catalog?discipline= projicerar katalogens byggstenar (Lagbildning · Kvalfaser · Slutspelsfaser + fas-enum-domäner) som DATA (SystemCatalogView/CatalogBlock), så systemkatalog-vyn (spelsystem.astro) renderar från riktig data i stället för en hårdkodad frontend-lista (AS-2). openapi + genererad TS-klient i synk (make api-ts-client-check). Wizard-UI + katalogvy = t-2/t-3. Bevis mot riktig Postgres: competition_wizard_backend_contract_integration_test.go. Docs: specs/api/competition-system-catalog.md. | ✅ ee51ed1f.m-5
  • F04.10.62 Shipped

    Full 7-stegs "Skapa tävling"-wizard, wire:ad mot riktiga endpoints (delta #3, ee51ed1f.m-5.t-2) — admin/components/competition/CompetitionWizard.tsx utökad från 4 → 7 steg i mockup-ordning (tavling-ny.astro): Grunder · Klass & format · Spelsystem · Sanktionering · Anmälan · Domare & jury · Granska & publicera. Varje steg/fält är wire:at till ett endpoint som finns: POST /v1/competitions (utkast + Grunder-fält), POST …/classes (constraints m-3 + scoring_default m-2), GET /v1/competitions/presets (preset-väljaren fyller steg/fas-editorn — inga hårdkodade mall-namn), PUT …/classes/{cid}/system + POST …/format/preview (komponering + fas-medveten förhandsvisning, m-1/m-2), POST …/request-sanction (§I-statuskedja), PATCH /v1/competitions/{id} (anmälnings-konfig), GET /v1/officials + POST /v1/officials/assignments (D-OFF), GET /v1/org-nodes (arrangör), och steg 7 bygger sammanfattningen från läst API-data (GET /v1/competitions/{id} + GET …/system) — aldrig formulärminne. Additiv backend-lucka stängd (FR-24): PATCH /v1/competitions/{id} accepterar nu entry_fee_minor/entry_fee_currency/allow_waitlist (Money *_minor+ISO-4217, NFR-4) för anmälnings-konfig-persistens (bakåtkompat; sqlc-regenererad). Bevis: admin/__acceptance__/competition-wizard.acceptance.mjs grön (7 steg + fält + wiring + kontrakt), npm run build grön, api-ts-client-check i synk, competition_registration_config_integration_test.go mot riktig Postgres. Katalogvy + spårbarhetsmatris = t-3. Docs: specs/admin/views/competition-wizard.md.

    ✅ ee51ed1f.m-5
  • F04.10.63 Shipped

    Fristående systemkatalog-vy (riktig data) + konformitets-/spårbarhetsmatris (delta #3, ee51ed1f.m-5.t-3) — den fristående systemkatalog-vyn (admin/app/tavlingar/spelsystem/page.tsx, route /tavlingar/spelsystem, nåbar från steg 3 via system-catalog-link, mockup spelsystem.astro) renderar hierarki-illustrationen (Tävling ▸ Steg ▸ Fas), de tre byggstens-sektionerna Lagbildning · Kvalfaser · Slutspelsfaser och de namngivna mallarna (presets) — allt från riktiga endpoints (GET /v1/competitions/system-catalog för byggstenarna, GET /v1/competitions/presets för mallarna), inte en hårdkodad frontend-lista (FR-22/AC-13). Serie/liga-preseten visas markerad "via D-LEAGUE" och expanderar inte (A-1). Parsers (parseSystemCatalog/parsePresets/presetViaExternal) är rena + enhetstestade (admin/lib/__tests__/competition-catalog.test.ts). Levererar även konformitets-/spårbarhetsmatrisen (milestones/ee51ed1f.m-5/conformance-matrix.md) som mappar varje steg+fält i tavling-ny.astro och varje byggsten+preset i spelsystem.astro post-för-post → wizard-/katalog-element + endpoint/datakälla. Bevis: node admin/__acceptance__/system-catalog-view.acceptance.mjs grön (vy + byggstens-/preset-testID + riktig-data-wiring + matris), npm run build grön. Docs: specs/admin/views/system-catalog.md, specs/admin/views/competition-wizard.md.

    ✅ ee51ed1f.m-5
  • F04.10.59 Shipped

    Strukturerade kategori-constraints + trupp > lag & reserver (D-COMP-SYS delta #4 + #6, ee51ed1f.m-3) — competition_class bär strukturerade behörighets-constraints min_age/max_age/gender_rule (open\

    men_only|women_only|mixed_required, §F/§K, mockup tavling-ny.astro steg 2) + trupp/reserv-modellen squad_size/reserves_allowed (§A/§G: EM-triplette = 4-mannatrupp ställer upp 3 + 1 reserv), och registration_player bär player_role (fielded|reserve). t-1 [DONE]: additiv migration (00064) + rena DB-fria behörighetsfunktioner (CheckCategoryEligibility ålder+kön per spelare, CheckMixedRequirement mixed-kvot per lag), deterministiska/ackumulerande, fail-open på saknad fakta. t-2 [DONE]: enforcering i anmälningsgrinden mot D-MEMBER (player_profile.date_of_birth/gender — enda källan), deny-by-default 422 category_ineligible (reasons[] ∈ {age_below_min, age_above_max, gender_not_allowed, mixed_requirement_unmet}) skild från 409-licensfamiljen; trupp/reserv-validering + player_role-persistens (422 team_composition_invalid); constraints + trupproller exponerade på läs-API + OpenAPI (RegistrationCreateInput/CompetitionClassConstraints) + TS-klient i synk — bevisat mot riktig Postgres. Kategori-preset-select + wizard-yta = delta #3. Docs: docs/domain/competition/category-constraints-squad.md, specs/api/endpoints/registrations-v1.md. | ✅ ee51ed1f.m-3
  • F04.10.64 Shipped

    Anpassade tävlingar — para-klasser och adaptiva regler som KONFIG-DATA (D-PARA cc3657f5.m-4.t-1) — en arrangör deklarerar tävlingen som anpassad i ett regelkort (para_competition_ruleset, migration 00213, 1:1 per tävling som DB-invariant): öppna para-kategorier ur FIPJP-katalogen, entry_model (para_only\

    mixed_para_open), throwing_circle (standard|extended_60cm|ramp_allowed), assistant_allowed och accessibility_requirement (wheelchair_full|partial|none) — allt ur DEKLARERADE vokabulärer i kod, aldrig fri text, aldrig en tenant-redigerbar tabell. adapted behåller EN definition — klassernas is_adapted (regelkortet omdefinierar den aldrig; ett kort kan inte skapas utan levande anpassad klass ⇒ 422 para_no_adapted_class). D-COMP:s allowed_para_categories får sin saknade katalogvalidering i BÅDA klass-skrivvägarna (422 para_category_unknown / para_category_not_open med fältpekare — delmängdsinvarianten, så två listor aldrig blir två sanningar), och anmälningsgrinden får EN snäv blockerare i den befintliga sömmen (409 para_classification_required, aktiv endast vid para_only ∧ icke-tom klasslista ∧ utan OPEN_NEC; utan regelkort är den INERT). Publikt: två additiva facetter (para_category, accessibility) + tre kortfält (adapted, para_categories, accessibility_requirement) + detaljens adapted_rules på husets BEFINTLIGA oautentiserade discovery — serverfiltrering, ingen ny rutt, oförändrad adapted/level/discipline-semantik. Arenans egen tillgänglighetsprofil förblir D-VENUE:s: kravet är arrangörens, ingen automatisk uppfyllnadsdom fälls. Lokal fixtur: go run . seed-para (två GLOBAL-publicerade demo-tävlingar i SWE genom D-COMP:s EGNA sömmar). Adminfliken *Anpassade tävlingar* + kalenderfiltret = t-2. Docs: specs/api/endpoints/para-competition-rulesets.md, specs/api/endpoints/public-competitions-adapted.md, docs/domain/para-petanque.md. | ✅ cc3657f5.m-4

Qualification Pathways

F04.11
Planned

Multi-stage qualification from local to international level.

How it works
  • F04.11.01 Shipped

    Qualification pathway definition (e.g., club > district > regional > national > world) — PL-F0411a

    ✅ greenfield-byggd i 7cd8cecf.m-4 (nivåerna kommer ur tenantens egna org_node_levels)
  • F04.11.02 Shipped

    Qualification spots allocation (how many advance from each stage) — PL-F0411a

    ✅ greenfield-byggd i 7cd8cecf.m-4 (places_forward per bunden tävlingsklass)
  • F04.11.03 Shipped

    Automatic qualification tracking (player qualifies at district → registered for regional) — PL-F0411a

    ✅ greenfield-byggd i 7cd8cecf.m-4 — med BOKFÖRD avgränsning: auto_entry_on_advancement flyttar spelaren fram i STEGEN och skriver INGEN tävlingsanmälan (anmälan ägs av D-COMP med avgift, godkännandegrind och klubbbundenhet)
  • F04.11.04 Shipped

    Wild card / invitation slots — PL-F0411a

    ✅ greenfield-byggd i 7cd8cecf.m-4 (den enda LAGRADE kvalificeringen; taket prövas under radlås)
  • F04.11.05 Shipped

    Qualification via ranking (top N nationally qualify for continental) — PL-F0411b

    ✅ greenfield-byggd i 7cd8cecf.m-4 (topp N ur en LÅST kval-snapshot, låset prövat vid varje härledning)
  • F04.11.06 Shipped

    Qualification history per player (which championships qualified for) — PL-F0411b

    ✅ greenfield-byggd i 7cd8cecf.m-5 — spelarhistoriken (GET /v1/tenant/selection/history/players/{userId}): hennes uttagningar + hennes kvalificeringar med EVIDENS, härledd vid läsning (ingen ny tabell, kval-halvan är m-4:s EGEN spårningssöm skopad till en människa). I 7cd8cecf.m-4 var raden ännu inte greenfield-byggd — m-4 spårade EN kvalstege i taget (m-4:s non-goal 8) och historiken över säsonger/stegar var uttryckligen senare arbete; det arbetet är m-5. ORDET är UTTAGNINGAR, aldrig landskamper: huset har inget landskampsregister, så selection_count räknar uttagningar registrerade i Petanque Life
  • F04.11.07 Planned

    Cross-reference: national qualification linked to continental/world entry — PL-F0411b

    ⛔ F04.11.07 är fortfarande inte greenfield-byggd — varken i 7cd8cecf.m-4 eller i 7cd8cecf.m-5, och det är ett UTTRYCKLIGT beslut: m-5 PRODUCERAR squad-artefakten (petanque-life-v1) men skickar den aldrig — inlämningen, kvittensen och M2M-mottagningen är D-PUBAPI (m-5:s bindande non-goal 1). Utan ett kvitto från CEP/FIPJP finns ingen byggd källa att korsreferera mot; mockupens fotnot renderas INTE och fabriceras inte. Uppdaterat (D-PUBAPI a95566cc.m-6, 2026-09): KVITTOT FINNS NU. Truppinlämningen till CEP/FIPJP är byggd (/v1/squad-submissions, kvittensen med sina MÄTTA kontroller, accepten på F1-6:s generiska ärendeyta — squad-submissions.md), så det finns en mottagen och beslutad inlämning att korsreferera MOT. Själva korsreferensen — att koppla den nationella kvalificeringen till den kontinentala/globala anmälan — är fortsatt D-NATIONAL/D-COMP:s och är INTE byggd här; m-6 äger transporten, inte kvalvägens koppling

International Competitions

F04.12
Planned

> **Truppinlämningen i arrangörsappen (D-ADMINAPP `94f74ebf.m-13`):** D-PUBAPI m-6:s truppinlämning till CEP/FIPJP

How it works
  • F04.12.01 Shipped

    National delegation management (federation submits team roster)

    ✅ PL-F0412a ✅ PL-F0412a
  • F04.12.02 Shipped

    Delegation size limits per event type

    ✅ PL-F0412a ✅ PL-F0412a
  • F04.12.03 Shipped

    Nation vs nation format (e.g., triplette championship = 3 triplettes per nation)

    ✅ PL-F0412a ✅ PL-F0412a
  • F04.12.04 Shipped

    Flag/anthem management per nation (for ceremonies)

    ✅ PL-F0412a ✅ PL-F0412a
  • F04.12.05 Shipped

    Accreditation system (player, official, media, VIP badges)

    ✅ PL-F0412a ✅ PL-F0412a
  • F04.12.06 Shipped

    Multi-language announcements at event

    ✅ PL-F0412a ✅ PL-F0412a
  • F04.12.07 Shipped

    Time zone management (schedule in local time, display in viewer's time)

    ✅ PL-F0412b ✅ PL-F0412b
  • F04.12.08 Shipped

    International ranking points (FIPJP points from world/continental events)

    ✅ PL-F0412b ✅ PL-F0412b
  • F04.12.09 Shipped

    Travel and accommodation coordination per delegation

    ✅ PL-F0412b ✅ PL-F0412b
  • F04.12.10 Shipped

    International competition results fed back to national rankings

    ✅ PL-F0412b ✅ PL-F0412b
  • F04.12.11 Shipped

    Historical records per international competition (all-time medal table)

    ✅ PL-F0412b ✅ PL-F0412b
  • F04.12.12 Shipped

    International competition bidding (federation applies to host)

    ✅ PL-F0412b ✅ PL-F0412b

Casual Games

F04.13
Planned

Non-tournament games between players — social play, practice matches, club evenings.

How it works
  • F04.13.01 Shipped

    Quick game creation (pick players, format, start playing) — PL-F0413a

    ✅ PL-F0413a | ⊘ ägarbeslut (live-räkning av ett casual-spel; m-3 loggar i efterhand — närmaste granne D-SOCIALSPEL)
  • F04.13.02 Shipped

    Casual game score tracking (same scoring as official matches) — PL-F0413a

    ✅ PL-F0413a | ⊘ ägarbeslut (samma som F04.13.01 — poängen loggas i efterhand)
  • F04.13.03 Shipped

    Mène tracking for casual games (optional) — PL-F0413a

    ✅ PL-F0413a | ⊘ ägarbeslut (samma som F04.13.01)
  • F04.13.04 Shipped

    Casual game history per player — PL-F0413a

    ✅ PL-F0413a | LIVE 0154301b.m-3 — GET /v1/me/casual-matches (JAG-projektionen) och GET /v1/social/casual-matches
  • F04.13.05 Shipped

    Casual game ELO impact (configurable — can be weighted lower than official) — PL-F0413a

    ✅ PL-F0413a | LIVE 0154301b.m-3 — §5d.2 match_completed source_kind='casual' till D-RANK (vikten casual_weight är D-RANK:s); kvittot my.elo läses ur liggaren
  • F04.13.06 Shipped

    Location tagging (where was the game played — venue or GPS)

    ✅ PL-F0413b | LIVE 0154301b.m-3 — location_hint {label, lat, lng} avrundad till ≈ 100 m; anläggningsbundna spel hör till D-VENUE (422 casual_match_venue_bound) ✅ PL-F0413b
  • F04.13.07 Shipped

    Invite players to casual game (in-app)

    ✅ PL-F0413b | delvis 0154301b.m-3 — kontobärande medspelare ur kontaktmängden får beskedet social_casual_match_logged; follow-grafen som källa ⊘ senare D-SOCIAL-delta ✅ PL-F0413b
  • F04.13.08 Shipped

    "Looking for game" status (player signals availability at a venue)

    ✅ PL-F0413b | ⊘ ägarbeslut (närvarosignal på en anläggning: D-VENUE/D-DISC) ✅ PL-F0413b
  • F04.13.09 Shipped

    Club evening management (organized casual play sessions)

    ✅ PL-F0413b | ⊘ D-SOCIALSPEL (gängkvällen) ✅ PL-F0413b
  • F04.13.10 Shipped

    Random team generator (shuffle players into balanced teams by ELO)

    ✅ PL-F0413b | ⊘ D-SOCIALSPEL (lottningen) ✅ PL-F0413b
  • F04.13.11 Shipped

    Casual game statistics (separate from official stats)

    ✅ PL-F0413c | ⊘ D-RANK (casual-statistik i spelarens statistikvy) ✅ PL-F0413c
  • F04.13.12 Shipped

    Social sharing of casual game results

    ✅ PL-F0413c | ⊘ ägarbeslut (delning) ✅ PL-F0413c
  • F04.13.13 Shipped

    Photo/video from casual games

    ✅ PL-F0413c | ⊘ D-COMM (media) ✅ PL-F0413c

Player of the Match & Awards

F04.14
Planned

Inspired by football, tennis, and other sports — in-match and post-match recognition.

How it works
  • F04.14.01 Shipped

    Player of the Match voting (spectators, officials, or automatic from stats)

    ✅ greenfield f01df0d0.m-2 — matchinstansen skapas EXPLICIT (POST /v1/award-instances, matchslutet skapar den aldrig), röstningen öppnas med sin FRYSTA regel, valsedeln materialiseras ur matchens egna anmälningar och rösten läggs antingen inloggad (POST /v1/me/award-ballots/{round_id}:vote, väljarklassen avgörs av SERVERN ur rullorna) eller anonymt genom den publika vägen med en HttpOnly förstapartskaka. Den statistik-baserade grenen är f01df0d0.m-1:s
  • F04.14.02 Shipped

    Player of the Tournament award

    ✅ greenfield f01df0d0.m-1 — katalograd med decision_method=panel; instansen föds open av publiceringen och avgörs med ett MANUELLT POST /v1/award-instances/{id}:decide med obligatorisk motivering — och sedan f01df0d0.m-2 kan samma pris i stället avgöras genom en RIKTIG panelomröstning med kvorum, jävsdeklaration och en attribuerbar juryröst
  • F04.14.03 Shipped

    Best Shooter award (highest tir accuracy in competition)

    ✅ greenfield f01df0d0.m-1 — metriken tir_hit_pct, RÄKNAD ur throw-rader i klassen i publiceringens EGEN transaktion (hit_bps i HELTALS-baspunkter med deklarerad half-up). Utan kastdata blir instansen not_measurable med skälet no_throw_data — aldrig en vinnare på tunn luft
  • F04.14.04 Shipped

    Best Pointer award (highest pointing accuracy)

    ✅ greenfield f01df0d0.m-1 — metriken point_hit_pct, samma källnivå och samma ärliga nej
  • F04.14.05 Shipped

    Most Carreaux award (most perfect hits)

    ✅ greenfield f01df0d0.m-1 — metriken carreau_count. Noll kröns aldrig: en klass där ingen slog en carreau ger no_qualifying_result, inte en vinnare med värdet 0
  • F04.14.06 Shipped

    Comeback of the tournament (biggest deficit overcome)

    ✅ greenfield f01df0d0.m-1 — metriken biggest_turnaround ur mene-nivån (tiebreak: FÄRRE spelade mèner vinner). Mène-för-mène är VALFRI i huset ⇒ utan den no_mene_data
  • F04.14.07 Shipped

    Fair play award (sportsmanship, nominated by umpires)

    ✅ greenfield f01df0d0.m-1 — katalograd med decision_method=umpire_nomination; instansen föds open och avgörs manuellt med motivering. Vinnaren kan vara en PERSON, en ANMÄLAN eller en ORGANISATION (composite-FK mot org_nodes (tenant_id, id))
  • F04.14.08 Shipped

    Season awards: Player of the Year, Young Player, Newcomer, Coach, Club, Umpire

    ✅ greenfield f01df0d0.m-1 — som KATALOGDATA (level=season, season_year = kalenderår). Sedan f01df0d0.m-2 får säsongspriset en instans EXPLICIT (utan aktivering, utan tävling, med en deterministisk scope_ref av (förbund, pris, år)) och avgörs genom nominering + röstning. Ingen publicering utlöser den — det är fortfarande en människas handling
  • F04.14.09 Shipped

    Award voting system (federation configurable: public vote, expert panel, stats-based)

    ✅ greenfield f01df0d0.m-1 + f01df0d0.m-2 — alla tre grenarna finns: den STATISTIK-baserade (m-1), den PUBLIKA/rulle-baserade och den VIKTADE rösten samt EXPERTPANELEN med kvorum (m-2). Konfigurationen är förbundets DATA i criteria med en SLUTEN nyckelmängd per metod (väljarkår · viktning i heltals-bps som måste summera till 10000 · fönster · tröskel · kvorum · mellanställningens synlighet · publiceringspolicy), och den ärver katalogens DUBBLA frysning. Räkningen är heltal hela vägen med deklarerad half-up, och ett delat högsta värde blir tie_unresolved — huset gör ingen automatisk tiebreak i en röstning
  • F04.14.10 Shipped

    Awards history and hall of fame integration

    ✅ greenfield f01df0d0.m-1 + f01df0d0.m-5 — historiken är rader sedan m-1 (award_instance + award_winner med decided_at/published_at och ett FRYST kriterium per instans, så ett avgjort pris för alltid bär den regel det dömdes efter), och hall of fame plus publiceringen till D-CMS-rekordväggen levererades i m-5. Ett inval är ett BESLUT: förvaltaren föreslår ur ett publicerat pris, ett publicerat rekord eller ett styrelseprotokoll, och en ANNAN människa avgör i F1-6 (hall_of_fame_induction; självbeslut ⇒ 403). Statusorden har EXAKT en skrivare var (hookparet respektive :withdraw), och EN levande invald per källa är ett partiellt unikt index — aldrig ett if. Namnet lagras inte för en person: det löses upp vid läsning bakom husets ENDA avtäckningsregel (awards.DiscloseHallOfFameHolder), ett lag med en dold medlem är odisclosed som helhet, och en SEVRAD person är odisclosed — en anonymiserad människa står aldrig som *»Raderad spelare«* på en hederssida. Väggen är en vanlig cms_page med blocket record_wall, skriven genom D-CMS:s EGNA sömmar (ingen rå DML mot cms_*), så redaktören äger sidan efteråt och record_scope_level=club ger en klubbvägg utan en ny rutt
  • F04.14.11 Shipped

    Record database with automatic record detection

    ✅ greenfield f01df0d0.m-3 — rekordkategorin är förbundets DATA (metrik · skop · riktning · trösklar) och posten en MÄTNING ur D-RANK:s performance_result/elo_rating och D-COMP:s publicerade resultat. Det finns medvetet ingen POST /v1/records: detekteringssömmen är enda producenten, med två anropare (nattsvepet award_record_detect_tick och människans :detect), och en människa granskar/publicerar/avslår. Idempotensen är faktum-nyckelns DB-invariant — som därmed också är »nagga aldrig igen«-garantin: en avslagen post kan aldrig resas på nytt. Lika värde superseder ingenting (delat rekord); faller källan bort auto-avslås en candidate medan en granskad/publicerad post STÄMPLAS och larmar (ett svep kör aldrig över en människa). Rekordboken är en LÄSNING ur template_of-kedjan — ingen tabell, ingen namnmatchning — och publiksiffran redovisas i coverage[] MED ägare, aldrig som ett tal
  • F04.14.12 Shipped

    Milestones and badges from career statistics

    ✅ greenfield f01df0d0.m-4 — milstolpeprogrammet är förbundets DATA (trösklar per mätetal ur en SLUTEN, kod-deklarerad katalog bunden till D-RANK:s rollup; mockupens 100 · 250 · 500 · 1000 står ingenstans i koden) och badgen ett FAKTUM om en karriär. Det finns medvetet ingen POST /v1/player-badges, ingen DELETE och inget :revoke — mätsömmen är enda producenten, med två anropare (nattsvepet award_milestone_detect_tick och människans :detect), och värdet LÄSES ur ranking.PerformanceRollup: D-AWARDS räknar aldrig en karriär själv. »En badge EN gång« är DB-invarianten unique (tenant_id, user_id, milestone_definition_id, threshold); en sänkt tröskel delar inte ut om (below_awarded_threshold) och en höjd tar aldrig tillbaka (threshold_retired, HÄRLETT vid läsning). Beskedet är en hälsning per spelare och körning (högsta tröskeln bär den, resten bundled) med MÄTT utfall på raden, och självläkningen är en EGEN notisplikt vars urval står i frågan. Spelaren ser alltid sina egna badges (GET /v1/me/badges, självguardad och cross-tenant); publiken bara genom TRE grindar i frågan (förbundets share_in_app, spelarens profile_public och husets inneslutning), där varje nej är BYTE-IDENTISKT tomt — ytan är varken ett existens- eller ett samtyckesorakel. ⊘ federations-skopad karriär (talen är cross-tenant; en tenant-skopad rollup-variant är ett tillägg i D-RANK, inte här)

Head-to-Head & Comparison Tools

F04.15
Planned

Inspired by tennis, chess, and combat sports.

How it works
  • F04.15.01 Shipped

    Head-to-head comparison (any two players — record, stats, ELO delta)

    ✅ PL-F0415a ✅ PL-F0415a
  • F04.15.02 Shipped

    Team vs team comparison (two clubs, two nations — all-time record)

    ✅ PL-F0415a ✅ PL-F0415a
  • F04.15.03 Shipped

    Player comparison tool (side-by-side: stats, ELO, ranking, strengths)

    ✅ PL-F0415a ✅ PL-F0415a
  • F04.15.04 Shipped

    Pre-match prediction (ELO-based win probability)

    ✅ PL-F0415a ✅ PL-F0415a
  • F04.15.05 Shipped

    Form guide (last 5/10/20 results, W/L streak)

    ✅ PL-F0415b ✅ PL-F0415b
  • F04.15.06 Shipped

    Surface/terrain performance comparison (indoor vs outdoor, gravel vs sand)

    ✅ PL-F0415b ✅ PL-F0415b
  • F04.15.07 Shipped

    Rivalry tracking (frequent opponents, notable matchups)

    ✅ PL-F0415b ✅ PL-F0415b

Records & Milestones

F04.16
Planned

Inspired by cricket, athletics, and tennis — tracking all-time records.

How it works
  • F04.16.01 Shipped

    All-time records database (per federation, per competition, per club)

    ✅ PL-F0416a
  • F04.16.02 Shipped

    Record categories: most titles, longest win streak, highest ELO, most 13-0 wins

    ✅ PL-F0416a
  • F04.16.03 Shipped

    Automatic record detection (system alerts when a record is broken)

    ✅ PL-F0416a
  • F04.16.04 Shipped

    Milestone alerts (100th match, 500th win, 10th season, etc.)

    ✅ PL-F0416a
  • F04.16.05 Shipped

    Career milestone badges

    ✅ PL-F0416a
  • F04.16.06 Shipped

    First-ever tracking (first player from a nation to reach X, first 13-0 in a final, etc.)

    ✅ PL-F0416b
  • F04.16.07 Shipped

    Youngest/oldest records (youngest champion, oldest active player, etc.)

    ✅ PL-F0416b
  • F04.16.08 Shipped

    Record book per competition (every edition's winners, stats, attendance)

    ✅ PL-F0416b
  • F04.16.09 Shipped

    Nation/club record walls (displayed on CMS site)

    ✅ PL-F0416b

Team Partnerships

F04.17
Planned

Track stable partnerships over time — who plays well together.

How it works
  • F04.17.01 Shipped

    Partnership registry (regular doublette/triplette combinations)

    ✅ PL-F0417a ✅ PL-F0417a
  • F04.17.02 Shipped

    Partnership win/loss record

    ✅ PL-F0417a ✅ PL-F0417a
  • F04.17.03 Shipped

    Partnership ELO (combined team rating)

    ✅ PL-F0417a ✅ PL-F0417a
  • F04.17.04 Shipped

    Partnership history (all matches played together)

    ✅ PL-F0417a ✅ PL-F0417a
  • F04.17.05 Shipped

    "Find a partner" matching (by ELO range, location, availability, playing style)

    ✅ PL-F0417b ✅ PL-F0417b
  • F04.17.06 Shipped

    Partnership chemistry score (win rate together vs. individually)

    ✅ PL-F0417b ✅ PL-F0417b
  • F04.17.07 Shipped

    Partnership profile page (public)

    ✅ PL-F0417b ✅ PL-F0417b

Per-National Competition Structures

F04.18
Planned

Per-nation championship pathways, league hierarchies, discipline variants, age-class configurations, and official calendars.

How it works
  • F04.18.01 Shipped

    France - Championnat de France national → ligue → comité → club

    ✅ PL-F0418a ✅ PL-F0418a
  • F04.18.02 Shipped

    France - 4 championship categories (Tête-à-tête, Doublette, Triplette, Mixte)

    ✅ PL-F0418a ✅ PL-F0418a
  • F04.18.03 Shipped

    France - Jeu provençal as separate discipline

    ✅ PL-F0418a ✅ PL-F0418a
  • F04.18.04 Shipped

    Sweden - SM (Svenska Mästerskapen)

    ✅ PL-F0418a ✅ PL-F0418a
  • F04.18.05 Shipped

    Sweden - Elitserien / Division 1 / Division 2

    ✅ PL-F0418a ✅ PL-F0418a
  • F04.18.06 Shipped

    Germany - DPV Bundesliga + Landesligan

    ✅ PL-F0418a ✅ PL-F0418a
  • F04.18.07 Shipped

    Norway - NM med kvalspel (flat hierarchy, federation-sanctioned)

    ✅ PL-F0418b ✅ PL-F0418b
  • F04.18.08 Shipped

    Spain - Campeonato de España (autonomous federation → national, Swiss system)

    ✅ PL-F0418b ✅ PL-F0418b
  • F04.18.09 Shipped

    FIPJP - VM-kvalifikationer per nation (national → continental → world)

    ✅ PL-F0418b ✅ PL-F0418b
  • F04.18.10 Shipped

    CEP - EM-kvalifikationer per nation (national → European Championship)

    ✅ PL-F0418b ✅ PL-F0418b
  • F04.18.11 Shipped

    Per-tenant tävlingskategorier (åldersklass) — Norway + Spain age classes

    ✅ PL-F0418b ✅ PL-F0418b
  • F04.18.12 Shipped

    Per-tenant officiell tävlingskalender — Norway + Spain calendars

    ✅ PL-F0418b ✅ PL-F0418b

Mêlée och avancerade tävlingsformat

F04.19
Planned

Multi-round mêlée tournaments, score-based pairing, 1v1 mêlée, cup formats, round robin, Swiss ELO, single/double elimination, poules→knockout, and Concours A/B/C.

How it works
  • F04.19.01 Shipped

    Mêlée draw algorithm (slumpad lagdragning)

    ✅ PL-F0419a ✅ PL-F0419a
  • F04.19.02 Shipped

    Supermêlée med score-based pairing

    ✅ PL-F0419a ✅ PL-F0419a
  • F04.19.03 Shipped

    Tête-à-tête mêlée variation

    ✅ PL-F0419a ✅ PL-F0419a
  • F04.19.04 Shipped

    Coupe de France-format

    ✅ PL-F0419a ✅ PL-F0419a
  • F04.19.05 Shipped

    National Cup-format per nation

    ✅ PL-F0419a ✅ PL-F0419a
  • F04.19.06 Shipped

    Round robin (alla mot alla)

    ✅ PL-F0419a ✅ PL-F0419a
  • F04.19.07 Shipped

    Schweizer system med ELO-baserad pairing

    ✅ PL-F0419b ✅ PL-F0419b
  • F04.19.08 Shipped

    Single elimination bracket

    ✅ PL-F0419b ✅ PL-F0419b
  • F04.19.09 Shipped

    Double elimination bracket

    ✅ PL-F0419b ✅ PL-F0419b
  • F04.19.10 Shipped

    Pool play → knockout-format

    ✅ PL-F0419b ✅ PL-F0419b
  • F04.19.11 Shipped

    Concours A/B/C med trösteklass

    ✅ PL-F0419b ✅ PL-F0419b

Official Rankings per Nation

F04.20
Planned

Official ranking preset definitions and provisioning for 5 nations/bodies. Static preset configurations with one-click provisioning to RankingConfig documents. Per-tenant formula config, cross-tenant ELO, ranking trends, qualification snapshots, and dispute workflow.

How it works
  • F04.20.01 Shipped

    France — Classement national + ligues + comités (24 mo, linear decay)

    ✅ PL-F0420a ✅ PL-F0420a
  • F04.20.02 Shipped

    Sverige — SM-ranking (12 mo, no decay) + nationell ELO

    ✅ PL-F0420a ✅ PL-F0420a
  • F04.20.03 Shipped

    Deutschland — DPV-Rangliste (36 mo, weighted_years 3/2/1, A-D multipliers)

    ✅ PL-F0420a ✅ PL-F0420a
  • F04.20.04 Shipped

    FIPJP — World ranking (cross-tenant, world scope)

    ✅ PL-F0420a ✅ PL-F0420a
  • F04.20.05 Shipped

    CEP — Continental ranking (cross-tenant, continental scope)

    ✅ PL-F0420a ✅ PL-F0420a
  • F04.20.06 Shipped

    Per-tenant ranking formula (point model with bonus rules, caps, thresholds)

    ✅ PL-F0420b ✅ PL-F0420b
  • F04.20.07 Shipped

    Cross-tenant ELO for casual matches (global singleton config, margin modifier)

    ✅ PL-F0420b ✅ PL-F0420b
  • F04.20.08 Shipped

    Ranking history and trends (direction, moving average, velocity)

    ✅ PL-F0420b ✅ PL-F0420b
  • F04.20.09 Shipped

    Ranking snapshot at qualification deadline (locked freeze for team selection)

    ✅ PL-F0420b ✅ PL-F0420b
  • F04.20.10 Shipped

    Dispute ranking points (formal process with review/resolve workflow)

    ✅ PL-F0420b ✅ PL-F0420b

Live Scoring & Official Result Entry

F04.21
Planned

Real-time scoring infrastructure: mobile-first live entry with offline support, official scorekeeper role with digital signing, real-time leaderboard, push notifications, score corrections with audit, score protests, walkover handling, and round timing.

How it works
  • F04.21.01 Shipped

    Live score entry on mobile with offline support

    ✅ PL-F0421a ✅ PL-F0421a
  • F04.21.02 Shipped

    Official scorekeeper role with digital signing

    ✅ PL-F0421a ✅ PL-F0421a
  • F04.21.03 Shipped

    Real-time leaderboard updates (SSE)

    ✅ PL-F0421a ✅ PL-F0421a
  • F04.21.04 Shipped

    Push notifications for match events (subscriptions)

    ✅ PL-F0421a ✅ PL-F0421a
  • F04.21.05 Shipped

    Score correction flow with audit

    ✅ PL-F0421b ✅ PL-F0421b
  • F04.21.06 Shipped

    Score protest from team captain

    ✅ PL-F0421b ✅ PL-F0421b
  • F04.21.07 Shipped

    Walkover and WO handling

    ✅ PL-F0421b ✅ PL-F0421b
  • F04.21.08 Shipped

    Round timing per round (45 min default)

    ✅ PL-F0421b ✅ PL-F0421b
  • F04.21.20 Shipped

    VolunteerScoreEntry — parallel light-weight scoring surface optimised for volunteers, big-button UI, idempotent on (device_id, client_ts, end_number), soft-validation with stable warning codes (zero_score_end / both_teams_scored / score_above_13 / missing_end_<n>) — PL-T222

    ✅ PL-T222 ✅ PL-T222
  • F04.21.21 Shipped

    Volunteer offline cache — exponential-backoff retry-loop, server-idempotency on tuple guarantees no duplicates, sync-status badge (synced/pending/error) — PL-T222

    ✅ PL-T222 ✅ PL-T222
  • F04.21.22 Shipped

    Dispute flagging — measure / dead_end / timeout / rule_question / other, sets is_dispute=true + needs_review, dispatchar scoring.dispute_raised till court-marshal via F09.02 — PL-T222

    ✅ PL-T222 ✅ PL-T222
  • F04.21.23 Shipped

    BulkScoreUpload — fixed-column CSV (competition_match_ref,end_number,team_a_points,team_b_points,scorer_note), parse-job med per-row error/warning, atomic-per-match apply, status uploaded/parsing/validated/applied/partially_applied/failed — PL-T222

    ✅ PL-T222 ✅ PL-T222
  • F04.21.30 Shipped

    Enhetsregistret scoreboard_device (migration 00161): den fysiska tavlan ägd av PL:s tenant-noll, bunden till hyresgästens match med mjuka referenser, med serial_no/kit_instance_id mot D-EQUIP:s brädregister — 1ee83e2c.m-1

    ✅ 1ee83e2c.m-1 (t-1)
  • F04.21.31 Shipped

    Signaturverifierad uplink-ingest POST /v1/scoreboards/ingest (LNS-webhook, X-PL-Webhook-Signature, ±5 min färskhetsfönster, fail-closed utan en enda DB-skrivning) — 1ee83e2c.m-1

    ✅ 1ee83e2c.m-1 (t-1)
  • F04.21.32 Shipped

    Uplink → score_entry med source='board' och device_id: delta mot competition.DeriveScore, ökning ⇒ ny mène, minskning med 1 ⇒ husets undo-rad (is_undo/replaces_entry_id), aldrig negativ poäng eller DELETE — 1ee83e2c.m-1

    ✅ 1ee83e2c.m-1 (t-1)
  • F04.21.33 Shipped

    Validering mot den resolvade poänggränsen (ResolveScoring, aldrig hårdkodad 13:a) + stabila avvisningskoder (score_above_max, score_decrement_too_large, invalid_score_delta, scoreboard_match_closed, scoreboard_match_mismatch) — 1ee83e2c.m-1

    ✅ 1ee83e2c.m-1 (t-1)
  • F04.21.34 Shipped

    Replay-skydd på frame counter inom sessions-epok + partiellt unikt index på (device_id, session_epoch, f_cnt) where outcome='applied' ⇒ exakt-en-gång även vid at-least-once-leverans; varje utfall spåras append-only i scoreboard_uplink_event — 1ee83e2c.m-1

    ✅ 1ee83e2c.m-1 (t-1)
  • F04.21.35 Shipped

    match_final → D-COMP:s egen FSM (Transition + CompleteMatch) med vinnare ur DeriveOutcome; tavlan sätter aldrig confirmed_by_* — det fysiska långtrycket är en inmatning, inte resultatsignering — 1ee83e2c.m-1

    ✅ 1ee83e2c.m-1 (t-1)
  • F04.21.36 Shipped

    Flott-/bindnings-API GET /v1/scoreboards, GET\

    PATCH /v1/scoreboards/{id}, POST /v1/scoreboards, POST /v1/scoreboards/{id}/assign-match — ETag/If-Match, cursor-paginering, server-injicerat skop (hyresgästen ser bara enheter med aktiv uthyrning), nyckelfälten projiceras aldrig — 1ee83e2c.m-1 | ✅ 1ee83e2c.m-1 (t-2)
  • F04.21.37 Shipped

    Två mandat, inte ett (scoreboard:fleet_admin i den smala systemmallen platform_scoreboard_admin; scoreboard:operate på klubb-/distrikts-/förbundsadmin) + fixturen seed-scoreboard-hw som konsumerar D-EQUIP:s custody-brädor — 1ee83e2c.m-1

    ✅ 1ee83e2c.m-1 (t-2)
  • F04.21.38 Shipped

    Enhetstelemetri som riktiga rader (migration 00162): scoreboard_device_health (1:1 per enhet — batteri, tavlans egen RSSI, gateway-RSSI/SNR ur rxInfo, senast sedd, härledd presence) + tidsserien scoreboard_health_sample, upsertad i ingestens enda transaktion. Ingen temperaturserie: v1-payloaden mäter ingen temperatur, over_temp är en flagga — 1ee83e2c.m-2

    ✅ 1ee83e2c.m-2 (t-1)
  • F04.21.39 Shipped

    Larm-inboxen scoreboard_alert + GET /v1/scoreboards/alerts(/{id}, /acknowledge, /resolve): fem typer, warning/critical, en öppen rad per (enhet, typ) via partiellt unikt index, kvittens ≠ lösning (kvittensen är idempotent och fryser eskaleringen), auto-lösning per typ — tamper löses endast manuellt — 1ee83e2c.m-2

    ✅ 1ee83e2c.m-2 (t-1)
  • F04.21.40 Shipped

    Trösklarna är konfig-data, aldrig konstanter — scoreboard_telemetry_config med treskikts-upplösning enhet → kit → plattform (null = ärv) och GET/PUT /v1/scoreboards/telemetry-config*; en ändring får effekt på nästa uplink utan omstart — 1ee83e2c.m-2

    ✅ 1ee83e2c.m-2 (t-1)
  • F04.21.41 Shipped

    Downlink-porten och kön (LNSDownlink + register + deterministisk fake + ChirpStack-adapter bakom env): scoreboard_command med den ärliga statusmaskinen queued → sent → acked \

    expired | failed, där sent betyder LNS:en accepterade enqueuen, aldrig levererad — 1ee83e2c.m-2 | ✅ 1ee83e2c.m-2 (t-2)
  • F04.21.42 Shipped

    Tamper-armering POST /v1/scoreboards/{id}/tamper-arm\

    tamper-disarm (202 med kommandoraden, If-Match, konvergent på partiellt unikt index) + kvittensvägen POST /v1/scoreboards/ingest?event=ack på samma signatur-fail-closed: enhetens tamper_armed speglas först vid tavlans egen kvittens — 1ee83e2c.m-2 | ✅ 1ee83e2c.m-2 (t-2)
  • F04.21.43 Shipped

    assign-match köar set_match (0x01) och auto-arm/disarm ur D-EQUIP:s egna emitterade scoreboard_inventory_event-rader (received ⇒ arm, returning ⇒ disarm) — läsning, aldrig skrivning i D-EQUIP:s revir; dedup-cursorn lever på m-2:s egen kommandorad — 1ee83e2c.m-2

    ✅ 1ee83e2c.m-2 (t-2)
  • F04.21.44 Shipped

    Hälsosvepet api run-job scoreboard_health_sweep med fyra plikter (närvaro-larm stale/lost, auto-arm/disarm-avstämning, kommando-TTL + omförsök, retention på tidsserien), now injicerat, batch-takat och idempotent — 1ee83e2c.m-2

    ✅ 1ee83e2c.m-2 (t-1/t-2)

External Event Proxying

F04.22
Planned

Cross-tenant event display: subscribe to GLOBAL-published competitions from other tenants, cache metadata locally, sync every 15 min, render in CMS upcoming-events widget with source badge and override support.

How it works
  • F04.22.01 Shipped

    ExternalEventProxy model with sync lifecycle (OK/STALE/FAILED/SOURCE_DELETED)

    ✅ PL-T008 ✅ PL-T008
  • F04.22.02 Shipped

    Admin subscribe/unsubscribe to global competitions

    ✅ PL-T008 ✅ PL-T008
  • F04.22.03 Shipped

    Local overrides (title, translation, note) per proxy

    ✅ PL-T008 ✅ PL-T008
  • F04.22.04 Shipped

    Background sync job (15 min, batch 50, exponential backoff)

    ✅ PL-T008 ✅ PL-T008
  • F04.22.05 Shipped

    Public upcoming-events endpoint (union of own + proxied)

    ✅ PL-T008 ✅ PL-T008
  • F04.22.06 Shipped

    CMS widget renders proxy events with source badge and link

    ✅ PL-T008 ✅ PL-T008
  • F04.22.07 Shipped

    Admin UI with status colors, search, subscribe, resync

    ✅ PL-T008 ✅ PL-T008
  • F04.22.08 Shipped

    Manual resync with rate limiting (1/min per proxy)

    ✅ PL-T008 ✅ PL-T008

Para-pétanque Classification & Adapted Competition

F04.23
Planned

FIPJP-aligned para-pétanque classification system: per-player

  • F04.23.01 Shipped

    ParaClassification model with FIPJP categories (W1/W2/W3/standing/visual/intellectual/open), status, validity window

    ✅ PL-T220 ✅ PL-T220
  • F04.23.02 Shipped

    ClassificationPanel with 3–5 members and required role coverage (medical+coach+admin)

    ✅ PL-T220 ✅ PL-T220
  • F04.23.03 Shipped

    ClassificationDecision with quorum, panel votes, reasoning, audit

    ✅ PL-T220 ✅ PL-T220
  • F04.23.04 Shipped

    Cross-tenant verify endpoint mirroring license-verify (FIPJP-recognised panels only)

    ✅ PL-T220 ✅ PL-T220
  • F04.23.05 Shipped

    Public adapted-competition discovery (/public/competitions?adapted=true) with category + accessibility filters

    ✅ PL-T220 ✅ PL-T220
  • F04.23.06 Shipped

    Daily expiry cron + 30/14/7-day renewal-reminder notifications

    ✅ PL-T220 ✅ PL-T220

Seriespel / Leagues — Struktur & Admin-API (D-LEAGUE m-1)

F04.24
Planned

Liga-strukturfundament (greenfield ovanpå den platta tävlingskärnan): säsong →

  • F04.24.01 Shipped

    Datalager: league_season/division/division_group/promotion_rule (migration 00078 + sqlc + store), tenant-scopat, optimistiskt låst, soft delete

    ✅
  • F04.24.02 Shipped

    Admin-CRUD-API /v1/league/* för säsong/division/grupp/upp-ned-regel (ETag/If-Match, audit, capability competitions:write)

    ✅
  • F04.24.03 Shipped

    Pyramid-läsyta GET /v1/league/seasons/{id}/pyramid per (säsong, player_class_code) — nivåer topp→botten + parallella grupper + admin per tier + upp/ned-länkar

    ✅
  • F04.24.04 Shipped

    Preset-applicering POST …/apply-preset — materialiserar seedad landstopologi som riktiga rader, idempotent per (säsong, preset_key)

    ✅
  • F04.24.05 Shipped

    seed-leagues-subkommando + SE/FR-presets som tenant_configs-DATA (migration 00079); config-är-data-guard

    ✅
  • F04.24.06 Shipped

    Genererad TS-klient operations/league.ts (drift-gate make api-ts-client-check) för admin-frontend (t-3)

    ✅
  • F04.24.07 Shipped

    Admin seriespel-yta (admin/app/tavlingar/seriespel) — strukturhalvan av mockupen: säsongsväljare (+ skapa säsong), klass-stege-väljare, divisionspyramid (namn/gruppantal/admin-badge/↕-text) och landspreset-lista med applicerings-flöde, allt mot riktiga /v1/league-endpoints (ingen hårdkodad topologi). Tabell/upp-ned-legend = m-3 (utelämnad)

    ✅

Seriespel / Leagues — Encounter & sammansatt matchdag (D-LEAGUE m-2)

F04.25
Planned

Komposit-matchdagen (§M axel 5 / §N gap #1): ett klubbmöte (`encounter`) aggregerar flera

  • F04.25.01 Shipped

    Datalager: encounter/encounter_scoring/encounter_format (migration 00080/00081 + sqlc + store) + nullbar competition_match.encounter_id/sub_match_ordinal (delmatch = kärn-match, draw_id nullbar per A-1); ren deterministisk utfalls-härledning (sub_match_wins/total_points, forfeit-semantik)

    ✅
  • F04.25.02 Shipped

    Encounter-API:t kontraktfryst additivt (10 operationer under /v1/league/*): möte-format läs/sätt (konfig-DATA, 422-validering mot kärnans formatfamiljer) · start-play (fyller m-1 A-1-sömmen, idempotent) · RR-spelschema (enkel/dubbel, bye, regenererings-lås schedule_locked) · mötes-läsyta med delmatcher + aggregat i ett anrop · möte-start (delmatch-materialisering per slot) · ombokning (app-validerad reason + deadline-spärr, mockupens "Postponed match") · möte-w.o. · minimal delmatch-uppställning (antal-mot-format via RequiredTeamSize + lagtillhörighet — m-4-kroken, 00082)

    ✅
  • F04.25.03 Shipped

    Automatiskt mötesutfall i samma transaktion: sista delmatchens confirm/forfeit fullbordar mötet (encounter.complete); jury-korrigering (protest) omhärleder aggregatet (encounter.rederive) — settle-sömmen är strikt no-op för icke-liga-matcher (kärnan oförändrad)

    ✅
  • F04.25.04 Shipped

    SE/FR-preset-utökning (data-only): encounter_format per klass-stege i presets/{se,fr}.json; apply-preset (fryst path) materialiserar formatet idempotent; topologi-guarden utökad med kompositions-fingeravtryck

    ✅
  • F04.25.05 Shipped

    Admin matchdags-sektion + ombokningskort (admin/app/tavlingar/seriespel) mot riktiga endpoints (aktuell mockup design/src/pages/admin/seriespel.astro): grupp/rond/möte-väljare ur pyramid + mötesschema, delmatch-tabell (nr · format · poänginput hemma/borta · status) med rapportering via kärnans /v1/matches/{id}/menes+/confirm, mötesutfall-läget läst ur serverns scoring-aggregat (aldrig lokalt summerat), starta-möte (If-Match), verkliga tomt-/laddnings-/fel-tillstånd, ombokningskort med frusna orsaks-values + svenska etiketter (412/422 som riktiga fel). m-3/m-4-sektionerna utelämnade (ej stubbar)

    ✅

Seriespel / Leagues — Ligatabell & poäng + publik tabellvy (D-LEAGUE m-3)

F04.26
Planned

Facit-lagret (§N gap #8 / §K / §E): varje spelande grupps ligatabell räknas fram

  • F04.26.01 Shipped

    Datalager: standing.league_points/drawn/sub_wins (heltal, additiv migration 00083) + division_group.public_visible (default dold) + league_table_config (poängschema + forfeit-jsonb + ordnad tiebreaks-jsonb + slutfall, en levande konfig per division, arv division→grupp) + sqlc/store

    ✅
  • F04.26.02 Shipped

    Ren deterministisk tabell-/tiebreak-motor (internal/league/table.go): schema + ORDNINGSKÄNSLIG kedja (head_to_head/sub_match_wins/point_diff/points_for) + slutfall (shared_position/playoff), forfeit som konfig-data; omräknings-söm i samma transaktion som fullbordan/forfeit/omhärledning — korrigeringskaskaden når tabellen automatiskt, auditerbart (league.table.recompute)

    ✅
  • F04.26.03 Shipped

    Tabell-API:t kontraktfryst additivt: table-config läs/sätt (404 tills satt · 422 vid ogiltiga värden · If-Match = divisionens ETag · PUT triggar omräkning av divisionens grupper) · tabell-läsmodellen GET /v1/league/groups/{id}/table (rader i positionsordning med lagnamn server-side — m-2:s "starta spel som namn-läsväg"-workaround pensionerad, after_round, poänglegend-data, tiebreak_playoff; ETag = gruppens; 422 table_config_missing)

    ✅
  • F04.26.04 Shipped

    Zoner ur promotion_rule vid LÄSNING (FR-5): promotion (topp-up_n), playoff (barrage-platsen), relegation (botten-down_n, kantfall utan fel), kryss-nivå via zone_to_division_id — ren härledning, flytten exekveras aldrig (non-goal)

    ✅
  • F04.26.05 Shipped

    Playoff-instansiering ur tabellen POST /v1/league/groups/{id}/playoffs (3 typer: mästerskapsslutspel topp-N seedat 1vN/2vN-1 · upp/ned-kval enligt barrage-regel · fristående uppflyttningsturnering; legs 1\

    2): intern container-grupp med egen kärnklass (RR-tabellen förblir ren), mötena spelas via m-2:s flöden; idempotent per (grupp, typ); 409 table_not_ready utan underlag | ✅
  • F04.26.06 Shipped

    Publik yta: synlighetsgrind PUT /v1/league/groups/{id}/visibility (default DOLD, auditloggad) + oinloggade GET /v1/public/league/{tenant_slug}/seasons (navigeringsträd med ENDAST synliggjorda grupper) och GET /v1/public/league/{tenant_slug}/groups/{id}/table (läsmodellen minus admin-fält; dold/okänd/fel tenant ⇒ samma 404 utan läcka; tenant ur slug, aldrig bearer)

    ✅
  • F04.26.07 Shipped

    SE/FR-preset-utökning (data-only): table_config (schema + kedja + slutfall, FR med källnot) per klass-stege i presets/{se,fr}.json; apply-preset (fryst path) materialiserar tabell-konfigen idempotent; topologi-guarden utökad med poängschema-/kedje-fingeravtryck

    ✅
  • F04.26.08 Shipped

    Admin-tabellyta (admin/app/tavlingar/seriespel/TableSection.tsx: tabell # · Lag · S · V · F · Diff · P, poänglegend renderad ur gruppens VERKLIGA points_scheme-data — aldrig mockupens exempeltext, zonmarkering radfärg + ↑/↓, synliggör-kontroll med If-Match, kval/playoff-kort med de 3 frusna typerna + legs; m-2:s lagnamns-workaround UTFASAD — resolveGroupTeamNames läser tabell-läsmodellen) + publik oinloggad web-sida web/app/seriespel/[tenant] (säsong/division/grupp-val + tabell ur /v1/public/league/*, no-store ⇒ aldrig stale efter korrigering). Vy-specar: specs/admin/seriespel-tabell.md + specs/web/seriespel-publik-tabell.md

    ✅

Seriespel / Leagues — Parallella klass-stegar (spelklarhet) + reservlag & könskvot (D-LEAGUE m-4)

F04.27
Planned

Regel-lagret (§M axel 4+11 / §N gap #4/#5 / §L): seriespelets lag-regler är **verkliga och

  • F04.27.01 Shipped

    Datalager 00084 (additiv): registration.is_reserve_team (default false) + league_team_eligibility_rules (ETT jsonb-regeldokument per division, arv division→grupp, soft delete) + division.class_rule (nullbar jsonb — preset-transport tills start-play materialiserar på kärnans 00064-kolumner) + courts.enclosed (NULLBAR — NULL = okänt = fail-open) + sqlc/store med batchade faktaqueries (ingen N+1)

    ✅
  • F04.27.02 Shipped

    Ren spelklarhetsmotor (internal/league/eligibility.go): per-spelare-evaluering (roster · licens · övergång · klubb · klassregel via kärnans frusna CheckCategoryEligibility · reservlagsspärr) + uppställningsnivåns könskvot/ersättarregler/bankrav; fryst skälkodskatalog (§3b) + statusmappning eligible/warning/ineligible; kontraktspaket fryst FÖRE handlers (FR-13)

    ✅
  • F04.27.03 Shipped

    Regel-CRUD GET/PUT /v1/league/divisions/{id}/team-eligibility-rules (404 tills satt; If-Match = divisionens ETag; 422 validation_failed, okända fält avvisas; auditloggad) — reglerna är DATA, aldrig kod (TestNoHardcodedCountryTopology utökad)

    ✅
  • F04.27.04 Shipped

    Spelklarhets-läsytan GET /v1/league/registrations/{id}/eligibility: {squad {size,max?}, items[{status, checks{roster,license,transfer,club}, reasons[], quarantine_until?}]} — ALLA skäl ackumulerade, batchläst (max 12 queries per koll oavsett truppstorlek, NFR-9), valfri ?player_profile_id= för icke-rostrade (late entry-vyn)

    ✅
  • F04.27.05 Shipped

    Verkställighet: uppställnings-PUT avvisar KÄNT ej spelklara spelare (422 lineup_ineligible + samtliga skäl — klassregel/licens/karantän/klubb/reservlagsspärr/könskvot/ersättarregler); rapporteringen (kärnans mène/confirm) OMEVALUERAR persisterade uppställningar; delmatch utan uppställning rapporteras som i m-2 (fail-open); anmälningsytan bär is_reserve_team + squad_full/reserve_team_tier/one_team_per_club; PATCH-actions add_player/late_entry (roster-lås; late entry = enda auditloggade vägen förbi)

    ✅
  • F04.27.06 Shipped

    Arena-valet PUT /v1/league/encounters/{id}/venue med bankravsvalidering (court_too_small/court_not_enclosed under 422 court_requirements_unmet; saknad bandata/enclosed NULL = fail-open; venues-API:t orört — ren läsning)

    ✅
  • F04.27.07 Shipped

    SE/FR-preset-utökning (data-only): class_rule per stege (SE V55 min_age 55, FR CNC-F women_only — med källnoter) + team_eligibility_rules per division; apply-preset (fryst path) materialiserar idempotent; NL/PL/CZ-kvotmotorn bevisad via config-data i test (deras presetdata = m-5)

    ✅
  • F04.27.08 Shipped

    Admin trupp & spelklarhets-yta (admin/app/tavlingar/seriespel/EligibilitySection.tsx): konfigkortet (truppstorlek-tak · "X av Y" ur spelklarhets-svarets squad {size,max} · lag-anmälnings-deadline · karantänväljare med tre frusna lägen) + spelklarhetskollen inför vald rond (grön/gul/röd chip MED text + mockupens fyra kontroller + ALLA klartext-skäl + quarantine_until-datum + blockeringsnotisen) + reservregler-kortet (max ersättare/matchdag · locked-to-sub-match ES · registrering-senast med frusna values) + bankravs-kortet (min-mått · pista cerrada ES) — allt mot riktiga endpoints, PUT mergar in i senast lästa kanoniska doc, verkliga tomt-/laddnings-/fel-tillstånd. Vy-spec: specs/admin/seriespel-trupp-spelklarhet.md

    ✅