Skip to main content
Petanque Life

Player of the Match & Awards

F04.14 12 features Planned

At a glance

In-match and post-match awards inspired by football and tennis: Player of the Match by spectator vote or stats, Player of the Tournament, Best Shooter / Best Pointer / Most Carreaux, Comeback of the Tournament, Fair Play, and season awards (Player of the Year, Young Player, Newcomer, Coach, Club, Umpire). Hall of fame integration preserves the history.

How it works

Awards are computed or voted depending on the federation's configuration. Player of the Match opens to spectators (push notification at match end), to officials (umpire vote), or runs automatically from the throw analytics — most carreaux + highest tir accuracy + decisive last-mène contribution. Player of the Tournament aggregates across all matches with a similar mix of votes and stats.

Skill-based awards key off the throw-level data captured in F04.05: Best Shooter takes the highest tir success ratio across the competition, Best Pointer the highest pointing accuracy, Most Carreaux the count of perfect hits. Comeback of the Tournament inspects the trajectory log and finds the team that recovered the largest deficit on the way to a win. Fair Play is umpire-nominated across the event with a free-text citation.

Season awards extend this beyond a single competition: Player of the Year, Young Player, Newcomer, Coach, Club, Umpire — each backed by a configurable voting system. The federation chooses public vote (one ballot per registered user with rate limiting), expert panel (named selectors with weighted votes), or stats-based (algorithm derived from season stats, with manual override). Voting periods open and close on declared dates, results publish to the CMS, and the awards history feeds the hall of fame: every winner across every year, with profile pages linking to the matches that earned the honour.

Key capabilities

  • Player of the Match by spectator vote, official vote, or automatic stats
  • Skill awards: Best Shooter, Best Pointer, Most Carreaux from throw analytics
  • Comeback of the Tournament from match trajectory analysis
  • Fair Play award nominated by umpires with citation text
  • Season awards: Player of the Year, Young Player, Newcomer, Coach, Club, Umpire
  • Configurable voting per federation (public, expert panel, stats-based)
  • Awards history and hall of fame integration with profile cross-links

In practice

Final whistle on the SM doublette final. Push notifications go out to all spectators tracking the match: "Vote for Player of the Match — closes in 30 minutes." 1,800 votes come in; the system cross-checks against the throw analytics and surfaces both — the public choice and the stats winner agree. The award lights up on the venue scoreboard and the federation CMS post.

After the season, a panel of five expert selectors votes Player of the Year via the secure ballot tool; results publish at the federation gala and the new winner joins the hall of fame, where their profile now shows a gold trophy badge linked to every Player-of-the-Match recognition they collected during the season.

Features in this subsystem

12
ID Status Features
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)