Ce document donne une vue d'ensemble de l'API REST de TPI Flow. La source de vérité reste packages/api-spec/openapi.yaml.
- API applicative :
/api - Health check :
/api/healthz
- L'API est servie par Express 5 sur Bun.
- Les validations d'entrée reposent sur Zod.
- L'authentification est gérée par better-auth avec sessions cookie.
- Les données métier sont isolées par utilisateur.
| Domaine | Rôle principal |
|---|---|
| Santé | Vérifier la disponibilité du service |
| Tâches | CRUD des tâches, export Kanban PDF |
| Dépendances | Création et suppression des dépendances entre tâches |
| Sections | CRUD et réordonnancement des sections |
| Jalons | Gestion des milestones |
| Journal | CRUD, import et export des entrées journal |
| Checklist | Suivi des livrables documentaires |
| Paramètres projet | Configuration métier du TPI |
| Critères d'évaluation | CRUD et import en masse |
| Documents | Gestion des documents et des sections de document |
| Baselines | Snapshots du planning |
| Gantt import | Import de planning depuis GanttProject |
| Risques | CRUD, réordonnancement et export PDF |
| Export/import projet | Sauvegarde et restauration globale |
| Exceptions récurrence | Skip/override d'occurrences de tâches récurrentes |
| Notifications WebSocket | Flux temps réel vers le navigateur via Socket.io (bandeau maintenance, toasts, déconnexion forcée) |
| Feedback | Remontée de bugs ou demandes de fonctionnalités depuis l'app |
| Admin | Opérations d'exploitation réservées aux comptes avec role = "admin" (notifications, feedback, utilisateurs, digest) |
| Méthode | Endpoint | Usage |
|---|---|---|
GET |
/api/tasks |
Liste des tâches |
POST |
/api/tasks |
Création d'une tâche |
PUT |
/api/tasks/:id |
Mise à jour d'une tâche |
GET |
/api/journal/export-json |
Export structuré du journal |
POST |
/api/journal/import-json |
Restauration du journal |
PUT |
/api/project-settings |
Sauvegarde des paramètres du projet |
POST |
/api/gantt-import |
Import depuis GanttProject |
GET |
/api/project-export |
Export complet du projet |
POST |
/api/project-import |
Import complet du projet |
- Le serveur Socket.io est attaché au serveur HTTP Express sur le path
/socket.io. Le frontend se connecte viasocket.io-client(WebSocket avec fallback polling). L'authentification est résolue à la connexion via le cookie de session better-auth. - Un Redis adapter (
@socket.io/redis-adapter) propage les événements entre toutes les instances API (ex : 2 instances sur Railway). Sans Redis (REDIS_URL=none), le broadcaster fonctionne en mode single-instance. - Événements émis :
MAINTENANCE—{ message, severity }(info/warning/critical). Replay automatique aux nouveaux clients tant que la bannière est active.CLEAR_MAINTENANCE— efface la bannière côté clientNEW_FEATURE—{ title, message, url? }(affiché en toast)DIRECT_MESSAGE—{ title, message, severity }(message ciblé ou broadcast)FORCE_LOGOUT— déclenchesignOut()et l'événementtpi:auth-expired
- Socket.io gère les heartbeats (ping/pong) et la reconnexion automatique avec backoff exponentiel.
- L'état
MAINTENANCEest persisté dans la table singletonmaintenance_stateet rechargé au boot parinitBroadcaster()— la bannière survit à un redémarrage de l'API (ex : redeploy Railway en incident).
POST /api/feedbackenregistre un bug report ou une feature request soumis par l'utilisateur connecté.- Payload :
{ type: "bug" | "feature", title, description, pageUrl?, userAgent? }. Titre ≤ 200, description ≤ 2000,pageUrl≤ 2048,userAgent≤ 500. - Rate-limit dédié
feedbackLimiter: 5 soumissions / heure, scope par IP (clé par défaut d'express-rate-limit). encryptFeedbackchiffretitleetdescriptionau repos.pageUrletuserAgentsont stockés en clair (voirFEEDBACK_FIELDSdanspackages/db/src/field-encryption.ts).
Protégés par une session better-auth avec user.role = "admin". Le middleware chain est adminLimiter → requireAuth → requireAdmin. Non disponibles en mode desktop (non montés), non documentés dans le contrat public côté client.
| Méthode | Endpoint | Usage |
|---|---|---|
POST |
/api/admin/auth/check |
Vérifier que la session a bien role = "admin" (probe UI) |
GET |
/api/admin/notifications/stats |
Nombre de clients WebSocket connectés |
POST |
/api/admin/notifications/broadcast |
Diffuser un événement à tous les clients connectés |
GET |
/api/admin/feedback |
Lister les feedbacks utilisateurs (filtres status, type, pagination limit/offset) |
PATCH |
/api/admin/feedback/:id |
Mettre à jour le statut (new, in_review, done) |
GET |
/api/admin/users |
Lister les utilisateurs inscrits (sessions, statuts live WebSocket) |
POST |
/api/admin/users/:id/reset-password |
Réinitialiser un mot de passe et révoquer les sessions |
DELETE |
/api/admin/users/:id |
Supprimer un utilisateur (emails protégés via ADMIN_PROTECTED_EMAILS) |
POST |
/api/admin/messages/send |
Envoyer un message WebSocket ciblé |
POST |
/api/admin/messages/broadcast |
Broadcast WebSocket (avec confirmation UI) |
GET/PATCH |
/api/admin/changelog/:id? |
Consulter et éditer le cache de release notes |
POST |
/api/admin/digest/send, /api/admin/digest/send-all |
Envoyer le digest hebdomadaire (preview via GET /api/admin/digest/preview) |
- Rate-limit dédié
adminLimitersur tout/api/admin/*. requireAdminrenvoie401si pas de session,403si la session n'a pasrole = "admin".- Bootstrap du premier admin :
bun run db:promote-admin <email>après création d'un compte standard, ou utiliser le compte de seed déjà marquéadmin.
- Spécification OpenAPI : packages/api-spec/openapi.yaml
- Client React Query généré : packages/api-client-react/src/generated
- Schémas Zod générés : packages/api-zod/src/generated
Après modification de la spec, régénérer les artefacts :
bun run codegen- better-auth gère les sessions et les providers.
- Les routes métier utilisent le middleware d'authentification côté API.
- Les cookies sont préférés à un stockage JWT côté navigateur.