xpeditis2.0/docs/architecture/overview.md
2026-05-14 21:11:54 +02:00

7.5 KiB

Architecture — Xpeditis

Xpeditis est une plateforme B2B SaaS de réservation de fret maritime, construite en monorepo avec une architecture hexagonale stricte côté backend.


Vue d'ensemble système

┌─────────────────────────────────────────────────────────────┐
│               Frontend (Next.js 14 + App Router)             │
│    React 18 · TanStack Query · Socket.IO · next-intl (i18n)  │
└──────────────────────────┬──────────────────────────────────┘
                           │ HTTPS / WSS
┌──────────────────────────▼──────────────────────────────────┐
│                    Backend (NestJS 10)                        │
│         JWT Auth · Rate Limiting · Swagger OpenAPI           │
└────┬──────────┬──────────┬──────────┬──────────┬────────────┘
     │          │          │          │          │
     ▼          ▼          ▼          ▼          ▼
  Rates      Bookings    Users    Carriers   CSV System
  Service    Service     Service   Service    Service
     │          │          │          │          │
     └──────────┴──────────┴──────────┴──────────┘
                           │
        ┌──────────────────┼──────────────────┐
        ▼                  ▼                  ▼
   PostgreSQL 15        Redis 7          MinIO (S3)
   (données)           (cache 15min)    (documents)

Architecture hexagonale (backend)

apps/backend/src/
├── domain/              # Logique métier pure — zéro dépendance framework
│   ├── entities/        # 17 entités métier
│   ├── value-objects/   # Objets valeur immuables
│   ├── services/        # Services métier purs
│   ├── ports/in/        # Interfaces use-case (execute())
│   └── ports/out/       # Interfaces repository/SPI
│
├── application/         # Controllers, DTOs, Guards
│   ├── controllers/     # REST controllers avec Swagger
│   ├── dto/             # DTOs class-validator
│   ├── mappers/         # Domain ↔ DTO
│   ├── guards/          # JwtAuthGuard, RolesGuard, ApiKeyGuard
│   ├── gateways/        # WebSocket (Socket.IO)
│   └── services/        # Services applicatifs (audit, notification)
│
└── infrastructure/      # Adaptateurs externes
    ├── persistence/     # TypeORM (entities, repositories, mappers, migrations)
    ├── carriers/        # Connecteurs carriers + CSV loader
    ├── cache/           # Adaptateur Redis
    ├── email/           # MJML + Nodemailer
    ├── storage/         # S3/MinIO + CSV storage
    ├── stripe/          # Abonnements et paiements
    ├── external/        # Pappers (SIRET)
    ├── pdf/             # Génération PDF (pdfkit)
    └── monitoring/      # Sentry, logging Pino

Règles de dépendance :

  • Domain : aucune dépendance externe (TypeScript pur)
  • Application : dépend uniquement du domain
  • Infrastructure : dépend uniquement du domain
  • Le flux de dépendances pointe toujours vers le centre

Stack technique

Backend

Composant Technologie
Framework NestJS 10.x
Langage TypeScript 5.3+ strict
ORM TypeORM 0.3.x
Base de données PostgreSQL 15+
Cache Redis 7+ (ioredis)
Auth JWT (15min) + Refresh tokens (7j) + OAuth2
Auth alternative API Keys (Argon2 hash)
WebSocket Socket.IO
Email Nodemailer + MJML templates
PDF pdfkit
Paiements Stripe
Stockage fichiers S3 / MinIO
Validation class-validator + class-transformer
Docs API Swagger/OpenAPI
Logging nestjs-pino (pino-pretty dev)
Monitoring Sentry
i18n nestjs-i18n
Circuit breaker opossum (5s timeout carriers)

Frontend

Composant Technologie
Framework Next.js 14 (App Router)
Langage TypeScript
Styling Tailwind CSS
State serveur TanStack Query v5
Tables TanStack Table v8 + Virtual
Formulaires react-hook-form + zod
Temps réel Socket.IO client
Graphiques recharts
Cartes react-leaflet
i18n next-intl (fr, en)
Éditeur riche Tiptap
État global zustand
Animations framer-motion

Modules NestJS

Guards globaux : JwtAuthGuard (toutes les routes protégées par défaut), CustomThrottlerGuard

Feature modules :

  • Auth, Rates, Ports, Bookings, CsvBookings, Organizations, Users
  • Dashboard, Audit, Notifications, Webhooks, GDPR, Admin
  • Subscriptions, ApiKeys, Blog, Logs

Infrastructure modules :

  • CacheModule (Redis), CarrierModule, SecurityModule
  • CsvRateModule, StripeModule, PdfModule, StorageModule, EmailModule

Flux clés

Recherche de tarifs (FCL)

POST /api/v1/rates/search
   → Vérification cache Redis (TTL 15min)
   → Si cache miss : appel parallel carriers API (5s timeout + circuit breaker)
   → Normalisation résultats → stockage Redis
   → Réponse JSON paginée

Réservation standard

POST /api/v1/bookings
   → Validation DTO → Génération WCM-YYYY-XXXXXX
   → Persistance PostgreSQL
   → Audit log
   → Notification WebSocket
   → Déclenchement webhooks
   → Email confirmation (MJML)
   → PDF booking

Portail Carrier (CSV Bookings)

Admin crée CSV booking → assigne carrier
   → Email magic link (1h expiry)
   → Carrier s'authentifie via token
   → Accept/Reject → Activité logguée

Abonnements

Stripe webhook → /api/v1/subscriptions/webhook
   → Vérification signature HMAC
   → Mise à jour subscription + license

Sécurité

Mesure Implémentation
Rate limiting 100 req/min global, 5/min auth, 30/min search
Password hashing Argon2id
JWT Access 15min + Refresh 7j avec rotation
API Keys Argon2 hash, préfixe xped_
Brute force Exponential backoff après 3 échecs
Headers sécurité Helmet.js (CSP, HSTS, XSS)
Validation class-validator sur tous les DTOs
RBAC 5 rôles : ADMIN, MANAGER, USER, VIEWER, CARRIER
CORS Origines strictes
Upload fichiers Validation MIME, max 10MB
GDPR Export/suppression données utilisateur

Performances

  • Recherche tarifs (avec cache) : < 2s (p90) — ~500ms observé
  • Création booking : < 3s — ~1s observé
  • Dashboard (5k bookings) : < 1s
  • Cache hit ratio cible : > 90%

Déploiement

L'application est containerisée (Dockerfile dans chaque app).

  • Développement : docker-compose (PostgreSQL + Redis + MinIO)
  • Production : Portainer / Docker Swarm ou Kubernetes (Hetzner)
  • CI/CD : GitHub Actions (.github/workflows/)

Voir ../deployment/portainer.md et ../deployment/hetzner/README.md.


Dernière mise à jour : Mai 2026