From aa618318783fe418a6b3728fc4b00ebc103d27ed Mon Sep 17 00:00:00 2001 From: Julien Martin Date: Mon, 24 Nov 2025 15:45:07 +0100 Subject: [PATCH] =?UTF-8?q?feat:=20Cr=C3=A9ation=20de=20la=20structure=20a?= =?UTF-8?q?pi-contracts?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Contrats d'API Frontend ↔ Backend (OpenAPI 3.0) - Contrats Backend ↔ Database (Prisma/SQL) - Documentation complète pour génération de code - Permet l'interchangeabilité des composants --- api-contracts/README.md | 85 ++++++++++ api-contracts/backend-database/README.md | 25 +++ api-contracts/frontend-backend/openapi.yaml | 177 ++++++++++++++++++++ 3 files changed, 287 insertions(+) create mode 100644 api-contracts/README.md create mode 100644 api-contracts/backend-database/README.md create mode 100644 api-contracts/frontend-backend/openapi.yaml diff --git a/api-contracts/README.md b/api-contracts/README.md new file mode 100644 index 0000000..6cddf04 --- /dev/null +++ b/api-contracts/README.md @@ -0,0 +1,85 @@ +# 📜 API Contracts - PtitsPas + +Ce dossier contient les **contrats d'API** qui définissent les interfaces entre les différentes couches de l'application. + +## 🎯 Objectif + +Garantir que **Frontend**, **Backend** et **Database** respectent des contrats stricts, permettant de les rendre **interchangeables** sans casser l'application. + +--- + +## 📁 Structure + +``` +api-contracts/ +├── frontend-backend/ # Contrat Frontend ↔ Backend (HTTP REST) +│ ├── openapi.yaml # Spécification OpenAPI 3.0 (source de vérité) +│ └── generated/ # Code généré automatiquement +│ ├── dart/ # Client API pour Flutter +│ └── typescript/ # Types pour NestJS +│ +└── backend-database/ # Contrat Backend ↔ Database (ORM/SQL) + ├── schema.prisma # Schéma Prisma (ou TypeORM entities) + └── migrations/ # Migrations SQL versionnées +``` + +--- + +## 🔄 Workflow de Génération + +### 1. Frontend ↔ Backend + +**Source de vérité :** `frontend-backend/openapi.yaml` + +**Génération du client Dart (Flutter) :** +```bash +cd api-contracts/frontend-backend +docker run --rm -v "${PWD}:/local" openapitools/openapi-generator-cli generate \ + -i /local/openapi.yaml \ + -g dart-dio \ + -o /local/generated/dart +``` + +**Génération des types TypeScript (NestJS) :** +```bash +cd api-contracts/frontend-backend +npx openapi-typescript openapi.yaml --output generated/typescript/api.types.ts +``` + +--- + +### 2. Backend ↔ Database + +**Source de vérité :** `backend-database/schema.prisma` + +**Génération du client Prisma :** +```bash +cd api-contracts/backend-database +npx prisma generate +``` + +**Génération des migrations SQL :** +```bash +cd api-contracts/backend-database +npx prisma migrate dev --name +``` + +--- + +## ✅ Avantages + +- **Frontend interchangeable** : React, Vue, Angular → il suffit de régénérer le client API +- **Backend interchangeable** : Python, Go, Java → tant qu'il respecte `openapi.yaml` +- **Database read-only en prod** : User PostgreSQL `app_user` (pas de DDL) +- **Cohérence garantie** : Types générés = pas d'erreur de typage +- **Documentation auto** : OpenAPI = documentation interactive (Swagger UI) + +--- + +## 📚 Documentation + +- [OpenAPI 3.0 Spec](https://swagger.io/specification/) +- [Prisma Schema](https://www.prisma.io/docs/concepts/components/prisma-schema) +- [openapi-generator](https://openapi-generator.tech/) +- [openapi-typescript](https://github.com/drwpow/openapi-typescript) + diff --git a/api-contracts/backend-database/README.md b/api-contracts/backend-database/README.md new file mode 100644 index 0000000..07dba29 --- /dev/null +++ b/api-contracts/backend-database/README.md @@ -0,0 +1,25 @@ +# 💾 Backend ↔ Database Contract + +Ce dossier contient le **contrat de données** entre le Backend et la Base de Données. + +## 📋 Contenu + +- **`schema.prisma`** : Schéma de base de données (à créer) +- **`migrations/`** : Migrations SQL versionnées (actuellement dans `/database/migrations/`) + +## 🔄 Migration Future + +À terme, les migrations SQL de `/database/migrations/` seront gérées ici avec Prisma : + +```bash +# Générer une migration +npx prisma migrate dev --name add_user_phone + +# Appliquer en production +npx prisma migrate deploy +``` + +## 📚 Référence + +- [Prisma Migrate](https://www.prisma.io/docs/concepts/components/prisma-migrate) + diff --git a/api-contracts/frontend-backend/openapi.yaml b/api-contracts/frontend-backend/openapi.yaml new file mode 100644 index 0000000..7b7b50a --- /dev/null +++ b/api-contracts/frontend-backend/openapi.yaml @@ -0,0 +1,177 @@ +openapi: 3.0.0 +info: + title: PtitsPas API + version: 1.0.0 + description: | + API REST pour l'application PtitsPas. + Ce contrat définit l'interface entre le Frontend (Flutter) et le Backend (NestJS). + contact: + name: PtitsPas Team + email: admin@ptits-pas.fr + +servers: + - url: https://app.ptits-pas.fr/api + description: Production + - url: http://localhost:3000/api + description: Développement local + +paths: + /auth/login: + post: + summary: Authentification utilisateur + operationId: loginUser + tags: + - Authentication + requestBody: + required: true + content: + application/json: + schema: + type: object + required: + - email + - password + properties: + email: + type: string + format: email + example: admin@ptits-pas.fr + password: + type: string + format: password + example: "4dm1n1strateur" + responses: + '200': + description: Authentification réussie + content: + application/json: + schema: + type: object + properties: + access_token: + type: string + description: Token JWT d'accès + refresh_token: + type: string + description: Token JWT de rafraîchissement + user: + $ref: '#/components/schemas/User' + '401': + description: Identifiants invalides + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + + /users: + get: + summary: Liste des utilisateurs + operationId: listUsers + tags: + - Users + security: + - bearerAuth: [] + parameters: + - name: role + in: query + schema: + $ref: '#/components/schemas/RoleType' + - name: statut + in: query + schema: + $ref: '#/components/schemas/StatutUtilisateurType' + responses: + '200': + description: Liste des utilisateurs + content: + application/json: + schema: + type: array + items: + $ref: '#/components/schemas/User' + '401': + description: Non authentifié + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + +components: + schemas: + User: + type: object + required: + - id + - email + - role + - statut + properties: + id: + type: string + format: uuid + example: "550e8400-e29b-41d4-a716-446655440000" + email: + type: string + format: email + example: "parent@ptits-pas.fr" + prenom: + type: string + example: "Jean" + nom: + type: string + example: "Dupont" + role: + $ref: '#/components/schemas/RoleType' + statut: + $ref: '#/components/schemas/StatutUtilisateurType' + telephone: + type: string + example: "0612345678" + adresse: + type: string + photo_url: + type: string + format: uri + cree_le: + type: string + format: date-time + + RoleType: + type: string + enum: + - parent + - assistante_maternelle + - gestionnaire + - administrateur + - super_admin + + StatutUtilisateurType: + type: string + enum: + - en_attente + - actif + - suspendu + + Error: + type: object + required: + - message + - statusCode + properties: + message: + type: string + example: "Identifiants invalides" + statusCode: + type: integer + example: 401 + error: + type: string + example: "Unauthorized" + + securitySchemes: + bearerAuth: + type: http + scheme: bearer + bearerFormat: JWT + description: Token JWT obtenu via /auth/login +