feat: Création de la structure api-contracts
- 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
This commit is contained in:
parent
ad81a2f4f4
commit
aa61831878
85
api-contracts/README.md
Normal file
85
api-contracts/README.md
Normal file
@ -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 <nom_migration>
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## ✅ 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)
|
||||||
|
|
||||||
25
api-contracts/backend-database/README.md
Normal file
25
api-contracts/backend-database/README.md
Normal file
@ -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)
|
||||||
|
|
||||||
177
api-contracts/frontend-backend/openapi.yaml
Normal file
177
api-contracts/frontend-backend/openapi.yaml
Normal file
@ -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
|
||||||
|
|
||||||
Loading…
x
Reference in New Issue
Block a user