Aller au contenu

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.

  1. Déclarer la route dans packages/schemas/src/routes.ts : chemin, schémas TypeBox du corps et des réponses, refus documentés.
  2. É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.
  3. 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é.
  4. Appeler la route depuis les applications par creerClient de @biotrace/api-client : les types viennent du document, les erreurs sont des ErreurApiClient dont le code se traduit avec messageErreur de @biotrace/i18n.