瀏覽代碼

(fix) mapper les domaines les dto et l'entité prisma

Brin AMONKONAN 1 年之前
父節點
當前提交
07407dcb9d
共有 31 個文件被更改,包括 330 次插入 和 188 次删除
  1. 7 3
      .env
  2. 33 1
      docker-compose.yml
  3. 42 21
      node_app/src/application/dto/create-company.dto.ts
  4. 27 21
      node_app/src/application/dto/create-driver.dto.ts
  5. 21 5
      node_app/src/application/dto/create-reservation.dto.ts
  6. 27 7
      node_app/src/application/dto/create-trajet.dto.ts
  7. 35 7
      node_app/src/application/dto/create-vehicule.dto.ts
  8. 6 4
      node_app/src/application/dto/responses/user-response.dto.ts
  9. 5 1
      node_app/src/application/use-cases/company/create-company.use-case.ts
  10. 4 1
      node_app/src/application/use-cases/driver/create-driver.use-case.ts
  11. 5 1
      node_app/src/application/use-cases/reservation/create-reservation.use-case.ts
  12. 5 1
      node_app/src/application/use-cases/reservation/update-reservation.use-case.ts
  13. 4 1
      node_app/src/application/use-cases/trajet/create-trajet.use-case.ts
  14. 4 1
      node_app/src/application/use-cases/trajet/update-trajet.use-case.ts
  15. 0 31
      node_app/src/domain/entities/driver.entity.ts
  16. 0 12
      node_app/src/domain/entities/place.entity.ts
  17. 0 22
      node_app/src/domain/entities/vehicule.entity.ts
  18. 11 8
      node_app/src/infrastructure/database/repositories/company.repository.ts
  19. 4 3
      node_app/src/infrastructure/database/repositories/driver.repository.ts
  20. 9 11
      node_app/src/infrastructure/database/repositories/reservation.repository.ts
  21. 9 11
      node_app/src/infrastructure/database/repositories/trajet.repository.ts
  22. 4 1
      node_app/src/infrastructure/mappers/company.mapper.ts
  23. 16 1
      node_app/src/infrastructure/mappers/driver.mapper.ts
  24. 12 0
      node_app/src/infrastructure/mappers/place.mapper.ts
  25. 2 0
      node_app/src/infrastructure/mappers/prisma-mapper.interface.ts
  26. 7 3
      node_app/src/infrastructure/mappers/reservation.mapper.ts
  27. 4 0
      node_app/src/infrastructure/mappers/trajet.mapper.ts
  28. 4 0
      node_app/src/infrastructure/mappers/user.mapper.ts
  29. 17 0
      node_app/src/infrastructure/mappers/vehicule.mapper.ts
  30. 5 10
      node_app/src/main.ts
  31. 1 0
      node_app/src/presentation/interceptors/transform.interceptor.ts

+ 7 - 3
.env

@@ -1,3 +1,7 @@
-FIREBASE_PROJECT_ID="monhopital"
-FIREBASE_CLIENT_EMAIL="firebase-adminsdk-8gixa@monhopital.iam.gserviceaccount.com"
-FIREBASE_PRIVATE_KEY="-----BEGIN PRIVATE KEY-----\nMIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQCTmdIetvaCr9b+\n8yfmeFeL8iCaHeSVMlDicms171htwB6RtTi+66hLbEUQoPAlA7MXVDatFpwDS/pw\n/KAdZFxTKjDIO4/CmWxZn+eJZ/fD41EghWDyjVyXb+DwLmKVGAJLtW0iGxU2yyB5\nXbc5aLCxFFBcXv2nASS0RbYuL9Nk4wjTMq4MZZZ4n3oJ/Ru2Sp4ftg0NRe8lMiuy\nL+Xzzqivqha5b/AJh5JBQXTmilatORk2ZRzKtRqehtObEjWbkilEx5FS1rpSlgHS\nQKijWXzAs+IxufieOX/1Usa3KxlSbA2UqdxfYQnn2NfKg0GzXqruzOkJju5HsIAI\nDY+BSnXJAgMBAAECggEAQtw/8Ufh/KsYkd6lqWHEDpG8sPNvkyH6v8kixYjJHtYT\nQt+7d8iaMKg31OOCRNIbMysjpV6Dh37IUJwvD4FhzQ5kkJ9ibL1A9oxXvseI1YRI\nQJoKo3Tjh3nXhBUO9QiuKYtihzuLbYmwCSopkGja+SwBhwZEkn0TGlIlx2BEuwLo\nffz0nl8GL9jhY2v2JUm1zmhMIFRqXuAM/cWSYmtsgtQBlXwK9I2Drzt111ClryrP\nELC8cz7ZSibSZQi3sECAqKfenT6Pymicb6qMsUEGze4IkJyhAC55iF2eVJPc0d+J\nCQKzqrKyHf58aJ2VwOAR5bUzE1CxeqAIwCjfm08QHQKBgQC1pJrEGwSumzZvWC6r\n9VfQLqigfq1NfEJ+dm0Z4v1qK4hNKk1kR9j3MiBtgAE5N6yqK8T5oN4gZnWa3VFf\nO8F9GI/T0QQ9L334rTfQL79WtTpJVhtH3zmws1503kjMCP4IGv7xWXQliAdJaMBP\nHGbZZ1K3m4r8vgygkHcn7F4A2wKBgQDQBb/lFcw+aNKbMVDvzIoXQ7kgbNKbyPE6\n49U3FLmxzrpLp5gGqMy9+h8UVCwhR+jodkEzw3Gu+NlP4y1spyDRfAEtpMDy3w10\nzeEC6ha4aJUKcnUABZF6Fi5iDqyrjx7IW3H7LgVFkfmiQfnf99FgtC3/28rDn9ui\n9uEcPQVDKwKBgQCPG0U3tZWlvvFPHel/Xwc1JF2EPOlqv7hfjAv+tiAzcmKrcOWS\nWSyt7JcxzgSowJ1PYLaKeVwnqLGFNlKythCF70D5f5ZYYj9cGZR8d/HGbXejaayK\nnmsENPz5FFvELF1/o00yduiT3SzogBfq/BRnugioUWpaH50xL0BBeu7AuwKBgQCO\nVYDJlLKdeUexXHsOuRs7c+E1qIAqi8FTFBUNjSbJ3LNnlJLW66S70Gp3lGhllTht\n5owSiQY+PJMksEKid3BjJcAApRxIkgo5A62UOuu03gosjcg0bZruuEKgYX4QHOtp\nF/jTbte4lHsEZLQ+ZOhkjKR0zsTcOYMk7Ft24OG65QKBgQCb0Jw4ZXfy6L00Hhui\nIR1VZDL7tvX2OArhcuJLn+btGHKD/ZythWZYsyWdktXWWWO5Q28T05wQlb41QINf\nwZQ0xhUS1ESkCtcTS+GFSXbWNj2GsRiB4J84FmTLj/RX5uZbJGpZAnMcLpmzGHFw\nhxJoNoNm0XlG4hrjZzIsk0fFSg==\n-----END PRIVATE KEY-----\n"
+FIREBASE_PROJECT_ID="monhopital"
+FIREBASE_CLIENT_EMAIL="firebase-adminsdk-8gixa@monhopital.iam.gserviceaccount.com"
+FIREBASE_PRIVATE_KEY="-----BEGIN PRIVATE KEY-----\nMIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQCTmdIetvaCr9b+\n8yfmeFeL8iCaHeSVMlDicms171htwB6RtTi+66hLbEUQoPAlA7MXVDatFpwDS/pw\n/KAdZFxTKjDIO4/CmWxZn+eJZ/fD41EghWDyjVyXb+DwLmKVGAJLtW0iGxU2yyB5\nXbc5aLCxFFBcXv2nASS0RbYuL9Nk4wjTMq4MZZZ4n3oJ/Ru2Sp4ftg0NRe8lMiuy\nL+Xzzqivqha5b/AJh5JBQXTmilatORk2ZRzKtRqehtObEjWbkilEx5FS1rpSlgHS\nQKijWXzAs+IxufieOX/1Usa3KxlSbA2UqdxfYQnn2NfKg0GzXqruzOkJju5HsIAI\nDY+BSnXJAgMBAAECggEAQtw/8Ufh/KsYkd6lqWHEDpG8sPNvkyH6v8kixYjJHtYT\nQt+7d8iaMKg31OOCRNIbMysjpV6Dh37IUJwvD4FhzQ5kkJ9ibL1A9oxXvseI1YRI\nQJoKo3Tjh3nXhBUO9QiuKYtihzuLbYmwCSopkGja+SwBhwZEkn0TGlIlx2BEuwLo\nffz0nl8GL9jhY2v2JUm1zmhMIFRqXuAM/cWSYmtsgtQBlXwK9I2Drzt111ClryrP\nELC8cz7ZSibSZQi3sECAqKfenT6Pymicb6qMsUEGze4IkJyhAC55iF2eVJPc0d+J\nCQKzqrKyHf58aJ2VwOAR5bUzE1CxeqAIwCjfm08QHQKBgQC1pJrEGwSumzZvWC6r\n9VfQLqigfq1NfEJ+dm0Z4v1qK4hNKk1kR9j3MiBtgAE5N6yqK8T5oN4gZnWa3VFf\nO8F9GI/T0QQ9L334rTfQL79WtTpJVhtH3zmws1503kjMCP4IGv7xWXQliAdJaMBP\nHGbZZ1K3m4r8vgygkHcn7F4A2wKBgQDQBb/lFcw+aNKbMVDvzIoXQ7kgbNKbyPE6\n49U3FLmxzrpLp5gGqMy9+h8UVCwhR+jodkEzw3Gu+NlP4y1spyDRfAEtpMDy3w10\nzeEC6ha4aJUKcnUABZF6Fi5iDqyrjx7IW3H7LgVFkfmiQfnf99FgtC3/28rDn9ui\n9uEcPQVDKwKBgQCPG0U3tZWlvvFPHel/Xwc1JF2EPOlqv7hfjAv+tiAzcmKrcOWS\nWSyt7JcxzgSowJ1PYLaKeVwnqLGFNlKythCF70D5f5ZYYj9cGZR8d/HGbXejaayK\nnmsENPz5FFvELF1/o00yduiT3SzogBfq/BRnugioUWpaH50xL0BBeu7AuwKBgQCO\nVYDJlLKdeUexXHsOuRs7c+E1qIAqi8FTFBUNjSbJ3LNnlJLW66S70Gp3lGhllTht\n5owSiQY+PJMksEKid3BjJcAApRxIkgo5A62UOuu03gosjcg0bZruuEKgYX4QHOtp\nF/jTbte4lHsEZLQ+ZOhkjKR0zsTcOYMk7Ft24OG65QKBgQCb0Jw4ZXfy6L00Hhui\nIR1VZDL7tvX2OArhcuJLn+btGHKD/ZythWZYsyWdktXWWWO5Q28T05wQlb41QINf\nwZQ0xhUS1ESkCtcTS+GFSXbWNj2GsRiB4J84FmTLj/RX5uZbJGpZAnMcLpmzGHFw\nhxJoNoNm0XlG4hrjZzIsk0fFSg==\n-----END PRIVATE KEY-----\n"
+
+SUBDOMAIN="brin.amonkonan"
+DOMAIN_NAME="n8n.com"
+GENERIC_TIMEZONE="Paris"

+ 33 - 1
docker-compose.yml

@@ -45,6 +45,37 @@ services:
     networks:
       - gogs-network
 
+  n8n:
+    image: docker.n8n.io/n8nio/n8n
+    restart: always
+    ports:
+      - "127.0.0.1:5678:5678"
+    # labels:
+    #   - traefik.enable=true
+    #   - traefik.http.routers.n8n.rule=Host(`${SUBDOMAIN}.${DOMAIN_NAME}`)
+    #   - traefik.http.routers.n8n.tls=true
+    #   - traefik.http.routers.n8n.entrypoints=web,websecure
+    #   - traefik.http.routers.n8n.tls.certresolver=mytlschallenge
+    #   - traefik.http.middlewares.n8n.headers.SSLRedirect=true
+    #   - traefik.http.middlewares.n8n.headers.STSSeconds=315360000
+    #   - traefik.http.middlewares.n8n.headers.browserXSSFilter=true
+    #   - traefik.http.middlewares.n8n.headers.contentTypeNosniff=true
+    #   - traefik.http.middlewares.n8n.headers.forceSTSHeader=true
+    #   - traefik.http.middlewares.n8n.headers.SSLHost=${DOMAIN_NAME}
+    #   - traefik.http.middlewares.n8n.headers.STSIncludeSubdomains=true
+    #   - traefik.http.middlewares.n8n.headers.STSPreload=true
+    #   - traefik.http.routers.n8n.middlewares=n8n@docker
+    environment:
+      - N8N_HOST=${SUBDOMAIN}.${DOMAIN_NAME}
+      - N8N_PORT=5678
+      - N8N_PROTOCOL=https
+      - NODE_ENV=production
+      - WEBHOOK_URL=https://${SUBDOMAIN}.${DOMAIN_NAME}/
+      - GENERIC_TIMEZONE=${GENERIC_TIMEZONE}
+    volumes:
+      - n8n_data:/home/node/.n8n
+      - ./local-files:/files
+
   # traefik:
   #   image: traefik:v2.10
   #   container_name: traefik
@@ -134,7 +165,7 @@ services:
     build:
       context: ./node_app  # Le dossier contenant le Dockerfile
       dockerfile: Dockerfile
-    restart: always
+    #restart: always
     container_name: node_app
     working_dir: /usr/src/app
     depends_on:
@@ -313,3 +344,4 @@ volumes:
   sonarqube_data:
   sonarqube_extensions:
   sonarqube_logs:
+  n8n_data:

+ 42 - 21
node_app/src/application/dto/create-company.dto.ts

@@ -1,36 +1,57 @@
-import { IsString, IsNotEmpty, IsNumber } from 'class-validator';
+import {
+  IsString,
+  IsNotEmpty,
+  IsNumber,
+  IsArray,
+  IsOptional,
+} from 'class-validator';
 import { ApiProperty } from '@nestjs/swagger';
-import { Driver, User } from '@prisma/client';
-import { Vehicule } from 'src/domain/entities/vehicule.entity';
-import { Company } from 'src/domain/entities/company.entity';
 
-interface ICreateCompanyDto {
-  name: string;
-  address: string;
-  manager: object;
-  vehicules?: Vehicule[];
-  drives: Driver[];
-}
-
-export class CreateCompanyDto extends Company implements ICreateCompanyDto {
-  id: number;
-
-  @ApiProperty()
+export class CreateCompanyDto {
+  @ApiProperty({
+    description: "Nom de l'entreprise",
+    example: 'Transport Express',
+    required: true,
+  })
   @IsString()
   @IsNotEmpty()
   name: string;
 
-  @ApiProperty()
+  @ApiProperty({
+    description: "Adresse de l'entreprise",
+    example: '123 Avenue de la République, 75011 Paris',
+    required: true,
+  })
   @IsString()
   @IsNotEmpty()
   address: string;
 
-  @ApiProperty()
+  @ApiProperty({
+    description: "ID du gestionnaire de l'entreprise",
+    example: 1,
+    required: true,
+  })
   @IsNumber()
   @IsNotEmpty()
-  manager: User;
+  managerId: number;
 
-  vehicules: Vehicule[];
+  @ApiProperty({
+    description: "Liste des véhicules associés à l'entreprise",
+    type: [Number],
+    required: false,
+    example: [1, 2, 3],
+  })
+  @IsArray()
+  @IsOptional()
+  vehiculeIds?: number[];
 
-  drives: Driver[];
+  @ApiProperty({
+    description: "Liste des chauffeurs associés à l'entreprise",
+    type: [Number],
+    required: false,
+    example: [1, 2, 3],
+  })
+  @IsArray()
+  @IsOptional()
+  driverIds?: number[];
 }

+ 27 - 21
node_app/src/application/dto/create-driver.dto.ts

@@ -1,43 +1,49 @@
 import { IsString, IsNotEmpty, IsNumber, IsOptional } from 'class-validator';
-import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger';
-import { Driver } from 'src/domain/entities/driver.entity';
-import { Vehicule } from 'src/domain/entities/vehicule.entity';
+import { ApiProperty } from '@nestjs/swagger';
 
-interface ICreateCompanyDto {
-  id: number;
-  address?: string;
-  telephone: string;
-  companyId?: number;
-  userId: number;
-  vehicules?: Vehicule[];
-}
-
-export class CreateDriverDto extends Driver implements ICreateCompanyDto {
-  @ApiProperty()
+export class CreateDriverDto {
+  @ApiProperty({
+    description: 'Nom du chauffeur',
+    example: 'Jean Dupont',
+    required: true,
+  })
   @IsString()
   @IsNotEmpty()
   name: string;
 
-  @ApiProperty()
+  @ApiProperty({
+    description: 'Adresse du chauffeur',
+    example: '45 Rue du Commerce, 75015 Paris',
+    required: true,
+  })
   @IsString()
   @IsNotEmpty()
   address: string;
 
-  @ApiProperty()
+  @ApiProperty({
+    description: 'Numéro de téléphone du chauffeur',
+    example: '+33612345678',
+    required: true,
+  })
   @IsString()
   @IsNotEmpty()
   telephone: string;
 
-  @ApiPropertyOptional()
+  @ApiProperty({
+    description: "ID de l'entreprise employeur",
+    example: 1,
+    required: false,
+  })
   @IsNumber()
   @IsOptional()
   companyId?: number;
 
-  @ApiProperty()
+  @ApiProperty({
+    description: "ID de l'utilisateur associé",
+    example: 1,
+    required: true,
+  })
   @IsNumber()
   @IsNotEmpty()
   userId: number;
-
-  @ApiProperty()
-  vehicules: Vehicule[];
 }

+ 21 - 5
node_app/src/application/dto/create-reservation.dto.ts

@@ -2,22 +2,38 @@ import { IsNotEmpty, IsNumber, IsDateString } from 'class-validator';
 import { ApiProperty } from '@nestjs/swagger';
 
 export class CreateReservationDto {
-  @ApiProperty()
+  @ApiProperty({
+    description: 'Date de la réservation',
+    example: '2023-06-15T08:30:00Z',
+    required: true,
+  })
   @IsDateString()
   @IsNotEmpty()
-  dateAt: Date;
+  dateAt: string;
 
-  @ApiProperty()
+  @ApiProperty({
+    description: 'ID de la place réservée',
+    example: 1,
+    required: true,
+  })
   @IsNumber()
   @IsNotEmpty()
   placeId: number;
 
-  @ApiProperty()
+  @ApiProperty({
+    description: "ID de l'utilisateur qui réserve",
+    example: 1,
+    required: true,
+  })
   @IsNumber()
   @IsNotEmpty()
   userId: number;
 
-  @ApiProperty()
+  @ApiProperty({
+    description: 'ID du trajet concerné',
+    example: 1,
+    required: true,
+  })
   @IsNumber()
   @IsNotEmpty()
   trajetId: number;

+ 27 - 7
node_app/src/application/dto/create-trajet.dto.ts

@@ -2,27 +2,47 @@ import { IsString, IsNotEmpty, IsNumber, IsDateString } from 'class-validator';
 import { ApiProperty } from '@nestjs/swagger';
 
 export class CreateTrajetDto {
-  @ApiProperty()
+  @ApiProperty({
+    description: 'Date et heure de départ',
+    example: '2023-06-15T10:00:00Z',
+    required: true,
+  })
   @IsDateString()
   @IsNotEmpty()
-  departAt: Date;
+  departAt: string;
 
-  @ApiProperty()
+  @ApiProperty({
+    description: "Date et heure d'arrivée",
+    example: '2023-06-15T12:00:00Z',
+    required: true,
+  })
   @IsDateString()
   @IsNotEmpty()
-  arriveAt: Date;
+  arriveAt: string;
 
-  @ApiProperty()
+  @ApiProperty({
+    description: 'Lieu de départ',
+    example: 'Paris',
+    required: true,
+  })
   @IsString()
   @IsNotEmpty()
   depart: string;
 
-  @ApiProperty()
+  @ApiProperty({
+    description: "Lieu d'arrivée",
+    example: 'Lyon',
+    required: true,
+  })
   @IsString()
   @IsNotEmpty()
   arrive: string;
 
-  @ApiProperty()
+  @ApiProperty({
+    description: 'ID du véhicule utilisé',
+    example: 1,
+    required: true,
+  })
   @IsNumber()
   @IsNotEmpty()
   vehiculeId: number;

+ 35 - 7
node_app/src/application/dto/create-vehicule.dto.ts

@@ -2,37 +2,65 @@ import { IsString, IsNotEmpty, IsNumber } from 'class-validator';
 import { ApiProperty } from '@nestjs/swagger';
 
 export class CreateVehiculeDto {
-  @ApiProperty()
+  @ApiProperty({
+    description: 'Nombre de places dans le véhicule',
+    example: 5,
+    required: true,
+  })
   @IsNumber()
   @IsNotEmpty()
   number_places: number;
 
-  @ApiProperty()
+  @ApiProperty({
+    description: 'Couleur du véhicule',
+    example: 'Bleu',
+    required: true,
+  })
   @IsString()
   @IsNotEmpty()
   color: string;
 
-  @ApiProperty()
+  @ApiProperty({
+    description: 'Type de véhicule',
+    example: 'Berline',
+    required: true,
+  })
   @IsString()
   @IsNotEmpty()
   type: string;
 
-  @ApiProperty()
+  @ApiProperty({
+    description: 'Immatriculation du véhicule',
+    example: 'AB-123-CD',
+    required: true,
+  })
   @IsString()
   @IsNotEmpty()
   immatriculation: string;
 
-  @ApiProperty()
+  @ApiProperty({
+    description: 'Modèle du véhicule',
+    example: 'Peugeot 308',
+    required: true,
+  })
   @IsString()
   @IsNotEmpty()
   model: string;
 
-  @ApiProperty()
+  @ApiProperty({
+    description: "ID de l'entreprise propriétaire",
+    example: 1,
+    required: true,
+  })
   @IsNumber()
   @IsNotEmpty()
   companyId: number;
 
-  @ApiProperty()
+  @ApiProperty({
+    description: 'ID du chauffeur assigné',
+    example: 1,
+    required: false,
+  })
   @IsNumber()
   @IsNotEmpty()
   driverId: number;

+ 6 - 4
node_app/src/application/dto/responses/user-response.dto.ts

@@ -1,4 +1,8 @@
+import { ApiProperty } from '@nestjs/swagger';
+import { User } from 'src/domain/entities/user.entity';
+
 export class UserResponseDto {
+  @ApiProperty({ example: 1 })
   id: number;
   email: string;
   name: string;
@@ -12,10 +16,8 @@ export class UserResponseDto {
     Object.assign(this, partial);
   }
 
-  static fromEntity(user: any): UserResponseDto {
-    // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unused-vars
-    const { password, ...userData } = user;
-    // eslint-disable-next-line @typescript-eslint/no-unsafe-argument
+  static fromEntity(user: User): UserResponseDto {
+    const userData = user;
     return new UserResponseDto(userData);
   }
 }

+ 5 - 1
node_app/src/application/use-cases/company/create-company.use-case.ts

@@ -1,15 +1,19 @@
 import { Injectable, Inject } from '@nestjs/common';
 import { CompanyRepository } from '../../../infrastructure/database/repositories/company.repository';
 import { CreateCompanyDto } from '../../dto/create-company.dto';
+import { CompanyMapper } from 'src/infrastructure/mappers/company.mapper';
 
 @Injectable()
 export class CreateCompanyUseCase {
   constructor(
     @Inject('CompanyRepository')
     private readonly companyRepository: CompanyRepository,
+    private readonly companyMapper: CompanyMapper,
   ) {}
 
   async execute(createCompanyDto: CreateCompanyDto) {
-    return this.companyRepository.create(createCompanyDto);
+    // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
+    const createCompany = this.companyMapper.fromDtoToDomain(createCompanyDto);
+    return this.companyRepository.create(createCompany);
   }
 }

+ 4 - 1
node_app/src/application/use-cases/driver/create-driver.use-case.ts

@@ -1,15 +1,18 @@
 import { Injectable, Inject } from '@nestjs/common';
 import { DriverRepository } from '../../../infrastructure/database/repositories/driver.repository';
 import { CreateDriverDto } from '../../dto/create-driver.dto';
+import { DriverMapper } from 'src/infrastructure/mappers/driver.mapper';
 
 @Injectable()
 export class CreateDriverUseCase {
   constructor(
     @Inject('DriverRepository')
     private readonly driverRepository: DriverRepository,
+    private readonly driverMapper: DriverMapper,
   ) {}
 
   async execute(createDriverDto: CreateDriverDto) {
-    return this.driverRepository.create(createDriverDto);
+    const createDriver = this.driverMapper.fromDtoToDomain(createDriverDto);
+    return this.driverRepository.create(createDriver);
   }
 }

+ 5 - 1
node_app/src/application/use-cases/reservation/create-reservation.use-case.ts

@@ -1,15 +1,19 @@
 import { Injectable, Inject } from '@nestjs/common';
 import { ReservationRepository } from '../../../infrastructure/database/repositories/reservation.repository';
 import { CreateReservationDto } from '../../dto/create-reservation.dto';
+import { ReservationMapper } from 'src/infrastructure/mappers/reservation.mapper';
 
 @Injectable()
 export class CreateReservationUseCase {
   constructor(
     @Inject('ReservationRepository')
     private readonly reservationRepository: ReservationRepository,
+    private readonly reservationMapper: ReservationMapper,
   ) {}
 
   async execute(createReservationDto: CreateReservationDto) {
-    return this.reservationRepository.create(createReservationDto);
+    const createReservation =
+      this.reservationMapper.fromDtoToDomain(createReservationDto);
+    return this.reservationRepository.create(createReservation);
   }
 }

+ 5 - 1
node_app/src/application/use-cases/reservation/update-reservation.use-case.ts

@@ -2,12 +2,14 @@ import { Injectable, Inject } from '@nestjs/common';
 import { ReservationRepository } from '../../../infrastructure/database/repositories/reservation.repository';
 import { UpdateReservationDto } from '../../dto/update-reservation.dto';
 import { ReservationNotFoundException } from '../../exceptions/reservation-not-found.exception';
+import { ReservationMapper } from 'src/infrastructure/mappers/reservation.mapper';
 
 @Injectable()
 export class UpdateReservationUseCase {
   constructor(
     @Inject('ReservationRepository')
     private readonly reservationRepository: ReservationRepository,
+    private readonly reservationMapper: ReservationMapper, // TODO: add reservation mapper he
   ) {}
 
   async execute(id: number, updateReservationDto: UpdateReservationDto) {
@@ -15,6 +17,8 @@ export class UpdateReservationUseCase {
     if (!reservation) {
       throw new ReservationNotFoundException(id);
     }
-    return this.reservationRepository.update(id, updateReservationDto);
+    const updateReservation =
+      this.reservationMapper.fromDtoToDomain(updateReservationDto);
+    return this.reservationRepository.update(id, updateReservation);
   }
 }

+ 4 - 1
node_app/src/application/use-cases/trajet/create-trajet.use-case.ts

@@ -1,15 +1,18 @@
 import { Injectable, Inject } from '@nestjs/common';
 import { TrajetRepository } from '../../../infrastructure/database/repositories/trajet.repository';
 import { CreateTrajetDto } from '../../dto/create-trajet.dto';
+import { TrajetMapper } from 'src/infrastructure/mappers/trajet.mapper';
 
 @Injectable()
 export class CreateTrajetUseCase {
   constructor(
     @Inject('TrajetRepository')
     private readonly trajetRepository: TrajetRepository,
+    private readonly trajetMapper: TrajetMapper,
   ) {}
 
   async execute(createTrajetDto: CreateTrajetDto) {
-    return this.trajetRepository.create(createTrajetDto);
+    const createTrajet = this.trajetMapper.fromDtoToDomain(createTrajetDto);
+    return this.trajetRepository.create(createTrajet);
   }
 }

+ 4 - 1
node_app/src/application/use-cases/trajet/update-trajet.use-case.ts

@@ -2,12 +2,14 @@ import { Injectable, Inject } from '@nestjs/common';
 import { TrajetRepository } from '../../../infrastructure/database/repositories/trajet.repository';
 import { UpdateTrajetDto } from '../../dto/update-trajet.dto';
 import { TrajetNotFoundException } from '../../exceptions/trajet-not-found.exception';
+import { TrajetMapper } from 'src/infrastructure/mappers/trajet.mapper';
 
 @Injectable()
 export class UpdateTrajetUseCase {
   constructor(
     @Inject('TrajetRepository')
     private readonly trajetRepository: TrajetRepository,
+    private readonly trajetMapper: TrajetMapper,
   ) {}
 
   async execute(id: number, updateTrajetDto: UpdateTrajetDto) {
@@ -15,6 +17,7 @@ export class UpdateTrajetUseCase {
     if (!trajet) {
       throw new TrajetNotFoundException(id);
     }
-    return this.trajetRepository.update(id, updateTrajetDto);
+    const createdTrajet = this.trajetMapper.fromDtoToDomain(updateTrajetDto);
+    return this.trajetRepository.update(id, createdTrajet);
   }
 }

+ 0 - 31
node_app/src/domain/entities/driver.entity.ts

@@ -1,47 +1,16 @@
-import { ApiProperty } from '@nestjs/swagger';
 import { Company } from './company.entity';
 import { Vehicule } from './vehicule.entity';
 import { User } from './user.entity';
 
 export class Driver {
-  @ApiProperty({ description: 'Unique identifier of the driver' })
   readonly id: number;
-
-  @ApiProperty({ description: 'Name of the driver' })
   name: string;
-
-  @ApiProperty({ description: 'Address of the driver' })
   address: string;
-
-  @ApiProperty({ description: 'Phone number of the driver' })
   telephone: string;
-
-  @ApiProperty({
-    description: 'Company the driver works for',
-    type: () => Company,
-    required: false,
-  })
   company?: Company;
-
-  @ApiProperty({
-    description: 'User account associated with the driver',
-    type: () => User,
-  })
   user: User;
-
-  @ApiProperty({
-    description: 'List of Vehicules assigned to the driver',
-    type: [Vehicule],
-  })
   vehicules: Vehicule[];
-
-  @ApiProperty({
-    description: 'ID of the company the driver works for',
-    required: false,
-  })
   companyId?: number | null;
-
-  @ApiProperty({ description: 'ID of the associated user account' })
   userId: number;
 
   constructor(partial: Partial<Driver>) {

+ 0 - 12
node_app/src/domain/entities/place.entity.ts

@@ -1,27 +1,15 @@
-import { ApiProperty } from '@nestjs/swagger';
 import { Vehicule } from './vehicule.entity';
 import { Reservation } from './reservation.entity';
 
 export class Place {
-  @ApiProperty({ description: 'Unique identifier of the seat' })
   readonly id: number;
 
-  @ApiProperty({ description: 'Seat number in the Vehicule' })
   number: number;
 
-  @ApiProperty({
-    description: 'Vehicule this seat belongs to',
-    type: () => Vehicule,
-  })
   vehicule: Vehicule;
 
-  @ApiProperty({
-    description: 'List of reservations for this seat',
-    type: [Reservation],
-  })
   reservations: Reservation[];
 
-  @ApiProperty({ description: 'ID of the Vehicule this seat belongs to' })
   vehiculeId: number;
 
   constructor(partial: Partial<Place>) {

+ 0 - 22
node_app/src/domain/entities/vehicule.entity.ts

@@ -1,53 +1,31 @@
-import { ApiProperty } from '@nestjs/swagger';
 import { Company } from './company.entity';
 import { Driver } from './driver.entity';
 import { Place } from './place.entity';
 import { Trajet } from './trajet.entity';
 
 export class Vehicule {
-  @ApiProperty({ description: 'Unique identifier of the vehicule' })
   id: number;
 
-  @ApiProperty({ description: 'Number of seats in the vehicule' })
   number_places: number;
 
-  @ApiProperty({ description: 'Color of the vehicule' })
   color: string;
 
-  @ApiProperty({ description: 'Type of the vehicule' })
   type: string;
 
-  @ApiProperty({ description: 'Registration number of the vehicule' })
   immatriculation: string;
 
-  @ApiProperty({ description: 'Model of the vehicule' })
   model: string;
 
-  @ApiProperty({
-    description: 'Company that owns the vehicule',
-    type: () => Company,
-  })
   company: Company;
 
-  @ApiProperty({
-    description: 'Driver assigned to the vehicule',
-    type: () => Driver,
-  })
   driver: Driver;
 
-  @ApiProperty({ description: 'List of seats in the vehicule', type: [Place] })
   places: Place[];
 
-  @ApiProperty({
-    description: 'List of trips for this vehicule',
-    type: [Trajet],
-  })
   trajets: Trajet[];
 
-  @ApiProperty({ description: 'ID of the company that owns the vehicule' })
   companyId: number;
 
-  @ApiProperty({ description: 'ID of the driver assigned to the vehicule' })
   driverId: number;
 
   constructor(partial: Partial<Vehicule>) {

+ 11 - 8
node_app/src/infrastructure/database/repositories/company.repository.ts

@@ -3,7 +3,6 @@
 import { Injectable } from '@nestjs/common';
 import { PrismaService } from '../prisma.service';
 import { Company } from '../../../domain/entities/company.entity';
-import { CreateCompanyDto } from '../../../application/dto/create-company.dto';
 import { UpdateCompanyDto } from '../../../application/dto/update-company.dto';
 import { CompanyMapper } from '../../mappers/company.mapper';
 import { Vehicule } from 'src/domain/entities/vehicule.entity';
@@ -15,7 +14,7 @@ export class CompanyRepository implements IBaseRepository<Company> {
 
   constructor(private prisma: PrismaService) {}
 
-  async create(data: CreateCompanyDto): Promise<Company> {
+  async create(data: Company): Promise<Company> {
     const prismaCompany = await this.prisma.company.create({
       data: {
         name: data.name,
@@ -59,18 +58,22 @@ export class CompanyRepository implements IBaseRepository<Company> {
         manager: true,
       },
     });
-    return companies.map((company) => this.companyMapper.toDomain(company));
+    // Remove the explicit type annotation that's causing the error
+    return companies.map(
+      // eslint-disable-next-line @typescript-eslint/no-unsafe-argument
+      (company: any): Company => this.companyMapper.toDomain(company),
+    );
   }
 
-  async update(id: number, data: UpdateCompanyDto): Promise<Company> {
+  async update(id: number, entity: UpdateCompanyDto): Promise<Company> {
     const prismaCompany = await this.prisma.company.update({
       where: { id },
       data: {
-        name: data.name,
-        address: data.address,
-        manager: data.manager?.id
+        name: entity.name,
+        address: entity.address,
+        manager: entity.managerId
           ? {
-              connect: { id: data.manager.id },
+              connect: { id: entity.managerId },
             }
           : undefined,
       },

+ 4 - 3
node_app/src/infrastructure/database/repositories/driver.repository.ts

@@ -13,7 +13,7 @@ export class DriverRepository implements IBaseRepository<Driver> {
     private readonly driverMapper: DriverMapper,
   ) {}
 
-  async create(driver: Driver): Promise<Driver> {
+  create = async (driver: Driver): Promise<Driver> => {
     const prismaDriver = await this.prisma.driver.create({
       data: {
         name: driver.name,
@@ -24,15 +24,16 @@ export class DriverRepository implements IBaseRepository<Driver> {
       },
     });
     return this.driverMapper.toDomain(prismaDriver);
-  }
+  };
 
   async findById(id: number): Promise<Driver | null> {
     const prismaDriver = await this.prisma.driver.findUnique({ where: { id } });
     return prismaDriver ? this.driverMapper.toDomain(prismaDriver) : null;
   }
+
   async findAll(): Promise<Driver[]> {
     const prismaDrivers = await this.prisma.driver.findMany();
-    return prismaDrivers.map((prismaDriver) =>
+    return prismaDrivers.map((prismaDriver: Partial<Driver>) =>
       this.driverMapper.toDomain(prismaDriver),
     );
   }

+ 9 - 11
node_app/src/infrastructure/database/repositories/reservation.repository.ts

@@ -1,8 +1,6 @@
 import { Injectable } from '@nestjs/common';
 import { PrismaService } from '../prisma.service';
 import { Reservation } from '../../../domain/entities/reservation.entity';
-import { CreateReservationDto } from '../../../application/dto/create-reservation.dto';
-import { UpdateReservationDto } from '../../../application/dto/update-reservation.dto';
 import { ReservationMapper } from 'src/infrastructure/mappers/reservation.mapper';
 import { IBaseRepository } from './BaseRepository';
 
@@ -28,7 +26,7 @@ export class ReservationRepository implements IBaseRepository<Reservation> {
       : null;
   }
 
-  async create(data: CreateReservationDto): Promise<Reservation> {
+  async create(data: Reservation): Promise<Reservation> {
     const createdReservation = await this.prisma.reservation.create({
       data: {
         dateAt: data.dateAt,
@@ -65,24 +63,24 @@ export class ReservationRepository implements IBaseRepository<Reservation> {
     return this.reservationMapper.toDomain(createdReservation);
   }
 
-  async update(id: number, data: UpdateReservationDto): Promise<Reservation> {
+  async update(id: number, entity: Reservation): Promise<Reservation> {
     const updatedReservation = await this.prisma.reservation.update({
       where: { id },
       data: {
-        dateAt: data.dateAt,
-        place: data.placeId
+        dateAt: entity.dateAt,
+        place: entity.placeId
           ? {
-              connect: { id: data.placeId },
+              connect: { id: entity.placeId },
             }
           : undefined,
-        user: data.userId
+        user: entity.userId
           ? {
-              connect: { id: data.userId },
+              connect: { id: entity.userId },
             }
           : undefined,
-        trajet: data.trajetId
+        trajet: entity.trajetId
           ? {
-              connect: { id: data.trajetId },
+              connect: { id: entity.trajetId },
             }
           : undefined,
       },

+ 9 - 11
node_app/src/infrastructure/database/repositories/trajet.repository.ts

@@ -1,8 +1,6 @@
 import { Injectable } from '@nestjs/common';
 import { PrismaService } from '../prisma.service';
 import { Trajet } from '../../../domain/entities/trajet.entity';
-import { CreateTrajetDto } from '../../../application/dto/create-trajet.dto';
-import { UpdateTrajetDto } from '../../../application/dto/update-trajet.dto';
 import { TrajetMapper } from 'src/infrastructure/mappers/trajet.mapper';
 import { IBaseRepository } from './BaseRepository';
 
@@ -20,7 +18,7 @@ export class TrajetRepository implements IBaseRepository<Trajet> {
     return prismaTrajet ? this.trajetMapper.toDomain(prismaTrajet) : null;
   }
 
-  async create(data: CreateTrajetDto): Promise<Trajet> {
+  create = async (data: Trajet): Promise<Trajet> => {
     const createdTrajet = await this.prisma.trajet.create({
       data: {
         departAt: data.departAt,
@@ -49,19 +47,19 @@ export class TrajetRepository implements IBaseRepository<Trajet> {
     });
 
     return this.trajetMapper.toDomain(createdTrajet);
-  }
+  };
 
-  async update(id: number, data: UpdateTrajetDto): Promise<Trajet> {
+  async update(id: number, entity: Trajet): Promise<Trajet> {
     const updatedTrajet = await this.prisma.trajet.update({
       where: { id },
       data: {
-        departAt: data.departAt,
-        arriveAt: data.arriveAt,
-        depart: data.depart,
-        arrive: data.arrive,
-        vehicule: data.vehiculeId
+        departAt: entity.departAt,
+        arriveAt: entity.arriveAt,
+        depart: entity.depart,
+        arrive: entity.arrive,
+        vehicule: entity.vehiculeId
           ? {
-              connect: { id: data.vehiculeId },
+              connect: { id: entity.vehiculeId },
             }
           : undefined,
       },

+ 4 - 1
node_app/src/infrastructure/mappers/company.mapper.ts

@@ -5,7 +5,7 @@ import { Company as PrismaCompany } from '@prisma/client';
 import { Company } from 'src/domain/entities/company.entity';
 
 export class CompanyMapper implements IPrismaMapper<PrismaCompany, Company> {
-  toDomain(prismaCompany: PrismaCompany): Company {
+  toDomain(prismaCompany: Partial<PrismaCompany>): Company {
     return new Company({
       id: prismaCompany.id,
       name: prismaCompany.name,
@@ -20,4 +20,7 @@ export class CompanyMapper implements IPrismaMapper<PrismaCompany, Company> {
       managerId: company.manager,
     };
   }
+  fromDtoToDomain(dto: unknown): Company {
+    return new Company(dto as Company);
+  }
 }

+ 16 - 1
node_app/src/infrastructure/mappers/driver.mapper.ts

@@ -3,7 +3,7 @@ import { Driver } from 'src/domain/entities/driver.entity';
 import { Driver as PrismaDriver } from '@prisma/client';
 
 export class DriverMapper implements IPrismaMapper<PrismaDriver, Driver> {
-  toDomain(prismaDriver: PrismaDriver): Driver {
+  toDomain(prismaDriver: Partial<PrismaDriver>): Driver {
     return new Driver({
       id: prismaDriver.id,
       name: prismaDriver.name,
@@ -13,4 +13,19 @@ export class DriverMapper implements IPrismaMapper<PrismaDriver, Driver> {
       companyId: prismaDriver.companyId,
     });
   }
+
+  toPrisma(driver: Driver): PrismaDriver {
+    return {
+      id: driver.id,
+      name: driver.name,
+      address: driver.address,
+      telephone: driver.telephone,
+      userId: driver.userId ?? null,
+      companyId: driver.companyId ?? null,
+    };
+  }
+
+  fromDtoToDomain(dto: unknown): Driver {
+    return new Driver(dto as Driver);
+  }
 }

+ 12 - 0
node_app/src/infrastructure/mappers/place.mapper.ts

@@ -10,4 +10,16 @@ export class PlaceMapper implements IPrismaMapper<PrismaPlace, Place> {
       vehiculeId: prismaPlace.vehiculeId,
     });
   }
+
+  toPrisma(place: Place): PrismaPlace {
+    return {
+      id: place.id,
+      number: place.number,
+      vehiculeId: place.vehiculeId,
+    };
+  }
+
+  fromDtoToDomain(dto: unknown): Place {
+    return new Place(dto as Place);
+  }
 }

+ 2 - 0
node_app/src/infrastructure/mappers/prisma-mapper.interface.ts

@@ -3,4 +3,6 @@ export interface IPrismaMapper<TPrisma, TDomain> {
   toDomain(prismaEntity: TPrisma): TDomain;
   // Optionnel : pour les opérations inverses
   toPrisma?(domainEntity: TDomain): Partial<TPrisma>;
+
+  fromDtoToDomain?(dto: unknown): TDomain;
 }

+ 7 - 3
node_app/src/infrastructure/mappers/reservation.mapper.ts

@@ -19,9 +19,13 @@ export class ReservationMapper
     return {
       id: reservation.id,
       dateAt: reservation.dateAt,
-      userId: reservation.userId,
-      placeId: reservation.placeId,
-      trajetId: reservation.trajetId,
+      userId: reservation.userId ?? null,
+      placeId: reservation.placeId ?? null,
+      trajetId: reservation.trajetId ?? null,
     };
   }
+
+  fromDtoToDomain(dto: unknown): Reservation {
+    return new Reservation(dto as Reservation);
+  }
 }

+ 4 - 0
node_app/src/infrastructure/mappers/trajet.mapper.ts

@@ -24,4 +24,8 @@ export class TrajetMapper implements IPrismaMapper<PrismaTrajet, Trajet> {
       vehiculeId: trajet.vehiculeId,
     };
   }
+
+  fromDtoToDomain(dto: unknown): Trajet {
+    return new Trajet(dto as Trajet);
+  }
 }

+ 4 - 0
node_app/src/infrastructure/mappers/user.mapper.ts

@@ -26,4 +26,8 @@ export class UserMapper implements IPrismaMapper<PrismaUser, User> {
       telephone: user.telephone,
     };
   }
+
+  fromDtoToDomain(dto: unknown): User {
+    return new User(dto as User);
+  }
 }

+ 17 - 0
node_app/src/infrastructure/mappers/vehicule.mapper.ts

@@ -14,4 +14,21 @@ export class VehiculeMapper implements IPrismaMapper<PrismaVehicule, Vehicule> {
       companyId: prismaVehicule.companyId,
     });
   }
+
+  toPrisma(vehicule: Vehicule): PrismaVehicule {
+    return {
+      id: vehicule.id,
+      immatriculation: vehicule.immatriculation,
+      color: vehicule.color,
+      type: vehicule.type,
+      number_places: vehicule.number_places,
+      driverId: vehicule.driverId,
+      companyId: vehicule.companyId,
+      model: vehicule.model,
+    };
+  }
+
+  fromDtoToDomain(dto: unknown): Vehicule {
+    return new Vehicule(dto as Vehicule);
+  }
 }

+ 5 - 10
node_app/src/main.ts

@@ -18,7 +18,7 @@ async function bootstrap() {
 
   // swagger document
   const config = new DocumentBuilder()
-    .setTitle('Transport example')
+    .setTitle('Transport app')
     .setDescription('The Transport API description')
     .setVersion('1.0')
     .addTag('Transport')
@@ -27,19 +27,14 @@ async function bootstrap() {
   const document = SwaggerModule.createDocument(app, config);
   SwaggerModule.setup('api-docs', app, document);
 
-  // Setup Redoc
-  //await RedocModule.setup('/docs', app, document, redocOptions);
-
   // Get Prisma Service
   const prismaService = app.get(PrismaService);
 
-  // Enable shutdown hooks
-  //await prismaService.enableShutdownHooks();
-
   app.useGlobalPipes(
     new ValidationPipe({
-      whitelist: true,
-      transform: true,
+      whitelist: true, // Cette option filtre automatiquement les propriétés qui n'ont pas de décorateurs de validation dans votre DTO
+      transform: true, // Cette option transforme automatiquement les données entrantes en les convertissant en types appropriés
+      forbidNonWhitelisted: true, // Cette option empêche l'utilisation de propriétés non autorisées dans la requête
     }),
   );
 
@@ -66,4 +61,4 @@ async function bootstrap() {
   await app.listen(3000, '0.0.0.0');
   console.log(`Application is running on: ${await app.getUrl()}`);
 }
-bootstrap();
+void bootstrap();

+ 1 - 0
node_app/src/presentation/interceptors/transform.interceptor.ts

@@ -22,6 +22,7 @@ export class TransformInterceptor<T>
   ): Observable<Response<T>> {
     return next.handle().pipe(
       map((data) => ({
+        // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
         data,
         timestamp: new Date().toISOString(),
       })),