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