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>
9.7 KiB
CSV Rate API Testing Guide
Prerequisites
- Start the backend API:
cd /Users/david/Documents/xpeditis/dev/xpeditis2.0/apps/backend
npm run dev
- Ensure PostgreSQL and Redis are running:
docker-compose up -d
- Run database migrations (if not done):
npm run migration:run
Test Scenarios
1. Get Available Companies
Test that all 4 configured companies are returned:
curl -X GET http://localhost:4000/api/v1/rates/companies \
-H "Authorization: Bearer YOUR_JWT_TOKEN"
Expected Response:
{
"companies": ["SSC Consolidation", "ECU Worldwide", "TCC Logistics", "NVO Consolidation"],
"total": 4
}
2. Get Filter Options
Test that all filter options are available:
curl -X GET http://localhost:4000/api/v1/rates/filters/options \
-H "Authorization: Bearer YOUR_JWT_TOKEN"
Expected Response:
{
"companies": ["SSC Consolidation", "ECU Worldwide", "TCC Logistics", "NVO Consolidation"],
"containerTypes": ["LCL"],
"currencies": ["USD", "EUR"]
}
3. Search CSV Rates - Single Company
Test search for NLRTM → USNYC with 25 CBM, 3500 kg:
curl -X POST http://localhost:4000/api/v1/rates/search-csv \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_JWT_TOKEN" \
-d '{
"origin": "NLRTM",
"destination": "USNYC",
"volumeCBM": 25,
"weightKG": 3500,
"palletCount": 10,
"containerType": "LCL"
}'
Expected: Multiple results from SSC Consolidation, ECU Worldwide, TCC Logistics, NVO Consolidation
4. Search with Company Filter
Test filtering by specific company:
curl -X POST http://localhost:4000/api/v1/rates/search-csv \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_JWT_TOKEN" \
-d '{
"origin": "NLRTM",
"destination": "USNYC",
"volumeCBM": 25,
"weightKG": 3500,
"palletCount": 10,
"containerType": "LCL",
"filters": {
"companies": ["SSC Consolidation"]
}
}'
Expected: Only SSC Consolidation results
5. Search with Price Range Filter
Test filtering by price range (USD 1000-1500):
curl -X POST http://localhost:4000/api/v1/rates/search-csv \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_JWT_TOKEN" \
-d '{
"origin": "NLRTM",
"destination": "USNYC",
"volumeCBM": 25,
"weightKG": 3500,
"palletCount": 10,
"containerType": "LCL",
"filters": {
"minPrice": 1000,
"maxPrice": 1500,
"currency": "USD"
}
}'
Expected: Only rates between $1000-$1500
6. Search with Transit Days Filter
Test filtering by maximum transit days (25 days):
curl -X POST http://localhost:4000/api/v1/rates/search-csv \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_JWT_TOKEN" \
-d '{
"origin": "NLRTM",
"destination": "USNYC",
"volumeCBM": 25,
"weightKG": 3500,
"containerType": "LCL",
"filters": {
"maxTransitDays": 25
}
}'
Expected: Only rates with transit ≤ 25 days
7. Search with Surcharge Filters
Test excluding rates with surcharges:
curl -X POST http://localhost:4000/api/v1/rates/search-csv \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_JWT_TOKEN" \
-d '{
"origin": "NLRTM",
"destination": "USNYC",
"volumeCBM": 25,
"weightKG": 3500,
"containerType": "LCL",
"filters": {
"withoutSurcharges": true
}
}'
Expected: Only "all-in" rates without separate surcharges
Admin Endpoints (ADMIN Role Required)
8. Upload Test Maritime Express CSV
Upload the fictional carrier CSV:
curl -X POST http://localhost:4000/api/v1/admin/csv-rates/upload \
-H "Authorization: Bearer YOUR_ADMIN_JWT_TOKEN" \
-F "file=@/Users/david/Documents/xpeditis/dev/xpeditis2.0/apps/backend/src/infrastructure/storage/csv-storage/rates/test-maritime-express.csv" \
-F "companyName=Test Maritime Express" \
-F "fileDescription=Fictional carrier for testing comparator"
Expected Response:
{
"message": "CSV file uploaded and validated successfully",
"companyName": "Test Maritime Express",
"ratesLoaded": 25,
"validation": {
"valid": true,
"errors": []
}
}
9. Get All CSV Configurations
List all configured CSV carriers:
curl -X GET http://localhost:4000/api/v1/admin/csv-rates/config \
-H "Authorization: Bearer YOUR_ADMIN_JWT_TOKEN"
Expected: 5 configurations (SSC, ECU, TCC, NVO, Test Maritime Express)
10. Get Specific Company Configuration
Get Test Maritime Express config:
curl -X GET http://localhost:4000/api/v1/admin/csv-rates/config/Test%20Maritime%20Express \
-H "Authorization: Bearer YOUR_ADMIN_JWT_TOKEN"
Expected Response:
{
"id": "...",
"companyName": "Test Maritime Express",
"filePath": "rates/test-maritime-express.csv",
"isActive": true,
"lastUpdated": "2025-10-24T...",
"fileDescription": "Fictional carrier for testing comparator"
}
11. Validate CSV File
Validate a CSV file before uploading:
curl -X POST http://localhost:4000/api/v1/admin/csv-rates/validate/Test%20Maritime%20Express \
-H "Authorization: Bearer YOUR_ADMIN_JWT_TOKEN"
Expected Response:
{
"valid": true,
"companyName": "Test Maritime Express",
"totalRates": 25,
"errors": [],
"warnings": []
}
12. Delete CSV Configuration
Delete Test Maritime Express configuration:
curl -X DELETE http://localhost:4000/api/v1/admin/csv-rates/config/Test%20Maritime%20Express \
-H "Authorization: Bearer YOUR_ADMIN_JWT_TOKEN"
Expected Response:
{
"message": "CSV configuration deleted successfully",
"companyName": "Test Maritime Express"
}
Comparator Test Scenario
MAIN TEST: Verify multiple company offers appear
-
Upload Test Maritime Express CSV (see test #8 above)
-
Search for rates on competitive route (NLRTM → USNYC):
curl -X POST http://localhost:4000/api/v1/rates/search-csv \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_JWT_TOKEN" \
-d '{
"origin": "NLRTM",
"destination": "USNYC",
"volumeCBM": 25.5,
"weightKG": 3500,
"palletCount": 10,
"containerType": "LCL"
}'
- Expected Results (multiple companies with different prices):
| Company | Price (USD) | Transit Days | Notes |
|---|---|---|---|
| Test Maritime Express | ~$950 | 22 | "BEST DEAL" - Cheapest |
| SSC Consolidation | ~$1,100 | 22 | Standard pricing |
| ECU Worldwide | ~$1,150 | 23 | Slightly higher |
| TCC Logistics | ~$1,120 | 22 | Mid-range |
| NVO Consolidation | ~$1,130 | 22 | Standard |
-
Verification Points:
- ✅ All 5 companies appear in results
- ✅ Test Maritime Express shows lowest price (~10-20% cheaper)
- ✅ Each company shows different pricing
- ✅ Match scores are calculated (0-100%)
- ✅ Results can be sorted by price, transit, company, match score
- ✅ "All-in price" badge appears for Test Maritime Express rates (withoutSurcharges=true)
-
Test filtering by company:
curl -X POST http://localhost:4000/api/v1/rates/search-csv \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_JWT_TOKEN" \
-d '{
"origin": "NLRTM",
"destination": "USNYC",
"volumeCBM": 25.5,
"weightKG": 3500,
"palletCount": 10,
"containerType": "LCL",
"filters": {
"companies": ["Test Maritime Express", "SSC Consolidation"]
}
}'
Expected: Only Test Maritime Express and SSC Consolidation results
Test Checklist
- All 4 original companies return in /companies endpoint
- Filter options return correct values
- Basic rate search returns multiple results
- Company filter works correctly
- Price range filter works correctly
- Transit days filter works correctly
- Surcharge filter works correctly
- Admin can upload Test Maritime Express CSV
- Test Maritime Express appears in configurations
- Search returns results from all 5 companies
- Test Maritime Express shows competitive pricing
- Results can be sorted by different criteria
- Match scores are calculated correctly
- "All-in price" badge appears for rates without surcharges
Authentication
To get a JWT token for testing:
# Login as regular user
curl -X POST http://localhost:4000/api/v1/auth/login \
-H "Content-Type: application/json" \
-d '{
"email": "test4@xpeditis.com",
"password": "SecurePassword123"
}'
# Login as admin (if you have an admin account)
curl -X POST http://localhost:4000/api/v1/auth/login \
-H "Content-Type: application/json" \
-d '{
"email": "admin@xpeditis.com",
"password": "AdminPassword123"
}'
Copy the accessToken from the response and use it as YOUR_JWT_TOKEN or YOUR_ADMIN_JWT_TOKEN in the test commands above.
Notes
- All prices are calculated using freight class rule:
max(volumeCBM * pricePerCBM, weightKG * pricePerKG) + surcharges - Test Maritime Express rates are designed to be 10-20% cheaper than competitors
- Surcharges are automatically added to total price (BAF, CAF, etc.)
- Match scores indicate how well each rate matches the search criteria (100% = perfect match)
- Results are cached in Redis for 15 minutes (planned feature)