{"openapi":"3.0.0","paths":{"/api/v1/health":{"get":{"operationId":"HealthController_health","summary":"Liveness + DB connectivity","parameters":[],"responses":{"200":{"description":""}},"tags":["Health"]}},"/api/v1/health/ready":{"get":{"operationId":"HealthController_ready","summary":"Readiness — DB + cache reachable","parameters":[],"responses":{"200":{"description":""}},"tags":["Health"]}},"/api/v1/cod/wallet":{"get":{"operationId":"CodController_wallet","summary":"Solde du portefeuille COD du marchand","parameters":[],"responses":{"200":{"description":""}},"tags":["COD"],"security":[{"bearer":[]}]}},"/api/v1/cod/transactions":{"get":{"operationId":"CodController_transactions","summary":"Historique des transactions COD (paginé)","parameters":[{"name":"page","required":false,"in":"query","schema":{"type":"number"}},{"name":"limit","required":false,"in":"query","schema":{"type":"number"}},{"name":"type","required":false,"in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"tags":["COD"],"security":[{"bearer":[]}]}},"/api/v1/cod/payouts":{"get":{"operationId":"CodController_payouts","summary":"Liste des demandes de virement","parameters":[{"name":"page","required":true,"in":"query","schema":{"type":"string"}},{"name":"limit","required":true,"in":"query","schema":{"type":"string"}},{"name":"status","required":true,"in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"tags":["COD"],"security":[{"bearer":[]}]},"post":{"operationId":"CodController_requestPayout","summary":"Créer une demande de virement (marchand)","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreatePayoutDto"}}}},"responses":{"201":{"description":""}},"tags":["COD"],"security":[{"bearer":[]}]}},"/api/v1/cod/payouts/{id}/approve":{"patch":{"operationId":"CodController_approve","summary":"Approuver une demande de virement (finance/ops)","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"tags":["COD"],"security":[{"bearer":[]}]}},"/api/v1/cod/payouts/{id}/reject":{"patch":{"operationId":"CodController_reject","summary":"Rejeter une demande de virement (finance/ops)","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RejectPayoutDto"}}}},"responses":{"200":{"description":""}},"tags":["COD"],"security":[{"bearer":[]}]}},"/api/v1/cod/report":{"get":{"operationId":"CodController_report","summary":"Synthèse de règlement COD du marchand","parameters":[],"responses":{"200":{"description":""}},"tags":["COD"],"security":[{"bearer":[]}]}},"/api/v1/notifications":{"get":{"operationId":"NotificationController_list","summary":"Liste des notifications du tenant (paginé)","parameters":[{"name":"page","required":false,"in":"query","schema":{"type":"number"}},{"name":"limit","required":false,"in":"query","schema":{"type":"number"}},{"name":"status","required":false,"in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"tags":["Notifications"],"security":[{"bearer":[]}]}},"/api/v1/notifications/templates":{"get":{"operationId":"NotificationController_templates","summary":"Catalogue des modèles de notification","parameters":[],"responses":{"200":{"description":""}},"tags":["Notifications"],"security":[{"bearer":[]}]}},"/api/v1/notifications/send":{"post":{"operationId":"NotificationController_send","summary":"Envoyer une notification (dispatchée via provider)","parameters":[],"responses":{"201":{"description":""}},"tags":["Notifications"],"security":[{"bearer":[]}]}},"/api/v1/notifications/{id}/read":{"patch":{"operationId":"NotificationController_markRead","summary":"Marquer une notification comme lue","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"tags":["Notifications"],"security":[{"bearer":[]}]}},"/api/v1/relay/points":{"get":{"operationId":"RelayController_points","summary":"Lister les points relais","parameters":[],"responses":{"200":{"description":""}},"tags":["Relay"],"security":[{"bearer":[]}]}},"/api/v1/relay/points/{id}":{"get":{"operationId":"RelayController_point","summary":"Détails d’un point relais","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"tags":["Relay"],"security":[{"bearer":[]}]},"patch":{"operationId":"RelayController_updatePoint","summary":"Mettre à jour un point relais (capacité/statut/horaires)","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdatePointDto"}}}},"responses":{"200":{"description":""}},"tags":["Relay"],"security":[{"bearer":[]}]}},"/api/v1/relay/inventory":{"get":{"operationId":"RelayController_inventory","summary":"Colis actuellement détenus au point relais","parameters":[],"responses":{"200":{"description":""}},"tags":["Relay"],"security":[{"bearer":[]}]}},"/api/v1/relay/scan-arrival":{"post":{"operationId":"RelayController_scanArrival","summary":"Scanner l’arrivée d’un colis (génère le code de retrait)","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ScanArrivalDto"}}}},"responses":{"200":{"description":""}},"tags":["Relay"],"security":[{"bearer":[]}]}},"/api/v1/relay/scan-pickup":{"post":{"operationId":"RelayController_scanPickup","summary":"Scanner le retrait par le client (QR / code)","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ScanPickupDto"}}}},"responses":{"200":{"description":""}},"tags":["Relay"],"security":[{"bearer":[]}]}},"/api/v1/relay/wallet":{"get":{"operationId":"RelayController_wallet","summary":"Portefeuille / commission du partenaire relais","parameters":[],"responses":{"200":{"description":""}},"tags":["Relay"],"security":[{"bearer":[]}]}},"/api/v1/analytics/overview":{"get":{"operationId":"AnalyticsController_overview","summary":"KPIs (role-scoped: marchand = ses données, ops = tenant)","parameters":[],"responses":{"200":{"description":""}},"tags":["Analytics"],"security":[{"bearer":[]}]}},"/api/v1/analytics/revenue":{"get":{"operationId":"AnalyticsController_revenue","summary":"Revenu COD + série temporelle (ops/admin)","parameters":[{"name":"days","required":false,"in":"query","schema":{"type":"number"}}],"responses":{"200":{"description":""}},"tags":["Analytics"],"security":[{"bearer":[]}]}},"/api/v1/analytics/forecast":{"get":{"operationId":"AnalyticsController_forecast","summary":"Prévision (placeholder — modèle IA en PHASE 6)","parameters":[{"name":"days","required":false,"in":"query","schema":{"type":"number"}}],"responses":{"200":{"description":""}},"tags":["Analytics"],"security":[{"bearer":[]}]}},"/api/v1/company/overview":{"get":{"operationId":"CompanyController_overview","summary":"Tableau de bord agrégé de la société (tenant)","parameters":[],"responses":{"200":{"description":""}},"tags":["Company"],"security":[{"bearer":[]}]}},"/api/v1/company/shipments":{"get":{"operationId":"CompanyController_shipments","summary":"Expéditions de la société (paginé)","parameters":[{"name":"page","required":false,"in":"query","schema":{"type":"number"}},{"name":"limit","required":false,"in":"query","schema":{"type":"number"}},{"name":"status","required":false,"in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"tags":["Company"],"security":[{"bearer":[]}]}},"/api/v1/company/drivers":{"get":{"operationId":"CompanyController_drivers","summary":"Livreurs de la société + statistiques","parameters":[],"responses":{"200":{"description":""}},"tags":["Company"],"security":[{"bearer":[]}]}},"/api/v1/company/sla":{"get":{"operationId":"CompanyController_sla","summary":"Indicateurs SLA (livraison à temps, taux d’échec)","parameters":[],"responses":{"200":{"description":""}},"tags":["Company"],"security":[{"bearer":[]}]}},"/api/v1/company/settings":{"patch":{"operationId":"CompanyController_settings","summary":"Mettre à jour les paramètres de la société","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateCompanySettingsDto"}}}},"responses":{"200":{"description":""}},"tags":["Company"],"security":[{"bearer":[]}]}},"/api/v1/client/profile":{"get":{"operationId":"ClientController_profile","summary":"Profil client","parameters":[],"responses":{"200":{"description":""},"401":{"description":"JWT manquant, expiré ou session révoquée"},"403":{"description":"Permission RBAC insuffisante (ou hors tenant)"}},"tags":["Client"],"security":[{"bearer":[]}]},"patch":{"operationId":"ClientController_updateProfile","summary":"Mettre à jour le profil","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateProfileDto"}}}},"responses":{"200":{"description":""},"401":{"description":"JWT manquant, expiré ou session révoquée"},"403":{"description":"Permission RBAC insuffisante (ou hors tenant)"}},"tags":["Client"],"security":[{"bearer":[]}]}},"/api/v1/client/dashboard":{"get":{"operationId":"ClientController_dashboard","summary":"Tableau de bord client","parameters":[],"responses":{"200":{"description":""},"401":{"description":"JWT manquant, expiré ou session révoquée"},"403":{"description":"Permission RBAC insuffisante (ou hors tenant)"}},"tags":["Client"],"security":[{"bearer":[]}]}},"/api/v1/client/shipments":{"get":{"operationId":"ClientController_shipments","summary":"Mes expéditions","parameters":[{"name":"status","required":true,"in":"query","schema":{"type":"string"}},{"name":"page","required":true,"in":"query","schema":{"type":"string"}},{"name":"limit","required":true,"in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":""},"401":{"description":"JWT manquant, expiré ou session révoquée"},"403":{"description":"Permission RBAC insuffisante (ou hors tenant)"}},"tags":["Client"],"security":[{"bearer":[]}]}},"/api/v1/client/shipments/{trackingNumber}":{"get":{"operationId":"ClientController_shipmentDetail","summary":"Détails + timeline d’une expédition","parameters":[{"name":"trackingNumber","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""},"401":{"description":"JWT manquant, expiré ou session révoquée"},"403":{"description":"Permission RBAC insuffisante (ou hors tenant)"}},"tags":["Client"],"security":[{"bearer":[]}]}},"/api/v1/client/addresses":{"get":{"operationId":"ClientController_addresses","summary":"Carnet d’adresses","parameters":[],"responses":{"200":{"description":""},"401":{"description":"JWT manquant, expiré ou session révoquée"},"403":{"description":"Permission RBAC insuffisante (ou hors tenant)"}},"tags":["Client"],"security":[{"bearer":[]}]},"post":{"operationId":"ClientController_createAddress","summary":"Ajouter une adresse","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateAddressDto"}}}},"responses":{"201":{"description":""},"401":{"description":"JWT manquant, expiré ou session révoquée"},"403":{"description":"Permission RBAC insuffisante (ou hors tenant)"}},"tags":["Client"],"security":[{"bearer":[]}]}},"/api/v1/client/addresses/{id}":{"patch":{"operationId":"ClientController_updateAddress","summary":"Modifier une adresse","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateAddressDto"}}}},"responses":{"200":{"description":""},"401":{"description":"JWT manquant, expiré ou session révoquée"},"403":{"description":"Permission RBAC insuffisante (ou hors tenant)"}},"tags":["Client"],"security":[{"bearer":[]}]},"delete":{"operationId":"ClientController_deleteAddress","summary":"Supprimer une adresse","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""},"401":{"description":"JWT manquant, expiré ou session révoquée"},"403":{"description":"Permission RBAC insuffisante (ou hors tenant)"}},"tags":["Client"],"security":[{"bearer":[]}]}},"/api/v1/client/claims":{"get":{"operationId":"ClientController_claims","summary":"Mes réclamations","parameters":[],"responses":{"200":{"description":""},"401":{"description":"JWT manquant, expiré ou session révoquée"},"403":{"description":"Permission RBAC insuffisante (ou hors tenant)"}},"tags":["Client"],"security":[{"bearer":[]}]},"post":{"operationId":"ClientController_createClaim","summary":"Ouvrir une réclamation","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateClaimDto"}}}},"responses":{"201":{"description":""},"401":{"description":"JWT manquant, expiré ou session révoquée"},"403":{"description":"Permission RBAC insuffisante (ou hors tenant)"}},"tags":["Client"],"security":[{"bearer":[]}]}},"/api/v1/client/claims/{id}":{"get":{"operationId":"ClientController_claim","summary":"Détails d’une réclamation","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""},"401":{"description":"JWT manquant, expiré ou session révoquée"},"403":{"description":"Permission RBAC insuffisante (ou hors tenant)"}},"tags":["Client"],"security":[{"bearer":[]}]}},"/api/v1/client/claims/{id}/messages":{"post":{"operationId":"ClientController_addMessage","summary":"Ajouter un message à une réclamation","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AddClaimMessageDto"}}}},"responses":{"201":{"description":""},"401":{"description":"JWT manquant, expiré ou session révoquée"},"403":{"description":"Permission RBAC insuffisante (ou hors tenant)"}},"tags":["Client"],"security":[{"bearer":[]}]}},"/api/v1/client/notifications":{"get":{"operationId":"ClientController_notifications","summary":"Mes notifications","parameters":[{"name":"page","required":true,"in":"query","schema":{"type":"string"}},{"name":"limit","required":true,"in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":""},"401":{"description":"JWT manquant, expiré ou session révoquée"},"403":{"description":"Permission RBAC insuffisante (ou hors tenant)"}},"tags":["Client"],"security":[{"bearer":[]}]}},"/api/v1/developer/api-keys":{"post":{"operationId":"DeveloperController_createKey","summary":"Créer une clé API (révélée une seule fois)","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateApiKeyDto"}}}},"responses":{"201":{"description":""},"401":{"description":"JWT manquant, expiré ou session révoquée"},"403":{"description":"Permission RBAC insuffisante (ou hors tenant)"}},"tags":["Developer"],"security":[{"bearer":[]}]},"get":{"operationId":"DeveloperController_listKeys","summary":"Lister les clés API (préfixe seulement)","parameters":[],"responses":{"200":{"description":""},"401":{"description":"JWT manquant, expiré ou session révoquée"},"403":{"description":"Permission RBAC insuffisante (ou hors tenant)"}},"tags":["Developer"],"security":[{"bearer":[]}]}},"/api/v1/developer/api-keys/{id}":{"delete":{"operationId":"DeveloperController_revokeKey","summary":"Révoquer une clé API","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""},"401":{"description":"JWT manquant, expiré ou session révoquée"},"403":{"description":"Permission RBAC insuffisante (ou hors tenant)"}},"tags":["Developer"],"security":[{"bearer":[]}]}},"/api/v1/developer/webhooks":{"post":{"operationId":"DeveloperController_createHook","summary":"Créer un webhook (signingSecret révélé une seule fois)","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateWebhookDto"}}}},"responses":{"201":{"description":""},"401":{"description":"JWT manquant, expiré ou session révoquée"},"403":{"description":"Permission RBAC insuffisante (ou hors tenant)"}},"tags":["Developer"],"security":[{"bearer":[]}]},"get":{"operationId":"DeveloperController_listHooks","summary":"Lister les webhooks","parameters":[],"responses":{"200":{"description":""},"401":{"description":"JWT manquant, expiré ou session révoquée"},"403":{"description":"Permission RBAC insuffisante (ou hors tenant)"}},"tags":["Developer"],"security":[{"bearer":[]}]}},"/api/v1/developer/webhooks/{id}":{"delete":{"operationId":"DeveloperController_revokeHook","summary":"Désactiver un webhook","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""},"401":{"description":"JWT manquant, expiré ou session révoquée"},"403":{"description":"Permission RBAC insuffisante (ou hors tenant)"}},"tags":["Developer"],"security":[{"bearer":[]}]}},"/api/v1/developer/webhooks/{id}/logs":{"get":{"operationId":"DeveloperController_hookLogs","summary":"Journal de livraison d’un webhook","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""},"401":{"description":"JWT manquant, expiré ou session révoquée"},"403":{"description":"Permission RBAC insuffisante (ou hors tenant)"}},"tags":["Developer"],"security":[{"bearer":[]}]}},"/api/v1/merchant-api/shipments":{"post":{"operationId":"MerchantApiController_create","summary":"Créer une expédition (API key)","parameters":[],"responses":{"201":{"description":""},"401":{"description":"Clé API manquante, invalide, expirée ou révoquée"},"403":{"description":"Scope de la clé API insuffisant"}},"tags":["Merchant API"],"security":[{"api-key":[]}]},"get":{"operationId":"MerchantApiController_list","summary":"Lister mes expéditions","parameters":[{"name":"status","required":true,"in":"query","schema":{"type":"string"}},{"name":"page","required":true,"in":"query","schema":{"type":"string"}},{"name":"limit","required":true,"in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":""},"401":{"description":"Clé API manquante, invalide, expirée ou révoquée"},"403":{"description":"Scope de la clé API insuffisant"}},"tags":["Merchant API"],"security":[{"api-key":[]}]}},"/api/v1/merchant-api/shipments/{id}":{"get":{"operationId":"MerchantApiController_get","summary":"Détails d’une expédition","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""},"401":{"description":"Clé API manquante, invalide, expirée ou révoquée"},"403":{"description":"Scope de la clé API insuffisant"}},"tags":["Merchant API"],"security":[{"api-key":[]}]}},"/api/v1/merchant-api/shipments/{id}/cancel":{"patch":{"operationId":"MerchantApiController_cancel","summary":"Annuler une expédition","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""},"401":{"description":"Clé API manquante, invalide, expirée ou révoquée"},"403":{"description":"Scope de la clé API insuffisant"}},"tags":["Merchant API"],"security":[{"api-key":[]}]}},"/api/v1/merchant-api/track/{trackingNumber}":{"get":{"operationId":"MerchantApiController_track","summary":"Suivi par numéro","parameters":[{"name":"trackingNumber","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""},"401":{"description":"Clé API manquante, invalide, expirée ou révoquée"},"403":{"description":"Scope de la clé API insuffisant"}},"tags":["Merchant API"],"security":[{"api-key":[]}]}},"/api/v1/merchant-api/import":{"post":{"operationId":"MerchantApiController_import","summary":"Import en masse (bulk create)","parameters":[],"responses":{"201":{"description":""},"401":{"description":"Clé API manquante, invalide, expirée ou révoquée"},"403":{"description":"Scope de la clé API insuffisant"}},"tags":["Merchant API"],"security":[{"api-key":[]}]}},"/api/v1/relay-api/scan-arrival":{"post":{"operationId":"RelayApiController_arrival","summary":"Scanner l’arrivée d’un colis (POS partenaire)","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ScanArrivalDto"}}}},"responses":{"201":{"description":""},"401":{"description":"Clé API manquante, invalide, expirée ou révoquée"},"403":{"description":"Scope de la clé API insuffisant"}},"tags":["Relay API"],"security":[{"api-key":[]}]}},"/api/v1/relay-api/scan-pickup":{"post":{"operationId":"RelayApiController_pickup","summary":"Scanner le retrait client","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ScanPickupDto"}}}},"responses":{"201":{"description":""},"401":{"description":"Clé API manquante, invalide, expirée ou révoquée"},"403":{"description":"Scope de la clé API insuffisant"}},"tags":["Relay API"],"security":[{"api-key":[]}]}},"/api/v1/relay-api/inventory":{"get":{"operationId":"RelayApiController_inventory","summary":"Stock détenu au point relais","parameters":[],"responses":{"200":{"description":""},"401":{"description":"Clé API manquante, invalide, expirée ou révoquée"},"403":{"description":"Scope de la clé API insuffisant"}},"tags":["Relay API"],"security":[{"api-key":[]}]}},"/api/v1/relay-api/capacity":{"get":{"operationId":"RelayApiController_capacity","summary":"Capacité / charge des points relais","parameters":[],"responses":{"200":{"description":""},"401":{"description":"Clé API manquante, invalide, expirée ou révoquée"},"403":{"description":"Scope de la clé API insuffisant"}},"tags":["Relay API"],"security":[{"api-key":[]}]}},"/api/v1/relay-api/commissions":{"get":{"operationId":"RelayApiController_commissions","summary":"Portefeuille / commissions du partenaire","parameters":[],"responses":{"200":{"description":""},"401":{"description":"Clé API manquante, invalide, expirée ou révoquée"},"403":{"description":"Scope de la clé API insuffisant"}},"tags":["Relay API"],"security":[{"api-key":[]}]}},"/api/v1/company-api/relay-points":{"get":{"operationId":"CompanyApiController_relayPoints","summary":"Réseau de points relais","parameters":[],"responses":{"200":{"description":""},"401":{"description":"Clé API manquante, invalide, expirée ou révoquée"},"403":{"description":"Scope de la clé API insuffisant"}},"tags":["Company API"],"security":[{"api-key":[]}]}},"/api/v1/company-api/relay-points/capacity":{"get":{"operationId":"CompanyApiController_capacity","summary":"Capacité des points relais","parameters":[],"responses":{"200":{"description":""},"401":{"description":"Clé API manquante, invalide, expirée ou révoquée"},"403":{"description":"Scope de la clé API insuffisant"}},"tags":["Company API"],"security":[{"api-key":[]}]}},"/api/v1/company-api/dropoff":{"post":{"operationId":"CompanyApiController_dropoff","summary":"Déposer un colis dans le réseau relais","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ScanArrivalDto"}}}},"responses":{"201":{"description":""},"401":{"description":"Clé API manquante, invalide, expirée ou révoquée"},"403":{"description":"Scope de la clé API insuffisant"}},"tags":["Company API"],"security":[{"api-key":[]}]}},"/api/v1/company-api/pickup":{"post":{"operationId":"CompanyApiController_pickup","summary":"Retrait depuis le réseau relais","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ScanPickupDto"}}}},"responses":{"201":{"description":""},"401":{"description":"Clé API manquante, invalide, expirée ou révoquée"},"403":{"description":"Scope de la clé API insuffisant"}},"tags":["Company API"],"security":[{"api-key":[]}]}},"/api/v1/company-api/drivers":{"get":{"operationId":"CompanyApiController_drivers","summary":"Livreurs de la société","parameters":[],"responses":{"200":{"description":""},"401":{"description":"Clé API manquante, invalide, expirée ou révoquée"},"403":{"description":"Scope de la clé API insuffisant"}},"tags":["Company API"],"security":[{"api-key":[]}]}},"/api/v1/company-api/cod":{"get":{"operationId":"CompanyApiController_cod","summary":"Rapport COD (tenant)","parameters":[],"responses":{"200":{"description":""},"401":{"description":"Clé API manquante, invalide, expirée ou révoquée"},"403":{"description":"Scope de la clé API insuffisant"}},"tags":["Company API"],"security":[{"api-key":[]}]}},"/api/v1/company-api/analytics":{"get":{"operationId":"CompanyApiController_analyticsOverview","summary":"KPIs de la société","parameters":[],"responses":{"200":{"description":""},"401":{"description":"Clé API manquante, invalide, expirée ou révoquée"},"403":{"description":"Scope de la clé API insuffisant"}},"tags":["Company API"],"security":[{"api-key":[]}]}},"/api/v1/company-api/subcontract/orders":{"post":{"operationId":"CompanyApiController_createSub","summary":"Créer un ordre de sous-traitance","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSubcontractDto"}}}},"responses":{"201":{"description":""},"401":{"description":"Clé API manquante, invalide, expirée ou révoquée"},"403":{"description":"Scope de la clé API insuffisant"}},"tags":["Company API"],"security":[{"api-key":[]}]},"get":{"operationId":"CompanyApiController_listSub","summary":"Lister les ordres de sous-traitance","parameters":[],"responses":{"200":{"description":""},"401":{"description":"Clé API manquante, invalide, expirée ou révoquée"},"403":{"description":"Scope de la clé API insuffisant"}},"tags":["Company API"],"security":[{"api-key":[]}]}},"/api/v1/company-api/subcontract/orders/{id}/accept":{"patch":{"operationId":"CompanyApiController_acceptSub","summary":"Accepter un ordre de sous-traitance","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""},"401":{"description":"Clé API manquante, invalide, expirée ou révoquée"},"403":{"description":"Scope de la clé API insuffisant"}},"tags":["Company API"],"security":[{"api-key":[]}]}},"/api/v1/company-api/subcontract/orders/{id}/cancel":{"patch":{"operationId":"CompanyApiController_cancelSub","summary":"Annuler un ordre de sous-traitance","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""},"401":{"description":"Clé API manquante, invalide, expirée ou révoquée"},"403":{"description":"Scope de la clé API insuffisant"}},"tags":["Company API"],"security":[{"api-key":[]}]}},"/api/v1/ai/forecast":{"get":{"operationId":"AiController_forecastEndpoint","summary":"COD collection forecast (linear trend + seasonality + confidence band)","parameters":[],"responses":{"200":{"description":""},"401":{"description":"JWT manquant, expiré ou session révoquée"},"403":{"description":"Permission RBAC insuffisante (ou hors tenant)"}},"tags":["AI"],"security":[{"bearer":[]}]}},"/api/v1/ai/insights":{"get":{"operationId":"AiController_insights","summary":"AI business insights — forecast + anomalies + narrative","parameters":[],"responses":{"200":{"description":""},"401":{"description":"JWT manquant, expiré ou session révoquée"},"403":{"description":"Permission RBAC insuffisante (ou hors tenant)"}},"tags":["AI"],"security":[{"bearer":[]}]}},"/api/v1/ai/fraud":{"get":{"operationId":"FraudController_getFraud","summary":"COD fraud risk scores (merchant: own; ops/admin: tenant-ranked)","parameters":[],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"object"}}}},"401":{"description":"JWT manquant, expiré ou session révoquée"},"403":{"description":"Permission RBAC insuffisante (ou hors tenant)"}},"tags":["AI"],"security":[{"bearer":[]}]}},"/api/v1/ai/dispatch/recommendations":{"get":{"operationId":"DispatchController_recommendations","summary":"Driver recommendations for unassigned shipments (recommendation only)","parameters":[{"name":"limit","required":false,"in":"query","description":"Max shipments to recommend for (1-100, default 25)","schema":{}}],"responses":{"200":{"description":""},"401":{"description":"JWT manquant, expiré ou session révoquée"},"403":{"description":"Permission RBAC insuffisante (ou hors tenant)"}},"tags":["AI"],"security":[{"bearer":[]}]}},"/api/v1/ai/routes/{missionId}":{"get":{"operationId":"RoutingController_optimize","summary":"Optimized stop sequence for a mission's driver workload (deterministic)","parameters":[{"name":"missionId","required":true,"in":"path","description":"Mission UUID (the driver's active workload is routed)","schema":{"type":"string"}}],"responses":{"200":{"description":""},"401":{"description":"JWT manquant, expiré ou session révoquée"},"403":{"description":"Permission RBAC insuffisante (ou hors tenant)"}},"tags":["AI"],"security":[{"bearer":[]}]}}},"info":{"title":"COLYA Core Service API","description":"Domain platform for COLYA — COD/Wallet, Notifications, Relay network, Analytics,\nCompany operations, Client portal and the Developer platform (API keys + webhooks).\n\n## Role APIs\n- **Merchant API** (`/merchant-api/*`, `X-Api-Key`) — external merchants: shipments, tracking, bulk import.\n  Dashboard merchant endpoints also use JWT: `COD`, `Analytics`, `Developer` (API keys & webhooks).\n- **Company Delivery API** (`/company-api/*`, `X-Api-Key`) — delivery companies: relay network, drivers,\n  COD, analytics, subcontracting. Internal company dashboard uses JWT under `Company`.\n- **Relay API** (`/relay-api/*`, `X-Api-Key`) — relay operators: scan arrival/pickup, inventory,\n  capacity, commissions. Internal relay dashboard uses JWT under `Relay`.\n- **Client API** (`/client/*`, JWT) — end customers: profile, addresses, claims, notifications, shipments.\n- **Admin API** (JWT + RBAC) — `COD` payout approvals, `Analytics` revenue/forecast, audit (auth-service).\n\n## Authentication\n- **JWT** (`Authorization: Bearer <token>`) — dashboards & portals (RBAC + tenant-scoped).\n- **API key** (`X-Api-Key: clk_live_<prefix>.<secret>`) — external partner integrations (scope-enforced).\n- **Internal secret** (`X-Internal-Secret`) — service-to-service event ingress only.\n\n## Versioning\nURI-versioned: all routes are under `/api/v1`. Responses carry `X-API-Version: v1`.\nSee `docs/api/API-VERSIONING.md`.","version":"1.0.0","contact":{"name":"COLYA Platform","url":"https://colya.ma","email":"developers@colya.ma"},"license":{"name":"Proprietary — © COLYA","url":"https://colya.ma"}},"tags":[{"name":"Merchant API","description":"External merchant integration — shipments, tracking, bulk import (X-Api-Key)"},{"name":"Company API","description":"External delivery-company integration — relay/drivers/COD/analytics/subcontracting (X-Api-Key)"},{"name":"Relay API","description":"External relay-operator integration — scan, inventory, capacity, commissions (X-Api-Key)"},{"name":"Client","description":"Client API — end-customer self-service portal (JWT)"},{"name":"COD","description":"COD wallet, transactions, payouts; payout approvals are Admin (JWT)"},{"name":"Analytics","description":"KPIs/overview (merchant) and revenue/forecast (Admin) (JWT)"},{"name":"AI","description":"AI Operations Suite — forecasting, insights, COD fraud scoring, smart dispatch, route optimization (JWT, RBAC analytics.forecast). Score/recommend only — never auto-acts."},{"name":"Company","description":"Company dashboard — overview, drivers, SLA, settings (JWT)"},{"name":"Relay","description":"Relay dashboard — points, inventory, scans, wallet (JWT)"},{"name":"Notifications","description":"Notification center & templates (JWT, ops)"},{"name":"Developer","description":"Developer platform — API keys & webhooks (JWT, merchant.api.manage)"},{"name":"Health","description":"Liveness/readiness probes"}],"servers":[{"url":"http://localhost:4003","description":"Local"},{"url":"https://api.colya.ma","description":"Production"}],"components":{"securitySchemes":{"bearer":{"scheme":"bearer","bearerFormat":"JWT","type":"http","description":"Merchant/company/relay/client/admin JWT"},"api-key":{"type":"apiKey","in":"header","name":"X-Api-Key","description":"Partner API key (clk_live_<prefix>.<secret>)"},"internal-secret":{"type":"apiKey","in":"header","name":"X-Internal-Secret","description":"Service-to-service only"}},"schemas":{"CreatePayoutDto":{"type":"object","properties":{"amount":{"type":"number","minimum":1},"bankAccount":{"type":"object","description":"Destination bank/RIB details (stored as JSON on the payout request)."},"note":{"type":"string"}},"required":["amount","bankAccount"]},"RejectPayoutDto":{"type":"object","properties":{"reason":{"type":"string"}}},"UpdatePointDto":{"type":"object","properties":{"capacity":{"type":"number","minimum":0},"status":{"type":"string"},"workingHours":{"type":"object"}}},"ScanArrivalDto":{"type":"object","properties":{"shipmentId":{"type":"string"},"relayPointId":{"type":"string","description":"Optional — defaults to the shipment's own relayPointId when omitted."}},"required":["shipmentId"]},"ScanPickupDto":{"type":"object","properties":{"qrCode":{"type":"string","description":"The pickup QR/code presented by the customer."}},"required":["qrCode"]},"UpdateCompanySettingsDto":{"type":"object","properties":{"settings":{"type":"object","description":"Partial settings object, shallow-merged into Tenant.settings (JSON)."}},"required":["settings"]},"UpdateProfileDto":{"type":"object","properties":{"displayName":{"type":"string","maxLength":80},"avatarUrl":{"type":"string"},"firstName":{"type":"string","maxLength":60},"lastName":{"type":"string","maxLength":60}}},"CreateAddressDto":{"type":"object","properties":{"label":{"type":"string","enum":["home","work","other"]},"contactName":{"type":"string","maxLength":120},"phone":{"type":"string"},"street":{"type":"string"},"district":{"type":"string"},"city":{"type":"string"},"postalCode":{"type":"string"},"lat":{"type":"number"},"lng":{"type":"number"},"isDefault":{"type":"boolean"}},"required":["label","contactName","phone","street","city"]},"UpdateAddressDto":{"type":"object","properties":{"label":{"type":"string","enum":["home","work","other"]},"contactName":{"type":"string"},"phone":{"type":"string"},"street":{"type":"string"},"district":{"type":"string"},"city":{"type":"string"},"postalCode":{"type":"string"},"lat":{"type":"number"},"lng":{"type":"number"},"isDefault":{"type":"boolean"}}},"CreateClaimDto":{"type":"object","properties":{"type":{"type":"string","enum":["late_delivery","damaged_parcel","missing_parcel","cod_issue","relay_issue"]},"subject":{"type":"string","minLength":3,"maxLength":140},"description":{"type":"string","minLength":3},"shipmentId":{"type":"string"}},"required":["type","subject","description"]},"AddClaimMessageDto":{"type":"object","properties":{"body":{"type":"string","minLength":1}},"required":["body"]},"CreateApiKeyDto":{"type":"object","properties":{"name":{"type":"string","maxLength":80},"scopes":{"type":"string","enum":["shipments:read","shipments:write","track:read","relay:read","relay:write","company:read","company:write","cod:read","analytics:read"]},"expiresAt":{"type":"string"}},"required":["name"]},"CreateWebhookDto":{"type":"object","properties":{"url":{"type":"string"},"events":{"type":"string","enum":["shipment.created","shipment.assigned","shipment.in_transit","shipment.cancelled","shipment.delivered","shipment.failed","shipment.returned","wallet.credited","wallet.debited","payout.requested","payout.approved","payout.rejected","relay.parcel.deposited","relay.parcel.picked_up"]}},"required":["url","events"]},"CreateSubcontractDto":{"type":"object","properties":{"shipmentId":{"type":"string"},"toType":{"type":"string","enum":["relay","driver","company"]},"toRef":{"type":"string"},"fee":{"type":"number","minimum":0},"notes":{"type":"string"}},"required":["toType"]}}}}