diff --git a/INDEX.md b/INDEX.md index 25651bf..661d530 100644 --- a/INDEX.md +++ b/INDEX.md @@ -1,348 +1,81 @@ -# 📑 Xpeditis Documentation Index - -Complete guide to all documentation files in the Xpeditis project. +# Index de documentation — Xpeditis --- -## 🚀 Getting Started (Read First) +## DĂ©marrage -Start here if you're new to the project: - -1. **[README.md](README.md)** - Project overview and quick start -2. **[QUICK-START.md](QUICK-START.md)** ⚡ - Get running in 5 minutes -3. **[INSTALLATION-STEPS.md](INSTALLATION-STEPS.md)** - Detailed installation guide -4. **[NEXT-STEPS.md](NEXT-STEPS.md)** - What to do after setup +| Fichier | Description | +|---------|-------------| +| [README.md](README.md) | Vue d'ensemble du projet | +| [QUICK-START.md](QUICK-START.md) | DĂ©marrage en 5 minutes | +| [CLAUDE.md](CLAUDE.md) | Architecture hexagonale, conventions, rĂšgles | +| [docs/README.md](docs/README.md) | Index complet de la documentation | --- -## 📊 Project Status & Planning +## Documentation complĂšte -### Sprint 0 (Complete ✅) +Toute la documentation est organisĂ©e dans [docs/](docs/) : -- **[SPRINT-0-FINAL.md](SPRINT-0-FINAL.md)** - Complete Sprint 0 report - - All deliverables - - Architecture details - - How to use - - Success criteria - -- **[SPRINT-0-SUMMARY.md](SPRINT-0-SUMMARY.md)** - Executive summary - - Objectives achieved - - Metrics - - Key features - - Next steps - -- **[SPRINT-0-COMPLETE.md](SPRINT-0-COMPLETE.md)** - Technical completion checklist - - Week-by-week breakdown - - Files created - - Remaining tasks - -### Project Roadmap - -- **[TODO.md](TODO.md)** 📅 - 30-week MVP development roadmap - - Sprint-by-sprint breakdown - - Detailed tasks with checkboxes - - Phase 1-4 planning - - Go-to-market strategy - -- **[PRD.md](PRD.md)** 📋 - Product Requirements Document - - Business context - - Functional specifications - - Technical requirements - - Success metrics +``` +docs/ +├── README.md # Index principal +├── getting-started/ # Installation et dĂ©marrage +│ ├── quick-start.md # Guide rapide mis Ă  jour +│ ├── installation.md # Installation dĂ©taillĂ©e +│ └── windows.md # SpĂ©cifique Windows +│ +├── architecture/ # Documentation technique +│ ├── overview.md # Vue d'ensemble systĂšme +│ ├── database.md # SchĂ©ma BDD complet (21 tables) +│ ├── backend.md # NestJS hexagonal, patterns +│ └── frontend.md # Next.js 14, App Router, i18n +│ +├── features/ # Documentation par fonctionnalitĂ© +│ ├── auth.md # Auth JWT/OAuth/API Keys + RBAC +│ ├── bookings.md # RĂ©servations standard +│ ├── csv-bookings.md # CSV bookings + portail carrier +│ ├── rate-search.md # Recherche tarifs FCL + CSV +│ ├── subscriptions.md # Stripe + abonnements +│ ├── notifications.md # WebSocket + webhooks +│ └── api-access.md # ClĂ©s API +│ +├── deployment/ # DĂ©ploiement +│ ├── portainer.md # Portainer / Docker Swarm (consolidĂ©) +│ ├── hetzner/ # Kubernetes Hetzner (15 fichiers numĂ©rotĂ©s) +│ └── STRIPE_SETUP.md # Configuration Stripe +│ +├── testing/ # Tests +├── csv-system/ # SystĂšme CSV (format, calcul prix) +├── carrier-portal/ # Portail carrier (recherche API) +├── api-access/ # Documentation accĂšs API +├── backend/ # Notes backend (cleanup, MinIO) +└── archive/ # Rapports de sprint archivĂ©s + ├── phases/ # Historique phases 1-4 + └── debug/ # Notes de debug rĂ©solues +``` --- -## đŸ—ïž Architecture & Development Guidelines +## Commandes essentielles -### Core Architecture +```bash +# DĂ©marrer +docker-compose up -d +npm run install:all +cd apps/backend && npm run migration:run && cd ../.. +npm run backend:dev # http://localhost:4000 +npm run frontend:dev # http://localhost:3000 -- **[CLAUDE.md](CLAUDE.md)** đŸ—ïž - **START HERE FOR ARCHITECTURE** - - Complete hexagonal architecture guide - - Domain/Application/Infrastructure layers - - Ports & Adapters pattern - - Naming conventions - - Testing strategy - - Common pitfalls - - Complete examples (476 lines) +# Tests +npm run backend:test +npm run frontend:test -### Component-Specific Documentation - -- **[apps/backend/README.md](apps/backend/README.md)** - Backend (NestJS + Hexagonal) - - Architecture details - - Available scripts - - API endpoints - - Testing guide - - Hexagonal architecture DOs and DON'Ts - -- **[apps/frontend/README.md](apps/frontend/README.md)** - Frontend (Next.js 14) - - Tech stack - - Project structure - - API integration - - Forms & validation - - Testing guide +# QualitĂ© +npm run format +npm run backend:lint && npm run frontend:lint +``` --- -## đŸ› ïž Technical Documentation - -### Configuration Files - -**Root Level**: -- `package.json` - Workspace configuration -- `.gitignore` - Git ignore rules -- `.prettierrc` - Code formatting -- `docker-compose.yml` - PostgreSQL + Redis -- `tsconfig.json` - TypeScript configuration (per app) - -**Backend** (`apps/backend/`): -- `package.json` - Backend dependencies -- `tsconfig.json` - TypeScript strict mode + path aliases -- `nest-cli.json` - NestJS CLI configuration -- `.eslintrc.js` - ESLint rules -- `.env.example` - Environment variables template - -**Frontend** (`apps/frontend/`): -- `package.json` - Frontend dependencies -- `tsconfig.json` - TypeScript configuration -- `next.config.js` - Next.js configuration -- `tailwind.config.ts` - Tailwind CSS theme -- `postcss.config.js` - PostCSS configuration -- `.env.example` - Environment variables template - -### CI/CD - -**GitHub Actions** (`.github/workflows/`): -- `ci.yml` - Continuous Integration - - Lint & format check - - Unit tests (backend + frontend) - - E2E tests - - Build verification - -- `security.yml` - Security Audit - - npm audit - - Dependency review - -**Templates**: -- `.github/pull_request_template.md` - PR template with hexagonal architecture checklist - ---- - -## 📚 Documentation by Use Case - -### I want to... - -**...get started quickly** -1. [QUICK-START.md](QUICK-START.md) - 5-minute setup -2. [INSTALLATION-STEPS.md](INSTALLATION-STEPS.md) - Detailed steps -3. [NEXT-STEPS.md](NEXT-STEPS.md) - Begin development - -**...understand the architecture** -1. [CLAUDE.md](CLAUDE.md) - Complete hexagonal architecture guide -2. [apps/backend/README.md](apps/backend/README.md) - Backend specifics -3. [SPRINT-0-FINAL.md](SPRINT-0-FINAL.md) - See what's implemented - -**...know what to build next** -1. [TODO.md](TODO.md) - Full roadmap -2. [NEXT-STEPS.md](NEXT-STEPS.md) - Immediate next tasks -3. [PRD.md](PRD.md) - Business requirements - -**...understand the business context** -1. [PRD.md](PRD.md) - Product requirements -2. [README.md](README.md) - Project overview -3. [SPRINT-0-SUMMARY.md](SPRINT-0-SUMMARY.md) - Executive summary - -**...fix an installation issue** -1. [INSTALLATION-STEPS.md](INSTALLATION-STEPS.md) - Troubleshooting section -2. [QUICK-START.md](QUICK-START.md) - Common issues -3. [README.md](README.md) - Basic setup - -**...write code following best practices** -1. [CLAUDE.md](CLAUDE.md) - Architecture guidelines (READ THIS FIRST) -2. [apps/backend/README.md](apps/backend/README.md) - Backend DOs and DON'Ts -3. [TODO.md](TODO.md) - Task specifications and acceptance criteria - -**...run tests** -1. [apps/backend/README.md](apps/backend/README.md) - Testing section -2. [apps/frontend/README.md](apps/frontend/README.md) - Testing section -3. [CLAUDE.md](CLAUDE.md) - Testing strategy - -**...deploy to production** -1. [SPRINT-0-FINAL.md](SPRINT-0-FINAL.md) - Security checklist -2. [apps/backend/.env.example](apps/backend/.env.example) - All required variables -3. `.github/workflows/ci.yml` - CI/CD pipeline - ---- - -## 📖 Documentation by Role - -### For Developers - -**Must Read**: -1. [CLAUDE.md](CLAUDE.md) - Architecture principles -2. [apps/backend/README.md](apps/backend/README.md) OR [apps/frontend/README.md](apps/frontend/README.md) -3. [TODO.md](TODO.md) - Current sprint tasks - -**Reference**: -- [INSTALLATION-STEPS.md](INSTALLATION-STEPS.md) - Setup issues -- [PRD.md](PRD.md) - Business context - -### For Architects - -**Must Read**: -1. [CLAUDE.md](CLAUDE.md) - Complete architecture -2. [SPRINT-0-FINAL.md](SPRINT-0-FINAL.md) - Implementation details -3. [PRD.md](PRD.md) - Technical requirements - -**Reference**: -- [TODO.md](TODO.md) - Technical roadmap -- [apps/backend/README.md](apps/backend/README.md) - Backend architecture - -### For Project Managers - -**Must Read**: -1. [SPRINT-0-SUMMARY.md](SPRINT-0-SUMMARY.md) - Status overview -2. [TODO.md](TODO.md) - Complete roadmap -3. [PRD.md](PRD.md) - Requirements & KPIs - -**Reference**: -- [SPRINT-0-FINAL.md](SPRINT-0-FINAL.md) - Detailed completion report -- [README.md](README.md) - Project overview - -### For DevOps - -**Must Read**: -1. [INSTALLATION-STEPS.md](INSTALLATION-STEPS.md) - Setup guide -2. [docker-compose.yml](docker-compose.yml) - Infrastructure -3. `.github/workflows/` - CI/CD pipelines - -**Reference**: -- [apps/backend/.env.example](apps/backend/.env.example) - Environment variables -- [SPRINT-0-FINAL.md](SPRINT-0-FINAL.md) - Security checklist - ---- - -## đŸ—‚ïž Complete File List - -### Documentation (11 files) - -| File | Purpose | Length | -|------|---------|--------| -| [README.md](README.md) | Project overview | Medium | -| [CLAUDE.md](CLAUDE.md) | Architecture guide | Long (476 lines) | -| [PRD.md](PRD.md) | Product requirements | Long (352 lines) | -| [TODO.md](TODO.md) | 30-week roadmap | Very Long (1000+ lines) | -| [QUICK-START.md](QUICK-START.md) | 5-minute setup | Short | -| [INSTALLATION-STEPS.md](INSTALLATION-STEPS.md) | Detailed setup | Medium | -| [NEXT-STEPS.md](NEXT-STEPS.md) | What's next | Medium | -| [SPRINT-0-FINAL.md](SPRINT-0-FINAL.md) | Sprint 0 report | Long | -| [SPRINT-0-SUMMARY.md](SPRINT-0-SUMMARY.md) | Executive summary | Medium | -| [SPRINT-0-COMPLETE.md](SPRINT-0-COMPLETE.md) | Technical checklist | Short | -| [INDEX.md](INDEX.md) | This file | Medium | - -### App-Specific (2 files) - -| File | Purpose | -|------|---------| -| [apps/backend/README.md](apps/backend/README.md) | Backend guide | -| [apps/frontend/README.md](apps/frontend/README.md) | Frontend guide | - -### Configuration (10+ files) - -Root, backend, and frontend configuration files (package.json, tsconfig.json, etc.) - ---- - -## 📊 Documentation Statistics - -- **Total Documentation Files**: 13 -- **Total Lines**: ~4,000+ -- **Coverage**: Setup, Architecture, Development, Testing, Deployment -- **Last Updated**: October 7, 2025 - ---- - -## 🎯 Recommended Reading Path - -### For New Team Members (Day 1) - -**Morning** (2 hours): -1. [README.md](README.md) - 10 min -2. [QUICK-START.md](QUICK-START.md) - 30 min (includes setup) -3. [CLAUDE.md](CLAUDE.md) - 60 min (comprehensive architecture) -4. [PRD.md](PRD.md) - 20 min (business context) - -**Afternoon** (2 hours): -5. [apps/backend/README.md](apps/backend/README.md) OR [apps/frontend/README.md](apps/frontend/README.md) - 30 min -6. [TODO.md](TODO.md) - Current sprint section - 30 min -7. [NEXT-STEPS.md](NEXT-STEPS.md) - 30 min -8. Start coding! 🚀 - -### For Code Review (30 minutes) - -1. [CLAUDE.md](CLAUDE.md) - Hexagonal architecture section -2. [apps/backend/README.md](apps/backend/README.md) - DOs and DON'Ts -3. [TODO.md](TODO.md) - Acceptance criteria for the feature - -### For Sprint Planning (1 hour) - -1. [TODO.md](TODO.md) - Next sprint tasks -2. [PRD.md](PRD.md) - Requirements for the module -3. [SPRINT-0-SUMMARY.md](SPRINT-0-SUMMARY.md) - Current status - ---- - -## 🔍 Quick Reference - -### Common Questions - -**Q: How do I get started?** -A: [QUICK-START.md](QUICK-START.md) - -**Q: What is hexagonal architecture?** -A: [CLAUDE.md](CLAUDE.md) - Complete guide with examples - -**Q: What should I build next?** -A: [NEXT-STEPS.md](NEXT-STEPS.md) then [TODO.md](TODO.md) - -**Q: How do I run tests?** -A: [apps/backend/README.md](apps/backend/README.md) or [apps/frontend/README.md](apps/frontend/README.md) - -**Q: Where are the business requirements?** -A: [PRD.md](PRD.md) - -**Q: What's the project status?** -A: [SPRINT-0-SUMMARY.md](SPRINT-0-SUMMARY.md) - -**Q: Installation failed, what do I do?** -A: [INSTALLATION-STEPS.md](INSTALLATION-STEPS.md) - Troubleshooting section - -**Q: Can I change the database/framework?** -A: Yes! That's the point of hexagonal architecture. See [CLAUDE.md](CLAUDE.md) - ---- - -## 📞 Getting Help - -If you can't find what you need: - -1. **Check this index** - Use Ctrl+F to search -2. **Read CLAUDE.md** - Covers 90% of architecture questions -3. **Check TODO.md** - Has detailed task specifications -4. **Open an issue** - If documentation is unclear or missing - ---- - -## 🎉 Happy Reading! - -All documentation is up-to-date as of Sprint 0 completion. - -**Quick Links**: -- 🚀 [Get Started](QUICK-START.md) -- đŸ—ïž [Architecture](CLAUDE.md) -- 📅 [Roadmap](TODO.md) -- 📋 [Requirements](PRD.md) - ---- - -*Xpeditis MVP - Maritime Freight Booking Platform* -*Documentation Index - October 7, 2025* +*DerniĂšre mise Ă  jour : Mai 2026* diff --git a/README.md b/README.md index c185b67..8e81a43 100644 --- a/README.md +++ b/README.md @@ -1,206 +1,151 @@ -# Xpeditis - Maritime Freight Booking Platform +# Xpeditis — Maritime Freight Booking Platform -**Xpeditis** is a B2B SaaS platform for freight forwarders to search, compare, and book maritime freight in real-time. +Plateforme B2B SaaS permettant aux transitaires de rechercher, comparer et rĂ©server du fret maritime en temps rĂ©el. --- -## ⭐ **[START HERE](START-HERE.md)** ⭐ - -**New to the project?** Read **[START-HERE.md](START-HERE.md)** - Get running in 10 minutes! - ---- - -## 🚀 Quick Start - -### Prerequisites - -- Node.js >= 20.0.0 -- npm >= 10.0.0 -- Docker & Docker Compose -- PostgreSQL 15+ -- Redis 7+ - -### Installation +## DĂ©marrage rapide ```bash -# Install dependencies -npm install +# 1. Installer les dĂ©pendances +npm run install:all -# Start infrastructure (PostgreSQL + Redis) +# 2. DĂ©marrer l'infrastructure (PostgreSQL + Redis + MinIO) docker-compose up -d -# Setup environment variables +# 3. Configurer l'environnement cp apps/backend/.env.example apps/backend/.env -cp apps/frontend/.env.example apps/frontend/.env +cp apps/frontend/.env.example apps/frontend/.env.local -# Run database migrations -npm run backend:migrate +# 4. ExĂ©cuter les migrations +cd apps/backend && npm run migration:run && cd ../.. -# Start backend (development) -npm run backend:dev - -# Start frontend (development) -npm run frontend:dev +# 5. DĂ©marrer les serveurs +npm run backend:dev # http://localhost:4000 · Swagger: /api/docs +npm run frontend:dev # http://localhost:3000 ``` -### Access Points +--- -- **Frontend**: http://localhost:3000 -- **Backend API**: http://localhost:4000 -- **API Documentation**: http://localhost:4000/api/docs - -## 📁 Project Structure +## Structure du projet ``` xpeditis/ ├── apps/ -│ ├── backend/ # NestJS API (Hexagonal Architecture) +│ ├── backend/ # NestJS 10 — Architecture hexagonale │ │ └── src/ -│ │ ├── domain/ # Pure business logic -│ │ ├── application/ # Controllers & DTOs -│ │ └── infrastructure/ # External adapters +│ │ ├── domain/ # Logique mĂ©tier pure (TypeScript) +│ │ ├── application/ # Controllers, DTOs, Guards +│ │ └── infrastructure/ # TypeORM, Redis, S3, Email, Stripe │ └── frontend/ # Next.js 14 App Router -├── packages/ -│ ├── shared-types/ # Shared TypeScript types -│ └── domain/ # Shared domain logic -└── infra/ # Infrastructure configs +│ ├── app/[locale]/ # Routing i18n (fr, en) +│ └── src/ # Components, hooks, lib/api +├── docker-compose.yml # PostgreSQL 15 + Redis 7 + MinIO +└── docs/ # Documentation complĂšte ``` -## đŸ—ïž Architecture - -This project follows **Hexagonal Architecture** (Ports & Adapters) principles: - -- **Domain Layer**: Pure business logic, no external dependencies -- **Application Layer**: Use cases, controllers, DTOs -- **Infrastructure Layer**: Database, external APIs, cache, email, storage - -See [CLAUDE.md](CLAUDE.md) for detailed architecture guidelines. - -## đŸ› ïž Development - -### Backend - -```bash -npm run backend:dev # Start dev server -npm run backend:test # Run tests -npm run backend:test:watch # Run tests in watch mode -npm run backend:test:cov # Generate coverage report -npm run backend:lint # Lint code -npm run backend:build # Build for production -``` - -### Frontend - -```bash -npm run frontend:dev # Start dev server -npm run frontend:build # Build for production -npm run frontend:test # Run tests -npm run frontend:lint # Lint code -``` - -## 📚 Documentation - -### Getting Started -- **[QUICK-START.md](QUICK-START.md)** ⚡ - Get running in 5 minutes -- **[INSTALLATION-STEPS.md](INSTALLATION-STEPS.md)** 📩 - Detailed installation guide -- **[NEXT-STEPS.md](NEXT-STEPS.md)** 🚀 - What to do after setup - -### Architecture & Guidelines -- **[CLAUDE.md](CLAUDE.md)** đŸ—ïž - Hexagonal architecture guidelines (complete) -- **[apps/backend/README.md](apps/backend/README.md)** - Backend documentation -- **[apps/frontend/README.md](apps/frontend/README.md)** - Frontend documentation - -### Project Planning -- **[PRD.md](PRD.md)** 📋 - Product Requirements Document -- **[TODO.md](TODO.md)** 📅 - 30-week development roadmap -- **[SPRINT-0-FINAL.md](SPRINT-0-FINAL.md)** ✅ - Sprint 0 completion report -- **[SPRINT-0-SUMMARY.md](SPRINT-0-SUMMARY.md)** 📊 - Executive summary - -### API Documentation -- **[API Docs](http://localhost:4000/api/docs)** 📖 - OpenAPI/Swagger (when running) - -## đŸ§Ș Testing - -```bash -# Run all tests -npm run test:all - -# Run backend tests -npm run backend:test - -# Run frontend tests -npm run frontend:test - -# E2E tests (after implementation) -npm run test:e2e -``` - -## 🔒 Security - -- All passwords hashed with bcrypt (12 rounds minimum) -- JWT tokens (access: 15min, refresh: 7 days) -- HTTPS/TLS 1.2+ enforced -- OWASP Top 10 protection -- Rate limiting on all endpoints -- CSRF protection - -## 📊 Tech Stack - -### Backend -- **Framework**: NestJS 10+ -- **Language**: TypeScript 5+ -- **Database**: PostgreSQL 15+ -- **Cache**: Redis 7+ -- **ORM**: TypeORM -- **Testing**: Jest, Supertest -- **API Docs**: Swagger/OpenAPI - -### Frontend -- **Framework**: Next.js 14+ (App Router) -- **Language**: TypeScript 5+ -- **Styling**: Tailwind CSS -- **UI Components**: shadcn/ui -- **State**: React Query (TanStack Query) -- **Forms**: React Hook Form + Zod -- **Testing**: Jest, React Testing Library, Playwright - -## 🚱 Carrier Integrations - -MVP supports the following maritime carriers: - -- ✅ Maersk -- ✅ MSC -- ✅ CMA CGM -- ✅ Hapag-Lloyd -- ✅ ONE (Ocean Network Express) - -## 📈 Monitoring & Logging - -- **Logging**: Winston / Pino -- **Error Tracking**: Sentry -- **APM**: Application Performance Monitoring -- **Metrics**: Prometheus (planned) - -## 🔧 Environment Variables - -See `.env.example` files in each app for required environment variables. - -## đŸ€ Contributing - -1. Create a feature branch -2. Make your changes -3. Write tests -4. Run linting and formatting -5. Submit a pull request - -## 📝 License - -Proprietary - All rights reserved - -## đŸ‘„ Team - -Built with ❀ by the Xpeditis team - --- -For detailed implementation guidelines, see [CLAUDE.md](CLAUDE.md). +## Documentation + +| Sujet | Fichier | +|-------|---------| +| Index complet | [docs/README.md](docs/README.md) | +| Architecture hexagonale + conventions | [CLAUDE.md](CLAUDE.md) | +| Vue d'ensemble systĂšme | [docs/architecture/overview.md](docs/architecture/overview.md) | +| SchĂ©ma BDD (21 tables) | [docs/architecture/database.md](docs/architecture/database.md) | +| DĂ©marrage rapide | [docs/getting-started/quick-start.md](docs/getting-started/quick-start.md) | + +--- + +## Commandes de dĂ©veloppement + +```bash +# Backend +npm run backend:dev # Serveur avec hot-reload +npm run backend:test # Tests unitaires Jest +npm run backend:lint # ESLint +npm run backend:build # Build production + +# Frontend +npm run frontend:dev # Serveur avec hot-reload +npm run frontend:test # Tests unitaires Jest +npm run frontend:lint # ESLint +cd apps/frontend && npm run test:e2e # Playwright E2E + +# QualitĂ© +npm run format # Prettier (tous les fichiers) + +# Base de donnĂ©es +cd apps/backend +npm run migration:generate -- src/infrastructure/persistence/typeorm/migrations/NomMigration +npm run migration:run +npm run migration:revert +``` + +--- + +## Stack technique + +### Backend + +| Composant | Technologie | +|-----------|-------------| +| Framework | NestJS 10 + TypeScript 5 (strict) | +| Base de donnĂ©es | PostgreSQL 15 + TypeORM | +| Cache | Redis 7 (ioredis) | +| Auth | JWT (15min) + Refresh + OAuth2 + API Keys (Argon2) | +| Temps rĂ©el | Socket.IO | +| Email | Nodemailer + MJML | +| Paiements | Stripe | +| Stockage | S3/MinIO | +| Logging | nestjs-pino | +| Monitoring | Sentry | + +### Frontend + +| Composant | Technologie | +|-----------|-------------| +| Framework | Next.js 14 App Router + TypeScript | +| Styling | Tailwind CSS + shadcn/ui (Radix UI) | +| State serveur | TanStack Query v5 | +| Tables | TanStack Table v8 + Virtual | +| Formulaires | react-hook-form + zod | +| Temps rĂ©el | Socket.IO client | +| i18n | next-intl (fr, en) | +| Graphiques | recharts | + +--- + +## Carriers intĂ©grĂ©s + +| Carrier | Code | Statut | +|---------|------|--------| +| Maersk | MAEU | Connecteur API | +| MSC | MSCU | Connecteur API | +| CMA CGM | CMDU | Connecteur API | +| Hapag-Lloyd | HLCU | Connecteur API | +| ONE | ONEY | Connecteur API | +| SSC Consolidation | — | CSV | +| ECU Worldwide | — | CSV + API | +| TCC Logistics | — | CSV | +| NVO Consolidation | — | CSV | + +--- + +## FonctionnalitĂ©s principales + +- **Recherche tarifs** : FCL (carriers API + cache Redis 15min) + LCL CSV +- **RĂ©servation standard** : workflow 4 Ă©tapes, numĂ©ro WCM-YYYY-XXXXXX +- **RĂ©servation CSV + Portail Carrier** : magic link, accept/reject +- **Dashboard** : KPI, graphiques, table interactive virtuelle +- **Auth** : JWT, OAuth2 (Google/Microsoft), API Keys, RBAC (5 rĂŽles) +- **Abonnements** : Stripe (FREE/BRONZE/SILVER/GOLD/PLATINIUM) +- **Notifications** : WebSocket temps rĂ©el + webhooks tiers +- **GDPR** : export/suppression des donnĂ©es utilisateur +- **Blog** : gestion de contenu bilingue (fr/en) +- **Audit** : journal d'audit de toutes les actions + +--- + +*Architecture hexagonale — NestJS 10 + Next.js 14 — PostgreSQL 15 + Redis 7* diff --git a/docs/README.md b/docs/README.md new file mode 100644 index 0000000..157cefe --- /dev/null +++ b/docs/README.md @@ -0,0 +1,105 @@ +# Xpeditis — Documentation + +Documentation complĂšte de la plateforme B2B SaaS de rĂ©servation de fret maritime. + +--- + +## DĂ©marrage rapide + +| Objectif | Fichier | +|---|---| +| DĂ©marrer en 5 minutes | [getting-started/quick-start.md](getting-started/quick-start.md) | +| Installation dĂ©taillĂ©e | [getting-started/installation.md](getting-started/installation.md) | +| Windows | [getting-started/windows.md](getting-started/windows.md) | + +--- + +## Architecture + +| Sujet | Fichier | +|---|---| +| Vue d'ensemble systĂšme | [architecture/overview.md](architecture/overview.md) | +| SchĂ©ma base de donnĂ©es | [architecture/database.md](architecture/database.md) | +| Backend (NestJS hexagonal) | [architecture/backend.md](architecture/backend.md) | +| Frontend (Next.js 14) | [architecture/frontend.md](architecture/frontend.md) | + +--- + +## FonctionnalitĂ©s + +| FonctionnalitĂ© | Fichier | +|---|---| +| Recherche de tarifs (FCL + CSV) | [features/rate-search.md](features/rate-search.md) | +| RĂ©servation standard | [features/bookings.md](features/bookings.md) | +| RĂ©servation CSV + Portail Carrier | [features/csv-bookings.md](features/csv-bookings.md) | +| Authentification & RBAC | [features/auth.md](features/auth.md) | +| Abonnements Stripe | [features/subscriptions.md](features/subscriptions.md) | +| Notifications temps rĂ©el | [features/notifications.md](features/notifications.md) | +| AccĂšs API (clĂ©s API) | [features/api-access.md](features/api-access.md) | +| SystĂšme CSV | [../csv-system/CSV_RATE_SYSTEM.md](../csv-system/CSV_RATE_SYSTEM.md) | + +--- + +## DĂ©ploiement + +| Sujet | Fichier | +|---|---| +| Portainer / Docker Swarm | [deployment/portainer.md](deployment/portainer.md) | +| Hetzner / Kubernetes | [deployment/hetzner/README.md](deployment/hetzner/README.md) | +| Stripe (paiements) | [deployment/STRIPE_SETUP.md](deployment/STRIPE_SETUP.md) | + +--- + +## Tests + +| Sujet | Fichier | +|---|---| +| Guide tests (unitĂ©, intĂ©gration, E2E) | [testing/TEST_EXECUTION_GUIDE.md](testing/TEST_EXECUTION_GUIDE.md) | +| Tests locaux | [testing/LOCAL_TESTING.md](testing/LOCAL_TESTING.md) | +| Tests manuels | [testing/MANUAL_TEST_INSTRUCTIONS.md](testing/MANUAL_TEST_INSTRUCTIONS.md) | +| Postman | [testing/GUIDE_TESTS_POSTMAN.md](testing/GUIDE_TESTS_POSTMAN.md) | +| Couverture | [testing/TEST_COVERAGE_REPORT.md](testing/TEST_COVERAGE_REPORT.md) | + +--- + +## Portail Carrier + +| Sujet | Fichier | +|---|---| +| Recherche API carriers | [carrier-portal/CARRIER_API_RESEARCH.md](carrier-portal/CARRIER_API_RESEARCH.md) | +| Plan d'implĂ©mentation | [carrier-portal/CARRIER_PORTAL_IMPLEMENTATION_PLAN.md](carrier-portal/CARRIER_PORTAL_IMPLEMENTATION_PLAN.md) | + +--- + +## Archives + +Les rapports de sprint et notes de debug sont archivĂ©s dans [archive/](archive/). + +--- + +## Pour les dĂ©veloppeurs + +### Lire dans cet ordre + +1. [getting-started/quick-start.md](getting-started/quick-start.md) — dĂ©marrer le projet +2. `CLAUDE.md` Ă  la racine — **architecture hexagonale, rĂšgles et conventions** +3. [architecture/overview.md](architecture/overview.md) — vision systĂšme +4. [architecture/database.md](architecture/database.md) — schĂ©ma BDD complet + +### Commandes essentielles + +```bash +# Infrastructure +docker-compose up -d + +# DĂ©marrer +npm run backend:dev # http://localhost:4000 — Swagger: /api/docs +npm run frontend:dev # http://localhost:3000 + +# Tests +npm run backend:test +npm run frontend:test + +# Migrations +cd apps/backend && npm run migration:run +``` diff --git a/docs/architecture/backend.md b/docs/architecture/backend.md new file mode 100644 index 0000000..fe02799 --- /dev/null +++ b/docs/architecture/backend.md @@ -0,0 +1,180 @@ +# Architecture Backend — NestJS Hexagonale + +--- + +## Structure des couches + +``` +apps/backend/src/ +├── domain/ # Logique mĂ©tier PURE — aucun import NestJS/TypeORM +│ ├── entities/ # 17 entitĂ©s mĂ©tier (private constructor + static create()) +│ ├── value-objects/ # Objets valeur immuables (Email, Money, BookingNumber...) +│ ├── services/ # Services mĂ©tier purs (csv-rate-price-calculator) +│ ├── exceptions/ # Exceptions domaine +│ └── ports/ +│ ├── in/ # Interfaces use-case (execute()) +│ └── out/ # Interfaces repository/SPI (token constants) +│ +├── application/ # Couche API — dĂ©pend UNIQUEMENT du domain +│ ├── controllers/ # REST controllers (Swagger + class-validator) +│ ├── dto/ # Data Transfer Objects +│ ├── mappers/ # Domain ↔ DTO (mĂ©thodes statiques) +│ ├── guards/ # JwtAuthGuard, RolesGuard, ApiKeyOrJwtGuard +│ ├── decorators/ # @Public(), @Roles(), @CurrentUser() +│ ├── filters/ # DomainExceptionFilter +│ ├── interceptors/ # PerformanceMonitoringInterceptor +│ ├── gateways/ # WebSocket Socket.IO (notifications) +│ ├── services/ # Services applicatifs (audit, notification, export, webhooks) +│ └── [feature]/ # Modules par feature (auth, bookings, rates, etc.) +│ +└── infrastructure/ # Adaptateurs externes — dĂ©pend UNIQUEMENT du domain + ├── persistence/typeorm/ + │ ├── entities/ # ORM entities (*.orm-entity.ts) + │ ├── repositories/# ImplĂ©mentations TypeORM + │ ├── mappers/ # ORM ↔ Domain (static toOrm/toDomain/toDomainMany) + │ └── migrations/ # Migrations TypeORM + ├── carriers/ # 5 connecteurs carriers + CSV loader + ├── cache/ # Adaptateur Redis + ├── email/ # MJML + Nodemailer + ├── storage/ # S3/MinIO (+ csv-storage/) + ├── stripe/ # Paiements et abonnements + ├── external/ # Pappers (SIRET), ECU Worldwide + ├── pdf/ # GĂ©nĂ©ration PDF pdfkit + ├── security/ # Utilitaires sĂ©curitĂ© + └── monitoring/ # Sentry + Pino +``` + +--- + +## EntitĂ©s domaine (17) + +| EntitĂ© | Fichier | +|--------|---------| +| ApiKey | api-key.entity.ts | +| AuditLog | audit-log.entity.ts | +| BlogPost | blog-post.entity.ts | +| Booking | booking.entity.ts | +| Carrier | carrier.entity.ts | +| Container | container.entity.ts | +| CsvBooking | csv-booking.entity.ts | +| CsvRate | csv-rate.entity.ts | +| InvitationToken | invitation-token.entity.ts | +| License | license.entity.ts | +| Notification | notification.entity.ts | +| Organization | organization.entity.ts | +| Port | port.entity.ts | +| RateQuote | rate-quote.entity.ts | +| Subscription | subscription.entity.ts | +| User | user.entity.ts | +| Webhook | webhook.entity.ts | + +--- + +## Pattern entitĂ© domaine + +```typescript +// Private constructor + static create() factory +export class Booking { + private constructor(private readonly props: BookingProps) {} + + static create(props: Omit): Booking { + return new Booking({ + ...props, + bookingNumber: BookingNumber.generate(), + status: BookingStatus.DRAFT, + }); + } + + // Les mutations retournent une nouvelle instance (immuabilitĂ©) + updateStatus(newStatus: BookingStatus): Booking { + return new Booking({ ...this.props, status: newStatus }); + } +} +``` + +--- + +## Pattern repository + +```typescript +// domain/ports/out/booking.repository.ts +export const BOOKING_REPOSITORY = 'BookingRepository'; + +export interface BookingRepository { + findById(id: string): Promise; + save(booking: Booking): Promise; + findByOrganization(orgId: string, filters: BookingFilters): Promise; +} + +// infrastructure/persistence/typeorm/repositories/typeorm-booking.repository.ts +@Injectable() +export class TypeOrmBookingRepository implements BookingRepository { + constructor( + @InjectRepository(BookingOrmEntity) + private readonly repo: Repository, + ) {} + // ... +} +``` + +--- + +## Conventions de nommage + +| Couche | Suffix | Exemple | +|--------|--------|---------| +| Domain entity | .entity.ts | booking.entity.ts | +| Value object | .vo.ts | money.vo.ts | +| In port | .use-case.ts | create-booking.use-case.ts | +| Out port | .repository.ts | booking.repository.ts | +| ORM entity | .orm-entity.ts | booking.orm-entity.ts | +| ORM mapper | .mapper.ts | booking.mapper.ts | +| Controller | .controller.ts | bookings.controller.ts | +| DTO | .dto.ts | create-booking-request.dto.ts | +| App mapper | .mapper.ts | booking.mapper.ts | + +--- + +## RĂšgles critiques + +- **Jamais** d'import NestJS/TypeORM dans `domain/` +- **Jamais** de type `any` dans le backend (strict mode) +- **Jamais** modifier une migration dĂ©jĂ  appliquĂ©e +- **Toujours** valider les DTOs avec class-validator +- **Toujours** crĂ©er un mapper sĂ©parĂ© pour ORM ↔ Domain +- `DATABASE_SYNC` est hard-codĂ© Ă  `false` — utiliser les migrations + +--- + +## Modules NestJS (app.module.ts) + +**Guards globaux** (toutes routes) : +- `JwtAuthGuard` — JWT obligatoire sauf routes `@Public()` +- `CustomThrottlerGuard` — rate limiting + +**Feature modules** : +Auth · Rates · Ports · Bookings · CsvBookings · Organizations · Users · Dashboard · Audit · Notifications · Webhooks · GDPR · Admin · Subscriptions · ApiKeys · Blog · Logs + +**Infrastructure modules** : +CacheModule · CarrierModule · SecurityModule · CsvRateModule · StripeModule · PdfModule · StorageModule · EmailModule + +--- + +## Alias de chemins (tsconfig.json) + +```json +{ + "@domain/*": ["src/domain/*"], + "@application/*": ["src/application/*"], + "@infrastructure/*": ["src/infrastructure/*"] +} +``` + +--- + +## Configuration TypeScript + +- `strict: true` +- `strictNullChecks: true` +- `strictPropertyInitialization: false` (exception pour ORM entities) +- `noImplicitAny: true` diff --git a/docs/architecture/database.md b/docs/architecture/database.md new file mode 100644 index 0000000..e87c5e2 --- /dev/null +++ b/docs/architecture/database.md @@ -0,0 +1,462 @@ +# SchĂ©ma de base de donnĂ©es — Xpeditis + +PostgreSQL 15 — 21 tables. + +**Extensions requises** : `uuid-ossp`, `pg_trgm` + +--- + +## Vue d'ensemble des tables + +| Table | Description | +|-------|-------------| +| organizations | Organisations (transitaires, transporteurs) | +| users | Comptes utilisateurs | +| carriers | Transporteurs maritimes | +| ports | Base de donnĂ©es des ports (UN/LOCODE) | +| rate_quotes | Cotations de tarifs carriers | +| bookings | RĂ©servations standard | +| containers | Conteneurs liĂ©s aux rĂ©servations | +| csv_bookings | RĂ©servations créées via CSV | +| csv_rate_configs | Configuration des carriers CSV | +| carrier_profiles | Profils portail carrier | +| carrier_activities | ActivitĂ©s du portail carrier | +| audit_logs | Journal d'audit des actions | +| notifications | Notifications push (WebSocket) | +| webhooks | Configuration des webhooks tiers | +| subscriptions | Abonnements Stripe | +| licenses | Licences d'utilisation | +| api_keys | ClĂ©s API (auth alternative au JWT) | +| invitation_tokens | Tokens d'invitation utilisateur | +| password_reset_tokens | Tokens de rĂ©initialisation mot de passe | +| cookie_consents | Consentements RGPD cookies | +| blog_posts | Articles de blog | + +--- + +## Tables dĂ©taillĂ©es + +### organizations + +| Colonne | Type | Contraintes | Description | +|---------|------|-------------|-------------| +| id | UUID | PK | Identifiant | +| name | VARCHAR(255) | NOT NULL, UNIQUE | Nom de l'organisation | +| type | VARCHAR(50) | NOT NULL | FREIGHT_FORWARDER, CARRIER, SHIPPER | +| scac | CHAR(4) | UNIQUE, NULLABLE | Standard Carrier Alpha Code | +| address_street | VARCHAR(255) | NOT NULL | Adresse | +| address_city | VARCHAR(100) | NOT NULL | Ville | +| address_state | VARCHAR(100) | NULLABLE | État/Province | +| address_postal_code | VARCHAR(20) | NOT NULL | Code postal | +| address_country | CHAR(2) | NOT NULL | Code pays ISO 3166-1 | +| logo_url | TEXT | NULLABLE | URL du logo | +| documents | JSONB | DEFAULT '[]' | Documents compliance | +| siret | VARCHAR(20) | NULLABLE | SIRET (entreprises françaises) | +| status_badge | VARCHAR(50) | NULLABLE | Badge de statut Pappers | +| is_carrier | BOOLEAN | DEFAULT FALSE | Est un carrier (portail) | +| is_active | BOOLEAN | DEFAULT TRUE | Compte actif | +| created_at | TIMESTAMP | DEFAULT NOW() | CrĂ©ation | +| updated_at | TIMESTAMP | DEFAULT NOW() | Mise Ă  jour | + +--- + +### users + +| Colonne | Type | Contraintes | Description | +|---------|------|-------------|-------------| +| id | UUID | PK | Identifiant | +| organization_id | UUID | FK organizations | Organisation | +| email | VARCHAR(255) | NOT NULL, UNIQUE | Email (minuscules) | +| password_hash | VARCHAR(255) | NOT NULL | Hash Argon2 | +| role | VARCHAR(50) | NOT NULL | ADMIN, MANAGER, USER, VIEWER, CARRIER | +| first_name | VARCHAR(100) | NOT NULL | PrĂ©nom | +| last_name | VARCHAR(100) | NOT NULL | Nom | +| phone_number | VARCHAR(20) | NULLABLE | TĂ©lĂ©phone | +| is_email_verified | BOOLEAN | DEFAULT FALSE | Email vĂ©rifiĂ© | +| is_active | BOOLEAN | DEFAULT TRUE | Compte actif | +| preferred_language | VARCHAR(10) | DEFAULT 'fr' | Langue prĂ©fĂ©rĂ©e (fr, en) | +| last_login_at | TIMESTAMP | NULLABLE | DerniĂšre connexion | +| created_at | TIMESTAMP | DEFAULT NOW() | CrĂ©ation | +| updated_at | TIMESTAMP | DEFAULT NOW() | Mise Ă  jour | + +Index : `idx_users_email`, `idx_users_organization`, `idx_users_role` + +--- + +### carriers + +| Colonne | Type | Contraintes | Description | +|---------|------|-------------|-------------| +| id | UUID | PK | Identifiant | +| name | VARCHAR(255) | NOT NULL | Nom (ex: "Maersk") | +| code | VARCHAR(50) | NOT NULL, UNIQUE | Code (ex: "MAERSK") | +| scac | CHAR(4) | NOT NULL, UNIQUE | Standard Carrier Alpha Code | +| logo_url | TEXT | NULLABLE | URL du logo | +| website | TEXT | NULLABLE | Site web | +| api_config | JSONB | NULLABLE | Config API (credentials, timeout) | +| is_active | BOOLEAN | DEFAULT TRUE | Actif | +| supports_api | BOOLEAN | DEFAULT FALSE | IntĂ©gration API disponible | +| created_at | TIMESTAMP | DEFAULT NOW() | CrĂ©ation | +| updated_at | TIMESTAMP | DEFAULT NOW() | Mise Ă  jour | + +Carriers seedĂ©s : Maersk (MAEU), MSC (MSCU), CMA CGM (CMDU), Hapag-Lloyd (HLCU), ONE (ONEY) + +--- + +### ports + +| Colonne | Type | Contraintes | Description | +|---------|------|-------------|-------------| +| id | UUID | PK | Identifiant | +| code | CHAR(5) | NOT NULL, UNIQUE | UN/LOCODE (ex: "NLRTM") | +| name | VARCHAR(255) | NOT NULL | Nom du port | +| city | VARCHAR(255) | NOT NULL | Ville | +| country | CHAR(2) | NOT NULL | Code pays | +| country_name | VARCHAR(100) | NOT NULL | Nom du pays | +| latitude | DECIMAL(9,6) | NOT NULL | Latitude | +| longitude | DECIMAL(9,6) | NOT NULL | Longitude | +| timezone | VARCHAR(50) | NULLABLE | Fuseau horaire IANA | +| is_active | BOOLEAN | DEFAULT TRUE | Actif | + +Index GIN pour recherche floue : `idx_ports_name_trgm`, `idx_ports_city_trgm` + +--- + +### rate_quotes + +| Colonne | Type | Contraintes | Description | +|---------|------|-------------|-------------| +| id | UUID | PK | Identifiant | +| carrier_id | UUID | FK carriers | Carrier | +| carrier_name | VARCHAR(255) | NOT NULL | Nom carrier (dĂ©normalisĂ©) | +| carrier_code | VARCHAR(50) | NOT NULL | Code carrier (dĂ©normalisĂ©) | +| origin_code | CHAR(5) | NOT NULL | Port d'origine | +| destination_code | CHAR(5) | NOT NULL | Port de destination | +| base_freight | DECIMAL(10,2) | NOT NULL | Fret de base | +| surcharges | JSONB | DEFAULT '[]' | Surcharges (BAF, CAF, etc.) | +| total_amount | DECIMAL(10,2) | NOT NULL | Prix total | +| currency | CHAR(3) | NOT NULL | Devise ISO 4217 | +| container_type | VARCHAR(20) | NOT NULL | Type conteneur (20GP, 40HC, etc.) | +| mode | VARCHAR(10) | NOT NULL | FCL ou LCL | +| etd | TIMESTAMP | NOT NULL | DĂ©part estimĂ© | +| eta | TIMESTAMP | NOT NULL | ArrivĂ©e estimĂ©e | +| transit_days | INTEGER | NOT NULL | Jours de transit | +| route | JSONB | NOT NULL | Escales | +| availability | INTEGER | NOT NULL | DisponibilitĂ© conteneurs | +| valid_until | TIMESTAMP | NOT NULL | Expiration (created_at + 15 min) | + +--- + +### bookings + +| Colonne | Type | Contraintes | Description | +|---------|------|-------------|-------------| +| id | UUID | PK | Identifiant | +| booking_number | VARCHAR(20) | NOT NULL, UNIQUE | Format WCM-YYYY-XXXXXX | +| user_id | UUID | FK users | Utilisateur crĂ©ateur | +| organization_id | UUID | FK organizations | Organisation | +| rate_quote_id | UUID | FK rate_quotes, NULLABLE | Cotation source | +| carrier_id | UUID | FK carriers | Carrier | +| status | VARCHAR(50) | NOT NULL | draft, confirmed, shipped, delivered, cancelled | +| shipper | JSONB | NOT NULL | Infos expĂ©diteur | +| consignee | JSONB | NOT NULL | Infos destinataire | +| cargo | JSONB | NULLABLE | DĂ©tails marchandise | +| notes | TEXT | NULLABLE | Notes internes | +| created_at | TIMESTAMP | DEFAULT NOW() | CrĂ©ation | +| updated_at | TIMESTAMP | DEFAULT NOW() | Mise Ă  jour | + +--- + +### containers + +| Colonne | Type | Contraintes | Description | +|---------|------|-------------|-------------| +| id | UUID | PK | Identifiant | +| booking_id | UUID | FK bookings, NULLABLE | RĂ©servation | +| type | VARCHAR(20) | NOT NULL | 20GP, 40HC, 40RF, etc. | +| category | VARCHAR(20) | NOT NULL | DRY, REEFER, OPEN_TOP, FLAT_RACK, TANK | +| container_number | VARCHAR(11) | NULLABLE, UNIQUE | ISO 6346 | +| seal_number | VARCHAR(50) | NULLABLE | NumĂ©ro de plomb | +| vgm | INTEGER | NULLABLE | Masse Brute VĂ©rifiĂ©e (kg) | +| is_hazmat | BOOLEAN | DEFAULT FALSE | Marchandise dangereuse | +| imo_class | VARCHAR(10) | NULLABLE | Classe IMO | +| cargo_description | TEXT | NULLABLE | Description de la marchandise | + +--- + +### csv_bookings + +| Colonne | Type | Contraintes | Description | +|---------|------|-------------|-------------| +| id | UUID | PK | Identifiant | +| organization_id | UUID | FK organizations | Organisation | +| carrier_id | UUID | FK carriers, NULLABLE | Carrier assignĂ© | +| booking_number | VARCHAR(50) | NOT NULL, UNIQUE | NumĂ©ro de rĂ©servation | +| shipper_name | VARCHAR(255) | NOT NULL | ExpĂ©diteur | +| consignee_name | VARCHAR(255) | NOT NULL | Destinataire | +| origin_port | CHAR(5) | NOT NULL | Port d'origine (UN/LOCODE) | +| destination_port | CHAR(5) | NOT NULL | Port de destination | +| container_type | VARCHAR(20) | NOT NULL | Type conteneur | +| commodity | TEXT | NULLABLE | Marchandise | +| weight_kg | DECIMAL(10,2) | NULLABLE | Poids | +| status | VARCHAR(50) | NOT NULL | pending, accepted, rejected, in_transit, delivered | +| carrier_magic_link_token | VARCHAR(255) | NULLABLE | Token lien magique carrier | +| carrier_magic_link_expires_at | TIMESTAMP | NULLABLE | Expiration du token | +| carrier_password_hash | VARCHAR(255) | NULLABLE | Hash mdp portail carrier | +| notes | TEXT | NULLABLE | Notes | +| documents | JSONB | DEFAULT '[]' | Documents joints | +| created_at | TIMESTAMP | DEFAULT NOW() | CrĂ©ation | +| updated_at | TIMESTAMP | DEFAULT NOW() | Mise Ă  jour | + +--- + +### csv_rate_configs + +| Colonne | Type | Contraintes | Description | +|---------|------|-------------|-------------| +| id | UUID | PK | Identifiant | +| company_name | VARCHAR(255) | NOT NULL, UNIQUE | Nom du carrier CSV | +| csv_file_path | VARCHAR(500) | NOT NULL | Chemin fichier CSV | +| type | VARCHAR(50) | DEFAULT 'CSV_ONLY' | CSV_ONLY ou CSV_AND_API | +| has_api | BOOLEAN | DEFAULT FALSE | A une API | +| api_connector | VARCHAR(100) | NULLABLE | Identifiant du connecteur API | +| is_active | BOOLEAN | DEFAULT TRUE | Actif | +| uploaded_at | TIMESTAMP | NOT NULL | Upload | +| uploaded_by | UUID | FK users, NULLABLE | UploadĂ© par | +| row_count | INTEGER | NULLABLE | Nombre de lignes | + +--- + +### carrier_profiles + +| Colonne | Type | Contraintes | Description | +|---------|------|-------------|-------------| +| id | UUID | PK | Identifiant | +| organization_id | UUID | FK organizations, UNIQUE | Organisation carrier | +| carrier_code | VARCHAR(50) | NOT NULL | Code carrier | +| contact_email | VARCHAR(255) | NOT NULL | Email de contact | +| contact_name | VARCHAR(255) | NULLABLE | Nom du contact | +| is_active | BOOLEAN | DEFAULT TRUE | Actif | +| created_at | TIMESTAMP | DEFAULT NOW() | CrĂ©ation | + +--- + +### carrier_activities + +| Colonne | Type | Contraintes | Description | +|---------|------|-------------|-------------| +| id | UUID | PK | Identifiant | +| carrier_profile_id | UUID | FK carrier_profiles | Profil carrier | +| csv_booking_id | UUID | FK csv_bookings | RĂ©servation CSV | +| action | VARCHAR(50) | NOT NULL | ACCEPTED, REJECTED, VIEWED, DOCUMENT_UPLOADED | +| notes | TEXT | NULLABLE | Notes de l'action | +| created_at | TIMESTAMP | DEFAULT NOW() | CrĂ©ation | + +--- + +### audit_logs + +| Colonne | Type | Contraintes | Description | +|---------|------|-------------|-------------| +| id | UUID | PK | Identifiant | +| user_id | UUID | FK users, NULLABLE | Utilisateur | +| organization_id | UUID | FK organizations, NULLABLE | Organisation | +| action | VARCHAR(100) | NOT NULL | Type d'action (26 types) | +| resource_type | VARCHAR(50) | NULLABLE | Type de ressource | +| resource_id | VARCHAR(255) | NULLABLE | ID de la ressource | +| status | VARCHAR(20) | NOT NULL | SUCCESS, FAILURE, WARNING | +| metadata | JSONB | NULLABLE | DonnĂ©es supplĂ©mentaires | +| ip_address | VARCHAR(45) | NULLABLE | Adresse IP | +| user_agent | TEXT | NULLABLE | User agent | +| created_at | TIMESTAMP | DEFAULT NOW() | CrĂ©ation | + +Index : `idx_audit_logs_user_id`, `idx_audit_logs_action`, `idx_audit_logs_created_at` + +--- + +### notifications + +| Colonne | Type | Contraintes | Description | +|---------|------|-------------|-------------| +| id | UUID | PK | Identifiant | +| user_id | UUID | FK users | Destinataire | +| type | VARCHAR(50) | NOT NULL | BOOKING_CREATED, DOCUMENT_UPLOADED, etc. (9 types) | +| title | VARCHAR(255) | NOT NULL | Titre | +| message | TEXT | NOT NULL | Message | +| data | JSONB | NULLABLE | DonnĂ©es associĂ©es | +| priority | VARCHAR(20) | NOT NULL | LOW, MEDIUM, HIGH, URGENT | +| read | BOOLEAN | DEFAULT FALSE | Lu | +| read_at | TIMESTAMP | NULLABLE | Date de lecture | +| created_at | TIMESTAMP | DEFAULT NOW() | CrĂ©ation | + +--- + +### webhooks + +| Colonne | Type | Contraintes | Description | +|---------|------|-------------|-------------| +| id | UUID | PK | Identifiant | +| organization_id | UUID | FK organizations | Organisation | +| url | TEXT | NOT NULL | URL cible | +| secret | VARCHAR(255) | NOT NULL | Secret HMAC SHA-256 | +| events | JSONB | NOT NULL | ÉvĂ©nements souscrits | +| is_active | BOOLEAN | DEFAULT TRUE | Actif | +| last_triggered_at | TIMESTAMP | NULLABLE | Dernier dĂ©clenchement | +| failure_count | INTEGER | DEFAULT 0 | Compteur d'Ă©checs | +| created_at | TIMESTAMP | DEFAULT NOW() | CrĂ©ation | + +--- + +### subscriptions + +| Colonne | Type | Contraintes | Description | +|---------|------|-------------|-------------| +| id | UUID | PK | Identifiant | +| organization_id | UUID | FK organizations, UNIQUE | Organisation | +| stripe_customer_id | VARCHAR(255) | NULLABLE | ID client Stripe | +| stripe_subscription_id | VARCHAR(255) | NULLABLE | ID abonnement Stripe | +| plan | VARCHAR(50) | NOT NULL | FREE, BRONZE, SILVER, GOLD, PLATINIUM | +| status | VARCHAR(50) | NOT NULL | active, past_due, cancelled, trialing, pending_payment, pending_bank_transfer | +| current_period_start | TIMESTAMP | NULLABLE | DĂ©but de pĂ©riode | +| current_period_end | TIMESTAMP | NULLABLE | Fin de pĂ©riode | +| billing_interval | VARCHAR(20) | NULLABLE | monthly, yearly | +| commission_rate | DECIMAL(5,4) | DEFAULT 0 | Taux de commission Xpeditis | +| created_at | TIMESTAMP | DEFAULT NOW() | CrĂ©ation | +| updated_at | TIMESTAMP | DEFAULT NOW() | Mise Ă  jour | + +--- + +### licenses + +| Colonne | Type | Contraintes | Description | +|---------|------|-------------|-------------| +| id | UUID | PK | Identifiant | +| organization_id | UUID | FK organizations | Organisation | +| feature | VARCHAR(100) | NOT NULL | FonctionnalitĂ© activĂ©e | +| is_active | BOOLEAN | DEFAULT TRUE | Actif | +| valid_until | TIMESTAMP | NULLABLE | Expiration | +| created_at | TIMESTAMP | DEFAULT NOW() | CrĂ©ation | + +--- + +### api_keys + +| Colonne | Type | Contraintes | Description | +|---------|------|-------------|-------------| +| id | UUID | PK | Identifiant | +| organization_id | UUID | FK organizations | Organisation | +| user_id | UUID | FK users | CrĂ©ateur | +| name | VARCHAR(255) | NOT NULL | Nom de la clĂ© | +| key_hash | VARCHAR(255) | NOT NULL | Hash Argon2 de la clĂ© | +| key_prefix | VARCHAR(10) | NOT NULL | PrĂ©fixe visible (ex: xped_) | +| last_used_at | TIMESTAMP | NULLABLE | DerniĂšre utilisation | +| expires_at | TIMESTAMP | NULLABLE | Expiration | +| is_active | BOOLEAN | DEFAULT TRUE | Actif | +| created_at | TIMESTAMP | DEFAULT NOW() | CrĂ©ation | + +--- + +### invitation_tokens + +| Colonne | Type | Contraintes | Description | +|---------|------|-------------|-------------| +| id | UUID | PK | Identifiant | +| organization_id | UUID | FK organizations | Organisation | +| email | VARCHAR(255) | NOT NULL | Email invitĂ© | +| token | VARCHAR(255) | NOT NULL, UNIQUE | Token d'invitation | +| role | VARCHAR(50) | NOT NULL | RĂŽle assignĂ© | +| expires_at | TIMESTAMP | NOT NULL | Expiration (24h) | +| used_at | TIMESTAMP | NULLABLE | UtilisĂ© le | +| created_by | UUID | FK users | CrĂ©ateur | + +--- + +### password_reset_tokens + +| Colonne | Type | Contraintes | Description | +|---------|------|-------------|-------------| +| id | UUID | PK | Identifiant | +| user_id | UUID | FK users | Utilisateur | +| token | VARCHAR(255) | NOT NULL, UNIQUE | Token de rĂ©initialisation | +| expires_at | TIMESTAMP | NOT NULL | Expiration (1h) | +| used_at | TIMESTAMP | NULLABLE | UtilisĂ© le | +| created_at | TIMESTAMP | DEFAULT NOW() | CrĂ©ation | + +--- + +### cookie_consents + +| Colonne | Type | Contraintes | Description | +|---------|------|-------------|-------------| +| id | UUID | PK | Identifiant | +| user_id | UUID | FK users, NULLABLE | Utilisateur (si connectĂ©) | +| session_id | VARCHAR(255) | NULLABLE | Session anonyme | +| analytics | BOOLEAN | NOT NULL | Consentement analytics | +| marketing | BOOLEAN | NOT NULL | Consentement marketing | +| ip_address | VARCHAR(45) | NULLABLE | IP | +| created_at | TIMESTAMP | DEFAULT NOW() | CrĂ©ation | + +--- + +### blog_posts + +| Colonne | Type | Contraintes | Description | +|---------|------|-------------|-------------| +| id | UUID | PK | Identifiant | +| slug | VARCHAR(255) | NOT NULL, UNIQUE | Slug URL | +| title_fr | VARCHAR(500) | NOT NULL | Titre en français | +| title_en | VARCHAR(500) | NULLABLE | Titre en anglais | +| content_fr | TEXT | NOT NULL | Contenu en français | +| content_en | TEXT | NULLABLE | Contenu en anglais | +| excerpt_fr | TEXT | NULLABLE | Extrait français | +| excerpt_en | TEXT | NULLABLE | Extrait anglais | +| cover_image_url | TEXT | NULLABLE | Image de couverture | +| author_id | UUID | FK users | Auteur | +| is_published | BOOLEAN | DEFAULT FALSE | PubliĂ© | +| published_at | TIMESTAMP | NULLABLE | Date de publication | +| tags | JSONB | DEFAULT '[]' | Tags | +| created_at | TIMESTAMP | DEFAULT NOW() | CrĂ©ation | +| updated_at | TIMESTAMP | DEFAULT NOW() | Mise Ă  jour | + +--- + +## Relations principales + +``` +organizations 1──* users +organizations 1──1 subscriptions +organizations 1──* licenses +organizations 1──* api_keys +organizations 1──* webhooks +organizations 1──* bookings +organizations 1──* csv_bookings +organizations 1──1 carrier_profiles + +users 1──* bookings +users 1──* audit_logs +users 1──* notifications +users 1──* api_keys + +bookings 1──* containers +bookings 1──1 rate_quotes (optionnel) + +csv_bookings 1──* carrier_activities (via carrier_profiles) +carrier_profiles 1──* carrier_activities +``` + +--- + +## StratĂ©gie de migrations + +Les migrations sont dans `apps/backend/src/infrastructure/persistence/typeorm/migrations/`. +Ne jamais modifier une migration dĂ©jĂ  appliquĂ©e — crĂ©er une nouvelle migration. + +```bash +cd apps/backend +npm run migration:generate -- src/infrastructure/persistence/typeorm/migrations/NomMigration +npm run migration:run +``` + +--- + +*DerniĂšre mise Ă  jour : Mai 2026 — 21 tables* diff --git a/docs/architecture/frontend.md b/docs/architecture/frontend.md new file mode 100644 index 0000000..3bc378c --- /dev/null +++ b/docs/architecture/frontend.md @@ -0,0 +1,157 @@ +# Architecture Frontend — Next.js 14 + +--- + +## Structure + +``` +apps/frontend/ +├── app/ # Next.js App Router +│ ├── [locale]/ # i18n wrapper (fr, en) — next-intl +│ │ ├── about/ +│ │ ├── blog/ +│ │ ├── booking/ # Flux de rĂ©servation +│ │ ├── careers/ +│ │ ├── carrier/ # Portail carrier (magic link) +│ │ ├── compliance/ +│ │ ├── contact/ +│ │ ├── dashboard/ # Application protĂ©gĂ©e +│ │ │ ├── bookings/ +│ │ │ ├── csv-bookings/ +│ │ │ ├── search/ +│ │ │ ├── settings/ +│ │ │ ├── admin/ +│ │ │ └── wiki/ +│ │ ├── docs/ +│ │ ├── forgot-password/ +│ │ ├── login/ +│ │ ├── pricing/ +│ │ ├── register/ +│ │ ├── reset-password/ +│ │ └── verify-email/ +│ └── api/v1/ # API routes Next.js (proxy) +│ +├── src/ +│ ├── components/ # Composants React +│ │ ├── admin/ +│ │ ├── blog/ +│ │ ├── bookings/ +│ │ ├── docs/ +│ │ ├── layout/ +│ │ ├── organization/ +│ │ ├── rate-search/ +│ │ └── ui/ # Composants shadcn/ui (Radix UI) +│ ├── hooks/ # Custom hooks (TanStack Query) +│ ├── lib/ +│ │ ├── api/ # Client fetch avec auto-refresh JWT +│ │ │ ├── client.ts # get/post/patch/del/upload/download +│ │ │ ├── auth.ts +│ │ │ ├── bookings.ts +│ │ │ ├── rates.ts +│ │ │ └── ... +│ │ ├── context/ # AuthContext, CookieContext +│ │ └── providers/ # QueryProvider (TanStack Query) +│ ├── types/ # Types TypeScript +│ └── utils/ # Export Excel, PDF +│ +├── i18n/ # Config next-intl +├── messages/ +│ ├── fr.json # Traductions français +│ └── en.json # Traductions anglais +└── middleware.ts # Auth + i18n routing +``` + +--- + +## i18n (Internationalisation) + +Le frontend supporte **français** (par dĂ©faut) et **anglais** via `next-intl`. + +Routes : `/fr/login`, `/en/login`, etc. + +```typescript +// i18n/routing.ts +export const routing = defineRouting({ + locales: ['fr', 'en'], + defaultLocale: 'fr', +}); +``` + +Le middleware `middleware.ts` combine la protection d'auth **et** le routing i18n. + +--- + +## Client API + +`src/lib/api/client.ts` — wrapper fetch avec auto-refresh JWT : + +```typescript +// Toutes les requĂȘtes passent par ces fonctions +export const get = (url: string): Promise +export const post = (url: string, body: unknown): Promise +export const patch = (url: string, body: unknown): Promise +export const del = (url: string): Promise +export const upload = (url: string, formData: FormData): Promise +export const download = (url: string): Promise +``` + +- Sur 401 : refresh automatique du token, retry de la requĂȘte +- Tokens : localStorage ET cookie `accessToken` (pour le middleware Next.js) + +--- + +## State management + +- **DonnĂ©es serveur** : TanStack Query v5 (`@tanstack/react-query`) +- **État global UI** : zustand (minimal) +- **Formulaires** : react-hook-form + zod + +```typescript +// Pattern hook standard +export function useBookings(filters?: BookingFilters) { + return useQuery({ + queryKey: ['bookings', filters], + queryFn: () => bookingsApi.list(filters), + }); +} +``` + +--- + +## Protection des routes + +`middleware.ts` vĂ©rifie le cookie `accessToken` avant chaque route. + +**Routes publiques exactes** : `/fr`, `/en`, `/` + +**Routes publiques par prĂ©fixe** : +`/login`, `/register`, `/forgot-password`, `/reset-password`, `/verify-email`, +`/about`, `/blog`, `/pricing`, `/contact`, `/careers`, `/press`, `/security`, +`/privacy`, `/terms`, `/cookies`, `/compliance`, `/carrier` + +Toutes les autres routes → redirection `/login?redirect=` + +--- + +## Design system + +| ÉlĂ©ment | Valeur | +|---------|--------| +| Couleur primaire | Navy `#10183A` | +| Couleur accent | Turquoise `#34CCCD` | +| SuccĂšs | Green `#067224` | +| Fond neutre | Gray `#F2F2F2` | +| Font headings | Manrope | +| Font body | Montserrat | +| UI components | shadcn/ui (Radix UI) | +| IcĂŽnes | lucide-react | + +--- + +## Conventions + +- Pas de fetch direct — toujours via `src/lib/api/*.ts` +- Les hooks wrappent TanStack Query, pas de `useEffect` pour les donnĂ©es +- `strict: false` en frontend (contrairement au backend) +- Alias `@/*` → `./src/*` +- La landing page est en **français** diff --git a/docs/architecture/overview.md b/docs/architecture/overview.md new file mode 100644 index 0000000..7b3785c --- /dev/null +++ b/docs/architecture/overview.md @@ -0,0 +1,215 @@ +# 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* diff --git a/docs/archive/README.md b/docs/archive/README.md new file mode 100644 index 0000000..c339441 --- /dev/null +++ b/docs/archive/README.md @@ -0,0 +1,16 @@ +# Archives + +Ce dossier contient les documents historiques qui ne sont plus actifs mais conservĂ©s pour rĂ©fĂ©rence. + +## Contenu + +| Dossier | Description | +|---------|-------------| +| phases/ | Rapports de sprint (Sprint 0, Phase 1-4) — projet terminĂ© | +| debug/ | Notes de debugging rĂ©solues | +| installation/ | Anciens guides d'installation (remplacĂ©s par docs/getting-started/) | +| portainer/ | 24 fichiers de debug/fix Portainer — consolidĂ©s dans docs/deployment/portainer.md | + +## Note + +La documentation active et Ă  jour se trouve dans [../](../README.md). diff --git a/docs/architecture/ARCHITECTURE.md b/docs/archive/architecture/ARCHITECTURE.md similarity index 100% rename from docs/architecture/ARCHITECTURE.md rename to docs/archive/architecture/ARCHITECTURE.md diff --git a/docs/architecture/BOOKING_WORKFLOW_TODO.md b/docs/archive/architecture/BOOKING_WORKFLOW_TODO.md similarity index 100% rename from docs/architecture/BOOKING_WORKFLOW_TODO.md rename to docs/archive/architecture/BOOKING_WORKFLOW_TODO.md diff --git a/docs/architecture/DASHBOARD_API_INTEGRATION.md b/docs/archive/architecture/DASHBOARD_API_INTEGRATION.md similarity index 100% rename from docs/architecture/DASHBOARD_API_INTEGRATION.md rename to docs/archive/architecture/DASHBOARD_API_INTEGRATION.md diff --git a/docs/architecture/DISCORD_NOTIFICATIONS.md b/docs/archive/architecture/DISCORD_NOTIFICATIONS.md similarity index 100% rename from docs/architecture/DISCORD_NOTIFICATIONS.md rename to docs/archive/architecture/DISCORD_NOTIFICATIONS.md diff --git a/docs/architecture/EMAIL_IMPLEMENTATION_STATUS.md b/docs/archive/architecture/EMAIL_IMPLEMENTATION_STATUS.md similarity index 100% rename from docs/architecture/EMAIL_IMPLEMENTATION_STATUS.md rename to docs/archive/architecture/EMAIL_IMPLEMENTATION_STATUS.md diff --git a/docs/architecture/RESUME_FRANCAIS.md b/docs/archive/architecture/RESUME_FRANCAIS.md similarity index 100% rename from docs/architecture/RESUME_FRANCAIS.md rename to docs/archive/architecture/RESUME_FRANCAIS.md diff --git a/docs/backend/DATABASE-SCHEMA.md b/docs/archive/backend/DATABASE-SCHEMA.md similarity index 100% rename from docs/backend/DATABASE-SCHEMA.md rename to docs/archive/backend/DATABASE-SCHEMA.md diff --git a/docs/debug/NOTIFICATION_IMPROVEMENTS.md b/docs/archive/debug/NOTIFICATION_IMPROVEMENTS.md similarity index 100% rename from docs/debug/NOTIFICATION_IMPROVEMENTS.md rename to docs/archive/debug/NOTIFICATION_IMPROVEMENTS.md diff --git a/docs/debug/USER_DISPLAY_SOLUTION.md b/docs/archive/debug/USER_DISPLAY_SOLUTION.md similarity index 100% rename from docs/debug/USER_DISPLAY_SOLUTION.md rename to docs/archive/debug/USER_DISPLAY_SOLUTION.md diff --git a/docs/debug/USER_INFO_DEBUG_ANALYSIS.md b/docs/archive/debug/USER_INFO_DEBUG_ANALYSIS.md similarity index 100% rename from docs/debug/USER_INFO_DEBUG_ANALYSIS.md rename to docs/archive/debug/USER_INFO_DEBUG_ANALYSIS.md diff --git a/docs/installation/INSTALLATION-COMPLETE.md b/docs/archive/installation/INSTALLATION-COMPLETE.md similarity index 100% rename from docs/installation/INSTALLATION-COMPLETE.md rename to docs/archive/installation/INSTALLATION-COMPLETE.md diff --git a/docs/installation/QUICK-START.md b/docs/archive/installation/QUICK-START.md similarity index 100% rename from docs/installation/QUICK-START.md rename to docs/archive/installation/QUICK-START.md diff --git a/docs/installation/START-HERE.md b/docs/archive/installation/START-HERE.md similarity index 100% rename from docs/installation/START-HERE.md rename to docs/archive/installation/START-HERE.md diff --git a/docs/phases/CHANGES_SUMMARY.md b/docs/archive/phases/CHANGES_SUMMARY.md similarity index 100% rename from docs/phases/CHANGES_SUMMARY.md rename to docs/archive/phases/CHANGES_SUMMARY.md diff --git a/docs/phases/COMPLETION-REPORT.md b/docs/archive/phases/COMPLETION-REPORT.md similarity index 100% rename from docs/phases/COMPLETION-REPORT.md rename to docs/archive/phases/COMPLETION-REPORT.md diff --git a/docs/phases/IMPLEMENTATION_COMPLETE.md b/docs/archive/phases/IMPLEMENTATION_COMPLETE.md similarity index 100% rename from docs/phases/IMPLEMENTATION_COMPLETE.md rename to docs/archive/phases/IMPLEMENTATION_COMPLETE.md diff --git a/docs/phases/IMPLEMENTATION_SUMMARY.md b/docs/archive/phases/IMPLEMENTATION_SUMMARY.md similarity index 100% rename from docs/phases/IMPLEMENTATION_SUMMARY.md rename to docs/archive/phases/IMPLEMENTATION_SUMMARY.md diff --git a/docs/phases/INDEX.md b/docs/archive/phases/INDEX.md similarity index 100% rename from docs/phases/INDEX.md rename to docs/archive/phases/INDEX.md diff --git a/docs/phases/NEXT-STEPS.md b/docs/archive/phases/NEXT-STEPS.md similarity index 100% rename from docs/phases/NEXT-STEPS.md rename to docs/archive/phases/NEXT-STEPS.md diff --git a/docs/phases/PHASE-1-PROGRESS.md b/docs/archive/phases/PHASE-1-PROGRESS.md similarity index 100% rename from docs/phases/PHASE-1-PROGRESS.md rename to docs/archive/phases/PHASE-1-PROGRESS.md diff --git a/docs/phases/PHASE-1-WEEK5-COMPLETE.md b/docs/archive/phases/PHASE-1-WEEK5-COMPLETE.md similarity index 100% rename from docs/phases/PHASE-1-WEEK5-COMPLETE.md rename to docs/archive/phases/PHASE-1-WEEK5-COMPLETE.md diff --git a/docs/phases/PHASE2_AUTHENTICATION_SUMMARY.md b/docs/archive/phases/PHASE2_AUTHENTICATION_SUMMARY.md similarity index 100% rename from docs/phases/PHASE2_AUTHENTICATION_SUMMARY.md rename to docs/archive/phases/PHASE2_AUTHENTICATION_SUMMARY.md diff --git a/docs/phases/PHASE2_BACKEND_COMPLETE.md b/docs/archive/phases/PHASE2_BACKEND_COMPLETE.md similarity index 100% rename from docs/phases/PHASE2_BACKEND_COMPLETE.md rename to docs/archive/phases/PHASE2_BACKEND_COMPLETE.md diff --git a/docs/phases/PHASE2_COMPLETE.md b/docs/archive/phases/PHASE2_COMPLETE.md similarity index 100% rename from docs/phases/PHASE2_COMPLETE.md rename to docs/archive/phases/PHASE2_COMPLETE.md diff --git a/docs/phases/PHASE2_COMPLETE_FINAL.md b/docs/archive/phases/PHASE2_COMPLETE_FINAL.md similarity index 100% rename from docs/phases/PHASE2_COMPLETE_FINAL.md rename to docs/archive/phases/PHASE2_COMPLETE_FINAL.md diff --git a/docs/phases/PHASE2_FINAL_PAGES.md b/docs/archive/phases/PHASE2_FINAL_PAGES.md similarity index 100% rename from docs/phases/PHASE2_FINAL_PAGES.md rename to docs/archive/phases/PHASE2_FINAL_PAGES.md diff --git a/docs/phases/PHASE2_FRONTEND_PROGRESS.md b/docs/archive/phases/PHASE2_FRONTEND_PROGRESS.md similarity index 100% rename from docs/phases/PHASE2_FRONTEND_PROGRESS.md rename to docs/archive/phases/PHASE2_FRONTEND_PROGRESS.md diff --git a/docs/phases/PHASE3_COMPLETE.md b/docs/archive/phases/PHASE3_COMPLETE.md similarity index 100% rename from docs/phases/PHASE3_COMPLETE.md rename to docs/archive/phases/PHASE3_COMPLETE.md diff --git a/docs/phases/PHASE4_REMAINING_TASKS.md b/docs/archive/phases/PHASE4_REMAINING_TASKS.md similarity index 100% rename from docs/phases/PHASE4_REMAINING_TASKS.md rename to docs/archive/phases/PHASE4_REMAINING_TASKS.md diff --git a/docs/phases/PHASE4_SUMMARY.md b/docs/archive/phases/PHASE4_SUMMARY.md similarity index 100% rename from docs/phases/PHASE4_SUMMARY.md rename to docs/archive/phases/PHASE4_SUMMARY.md diff --git a/docs/phases/PRD.md b/docs/archive/phases/PRD.md similarity index 100% rename from docs/phases/PRD.md rename to docs/archive/phases/PRD.md diff --git a/docs/phases/PROGRESS.md b/docs/archive/phases/PROGRESS.md similarity index 100% rename from docs/phases/PROGRESS.md rename to docs/archive/phases/PROGRESS.md diff --git a/docs/phases/READY.md b/docs/archive/phases/READY.md similarity index 100% rename from docs/phases/READY.md rename to docs/archive/phases/READY.md diff --git a/docs/phases/READY_FOR_TESTING.md b/docs/archive/phases/READY_FOR_TESTING.md similarity index 100% rename from docs/phases/READY_FOR_TESTING.md rename to docs/archive/phases/READY_FOR_TESTING.md diff --git a/docs/phases/SESSION_SUMMARY.md b/docs/archive/phases/SESSION_SUMMARY.md similarity index 100% rename from docs/phases/SESSION_SUMMARY.md rename to docs/archive/phases/SESSION_SUMMARY.md diff --git a/docs/phases/SPRINT-0-COMPLETE.md b/docs/archive/phases/SPRINT-0-COMPLETE.md similarity index 100% rename from docs/phases/SPRINT-0-COMPLETE.md rename to docs/archive/phases/SPRINT-0-COMPLETE.md diff --git a/docs/phases/SPRINT-0-FINAL.md b/docs/archive/phases/SPRINT-0-FINAL.md similarity index 100% rename from docs/phases/SPRINT-0-FINAL.md rename to docs/archive/phases/SPRINT-0-FINAL.md diff --git a/docs/phases/SPRINT-0-SUMMARY.md b/docs/archive/phases/SPRINT-0-SUMMARY.md similarity index 100% rename from docs/phases/SPRINT-0-SUMMARY.md rename to docs/archive/phases/SPRINT-0-SUMMARY.md diff --git a/docs/phases/START-HERE.md b/docs/archive/phases/START-HERE.md similarity index 100% rename from docs/phases/START-HERE.md rename to docs/archive/phases/START-HERE.md diff --git a/docs/phases/TODO.md b/docs/archive/phases/TODO.md similarity index 100% rename from docs/phases/TODO.md rename to docs/archive/phases/TODO.md diff --git a/docs/installation/WINDOWS-INSTALLATION.md b/docs/archive/phases/WINDOWS-INSTALLATION.md similarity index 100% rename from docs/installation/WINDOWS-INSTALLATION.md rename to docs/archive/phases/WINDOWS-INSTALLATION.md diff --git a/docs/deployment/portainer/ARM64_SUPPORT.md b/docs/archive/portainer/ARM64_SUPPORT.md similarity index 100% rename from docs/deployment/portainer/ARM64_SUPPORT.md rename to docs/archive/portainer/ARM64_SUPPORT.md diff --git a/docs/deployment/portainer/AWS_COSTS_KUBERNETES.md b/docs/archive/portainer/AWS_COSTS_KUBERNETES.md similarity index 100% rename from docs/deployment/portainer/AWS_COSTS_KUBERNETES.md rename to docs/archive/portainer/AWS_COSTS_KUBERNETES.md diff --git a/docs/deployment/portainer/CICD_REGISTRY_SETUP.md b/docs/archive/portainer/CICD_REGISTRY_SETUP.md similarity index 100% rename from docs/deployment/portainer/CICD_REGISTRY_SETUP.md rename to docs/archive/portainer/CICD_REGISTRY_SETUP.md diff --git a/docs/deployment/portainer/CI_CD_MULTI_ENV.md b/docs/archive/portainer/CI_CD_MULTI_ENV.md similarity index 100% rename from docs/deployment/portainer/CI_CD_MULTI_ENV.md rename to docs/archive/portainer/CI_CD_MULTI_ENV.md diff --git a/docs/deployment/portainer/CLOUD_COST_COMPARISON.md b/docs/archive/portainer/CLOUD_COST_COMPARISON.md similarity index 100% rename from docs/deployment/portainer/CLOUD_COST_COMPARISON.md rename to docs/archive/portainer/CLOUD_COST_COMPARISON.md diff --git a/docs/deployment/portainer/DEPLOYMENT.md b/docs/archive/portainer/DEPLOYMENT.md similarity index 100% rename from docs/deployment/portainer/DEPLOYMENT.md rename to docs/archive/portainer/DEPLOYMENT.md diff --git a/docs/deployment/portainer/DEPLOYMENT_CHECKLIST.md b/docs/archive/portainer/DEPLOYMENT_CHECKLIST.md similarity index 100% rename from docs/deployment/portainer/DEPLOYMENT_CHECKLIST.md rename to docs/archive/portainer/DEPLOYMENT_CHECKLIST.md diff --git a/docs/deployment/portainer/DEPLOYMENT_FIX.md b/docs/archive/portainer/DEPLOYMENT_FIX.md similarity index 100% rename from docs/deployment/portainer/DEPLOYMENT_FIX.md rename to docs/archive/portainer/DEPLOYMENT_FIX.md diff --git a/docs/deployment/portainer/DEPLOYMENT_READY.md b/docs/archive/portainer/DEPLOYMENT_READY.md similarity index 100% rename from docs/deployment/portainer/DEPLOYMENT_READY.md rename to docs/archive/portainer/DEPLOYMENT_READY.md diff --git a/docs/deployment/portainer/DEPLOY_README.md b/docs/archive/portainer/DEPLOY_README.md similarity index 100% rename from docs/deployment/portainer/DEPLOY_README.md rename to docs/archive/portainer/DEPLOY_README.md diff --git a/docs/deployment/portainer/DOCKER_ARM64_FIX.md b/docs/archive/portainer/DOCKER_ARM64_FIX.md similarity index 100% rename from docs/deployment/portainer/DOCKER_ARM64_FIX.md rename to docs/archive/portainer/DOCKER_ARM64_FIX.md diff --git a/docs/deployment/portainer/DOCKER_CSS_FIX.md b/docs/archive/portainer/DOCKER_CSS_FIX.md similarity index 100% rename from docs/deployment/portainer/DOCKER_CSS_FIX.md rename to docs/archive/portainer/DOCKER_CSS_FIX.md diff --git a/docs/deployment/portainer/DOCKER_FIXES_SUMMARY.md b/docs/archive/portainer/DOCKER_FIXES_SUMMARY.md similarity index 100% rename from docs/deployment/portainer/DOCKER_FIXES_SUMMARY.md rename to docs/archive/portainer/DOCKER_FIXES_SUMMARY.md diff --git a/docs/deployment/portainer/FIX_404_SWARM.md b/docs/archive/portainer/FIX_404_SWARM.md similarity index 100% rename from docs/deployment/portainer/FIX_404_SWARM.md rename to docs/archive/portainer/FIX_404_SWARM.md diff --git a/docs/deployment/portainer/FIX_DOCKER_PROXY.md b/docs/archive/portainer/FIX_DOCKER_PROXY.md similarity index 100% rename from docs/deployment/portainer/FIX_DOCKER_PROXY.md rename to docs/archive/portainer/FIX_DOCKER_PROXY.md diff --git a/docs/deployment/portainer/PORTAINER_CHECKLIST.md b/docs/archive/portainer/PORTAINER_CHECKLIST.md similarity index 100% rename from docs/deployment/portainer/PORTAINER_CHECKLIST.md rename to docs/archive/portainer/PORTAINER_CHECKLIST.md diff --git a/docs/deployment/portainer/PORTAINER_CRASH_DEBUG.md b/docs/archive/portainer/PORTAINER_CRASH_DEBUG.md similarity index 100% rename from docs/deployment/portainer/PORTAINER_CRASH_DEBUG.md rename to docs/archive/portainer/PORTAINER_CRASH_DEBUG.md diff --git a/docs/deployment/portainer/PORTAINER_DEBUG.md b/docs/archive/portainer/PORTAINER_DEBUG.md similarity index 100% rename from docs/deployment/portainer/PORTAINER_DEBUG.md rename to docs/archive/portainer/PORTAINER_DEBUG.md diff --git a/docs/deployment/portainer/PORTAINER_DEBUG_COMMANDS.md b/docs/archive/portainer/PORTAINER_DEBUG_COMMANDS.md similarity index 100% rename from docs/deployment/portainer/PORTAINER_DEBUG_COMMANDS.md rename to docs/archive/portainer/PORTAINER_DEBUG_COMMANDS.md diff --git a/docs/deployment/portainer/PORTAINER_DEPLOY_FINAL.md b/docs/archive/portainer/PORTAINER_DEPLOY_FINAL.md similarity index 100% rename from docs/deployment/portainer/PORTAINER_DEPLOY_FINAL.md rename to docs/archive/portainer/PORTAINER_DEPLOY_FINAL.md diff --git a/docs/deployment/portainer/PORTAINER_ENV_FIX.md b/docs/archive/portainer/PORTAINER_ENV_FIX.md similarity index 100% rename from docs/deployment/portainer/PORTAINER_ENV_FIX.md rename to docs/archive/portainer/PORTAINER_ENV_FIX.md diff --git a/docs/deployment/portainer/PORTAINER_FIX_QUICK.md b/docs/archive/portainer/PORTAINER_FIX_QUICK.md similarity index 100% rename from docs/deployment/portainer/PORTAINER_FIX_QUICK.md rename to docs/archive/portainer/PORTAINER_FIX_QUICK.md diff --git a/docs/deployment/portainer/PORTAINER_MIGRATION_AUTO.md b/docs/archive/portainer/PORTAINER_MIGRATION_AUTO.md similarity index 100% rename from docs/deployment/portainer/PORTAINER_MIGRATION_AUTO.md rename to docs/archive/portainer/PORTAINER_MIGRATION_AUTO.md diff --git a/docs/deployment/portainer/PORTAINER_REGISTRY_NAMING.md b/docs/archive/portainer/PORTAINER_REGISTRY_NAMING.md similarity index 100% rename from docs/deployment/portainer/PORTAINER_REGISTRY_NAMING.md rename to docs/archive/portainer/PORTAINER_REGISTRY_NAMING.md diff --git a/docs/deployment/portainer/PORTAINER_TRAEFIK_404.md b/docs/archive/portainer/PORTAINER_TRAEFIK_404.md similarity index 100% rename from docs/deployment/portainer/PORTAINER_TRAEFIK_404.md rename to docs/archive/portainer/PORTAINER_TRAEFIK_404.md diff --git a/docs/deployment/portainer/PORTAINER_YAML_FIX.md b/docs/archive/portainer/PORTAINER_YAML_FIX.md similarity index 100% rename from docs/deployment/portainer/PORTAINER_YAML_FIX.md rename to docs/archive/portainer/PORTAINER_YAML_FIX.md diff --git a/docs/deployment/portainer/REGISTRY_PUSH_GUIDE.md b/docs/archive/portainer/REGISTRY_PUSH_GUIDE.md similarity index 100% rename from docs/deployment/portainer/REGISTRY_PUSH_GUIDE.md rename to docs/archive/portainer/REGISTRY_PUSH_GUIDE.md diff --git a/docs/deployment/portainer.md b/docs/deployment/portainer.md new file mode 100644 index 0000000..4d038cb --- /dev/null +++ b/docs/deployment/portainer.md @@ -0,0 +1,248 @@ +# DĂ©ploiement Portainer / Docker Swarm + +Guide de dĂ©ploiement de Xpeditis sur Portainer avec Docker Swarm. + +--- + +## Infrastructure + +| Composant | Image | Registry | +|-----------|-------|----------| +| Backend NestJS | xpeditis-backend | rg.fr-par.scw.cloud/weworkstudio | +| Frontend Next.js | xpeditis-frontend | rg.fr-par.scw.cloud/weworkstudio | +| PostgreSQL 15 | postgres:15-alpine | Docker Hub | +| Redis 7 | redis:7-alpine | Docker Hub | +| MinIO | minio/minio | Docker Hub | + +**Registry** : Scaleway Container Registry (fr-par) +**Portainer** : https://portainer.weworkstudio.com + +--- + +## PrĂ©requis + +### 1. Configurer le registry Scaleway dans Portainer + +**Portainer → Registries → Add registry** : +- Registry URL : `rg.fr-par.scw.cloud/weworkstudio` +- Username : `nologin` +- Password : token Scaleway (Console → Registry → Push/Pull credentials) + +### 2. CrĂ©er le rĂ©seau Traefik + +```bash +docker network create traefik_network +``` + +### 3. VĂ©rifier que les images existent + +```bash +docker manifest inspect rg.fr-par.scw.cloud/weworkstudio/xpeditis-backend:preprod +docker manifest inspect rg.fr-par.scw.cloud/weworkstudio/xpeditis-frontend:preprod +``` + +--- + +## Build et push des images + +### Script de dĂ©ploiement complet + +```bash +# Build et push backend (supporte AMD64 + ARM64) +cd apps/backend +docker buildx build \ + --platform linux/amd64,linux/arm64 \ + -t rg.fr-par.scw.cloud/weworkstudio/xpeditis-backend:preprod \ + --push . + +# Build et push frontend +cd ../frontend +docker buildx build \ + --platform linux/amd64,linux/arm64 \ + -t rg.fr-par.scw.cloud/weworkstudio/xpeditis-frontend:preprod \ + --push . +``` + +> Pour ARM64 seul (serveur Hetzner CAX) : `--platform linux/arm64` + +--- + +## DĂ©ploiement dans Portainer + +1. **Portainer → Stacks → Add stack** +2. **Name** : `xpeditis-preprod` +3. **Build method** : Web editor +4. Coller le contenu de `docker/portainer-stack.yml` +5. DĂ©finir les variables d'environnement (voir section suivante) +6. **Deploy the stack** + +--- + +## Variables d'environnement production + +### Backend + +```bash +NODE_ENV=production +PORT=4000 +API_PREFIX=api/v1 +FRONTEND_URL=https://app.xpeditis.com + +# Base de donnĂ©es +DATABASE_HOST=xpeditis-db +DATABASE_PORT=5432 +DATABASE_USER=xpeditis +DATABASE_PASSWORD=CHANGER_EN_PROD +DATABASE_NAME=xpeditis_prod +DATABASE_SYNC=false +DATABASE_LOGGING=false + +# Redis +REDIS_HOST=xpeditis-redis +REDIS_PORT=6379 +REDIS_PASSWORD=CHANGER_EN_PROD + +# JWT +JWT_SECRET=MINIMUM_32_CARACTERES_ALEATOIRES +JWT_ACCESS_EXPIRATION=15m +JWT_REFRESH_EXPIRATION=7d + +# Email +SMTP_HOST=smtp-relay.brevo.com +SMTP_PORT=587 +SMTP_USER= +SMTP_PASS= +SMTP_FROM=noreply@xpeditis.com + +# Storage (MinIO en prod ou S3) +AWS_ACCESS_KEY_ID=minioadmin +AWS_SECRET_ACCESS_KEY=minioadmin +AWS_REGION=us-east-1 +AWS_S3_ENDPOINT=http://xpeditis-minio:9000 + +# Swagger +SWAGGER_USERNAME=admin +SWAGGER_PASSWORD=CHANGER_EN_PROD + +# Stripe +STRIPE_SECRET_KEY=sk_live_xxxx +STRIPE_WEBHOOK_SECRET=whsec_xxxx +STRIPE_SILVER_MONTHLY_PRICE_ID=price_xxxx +# ... autres price IDs + +# Monitoring +SENTRY_DSN= +``` + +### Frontend + +```bash +NEXT_PUBLIC_API_URL=https://api.xpeditis.com +``` + +--- + +## Migrations automatiques + +Le backend exĂ©cute les migrations automatiquement au dĂ©marrage via le script `docker-entrypoint.sh` : + +```bash +# apps/backend/docker-entrypoint.sh attend PostgreSQL puis : +npm run migration:run +node dist/main.js +``` + +Les logs Portainer affichent : +``` +✅ PostgreSQL is ready +✅ Successfully ran N migration(s) +🚀 Xpeditis API Server Running +``` + +--- + +## VĂ©rifier le dĂ©ploiement + +```bash +# Depuis Portainer → Containers → xpeditis-backend → Logs +# Ou en SSH sur le serveur : +docker logs xpeditis-backend --tail 50 -f + +# Tester les endpoints +curl https://api.xpeditis.com/api/v1/health +# → {"status":"ok"} + +curl https://app.xpeditis.com +# → 200 OK +``` + +--- + +## ProblĂšmes courants + +### CSS manquant en production (Next.js) + +VĂ©rifier que la variable `NEXT_PUBLIC_API_URL` est dĂ©finie **au moment du build** (pas au runtime). +Solution : passer la variable en ARG dans le Dockerfile frontend ou utiliser `--build-arg`. + +### 404 sur routes Next.js + +Le frontend Next.js est configurĂ© en mode `standalone`. VĂ©rifier que le serveur pointe bien sur `server.js` et non sur un fichier statique. + +Si Traefik retourne 404 : +```yaml +# Dans portainer-stack.yml, vĂ©rifier le label Traefik : +traefik.http.routers.frontend.rule=Host(`app.xpeditis.com`) +traefik.http.services.frontend.loadbalancer.server.port=3000 +``` + +### Migrations Ă©chouent + +```bash +docker exec -it xpeditis-backend sh +cd /app && npm run migration:run +``` + +Si blocage : vĂ©rifier que PostgreSQL est accessible (`DATABASE_HOST` = nom du service Docker). + +### Registry pull Ă©choue (401) + +1. VĂ©rifier le token Scaleway (peut expirer) +2. Portainer → Registries → rafraĂźchir les credentials +3. `docker login rg.fr-par.scw.cloud/weworkstudio` + +### ARM64 / multi-architecture + +Les Dockerfiles sont compatibles AMD64 et ARM64. Si le build Ă©choue sur ARM64 : +- VĂ©rifier que `buildx` est installĂ© et activĂ© +- Utiliser le builder multi-platform : `docker buildx create --use` + +--- + +## CI/CD GitHub Actions + +Le workflow `.github/workflows/ci.yml` exĂ©cute en automatique : +1. Lint + type-check +2. Tests unitaires (backend + frontend) +3. Build des images Docker +4. Push vers registry Scaleway (sur merge vers `main` ou `preprod`) + +Variables GitHub Actions requises (Settings → Secrets) : +``` +SCALEWAY_REGISTRY_TOKEN +PORTAINER_URL +PORTAINER_API_KEY +PORTAINER_STACK_ID +``` + +--- + +## CoĂ»ts d'infrastructure estimĂ©s + +| Option | CoĂ»t/mois | Notes | +|--------|-----------|-------| +| Hetzner CAX21 (ARM64) | ~8€ | RecommandĂ© pour preprod | +| Hetzner CX31 (AMD64) | ~12€ | Production | +| Scaleway Registry | Gratuit | Jusqu'Ă  1GB | + +Voir [../deployment/hetzner/README.md](hetzner/README.md) pour le dĂ©ploiement Kubernetes sur Hetzner. diff --git a/docs/features/api-access.md b/docs/features/api-access.md new file mode 100644 index 0000000..bc2ff84 --- /dev/null +++ b/docs/features/api-access.md @@ -0,0 +1,71 @@ +# AccĂšs API via clĂ©s API + +--- + +## Vue d'ensemble + +En plus du JWT, Xpeditis supporte l'authentification par **clĂ© API** pour les intĂ©grations tierces. + +--- + +## Format + +``` +Header: x-api-key: xped_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +``` + +Le prĂ©fixe `xped_` est toujours visible. Le reste est une chaĂźne alĂ©atoire sĂ©curisĂ©e. +La clĂ© complĂšte est hashĂ©e avec Argon2 — impossible de la retrouver aprĂšs crĂ©ation. + +--- + +## Gestion des clĂ©s + +| MĂ©thode | Route | Description | +|---------|-------|-------------| +| GET | /api/v1/api-keys | Liste les clĂ©s de l'organisation | +| POST | /api/v1/api-keys | CrĂ©er une nouvelle clĂ© | +| PATCH | /api/v1/api-keys/:id | Renommer / dĂ©sactiver | +| DELETE | /api/v1/api-keys/:id | Supprimer | + +### CrĂ©er une clĂ© + +``` +POST /api/v1/api-keys +Authorization: Bearer + +{ "name": "Integration ERP" } +``` + +RĂ©ponse (unique — la clĂ© complĂšte n'est retournĂ©e qu'une seule fois) : +```json +{ + "id": "uuid", + "name": "Integration ERP", + "key": "xped_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + "keyPrefix": "xped_xxxx", + "createdAt": "2026-05-13T10:00:00Z" +} +``` + +--- + +## Permissions + +Les clĂ©s API hĂ©ritent des permissions de l'organisation. Elles ne peuvent pas avoir plus de droits que le compte utilisateur qui les a créées. + +--- + +## SĂ©curitĂ© + +- Stockage : hash Argon2 uniquement (pas de rĂ©cupĂ©ration possible) +- Expiration : configurable (`expires_at`, null = pas d'expiration) +- RĂ©vocation immĂ©diate : `DELETE /api/v1/api-keys/:id` +- Suivi : `last_used_at` mis Ă  jour Ă  chaque utilisation + +--- + +## Endpoints supportant les clĂ©s API + +Tous les endpoints protĂ©gĂ©s acceptent soit un JWT soit une clĂ© API. +Voir `apps/backend/src/application/guards/api-key-or-jwt.guard.ts` pour l'implĂ©mentation. diff --git a/docs/features/auth.md b/docs/features/auth.md new file mode 100644 index 0000000..d869b07 --- /dev/null +++ b/docs/features/auth.md @@ -0,0 +1,140 @@ +# Authentification & Autorisation + +--- + +## MĂ©canismes d'authentification + +### 1. JWT (principal) + +- **Access token** : 15 minutes, signĂ© avec `JWT_SECRET` +- **Refresh token** : 7 jours, rotation automatique +- **Stockage frontend** : localStorage + cookie `accessToken` (pour le middleware Next.js) + +#### Flow login + +``` +POST /api/v1/auth/login + { email, password } + → VĂ©rification hash Argon2 + → Brute-force check (3 Ă©checs → backoff exponentiel) + → Retourne { accessToken, refreshToken, user } +``` + +#### Refresh + +``` +POST /api/v1/auth/refresh + { refreshToken } + → Nouveau accessToken + refreshToken (rotation) +``` + +### 2. OAuth2 + +- **Google** : `GET /api/v1/auth/google` → callback `GOOGLE_CALLBACK_URL` +- **Microsoft** : `GET /api/v1/auth/microsoft` → callback `MICROSOFT_CALLBACK_URL` + +Configuration dans `.env` : +```bash +GOOGLE_CLIENT_ID=... +GOOGLE_CLIENT_SECRET=... +MICROSOFT_CLIENT_ID=... +MICROSOFT_CLIENT_SECRET=... +``` + +### 3. API Keys + +Authentification alternative au JWT pour intĂ©grations tierces. + +``` +Header: x-api-key: xped_xxxxxxxxxxxxxxxx +``` + +Gestion via `GET/POST /api/v1/api-keys`. Les clĂ©s sont hashĂ©es avec Argon2 — seul le prĂ©fixe est stockĂ© en clair. + +--- + +## RBAC — RĂŽles et permissions + +| RĂŽle | Description | AccĂšs | +|------|-------------|-------| +| ADMIN | Administrateur de l'organisation | Tout | +| MANAGER | Gestionnaire | Bookings, dashboard, utilisateurs (no admin) | +| USER | Utilisateur standard | Recherche, crĂ©ation bookings | +| VIEWER | Lecture seule | Dashboard, liste bookings | +| CARRIER | Portail carrier | Accepter/rejeter CSV bookings assignĂ©s | + +### DĂ©corateurs + +```typescript +@Roles('ADMIN', 'MANAGER') // Restreindre Ă  des rĂŽles +@Public() // Route publique (pas de JWT requis) +@CurrentUser() // Injecter l'utilisateur courant +``` + +--- + +## VĂ©rification email + +``` +POST /api/v1/auth/register + → Email de vĂ©rification envoyĂ© (token 24h) +POST /api/v1/auth/verify-email?token=xxx + → Marque l'email comme vĂ©rifiĂ© +``` + +--- + +## RĂ©initialisation de mot de passe + +``` +POST /api/v1/auth/forgot-password { email } + → Email avec token (1h, table password_reset_tokens) +POST /api/v1/auth/reset-password { token, newPassword } + → Nouveau mot de passe hashĂ© Argon2 +``` + +--- + +## Invitations + +Les admins peuvent inviter des utilisateurs dans leur organisation : + +``` +POST /api/v1/invitations { email, role } + → Email d'invitation avec token (24h, table invitation_tokens) +GET /api/v1/invitations/accept?token=xxx + → CrĂ©e l'utilisateur avec le rĂŽle assignĂ© +``` + +--- + +## Protection des routes (middleware Next.js) + +`apps/frontend/middleware.ts` vĂ©rifie le cookie `accessToken` avant chaque requĂȘte. + +**Routes publiques** (pas de redirection) : +- Exactes : `/`, pages lĂ©gales +- Par prĂ©fixe : `/login`, `/register`, `/carrier`, `/about`, `/blog`, `/pricing`, etc. + +Toutes les autres routes redirigent vers `/login?redirect=`. + +--- + +## Variables d'environnement + +```bash +JWT_SECRET=your-super-secret-jwt-key +JWT_ACCESS_EXPIRATION=15m +JWT_REFRESH_EXPIRATION=7d + +GOOGLE_CLIENT_ID= +GOOGLE_CLIENT_SECRET= +GOOGLE_CALLBACK_URL=http://localhost:4000/api/v1/auth/google/callback + +MICROSOFT_CLIENT_ID= +MICROSOFT_CLIENT_SECRET= +MICROSOFT_CALLBACK_URL=http://localhost:4000/api/v1/auth/microsoft/callback + +BCRYPT_ROUNDS=12 +SESSION_TIMEOUT_MS=7200000 +``` diff --git a/docs/features/bookings.md b/docs/features/bookings.md new file mode 100644 index 0000000..0eca89a --- /dev/null +++ b/docs/features/bookings.md @@ -0,0 +1,109 @@ +# RĂ©servations standard + +--- + +## Workflow de rĂ©servation (4 Ă©tapes max) + +``` +1. SĂ©lection de l'offre (vĂ©rification dispo temps rĂ©el) +2. Informations expĂ©diteur / destinataire +3. DĂ©tails conteneur +4. Confirmation + CGU → GĂ©nĂ©ration booking number +``` + +--- + +## NumĂ©ro de rĂ©servation + +Format : `WCM-YYYY-XXXXXX` (XXXXXX = 6 caractĂšres alphanumĂ©riques uniques) + +Exemple : `WCM-2026-A3F7K2` + +--- + +## Statuts + +| Statut | Description | +|--------|-------------| +| draft | Brouillon (en cours de crĂ©ation) | +| confirmed | ConfirmĂ© | +| shipped | En transit | +| delivered | LivrĂ© | +| cancelled | AnnulĂ© | + +--- + +## API + +| MĂ©thode | Route | Description | +|---------|-------|-------------| +| GET | /api/v1/bookings | Liste (paginĂ©e, filtrable) | +| POST | /api/v1/bookings | CrĂ©er une rĂ©servation | +| GET | /api/v1/bookings/:id | DĂ©tail | +| PATCH | /api/v1/bookings/:id | Mettre Ă  jour | +| DELETE | /api/v1/bookings/:id | Annuler | +| GET | /api/v1/bookings/:id/pdf | GĂ©nĂ©rer PDF | +| POST | /api/v1/bookings/export | Export Excel/PDF | + +### Exemple crĂ©ation + +``` +POST /api/v1/bookings +Authorization: Bearer + +{ + "rateQuoteId": "uuid-de-la-cotation", + "shipper": { + "name": "Acme Corp", + "address": "123 Main St", + "country": "FR" + }, + "consignee": { + "name": "Shanghai Trading", + "address": "456 Nanjing Rd", + "country": "CN" + }, + "containers": [ + { + "type": "40HC", + "cargoDescription": "Electronic components", + "isHazmat": false + } + ], + "notes": "Fragile cargo" +} +``` + +--- + +## Post-booking automatique + +AprĂšs crĂ©ation d'une rĂ©servation : + +1. **Audit log** — action `BOOKING_CREATED` +2. **Notification WebSocket** — push en temps rĂ©el +3. **Webhooks** — Ă©vĂ©nement `BOOKING_CREATED` envoyĂ© aux abonnĂ©s +4. **Email confirmation** — template MJML +5. **PDF** — gĂ©nĂ©rĂ© via pdfkit, stockĂ© sur MinIO + +--- + +## Filtres disponibles + +``` +GET /api/v1/bookings?status=confirmed&carrierId=xxx&page=1&limit=20 + &startDate=2026-01-01&endDate=2026-12-31 + &search=WCM-2026 (recherche floue sur numĂ©ro, expĂ©diteur, destinataire) +``` + +--- + +## Dashboard + +Le dashboard agrĂšge : +- KPI cards : bookings/mois, TEUs, montant total +- Graphiques 6 mois (recharts) +- Alertes (retards, confirmations en attente) +- Table interactive avec TanStack Table (tri, filtres, pagination, virtual scroll) + +Endpoint : `GET /api/v1/dashboard/stats` diff --git a/docs/features/csv-bookings.md b/docs/features/csv-bookings.md new file mode 100644 index 0000000..1398397 --- /dev/null +++ b/docs/features/csv-bookings.md @@ -0,0 +1,116 @@ +# RĂ©servations CSV & Portail Carrier + +--- + +## Vue d'ensemble + +Le systĂšme de rĂ©servation CSV permet aux admins de crĂ©er des rĂ©servations en important des fichiers CSV et d'envoyer automatiquement un **lien magique** aux transporteurs pour qu'ils acceptent ou rejettent via un portail dĂ©diĂ©. + +--- + +## Workflow complet + +``` +1. Admin upload CSV → crĂ©ation csv_bookings +2. Admin assigne un carrier Ă  la rĂ©servation +3. SystĂšme envoie email avec magic link (expiry 1h) +4. Carrier clique → authentification automatique (token URL) +5. Carrier voit les dĂ©tails → Accept ou Reject +6. ActivitĂ© logguĂ©e dans carrier_activities +7. Admin voit le statut mis Ă  jour en dashboard +``` + +--- + +## API — RĂ©servations CSV (Admin) + +| MĂ©thode | Route | Description | +|---------|-------|-------------| +| GET | /api/v1/csv-bookings | Liste des rĂ©servations CSV | +| POST | /api/v1/csv-bookings | CrĂ©er une rĂ©servation CSV | +| GET | /api/v1/csv-bookings/:id | DĂ©tail d'une rĂ©servation | +| PATCH | /api/v1/csv-bookings/:id | Mettre Ă  jour | +| DELETE | /api/v1/csv-bookings/:id | Supprimer | +| POST | /api/v1/csv-bookings/:id/assign-carrier | Assigner un carrier | +| POST | /api/v1/csv-bookings/:id/send-magic-link | Envoyer le lien magique | + +--- + +## API — Portail Carrier + +| MĂ©thode | Route | Description | +|---------|-------|-------------| +| GET | /api/v1/carrier/auth | Auth via magic link token | +| GET | /api/v1/carrier/booking | Voir la rĂ©servation assignĂ©e | +| POST | /api/v1/carrier/booking/accept | Accepter | +| POST | /api/v1/carrier/booking/reject | Rejeter | +| POST | /api/v1/carrier/booking/documents | Uploader des documents | + +### Authentification portail carrier + +Le lien magique contient un token unique : +``` +https://app.xpeditis.com/carrier/auth?token=xxxxxxxx +``` + +Le token est stockĂ© dans `csv_bookings.carrier_magic_link_token` (hashĂ©). +Expiry : 1 heure. Si expirĂ©, l'admin doit renvoyer un nouveau lien. + +--- + +## Statuts des rĂ©servations CSV + +| Statut | Description | +|--------|-------------| +| pending | En attente d'assignation carrier | +| sent | Lien magique envoyĂ© au carrier | +| accepted | Carrier a acceptĂ© | +| rejected | Carrier a refusĂ© | +| in_transit | En cours de transport | +| delivered | LivrĂ© | + +--- + +## Pages frontend + +| Route | Description | +|-------|-------------| +| /dashboard/csv-bookings | Liste admin des rĂ©servations CSV | +| /carrier/auth | Page d'auth carrier (via magic link) | +| /carrier/booking | Dashboard carrier (accept/reject) | +| /carrier/documents | Upload documents carrier | + +--- + +## Import CSV (upload admin) + +Le fichier CSV peut ĂȘtre uploadĂ© via `POST /api/v1/admin/csv-rates/upload`. + +Format des colonnes requis : voir [../csv-system/CSV_RATE_SYSTEM.md](../csv-system/CSV_RATE_SYSTEM.md). + +--- + +## Profils carrier + +Les carriers qui utilisent le portail ont un `CarrierProfile` liĂ© Ă  leur `Organization`. +Chaque action (accept, reject, document upload) est tracĂ©e dans `carrier_activities`. + +```sql +SELECT ca.action, ca.created_at, cb.booking_number +FROM carrier_activities ca +JOIN csv_bookings cb ON cb.id = ca.csv_booking_id +WHERE ca.carrier_profile_id = 'xxx' +ORDER BY ca.created_at DESC; +``` + +--- + +## Email magic link + +Template MJML dans `apps/backend/src/infrastructure/email/templates/`. + +Variables disponibles : +- `bookingNumber` — numĂ©ro de rĂ©servation +- `magicLink` — URL avec token +- `expiresIn` — durĂ©e de validitĂ© ("1 heure") +- `carrierName` — nom du carrier diff --git a/docs/features/notifications.md b/docs/features/notifications.md new file mode 100644 index 0000000..9612063 --- /dev/null +++ b/docs/features/notifications.md @@ -0,0 +1,112 @@ +# Notifications temps rĂ©el & Webhooks + +--- + +## Notifications WebSocket + +### Architecture + +``` +ÉvĂ©nement serveur → NotificationService → CrĂ©ation en base (notifications) + ↓ + NotificationsGateway (Socket.IO) + ↓ + Émission vers la room userId + ↓ + Client reçoit l'Ă©vĂ©nement 'notification' +``` + +### Connexion depuis le frontend + +Le hook `useNotifications` gĂšre la connexion Socket.IO : + +```typescript +// Connexion avec JWT dans le handshake +const socket = io(API_URL, { + auth: { token: accessToken } +}); + +socket.on('notification', (notification) => { /* ... */ }); +``` + +### Types de notifications + +| Type | DĂ©clencheur | +|------|-------------| +| BOOKING_CREATED | Nouvelle rĂ©servation | +| BOOKING_STATUS_CHANGED | Changement de statut | +| DOCUMENT_UPLOADED | Document uploadĂ© | +| CARRIER_ACCEPTED | Carrier a acceptĂ© une CSV booking | +| CARRIER_REJECTED | Carrier a refusĂ© | +| PAYMENT_SUCCESS | Paiement Stripe rĂ©ussi | +| PAYMENT_FAILED | Paiement Stripe Ă©chouĂ© | +| SUBSCRIPTION_UPDATED | Abonnement modifiĂ© | +| SYSTEM | Notification systĂšme | + +### Niveaux de prioritĂ© + +`LOW` · `MEDIUM` · `HIGH` · `URGENT` + +### API notifications + +| MĂ©thode | Route | Description | +|---------|-------|-------------| +| GET | /api/v1/notifications | Liste (paginĂ©e, filtrable) | +| PATCH | /api/v1/notifications/:id/read | Marquer comme lu | +| PATCH | /api/v1/notifications/read-all | Tout marquer comme lu | +| DELETE | /api/v1/notifications/:id | Supprimer | + +--- + +## Webhooks + +### Pour qui + +Les webhooks permettent Ă  des systĂšmes tiers de recevoir des Ă©vĂ©nements Xpeditis en temps rĂ©el. + +### Configuration + +``` +POST /api/v1/webhooks +{ + "url": "https://your-system.com/webhook", + "events": ["BOOKING_CREATED", "BOOKING_UPDATED"], + "secret": "your-signing-secret" +} +``` + +### SĂ©curitĂ© + +Chaque webhook est signĂ© HMAC-SHA256 : +``` +X-Webhook-Signature: sha256=xxxxxxxx +``` + +VĂ©rification cĂŽtĂ© rĂ©cepteur : +```typescript +const signature = crypto + .createHmac('sha256', secret) + .update(rawBody) + .digest('hex'); +const isValid = `sha256=${signature}` === headers['x-webhook-signature']; +``` + +### Retry + +- 3 tentatives avec backoff exponentiel +- AprĂšs 3 Ă©checs → statut `FAILED`, webhook dĂ©sactivĂ© +- `failure_count` incrĂ©mentĂ© Ă  chaque Ă©chec + +### ÉvĂ©nements disponibles + +`BOOKING_CREATED` · `BOOKING_UPDATED` · `BOOKING_CANCELLED` · `RATE_QUOTED` · `CARRIER_ACCEPTED` · `CARRIER_REJECTED` · `PAYMENT_SUCCESS` · `PAYMENT_FAILED` + +### API webhooks + +| MĂ©thode | Route | Description | +|---------|-------|-------------| +| GET | /api/v1/webhooks | Liste des webhooks | +| POST | /api/v1/webhooks | CrĂ©er un webhook | +| PATCH | /api/v1/webhooks/:id | Modifier | +| DELETE | /api/v1/webhooks/:id | Supprimer | +| POST | /api/v1/webhooks/:id/test | Tester le webhook | diff --git a/docs/features/rate-search.md b/docs/features/rate-search.md new file mode 100644 index 0000000..2384066 --- /dev/null +++ b/docs/features/rate-search.md @@ -0,0 +1,143 @@ +# Recherche de tarifs + +--- + +## Deux types de recherche + +| Type | Description | Endpoint | +|------|-------------|----------| +| FCL (Full Container Load) | Tarifs via connecteurs carriers (Maersk, MSC, etc.) | POST /api/v1/rates/search | +| CSV / LCL | Tarifs chargĂ©s depuis des fichiers CSV | POST /api/v1/rates/csv-search | + +--- + +## Recherche FCL — Carriers API + +### Endpoint + +``` +POST /api/v1/rates/search +Authorization: Bearer + +{ + "origin": "NLRTM", + "destination": "CNSHA", + "containerType": "40HC", + "mode": "FCL", + "departureDate": "2026-06-01", + "hazmat": false +} +``` + +### RĂ©ponse + +```json +{ + "results": [ + { + "id": "uuid", + "carrier": { "name": "Maersk", "code": "MAERSK", "logoUrl": "..." }, + "origin": { "code": "NLRTM", "name": "Rotterdam" }, + "destination": { "code": "CNSHA", "name": "Shanghai" }, + "baseFreight": 1850.00, + "surcharges": [ + { "type": "BAF", "amount": 250.00, "currency": "USD" } + ], + "totalAmount": 2100.00, + "currency": "USD", + "transitDays": 28, + "etd": "2026-06-01T00:00:00Z", + "eta": "2026-06-29T00:00:00Z", + "availability": 50, + "validUntil": "2026-05-13T10:15:00Z" + } + ], + "total": 5, + "page": 1, + "pageSize": 20 +} +``` + +### Cache Redis + +- ClĂ© : `rate:{origin}:{destination}:{containerType}` +- TTL : 15 minutes +- Les cotations expirent automatiquement aprĂšs 15min (`valid_until`) + +### Carriers intĂ©grĂ©s + +| Carrier | Code | SCAC | +|---------|------|------| +| Maersk | MAERSK | MAEU | +| MSC | MSC | MSCU | +| CMA CGM | CMACGM | CMDU | +| Hapag-Lloyd | HAPAG | HLCU | +| ONE | ONE | ONEY | + +Chaque carrier a son connecteur dans `apps/backend/src/infrastructure/carriers/`. +Circuit breaker via `opossum` : timeout 5s, bascule sur fallback si indisponible. + +--- + +## Recherche CSV + +### Endpoint + +``` +POST /api/v1/rates/csv-search +Authorization: Bearer + +{ + "origin": "NLRTM", + "destination": "USNYC", + "volumeCBM": 25.5, + "weightKG": 3500, + "palletCount": 10, + "filters": { + "companies": ["SSC Consolidation"], + "minPrice": 1000, + "maxPrice": 3000, + "currency": "USD" + } +} +``` + +### Carriers CSV disponibles + +| Company | Type | API | +|---------|------|-----| +| SSC Consolidation | CSV_ONLY | Non | +| ECU Worldwide | CSV_AND_API | Oui | +| TCC Logistics | CSV_ONLY | Non | +| NVO Consolidation | CSV_ONLY | Non | + +Les fichiers CSV sont dans `apps/backend/src/infrastructure/storage/csv-storage/rates/`. + +### Calcul de prix CSV + +```typescript +// Freight class : prendre le max de volume-based ou weight-based +const volumePrice = volumeCBM * pricePerCBM; +const weightPrice = weightKG * pricePerKG; +const freightPrice = Math.max(volumePrice, weightPrice); +const totalPrice = freightPrice + surchargeBAF + surchargeCAF; +``` + +--- + +## Recherche de ports + +Autocomplete avec recherche floue (pg_trgm) : + +``` +GET /api/v1/ports/search?q=rotterdam&limit=10 +``` + +~10 000 ports UN/LOCODE seedĂ©s en base. + +--- + +## Export des rĂ©sultats + +Les rĂ©sultats peuvent ĂȘtre exportĂ©s en PDF ou Excel depuis le frontend. +Voir `apps/frontend/src/utils/` pour les utilitaires d'export. diff --git a/docs/features/subscriptions.md b/docs/features/subscriptions.md new file mode 100644 index 0000000..4a66f68 --- /dev/null +++ b/docs/features/subscriptions.md @@ -0,0 +1,110 @@ +# Abonnements & Paiements (Stripe) + +--- + +## Plans disponibles + +| Plan | Description | +|------|-------------| +| FREE | AccĂšs limitĂ© (aprĂšs inscription) | +| BRONZE | EntrĂ©e de gamme | +| SILVER | Standard | +| GOLD | AvancĂ© | +| PLATINIUM | Entreprise | + +Les plans BRONZE/SILVER/GOLD/PLATINIUM sont disponibles en facturation **mensuelle** ou **annuelle**. + +--- + +## Architecture + +Le systĂšme utilise Stripe pour la gestion des paiements. Chaque organisation a exactement un enregistrement `subscriptions`. + +``` +Organization 1──1 Subscription + └── stripe_customer_id (Stripe Customer) + └── stripe_subscription_id (Stripe Subscription) +``` + +--- + +## API + +| MĂ©thode | Route | Description | +|---------|-------|-------------| +| GET | /api/v1/subscriptions/current | Abonnement courant de l'org | +| POST | /api/v1/subscriptions/create-checkout | CrĂ©er session Stripe Checkout | +| POST | /api/v1/subscriptions/cancel | Annuler l'abonnement | +| POST | /api/v1/subscriptions/webhook | Webhook Stripe (signature HMAC) | +| GET | /api/v1/subscriptions/plans | Liste des plans disponibles | + +--- + +## Configuration + +```bash +# .env backend +STRIPE_SECRET_KEY=sk_test_xxxx +STRIPE_WEBHOOK_SECRET=whsec_xxxx + +# Price IDs depuis le Dashboard Stripe +STRIPE_SILVER_MONTHLY_PRICE_ID=price_xxxx +STRIPE_SILVER_YEARLY_PRICE_ID=price_xxxx +STRIPE_GOLD_MONTHLY_PRICE_ID=price_xxxx +STRIPE_GOLD_YEARLY_PRICE_ID=price_xxxx +STRIPE_PLATINIUM_MONTHLY_PRICE_ID=price_xxxx +STRIPE_PLATINIUM_YEARLY_PRICE_ID=price_xxxx +``` + +--- + +## Webhook Stripe + +Le endpoint `/api/v1/subscriptions/webhook` reçoit les Ă©vĂ©nements Stripe. + +**ÉvĂ©nements gĂ©rĂ©s** : +- `checkout.session.completed` — activation abonnement +- `customer.subscription.updated` — changement de plan +- `customer.subscription.deleted` — annulation +- `invoice.payment_succeeded` — paiement rĂ©ussi +- `invoice.payment_failed` — paiement Ă©chouĂ© → statut `past_due` + +Le secret `STRIPE_WEBHOOK_SECRET` est utilisĂ© pour vĂ©rifier la signature de chaque Ă©vĂ©nement. + +### Configurer le webhook en local (test) + +```bash +# Installer Stripe CLI +stripe listen --forward-to localhost:4000/api/v1/subscriptions/webhook +``` + +--- + +## Statuts d'abonnement + +| Statut | Description | +|--------|-------------| +| active | Abonnement en cours, paiement OK | +| trialing | PĂ©riode d'essai | +| past_due | Paiement en retard | +| cancelled | AnnulĂ© | +| pending_payment | En attente de paiement CB | +| pending_bank_transfer | En attente de virement bancaire | + +--- + +## Licenses + +Le systĂšme de licenses (`licenses` table) permet d'activer des fonctionnalitĂ©s spĂ©cifiques par organisation, indĂ©pendamment du plan Stripe. + +--- + +## Taux de commission + +La colonne `subscriptions.commission_rate` (DECIMAL 5,4) permet de stocker un taux de commission Xpeditis par organisation (pour tracking interne). + +--- + +## Guide de configuration initial + +Voir [../deployment/STRIPE_SETUP.md](../deployment/STRIPE_SETUP.md) pour la configuration complĂšte de Stripe (crĂ©ation des products/prices, webhooks, etc.). diff --git a/docs/installation/INSTALLATION-STEPS.md b/docs/getting-started/installation.md similarity index 100% rename from docs/installation/INSTALLATION-STEPS.md rename to docs/getting-started/installation.md diff --git a/docs/getting-started/quick-start.md b/docs/getting-started/quick-start.md new file mode 100644 index 0000000..122fe22 --- /dev/null +++ b/docs/getting-started/quick-start.md @@ -0,0 +1,160 @@ +# DĂ©marrage rapide — Xpeditis + +Guide de dĂ©marrage en 5 minutes. + +--- + +## PrĂ©requis + +- **Node.js** ≄ 20.x +- **npm** ≄ 10.x +- **Docker** + Docker Compose (pour PostgreSQL, Redis, MinIO) + +--- + +## 1. Installer les dĂ©pendances + +```bash +npm run install:all +``` + +> Sur Windows si l'installation Ă©choue, voir [windows.md](windows.md). + +--- + +## 2. DĂ©marrer l'infrastructure + +```bash +docker-compose up -d +``` + +VĂ©rifier que tout est actif : + +```bash +docker-compose ps +# postgres Up (healthy) +# redis Up (healthy) +# minio Up (healthy) +``` + +--- + +## 3. Configurer l'environnement + +```bash +cp apps/backend/.env.example apps/backend/.env +cp apps/frontend/.env.example apps/frontend/.env.local +``` + +Les valeurs par dĂ©faut fonctionnent pour le dĂ©veloppement local — aucune modification nĂ©cessaire. + +--- + +## 4. ExĂ©cuter les migrations + +```bash +cd apps/backend && npm run migration:run && cd ../.. +``` + +--- + +## 5. DĂ©marrer les serveurs + +```bash +# Terminal 1 +npm run backend:dev +# → http://localhost:4000/api/v1 +# → Swagger: http://localhost:4000/api/docs + +# Terminal 2 +npm run frontend:dev +# → http://localhost:3000 +``` + +--- + +## VĂ©rification + +| URL | Attendu | +|-----|---------| +| http://localhost:4000/api/v1/health | `{"status":"ok"}` | +| http://localhost:4000/api/docs | Swagger UI | +| http://localhost:3000 | Page d'accueil Xpeditis | + +--- + +## Commandes de rĂ©fĂ©rence + +```bash +# DĂ©veloppement +npm run backend:dev # Backend avec hot-reload +npm run frontend:dev # Frontend avec hot-reload + +# Tests +npm run backend:test # Tests unitaires backend +npm run frontend:test # Tests unitaires frontend +cd apps/backend && npm run test:integration # Tests d'intĂ©gration +cd apps/frontend && npm run test:e2e # Tests E2E Playwright + +# QualitĂ© de code +npm run backend:lint # ESLint backend +npm run frontend:lint # ESLint frontend +npm run format # Prettier (tous les fichiers) +npm run format:check # VĂ©rifier le formatage + +# Base de donnĂ©es +cd apps/backend +npm run migration:generate -- src/infrastructure/persistence/typeorm/migrations/NomMigration +npm run migration:run +npm run migration:revert + +# Build +npm run backend:build # Build NestJS +npm run frontend:build # Build Next.js +npm run clean # Supprimer node_modules, dist, .next +``` + +--- + +## Infrastructure locale (Docker) + +| Service | URL / Port | Credentials | +|---------|-----------|-------------| +| PostgreSQL | localhost:5432 | xpeditis / xpeditis_dev_password | +| Redis | localhost:6379 | password: xpeditis_redis_password | +| MinIO API | http://localhost:9000 | minioadmin / minioadmin | +| MinIO Console | http://localhost:9001 | minioadmin / minioadmin | + +--- + +## Comptes de test (aprĂšs migration) + +Les migrations seed crĂ©ent automatiquement des comptes de test. Voir la migration `1730000000007-SeedTestUsers.ts` pour les credentials exacts. + +--- + +## RĂ©solution de problĂšmes courants + +**Backend ne dĂ©marre pas :** +```bash +cd apps/backend && rm -rf node_modules && npm install && npm run dev +``` + +**Erreur de migration :** +```bash +cd apps/backend +npm run migration:revert # Annuler la derniĂšre migration +npm run migration:run # Relancer +``` + +**Port dĂ©jĂ  utilisĂ© :** +```bash +# Modifier PORT dans apps/backend/.env +PORT=4001 +``` + +**Docker ne dĂ©marre pas :** +```bash +docker-compose down +docker-compose up -d +``` diff --git a/docs/phases/WINDOWS-INSTALLATION.md b/docs/getting-started/windows.md similarity index 100% rename from docs/phases/WINDOWS-INSTALLATION.md rename to docs/getting-started/windows.md