chore: update
This commit is contained in:
@@ -680,17 +680,20 @@ Tous les serveurs backend communiquent via un réseau WireGuard privé `10.0.0.0
|
||||
|
||||
### Architecture DMZ / LAN
|
||||
|
||||
```
|
||||
Internet
|
||||
│
|
||||
▼
|
||||
prod-uber (DMZ — 185.103.166.119)
|
||||
│ 80/443 public
|
||||
│ ──── VPN (10.0.0.6) ────► bdd-redis-prod (LAN — 10.0.0.5)
|
||||
│ ├── PostgreSQL :5432
|
||||
│ └── Redis :6379
|
||||
│
|
||||
vpn-uber (10.0.0.1) — jump host SSH pour accès aux autres serveurs
|
||||
```mermaid
|
||||
graph TB
|
||||
Internet((Internet)) -->|"80/443 public"| Prod["prod-uber — DMZ<br/>185.103.166.119"]
|
||||
Prod -->|"VPN (10.0.0.6)"| BDD["bdd-redis-prod — LAN<br/>10.0.0.5"]
|
||||
BDD --> PG["PostgreSQL :5432"]
|
||||
BDD --> Redis["Redis :6379"]
|
||||
|
||||
VPN["vpn-uber — 10.0.0.1<br/>jump host SSH"] -.->|"accès admin uniquement"| BDD
|
||||
VPN -.-> Prod
|
||||
|
||||
style Internet fill:#eee,stroke:#999
|
||||
style Prod fill:#fde68a,stroke:#b45309
|
||||
style BDD fill:#bbf7d0,stroke:#15803d
|
||||
style VPN fill:#bfdbfe,stroke:#1d4ed8
|
||||
```
|
||||
|
||||
L'application prod-uber se connecte à PostgreSQL et Redis via les IP VPN :
|
||||
@@ -826,6 +829,26 @@ SESSION_SECRET= # Secret sessions
|
||||
TELEGRAM_WEBHOOK_URL= # URL webhook Telegram
|
||||
TELEGRAM_WEBHOOK_SECRET= # Secret webhook Telegram
|
||||
NOWPAYMENTS_IPN_SECRET= # Secret IPN NowPayments
|
||||
|
||||
# Stockage médias produits (photos/vidéos)
|
||||
STORAGE_DRIVER=local # "local" (disque, défaut) ou "s3" (RustFS)
|
||||
# Requis uniquement si STORAGE_DRIVER=s3 :
|
||||
S3_REGION= # Région S3 (arbitraire pour RustFS, ex: us-east-1)
|
||||
S3_BUCKET= # Nom du bucket
|
||||
S3_ENDPOINT= # URL du endpoint S3-compatible (RustFS, IP VPN interne)
|
||||
RUSTFS_ACCESS_KEY= # Clé d'accès RustFS
|
||||
RUSTFS_SECRET_KEY= # Clé secrète RustFS
|
||||
```
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
Upload["CreateProduct /<br/>UploadMedia"] --> Check{"STORAGE_DRIVER"}
|
||||
Check -->|"local (défaut)"| Local["LocalStorage<br/>disque ./uploads"]
|
||||
Check -->|"s3"| S3["S3Storage<br/>RustFS (auto-hébergé)"]
|
||||
|
||||
Delete["DeleteProduct /<br/>DeleteMedia"] --> KeyCheck{"media.Key<br/>rempli ?"}
|
||||
KeyCheck -->|non| Local
|
||||
KeyCheck -->|oui| S3
|
||||
```
|
||||
|
||||
---
|
||||
@@ -1356,6 +1379,38 @@ Content-Type: application/json
|
||||
- `401` - Non authentifié
|
||||
- `500` - Erreur création commande
|
||||
|
||||
**Réponse — adresse connue pour être mal formée (400 Bad Request):**
|
||||
|
||||
Si l'adresse saisie correspond (match exact ou normalisé — accents/casse/espaces ignorés) à une entrée de la table de corrections gérée par l'admin/cabine (`POST/DELETE /addresses`), le checkout est volontairement bloqué pour forcer une reconfirmation du client plutôt que d'appliquer la correction en silence :
|
||||
```json
|
||||
{
|
||||
"error": "Adresse non reconnue",
|
||||
"corrected_address": "15 Rue de la Paix, 75002 Paris, France"
|
||||
}
|
||||
```
|
||||
Le client doit renvoyer la requête avec `delivery_address` = `corrected_address` pour valider le checkout.
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant C as Client
|
||||
participant API as API (ValidateBasket)
|
||||
participant DB as adresse_correction
|
||||
|
||||
C->>API: POST /checkout {delivery_address}
|
||||
API->>DB: CheckAddress(delivery_address)
|
||||
DB->>DB: Match exact, sinon fallback normalisé<br/>(accents/casse/espaces)
|
||||
alt Correction trouvée
|
||||
DB-->>API: corrected_address
|
||||
API-->>C: 400 {error, corrected_address}
|
||||
C->>C: Affiche la suggestion (modal)
|
||||
C->>API: POST /checkout {delivery_address: corrected_address}
|
||||
API-->>C: 200 Commande créée
|
||||
else Aucune correction connue
|
||||
DB-->>API: nil
|
||||
API-->>C: 200 Commande créée
|
||||
end
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
#### Mes commandes avec suivi
|
||||
@@ -3106,6 +3161,13 @@ Le système tente d'abord toutes les clés disponibles en rotation, puis bascule
|
||||
|
||||
## 📋 Changelog
|
||||
|
||||
### v5.7.0 — 2026-08-04
|
||||
|
||||
- **Nouveau — choix du backend de stockage médias (`STORAGE_DRIVER`)** : les photos/vidéos produits pouvaient être stockées soit sur disque local (`CreateProduct`) soit sur S3/RustFS (`UploadMedia`) selon l'endpoint utilisé, sans logique commune. Une interface `Storage` unifiée (`services/storage.go`, implémentations `LocalStorage`/`S3Storage`) est maintenant utilisée par les deux endpoints, pilotée par la variable d'environnement `STORAGE_DRIVER` (`local` par défaut, ou `s3`).
|
||||
- **Fix — nettoyage croisé des médias à la suppression** : `DeleteProduct` supprimait toujours sur disque (même pour un média stocké sur S3) et `DeleteMedia` supprimait toujours sur S3 (même pour un média local), laissant systématiquement des fichiers orphelins sur l'autre backend. Les deux fonctions branchent désormais sur `media.Key` (rempli uniquement pour les médias S3) pour cibler le bon backend, indépendamment du `STORAGE_DRIVER` courant.
|
||||
- **Fix — correction d'adresse jamais appliquée au checkout (`CheckAddress`)** : le mécanisme de correction d'adresse (table `adresse_correction`, gérée par l'admin/cabine) détectait bien une adresse connue pour être mal formée, mais le checkout était systématiquement abandonné au lieu de proposer la correction de façon exploitable — le contrat de réponse (`corrected_address`) n'était lu nulle part côté client (mobile : parsing d'un format de message d'erreur obsolète ; web : aucune gestion de ce cas). Mobile et web lisent désormais directement `corrected_address` et proposent au client de reprendre le checkout avec l'adresse corrigée.
|
||||
- **Fix — matching de correction d'adresse trop strict** : `CheckAddress` ne matchait qu'une égalité exacte de texte. Ajout d'un fallback normalisé (accents/casse/espaces ignorés, réutilise `utils.NormalizeAddress` déjà utilisée par le service de géocodage) pour rattraper les variantes mineures de saisie.
|
||||
|
||||
### v5.6.0 — 2026-07-11
|
||||
|
||||
- **Fix — ETA introuvable pour l'annulation tardive (`CheckCommandETAExistsAndValid`)** : la fonction lisait la clé Redis `command:eta:{id}` (un *hash*) avec `Redis.Get` (string), ce qui provoquait systématiquement une erreur `WRONGTYPE` silencieuse. Une ETA valide n'était donc jamais détectée par ce chemin, et un client pouvait annuler sans pénalité juste après l'assignation d'un livreur (avant le passage au statut `en_route`). Corrigé en `Redis.HGetAll`.
|
||||
|
||||
Reference in New Issue
Block a user