API
Le contrat est un document OpenAPI 3.1, écrit depuis le registre de routes de packages/schemas (ADR 0036). L’API le sert sur GET /v1/openapi.json ; il est versionné dans packages/api-client/openapi.json, d’où openapi-typescript tire les types du client (packages/api-client/src/schema.ts). Contrat gelé en 1.0.0 (Lot 1, séquence A9), 1.1.0 depuis B2 (champ bloquant de Controle), puis 1.9.0 avec les routes de lecture de B3 (détail). Tout est additif. Le document est publié dans ce site : /openapi.json. Règle de version : un ajout de route est une version mineure (1.x), un retrait ou un changement incompatible une version majeure. L’empreinte du document est enregistrée avec la version (packages/schemas/contrat-gele.json) : un test échoue si le contrat change sans changement de version. Les services écrits en A3 à A8 n’ont pas encore de route ; elles arriveront en 1.x, additives, avec les écrans du back-office. Le téléphone s’appuie sur le protocole de synchronisation (tables PowerSync et commandes), dont le contrat des colonnes est gelé dans infra/powersync/contrat-donnees.json.
Points d’entrée en service :
| Route | Usage |
|---|---|
GET /sante |
Vivacité |
GET /v1/openapi.json |
Document OpenAPI de l’API (public) |
POST /v1/sync/commandes |
Envoi d’un lot de 1 à 50 commandes (protocole §6) |
GET /v1/sync/etat-appareil?appareil_id= |
Dernière séquence, statut, versions minimales, heure serveur |
POST /v1/sync/jeton |
Jeton PowerSync de 5 minutes |
GET /.well-known/jwks.json |
Clé publique du jeton PowerSync |
GET /v1/moi |
Utilisateur courant, organisation active et permissions effectives à l’instant (tout membre actif) |
GET /v1/campagnes?statut= |
Campagnes de l’organisation (tout membre actif) |
GET /v1/controles?statut=&limite= |
File de contrôle, du plus ancien au plus récent (review.resolve) |
POST /v1/controles/{id}/lever |
Lever un contrôle par une décision motivée (review.resolve) |
GET /v1/permissions |
Catalogue des permissions (permission_sets.manage) |
GET, POST /v1/utilisateurs |
Lister, créer un compte de l’organisation (users.manage) ; le mot de passe provisoire n’est rendu qu’à la création |
POST /v1/utilisateurs/{id}/desactiver |
Désactiver un compte, révoquer sessions et appareils, motif obligatoire (users.manage) |
POST /v1/utilisateurs/{id}/reinitialiser-mot-de-passe |
Nouveau mot de passe provisoire, sessions révoquées (users.manage) |
POST /v1/utilisateurs/{id}/revoquer-sessions |
Révoquer toutes les sessions d’un compte (users.manage) |
GET, POST /v1/ensembles-permissions, PATCH /v1/ensembles-permissions/{id} |
Ensembles de permissions ; le second facteur des titulaires suit les ensembles sensibles (permission_sets.manage) |
POST /v1/utilisateurs/{id}/attributions, POST /v1/attributions/{id}/terminer |
Attribuer et terminer un ensemble (permission_sets.manage) |
POST /v1/appareils/{id}/revoquer |
Révoquer un appareil et la session hors-ligne de l’agent (devices.manage) |
POST /v1/organisations |
Créer une organisation cliente, ses ensembles par défaut et son premier administrateur ; rôle editeur_support ou editeur_admin (EC-099), sans X-Organisation |
Toutes les routes /v1 exigent un jeton Keycloak (audience biotrace-api), sauf GET /v1/openapi.json. Le compte doit exister, dans l’organisation active, dans app.utilisateur ; les routes d’administration exigent en plus une permission, lue en base à chaque requête et refusée à un compte suspendu ou désactivé. Un refus de permission est inscrit au journal des appels d’administration. Un compte rattaché à plusieurs organisations précise l’organisation active par l’en-tête X-Organisation.
Ajouter ou modifier une route
Section intitulée « Ajouter ou modifier une route »- Déclarer la route dans
packages/schemas/src/routes.ts: chemin, schémas TypeBox du corps et des réponses, refus documentés. - Écrire le contrôleur Nest. Le test
apps/api/src/openapi.test.tséchoue si une route montée manque au registre, ou l’inverse. - Régénérer le contrat :
pnpm --filter @biotrace/schemas build && pnpm --filter @biotrace/api-client generer. L’intégration continue refuse un contrat périmé. - Appeler la route depuis les applications par
creerClientde@biotrace/api-client: les types viennent du document, les erreurs sont desErreurApiClientdont lecodese traduit avecmessageErreurde@biotrace/i18n.