[Backend] API Inscription Parent - REFONTE Workflow 6 etapes (#72)
Co-authored-by: Julien Martin <julien.martin@ptits-pas.fr> Co-committed-by: Julien Martin <julien.martin@ptits-pas.fr>
This commit was merged in pull request #72.
This commit is contained in:
@@ -0,0 +1,344 @@
|
||||
# 📐 Règles de Codage - Projet P'titsPas
|
||||
|
||||
**Version** : 1.0
|
||||
**Date** : 1er Décembre 2025
|
||||
**Statut** : ✅ Actif
|
||||
|
||||
---
|
||||
|
||||
## 🌍 Langue du Code
|
||||
|
||||
### Principe Général
|
||||
**Tout le code doit être écrit en FRANÇAIS**, sauf les termes techniques qui restent en **ANGLAIS**.
|
||||
|
||||
---
|
||||
|
||||
## ✅ Ce qui doit être en FRANÇAIS
|
||||
|
||||
### 1. Noms de variables
|
||||
```typescript
|
||||
// ✅ BON
|
||||
const utilisateurConnecte = await this.trouverUtilisateur(id);
|
||||
const enfantsEnregistres = [];
|
||||
const tokenCreationMotDePasse = crypto.randomUUID();
|
||||
|
||||
// ❌ MAUVAIS
|
||||
const loggedUser = await this.findUser(id);
|
||||
const savedChildren = [];
|
||||
const passwordCreationToken = crypto.randomUUID();
|
||||
```
|
||||
|
||||
### 2. Noms de fonctions/méthodes
|
||||
```typescript
|
||||
// ✅ BON
|
||||
async inscrireParentComplet(dto: DtoInscriptionParentComplet) { }
|
||||
async creerGestionnaire(dto: DtoCreationGestionnaire) { }
|
||||
async validerCompte(idUtilisateur: string) { }
|
||||
|
||||
// ❌ MAUVAIS
|
||||
async registerParentComplete(dto: RegisterParentCompleteDto) { }
|
||||
async createManager(dto: CreateManagerDto) { }
|
||||
async validateAccount(userId: string) { }
|
||||
```
|
||||
|
||||
### 3. Noms de classes/interfaces/types
|
||||
```typescript
|
||||
// ✅ BON
|
||||
export class DtoInscriptionParentComplet { }
|
||||
export class ServiceAuthentification { }
|
||||
export interface OptionsConfiguration { }
|
||||
export type StatutUtilisateur = 'actif' | 'en_attente' | 'suspendu';
|
||||
|
||||
// ❌ MAUVAIS
|
||||
export class RegisterParentCompleteDto { }
|
||||
export class AuthService { }
|
||||
export interface ConfigOptions { }
|
||||
export type UserStatus = 'active' | 'pending' | 'suspended';
|
||||
```
|
||||
|
||||
### 4. Noms de fichiers
|
||||
```typescript
|
||||
// ✅ BON
|
||||
inscription-parent-complet.dto.ts
|
||||
service-authentification.ts
|
||||
entite-utilisateurs.ts
|
||||
controleur-configuration.ts
|
||||
|
||||
// ❌ MAUVAIS
|
||||
register-parent-complete.dto.ts
|
||||
auth.service.ts
|
||||
users.entity.ts
|
||||
config.controller.ts
|
||||
```
|
||||
|
||||
### 5. Propriétés d'entités/DTOs
|
||||
```typescript
|
||||
// ✅ BON
|
||||
export class Enfants {
|
||||
@Column({ name: 'prenom' })
|
||||
prenom: string;
|
||||
|
||||
@Column({ name: 'date_naissance' })
|
||||
dateNaissance: Date;
|
||||
|
||||
@Column({ name: 'consentement_photo' })
|
||||
consentementPhoto: boolean;
|
||||
}
|
||||
|
||||
// ❌ MAUVAIS
|
||||
export class Children {
|
||||
@Column({ name: 'first_name' })
|
||||
firstName: string;
|
||||
|
||||
@Column({ name: 'birth_date' })
|
||||
birthDate: Date;
|
||||
|
||||
@Column({ name: 'consent_photo' })
|
||||
consentPhoto: boolean;
|
||||
}
|
||||
```
|
||||
|
||||
### 6. Commentaires
|
||||
```typescript
|
||||
// ✅ BON
|
||||
// Créer Parent 1 + Parent 2 (si existe) + entités parents
|
||||
// Vérifier que l'email n'existe pas déjà
|
||||
// Transaction : Créer utilisateur + entité métier
|
||||
|
||||
// ❌ MAUVAIS
|
||||
// Create Parent 1 + Parent 2 (if exists) + parent entities
|
||||
// Check if email already exists
|
||||
// Transaction: Create user + business entity
|
||||
```
|
||||
|
||||
### 7. Messages d'erreur/succès
|
||||
```typescript
|
||||
// ✅ BON
|
||||
throw new ConflictException('Un compte avec cet email existe déjà');
|
||||
return { message: 'Inscription réussie. Votre dossier est en attente de validation.' };
|
||||
|
||||
// ❌ MAUVAIS
|
||||
throw new ConflictException('An account with this email already exists');
|
||||
return { message: 'Registration successful. Your application is pending validation.' };
|
||||
```
|
||||
|
||||
### 8. Logs
|
||||
```typescript
|
||||
// ✅ BON
|
||||
this.logger.log('📦 Chargement de 16 configurations en cache');
|
||||
this.logger.error('Erreur lors de la création du parent');
|
||||
|
||||
// ❌ MAUVAIS
|
||||
this.logger.log('📦 Loading 16 configurations in cache');
|
||||
this.logger.error('Error creating parent');
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## ✅ Ce qui RESTE en ANGLAIS (Termes Techniques)
|
||||
|
||||
### 1. Patterns de conception
|
||||
- `singleton`
|
||||
- `factory`
|
||||
- `repository`
|
||||
- `observer`
|
||||
- `decorator`
|
||||
|
||||
### 2. Architecture/Framework
|
||||
- `backend` / `frontend`
|
||||
- `controller`
|
||||
- `service`
|
||||
- `middleware`
|
||||
- `guard`
|
||||
- `interceptor`
|
||||
- `pipe`
|
||||
- `filter`
|
||||
- `module`
|
||||
- `provider`
|
||||
|
||||
### 3. Concepts techniques
|
||||
- `entity` (TypeORM)
|
||||
- `DTO` (Data Transfer Object)
|
||||
- `API` / `endpoint`
|
||||
- `token` (JWT)
|
||||
- `hash` (bcrypt)
|
||||
- `cache`
|
||||
- `query`
|
||||
- `transaction`
|
||||
- `migration`
|
||||
- `seed`
|
||||
|
||||
### 4. Bibliothèques/Technologies
|
||||
- `NestJS`
|
||||
- `TypeORM`
|
||||
- `PostgreSQL`
|
||||
- `Docker`
|
||||
- `Git`
|
||||
- `JWT`
|
||||
- `bcrypt`
|
||||
- `Multer`
|
||||
- `Nodemailer`
|
||||
|
||||
### 5. Mots-clés TypeScript/JavaScript
|
||||
- `async` / `await`
|
||||
- `const` / `let` / `var`
|
||||
- `function`
|
||||
- `class`
|
||||
- `interface`
|
||||
- `type`
|
||||
- `enum`
|
||||
- `import` / `export`
|
||||
- `return`
|
||||
- `throw`
|
||||
|
||||
---
|
||||
|
||||
## 📋 Exemples Complets
|
||||
|
||||
### Exemple 1 : Service d'authentification
|
||||
|
||||
```typescript
|
||||
// ✅ BON
|
||||
@Injectable()
|
||||
export class ServiceAuthentification {
|
||||
constructor(
|
||||
private readonly serviceUtilisateurs: ServiceUtilisateurs,
|
||||
private readonly serviceJwt: JwtService,
|
||||
@InjectRepository(Utilisateurs)
|
||||
private readonly depotUtilisateurs: Repository<Utilisateurs>,
|
||||
) {}
|
||||
|
||||
async inscrireParentComplet(dto: DtoInscriptionParentComplet) {
|
||||
// Vérifier que l'email n'existe pas
|
||||
const existe = await this.serviceUtilisateurs.trouverParEmail(dto.email);
|
||||
if (existe) {
|
||||
throw new ConflictException('Un compte avec cet email existe déjà');
|
||||
}
|
||||
|
||||
// Générer le token de création de mot de passe
|
||||
const tokenCreationMdp = crypto.randomUUID();
|
||||
const dateExpiration = new Date();
|
||||
dateExpiration.setDate(dateExpiration.getDate() + 7);
|
||||
|
||||
// Transaction : Créer parent + enfants
|
||||
const resultat = await this.depotUtilisateurs.manager.transaction(async (manager) => {
|
||||
const parent1 = new Utilisateurs();
|
||||
parent1.email = dto.email;
|
||||
parent1.prenom = dto.prenom;
|
||||
parent1.nom = dto.nom;
|
||||
parent1.tokenCreationMdp = tokenCreationMdp;
|
||||
|
||||
const parentEnregistre = await manager.save(Utilisateurs, parent1);
|
||||
|
||||
return { parent: parentEnregistre, token: tokenCreationMdp };
|
||||
});
|
||||
|
||||
return {
|
||||
message: 'Inscription réussie. Votre dossier est en attente de validation.',
|
||||
idParent: resultat.parent.id,
|
||||
statut: 'en_attente',
|
||||
};
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Exemple 2 : Entité Enfants
|
||||
|
||||
```typescript
|
||||
// ✅ BON
|
||||
@Entity('enfants')
|
||||
export class Enfants {
|
||||
@PrimaryGeneratedColumn('uuid')
|
||||
id: string;
|
||||
|
||||
@Column({ name: 'prenom', length: 100 })
|
||||
prenom: string;
|
||||
|
||||
@Column({ name: 'nom', length: 100 })
|
||||
nom: string;
|
||||
|
||||
@Column({
|
||||
type: 'enum',
|
||||
enum: TypeGenre,
|
||||
name: 'genre'
|
||||
})
|
||||
genre: TypeGenre;
|
||||
|
||||
@Column({ type: 'date', name: 'date_naissance', nullable: true })
|
||||
dateNaissance?: Date;
|
||||
|
||||
@Column({ type: 'date', name: 'date_prevue_naissance', nullable: true })
|
||||
datePrevueNaissance?: Date;
|
||||
|
||||
@Column({ name: 'photo_url', type: 'text', nullable: true })
|
||||
photoUrl?: string;
|
||||
|
||||
@Column({ name: 'consentement_photo', type: 'boolean', default: false })
|
||||
consentementPhoto: boolean;
|
||||
|
||||
@Column({ name: 'est_multiple', type: 'boolean', default: false })
|
||||
estMultiple: boolean;
|
||||
|
||||
@Column({
|
||||
type: 'enum',
|
||||
enum: StatutEnfantType,
|
||||
name: 'statut'
|
||||
})
|
||||
statut: StatutEnfantType;
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🔄 Migration Progressive
|
||||
|
||||
### Stratégie
|
||||
1. ✅ **Nouveau code** : Appliquer la règle immédiatement
|
||||
2. ⏳ **Code existant** : Migrer progressivement lors des modifications
|
||||
3. ❌ **Ne PAS refactoriser** tout le code d'un coup
|
||||
|
||||
### Priorités de migration
|
||||
1. **Haute priorité** : Nouveaux fichiers, nouvelles fonctionnalités
|
||||
2. **Moyenne priorité** : Fichiers modifiés fréquemment
|
||||
3. **Basse priorité** : Code stable non modifié
|
||||
|
||||
### Exemple de migration progressive
|
||||
```typescript
|
||||
// Avant (ancien code - OK pour l'instant)
|
||||
export class Children { }
|
||||
|
||||
// Après modification (nouveau code - appliquer la règle)
|
||||
export class Enfants { }
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🚫 Exceptions
|
||||
|
||||
### Cas où l'anglais est toléré
|
||||
1. **Noms de colonnes en BDD** : Si la BDD existe déjà (ex: `first_name` en BDD → `prenom` en TypeScript)
|
||||
2. **APIs externes** : Noms imposés par des bibliothèques tierces
|
||||
3. **Standards** : `id`, `uuid`, `url`, `email`, `password` (termes universels)
|
||||
|
||||
---
|
||||
|
||||
## ✅ Checklist Avant Commit
|
||||
|
||||
- [ ] Noms de variables en français
|
||||
- [ ] Noms de fonctions/méthodes en français
|
||||
- [ ] Noms de classes/interfaces en français
|
||||
- [ ] Noms de fichiers en français
|
||||
- [ ] Propriétés d'entités/DTOs en français
|
||||
- [ ] Commentaires en français
|
||||
- [ ] Messages d'erreur/succès en français
|
||||
- [ ] Termes techniques restent en anglais
|
||||
- [ ] Pas de `console.log` (utiliser `this.logger`)
|
||||
- [ ] Pas de code commenté
|
||||
- [ ] Types TypeScript corrects (pas de `any`)
|
||||
- [ ] Imports propres (pas d'imports inutilisés)
|
||||
|
||||
---
|
||||
|
||||
**Dernière mise à jour** : 1er Décembre 2025
|
||||
**Auteur** : Équipe P'titsPas
|
||||
|
||||
Reference in New Issue
Block a user