diff --git a/README.md b/README.md index 29b7f1a0..6fe8376d 100644 --- a/README.md +++ b/README.md @@ -35,14 +35,13 @@ Cette API REST complète gère une plateforme de livraison avec assignation auto - **📍 Suivi temps réel** avec ETA et géolocalisation - **🔄 Système de queues** Redis optimisé pour les livraisons - **⚡ Workers automatiques** (nettoyage, assignation, notifications) -- **🎯 Système de pénalités** pour la gestion des comportements (client & livreur) -- **🔔 Notifications push** Expo (iOS/Android) pour clients et livreurs -- **🤖 Intégration Telegram** pour alertes et notifications admin/livreur +- **🎯 Système de pénalités clients** — amendes progressives sur annulations (livreurs non concernés) +- **🤖 Notifications Telegram** pour clients, livreurs et admins (push Expo abandonné) - **💸 Paiements crypto** via NowPayments (webhook HMAC) - **🛡️ WAF nginx + ModSecurity** (OWASP CRS) en production - **📱 Applications mobiles** Expo 54 (client + admin/livreur) - **🏷️ Prix par quantité activables/désactivables** — visibilité client filtrée automatiquement -- **⏱️ Bouton "Client absent"** — timer 5 min au statut `arrived`, amende automatique au livreur si annulation +- **⏱️ Bouton "Client absent"** — timer 5 min au statut `arrived`, amende automatique appliquée au **client** si absent - **📲 OTA updates** canaux nommés par rôle (`pre-prod-client`, `production-client`, `pre-prod-admin`, etc.) ### 🏗️ Stack Technique @@ -721,7 +720,10 @@ DB_PASSWORD= # Mot de passe PostgreSQL USER_JWT_SECRET= # Secret JWT clients (min 32 chars) ADMIN_JWT_SECRET= # Secret JWT admin/livreur/cabine (min 32 chars) REDIS_PASSWORD= # Mot de passe Redis -TOMTOM_API_KEY= # Clé API TomTom +TOMTOM_API_KEY= # Clé API TomTom (principale / legacy) +TOMTOM_API_KEY_1= # Clé TomTom #1 (rotation automatique) +TOMTOM_API_KEY_2= # Clé TomTom #2 (rotation automatique) +TOMTOM_API_KEY_3= # Clé TomTom #3 (rotation automatique) SESSION_SECRET= # Secret sessions TELEGRAM_WEBHOOK_URL= # URL webhook Telegram TELEGRAM_WEBHOOK_SECRET= # Secret webhook Telegram @@ -730,27 +732,22 @@ NOWPAYMENTS_IPN_SECRET= # Secret IPN NowPayments --- -## 🔔 Notifications Push & Telegram +## 🔔 Notifications -### Push Notifications (Expo) +Les notifications clients et livreurs sont gérées **exclusivement via Telegram** — les push notifications Expo (iOS/Android) ne sont plus utilisées. -Le système utilise Expo Push Notifications pour envoyer des notifications aux applications mobiles (client et livreur). Les tokens Expo sont envoyés directement via l'API Expo depuis le backend — il n'y a pas d'endpoint REST dédié à l'enregistrement du push token. +### Notifications Telegram -**Flux :** -1. L'app mobile obtient un `ExponentPushToken` via `expo-notifications` -2. Le backend envoie les notifications via `sendExpoPush()` dans `db/db_notifications.go` -3. Expo relay la notification vers le device cible (iOS/Android) +Clients, livreurs et admins reçoivent leurs alertes via un bot Telegram lié à leur compte. **Types de notifications envoyées :** - `assigned` — Commande assignée à un livreur - `en_route` — Livreur en route (avec ETA) -- `arrived` — Livreur arrivé (bouton "Le livreur est là") +- `arrived` — Livreur arrivé - `livre` — Commande livrée -- `ready_pickup` — Notification cabine "descendez chercher" +- `ready_pickup` — Cabine : "descendez chercher votre commande" - `address_proposal` — Proposition de changement d'adresse -### Notifications Telegram - Les admins et livreurs peuvent lier leur compte Telegram pour recevoir des alertes. #### Générer un token de liaison (Admin) @@ -1856,7 +1853,9 @@ Content-Type: application/json --- -### Système de Pénalités +### Système de Pénalités (Clients uniquement) + +Les amendes s'appliquent **uniquement aux clients**. Les livreurs n'ont pas d'amende. Les amendes sont stockées dans `clients.amende` (PostgreSQL). Tant que `amende > 0`, le middleware `BlockClientIfPenalty` bloque toute tentative de checkout. @@ -1870,7 +1869,7 @@ Les amendes sont stockées dans `clients.amende` (PostgreSQL). Tant que `amende **Sources d'amende :** - Client annule sa propre commande → `ApplyCancellationPenalty` (incrémente `cancellations_count`) -- Livreur annule depuis le statut `arrived` (client absent) → même fonction appelée automatiquement +- Livreur marque le client absent depuis le statut `arrived` → amende appliquée automatiquement sur le **client** **Message d'erreur au checkout bloqué :** ```json @@ -2471,23 +2470,26 @@ L'ETA est calcule en utilisant l'API TomTom qui prend en compte: - Les travaux - L'heure de la journee +**Rotation automatique des clés :** jusqu'à 3 clés TomTom peuvent être configurées (`TOMTOM_API_KEY`, `TOMTOM_API_KEY_1`, `TOMTOM_API_KEY_2`, `TOMTOM_API_KEY_3`). En cas de quota dépassé (HTTP 403/429), le système passe automatiquement à la clé suivante sans interruption de service. + ```mermaid flowchart TD - A[Demande ETA] --> B{TomTom API disponible?} - B -->|Oui| C[Appel TomTom Routing API] - C --> D[ETA avec trafic reel] + A[Demande ETA] --> B{Clés TomTom configurées?} B -->|Non| E[Calcul Haversine] - E --> F[Distance a vol d'oiseau] + B -->|Oui| C[Appel TomTom — clé active] + C --> Q{Quota dépassé 403/429?} + Q -->|Oui| R{Clé suivante disponible?} + R -->|Oui| C + R -->|Non| E + Q -->|Non| D[ETA avec trafic réel] + E --> F[Distance à vol d'oiseau] F --> G[Vitesse moyenne 30 km/h] - G --> H[ETA estime] + G --> H[ETA estimé] 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: +**Fallback:** Si toutes les clés TomTom sont épuisées ou indisponibles, le système utilise un calcul local base sur: - Distance Haversine - Vitesse moyenne estimee (30 km/h en ville) @@ -2896,9 +2898,9 @@ Si une adresse ne peut pas etre geocodee: - Un log d'erreur est genere - L'admin peut corriger l'adresse manuellement -#### API TomTom Indisponible +#### API TomTom Indisponible / Quota dépassé -Le systeme bascule automatiquement sur le calcul local: +Le système tente d'abord toutes les clés disponibles en rotation, puis bascule 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 @@ -3049,12 +3051,21 @@ Le systeme bascule automatiquement sur le calcul local: ## 📋 Changelog +### v5.4.0 — 2026-05-18 + +- **Rotation automatique des clés TomTom** : jusqu'à 3 clés configurables (`TOMTOM_API_KEY_1/2/3`). En cas de quota dépassé (403/429), le système passe à la clé suivante automatiquement sans interruption. Fallback Haversine si toutes les clés sont épuisées. +- **Sécurité — création d'utilisateurs** : seul un `admin` peut créer des comptes `livreur` ou `cabine` via l'API. La création de compte `admin` est entièrement bloquée via l'application — uniquement possible en base de données directement. +- **Sécurité — cabine** : le rôle `cabine` n'a plus aucun droit de création d'utilisateurs ou de clients (retiré côté backend). +- **Fix frontend** : `createUserByAdmin` appelait `/admin/auth/register` (inexistant) → corrigé vers `/admin/protected/users`. +- **WAF ModSecurity logs** : les logs nginx et l'audit log ModSecurity sont désormais montés sur l'hôte (`/var/log/waf/nginx/` et `/var/log/waf/modsec/`) via volumes Docker stables. La variable `MODSEC_AUDIT_LOG` redirige l'audit log vers un fichier (au lieu de stdout) pour collecte Wazuh. +- **Notifications Telegram uniquement** : les push notifications Expo (iOS/Android) sont abandonnées. Clients et livreurs reçoivent désormais toutes leurs alertes via Telegram. + ### v5.3.0 — 2026-05-15 - **Prix inactifs filtrés côté client** : le flag `active_price` sur `PRODUCT_PRICES` permet de désactiver un tarif sans le supprimer. Les endpoints publics/client et les frontends web+mobile masquent automatiquement les prix inactifs. Admin et cabine voient tous les prix. - **Désactivation au lieu de suppression** : dans la modal d'édition produit (admin), retirer un prix existant le désactive (`active_price = false`) plutôt que de le supprimer de la base. -- **Amende automatique — livreur annule depuis `arrived`** : quand le livreur passe une commande en `cancelled` alors qu'elle était à `arrived`, `ApplyCancellationPenalty` est appelé automatiquement (amende progressive : 20→50→100→150€). -- **Bouton "Client absent"** : après 5 minutes au statut `arrived`, l'app livreur affiche un bouton "Client absent" qui déclenche l'annulation avec amende. +- **Amende automatique client — livreur annule depuis `arrived`** : quand le livreur marque le client absent (`arrived` → `cancelled`), `ApplyCancellationPenalty` est appelé automatiquement sur le **client** (amende progressive : 20→50→100→150€). +- **Bouton "Client absent"** : après 5 minutes au statut `arrived`, l'app livreur affiche un bouton "Client absent" qui déclenche l'annulation avec amende sur le client. - **Message d'erreur checkout avec contact** : le message de blocage inclut désormais "Prenez attache avec Milieu Nantais sur signal pour régulariser votre situation." - **OTA channels par rôle** : les canaux Expo OTA sont désormais nommés `pre-prod-client` / `production-client` / `pre-prod-admin` / `production-admin` pour éviter les mises à jour croisées entre builds. @@ -3066,8 +3077,8 @@ Le systeme bascule automatiquement sur le calcul local: --- -**Documentation mise à jour le :** 2026-05-15 -**Version API :** 5.3.0 +**Documentation mise à jour le :** 2026-05-18 +**Version API :** 5.4.0 **Technologies :** Go 1.24, Gin, PostgreSQL 16, Redis 7, React 19, Expo 54, TomTom API, ModSecurity WAF **Déploiement :** Docker Compose · Nginx + ModSecurity OWASP CRS · TLS 1.2/1.3 **Base URL prod :** `https://mln-uber.club`