2026-03-06 19:30:45 +01:00
2026-03-06 17:16:24 +01:00
2026-03-03 23:42:23 +01:00
2026-03-03 23:42:23 +01:00
2026-03-06 19:29:49 +01:00
2026-03-05 19:09:16 +01:00
2026-03-06 19:30:45 +01:00
2026-03-03 23:42:23 +01:00
2026-03-01 14:43:57 +01:00
2026-03-01 17:30:08 +01:00
2026-02-28 23:23:54 +01:00
2026-02-28 23:23:54 +01:00
2026-03-05 19:09:16 +01:00
2026-02-07 22:33:02 +01:00

📚 Documentation API - Plateforme de Gestion de Commandes

Version: 4.0.0
Date: 2025-01-18
Base URL: http://localhost:8080
Technologies: Go, Gin, PostgreSQL, Redis, TomTom API


📋 Table des Matières

  1. Vue d'ensemble
  2. Authentication
  3. API Client (v1)
  4. API Admin (v2)
  5. API Cabine (v1)
  6. API Livreur (v1)
  7. Systeme GPS Integre
  8. Codes d'Erreur

🎯 Vue d'ensemble

Cette API REST complète gère une plateforme de livraison avec assignation automatique GPS des livreurs, suivi en temps réel, et système de pénalités avancé.

Fonctionnalités Principales

  • 🔐 Authentication JWT multi-rôles (Client, Admin, Livreur, Cabine)
  • 🚗 Auto-assignation GPS des livreurs les plus proches
  • 📍 Suivi temps réel avec ETA et géolocalisation
  • 🔄 Système de queues optimisé pour les livraisons
  • Workers automatiques (nettoyage, assignation, notifications)
  • 🎯 Système de pénalités pour la gestion des comportements

🏗️ Architecture Globale du Systeme

graph TB
    subgraph Frontend["🖥️ Frontend (React/TypeScript)"]
        UI_CLIENT[Interface Client]
        UI_ADMIN[Interface Admin]
        UI_LIVREUR[Interface Livreur]
        UI_CABINE[Interface Cabine]
        TOMTOM_MAP[TomTomMap Component]
    end

    subgraph API_GATEWAY["🌐 API Gateway (Go/Gin)"]
        AUTH[Middleware Auth JWT]
        ROUTES[Router]
    end

    subgraph API_V1["📱 API v1"]
        CLIENT_API["/api/v1/client"]
        LIVREUR_API["/api/v1/livreur"]
        CABINE_API["/api/v1/cabine"]
        PUBLIC_API["/api/v1/public"]
    end

    subgraph API_V2["👨‍💼 API v2 Admin"]
        ADMIN_API["/api/v2/admin"]
    end

    subgraph HANDLERS["⚙️ Handlers"]
        H_AUTH[Auth Handler]
        H_PRODUCT[Product Handler]
        H_PANIER[Panier Handler]
        H_COMMAND[Command Handler]
        H_DELIVERY[Delivery Handler]
        H_GPS[GPS Handler]
        H_ETA[ETA Handler]
        H_PENALTY[Penalty Handler]
    end

    subgraph SERVICES["🔧 Services"]
        S_GEO[Geo Service]
        S_TOMTOM[TomTom Service]
        S_QUEUE[Queue Service]
        S_NOTIF[Notification Service]
    end

    subgraph EXTERNAL["🌍 APIs Externes"]
        NOMINATIM[Nominatim API]
        TOMTOM_API[TomTom API]
    end

    subgraph STORAGE["💾 Stockage"]
        POSTGRES[(PostgreSQL)]
        REDIS[(Redis)]
    end

    subgraph WORKERS["⚡ Workers"]
        W_ASSIGN[Auto-Assign Worker]
        W_CLEANUP[Cleanup Worker]
        W_ETA[ETA Update Worker]
    end

    %% Frontend connections
    UI_CLIENT --> AUTH
    UI_ADMIN --> AUTH
    UI_LIVREUR --> AUTH
    UI_CABINE --> AUTH
    TOMTOM_MAP --> TOMTOM_API

    %% API Gateway
    AUTH --> ROUTES
    ROUTES --> API_V1
    ROUTES --> API_V2

    %% API to Handlers
    CLIENT_API --> H_AUTH
    CLIENT_API --> H_PANIER
    CLIENT_API --> H_COMMAND
    LIVREUR_API --> H_DELIVERY
    LIVREUR_API --> H_GPS
    CABINE_API --> H_COMMAND
    PUBLIC_API --> H_PRODUCT
    ADMIN_API --> H_COMMAND
    ADMIN_API --> H_DELIVERY
    ADMIN_API --> H_GPS
    ADMIN_API --> H_PENALTY

    %% Handlers to Services
    H_GPS --> S_GEO
    H_GPS --> S_TOMTOM
    H_ETA --> S_TOMTOM
    H_DELIVERY --> S_QUEUE
    H_COMMAND --> S_NOTIF

    %% Services to External
    S_GEO --> NOMINATIM
    S_TOMTOM --> TOMTOM_API

    %% Services to Storage
    S_GEO --> REDIS
    S_QUEUE --> REDIS
    H_COMMAND --> POSTGRES
    H_PRODUCT --> POSTGRES
    H_DELIVERY --> POSTGRES

    %% Workers
    W_ASSIGN --> S_GEO
    W_ASSIGN --> S_QUEUE
    W_ASSIGN --> POSTGRES
    W_CLEANUP --> REDIS
    W_CLEANUP --> POSTGRES
    W_ETA --> S_TOMTOM
    W_ETA --> REDIS

🔄 Flux des Donnees par Role

flowchart LR
    subgraph Client["👤 Client"]
        C1[Consulter Produits]
        C2[Gerer Panier]
        C3[Passer Commande]
        C4[Suivre Livraison]
        C5[Approuver/Annuler]
    end

    subgraph Admin["👨‍💼 Admin"]
        A1[Gerer Produits]
        A2[Voir Commandes]
        A3[Assigner Livreurs]
        A4[Gerer Penalites]
        A5[Surveiller GPS]
    end

    subgraph Livreur["🚚 Livreur"]
        L1[Voir Mes Livraisons]
        L2[Mettre a Jour Position]
        L3[Changer Statut]
        L4[Voir Ma Queue]
    end

    subgraph Cabine["🏭 Cabine/Cuisine"]
        K1[Voir Articles]
        K2[Preparer Commande]
        K3[Marquer Pret]
    end

    subgraph Backend["⚙️ Backend"]
        API[API REST]
        GPS[Service GPS]
        QUEUE[Gestion Queue]
    end

    C1 & C2 & C3 & C4 & C5 --> API
    A1 & A2 & A3 & A4 & A5 --> API
    L1 & L2 & L3 & L4 --> API
    K1 & K2 & K3 --> API
    API --> GPS
    API --> QUEUE

📡 Architecture des Endpoints API

graph TD
    subgraph PUBLIC["🔓 Endpoints Publics"]
        P1["GET /api/v1/products"]
        P2["GET /api/v1/products/:id"]
        P3["POST /api/v1/auth/register"]
        P4["POST /api/v1/auth/login"]
        P5["POST /api/v1/geocode"]
    end

    subgraph CLIENT_AUTH["🔐 Client (JWT Required)"]
        C1["POST /api/v1/panier/add"]
        C2["GET /api/v1/panier/:username"]
        C3["DELETE /api/v1/panier/remove"]
        C4["POST /api/v1/checkout"]
        C5["GET /api/v1/my-commands"]
        C6["GET /api/v1/commands/:id/status"]
        C7["GET /api/v1/commands/:id/tracking"]
        C8["GET /api/v1/commands/:id/eta"]
        C9["POST /api/v1/commands/:id/approve"]
        C10["POST /api/v1/commands/:id/cancel"]
    end

    subgraph ADMIN_AUTH["👨‍💼 Admin (JWT Required)"]
        A1["GET /api/v2/admin/protected/orders"]
        A2["POST /api/v2/admin/protected/orders/:id/auto-assign"]
        A3["POST /api/v2/admin/protected/orders/auto-assign-all"]
        A4["GET /api/v2/admin/protected/delivery-persons"]
        A5["GET /api/v2/admin/protected/delivery-persons/:username/location"]
        A6["GET /api/v2/admin/protected/delivery/queues"]
        A7["POST /api/v2/admin/protected/delivery/distances"]
        A8["GET /api/v2/admin/protected/commands/:id/navigation-links"]
        A9["POST /api/v2/admin/protected/products"]
        A10["POST /api/v2/admin/protected/penalty"]
    end

    subgraph LIVREUR_AUTH["🚚 Livreur (JWT Required)"]
        L1["GET /api/v1/livreur/deliveries"]
        L2["PUT /api/v1/livreur/deliveries/:id/status"]
        L3["POST /api/v1/livreur/location/update"]
        L4["GET /api/v1/livreur/location"]
        L5["POST /api/v1/livreur/update/status"]
        L6["GET /api/v1/livreur/queue"]
    end

    subgraph CABINE_AUTH["🏭 Cabine (JWT Required)"]
        K1["GET /api/v1/cabine/commands/:id/items"]
        K2["PUT /api/v1/cabine/items/:item_id/status"]
    end

    GW[API Gateway :8080]
    GW --> PUBLIC
    GW --> CLIENT_AUTH
    GW --> ADMIN_AUTH
    GW --> LIVREUR_AUTH
    GW --> CABINE_AUTH

🔐 Flux d'Authentification

sequenceDiagram
    participant U as Utilisateur
    participant F as Frontend
    participant API as Backend API
    participant DB as PostgreSQL
    participant R as Redis

    rect rgb(200, 230, 200)
        Note over U,R: Registration
        U->>F: Remplir formulaire inscription
        F->>API: POST /auth/register
        API->>DB: Creer utilisateur
        DB-->>API: User cree
        API-->>F: 201 Created + User info
        F-->>U: Compte cree
    end

    rect rgb(200, 200, 230)
        Note over U,R: Login
        U->>F: Entrer credentials
        F->>API: POST /auth/login
        API->>DB: Verifier credentials
        DB-->>API: User valide
        API->>API: Generer JWT
        API->>R: Stocker session
        API-->>F: 200 OK + JWT Token
        F->>F: Stocker token (localStorage)
        F-->>U: Connecte
    end

    rect rgb(230, 200, 200)
        Note over U,R: Requete Authentifiee
        U->>F: Action protegee
        F->>API: Request + Authorization: Bearer JWT
        API->>API: Valider JWT
        API->>R: Verifier session active
        R-->>API: Session valide
        API->>DB: Executer action
        DB-->>API: Resultat
        API-->>F: Response
        F-->>U: Resultat affiche
    end

📦 Flux Complet d'une Commande

sequenceDiagram
    participant C as Client
    participant F as Frontend
    participant API as Backend
    participant GPS as Service GPS
    participant Q as Queue Service
    participant L as Livreur
    participant DB as PostgreSQL
    participant R as Redis

    rect rgb(230, 245, 230)
        Note over C,R: 1. Creation Commande
        C->>F: Valider panier
        F->>API: POST /checkout {address}
        API->>GPS: Geocoder adresse
        GPS->>R: Check cache
        R-->>GPS: Miss
        GPS->>GPS: Appel Nominatim
        GPS->>R: Cache resultat (7j)
        GPS-->>API: Coordonnees
        API->>DB: Creer commande
        API->>Q: Chercher livreur proche
        Q->>R: Get positions livreurs
        Q->>Q: Calcul distances Haversine
        Q->>GPS: Calculer ETA (TomTom)
        Q-->>API: Livreur assigne
        API->>DB: Update commande
        API->>R: Ajouter a queue livreur
        API-->>F: Commande creee + ETA
        F-->>C: Confirmation
    end

    rect rgb(230, 230, 245)
        Note over C,R: 2. Livraison
        L->>API: GET /livreur/deliveries
        API-->>L: Liste commandes
        L->>API: PUT /deliveries/:id/status {support}
        L->>API: POST /location/update {lat, lng}
        API->>R: Update position
        API->>R: Publish update
        R-->>F: Notification position
        F-->>C: Carte mise a jour
        L->>API: PUT /deliveries/:id/status {en_route}
        L->>API: PUT /deliveries/:id/status {arrived}
        L->>API: PUT /deliveries/:id/status {livre}
    end

    rect rgb(245, 230, 230)
        Note over C,R: 3. Finalisation
        C->>F: Approuver livraison
        F->>API: POST /commands/:id/approve {rating}
        API->>DB: Update statut approved
        API->>R: Retirer de queue
        API-->>F: Confirmation
        F-->>C: Livraison terminee
    end

💾 Schema de la Base de Donnees

erDiagram
    CLIENTS {
        int id PK
        string username UK
        string password
        string nom
        string prenom
        string telephone UK
        int command
        int point
        int points_zipette
        float amende
        int cancellations_count
        timestamp created_at
    }

    ADMINS {
        int id PK
        string username UK
        string password
        string role
        timestamp created_at
    }

    LIVREURS {
        int id PK
        string username UK
        string password
        string status
        timestamp created_at
    }

    CABINES {
        int id PK
        string username UK
        string password
        timestamp created_at
    }

    PRODUCTS {
        int id PK
        string nom
        string description
        string category
        int stock
        float prix
        timestamp created_at
    }

    PRODUCT_PRICES {
        int id PK
        int product_id FK
        int quantity
        float price
    }

    PRODUCT_MEDIA {
        int id PK
        int product_id FK
        string type
        string url
    }

    PANIER {
        int id PK
        string username FK
        string name_product
        string category
        int quantity
        float price
        timestamp created_at
    }

    COMMANDS {
        int id PK
        string username FK
        string status
        float total
        string adresse
        float dest_latitude
        float dest_longitude
        string livreur_assign FK
        timestamp created_at
        timestamp updated_at
    }

    COMMAND_ITEMS {
        int id PK
        int command_id FK
        string produit
        int quantite
        float prix
        string status
        string category
    }

    RATINGS {
        int id PK
        int command_id FK
        string deliveryman
        int rating
        string comment
        timestamp created_at
    }

    CLIENTS ||--o{ PANIER : "possede"
    CLIENTS ||--o{ COMMANDS : "passe"
    PRODUCTS ||--o{ PRODUCT_PRICES : "a"
    PRODUCTS ||--o{ PRODUCT_MEDIA : "a"
    COMMANDS ||--o{ COMMAND_ITEMS : "contient"
    COMMANDS ||--o| RATINGS : "a"
    LIVREURS ||--o{ COMMANDS : "livre"

🗄️ Structure Redis

graph LR
    subgraph Sessions["🔐 Sessions"]
        S1["session:{token}<br/>TTL: 5h (client) / 2h (admin)"]
    end

    subgraph Positions["📍 Positions GPS"]
        P1["delivery:location:{username}<br/>TTL: 2h"]
        P2["delivery:status:{username}<br/>TTL: 1h"]
    end

    subgraph Queues["📋 Queues Livraison"]
        Q1["livreur:queue:{username}<br/>List of command_ids"]
        Q2["queue:size:{username}<br/>Integer"]
    end

    subgraph Cache["💾 Cache"]
        C1["geocode:cache:{hash}<br/>TTL: 7j"]
        C2["command:destination:{id}<br/>TTL: 4h"]
        C3["product:cache:{id}<br/>TTL: 1h"]
    end

    subgraph PubSub[" Pub/Sub Channels"]
        PS1["channel:position_updates"]
        PS2["channel:order_status"]
        PS3["channel:notifications"]
    end

    REDIS[(Redis Server)]
    REDIS --- Sessions
    REDIS --- Positions
    REDIS --- Queues
    REDIS --- Cache
    REDIS --- PubSub

🔐 Authentication

Register Client

Créer un nouveau compte client

POST /api/v1/auth/register
Content-Type: application/json

Requête:

{
  "username": "jean_dupont",
  "password": "SecurePass123!",
  "nom": "Dupont",
  "prenom": "Jean",
  "telephone": "+33612345678"
}

Réponse (201 Created):

{
  "success": true,
  "message": "Client créé avec succès",
  "client": {
    "id": 42,
    "username": "jean_dupont",
    "nom": "Dupont",
    "prenom": "Jean",
    "telephone": "+33612345678",
    "command": 0,
    "point": 0,
    "points_zipette": 0,
    "amende": 0.0,
    "cancellations_count": 0,
    "created_at": "2025-01-18T14:30:00Z"
  }
}

Erreurs possibles:

  • 400 - Données invalides (validation échouée)
  • 409 - Username ou téléphone déjà utilisé

Login Client

Se connecter et obtenir un token JWT

POST /api/v1/auth/login
Content-Type: application/json

Requête:

{
  "username": "jean_dupont",
  "password": "SecurePass123!"
}

Réponse (200 OK):

{
  "access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
  "token_type": "Bearer",
  "expires_in": 18000,
  "user": {
    "username": "jean_dupont",
    "role": "client"
  }
}

Erreurs possibles:

  • 400 - Données manquantes
  • 401 - Identifiants incorrects

Logout Client

Se déconnecter (invalider le token)

POST /api/v1/auth/logout
Authorization: Bearer <token>

Réponse (200 OK):

{
  "success": true,
  "message": "Déconnexion réussie"
}

🛒 API Client (v1)

Toutes les routes clients nécessitent le header:

Authorization: Bearer <client_token>

Produits (Public - Pas d'auth requis)

Liste des produits

GET /api/v1/products

Réponse (200 OK):

{
  "success": true,
  "products": [
    {
      "id": 1,
      "nom": "Pizza Margherita",
      "description": "Pizza traditionnelle avec tomate, mozzarella et basilic",
      "category": "pizza",
      "stock": 50,
      "prix": 12.50,
      "prices": [
        {
          "id": 1,
          "product_id": 1,
          "quantity": 1,
          "price": 12.50
        }
      ],
      "media": [
        {
          "id": 1,
          "product_id": 1,
          "type": "image",
          "url": "/uploads/pizza_margherita.jpg"
        }
      ],
      "created_at": "2025-01-18T00:00:00Z"
    }
  ],
  "total": 1
}

Produit par ID

GET /api/v1/products/:id

Réponse (200 OK):

{
  "success": true,
  "product": {
    "id": 1,
    "nom": "Pizza Margherita",
    "description": "Pizza traditionnelle avec tomate, mozzarella et basilic",
    "category": "pizza",
    "stock": 50,
    "prix": 12.50,
    "prices": [...],
    "media": [...],
    "created_at": "2025-01-18T00:00:00Z"
  }
}

Erreurs possibles:

  • 404 - Produit non trouvé

Gestion du Panier

Ajouter au panier

POST /api/v1/panier/add
Authorization: Bearer <token>
Content-Type: application/json

Requête:

{
  "name_product": "Pizza Margherita",
  "category": "pizza",
  "quantity": 2
}

Réponse (201 Created):

{
  "success": true,
  "message": "Produit ajouté au panier avec succès",
  "panier": {
    "id": 15,
    "username": "jean_dupont",
    "name_product": "Pizza Margherita",
    "category": "pizza",
    "quantity": 2,
    "price": 25.00,
    "created_at": "2025-01-18T14:35:00Z"
  }
}

Erreurs possibles:

  • 400 - Données invalides ou stock insuffisant
  • 401 - Non authentifié
  • 404 - Produit non trouvé

Voir mon panier

GET /api/v1/panier/:username
Authorization: Bearer <token>

Réponse (200 OK):

{
  "success": true,
  "message": "Panier récupéré avec succès",
  "panier": [
    {
      "id": 15,
      "username": "jean_dupont",
      "name_product": "Pizza Margherita",
      "category": "pizza",
      "quantity": 2,
      "price": 25.00,
      "created_at": "2025-01-18T14:35:00Z"
    }
  ],
  "count": 1,
  "total_amount": 25.00
}

Erreurs possibles:

  • 403 - Accès au panier d'un autre utilisateur
  • 404 - Utilisateur non trouvé

Supprimer du panier

DELETE /api/v1/panier/remove
Authorization: Bearer <token>
Content-Type: application/json

Requête:

{
  "id": 15
}

Réponse (200 OK):

{
  "success": true,
  "message": "Produit supprimé du panier avec succès",
  "item_id": 15,
  "stock_released": true
}

Erreurs possibles:

  • 403 - Tentative de supprimer l'article d'un autre utilisateur
  • 404 - Article non trouvé

Vider le panier

DELETE /api/v1/panier/clear
Authorization: Bearer <token>

Réponse (200 OK):

{
  "success": true,
  "message": "Panier vidé avec succès",
  "stock_released": 3
}

Commandes

Valider le panier (Checkout avec Auto-assignation)

POST /api/v1/checkout
Authorization: Bearer <token>
Content-Type: application/json

Requête:

{
  "delivery_address": "15 Rue de la Paix, 75002 Paris, France"
}

Réponse avec auto-assignation (200 OK):

{
  "success": true,
  "message": "Commande créée et livreur assigné automatiquement",
  "command_id": 1234,
  "delivery_address": "15 Rue de la Paix, 75002 Paris, France",
  "status": "assigned",
  "auto_assigned": true,
  "assigned_to": {
    "username": "john_deliveryman",
    "distance_km": 1.5,
    "travel_time": 8
  }
}

Réponse sans auto-assignation (200 OK):

{
  "success": true,
  "message": "Commande créée - En attente d'assignation",
  "command_id": 1234,
  "delivery_address": "15 Rue de la Paix, 75002 Paris, France",
  "status": "pending",
  "auto_assigned": false
}

Erreurs possibles:

  • 400 - Panier vide ou adresse manquante
  • 401 - Non authentifié
  • 500 - Erreur création commande

Mes commandes avec suivi

GET /api/v1/my-commands
Authorization: Bearer <token>

Réponse (200 OK):

{
  "success": true,
  "commands": [
    {
      "id": 1234,
      "username": "jean_dupont",
      "status": "assigned",
      "total": 25.00,
      "delivery_address": "15 Rue de la Paix, 75002 Paris",
      "livreur_assign": "john_deliveryman",
      "created_at": "2025-01-18T14:40:00Z",
      "updated_at": "2025-01-18T14:42:00Z",
      "tracking": {
        "eta_minutes": 25,
        "estimated_arrival": "15:05",
        "deliveryman_status": "en_route",
        "queue_position": 2
      }
    }
  ],
  "total": 1
}

Statut temps réel d'une commande

GET /api/v1/commands/:id/status
Authorization: Bearer <token>

Réponse (200 OK):

{
  "success": true,
  "command_id": 1234,
  "status": "en_route",
  "deliveryman": "john_deliveryman",
  "updated_at": "2025-01-18T15:20:00Z"
}

Statuts possibles:

  • pending - En attente d'assignation
  • assigned - Assignée à un livreur
  • support - Prise en charge par le livreur
  • en_route - Livreur en chemin
  • arrived - Livreur arrivé
  • livre - Livrée (en attente d'approbation)
  • approved - Approuvée par le client
  • cancelled - Annulée
  • failed - Échec de livraison

Suivi détaillé avec ETA

GET /api/v1/commands/:id/tracking
Authorization: Bearer <token>

Réponse (200 OK):

{
  "success": true,
  "command_id": 1234,
  "status": "en_route",
  "deliveryman": "john_deliveryman",
  "eta": {
    "minutes": 22,
    "estimated_arrival": "15:02",
    "arrival_time_unix": 1705669320,
    "updated_at": "2025-01-18T14:40:00Z"
  },
  "queue_position": 2,
  "total_queue_size": 5
}

ETA de livraison

GET /api/v1/commands/:id/eta
Authorization: Bearer <token>

Réponse (200 OK):

{
  "success": true,
  "command_id": 1234,
  "eta_minutes": 22,
  "estimated_arrival": "15:02:00",
  "queue_position": 2,
  "updated_at": "2025-01-18T14:40:00Z"
}

Approuver une livraison

POST /api/v1/commands/:id/approve
Authorization: Bearer <token>
Content-Type: application/json

Requête:

{
  "rating": 5,
  "comment": "Excellent service, livreur très professionnel !"
}

Réponse (200 OK):

{
  "success": true,
  "message": "Livraison approuvée avec succès",
  "command_id": 1234,
  "status": "approved",
  "rating": {
    "deliveryman": "john_deliveryman",
    "rating": 5,
    "comment": "Excellent service, livreur très professionnel !",
    "created_at": "2025-01-18T15:05:00Z"
  }
}

Annuler une commande

POST /api/v1/commands/:id/cancel
Authorization: Bearer <token>
Content-Type: application/json

Requête:

{
  "reason": "Changement de plans"
}

Réponse (200 OK):

{
  "success": true,
  "message": "Commande annulée avec succès",
  "command_id": 1234,
  "penalty_applied": true,
  "penalty_details": {
    "cancellations_count": 1,
    "penalty_amount": 20.0,
    "warning": "Pénalité appliquée pour annulation"
  }
}

Profil et Historique

Mettre à jour mon profil

PUT /api/v1/profile/update
Authorization: Bearer <token>
Content-Type: application/json

Requête:

{
  "nom": "Nouveau Nom",
  "prenom": "Nouveau Prénom",
  "telephone": "+33687654321",
  "password": "NewSecurePass456!"
}

Réponse (200 OK):

{
  "success": true,
  "message": "Profil mis à jour avec succès",
  "client": {
    "id": 42,
    "username": "jean_dupont",
    "nom": "Nouveau Nom",
    "prenom": "Nouveau Prénom",
    "telephone": "+33687654321",
    "updated_at": "2025-01-18T15:30:00Z"
  }
}

Mes pénalités

GET /api/v1/penalties
Authorization: Bearer <token>

Réponse (200 OK):

{
  "success": true,
  "client": {
    "username": "jean_dupont",
    "amende": 20.0,
    "cancellations_count": 1,
    "last_penalty_reason": "Annulation tardive"
  },
  "penalty_scale": {
    "1st": 20.0,
    "2nd": 50.0,
    "3rd": 100.0,
    "4th+": 150.0
  },
  "next_penalty": 50.0,
  "warning": "La prochaine annulation entraînera une pénalité de 50 points"
}

👨‍💼 API Admin (v2)

Toutes les routes admin nécessitent le header:

Authorization: Bearer <admin_token>

Authentication Admin

Login Admin

POST /api/v2/admin/auth/login
Content-Type: application/json

Requête:

{
  "username": "admin_master",
  "password": "AdminSecure123!"
}

Réponse (200 OK):

{
  "access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
  "token_type": "Bearer",
  "expires_in": 7200,
  "user": {
    "username": "admin_master",
    "role": "admin"
  }
}

Gestion des Commandes

Liste des commandes

GET /api/v2/admin/protected/orders
Authorization: Bearer <admin_token>

Réponse (200 OK):

{
  "success": true,
  "orders": [
    {
      "id": 1234,
      "username": "jean_dupont",
      "status": "assigned",
      "total": 25.00,
      "delivery_address": "15 Rue de la Paix, 75002 Paris",
      "livreur_assign": "john_deliveryman",
      "dest_latitude": 48.8698,
      "dest_longitude": 2.3311,
      "created_at": "2025-01-18T14:40:00Z",
      "updated_at": "2025-01-18T14:42:00Z"
    }
  ],
  "total": 1
}

Assignation automatique GPS

POST /api/v2/admin/protected/orders/:id/auto-assign
Authorization: Bearer <admin_token>

Réponse (200 OK):

{
  "success": true,
  "message": "Commande assignée automatiquement",
  "command_id": 1234,
  "assigned_to": "john_deliveryman",
  "distance": {
    "km": 1.5,
    "eta_minutes": 8
  },
  "queue_position": 3
}

Erreurs possibles:

  • 404 - Commande non trouvée
  • 400 - Aucun livreur disponible
  • 409 - Commande déjà assignée

Assigner toutes les commandes en attente

POST /api/v2/admin/protected/orders/auto-assign-all
Authorization: Bearer <admin_token>

Réponse (200 OK):

{
  "success": true,
  "message": "Auto-assignation effectuée",
  "assigned_count": 5,
  "failed_count": 0,
  "details": [
    {
      "command_id": 1234,
      "assigned_to": "john_deliveryman",
      "distance_km": 1.5,
      "eta_minutes": 8
    }
  ]
}

Gestion des Livreurs

Livreurs disponibles

GET /api/v2/admin/protected/delivery-persons
Authorization: Bearer <admin_token>

Réponse (200 OK):

{
  "success": true,
  "delivery_persons": [
    {
      "username": "john_deliveryman",
      "status": "available",
      "current_command": 0,
      "queue_size": 2,
      "location": {
        "latitude": 48.8566,
        "longitude": 2.3522,
        "last_update": "2025-01-18T16:30:00Z"
      }
    }
  ],
  "total": 1
}

Position d'un livreur

GET /api/v2/admin/protected/delivery-persons/:username/location
Authorization: Bearer <admin_token>

Réponse (200 OK):

{
  "success": true,
  "deliveryman": "john_deliveryman",
  "location": {
    "latitude": 48.8566,
    "longitude": 2.3522,
    "last_update": "2025-01-18T16:25:00Z"
  },
  "status": "available"
}

Queues des livreurs

GET /api/v2/admin/protected/delivery/queues
Authorization: Bearer <admin_token>

Réponse (200 OK):

{
  "success": true,
  "queues": {
    "john_deliveryman": {
      "queue_size": 3,
      "commands": [1234, 1235, 1236],
      "can_accept_more": true,
      "capacity": "3/10",
      "status": "available"
    }
  },
  "total_pending": 3
}

Gestion des Produits

Créer un produit

POST /api/v2/admin/protected/products
Authorization: Bearer <admin_token>
Content-Type: application/json

Requête:

{
  "nom": "Pizza Pepperoni",
  "category": "pizza",
  "description": "Pizza avec pepperoni et mozzarella",
  "stock": 30,
  "prix": 14.50
}

Réponse (201 Created):

{
  "success": true,
  "message": "Produit créé avec succès",
  "product": {
    "id": 10,
    "nom": "Pizza Pepperoni",
    "category": "pizza",
    "description": "Pizza avec pepperoni et mozzarella",
    "stock": 30,
    "prix": 14.50,
    "created_at": "2025-01-18T16:10:00Z"
  }
}

Système de Pénalités

Appliquer une pénalité

POST /api/v2/admin/protected/penalty
Authorization: Bearer <admin_token>
Content-Type: application/json

Requête:

{
  "username": "jean_dupont",
  "amount": 50.0,
  "reason": "Comportement inapproprié"
}

Réponse (200 OK):

{
  "success": true,
  "message": "Pénalité appliquée",
  "client": "jean_dupont",
  "penalty": {
    "amount": 50.0,
    "reason": "Comportement inapproprié",
    "applied_at": "2025-01-18T17:00:00Z"
  },
  "total_amende": 70.0
}

🏪 API Cabine (v1)

Toutes les routes cabine nécessitent le header:

Authorization: Bearer <cabine_token>

Articles d'une commande

GET /api/v1/cabine/commands/:id/items
Authorization: Bearer <cabine_token>

Réponse (200 OK):

{
  "success": true,
  "command_id": 1234,
  "items": [
    {
      "id": 1,
      "command_id": 1234,
      "produit": "Pizza Margherita",
      "quantite": 2,
      "prix": 25.0,
      "status": "pending",
      "category": "pizza"
    }
  ],
  "total": 1
}

Modifier le statut d'un article

PUT /api/v1/cabine/items/:item_id/status
Authorization: Bearer <cabine_token>
Content-Type: application/json

Requête:

{
  "status": "prepared"
}

Réponse (200 OK):

{
  "success": true,
  "message": "Statut mis à jour",
  "item": {
    "id": 1,
    "command_id": 1234,
    "status": "prepared",
    "updated_at": "2025-01-18T17:15:00Z"
  }
}

Statuts disponibles: pending, prepared, packed, ready


🚚 API Livreur (v1)

Toutes les routes livreur nécessitent le header:

Authorization: Bearer <livreur_token>

Livraisons

Mes livraisons (données filtrées)

GET /api/v1/livreur/deliveries
Authorization: Bearer <livreur_token>

Réponse (200 OK):

{
  "success": true,
  "deliveries": [
    {
      "id": 1234,
      "status": "assigned",
      "adresse": "15 Rue de la Paix, 75002 Paris",
      "total_prix": 25.0,
      "created_at": "2025-01-18T14:40:00Z",
      "client_info": {
        "nom": "Dupont",
        "prenom": "Jean"
      },
      "items": [
        {
          "produit": "Pizza Margherita",
          "quantite": 2,
          "prix": 25.0
        }
      ],
      "items_count": 1,
      "eta": {
        "minutes": 25,
        "estimated_arrival": "15:05"
      }
    }
  ],
  "count": 1
}

Note: Les données sensibles comme le téléphone client sont filtrées pour les livreurs.


Mettre à jour le statut d'une livraison

PUT /api/v1/livreur/deliveries/:id/status
Authorization: Bearer <livreur_token>
Content-Type: application/json

Requête:

{
  "status": "en_route",
  "notes": "En route vers le client",
  "latitude": 48.8566,
  "longitude": 2.3522
}

Réponse (200 OK):

{
  "success": true,
  "message": "Statut mis à jour",
  "command_id": 1234,
  "status": "en_route",
  "eta_minutes": 15,
  "eta_message": "Arrivée prévue dans 15 minutes"
}

Statuts valides pour livreur:

  • support - Prise en charge
  • assigned - Assigné
  • en_route - En route vers le client
  • arrived - Arrivé à destination
  • livre - Livré
  • failed - Échec de livraison
  • cancelled - Annulée

Position GPS

Mettre à jour ma position

POST /api/v1/livreur/location/update
Authorization: Bearer <livreur_token>
Content-Type: application/json

Requête:

{
  "latitude": 48.8566,
  "longitude": 2.3522
}

Réponse (200 OK):

{
  "success": true,
  "message": "Position mise à jour",
  "location": {
    "latitude": 48.8566,
    "longitude": 2.3522,
    "updated_at": "2025-01-18T17:35:00Z"
  }
}

Ma position actuelle

GET /api/v1/livreur/location
Authorization: Bearer <livreur_token>

Réponse (200 OK):

{
  "success": true,
  "location": {
    "latitude": 48.8566,
    "longitude": 2.3522,
    "last_update": "2025-01-18T17:35:00Z"
  }
}

Statut et Queue

Mettre à jour mon statut

POST /api/v1/livreur/update/status
Authorization: Bearer <livreur_token>
Content-Type: application/json

Requête:

{
  "status": "available"
}

Réponse (200 OK):

{
  "success": true,
  "message": "Statut mis à jour",
  "status": {
    "username": "john_deliveryman",
    "status": "available",
    "updated_at": "2025-01-18T17:40:00Z"
  }
}

Statuts disponibles: available, busy, offline


Ma queue de livraisons

GET /api/v1/livreur/queue
Authorization: Bearer <livreur_token>

Réponse (200 OK):

{
  "success": true,
  "deliveryman": "john_deliveryman",
  "queue_size": 3,
  "commands": [
    {
      "position": 1,
      "command_id": 1234,
      "address": "15 Rue de la Paix, 75002 Paris",
      "estimated_eta": 12,
      "total_prix": 25.0
    }
  ]
}

🗺️ Systeme GPS Integre

Le systeme GPS est au coeur de la plateforme de livraison. Il permet l'assignation automatique des livreurs, le calcul d'ETA en temps reel, et le suivi des livraisons.

Architecture GPS

Flux GPS Complet

flowchart TD
    A[1. Commande creee par le Client] --> B[2. Geocodage adresse]
    B --> |Nominatim API| C[(Cache Redis 7 jours)]
    C --> D[3. Worker Auto-Assignation]
    D --> |Toutes les 5 min| E[4. Recherche livreur le plus proche]
    E --> |Haversine + TomTom| F[5. Calcul ETA avec trafic reel]
    F --> G[6. Assignation a la queue du livreur]
    G --> H[7. Livreur accepte et met a jour sa position]
    H --> |Redis Pub/Sub| I[8. Client/Admin recoivent les mises a jour]
    I --> J[9. Navigation vers destination]
    J --> |TomTom Routing| K[10. Livraison terminee]

Architecture des Services GPS

graph TB
    subgraph Frontend
        MAP[TomTomMap Component]
        UI[Interface Utilisateur]
    end

    subgraph Backend
        GEO[Service Geocodage]
        DIST[Service Distance]
        ETA[Service ETA]
        ASSIGN[Service Auto-Assignation]
    end

    subgraph APIs Externes
        NOM[Nominatim API]
        TOM[TomTom API]
    end

    subgraph Stockage
        REDIS[(Redis Cache)]
        PG[(PostgreSQL)]
    end

    UI --> MAP
    MAP --> TOM
    GEO --> NOM
    GEO --> REDIS
    DIST --> GEO
    ETA --> TOM
    ETA --> DIST
    ASSIGN --> DIST
    ASSIGN --> ETA
    ASSIGN --> PG
    ASSIGN --> REDIS

Services GPS Utilises

Service Utilisation Cache
Nominatim (OpenStreetMap) Geocodage d'adresses Redis 7 jours
TomTom Routing API ETA avec trafic reel, itineraires Non
Haversine (local) Calcul de distance a vol d'oiseau Non

Configuration Requise

Variables d'environnement Backend:

TOMTOM_API_KEY=<votre_cle_api_tomtom>

Variables d'environnement Frontend:

VITE_TOMTOM_API_KEY=<votre_cle_api_tomtom>

Note: Obtenez une cle API TomTom gratuite sur developer.tomtom.com


Geocodage d'Adresses

Le geocodage convertit une adresse textuelle en coordonnees GPS (latitude/longitude).

Geocoder une adresse

POST /api/v1/geocode
Content-Type: application/json

Requete:

{
  "address": "15 Rue de la Paix, 75002 Paris, France"
}

Reponse (200 OK):

{
  "success": true,
  "address": "15 Rue de la Paix, 75002 Paris, France",
  "coordinates": {
    "latitude": 48.8698,
    "longitude": 2.3311
  },
  "cached": false
}

Erreurs possibles:

  • 400 - Adresse manquante ou invalide
  • 404 - Adresse non trouvee (geocodage echoue)

Valider une adresse

Verifie si une adresse peut etre geocodee sans la stocker.

POST /api/v1/validate-address
Content-Type: application/json

Requete:

{
  "address": "15 Rue de la Paix, 75002 Paris"
}

Reponse (200 OK):

{
  "success": true,
  "valid": true,
  "address": "15 Rue de la Paix, 75002 Paris",
  "coordinates": {
    "latitude": 48.8698,
    "longitude": 2.3311
  }
}

Calcul de Distance et ETA

Formule Haversine

Le systeme utilise la formule Haversine pour calculer la distance a vol d'oiseau entre deux points GPS:

a = sin²(Δlat/2) + cos(lat1) × cos(lat2) × sin²(Δlon/2)
c = 2 × atan2(√a, √(1-a))
distance = R × c

Ou R = 6371 km (rayon de la Terre)

ETA avec Trafic (TomTom)

L'ETA est calcule en utilisant l'API TomTom qui prend en compte:

  • Les conditions de trafic en temps reel
  • Les incidents routiers
  • Les travaux
  • L'heure de la journee
flowchart TD
    A[Demande ETA] --> B{TomTom API disponible?}
    B -->|Oui| C[Appel TomTom Routing API]
    C --> D[ETA avec trafic reel]
    B -->|Non| E[Calcul Haversine]
    E --> F[Distance a vol d'oiseau]
    F --> G[Vitesse moyenne 30 km/h]
    G --> H[ETA estime]
    D --> I[Retourner ETA]
    H --> I
    I --> J{Fallback utilise?}
    J -->|Oui| K[Ajouter flag fallback_used: true]
    J -->|Non| L[Response standard]

Fallback: Si l'API TomTom est indisponible, le systeme utilise un calcul local base sur:

  • Distance Haversine
  • Vitesse moyenne estimee (30 km/h en ville)

Auto-Assignation GPS

Le systeme assigne automatiquement les commandes au livreur le plus proche.

Processus d'Auto-Assignation

flowchart LR
    A[Nouvelle Commande] --> B{Adresse geocodee?}
    B -->|Non| C[Geocoder adresse]
    C --> D
    B -->|Oui| D[Recuperer livreurs disponibles]
    D --> E[Calculer distances Haversine]
    E --> F[Trier par proximite]
    F --> G{Livreur avec capacite?}
    G -->|Oui| H[Calculer ETA TomTom]
    G -->|Non| I{Forcer assignation?}
    I -->|Oui| H
    I -->|Non| J[Commande en attente]
    H --> K[Assigner a la queue]
    K --> L[Notifier livreur]

Regles de Capacite

  • Chaque livreur peut avoir jusqu'a 10 commandes dans sa queue
  • Si tous les livreurs sont a capacite maximale, le systeme peut forcer l'assignation
  • Les livreurs avec le statut offline ne recoivent pas de commandes

Auto-assigner une commande specifique

POST /api/v2/admin/protected/orders/:id/auto-assign
Authorization: Bearer <admin_token>

Reponse (200 OK):

{
  "success": true,
  "message": "Commande assignee automatiquement",
  "command_id": 1234,
  "assigned_to": "john_deliveryman",
  "assignment_details": {
    "distance_km": 1.5,
    "eta_minutes": 8,
    "queue_position": 3,
    "method": "nearest_available"
  }
}

Lister les livreurs par distance

Obtient la liste des livreurs tries par distance depuis une adresse.

POST /api/v2/admin/protected/delivery/distances
Authorization: Bearer <admin_token>
Content-Type: application/json

Requete:

{
  "address": "15 Rue de la Paix, 75002 Paris"
}

Reponse (200 OK):

{
  "success": true,
  "address": "15 Rue de la Paix, 75002 Paris",
  "destination": {
    "latitude": 48.8698,
    "longitude": 2.3311
  },
  "delivery_persons": [
    {
      "username": "john_deliveryman",
      "distance_km": 1.5,
      "eta_minutes": 8,
      "status": "available",
      "queue_size": 2,
      "location": {
        "latitude": 48.8566,
        "longitude": 2.3522
      }
    },
    {
      "username": "jane_delivery",
      "distance_km": 3.2,
      "eta_minutes": 15,
      "status": "available",
      "queue_size": 5,
      "location": {
        "latitude": 48.8456,
        "longitude": 2.3789
      }
    }
  ]
}

Liens de Navigation

Le systeme genere des liens vers plusieurs applications de cartographie.

Obtenir les liens carte d'un livreur

GET /api/v2/admin/protected/delivery-persons/:username/map-links
Authorization: Bearer <admin_token>

Reponse (200 OK):

{
  "success": true,
  "deliveryman": "john_deliveryman",
  "location": {
    "latitude": 48.8566,
    "longitude": 2.3522
  },
  "map_links": {
    "google_maps": "https://www.google.com/maps?q=48.8566,2.3522",
    "google_maps_app": "comgooglemaps://?center=48.8566,2.3522",
    "waze": "https://www.waze.com/ul?ll=48.8566,2.3522&navigate=yes",
    "waze_app": "waze://?ll=48.8566,2.3522&navigate=yes",
    "apple_maps": "https://maps.apple.com/?ll=48.8566,2.3522",
    "openstreetmap": "https://www.openstreetmap.org/?mlat=48.8566&mlon=2.3522",
    "bing_maps": "https://www.bing.com/maps?cp=48.8566~2.3522",
    "here_maps": "https://share.here.com/l/48.8566,2.3522"
  }
}

Obtenir les liens de navigation pour une commande

Genere des liens de navigation depuis la position du livreur vers la destination de livraison.

GET /api/v2/admin/protected/commands/:id/navigation-links
Authorization: Bearer <admin_token>

Reponse (200 OK):

{
  "success": true,
  "command_id": 1234,
  "origin": {
    "latitude": 48.8566,
    "longitude": 2.3522,
    "description": "Position du livreur"
  },
  "destination": {
    "latitude": 48.8698,
    "longitude": 2.3311,
    "address": "15 Rue de la Paix, 75002 Paris"
  },
  "navigation_links": {
    "google_maps": "https://www.google.com/maps/dir/48.8566,2.3522/48.8698,2.3311",
    "waze": "https://www.waze.com/ul?ll=48.8698,2.3311&navigate=yes&from=48.8566,2.3522",
    "apple_maps": "https://maps.apple.com/?saddr=48.8566,2.3522&daddr=48.8698,2.3311"
  }
}

Gestion des Positions en Temps Reel

Flux de Mise a Jour de Position

sequenceDiagram
    participant L as Livreur (App)
    participant API as Backend API
    participant R as Redis
    participant PS as Redis Pub/Sub
    participant A as Admin/Client

    L->>API: POST /location/update {lat, lng}
    API->>API: Valider coordonnees
    API->>R: SET delivery:location:{username}
    API->>PS: PUBLISH position_update
    PS-->>A: Notification temps reel
    API-->>L: 200 OK {location, updated_at}

Mise a jour de position (Livreur)

POST /api/v1/livreur/location/update
Authorization: Bearer <livreur_token>
Content-Type: application/json

Requete:

{
  "latitude": 48.8566,
  "longitude": 2.3522
}

Validation des coordonnees:

  • Latitude: entre -90 et +90
  • Longitude: entre -180 et +180

Reponse (200 OK):

{
  "success": true,
  "message": "Position mise a jour",
  "location": {
    "latitude": 48.8566,
    "longitude": 2.3522,
    "updated_at": "2025-01-18T17:35:00Z"
  }
}

Erreurs possibles:

  • 400 - Coordonnees invalides (hors limites)
  • 401 - Non authentifie

Stockage Redis des Positions

Les positions GPS sont stockees dans Redis pour un acces rapide:

graph LR
    subgraph Redis Cache
        A[delivery:location:username<br/>TTL: 2h]
        B[delivery:status:username<br/>TTL: 1h]
        C[geocode:cache:address_hash<br/>TTL: 7j]
        D[command:destination:id<br/>TTL: 4h]
    end

    subgraph Donnees
        A --> A1[latitude, longitude, updated_at]
        B --> B1[status, latitude, longitude]
        C --> C1[latitude, longitude, address]
        D --> D1[dest_lat, dest_lng]
    end

| command:destination:{command_id} | Coordonnees destination | 4 heures |


Composant Carte Frontend (TomTomMap)

Le frontend inclut un composant React/TypeScript pour afficher la carte interactive.

Fonctionnalites du Composant

  • Carte interactive avec marqueurs livreur/destination
  • Calcul d'itineraire en temps reel
  • Instructions de navigation (tourner a gauche, a droite, rond-point, etc.)
  • Affichage distance/duree du trajet
  • Mode 3D avec orientation selon la direction
  • Support francais pour toutes les instructions

Exemple d'Utilisation

import TomTomMap from './components/TomTomMap';

function DeliveryTracking() {
  return (
    <TomTomMap
      driverPosition={{ lat: 48.8566, lng: 2.3522 }}
      destinationPosition={{ lat: 48.8698, lng: 2.3311 }}
      showRoute={true}
      showInstructions={true}
    />
  );
}

Props du Composant

Prop Type Description
driverPosition {lat: number, lng: number} Position du livreur
destinationPosition {lat: number, lng: number} Destination de livraison
showRoute boolean Afficher l'itineraire
showInstructions boolean Afficher le panneau d'instructions
onEtaUpdate (eta: number) => void Callback quand l'ETA change

Worker d'Auto-Assignation

Un worker CRON s'execute automatiquement pour assigner les commandes en attente.

Configuration

  • Frequence: Toutes les 5 minutes
  • Fichier: backend/gestion/workers/cron_auto_assign.go

Processus du Worker

flowchart TD
    START((Demarrage CRON)) --> A[Recuperer commandes pending]
    A --> B{Commandes a traiter?}
    B -->|Non| END((Fin))
    B -->|Oui| C[Prendre commande suivante]
    C --> D{Adresse geocodee?}
    D -->|Non| E[Geocoder via Nominatim]
    E --> F
    D -->|Oui| F[Recuperer livreurs disponibles]
    F --> G[Calculer distances]
    G --> H[Selectionner le plus proche]
    H --> I{Capacite disponible?}
    I -->|Non| J[Marquer pour retry]
    I -->|Oui| K[Calculer ETA TomTom]
    K --> L[Assigner commande]
    L --> M[Mettre a jour statut]
    M --> N{Autres commandes?}
    J --> N
    N -->|Oui| C
    N -->|Non| O[Logger resultats]
    O --> END

Logs d'Exemple

[AUTO-ASSIGN] Processing 5 pending orders
[AUTO-ASSIGN] Order #1234: Geocoded to (48.8698, 2.3311)
[AUTO-ASSIGN] Order #1234: Nearest driver is john_deliveryman (1.5 km)
[AUTO-ASSIGN] Order #1234: ETA calculated: 8 minutes
[AUTO-ASSIGN] Order #1234: Assigned successfully
[AUTO-ASSIGN] Completed: 5 assigned, 0 failed

Cycle de Vie d'une Livraison (GPS)

stateDiagram-v2
    [*] --> pending: Commande creee
    pending --> assigned: Auto-assignation GPS
    pending --> pending: Geocodage en cours
    
    assigned --> support: Livreur prend en charge
    assigned --> cancelled: Annulation
    
    support --> en_route: Livreur demarre
    support --> cancelled: Annulation
    
    en_route --> arrived: Position = Destination
    en_route --> en_route: Mise a jour position
    
    arrived --> livre: Remise au client
    arrived --> failed: Client absent
    
    livre --> approved: Client confirme
    livre --> failed: Probleme signale
    
    approved --> [*]
    cancelled --> [*]
    failed --> [*]

    note right of en_route
        Position GPS mise a jour
        toutes les 30 secondes
        ETA recalcule en temps reel
    end note

Gestion des Erreurs GPS

Geocodage Echoue

Si une adresse ne peut pas etre geocodee:

  • La commande reste en statut pending
  • Un log d'erreur est genere
  • L'admin peut corriger l'adresse manuellement

API TomTom Indisponible

Le systeme bascule automatiquement sur le calcul local:

  • Utilise la formule Haversine pour la distance
  • Estime l'ETA avec une vitesse moyenne de 30 km/h
  • Un flag fallback_used: true est ajoute a la reponse

Bonnes Pratiques

Pour les Livreurs

  1. Mettre a jour la position frequemment (toutes les 30 secondes recommande)
  2. Verifier le statut avant de commencer une livraison
  3. Utiliser les liens de navigation generes par l'API

Pour les Admins

  1. Surveiller les queues des livreurs pour eviter la surcharge
  2. Verifier les adresses qui echouent au geocodage
  3. Utiliser l'endpoint distances pour l'assignation manuelle si necessaire

Pour les Developpeurs

  1. Toujours valider les coordonnees avant stockage
  2. Utiliser le cache Redis pour les adresses frequentes
  3. Implementer un fallback si TomTom est indisponible
  4. Logger les erreurs de geocodage pour analyse

Codes d'Erreur

Erreurs HTTP Standards

Code Signification Description
200 OK Succès
201 Created Ressource créée
400 Bad Request Données invalides
401 Unauthorized Non authentifié
403 Forbidden Non autorisé
404 Not Found Ressource introuvable
409 Conflict Conflit (username déjà pris)
422 Unprocessable Entity Validation échouée
500 Internal Server Error Erreur serveur

Exemples d'Erreurs

400 - Bad Request

{
  "error": "Données invalides",
  "details": "Le champ 'username' est requis"
}

401 - Unauthorized

{
  "error": "Token invalide ou expiré",
  "message": "Veuillez vous reconnecter"
}

403 - Forbidden

{
  "error": "Accès refusé",
  "message": "Vous n'avez pas les permissions nécessaires"
}

404 - Not Found

{
  "error": "Ressource introuvable",
  "message": "Commande avec l'ID 9999 introuvable"
}

409 - Conflict

{
  "error": "Conflit",
  "message": "Ce nom d'utilisateur est déjà pris"
}

422 - Unprocessable Entity

{
  "error": "Validation échouée",
  "details": {
    "field": "telephone",
    "message": "Format de téléphone invalide"
  }
}

500 - Internal Server Error

{
  "error": "Erreur serveur interne",
  "message": "Une erreur inattendue s'est produite"
}

📝 Notes Importantes

Sécurité

  • Tokens JWT : Expiration variable selon le rôle (Client: 5h, Admin: 2h)
  • Validation GPS : Requis pour certaines actions de livraison
  • Filtrage des données : Les livreurs n'ont pas accès aux téléphones clients
  • Rate Limiting : Protection contre les abus

Format des Données

  • Dates : Format ISO 8601 (2025-01-18T14:30:00Z)
  • Coordonnées : Latitude/Longitude en décimal (WGS84)
  • Prix : En euros avec 2 décimales
  • Téléphones : Format international (+33612345678)

Workers Automatiques

  • Auto-Assignment Cron : Toutes les 5 minutes
  • Queue Cleanup : Toutes les 5 minutes
  • ETA Updates : Toutes les 30 secondes
  • Stock Cleanup : Toutes les 5 minutes

Fonctionnalités Avancées

  • Assignation GPS automatique au checkout
  • Calcul ETA temps réel avec TomTom API
  • Système de queues optimisé pour les livreurs
  • Nettoyage automatique des commandes invalides
  • Notifications temps réel via Redis Pub/Sub

Documentation générée le : 2025-01-18
Version API : 4.0.0
Technologies : Go, Gin, PostgreSQL, Redis, TomTom API
Support : Développé avec ❤️ en Go

S
Description
No description provided
Readme
154 MiB
Languages
TypeScript 59.3%
Go 33.9%
CSS 6.3%
Python 0.3%