# CLAUDE.md This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. ## Project Overview **Xpeditis** is a B2B SaaS maritime freight booking and management platform (maritime equivalent of WebCargo). The platform allows freight forwarders to search and compare real-time shipping rates, book containers online, and manage shipments from a centralized dashboard. **Current Status**: Phase 4 - Production-ready with security hardening, monitoring, and comprehensive testing infrastructure. **Active Feature**: Carrier Portal (Branch: `feature_dashboard_transporteur`) - Dedicated portal for carriers to manage booking requests, view statistics, and download documents. ## Development Commands ### Local Development Setup ```bash # Install all dependencies (monorepo) npm install cd apps/backend && npm install cd ../frontend && npm install # Start infrastructure (PostgreSQL + Redis + MinIO) docker-compose up -d # Verify all services are running docker-compose ps # Expected: xpeditis-postgres, xpeditis-redis, xpeditis-minio # Run database migrations cd apps/backend npm run migration:run # Start backend development server (with hot reload) npm run backend:dev # From root, or: cd apps/backend && npm run dev # Start frontend development server npm run frontend:dev # From root, or: cd apps/frontend && npm run dev ``` **Access Points**: - Frontend: http://localhost:3000 - Backend API: http://localhost:4000 - API Docs (Swagger): http://localhost:4000/api/docs - MinIO Console (local S3): http://localhost:9001 (minioadmin/minioadmin) - Carrier Portal: http://localhost:3000/carrier (in development) ### Monorepo Scripts (from root) ```bash # Development npm run backend:dev # Start backend dev server npm run frontend:dev # Start frontend dev server # Testing npm run backend:test # Run backend unit tests npm run frontend:test # Run frontend tests npm run backend:lint # Lint backend code npm run frontend:lint # Lint frontend code # Code Quality npm run format # Format all code (Prettier) npm run format:check # Check formatting # Build npm run backend:build # Build backend for production npm run frontend:build # Build frontend for production # Utilities npm run install:all # Install deps for all workspaces npm run clean # Clean all node_modules and build artifacts ``` ### Testing Commands #### Backend Tests ```bash cd apps/backend # Unit tests (domain layer - no external dependencies) npm test # Run all unit tests npm run test:watch # Run in watch mode npm run test:cov # With coverage report # Integration tests (infrastructure layer with real DB/Redis) npm run test:integration # Run all integration tests npm run test:integration:watch # Run in watch mode npm run test:integration:cov # With coverage report # E2E tests (full API workflow) npm run test:e2e # Run end-to-end tests # Run a single test file npm test -- booking.service.spec.ts npm run test:integration -- redis-cache.adapter.spec.ts npm run test:e2e -- carrier-portal.e2e-spec.ts ``` #### Load Testing (K6) ```bash cd apps/backend # Install k6 (macOS) brew install k6 # Run rate search load test (100 virtual users) k6 run load-tests/rate-search.test.js # Run with custom parameters k6 run --vus 50 --duration 60s load-tests/rate-search.test.js ``` #### E2E Testing (Playwright) ```bash cd apps/frontend # Install Playwright npx playwright install # Run E2E tests (booking workflow) npx playwright test e2e/booking-workflow.spec.ts # Run with UI mode npx playwright test --ui # Run specific browser npx playwright test --project=chromium ``` #### API Testing (Postman/Newman) ```bash # Install Newman globally npm install -g newman # Run Postman collection newman run postman/Xpeditis_API.postman_collection.json ``` ### Database Migrations ```bash cd apps/backend # Generate new migration (after changing ORM entities) npm run migration:generate -- src/infrastructure/persistence/typeorm/migrations/MigrationName # Run pending migrations npm run migration:run # Revert last migration npm run migration:revert ``` ### Build & Production ```bash # Backend build cd apps/backend npm run build npm run start:prod # Frontend build cd apps/frontend npm run build npm start ``` ## Architecture ### Hexagonal Architecture (Ports & Adapters) The backend follows strict hexagonal architecture with three isolated layers: ``` apps/backend/src/ ├── application/ # 🔌 Controllers & DTOs (depends ONLY on domain) │ ├── auth/ # JWT authentication module │ ├── rates/ # Rate search endpoints │ ├── bookings/ # Booking management │ ├── csv-bookings.module.ts # CSV booking imports │ ├── modules/ │ │ └── carrier-portal.module.ts # Carrier portal feature │ ├── controllers/ # REST endpoints │ │ ├── carrier-auth.controller.ts │ │ └── carrier-dashboard.controller.ts │ ├── dto/ # Data transfer objects with validation │ │ └── carrier-auth.dto.ts │ ├── services/ # Application services │ │ ├── carrier-auth.service.ts │ │ └── carrier-dashboard.service.ts │ ├── guards/ # Auth guards, rate limiting, RBAC │ └── mappers/ # DTO ↔ Domain entity mapping │ └── infrastructure/ # 🏗️ External integrations (depends ONLY on domain) ├── persistence/typeorm/ # PostgreSQL repositories │ ├── entities/ │ │ ├── carrier-profile.orm-entity.ts │ │ ├── carrier-activity.orm-entity.ts │ │ ├── csv-booking.orm-entity.ts │ │ └── organization.orm-entity.ts │ ├── repositories/ │ │ ├── carrier-profile.repository.ts │ │ └── carrier-activity.repository.ts │ └── migrations/ │ ├── 1733185000000-CreateCarrierProfiles.ts │ ├── 1733186000000-CreateCarrierActivities.ts │ ├── 1733187000000-AddCarrierToCsvBookings.ts │ └── 1733188000000-AddCarrierFlagToOrganizations.ts ├── cache/ # Redis adapter ├── carriers/ # Maersk, MSC, CMA CGM connectors │ └── csv-loader/ # CSV-based rate connector ├── email/ # MJML email service (carrier notifications) ├── storage/ # S3 storage adapter ├── websocket/ # Real-time carrier updates └── security/ # Helmet.js, rate limiting, CORS ``` **Critical Rules**: 1. **Domain layer**: No imports of NestJS, TypeORM, Redis, or any framework (domain layer not shown - pure business logic) 2. **Dependencies flow inward**: Infrastructure → Application → Domain 3. **TypeScript path aliases**: Use `@domain/*`, `@application/*`, `@infrastructure/*` 4. **Testing**: Domain tests must run without NestJS TestingModule ### Frontend Architecture (Next.js 14 App Router) ``` apps/frontend/ ├── app/ # Next.js 14 App Router (routing) │ ├── page.tsx # Landing page │ ├── layout.tsx # Root layout │ ├── login/ # Auth pages │ ├── register/ │ ├── dashboard/ # Protected dashboard routes │ └── carrier/ # 🚛 Carrier portal routes (in development) │ ├── login/ │ ├── dashboard/ │ └── bookings/ ├── src/ │ ├── components/ # React components │ │ ├── ui/ # shadcn/ui components (Button, Dialog, etc.) │ │ ├── bookings/ # Booking components │ │ └── admin/ # Admin components │ ├── hooks/ # Custom React hooks │ │ ├── useBookings.ts │ │ ├── useCompanies.ts │ │ └── useNotifications.ts │ ├── lib/ # Utilities and API client │ │ ├── api/ # API client modules │ │ │ ├── auth.ts │ │ │ ├── bookings.ts │ │ │ ├── csv-rates.ts │ │ │ └── dashboard.ts │ │ ├── context/ # React contexts │ │ └── providers/ # React Query and other providers │ ├── types/ # TypeScript type definitions │ │ ├── booking.ts │ │ ├── carrier.ts │ │ └── rates.ts │ ├── utils/ # Helper functions │ │ └── export.ts # Excel/CSV/PDF export utilities │ └── pages/ # Legacy page components └── public/ # Static assets (logos, images) ``` **Frontend Patterns**: - Server Components by default, Client Components when needed (`"use client"`) - React Hook Form + Zod for form validation - TanStack Query for server state management - Zustand for client state management - shadcn/ui for accessible UI components **TypeScript Path Aliases** (Frontend): - `@/*` - Maps to `./src/*` - `@/components/*` - Maps to `./src/components/*` - `@/lib/*` - Maps to `./src/lib/*` - `@/app/*` - Maps to `./app/*` - `@/types/*` - Maps to `./src/types/*` - `@/hooks/*` - Maps to `./src/hooks/*` - `@/utils/*` - Maps to `./src/utils/*` - `@/pages/*` - Maps to `./src/pages/*` ### Tech Stack **Backend**: - NestJS 10+ (framework) - TypeScript 5+ (strict mode) - PostgreSQL 15+ (database) - TypeORM 0.3+ (ORM) - Redis 7+ (cache, 15min TTL for rates) - Passport + JWT (authentication) - Argon2 (password hashing) - Helmet.js (security headers) - Pino (structured logging) - Sentry (error tracking + APM) **Frontend**: - Next.js 14+ App Router - TypeScript 5+ - React 18+ - TanStack Table (data grids) - TanStack Query (server state) - React Hook Form + Zod (forms) - Socket.IO (real-time updates) - Tailwind CSS + shadcn/ui - Framer Motion (animations) **Infrastructure**: - Docker + Docker Compose - GitHub Actions (CI/CD) - AWS RDS (PostgreSQL) - AWS ElastiCache (Redis) - AWS S3 (document storage) - MinIO (local S3-compatible storage for development) ## Testing Strategy ### Test Coverage Targets - **Domain layer**: 90%+ (currently ~100% for value objects and entities) - **Application layer**: 80%+ - **Infrastructure layer**: 70%+ (currently ~82% for Phase 3 services) ### Test File Locations ``` apps/backend/ ├── src/ │ ├── application/ │ │ └── services/ │ │ ├── carrier-auth.service.spec.ts │ │ └── carrier-dashboard.service.spec.ts │ └── domain/ │ ├── entities/ │ │ └── rate-quote.entity.spec.ts │ └── value-objects/ │ ├── email.vo.spec.ts │ └── money.vo.spec.ts ├── test/ │ ├── integration/ │ │ ├── booking.repository.spec.ts │ │ ├── redis-cache.adapter.spec.ts │ │ └── maersk.connector.spec.ts │ ├── carrier-portal.e2e-spec.ts # Carrier portal E2E tests │ ├── app.e2e-spec.ts │ ├── jest-integration.json │ ├── jest-e2e.json │ └── setup-integration.ts └── load-tests/ └── rate-search.test.js apps/frontend/ └── e2e/ └── booking-workflow.spec.ts ``` ### Running Tests in CI Tests run automatically on GitHub Actions for all PRs: - Linting & formatting check - Backend unit tests - Backend integration tests (with PostgreSQL + Redis services) - Backend E2E tests - Frontend tests - Security scans See [.github/workflows/ci.yml](.github/workflows/ci.yml) for full pipeline. ## Security Features (Phase 4) **OWASP Top 10 Compliance**: - ✅ Helmet.js security headers (CSP, HSTS, X-Frame-Options) - ✅ Rate limiting (global: 100/min, auth: 5/min, search: 30/min) - ✅ Brute-force protection (exponential backoff after 3 failed attempts) - ✅ File upload validation (MIME, magic number, size limits) - ✅ Password policy (12+ chars, complexity requirements, Argon2 hashing) - ✅ CORS with strict origin validation - ✅ SQL injection prevention (TypeORM parameterized queries) - ✅ XSS protection (CSP headers + input sanitization) **Monitoring & Observability**: - Sentry error tracking + APM (10% trace sampling) - Performance monitoring interceptor (slow request alerts) - Structured JSON logging with Pino - WebSocket real-time notifications (NotificationsGateway) - WebSocket carrier status updates ## Database Schema **Key Tables**: - `organizations` - Freight forwarders and carriers (has `is_carrier` flag) - `users` - User accounts with RBAC roles (Argon2 password hashing) - `carriers` - Shipping line integrations (Maersk, MSC, CMA CGM, etc.) - `carrier_profiles` - Carrier profile metadata and settings - `carrier_activities` - Audit trail for carrier actions (accept/reject bookings, etc.) - `ports` - 10k+ global ports (UN LOCODE) - `rate_quotes` - Cached shipping rates (15min TTL) - `bookings` - Container bookings (status workflow) - `containers` - Container details (type, VGM, seal numbers) - `shipments` - Real-time shipment tracking - `audit_logs` - Compliance audit trail - `csv_rates` - CSV-based rate data for offline/bulk rate loading - `csv_bookings` - CSV-based booking imports (has `carrier_id` foreign key) - `notifications` - User notifications (email, in-app) - `webhooks` - Webhook configurations for external integrations **Migrations**: Located in `apps/backend/src/infrastructure/persistence/typeorm/migrations/` See [apps/backend/DATABASE-SCHEMA.md](apps/backend/DATABASE-SCHEMA.md) for complete schema documentation. ## Environment Variables ### Required Variables **Backend** (`apps/backend/.env`): ```bash NODE_ENV=development PORT=4000 DATABASE_HOST=localhost DATABASE_PORT=5432 DATABASE_USER=xpeditis DATABASE_PASSWORD=xpeditis_dev_password DATABASE_NAME=xpeditis_dev REDIS_HOST=localhost REDIS_PORT=6379 REDIS_PASSWORD=xpeditis_redis_password JWT_SECRET=your-super-secret-jwt-key-change-this-in-production JWT_ACCESS_EXPIRATION=15m JWT_REFRESH_EXPIRATION=7d # Email configuration (for carrier notifications) EMAIL_HOST=smtp.example.com EMAIL_PORT=587 EMAIL_USER=noreply@xpeditis.com EMAIL_PASSWORD=your-email-password EMAIL_FROM=noreply@xpeditis.com ``` **Frontend** (`apps/frontend/.env.local`): ```bash NEXT_PUBLIC_API_URL=http://localhost:4000 NEXT_PUBLIC_WS_URL=ws://localhost:4000 ``` See `apps/backend/.env.example` and `apps/frontend/.env.example` for all available variables. ## API Documentation **OpenAPI/Swagger**: http://localhost:4000/api/docs (when backend running) **Key Endpoints**: ### Client Portal - `POST /api/v1/auth/login` - JWT authentication - `POST /api/v1/auth/register` - User registration - `POST /api/v1/rates/search` - Search shipping rates (cached 15min) - `POST /api/v1/rates/csv-search` - Search rates from CSV data - `POST /api/v1/bookings` - Create booking - `GET /api/v1/bookings` - List bookings (paginated) - `GET /api/v1/bookings/:id` - Get booking details - `POST /api/v1/bookings/csv-import` - Bulk import bookings from CSV ### Carrier Portal (New) - `POST /api/v1/carrier/auth/auto-login` - Auto-login via magic link token - `POST /api/v1/carrier/auth/login` - Standard carrier login - `GET /api/v1/carrier/dashboard/stats` - Carrier dashboard statistics - `GET /api/v1/carrier/bookings` - List bookings assigned to carrier - `GET /api/v1/carrier/bookings/:id` - Get booking details - `PATCH /api/v1/carrier/bookings/:id/accept` - Accept booking request - `PATCH /api/v1/carrier/bookings/:id/reject` - Reject booking request - `GET /api/v1/carrier/profile` - Get carrier profile - `PATCH /api/v1/carrier/profile` - Update carrier profile ### Common - `GET /api/v1/carriers/:id/status` - Real-time carrier status - `GET /api/v1/notifications` - Get user notifications - `WS /notifications` - WebSocket for real-time notifications - `WS /carrier-status` - WebSocket for carrier status updates See [apps/backend/docs/CARRIER_PORTAL_API.md](apps/backend/docs/CARRIER_PORTAL_API.md) for complete carrier portal API documentation. ## Business Rules **Critical Constraints**: - Rate quotes expire after 15 minutes (Redis TTL) - Carrier API timeout: 5 seconds per carrier - Booking workflow: Maximum 4 steps - Session timeout: 2 hours inactivity - Rate search: <2s response time (90% with cache) - Booking number format: `WCM-YYYY-XXXXXX` (6 alphanumeric chars) - Cache hit target: >90% for common routes - Multi-currency support: USD, EUR **RBAC Roles**: - `ADMIN` - Full system access - `MANAGER` - Manage organization bookings + users - `USER` - Create and view own bookings - `VIEWER` - Read-only access - `CARRIER` - Carrier portal access (view assigned bookings, accept/reject) **Carrier Portal Workflow**: 1. Admin creates CSV booking and assigns carrier 2. Email sent to carrier with magic link (auto-login token, valid 1 hour) 3. Carrier clicks link → auto-login → redirected to dashboard 4. Carrier can accept/reject booking, download documents 5. Activity logged in `carrier_activities` table 6. Client notified of carrier decision ## Real-Time Features (WebSocket) The platform uses WebSocket connections for real-time updates: **Notifications Gateway** (`application/gateways/notifications.gateway.ts`): - Real-time user notifications (booking updates, system alerts) - JWT-authenticated WebSocket connections - Auto-reconnect with exponential backoff - Connect to `ws://localhost:4000/notifications` **Carrier Status Updates**: - Real-time carrier API status monitoring - Live shipment tracking updates - Connection status: online/offline/degraded - Connect to `ws://localhost:4000/carrier-status` **Frontend Integration**: - Socket.IO client for WebSocket connections - Context providers in `lib/providers/` - Real-time notification dropdown component - Auto-refresh on status changes ## CSV Import/Export Features The platform supports CSV-based operations for bulk data management: **CSV Rate Search**: - Upload CSV files with rate data for offline/bulk rate loading - CSV-based carrier connectors in `infrastructure/carriers/csv-loader/` - Stored in `csv_rates` table - Accessible via admin dashboard at `/admin/csv-rates` **CSV Booking Import**: - Bulk import bookings from CSV files - Validation and mapping to domain entities - Stored in `csv_bookings` table - CSV parsing with `csv-parse` library - Automatic carrier assignment and email notification **Export Features**: - Export bookings to Excel (`.xlsx`) using `exceljs` - Export to CSV format - Export to PDF documents using `pdfkit` - File downloads using `file-saver` on frontend ## Admin User Management The platform includes a dedicated admin interface for user management: **Admin Features** (Branch: `users_admin`): - User CRUD operations (Create, Read, Update, Delete) - Organization management - Role assignment and permissions - Argon2 password hash generation for new users - Accessible at `/admin/users` (ADMIN role required) **Password Hashing Utility**: - Use `apps/backend/generate-hash.js` to generate Argon2 password hashes - Example: `node apps/backend/generate-hash.js mypassword` ## Deployment ### Docker Build ```bash # Build backend image docker build -t xpeditis-backend:latest -f apps/backend/Dockerfile . # Build frontend image docker build -t xpeditis-frontend:latest -f apps/frontend/Dockerfile . # Run with Docker Compose (development) docker-compose up -d ``` ### Production Deployment (Portainer) See [docker/PORTAINER_DEPLOYMENT_GUIDE.md](docker/PORTAINER_DEPLOYMENT_GUIDE.md) for complete instructions: - Scaleway Container Registry (rg.fr-par.scw.cloud/weworkstudio) - Docker Swarm stack deployment - Traefik reverse proxy configuration - Environment-specific configs (staging/production) **CI/CD**: Automated via GitHub Actions - Build and push Docker images to Scaleway Registry - Deploy to staging/production via Portainer - Run smoke tests post-deployment **Deployment Scripts**: - `docker/build-images.sh` - Build and tag Docker images - `deploy-to-portainer.sh` - Automated deployment script - `docker/portainer-stack.yml` - Production stack configuration ## Performance Targets - Rate search: <2s for 90% of requests (with cache) - Rate search: <5s for 90% of requests (cache miss) - Dashboard load: <1s for up to 5k bookings - Email confirmation: Send within 3s of booking - Carrier email notification: Send within 5s of booking assignment - Cache hit ratio: >90% for top 100 trade lanes - Carrier API timeout: 5s (with circuit breaker) ## Naming Conventions **TypeScript**: - Entities: `Booking`, `RateQuote`, `CarrierProfile` (PascalCase) - Value Objects: `Email`, `Money`, `BookingNumber` - Services: `BookingService`, `RateSearchService`, `CarrierAuthService` - Repositories: `BookingRepository`, `CarrierProfileRepository` (interface in domain) - Repository Implementations: `TypeOrmBookingRepository`, `TypeOrmCarrierProfileRepository` - DTOs: `CreateBookingDto`, `RateSearchRequestDto`, `CarrierAutoLoginDto` - Ports: `SearchRatesPort`, `CarrierConnectorPort` **Files**: - Entities: `booking.entity.ts` - Value Objects: `email.vo.ts` - Services: `booking.service.ts`, `carrier-auth.service.ts` - Tests: `booking.service.spec.ts`, `carrier-auth.service.spec.ts` - ORM Entities: `booking.orm-entity.ts`, `carrier-profile.orm-entity.ts` - Migrations: `1730000000001-CreateBookings.ts`, `1733185000000-CreateCarrierProfiles.ts` ## Common Pitfalls to Avoid ❌ **DO NOT**: - Import NestJS/TypeORM in domain layer - Put business logic in controllers or repositories - Use `any` type (strict mode enabled) - Skip writing tests (coverage targets enforced) - Use `DATABASE_SYNC=true` in production - Commit `.env` files - Expose sensitive data in API responses - Skip rate limiting on public endpoints - Use circular imports (leverage barrel exports) - Send emails without proper error handling - Store plain text passwords (always use Argon2) ✅ **DO**: - Follow hexagonal architecture strictly - Write tests for all new features (domain 90%+) - Use TypeScript path aliases (`@domain/*`, `@application/*`, `@infrastructure/*`) - Validate all DTOs with `class-validator` - Implement circuit breakers for external APIs - Cache frequently accessed data (Redis) - Use structured logging (Pino) - Document APIs with Swagger decorators - Run migrations before deployment - Test email sending in development with test accounts - Use MJML for responsive email templates ## Documentation **Architecture & Planning**: - [ARCHITECTURE.md](ARCHITECTURE.md) - System architecture (5,800 words) - [DEPLOYMENT.md](DEPLOYMENT.md) - Deployment guide (4,500 words) - [PRD.md](PRD.md) - Product requirements - [TODO.md](TODO.md) - 30-week development roadmap - [CARRIER_PORTAL_IMPLEMENTATION_PLAN.md](CARRIER_PORTAL_IMPLEMENTATION_PLAN.md) - Carrier portal implementation plan **Implementation Summaries**: - [PHASE4_SUMMARY.md](PHASE4_SUMMARY.md) - Security, monitoring, testing - [PHASE3_COMPLETE.md](PHASE3_COMPLETE.md) - Booking workflow, exports - [PHASE2_COMPLETE.md](PHASE2_COMPLETE.md) - Authentication, RBAC - [PHASE-1-WEEK5-COMPLETE.md](PHASE-1-WEEK5-COMPLETE.md) - Rate search, cache **API Documentation**: - [apps/backend/docs/CARRIER_PORTAL_API.md](apps/backend/docs/CARRIER_PORTAL_API.md) - Carrier portal API reference **Testing**: - [TEST_EXECUTION_GUIDE.md](TEST_EXECUTION_GUIDE.md) - How to run all tests - [TEST_COVERAGE_REPORT.md](TEST_COVERAGE_REPORT.md) - Coverage metrics - [GUIDE_TESTS_POSTMAN.md](GUIDE_TESTS_POSTMAN.md) - Postman API tests **Deployment**: - [docker/PORTAINER_DEPLOYMENT_GUIDE.md](docker/PORTAINER_DEPLOYMENT_GUIDE.md) - Portainer setup - [docker/DOCKER_BUILD_GUIDE.md](docker/DOCKER_BUILD_GUIDE.md) - Docker build instructions - [DEPLOYMENT_CHECKLIST.md](DEPLOYMENT_CHECKLIST.md) - Pre-deployment checklist ## Code Review Checklist 1. Hexagonal architecture principles followed 2. Domain layer has zero external dependencies 3. Unit tests written (90%+ coverage for domain) 4. Integration tests for infrastructure adapters 5. DTOs validated with class-validator 6. Swagger documentation updated 7. No secrets committed 8. TypeScript strict mode passes 9. Prettier formatting applied 10. ESLint passes with no warnings 11. Email templates tested in development 12. Carrier workflow tested end-to-end