L'API GraphQL
This content is not available in your language yet.
L’accueil et l’application joueur parlent à une seule API GraphQL (apps/api, GraphQL Yoga + Pothos). Elle ne contient aucune règle métier : chaque champ appelle une commande ou une requête de packages/domain, exécutée au nom de la personne connectée, sur le club de la requête.
L’endpoint et l’identité
Section intitulée « L’endpoint et l’identité »- Endpoint :
POST /graphqlsur l’API, en localhttp://localhost:<API_PORT>/graphql(le port est dans.ports). - Le club vient de l’hôte : l’en-tête
x-bo-club-host(envoyé par l’accueil et l’application joueur), sinon l’en-têteHost. En local, le club de démonstration estbo.localhost. Un sous-domaine du club ou un domaine personnalisé vérifié fonctionnent de la même façon. - La personne vient du cookie de session Better Auth, émis pour cet hôte de club et refusé sur un autre. Sans session, vous êtes anonyme : seuls les champs ouverts à tous répondent, comme
club,availabilityouopeningHours. - Protection CSRF : une requête « simple » sans
x-bo-club-hostest refusée. Envoyez toujours cet en-tête. - Le rôle (joueur, équipe, propriétaire) vient de l’adhésion au club. Un champ réservé à l’équipe ou au propriétaire est refusé avant même d’atteindre le domaine.
Les erreurs
Section intitulée « Les erreurs »Une règle métier refusée revient comme une erreur GraphQL dont extensions.code est le nom de l’erreur du domaine, avec ses champs. L’accueil traduit ces codes en français (« Ce terrain est déjà pris sur ce créneau » pour SlotTaken).
- Réservations :
SlotTaken,OutsideOpeningHours,InvalidDuration,NotACreneau(entre deux créneaux :previous/next),DurationNotOnStep,OutsideBookingWindow,TooManyActiveBookings(le joueur nommé paruserId/namea déjàmaxActiveBookingsmatchs à venir dans ce sport),OverCapacity,InvalidTransition,HoldExpired,ShareUnpaid,NotInClub. - Tarifs et droits :
EntitlementExhausted,EntitlementNotApplicable(avecrule:perDay,perWeek,perMonth,period,sport,duration,validity),ShareAlreadySettled. - Argent :
AlreadyPaid,PaymentPending(payé chez le prestataire, confirmation en attente),InsufficientWallet,PaymentsNotConfigured,ProviderError,DayClosed(avecdate: la journée a déjà son Z). - Horaires :
ScheduleInUse(avecsiteIdsetassignmentIds: les sites et les périodes qui suivent encore cet horaire, passées comprises),ScheduleOverlap(avecconflictingAssignmentId: la période du même site ou terrain qui chevauche ;nullquand deux enregistrements se sont croisés). - Événements :
RegistrationClosed(avecreason:cancelled,closed(inscriptions closes),ended),AlreadyEntered(avecuserIds: déjà dans une inscription en cours),EventFull(avecplaces: plus de place pour sortir de la liste d’attente),NotPartner. - Import :
ImportFileUnreadable,ImportMappingIncomplete,ImportNotValidated,ImportAlreadyApplied,ImportDayClosed. - Club :
ContrastTooLow,ImageRejected,HostRefused. - Génériques :
NotFound(avecentity,id),Forbidden(avecreason),Invalid(avecfieldetreason). - Infrastructure :
DbError,StorageError,EdgeErrorne renvoient que le code, sans détail ;DbErrora pour messagedatabase error. Un bug dans une commande revient enInternal(« internal error ») ; toute autre erreur inattendue revient masquée (INTERNAL_SERVER_ERROR). Le détail va dans les journaux du serveur.
Essayer depuis le terminal
Section intitulée « Essayer depuis le terminal »bo api query envoie une requête à l’API de ce worktree, connecté par défaut comme propriétaire du club bo (--as none pour anonyme, --as <email> pour quelqu’un d’autre) :
pnpm bo api query -q '{ planning(day: "2026-10-24T12:00:00Z") { bookings { kind startsAt } } }'pnpm bo api query -q '{ availability(day: "2026-10-26T12:00:00Z", sport: "padel") { resources { resource { name } stepMin creneaux { startsAt endsAt state durationsMin } } } }'Pour un script à vous, pnpm bo auth login <email> affiche un cookie de session et la commande curl correspondante.
Après une modification du schéma, pnpm bo api codegen réécrit apps/api/schema.graphql et régénère les types de l’accueil et de l’application joueur.
Les principaux champs
Section intitulée « Les principaux champs »Le schéma complet est dans apps/api/schema.graphql. Les plus utiles :
- Lecture :
club(public),me,planning(day),availability(day, sport),booking(id),quote(input),openingHours,scheduleSettings,scheduleChangePreview(change)(les réservations qu’un changement d’horaire laisserait hors horaires, avant d’enregistrer),periods,tariffs,formules,clients(search),clientFile(userId)(la fiche client, section par section),wallet(userId),bookingMoney(bookingId),till(date),closings,strayPayments(l’argent reçu en trop, à rendre),pilotage(from, to, sport). - Côté joueur :
playerClub,myBookings(scope),myBooking(id),myWallet,openMatches,searchMembers(q). - Réservations :
createBooking,createBlock,createSeries,moveBooking,cancelBooking,changeBookingPlayers,checkIn,markNoShow. - Côté joueur, en écriture :
bookAsPlayer,payMyShare,buyFormule,startTopUp. - Argent :
collectShare,collectBooking,recordPayment,payWithWallet,createTopUp,refundPayment,closeDay. - Réglages :
saveSchedule,deleteSchedule,setSiteDefaultSchedule,assignSchedule,setScheduleAssignmentDates,unassignSchedule,addClosure,createTariff,createPeriod,createFormule,sellFormule,createAddon,updateClubSettings,updateNotificationSettings. - Fiche client :
addClientNote,removeClientNote. - Import :
startImport,mapImport,applyImport.
Voir aussi
Section intitulée « Voir aussi »- Le serveur MCP, le même domaine pour un assistant.
- La référence de la CLI :
bo api query,bo api codegen,bo auth login.