Documented comprehensive implementation plans for the authentication system and database schema, including architecture, module structure, API integration, security measures, and GDPR compliance details.
761 lines
21 KiB
Markdown
761 lines
21 KiB
Markdown
# Guide d'Implémentation du Backend
|
|
|
|
Ce document présente un guide complet pour l'implémentation du backend de l'application de création de groupes, basé sur les spécifications du cahier des charges et les plans détaillés précédemment établis.
|
|
|
|
## Table des Matières
|
|
|
|
1. [Vue d'Ensemble](#1-vue-densemble)
|
|
2. [Préparation de l'Environnement](#2-préparation-de-lenvironnement)
|
|
3. [Structure du Projet](#3-structure-du-projet)
|
|
4. [Configuration de Base](#4-configuration-de-base)
|
|
5. [Base de Données](#5-base-de-données)
|
|
6. [Authentification](#6-authentification)
|
|
7. [Modules Fonctionnels](#7-modules-fonctionnels)
|
|
8. [Communication en Temps Réel](#8-communication-en-temps-réel)
|
|
9. [Sécurité et Conformité RGPD](#9-sécurité-et-conformité-rgpd)
|
|
10. [Tests et Documentation](#10-tests-et-documentation)
|
|
11. [Déploiement](#11-déploiement)
|
|
12. [Calendrier d'Implémentation](#12-calendrier-dimplémentation)
|
|
|
|
## 1. Vue d'Ensemble
|
|
|
|
L'application est une plateforme de création et de gestion de groupes qui permet aux utilisateurs de créer des groupes en prenant en compte divers paramètres et de conserver un historique des groupes précédemment créés.
|
|
|
|
### 1.1 Architecture Globale
|
|
|
|
L'application suit une architecture monorepo avec séparation claire entre le frontend et le backend :
|
|
|
|
- **Frontend** : Application Next.js avec App Router et Server Components
|
|
- **Backend** : API NestJS avec PostgreSQL et DrizzleORM
|
|
- **Communication** : API REST pour les opérations CRUD et WebSockets pour les mises à jour en temps réel
|
|
- **Authentification** : OAuth 2.0 avec GitHub et JWT pour la gestion des sessions
|
|
|
|
## 2. Préparation de l'Environnement
|
|
|
|
### 2.1 Installation des Dépendances
|
|
|
|
```bash
|
|
# Installation des dépendances principales
|
|
pnpm add @nestjs/config @nestjs/passport passport passport-github2 @nestjs/jwt
|
|
pnpm add @nestjs/websockets @nestjs/platform-socket.io socket.io
|
|
pnpm add drizzle-orm pg
|
|
pnpm add @node-rs/argon2 jose
|
|
pnpm add class-validator class-transformer
|
|
pnpm add zod zod-validation-error
|
|
pnpm add uuid
|
|
|
|
# Installation des dépendances de développement
|
|
pnpm add -D drizzle-kit
|
|
pnpm add -D @types/passport-github2 @types/socket.io @types/pg @types/uuid
|
|
```
|
|
|
|
### 2.2 Configuration de l'Environnement
|
|
|
|
Créer un fichier `.env.example` à la racine du projet backend :
|
|
|
|
```
|
|
# Application
|
|
PORT=3000
|
|
NODE_ENV=development
|
|
API_PREFIX=api
|
|
|
|
# Database
|
|
DATABASE_URL=postgres://postgres:postgres@localhost:5432/groupmaker
|
|
|
|
# Authentication
|
|
GITHUB_CLIENT_ID=your_github_client_id
|
|
GITHUB_CLIENT_SECRET=your_github_client_secret
|
|
GITHUB_CALLBACK_URL=http://localhost:3000/api/auth/github/callback
|
|
|
|
# JWT
|
|
JWT_ACCESS_SECRET=your_access_token_secret
|
|
JWT_REFRESH_SECRET=your_refresh_token_secret
|
|
JWT_ACCESS_EXPIRATION=15m
|
|
JWT_REFRESH_EXPIRATION=7d
|
|
|
|
# CORS
|
|
CORS_ORIGIN=http://localhost:3000
|
|
FRONTEND_URL=http://localhost:3000
|
|
```
|
|
|
|
## 3. Structure du Projet
|
|
|
|
La structure du projet backend suivra l'organisation suivante :
|
|
|
|
```
|
|
backend/
|
|
├── src/
|
|
│ ├── main.ts # Point d'entrée de l'application
|
|
│ ├── app.module.ts # Module principal
|
|
│ ├── config/ # Configuration de l'application
|
|
│ │ ├── app.config.ts # Configuration générale
|
|
│ │ ├── database.config.ts # Configuration de la base de données
|
|
│ │ ├── auth.config.ts # Configuration de l'authentification
|
|
│ │ └── env.validation.ts # Validation des variables d'environnement
|
|
│ ├── common/ # Utilitaires partagés
|
|
│ │ ├── decorators/ # Décorateurs personnalisés
|
|
│ │ ├── filters/ # Filtres d'exception
|
|
│ │ ├── guards/ # Guards d'authentification et d'autorisation
|
|
│ │ ├── interceptors/ # Intercepteurs
|
|
│ │ ├── pipes/ # Pipes de validation
|
|
│ │ └── utils/ # Fonctions utilitaires
|
|
│ ├── modules/ # Modules fonctionnels
|
|
│ │ ├── auth/ # Module d'authentification
|
|
│ │ ├── users/ # Module de gestion des utilisateurs
|
|
│ │ ├── projects/ # Module de gestion des projets
|
|
│ │ ├── persons/ # Module de gestion des personnes
|
|
│ │ ├── groups/ # Module de gestion des groupes
|
|
│ │ ├── tags/ # Module de gestion des tags
|
|
│ │ └── websockets/ # Module de gestion des WebSockets
|
|
│ └── database/ # Configuration de la base de données
|
|
│ ├── migrations/ # Migrations de base de données
|
|
│ ├── schema/ # Schéma de base de données (DrizzleORM)
|
|
│ └── database.module.ts # Module de base de données
|
|
├── test/ # Tests
|
|
│ ├── e2e/ # Tests end-to-end
|
|
│ └── unit/ # Tests unitaires
|
|
└── .env.example # Exemple de fichier d'environnement
|
|
```
|
|
|
|
## 4. Configuration de Base
|
|
|
|
### 4.1 Point d'Entrée de l'Application
|
|
|
|
Mettre à jour le fichier `src/main.ts` :
|
|
|
|
```typescript
|
|
import { NestFactory } from '@nestjs/core';
|
|
import { ValidationPipe } from '@nestjs/common';
|
|
import { ConfigService } from '@nestjs/config';
|
|
import { AppModule } from './app.module';
|
|
|
|
async function bootstrap() {
|
|
const app = await NestFactory.create(AppModule);
|
|
const configService = app.get(ConfigService);
|
|
|
|
// Configuration globale des pipes de validation
|
|
app.useGlobalPipes(
|
|
new ValidationPipe({
|
|
whitelist: true,
|
|
transform: true,
|
|
forbidNonWhitelisted: true,
|
|
}),
|
|
);
|
|
|
|
// Configuration CORS
|
|
app.enableCors({
|
|
origin: configService.get<string>('CORS_ORIGIN'),
|
|
methods: 'GET,HEAD,PUT,PATCH,POST,DELETE',
|
|
credentials: true,
|
|
});
|
|
|
|
// Préfixe global pour les routes API
|
|
app.setGlobalPrefix(configService.get<string>('API_PREFIX', 'api'));
|
|
|
|
const port = configService.get<number>('PORT', 3000);
|
|
await app.listen(port);
|
|
console.log(`Application is running on: http://localhost:${port}`);
|
|
}
|
|
bootstrap();
|
|
```
|
|
|
|
### 4.2 Module Principal
|
|
|
|
Mettre à jour le fichier `src/app.module.ts` :
|
|
|
|
```typescript
|
|
import { Module } from '@nestjs/common';
|
|
import { ConfigModule, ConfigService } from '@nestjs/config';
|
|
import { APP_GUARD } from '@nestjs/core';
|
|
import { AppController } from './app.controller';
|
|
import { AppService } from './app.service';
|
|
import { DatabaseModule } from './database/database.module';
|
|
import { AuthModule } from './modules/auth/auth.module';
|
|
import { UsersModule } from './modules/users/users.module';
|
|
import { ProjectsModule } from './modules/projects/projects.module';
|
|
import { PersonsModule } from './modules/persons/persons.module';
|
|
import { GroupsModule } from './modules/groups/groups.module';
|
|
import { TagsModule } from './modules/tags/tags.module';
|
|
import { WebSocketsModule } from './modules/websockets/websockets.module';
|
|
import { JwtAuthGuard } from './modules/auth/guards/jwt-auth.guard';
|
|
import { validate } from './config/env.validation';
|
|
|
|
@Module({
|
|
imports: [
|
|
ConfigModule.forRoot({
|
|
isGlobal: true,
|
|
validate,
|
|
}),
|
|
DatabaseModule,
|
|
AuthModule,
|
|
UsersModule,
|
|
ProjectsModule,
|
|
PersonsModule,
|
|
GroupsModule,
|
|
TagsModule,
|
|
WebSocketsModule,
|
|
],
|
|
controllers: [AppController],
|
|
providers: [
|
|
AppService,
|
|
{
|
|
provide: APP_GUARD,
|
|
useClass: JwtAuthGuard,
|
|
},
|
|
],
|
|
})
|
|
export class AppModule {}
|
|
```
|
|
|
|
### 4.3 Validation des Variables d'Environnement
|
|
|
|
Créer le fichier `src/config/env.validation.ts` :
|
|
|
|
```typescript
|
|
import { plainToClass } from 'class-transformer';
|
|
import { IsEnum, IsNumber, IsString, validateSync } from 'class-validator';
|
|
|
|
enum Environment {
|
|
Development = 'development',
|
|
Production = 'production',
|
|
Test = 'test',
|
|
}
|
|
|
|
class EnvironmentVariables {
|
|
@IsEnum(Environment)
|
|
NODE_ENV: Environment;
|
|
|
|
@IsNumber()
|
|
PORT: number;
|
|
|
|
@IsString()
|
|
API_PREFIX: string;
|
|
|
|
@IsString()
|
|
DATABASE_URL: string;
|
|
|
|
@IsString()
|
|
GITHUB_CLIENT_ID: string;
|
|
|
|
@IsString()
|
|
GITHUB_CLIENT_SECRET: string;
|
|
|
|
@IsString()
|
|
GITHUB_CALLBACK_URL: string;
|
|
|
|
@IsString()
|
|
JWT_ACCESS_SECRET: string;
|
|
|
|
@IsString()
|
|
JWT_REFRESH_SECRET: string;
|
|
|
|
@IsString()
|
|
JWT_ACCESS_EXPIRATION: string;
|
|
|
|
@IsString()
|
|
JWT_REFRESH_EXPIRATION: string;
|
|
|
|
@IsString()
|
|
CORS_ORIGIN: string;
|
|
|
|
@IsString()
|
|
FRONTEND_URL: string;
|
|
}
|
|
|
|
export function validate(config: Record<string, unknown>) {
|
|
const validatedConfig = plainToClass(
|
|
EnvironmentVariables,
|
|
{
|
|
...config,
|
|
PORT: config.PORT ? parseInt(config.PORT as string, 10) : 3000,
|
|
},
|
|
{ enableImplicitConversion: true },
|
|
);
|
|
|
|
const errors = validateSync(validatedConfig, {
|
|
skipMissingProperties: false,
|
|
});
|
|
|
|
if (errors.length > 0) {
|
|
throw new Error(errors.toString());
|
|
}
|
|
return validatedConfig;
|
|
}
|
|
```
|
|
|
|
## 5. Base de Données
|
|
|
|
### 5.1 Configuration de DrizzleORM
|
|
|
|
Créer le fichier `drizzle.config.ts` à la racine du projet backend :
|
|
|
|
```typescript
|
|
import type { Config } from 'drizzle-kit';
|
|
import * as dotenv from 'dotenv';
|
|
|
|
dotenv.config();
|
|
|
|
export default {
|
|
schema: './src/database/schema/*.ts',
|
|
out: './src/database/migrations',
|
|
driver: 'pg',
|
|
dbCredentials: {
|
|
connectionString: process.env.DATABASE_URL || 'postgres://postgres:postgres@localhost:5432/groupmaker',
|
|
},
|
|
verbose: true,
|
|
strict: true,
|
|
} satisfies Config;
|
|
```
|
|
|
|
### 5.2 Module de Base de Données
|
|
|
|
Créer le fichier `src/database/database.module.ts` :
|
|
|
|
```typescript
|
|
import { Module, Global } from '@nestjs/common';
|
|
import { ConfigModule, ConfigService } from '@nestjs/config';
|
|
import { Pool } from 'pg';
|
|
import { drizzle } from 'drizzle-orm/node-postgres';
|
|
import * as schema from './schema';
|
|
|
|
export const DATABASE_POOL = 'DATABASE_POOL';
|
|
export const DRIZZLE = 'DRIZZLE';
|
|
|
|
@Global()
|
|
@Module({
|
|
imports: [ConfigModule],
|
|
providers: [
|
|
{
|
|
provide: DATABASE_POOL,
|
|
inject: [ConfigService],
|
|
useFactory: async (configService: ConfigService) => {
|
|
const pool = new Pool({
|
|
connectionString: configService.get<string>('DATABASE_URL'),
|
|
});
|
|
|
|
// Test the connection
|
|
const client = await pool.connect();
|
|
try {
|
|
await client.query('SELECT NOW()');
|
|
console.log('Database connection established successfully');
|
|
} finally {
|
|
client.release();
|
|
}
|
|
|
|
return pool;
|
|
},
|
|
},
|
|
{
|
|
provide: DRIZZLE,
|
|
inject: [DATABASE_POOL],
|
|
useFactory: (pool: Pool) => {
|
|
return drizzle(pool, { schema });
|
|
},
|
|
},
|
|
],
|
|
exports: [DATABASE_POOL, DRIZZLE],
|
|
})
|
|
export class DatabaseModule {}
|
|
```
|
|
|
|
### 5.3 Script de Migration
|
|
|
|
Créer le fichier `src/database/migrate.ts` :
|
|
|
|
```typescript
|
|
import { drizzle } from 'drizzle-orm/node-postgres';
|
|
import { migrate } from 'drizzle-orm/node-postgres/migrator';
|
|
import { Pool } from 'pg';
|
|
import * as dotenv from 'dotenv';
|
|
|
|
dotenv.config();
|
|
|
|
const main = async () => {
|
|
const pool = new Pool({
|
|
connectionString: process.env.DATABASE_URL,
|
|
});
|
|
|
|
const db = drizzle(pool);
|
|
|
|
console.log('Running migrations...');
|
|
|
|
await migrate(db, { migrationsFolder: './src/database/migrations' });
|
|
|
|
console.log('Migrations completed successfully');
|
|
|
|
await pool.end();
|
|
};
|
|
|
|
main().catch((err) => {
|
|
console.error('Migration failed');
|
|
console.error(err);
|
|
process.exit(1);
|
|
});
|
|
```
|
|
|
|
### 5.4 Schéma de Base de Données
|
|
|
|
Créer les fichiers de schéma dans le dossier `src/database/schema/` selon le plan détaillé dans le document DATABASE_SCHEMA_PLAN.md.
|
|
|
|
### 5.5 Scripts pour les Migrations
|
|
|
|
Ajouter les scripts suivants au `package.json` du backend :
|
|
|
|
```json
|
|
{
|
|
"scripts": {
|
|
"db:generate": "drizzle-kit generate:pg",
|
|
"db:migrate": "ts-node src/database/migrate.ts",
|
|
"db:studio": "drizzle-kit studio"
|
|
}
|
|
}
|
|
```
|
|
|
|
## 6. Authentification
|
|
|
|
### 6.1 Module d'Authentification
|
|
|
|
Créer le fichier `src/modules/auth/auth.module.ts` selon le plan détaillé dans le document AUTH_IMPLEMENTATION_PLAN.md.
|
|
|
|
### 6.2 Stratégies d'Authentification
|
|
|
|
Implémenter les stratégies d'authentification (GitHub, JWT, JWT Refresh) selon le plan détaillé dans le document AUTH_IMPLEMENTATION_PLAN.md.
|
|
|
|
### 6.3 Service d'Authentification
|
|
|
|
Implémenter le service d'authentification selon le plan détaillé dans le document AUTH_IMPLEMENTATION_PLAN.md.
|
|
|
|
### 6.4 Contrôleur d'Authentification
|
|
|
|
Implémenter le contrôleur d'authentification selon le plan détaillé dans le document AUTH_IMPLEMENTATION_PLAN.md.
|
|
|
|
### 6.5 Guards et Décorateurs
|
|
|
|
Implémenter les guards et décorateurs d'authentification selon le plan détaillé dans le document AUTH_IMPLEMENTATION_PLAN.md.
|
|
|
|
## 7. Modules Fonctionnels
|
|
|
|
### 7.1 Module Utilisateurs
|
|
|
|
#### 7.1.1 Service Utilisateurs
|
|
|
|
```typescript
|
|
// src/modules/users/services/users.service.ts
|
|
import { Injectable, NotFoundException } from '@nestjs/common';
|
|
import { DRIZZLE } from '../../../database/database.module';
|
|
import { Inject } from '@nestjs/common';
|
|
import { eq } from 'drizzle-orm';
|
|
import * as schema from '../../../database/schema';
|
|
import { CreateUserDto } from '../dto/create-user.dto';
|
|
import { UpdateUserDto } from '../dto/update-user.dto';
|
|
|
|
@Injectable()
|
|
export class UsersService {
|
|
constructor(@Inject(DRIZZLE) private readonly db: any) {}
|
|
|
|
async create(createUserDto: CreateUserDto) {
|
|
const [user] = await this.db
|
|
.insert(schema.users)
|
|
.values(createUserDto)
|
|
.returning();
|
|
return user;
|
|
}
|
|
|
|
async findAll() {
|
|
return this.db.select().from(schema.users);
|
|
}
|
|
|
|
async findById(id: string) {
|
|
const [user] = await this.db
|
|
.select()
|
|
.from(schema.users)
|
|
.where(eq(schema.users.id, id));
|
|
|
|
if (!user) {
|
|
throw new NotFoundException(`User with ID ${id} not found`);
|
|
}
|
|
|
|
return user;
|
|
}
|
|
|
|
async findByGithubId(githubId: string) {
|
|
const [user] = await this.db
|
|
.select()
|
|
.from(schema.users)
|
|
.where(eq(schema.users.githubId, githubId));
|
|
|
|
return user;
|
|
}
|
|
|
|
async update(id: string, updateUserDto: UpdateUserDto) {
|
|
const [user] = await this.db
|
|
.update(schema.users)
|
|
.set({
|
|
...updateUserDto,
|
|
updatedAt: new Date(),
|
|
})
|
|
.where(eq(schema.users.id, id))
|
|
.returning();
|
|
|
|
if (!user) {
|
|
throw new NotFoundException(`User with ID ${id} not found`);
|
|
}
|
|
|
|
return user;
|
|
}
|
|
|
|
async remove(id: string) {
|
|
const [user] = await this.db
|
|
.delete(schema.users)
|
|
.where(eq(schema.users.id, id))
|
|
.returning();
|
|
|
|
if (!user) {
|
|
throw new NotFoundException(`User with ID ${id} not found`);
|
|
}
|
|
|
|
return user;
|
|
}
|
|
|
|
async updateGdprConsent(id: string) {
|
|
return this.update(id, { gdprTimestamp: new Date() });
|
|
}
|
|
|
|
async exportUserData(id: string) {
|
|
const user = await this.findById(id);
|
|
const projects = await this.db
|
|
.select()
|
|
.from(schema.projects)
|
|
.where(eq(schema.projects.ownerId, id));
|
|
|
|
return {
|
|
user,
|
|
projects,
|
|
};
|
|
}
|
|
}
|
|
```
|
|
|
|
#### 7.1.2 Contrôleur Utilisateurs
|
|
|
|
```typescript
|
|
// src/modules/users/controllers/users.controller.ts
|
|
import {
|
|
Controller,
|
|
Get,
|
|
Post,
|
|
Body,
|
|
Patch,
|
|
Param,
|
|
Delete,
|
|
UseGuards,
|
|
} from '@nestjs/common';
|
|
import { UsersService } from '../services/users.service';
|
|
import { CreateUserDto } from '../dto/create-user.dto';
|
|
import { UpdateUserDto } from '../dto/update-user.dto';
|
|
import { GetUser } from '../../auth/decorators/get-user.decorator';
|
|
import { JwtAuthGuard } from '../../auth/guards/jwt-auth.guard';
|
|
import { RolesGuard } from '../../auth/guards/roles.guard';
|
|
import { Roles } from '../../auth/decorators/roles.decorator';
|
|
import { Role } from '../../auth/enums/role.enum';
|
|
|
|
@Controller('users')
|
|
export class UsersController {
|
|
constructor(private readonly usersService: UsersService) {}
|
|
|
|
@Post()
|
|
@UseGuards(JwtAuthGuard, RolesGuard)
|
|
@Roles(Role.ADMIN)
|
|
create(@Body() createUserDto: CreateUserDto) {
|
|
return this.usersService.create(createUserDto);
|
|
}
|
|
|
|
@Get()
|
|
@UseGuards(JwtAuthGuard, RolesGuard)
|
|
@Roles(Role.ADMIN)
|
|
findAll() {
|
|
return this.usersService.findAll();
|
|
}
|
|
|
|
@Get('profile')
|
|
@UseGuards(JwtAuthGuard)
|
|
getProfile(@GetUser() user) {
|
|
return user;
|
|
}
|
|
|
|
@Get(':id')
|
|
@UseGuards(JwtAuthGuard, RolesGuard)
|
|
@Roles(Role.ADMIN)
|
|
findOne(@Param('id') id: string) {
|
|
return this.usersService.findById(id);
|
|
}
|
|
|
|
@Patch(':id')
|
|
@UseGuards(JwtAuthGuard, RolesGuard)
|
|
@Roles(Role.ADMIN)
|
|
update(@Param('id') id: string, @Body() updateUserDto: UpdateUserDto) {
|
|
return this.usersService.update(id, updateUserDto);
|
|
}
|
|
|
|
@Delete(':id')
|
|
@UseGuards(JwtAuthGuard, RolesGuard)
|
|
@Roles(Role.ADMIN)
|
|
remove(@Param('id') id: string) {
|
|
return this.usersService.remove(id);
|
|
}
|
|
|
|
@Post('gdpr-consent')
|
|
@UseGuards(JwtAuthGuard)
|
|
updateGdprConsent(@GetUser('id') userId: string) {
|
|
return this.usersService.updateGdprConsent(userId);
|
|
}
|
|
|
|
@Get('export-data')
|
|
@UseGuards(JwtAuthGuard)
|
|
exportUserData(@GetUser('id') userId: string) {
|
|
return this.usersService.exportUserData(userId);
|
|
}
|
|
}
|
|
```
|
|
|
|
### 7.2 Module Projets
|
|
|
|
Implémenter le module de gestion des projets avec les opérations CRUD et les relations avec les utilisateurs, les personnes et les groupes.
|
|
|
|
### 7.3 Module Personnes
|
|
|
|
Implémenter le module de gestion des personnes avec les opérations CRUD et les attributs spécifiés (niveau technique, genre, âge, etc.).
|
|
|
|
### 7.4 Module Groupes
|
|
|
|
Implémenter le module de gestion des groupes avec les opérations CRUD et les algorithmes de création automatique de groupes équilibrés.
|
|
|
|
### 7.5 Module Tags
|
|
|
|
Implémenter le module de gestion des tags avec les opérations CRUD et la gestion des types de tags (PROJECT, PERSON).
|
|
|
|
## 8. Communication en Temps Réel
|
|
|
|
### 8.1 Module WebSockets
|
|
|
|
Implémenter le module WebSockets selon le plan détaillé dans le document WEBSOCKET_IMPLEMENTATION_PLAN.md.
|
|
|
|
### 8.2 Gateways WebSocket
|
|
|
|
Implémenter les gateways WebSocket (Projets, Groupes, Notifications) selon le plan détaillé dans le document WEBSOCKET_IMPLEMENTATION_PLAN.md.
|
|
|
|
### 8.3 Service WebSocket
|
|
|
|
Implémenter le service WebSocket selon le plan détaillé dans le document WEBSOCKET_IMPLEMENTATION_PLAN.md.
|
|
|
|
## 9. Sécurité et Conformité RGPD
|
|
|
|
### 9.1 Sécurité
|
|
|
|
#### 9.1.1 Protection contre les Attaques Courantes
|
|
|
|
- Implémenter la protection CSRF pour les opérations sensibles
|
|
- Configurer les en-têtes de sécurité (Content-Security-Policy, X-XSS-Protection, etc.)
|
|
- Utiliser des paramètres préparés avec DrizzleORM pour prévenir les injections SQL
|
|
- Mettre en place le rate limiting pour prévenir les attaques par force brute
|
|
|
|
#### 9.1.2 Gestion des Tokens
|
|
|
|
- Implémenter la révocation des tokens JWT
|
|
- Configurer la rotation des clés de signature
|
|
- Mettre en place la validation complète des tokens (signature, expiration, émetteur)
|
|
|
|
### 9.2 Conformité RGPD
|
|
|
|
#### 9.2.1 Gestion du Consentement
|
|
|
|
- Implémenter l'enregistrement du timestamp d'acceptation RGPD
|
|
- Mettre en place le renouvellement du consentement tous les 13 mois
|
|
|
|
#### 9.2.2 Droits des Utilisateurs
|
|
|
|
- Implémenter l'export des données personnelles
|
|
- Mettre en place la suppression de compte avec option de conservation ou suppression des projets
|
|
|
|
## 10. Tests et Documentation
|
|
|
|
### 10.1 Tests
|
|
|
|
#### 10.1.1 Tests Unitaires
|
|
|
|
Écrire des tests unitaires pour les services et les contrôleurs en utilisant Jest.
|
|
|
|
#### 10.1.2 Tests E2E
|
|
|
|
Développer des tests end-to-end pour les API en utilisant Supertest.
|
|
|
|
### 10.2 Documentation
|
|
|
|
#### 10.2.1 Documentation API
|
|
|
|
Générer la documentation API avec Swagger en utilisant les décorateurs NestJS.
|
|
|
|
#### 10.2.2 Documentation Technique
|
|
|
|
Documenter l'architecture, les modèles de données et les flux d'interaction.
|
|
|
|
## 11. Déploiement
|
|
|
|
### 11.1 Conteneurisation
|
|
|
|
Créer un Dockerfile pour le backend :
|
|
|
|
```dockerfile
|
|
FROM node:20-alpine AS builder
|
|
|
|
WORKDIR /app
|
|
|
|
COPY package.json pnpm-lock.yaml ./
|
|
RUN npm install -g pnpm && pnpm install
|
|
|
|
COPY . .
|
|
RUN pnpm build
|
|
|
|
FROM node:20-alpine
|
|
|
|
WORKDIR /app
|
|
|
|
COPY --from=builder /app/package.json /app/pnpm-lock.yaml ./
|
|
COPY --from=builder /app/dist ./dist
|
|
COPY --from=builder /app/node_modules ./node_modules
|
|
|
|
EXPOSE 3000
|
|
|
|
CMD ["node", "dist/main"]
|
|
```
|
|
|
|
### 11.2 CI/CD
|
|
|
|
Configurer un workflow CI/CD avec GitHub Actions pour l'intégration et le déploiement continus.
|
|
|
|
## 12. Calendrier d'Implémentation
|
|
|
|
1. **Semaine 1: Configuration et Base de Données**
|
|
- Configuration de l'environnement
|
|
- Mise en place de la base de données avec DrizzleORM
|
|
- Définition du schéma et création des migrations
|
|
|
|
2. **Semaine 2: Authentification et Utilisateurs**
|
|
- Implémentation de l'authentification GitHub OAuth
|
|
- Développement du module utilisateurs
|
|
- Mise en place de la gestion des JWT
|
|
|
|
3. **Semaine 3: Modules Principaux**
|
|
- Développement des modules projets, personnes et groupes
|
|
- Implémentation des opérations CRUD
|
|
- Mise en place des relations entre entités
|
|
|
|
4. **Semaine 4: Fonctionnalités Avancées**
|
|
- Implémentation des WebSockets pour la communication en temps réel
|
|
- Développement des algorithmes de création de groupes
|
|
- Mise en place des fonctionnalités de sécurité et de conformité RGPD
|
|
|
|
5. **Semaine 5: Tests et Finalisation**
|
|
- Écriture des tests unitaires et e2e
|
|
- Documentation de l'API
|
|
- Optimisation des performances et correction des bugs |