Table des matières

Architecture Hexagonale Backend NestJS

Objectifs

L'architecture backend doit répondre aux exigences suivantes :

L'architecture retenue est :


Vue globale

                   ┌──────────────────┐
                   │    Frontend      │
                   │     NextJS       │
                   └────────┬─────────┘
                            │
                            ▼

                  ┌────────────────────┐
                  │    REST API        │
                  │ NestJS Controllers │
                  └────────┬───────────┘
                           │
                           ▼

                ┌─────────────────────────┐
                │    Application Layer    │
                │ Commands / Queries      │
                └──────────┬──────────────┘
                           │
                           ▼

                ┌─────────────────────────┐
                │      Domain Layer       │
                │ Entities / Services     │
                └──────────┬──────────────┘
                           │
                           ▼

                ┌─────────────────────────┐
                │ Infrastructure Layer    │
                │ PostgreSQL / S3 / SMTP  │
                └─────────────────────────┘

Structure du projet

src/

├── core/
│
├── modules/
│
├── infrastructure/
│
├── shared/
│
├── config/
│
└── main.ts

Core

Le dossier Core contient les composants techniques communs.

core/

├── domain/
│
├── application/
│
├── ports/
│
├── cqrs/
│
├── events/
│
├── exceptions/
│
├── value-objects/
│
└── shared-kernel/

Organisation DDD

Chaque domaine métier devient un Bounded Context.

modules/

├── auth
├── users
├── owners
├── properties
├── reservations
├── contracts
├── payments
├── crm
├── messaging
├── reporting
├── administration
└── notifications

Chaque module est totalement autonome.


Structure interne d'un module

Exemple : Reservation

reservations/

├── domain
│
├── application
│
├── infrastructure
│
└── presentation

Domain

Contient exclusivement le métier.

domain/

├── entities/
├── value-objects/
├── repositories/
├── services/
├── events/
└── exceptions/

Exemple :

Reservation.ts

ReservationStatus.ts

ReservationCreatedEvent.ts

ReservationRepository.ts

Aucune dépendance NestJS.


Application

Contient les cas d'usage.

application/

├── commands/
├── queries/
├── handlers/
├── dto/
└── mappers/

Infrastructure

Contient les implémentations.

infrastructure/

├── persistence/
├── external/
├── repositories/
├── mappers/
└── listeners/

Presentation

Couche d'exposition.

presentation/

├── controllers/
├── swagger/
└── validators/

Ports & Adapters

Ports

Définis dans le domaine.

export interface ReservationRepository {
 
  save(
    reservation: Reservation
  ): Promise<void>;
 
  findById(
    id: string
  ): Promise<Reservation>;
 
}

Adapter PostgreSQL

@Injectable()
export class ReservationRepositoryPg
implements ReservationRepository {
 
}

Adapter Stripe

export interface PaymentGateway {
 
  createPayment(
    amount: number
  ): Promise<string>;
 
}

@Injectable()
export class StripeGateway
implements PaymentGateway {
 
}

Adapter Signature Électronique

export interface SignatureGateway {
 
  sendDocument(
    document: Contract
  ): Promise<void>;
 
}

Architecture CQRS

Les commandes modifient l'état.

Les requêtes lisent l'état.


Commands

CreateReservationCommand

UpdateReservationCommand

CancelReservationCommand

ConfirmReservationCommand

Queries

GetReservationQuery

SearchReservationsQuery

GetCustomerReservationsQuery

Handlers

CreateReservationHandler

UpdateReservationHandler

CancelReservationHandler

Exemple de flux CQRS

POST /reservations

        │

        ▼

CreateReservationCommand

        │

        ▼

CreateReservationHandler

        │

        ▼

ReservationDomainService

        │

        ▼

ReservationRepository

        │

        ▼

PostgreSQL

Event Bus

Tous les événements métier sont publiés.


Événements Réservation

ReservationCreated

ReservationConfirmed

ReservationCancelled

ReservationCompleted

Événements Contrat

ContractGenerated

ContractSigned

ContractRefused

Événements Paiement

PaymentAuthorized

PaymentSucceeded

PaymentFailed

PaymentRefunded

Flux événementiel

ReservationCreated

       │

       ├── NotificationService
       │
       ├── ContractService
       │
       ├── CRMService
       │
       └── AuditService

Repository Pattern

Interface Domaine

export interface PropertyRepository {
 
  findById(
    id: string
  ): Promise<Property>;
 
  save(
    property: Property
  ): Promise<void>;
 
}

Implémentation PostgreSQL

export class PropertyRepositoryPg
implements PropertyRepository {
 
}

Domain Services

Lorsque la logique dépasse une seule entité.


Exemple

ReservationDomainService

PropertyAvailabilityService

ContractGenerationService

PaymentCalculationService

OwnerRevenueService

Value Objects

Objets immuables métier.


Exemples

Money

Email

PhoneNumber

PostalAddress

DateRange

ReservationPeriod

Aggregate Roots

Reservation

Reservation

 ├── Guests
 ├── Payments
 ├── Contract
 └── Events

Property

Property

 ├── Address
 ├── Features
 ├── Photos
 ├── Availability
 └── Rates

Modules NestJS

AuthModule

UsersModule

OwnersModule

PropertiesModule

ReservationsModule

ContractsModule

PaymentsModule

MessagingModule

CRMModule

ReportingModule

AdministrationModule

NotificationsModule

Services externes

Paiement

Stripe

PayPal (optionnel)

MangoPay (optionnel)

Signature

Yousign

DocuSign

Stockage

AWS S3

MinIO

OVH Object Storage

Notifications

SMTP

SMS Gateway

Push Notifications

Architecture de déploiement

Internet

 │

 ▼

Cloudflare

 │

 ▼

Nginx

 │

 ▼

Frontend NextJS

 │

 ▼

Backend NestJS

 │

 ├── API
 │
 ├── Workers
 │
 ├── Scheduler
 │
 └── Event Consumers

 ▼

PostgreSQL

 ▼

Redis

 ▼

S3

Redis

Utilisations :


Workers

Traitements asynchrones.

GenerateContractWorker

SendEmailWorker

SendNotificationWorker

GenerateInvoiceWorker

ReportingWorker

Sécurité

Authentification


Autorisation


Audit

Toutes les actions critiques :

sont journalisées.


Résultat

Cette architecture permet :


Étape suivante

À partir de cette architecture, nous pouvons désormais produire :

Ce document servira ensuite de base à la génération automatique du frontend et des SDK clients.

DokuWiki Appliance - Powered by TurnKey Linux