Skip to main content
Cette page décrit l’architecture et l’organisation du code de Châtaigne, conçue pour être modulaire, maintenable et évolutive.

Organisation Générale

Châtaigne utilise une architecture monorepo organisée avec les dossiers principaux suivants :
/
├── apps/
   ├── server/        # Backend NestJS
   └── web/           # Frontend NextJS
└── packages/
    ├── prisma/          # Schéma de base de données et migrations
    └── backend-client/  # Types partagés et méthode permettant
                         # d'appeler les endpoints du backend

Modules principaux

1

Domain Module

Le cœur de l’application :
  • Contient toutes les entités métier
  • Implémente la logique métier pure
  • Ne dépend d’aucun autre module
2

Application Module

La couche d’orchestration :
  • Orchestre les use cases
  • Injecte les dépendances nécessaires
  • Gère les transactions
  • Dépend uniquement du Domain Module
3

Infrastructure Module

La couche technique :
  • Implémente les repositories
  • Gère les connexions externes
  • Configure les services tiers
  • Implémente les adaptateurs
4

Presentation Module

L’interface avec l’extérieur :
  • Expose les API REST
  • Gère la validation des entrées
  • Configure la documentation OpenAPI
  • Implémente la sécurité et l’authentification
/src
├── domain/                # Couche Domain
   ├── entities/          # Entités métier
   ├── value-objects/     # Value Objects
   └── exceptions/        # Exceptions métier

├── application/           # Couche Application
   ├── use-cases/        # Use cases par fonctionnalité
      ├── order/
      ├── catalog/
      ├── catalog/
      └── .../

├── infrastructure/  # Couche Infrastructure
   ├── repositories/    # Implémentation des repositories (Accès à la Database)
   ├── services/        # Services externes
   ├── dialog/         # Service WhatsApp
   ├── stripe/         # Service de paiement
   ├── hubrise/        # Integration POS
   ├── expedy/         # Integration POS
   └── .../            # Service d'impression
   ├── adapters/        # Adaptateurs pour les services externes
   ├── prisma/         # Adapters Prisma
   └── dtos/           # Adapters DTOs
   ├── queues/          # Définition des queues
   └── processors/      # Processors pour les tâches asynchrones

└── presentation/     # Couche Presentation
    ├── controllers/    # Controllers REST
    ├── dtos/           # Validation et documentation des types d'entrées et de sorties
    ├── guards/         # Guards d'authentification
    └── middlewares/    # Middlewares

Conventions de Nommage

Nous utilisons des conventions de nommage strictes pour maintenir la cohérence du code.

Fichiers

Tous les fichiers suivent le format kebab-case avec des suffixes spécifiques selon leur type :

Entités & Repositories

.entity.ts - Entités.repository.ts - Repositories

Use Cases & Controllers

.usecase.ts - Use cases.controller.ts - Controllers

Services & Adaptateurs

.service.ts - Services.adapter.ts - Adaptateurs

Events & Listeners

.event.ts - Events.listener.ts - Event Listeners

Injection de Dépendances

NestJS fournit un système d’injection de dépendances robuste que nous utilisons de la manière suivante :
  • Les interfaces sont injectées via des tokens
  • La configuration se fait dans les modules respectifs
Voici un exemple de configuration :
// Dans la couche Domain
interface IConversationRepository {
  //...
}

const IConversationRepository = Symbol("IConversationRepository");
// Dans la couche infrastructure
class ConversationRepository implements IConversationRepository {
  ///...
}
// Dans le Module Infrastructure
@Module({
  providers: [
    {
      provide: IConversationRepository, // Symbole de la classe défini dans l'interface
      useClass: ConversationRepository // Implementation de la classe
    },
  ]
})

Points d’Attention

Dépendances

• Les dépendances pointent vers l’intérieur (Domain)• Communication uniquement entre couches adjacentes

Adaptateurs

• Obligatoires pour la transformation de données• Isolation claire des formats de données externes

Repositories

• Manipulation exclusive des entités domain• Pas de logique métier

Use Cases

• Une seule responsabilité• Orchestration claire des dépendances
Cette structure permet une séparation claire des responsabilités tout en maintenant la flexibilité nécessaire pour l’évolution du système et l’ajout de nouvelles intégrations.