# 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](../deployment/portainer.md) et [../deployment/hetzner/README.md](../deployment/hetzner/README.md).

---

*Dernière mise à jour : Mai 2026*
