> ## Documentation Index
> Fetch the complete documentation index at: https://docs.cel-eleague.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Api http

# API HTTP Convex

Cette page cartographie les deux handlers HTTP Next.js et les routes enregistrées
par `convex/http.ts` et les modules `convex/http/*`. Elle décrit les chemins
réellement présents, sans remplacer les validateurs et règles d’autorisation des
fonctions appelées.

## Handlers Next.js

| Méthode | Route                        | Rôle                                                                                           |
| ------- | ---------------------------- | ---------------------------------------------------------------------------------------------- |
| `POST`  | `/api/feedback`              | Valide et limite les retours par IP, crée une issue GitHub puis notifie Convex en best-effort. |
| `GET`   | `/adsterra-frame/:snippetId` | Rend un document HTML isolé pour les snippets banner/native Adsterra autorisés.                |

Sources :

* `web/src/app/api/feedback/route.ts`
* `web/src/app/adsterra-frame/[snippetId]/route.ts`

## Architecture du routeur

`convex/http.ts` :

* crée le `httpRouter` Convex ;
* monte les routes de `@convex-dev/auth` via `auth.addHttpRoutes(http)` ;
* monte les modules auth, clubs, litiges, ligues, matchs, mercato, système,
  opérations, uploads et utilisateurs ;
* monte le webhook Stripe ;
* expose l’échange OAuth Convex.

Les routes dynamiques utilisent `pathPrefix` puis analysent les segments du
chemin dans le handler.

## Authentification, CORS et sécurité

* Les routes qui appellent `resolveCurrentSessionUser` ou
  `resolveActorUserIdFromRequest` résolvent l’utilisateur depuis les cookies
  Convex Auth et refusent les comptes bloqués. Les endpoints publics (ex.
  `GET /api/leagues`) ne résolvent aucune session : un compte bloqué peut les
  interroger comme un visiteur anonyme.
* Les cookies d’accès et de refresh utilisent les variantes sécurisées
  `__Host-*` sur HTTPS.
* Les origines autorisées sont dérivées de `AUTH_ALLOWED_ORIGINS`,
  `CORS_ORIGIN`, `NEXT_PUBLIC_APP_URL`, `CONVEX_SITE_ORIGIN` et
  `FRONTEND_URL`.
* Un `actorUserId` transmis dans un body ne remplace pas l’identité de session ;
  les routes sensibles vérifient la cohérence de l’acteur.
* Les routes `/api/ops/*` d’écriture utilisent l’en-tête `x-admin-key`, comparé
  en temps constant à `CONVEX_OPS_ADMIN_KEY`.
* Les mutations Convex restent la dernière frontière d’autorisation : exposer un
  chemin HTTP ne contourne pas leurs contrôles métier.

## Santé, webhooks et intégrations

| Méthode | Route                   | Rôle                                      |
| ------- | ----------------------- | ----------------------------------------- |
| `GET`   | `/api/health`           | Santé HTTP générale.                      |
| `GET`   | `/api/auth/health`      | Santé du bridge auth.                     |
| `GET`   | `/api/ops/admin/status` | Inventaire non destructif des routes ops. |
| `POST`  | `/stripe/webhook`       | Événements Stripe et index client local.  |
| `POST`  | `/resend-webhook`       | Événements de livraison Resend.           |
| `POST`  | `/feedback/notify`      | Notification interne du flux feedback.    |
| `POST`  | `/oauth/exchange`       | Échange de code OAuth Convex.             |

Les routes fournies directement par `@convex-dev/auth` sont montées par la
bibliothèque et ne sont pas redéfinies dans les modules CEL.

## Auth et compte

| Méthode  | Route                                | Opération                                              |
| -------- | ------------------------------------ | ------------------------------------------------------ |
| `POST`   | `/api/auth/ea/signup/search-clubs`   | Recherche de clubs EA.                                 |
| `POST`   | `/api/auth/ea/signup/club-members`   | Liste des membres EA d’un club.                        |
| `POST`   | `/api/auth/ea/signup/verify-member`  | Vérification du gamertag et émission d’un token court. |
| `POST`   | `/api/auth/complete-ea-verification` | Consommation du token EA pour le compte connecté.      |
| `POST`   | `/api/users/change-password`         | Changement ou première définition du mot de passe.     |
| `DELETE` | `/api/users/account`                 | Suppression self-service du compte.                    |

## Clubs et mercato

| Méthode | Route                            | Opération                                     |
| ------- | -------------------------------- | --------------------------------------------- |
| `GET`   | `/api/clubs/:clubId`             | Détail public du club, statistiques et forme. |
| `GET`   | `/api/clubs/:clubId/permissions` | Permissions du visiteur sur le club.          |
| `GET`   | `/api/mercato/movements`         | Mouvements de mercato filtrables et paginés.  |

## Ligues

### Lecture

| Méthode | Route                                 | Opération                        |
| ------- | ------------------------------------- | -------------------------------- |
| `GET`   | `/api/leagues`                        | Liste paginée.                   |
| `GET`   | `/api/leagues/main`                   | Ligue principale.                |
| `GET`   | `/api/leagues/:leagueId`              | Détail d’une ligue.              |
| `GET`   | `/api/leagues/:leagueId/standings`    | Classement.                      |
| `GET`   | `/api/leagues/:leagueId/calendar`     | Calendrier.                      |
| `GET`   | `/api/leagues/:leagueId/player-stats` | Statistiques joueurs filtrables. |

### Administration

| Méthode  | Route                                          | Opération                                   |
| -------- | ---------------------------------------------- | ------------------------------------------- |
| `POST`   | `/api/leagues`                                 | Création.                                   |
| `PATCH`  | `/api/leagues/:leagueId`                       | Mise à jour.                                |
| `DELETE` | `/api/leagues/:leagueId`                       | Suppression.                                |
| `POST`   | `/api/leagues/:leagueId/add-club`              | Ajout d’un club.                            |
| `POST`   | `/api/leagues/:leagueId/clubs/bulk`            | Ajout en lot.                               |
| `DELETE` | `/api/leagues/:leagueId/clubs/bulk`            | Retrait en lot.                             |
| `DELETE` | `/api/leagues/:leagueId/clubs/:clubId`         | Retrait d’un club.                          |
| `POST`   | `/api/leagues/:leagueId/generate-calendar`     | Génération du calendrier.                   |
| `POST`   | `/api/leagues/:leagueId/delete-calendar`       | Suppression avec snapshot et confirmations. |
| `POST`   | `/api/leagues/:leagueId/restore-calendar`      | Restauration depuis snapshot.               |
| `POST`   | `/api/leagues/:leagueId/recalculate-standings` | Recalcul du classement.                     |

## Matchs

### Lecture

| Méthode | Route                           | Opération                                    |
| ------- | ------------------------------- | -------------------------------------------- |
| `GET`   | `/api/matches`                  | Liste filtrable par ligue, équipe ou statut. |
| `GET`   | `/api/matches/:matchId`         | Détail enrichi du match.                     |
| `GET`   | `/api/matches/:matchId/context` | Contexte de compatibilité historique.        |

### Résultats, planning et statistiques

| Méthode  | Route                                           | Opération                                         |
| -------- | ----------------------------------------------- | ------------------------------------------------- |
| `POST`   | `/api/matches/:matchId/submit-result`           | Soumission de résultat.                           |
| `POST`   | `/api/matches/:matchId/validate-result`         | Validation.                                       |
| `POST`   | `/api/matches/:matchId/contest-result`          | Contestation.                                     |
| `POST`   | `/api/matches/:matchId/report-dispute`          | Ouverture d’un litige.                            |
| `POST`   | `/api/matches/:matchId/sync-ea-score`           | Synchronisation score EA.                         |
| `POST`   | `/api/matches/:matchId/sync-ea-stats`           | Synchronisation statistiques EA.                  |
| `POST`   | `/api/matches/:matchId/scheduling/propose`      | Proposition de date.                              |
| `POST`   | `/api/matches/scheduling/:propositionId/accept` | Acceptation d’une proposition.                    |
| `POST`   | `/api/matches/scheduling/:propositionId/reject` | Refus d’une proposition.                          |
| `POST`   | `/api/matches/scheduling/:propositionId/cancel` | Annulation d’une proposition.                     |
| `POST`   | `/api/matches/:matchId/stats`                   | Ajout unitaire ou import en lot des stats joueur. |
| `PATCH`  | `/api/matches/:matchId/stats/:statId`           | Mise à jour d’une stat joueur.                    |
| `DELETE` | `/api/matches/:matchId/stats/:statId`           | Suppression d’une stat joueur.                    |

### Administration des matchs

| Méthode  | Route                                            | Opération                                 |
| -------- | ------------------------------------------------ | ----------------------------------------- |
| `GET`    | `/api/admin/matches`                             | Liste admin paginée.                      |
| `POST`   | `/api/admin/matches/:matchId/set-result`         | Pose ou correction d’un résultat.         |
| `POST`   | `/api/admin/matches/:matchId/reset-result`       | Réinitialisation du résultat.             |
| `POST`   | `/api/admin/matches/:matchId/validate-result`    | Validation admin.                         |
| `POST`   | `/api/admin/matches/:matchId/resolve-dispute`    | Résolution d’un litige.                   |
| `POST`   | `/api/admin/matches/:matchId/apply-ea-candidate` | Choix d’un candidat score EA ambigu.      |
| `POST`   | `/api/admin/matches/:matchId/map-unmatched-ea`   | Rattachement d’une stat EA non reconnue.  |
| `POST`   | `/api/admin/matches/:matchId/sync-ea-score`      | Synchronisation score forcée.             |
| `POST`   | `/api/admin/matches/:matchId/sync-ea-stats`      | Synchronisation stats forcée.             |
| `PATCH`  | `/api/admin/matches/:matchId`                    | Mise à jour statut, planning ou activité. |
| `DELETE` | `/api/admin/matches/:matchId`                    | Réinitialisation admin du résultat.       |

## Litiges

| Méthode | Route                            | Opération             |
| ------- | -------------------------------- | --------------------- |
| `POST`  | `/api/disputes/:matchId/report`  | Création d’un litige. |
| `POST`  | `/api/disputes/:matchId/resolve` | Résolution.           |

## Uploads et opérations

| Méthode | Route                      | Opération                                  |
| ------- | -------------------------- | ------------------------------------------ |
| `POST`  | `/api/uploads`             | Upload image authentifié, 5 Mo maximum.    |
| `GET`   | `/uploads/:folder/:file`   | Lecture publique d’un objet uploadé.       |
| `POST`  | `/api/ops/upload/session`  | Descripteur de session d’upload opérateur. |
| `POST`  | `/api/ops/upload/complete` | Métadonnées de fin d’upload opérateur.     |
| `POST`  | `/api/ops/export`          | Création d’un export non destructif.       |

Les dossiers applicatifs acceptés par `/api/uploads` sont `profiles`, `clubs`,
`leagues` et `disputes`. Les formats détectés sont JPEG, PNG, GIF et WEBP.

## Convention de maintenance

Toute modification de `convex/http.ts` ou `convex/http/*.ts` doit actualiser
cette page. Les détails de payload ne doivent être documentés que lorsqu’ils
sont confirmés par les validateurs et appels Convex du handler.
