Skip to main content

Matchs, reports, résultats et compositions

Cette page documente uniquement les règles vérifiées dans le backend Convex de CEL. Sources principales :
  • convex/schema.ts
  • convex/competition/match_result_mutations.ts
  • convex/competition/match_postponement_mutations.ts
  • convex/competition/match_postponement_shared.ts
  • convex/competition/match_admin_mutations.ts
  • convex/admin/disputes.ts
  • convex/competition/match_lineups.ts
  • convex/competition/match_scheduling_mutations.ts

matches.status vs match_reports.status

matches.status est une chaîne métier utilisée par les flux Convex de match : planification, paris, validation, etc. match_reports.status est un enum optionnel (PENDING, ACCEPTED, COUNTER_PROPOSED, CANCELLED, REJECTED) ; undefined reste possible en legacy. Conséquence vérifiée : une ligne de report legacy bloque la création d’un nouveau report tant que assertNoLegacyMatchReportsForMatch n’est pas passée.

matches et données liées

matches contient notamment : leagueId, homeClubId, awayClubId, matchday, scheduledAt, originalScheduledAt, postponedAt, postponedById, status, isActive. Des index techniques existent par ligue, statut, clubs, journée, date planifiée et états de synchronisation EA.

Cycle de vie des résultats de match

Statuts observés

  • scheduled
  • pending_validation
  • disputed
  • validated
  • completed (présent dans certains filtres ; le passage exact vers/depuis ce statut n’est pas confirmé dans les modules lus) [non vérifié]

Soumission GM (submitMatchResult)

  • En premier passage (match en scheduled), une soumission côté club crée homeScoreBy* / awayScoreBy* et met match.status = pending_validation.
  • En second passage, si les deux scores concordent :
    • scores finaux posés,
    • validatedAt,
    • match.status = validated,
    • settlement paris (vague courante) + mise à jour classement.
  • Si les soumissions divergent :
    • match_results.isDisputed = true,
    • match.status = disputed.

Actions admin avancées

  • adminSetMatchResult (admin) :
    • écrit un score explicite,
    • cible validated (défaut) ou pending_validation,
    • inverse la précédente contribution au classement si nécessaire,
    • peut nettoyer les sous-soumissions,
    • relance settlement/standings en validated,
    • réouvre paris si retour en pending_validation.
  • adminResetMatchResult (admin) :
    • supprime le résultat,
    • inverse classement si nécessaire,
    • remet en scheduled ou pending_validation,
    • réouvre les paris.
  • contestResult suit le flux de gestion de litige côté module (admin ou staff selon règles d’accès applicables), puis réévalue statut/paris selon la phase de résolution.

Report de match (postponement)

Les match_reports peuvent avoir les statuts vérifiés : PENDING, ACCEPTED, COUNTER_PROPOSED, CANCELLED, REJECTED. isReportQuotaConsumed compte uniquement les ACCEPTED. Le quota métier de base utilise league.reportsPerClubTotal avec un bonus premium PREMIUM_REPORTS_BONUS = 2 côté mutation.

requestPostponement

Conditions confirmées :
  • match existant en scheduled ou provisional,
  • acteur côté l’un des clubs,
  • quota disponible,
  • scheduledAt conforme, pas de conflit de calendrier,
  • pas de report legacy,
  • pas de PENDING / COUNTER_PROPOSED,
  • pas d’ACCEPTED existant.
Effet : création PENDING + audit.

acceptPostponement

Entrées : report PENDING ou COUNTER_PROPOSED.
  • Côté adverse si PENDING, côté demandeur si COUNTER_PROPOSED.
  • revalidation date + conflit + quota.
Effets :
  • status report ACCEPTED,
  • matches.scheduledAt déplacé,
  • conservation de originalScheduledAt si déjà présent,
  • postponedAt, postponedById mis à jour,
  • match.status = scheduled.

counterProposePostponement

Sur PENDING, côté adverse, avec nouvelle date valide. Statut -> COUNTER_PROPOSED.

cancelPostponement

Sur PENDING ou COUNTER_PROPOSED, acteur du club demandeur selon la logique du module.

rejectPostponement

Exclusif admin sur PENDING ou COUNTER_PROPOSED.

adminDirectPostponement

Parcours admin qui valide quotas/date/conflits et crée directement un report ACCEPTED en impactant le match.

Snapshots calendrier

Le modèle conserve au moins originalScheduledAt avant report. acceptPostponement met à jour scheduledAt du match. La mécanique exacte de restauration inverse d’un report annulé/invalidé après acceptation n’est pas pleinement détaillée dans les modules consultés. [non vérifié]

Litiges

reportDispute (module résultat) :
  • crée une entrée disputes en OPEN si aucun litige ouvert,
  • met match.status = disputed.
Le contrôle d’accès côté invocation n’est pas exclusivement admin-only : côté club actif et admin peuvent initier la déclaration selon helpers. resolveDispute (admin) :
  • APPROVED : validation du match,
  • REJECTED : match.status = pending_validation,
  • CUSTOM + score : enregistrement score, sortie litige, validatedAt.
convex/admin/disputes.ts expose la même palette de statuts de décision.

Compositions d’avant-match

match_lineups couvre les statuts draft et submitted. Règles vérifiées :
  • deadline : LINEUP_DEADLINE_MS = 20 * 60 * 1000,
  • soumission seulement si match scheduled et avant deadline,
  • minimum 7 joueurs à la soumission,
  • ADMIN et MODERATOR peuvent bypasser statut/deadline (auditées).

Limites / précautions

  • La provenance exacte de certains statuts historiques (ex. completed) reste non vérifiée dans ce périmètre de code. [non vérifié]
  • La restitution complète d’un report sur annulation/rejet post-acceptation dépend du chainage d’appels externes au module lu. [non vérifié]
Last modified on June 24, 2026