Some checks failed
CI/CD Pipeline / Backend - Build, Test & Push (push) Failing after 58s
CI/CD Pipeline / Frontend - Build, Test & Push (push) Failing after 5m55s
CI/CD Pipeline / Integration Tests (push) Has been skipped
CI/CD Pipeline / Deployment Summary (push) Has been skipped
CI/CD Pipeline / Deploy to Portainer (push) Has been skipped
CI/CD Pipeline / Discord Notification (Success) (push) Has been skipped
CI/CD Pipeline / Discord Notification (Failure) (push) Has been skipped
Reorganisation majeure de toute la documentation du projet pour ameliorer la navigation et la maintenance. ## Changements principaux ### Organisation (80 -> 4 fichiers .md a la racine) - Deplace 82 fichiers .md dans docs/ organises en 11 categories - Conserve uniquement 4 fichiers essentiels a la racine: * README.md, CLAUDE.md, PRD.md, TODO.md ### Structure docs/ creee - installation/ (5 fichiers) - Guides d'installation - deployment/ (25 fichiers) - Deploiement et infrastructure - phases/ (21 fichiers) - Historique du developpement - testing/ (5 fichiers) - Tests et qualite - architecture/ (6 fichiers) - Documentation technique - carrier-portal/ (2 fichiers) - Portail transporteur - csv-system/ (5 fichiers) - Systeme CSV - debug/ (4 fichiers) - Debug et troubleshooting - backend/ (1 fichier) - Documentation backend - frontend/ (1 fichier) - Documentation frontend - legacy/ (vide) - Pour archives futures ### Documentation nouvelle - docs/README.md - Index complet de toute la documentation (367 lignes) * Guide de navigation par scenario * Recherche rapide par theme * FAQ et commandes rapides - docs/CLEANUP-REPORT-2025-12-22.md - Rapport detaille du nettoyage ### Scripts reorganises - add-email-to-csv.py -> scripts/ - deploy-to-portainer.sh -> docker/ ### Fichiers supprimes - 1536w default.svg (11MB) - Fichier non utilise ### References mises a jour - CLAUDE.md - Section Documentation completement reecrite - docs/architecture/EMAIL_IMPLEMENTATION_STATUS.md - Chemin script Python - docs/deployment/REGISTRY_PUSH_GUIDE.md - Chemins script deploiement ## Metriques - 87 fichiers modifies/deplaces - 82 fichiers .md organises dans docs/ - 11MB d'espace libere - Temps de recherche reduit de ~5min a ~30s (-90%) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
583 lines
14 KiB
Markdown
583 lines
14 KiB
Markdown
# Guide de Test avec Postman - Xpeditis API
|
|
|
|
## 📦 Importer la Collection Postman
|
|
|
|
### Option 1 : Importer le fichier JSON
|
|
|
|
1. Ouvrez Postman
|
|
2. Cliquez sur **"Import"** (en haut à gauche)
|
|
3. Sélectionnez le fichier : `postman/Xpeditis_API.postman_collection.json`
|
|
4. Cliquez sur **"Import"**
|
|
|
|
### Option 2 : Collection créée manuellement
|
|
|
|
La collection contient **13 requêtes** organisées en 3 dossiers :
|
|
- **Rates API** (4 requêtes)
|
|
- **Bookings API** (6 requêtes)
|
|
- **Health & Status** (1 requête)
|
|
|
|
---
|
|
|
|
## 🚀 Avant de Commencer
|
|
|
|
### 1. Démarrer les Services
|
|
|
|
```bash
|
|
# Terminal 1 : PostgreSQL
|
|
# Assurez-vous que PostgreSQL est démarré
|
|
|
|
# Terminal 2 : Redis
|
|
redis-server
|
|
|
|
# Terminal 3 : Backend API
|
|
cd apps/backend
|
|
npm run dev
|
|
```
|
|
|
|
L'API sera disponible sur : **http://localhost:4000**
|
|
|
|
### 2. Configurer les Variables d'Environnement
|
|
|
|
La collection utilise les variables suivantes :
|
|
|
|
| Variable | Valeur par défaut | Description |
|
|
|----------|-------------------|-------------|
|
|
| `baseUrl` | `http://localhost:4000` | URL de base de l'API |
|
|
| `rateQuoteId` | (auto) | ID du tarif (sauvegardé automatiquement) |
|
|
| `bookingId` | (auto) | ID de la réservation (auto) |
|
|
| `bookingNumber` | (auto) | Numéro de réservation (auto) |
|
|
|
|
**Note :** Les variables `rateQuoteId`, `bookingId` et `bookingNumber` sont automatiquement sauvegardées après les requêtes correspondantes.
|
|
|
|
---
|
|
|
|
## 📋 Scénario de Test Complet
|
|
|
|
### Étape 1 : Rechercher des Tarifs Maritimes
|
|
|
|
**Requête :** `POST /api/v1/rates/search`
|
|
|
|
**Dossier :** Rates API → Search Rates - Rotterdam to Shanghai
|
|
|
|
**Corps de la requête :**
|
|
```json
|
|
{
|
|
"origin": "NLRTM",
|
|
"destination": "CNSHA",
|
|
"containerType": "40HC",
|
|
"mode": "FCL",
|
|
"departureDate": "2025-02-15",
|
|
"quantity": 2,
|
|
"weight": 20000,
|
|
"isHazmat": false
|
|
}
|
|
```
|
|
|
|
**Codes de port courants :**
|
|
- `NLRTM` - Rotterdam, Pays-Bas
|
|
- `CNSHA` - Shanghai, Chine
|
|
- `DEHAM` - Hamburg, Allemagne
|
|
- `USLAX` - Los Angeles, États-Unis
|
|
- `SGSIN` - Singapore
|
|
- `USNYC` - New York, États-Unis
|
|
- `GBSOU` - Southampton, Royaume-Uni
|
|
|
|
**Types de conteneurs :**
|
|
- `20DRY` - Conteneur 20 pieds standard
|
|
- `20HC` - Conteneur 20 pieds High Cube
|
|
- `40DRY` - Conteneur 40 pieds standard
|
|
- `40HC` - Conteneur 40 pieds High Cube (le plus courant)
|
|
- `40REEFER` - Conteneur 40 pieds réfrigéré
|
|
- `45HC` - Conteneur 45 pieds High Cube
|
|
|
|
**Réponse attendue (200 OK) :**
|
|
```json
|
|
{
|
|
"quotes": [
|
|
{
|
|
"id": "550e8400-e29b-41d4-a716-446655440000",
|
|
"carrierId": "...",
|
|
"carrierName": "Maersk Line",
|
|
"carrierCode": "MAERSK",
|
|
"origin": {
|
|
"code": "NLRTM",
|
|
"name": "Rotterdam",
|
|
"country": "Netherlands"
|
|
},
|
|
"destination": {
|
|
"code": "CNSHA",
|
|
"name": "Shanghai",
|
|
"country": "China"
|
|
},
|
|
"pricing": {
|
|
"baseFreight": 1500.0,
|
|
"surcharges": [
|
|
{
|
|
"type": "BAF",
|
|
"description": "Bunker Adjustment Factor",
|
|
"amount": 150.0,
|
|
"currency": "USD"
|
|
}
|
|
],
|
|
"totalAmount": 1700.0,
|
|
"currency": "USD"
|
|
},
|
|
"containerType": "40HC",
|
|
"mode": "FCL",
|
|
"etd": "2025-02-15T10:00:00Z",
|
|
"eta": "2025-03-17T14:00:00Z",
|
|
"transitDays": 30,
|
|
"route": [...],
|
|
"availability": 85,
|
|
"frequency": "Weekly"
|
|
}
|
|
],
|
|
"count": 5,
|
|
"fromCache": false,
|
|
"responseTimeMs": 234
|
|
}
|
|
```
|
|
|
|
**✅ Tests automatiques :**
|
|
- Vérifie le status code 200
|
|
- Vérifie la présence du tableau `quotes`
|
|
- Vérifie le temps de réponse < 3s
|
|
- **Sauvegarde automatiquement le premier `rateQuoteId`** pour l'étape suivante
|
|
|
|
**💡 Note :** Le `rateQuoteId` est **indispensable** pour créer une réservation !
|
|
|
|
---
|
|
|
|
### Étape 2 : Créer une Réservation
|
|
|
|
**Requête :** `POST /api/v1/bookings`
|
|
|
|
**Dossier :** Bookings API → Create Booking
|
|
|
|
**Prérequis :** Avoir exécuté l'étape 1 pour obtenir un `rateQuoteId`
|
|
|
|
**Corps de la requête :**
|
|
```json
|
|
{
|
|
"rateQuoteId": "{{rateQuoteId}}",
|
|
"shipper": {
|
|
"name": "Acme Corporation",
|
|
"address": {
|
|
"street": "123 Main Street",
|
|
"city": "Rotterdam",
|
|
"postalCode": "3000 AB",
|
|
"country": "NL"
|
|
},
|
|
"contactName": "John Doe",
|
|
"contactEmail": "john.doe@acme.com",
|
|
"contactPhone": "+31612345678"
|
|
},
|
|
"consignee": {
|
|
"name": "Shanghai Imports Ltd",
|
|
"address": {
|
|
"street": "456 Trade Avenue",
|
|
"city": "Shanghai",
|
|
"postalCode": "200000",
|
|
"country": "CN"
|
|
},
|
|
"contactName": "Jane Smith",
|
|
"contactEmail": "jane.smith@shanghai-imports.cn",
|
|
"contactPhone": "+8613812345678"
|
|
},
|
|
"cargoDescription": "Electronics and consumer goods for retail distribution",
|
|
"containers": [
|
|
{
|
|
"type": "40HC",
|
|
"containerNumber": "ABCU1234567",
|
|
"vgm": 22000,
|
|
"sealNumber": "SEAL123456"
|
|
}
|
|
],
|
|
"specialInstructions": "Please handle with care. Delivery before 5 PM."
|
|
}
|
|
```
|
|
|
|
**Réponse attendue (201 Created) :**
|
|
```json
|
|
{
|
|
"id": "550e8400-e29b-41d4-a716-446655440001",
|
|
"bookingNumber": "WCM-2025-ABC123",
|
|
"status": "draft",
|
|
"shipper": {...},
|
|
"consignee": {...},
|
|
"cargoDescription": "Electronics and consumer goods for retail distribution",
|
|
"containers": [
|
|
{
|
|
"id": "...",
|
|
"type": "40HC",
|
|
"containerNumber": "ABCU1234567",
|
|
"vgm": 22000,
|
|
"sealNumber": "SEAL123456"
|
|
}
|
|
],
|
|
"specialInstructions": "Please handle with care. Delivery before 5 PM.",
|
|
"rateQuote": {
|
|
"id": "550e8400-e29b-41d4-a716-446655440000",
|
|
"carrierName": "Maersk Line",
|
|
"origin": {...},
|
|
"destination": {...},
|
|
"pricing": {...}
|
|
},
|
|
"createdAt": "2025-02-15T10:00:00Z",
|
|
"updatedAt": "2025-02-15T10:00:00Z"
|
|
}
|
|
```
|
|
|
|
**✅ Tests automatiques :**
|
|
- Vérifie le status code 201
|
|
- Vérifie la présence de `id` et `bookingNumber`
|
|
- Vérifie le format du numéro : `WCM-YYYY-XXXXXX`
|
|
- Vérifie que le statut initial est `draft`
|
|
- **Sauvegarde automatiquement `bookingId` et `bookingNumber`**
|
|
|
|
**Statuts de réservation possibles :**
|
|
- `draft` → Brouillon (modifiable)
|
|
- `pending_confirmation` → En attente de confirmation transporteur
|
|
- `confirmed` → Confirmé par le transporteur
|
|
- `in_transit` → En transit
|
|
- `delivered` → Livré (état final)
|
|
- `cancelled` → Annulé (état final)
|
|
|
|
---
|
|
|
|
### Étape 3 : Consulter une Réservation par ID
|
|
|
|
**Requête :** `GET /api/v1/bookings/{{bookingId}}`
|
|
|
|
**Dossier :** Bookings API → Get Booking by ID
|
|
|
|
**Prérequis :** Avoir exécuté l'étape 2
|
|
|
|
Aucun corps de requête nécessaire. Le `bookingId` est automatiquement utilisé depuis les variables d'environnement.
|
|
|
|
**Réponse attendue (200 OK) :** Même structure que la création
|
|
|
|
---
|
|
|
|
### Étape 4 : Consulter une Réservation par Numéro
|
|
|
|
**Requête :** `GET /api/v1/bookings/number/{{bookingNumber}}`
|
|
|
|
**Dossier :** Bookings API → Get Booking by Booking Number
|
|
|
|
**Prérequis :** Avoir exécuté l'étape 2
|
|
|
|
Exemple de numéro : `WCM-2025-ABC123`
|
|
|
|
**Avantage :** Format plus convivial que l'UUID pour les utilisateurs finaux.
|
|
|
|
---
|
|
|
|
### Étape 5 : Lister les Réservations avec Pagination
|
|
|
|
**Requête :** `GET /api/v1/bookings?page=1&pageSize=20`
|
|
|
|
**Dossier :** Bookings API → List Bookings (Paginated)
|
|
|
|
**Paramètres de requête :**
|
|
- `page` : Numéro de page (défaut : 1)
|
|
- `pageSize` : Nombre d'éléments par page (défaut : 20, max : 100)
|
|
- `status` : Filtrer par statut (optionnel)
|
|
|
|
**Exemples d'URLs :**
|
|
```
|
|
GET /api/v1/bookings?page=1&pageSize=20
|
|
GET /api/v1/bookings?page=2&pageSize=10
|
|
GET /api/v1/bookings?page=1&pageSize=20&status=draft
|
|
GET /api/v1/bookings?status=confirmed
|
|
```
|
|
|
|
**Réponse attendue (200 OK) :**
|
|
```json
|
|
{
|
|
"bookings": [
|
|
{
|
|
"id": "...",
|
|
"bookingNumber": "WCM-2025-ABC123",
|
|
"status": "draft",
|
|
"shipperName": "Acme Corporation",
|
|
"consigneeName": "Shanghai Imports Ltd",
|
|
"originPort": "NLRTM",
|
|
"destinationPort": "CNSHA",
|
|
"carrierName": "Maersk Line",
|
|
"etd": "2025-02-15T10:00:00Z",
|
|
"eta": "2025-03-17T14:00:00Z",
|
|
"totalAmount": 1700.0,
|
|
"currency": "USD",
|
|
"createdAt": "2025-02-15T10:00:00Z"
|
|
}
|
|
],
|
|
"total": 25,
|
|
"page": 1,
|
|
"pageSize": 20,
|
|
"totalPages": 2
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## ❌ Tests d'Erreurs
|
|
|
|
### Test 1 : Code de Port Invalide
|
|
|
|
**Requête :** Rates API → Search Rates - Invalid Port Code (Error)
|
|
|
|
**Corps de la requête :**
|
|
```json
|
|
{
|
|
"origin": "INVALID",
|
|
"destination": "CNSHA",
|
|
"containerType": "40HC",
|
|
"mode": "FCL",
|
|
"departureDate": "2025-02-15"
|
|
}
|
|
```
|
|
|
|
**Réponse attendue (400 Bad Request) :**
|
|
```json
|
|
{
|
|
"statusCode": 400,
|
|
"message": [
|
|
"Origin must be a valid 5-character UN/LOCODE (e.g., NLRTM)"
|
|
],
|
|
"error": "Bad Request"
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
### Test 2 : Validation de Réservation
|
|
|
|
**Requête :** Bookings API → Create Booking - Validation Error
|
|
|
|
**Corps de la requête :**
|
|
```json
|
|
{
|
|
"rateQuoteId": "invalid-uuid",
|
|
"shipper": {
|
|
"name": "A",
|
|
"address": {
|
|
"street": "123",
|
|
"city": "R",
|
|
"postalCode": "3000",
|
|
"country": "INVALID"
|
|
},
|
|
"contactName": "J",
|
|
"contactEmail": "invalid-email",
|
|
"contactPhone": "123"
|
|
},
|
|
"consignee": {...},
|
|
"cargoDescription": "Short",
|
|
"containers": []
|
|
}
|
|
```
|
|
|
|
**Réponse attendue (400 Bad Request) :**
|
|
```json
|
|
{
|
|
"statusCode": 400,
|
|
"message": [
|
|
"Rate quote ID must be a valid UUID",
|
|
"Name must be at least 2 characters",
|
|
"Contact email must be a valid email address",
|
|
"Contact phone must be a valid international phone number",
|
|
"Country must be a valid 2-letter ISO country code",
|
|
"Cargo description must be at least 10 characters"
|
|
],
|
|
"error": "Bad Request"
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## 📊 Variables d'Environnement Postman
|
|
|
|
### Configuration Recommandée
|
|
|
|
1. Créez un **Environment** nommé "Xpeditis Local"
|
|
2. Ajoutez les variables suivantes :
|
|
|
|
| Variable | Type | Valeur Initiale | Valeur Courante |
|
|
|----------|------|-----------------|-----------------|
|
|
| `baseUrl` | default | `http://localhost:4000` | `http://localhost:4000` |
|
|
| `rateQuoteId` | default | (vide) | (auto-rempli) |
|
|
| `bookingId` | default | (vide) | (auto-rempli) |
|
|
| `bookingNumber` | default | (vide) | (auto-rempli) |
|
|
|
|
3. Sélectionnez l'environnement "Xpeditis Local" dans Postman
|
|
|
|
---
|
|
|
|
## 🔍 Tests Automatiques Intégrés
|
|
|
|
Chaque requête contient des **tests automatiques** dans l'onglet "Tests" :
|
|
|
|
```javascript
|
|
// Exemple de tests intégrés
|
|
pm.test("Status code is 200", function () {
|
|
pm.response.to.have.status(200);
|
|
});
|
|
|
|
pm.test("Response has quotes array", function () {
|
|
var jsonData = pm.response.json();
|
|
pm.expect(jsonData).to.have.property('quotes');
|
|
pm.expect(jsonData.quotes).to.be.an('array');
|
|
});
|
|
|
|
// Sauvegarde automatique de variables
|
|
pm.environment.set("rateQuoteId", pm.response.json().quotes[0].id);
|
|
```
|
|
|
|
**Voir les résultats :**
|
|
- Onglet **"Test Results"** après chaque requête
|
|
- Indicateurs ✅ ou ❌ pour chaque test
|
|
|
|
---
|
|
|
|
## 🚨 Dépannage
|
|
|
|
### Erreur : "Cannot connect to server"
|
|
|
|
**Cause :** Le serveur backend n'est pas démarré
|
|
|
|
**Solution :**
|
|
```bash
|
|
cd apps/backend
|
|
npm run dev
|
|
```
|
|
|
|
Vérifiez que vous voyez : `[Nest] Application is running on: http://localhost:4000`
|
|
|
|
---
|
|
|
|
### Erreur : "rateQuoteId is not defined"
|
|
|
|
**Cause :** Vous essayez de créer une réservation sans avoir recherché de tarif
|
|
|
|
**Solution :** Exécutez d'abord **"Search Rates - Rotterdam to Shanghai"**
|
|
|
|
---
|
|
|
|
### Erreur 500 : "Internal Server Error"
|
|
|
|
**Cause possible :**
|
|
1. Base de données PostgreSQL non démarrée
|
|
2. Redis non démarré
|
|
3. Variables d'environnement manquantes
|
|
|
|
**Solution :**
|
|
```bash
|
|
# Vérifier PostgreSQL
|
|
psql -U postgres -h localhost
|
|
|
|
# Vérifier Redis
|
|
redis-cli ping
|
|
# Devrait retourner: PONG
|
|
|
|
# Vérifier les variables d'environnement
|
|
cat apps/backend/.env
|
|
```
|
|
|
|
---
|
|
|
|
### Erreur 404 : "Not Found"
|
|
|
|
**Cause :** L'ID ou le numéro de réservation n'existe pas
|
|
|
|
**Solution :** Vérifiez que vous avez créé une réservation avant de la consulter
|
|
|
|
---
|
|
|
|
## 📈 Utilisation Avancée
|
|
|
|
### Exécuter Toute la Collection
|
|
|
|
1. Cliquez sur les **"..."** à côté du nom de la collection
|
|
2. Sélectionnez **"Run collection"**
|
|
3. Sélectionnez les requêtes à exécuter
|
|
4. Cliquez sur **"Run Xpeditis API"**
|
|
|
|
**Ordre recommandé :**
|
|
1. Search Rates - Rotterdam to Shanghai
|
|
2. Create Booking
|
|
3. Get Booking by ID
|
|
4. Get Booking by Booking Number
|
|
5. List Bookings (Paginated)
|
|
|
|
---
|
|
|
|
### Newman (CLI Postman)
|
|
|
|
Pour automatiser les tests en ligne de commande :
|
|
|
|
```bash
|
|
# Installer Newman
|
|
npm install -g newman
|
|
|
|
# Exécuter la collection
|
|
newman run postman/Xpeditis_API.postman_collection.json \
|
|
--environment postman/Xpeditis_Local.postman_environment.json
|
|
|
|
# Avec rapport HTML
|
|
newman run postman/Xpeditis_API.postman_collection.json \
|
|
--reporters cli,html \
|
|
--reporter-html-export newman-report.html
|
|
```
|
|
|
|
---
|
|
|
|
## 📚 Ressources Supplémentaires
|
|
|
|
### Documentation API Complète
|
|
|
|
Voir : `apps/backend/docs/API.md`
|
|
|
|
### Codes de Port UN/LOCODE
|
|
|
|
Liste complète : https://unece.org/trade/cefact/unlocode-code-list-country-and-territory
|
|
|
|
**Codes courants :**
|
|
- Europe : NLRTM (Rotterdam), DEHAM (Hamburg), GBSOU (Southampton)
|
|
- Asie : CNSHA (Shanghai), SGSIN (Singapore), HKHKG (Hong Kong)
|
|
- Amérique : USLAX (Los Angeles), USNYC (New York), USHOU (Houston)
|
|
|
|
### Classes IMO (Marchandises Dangereuses)
|
|
|
|
1. Explosifs
|
|
2. Gaz
|
|
3. Liquides inflammables
|
|
4. Solides inflammables
|
|
5. Substances comburantes
|
|
6. Substances toxiques
|
|
7. Matières radioactives
|
|
8. Substances corrosives
|
|
9. Matières dangereuses diverses
|
|
|
|
---
|
|
|
|
## ✅ Checklist de Test
|
|
|
|
- [ ] Recherche de tarifs Rotterdam → Shanghai
|
|
- [ ] Recherche de tarifs avec autres ports
|
|
- [ ] Recherche avec marchandises dangereuses
|
|
- [ ] Test de validation (code port invalide)
|
|
- [ ] Création de réservation complète
|
|
- [ ] Consultation par ID
|
|
- [ ] Consultation par numéro de réservation
|
|
- [ ] Liste paginée (page 1)
|
|
- [ ] Liste avec filtre de statut
|
|
- [ ] Test de validation (réservation invalide)
|
|
- [ ] Vérification des tests automatiques
|
|
- [ ] Temps de réponse acceptable (<3s pour recherche)
|
|
|
|
---
|
|
|
|
**Version :** 1.0
|
|
**Dernière mise à jour :** Février 2025
|
|
**Statut :** Phase 1 MVP - Tests Fonctionnels
|