# My Truck — Installation Asustor (Portainer + MariaDB)

App complète : **Backend FastAPI + Frontend React + ta MariaDB existante** + apps mobiles Android / iOS (via Capacitor).

Approche utilisée : **volume-mount des sources** dans des images officielles (`python:3.11-slim` + `node:20-alpine`). Pas de build d'image Docker → mise à jour ultra simple (tu remplaces juste les fichiers).

---

## 📋 Pour les pressés

Tu as **2 cas d'installation** :

### Cas A — DB partagée avec ton autre site (recommandé)
Tu as déjà une DB avec une table `users` pour ton autre site. My Truck va l'utiliser pour partager les comptes.
→ **Utilise `migration_mytruck.sql`** (étape 1.2 ci-dessous)

### Cas B — Installation propre
Pas d'autre site, DB neuve.
→ **Utilise `init.sql`** (étape 1.2 ci-dessous)

---

## ⚠️ Ordre des étapes

1. Préparer la base MariaDB (phpMyAdmin)
2. Copier les fichiers dans `/volume1/Web/cariste-api/`
3. Créer la stack Portainer
4. Première connexion + changement de code

---

## 🗄️ Étape 1 — Base MariaDB

### 1.1 Choisir / créer la base

- **Cas A** : tu utilises ta DB existante (ex `gp-eff_gestion_palettes`). Pas de création.
- **Cas B** : crée la base `cariste_api` avec interclassement `utf8mb4_unicode_ci`.

### 1.2 Importer le schéma

phpMyAdmin → sélectionne ta base → onglet **Importer** :
- **Cas A** → choisis `migration_mytruck.sql` (ajoute 7 tables + 1 colonne à `users`, sans toucher tes données)
- **Cas B** → choisis `init.sql` (crée toutes les tables)

### 1.3 Créer un utilisateur dédié (Cas B uniquement)

Pour Cas A, tu utilises déjà l'user MariaDB de ton autre site. Saute cette étape.

Pour Cas B :
phpMyAdmin → **Comptes utilisateurs** → **Ajouter un compte** :
- Nom : `cariste_api`
- Hôte : `Tout hôte (%)`
- Mot de passe : génère-en un, **note-le**
- Privilèges globaux : RIEN
- **Exécuter**

Puis **Modifier les privilèges** → onglet **Base de données** → choisis ta base → **Tout cocher** → **Exécuter**.

---

## 📁 Étape 2 — Fichiers sur le NAS

Via **File Explorer** d'Asustor, place TOUT le contenu du zip dans `/volume1/Web/cariste-api/` :

```
/volume1/Web/cariste-api/
├── docker-compose.yml
├── init.sql                          (Cas B)
├── migration_mytruck.sql             (Cas A)
├── README.md
├── MOBILE_BUILD.md
├── backend/
│   ├── requirements.txt
│   └── server.py
└── frontend/
    ├── package.json
    ├── yarn.lock
    ├── public/
    └── src/
```

---

## 🌐 Étape 3.5 — Reverse proxy HTTPS Asustor sur `appli.gp-eff.fr`

L'architecture utilise un **container nginx interne** qui regroupe API et frontend sur un seul port (`8080`). Tu n'as qu'**une seule entrée** à configurer dans le reverse proxy Asustor.

### Pré-requis DNS

Crée un enregistrement **`A`** chez ton registrar :
- **Nom** : `appli`
- **Type** : `A`
- **Valeur** : l'IP publique de ton NAS (celle où arrivent tes redirections de ports)
- **TTL** : 300 (5 min)

Vérifie : `nslookup appli.gp-eff.fr` doit retourner ton IP.

### Configurer le reverse proxy Asustor

1. **ADM** → **Services Web** → **Reverse Proxy** → **Ajouter**
2. Renseigne :
   - **Nom d'hôte** : `appli.gp-eff.fr`
   - **Port d'écoute** : `443` (HTTPS standard, plus besoin du `:8443` dans l'URL)
   - **Activer SSL** : ✅
   - **Certificat** : Let's Encrypt pour `appli.gp-eff.fr` (ADM peut le générer si le port 80 est ouvert)
   - **Hôte cible** : `localhost`
   - **Port cible** : `8080`
   - **Protocole cible** : `http`
   - **WebSocket support** : ✅ (indispensable)
3. **Sauvegarder** → relance le service Web Asustor

⚠️ **Important** : sur ton routeur, ouvre les ports `80` (pour Let's Encrypt) et `443` (HTTPS) vers ton NAS.

Désormais l'app est joignable sur :
- `https://appli.gp-eff.fr/` → frontend My Truck
- `https://appli.gp-eff.fr/api/*` → backend (via nginx interne)
- `wss://appli.gp-eff.fr/api/ws/...` → WebSocket temps réel
- `https://appli.gp-eff.fr/sso?t=...` → entrée SSO depuis GP v3

---

## 🚀 Étape 4 — Stack Portainer

### 3.1 Trouve l'IP locale de ton NAS
Note l'IP locale (ex: `192.168.1.50`).

### 3.2 Crée la stack
Portainer → **Stacks** → **Add stack** → Web editor → colle le `docker-compose.yml`.

**Modifie ces valeurs critiques** :
- `MYSQL_HOST` : `host.docker.internal` ou IP du NAS
- `MYSQL_USER` : `cariste_api` (Cas B) ou ton user existant (Cas A)
- `MYSQL_PASSWORD` : le mot de passe
- `MYSQL_DB` : `cariste_api` (Cas B) ou nom de ta DB existante (Cas A)
- `JWT_SECRET` : chaîne longue aléatoire (32+ chars). Génère via : `openssl rand -hex 32`
- `REACT_APP_BACKEND_URL` : `http://<IP-NAS>:8002` (l'URL qu'on tape depuis le navigateur)

**Deploy the stack**.

### 3.3 Premier démarrage (lent)
3-8 minutes (pip install + yarn install + yarn build). Ensuite, redémarrer = quasi instantané.

### 3.4 Vérifier
- `cariste-backend` running : `Uvicorn running on http://0.0.0.0:8002`
- `cariste-frontend` running : `Accepting connections at http://localhost:8080`

---

## ✅ Étape 4 — Première connexion

URL : `http://<IP-NAS>:8080`

### Cas B (installation propre)
Un compte par défaut est créé au premier démarrage :
- **Identifiant** : `admin.b`
- **Code** : `123456`

⚠️ Change ce code immédiatement (force prompt désactivé sur ce compte pour faciliter le 1er login — fais-le manuellement via Paramètres).

### Cas A (DB partagée)
Connecte-toi avec un compte existant de ton autre site. **À la première connexion**, l'app te forcera à choisir un **nouveau code à 6 chiffres** personnel.

> Note : le rôle `admin` de ton autre site est **bloqué** sur My Truck (sécurité). Seuls les rôles `cariste` et `bureau` peuvent se connecter.
> Si tu as déjà créé tes utilisateurs avec le rôle `user`, fais en SQL :
> ```sql
> UPDATE users SET role = 'cariste' WHERE role = 'user';
> ```
> Puis depuis les Paramètres My Truck, passe certains en `bureau`.

---

## 🔐 Architecture authentification

- **Identifiant** : `prenom.x` (ex `mathieu.u`) — partagé avec ton site web
- **Mot de passe** : code à **6 chiffres** spécifique My Truck (bcrypt)
- **Session** : JWT 1 an (reste connecté tant qu'il ne se déconnecte pas)
- **Roles** :
  - `admin` → ton site web uniquement (refusé sur My Truck)
  - `bureau` → My Truck, gère les utilisateurs/phrases/notifs
  - `cariste` → My Truck, crée et complète ses dossiers

---

## 📱 Apps mobiles Android / iOS

Voir `MOBILE_BUILD.md`. En résumé :
- Le dossier `frontend/` contient le projet **Capacitor** prêt
- `npx cap open android` → ouvre dans Android Studio → build APK
- `npx cap open ios` → ouvre dans Xcode (sur Mac) → build IPA

---

## 🔄 Mises à jour de l'app

1. **File Explorer** → remplace les fichiers dans `/volume1/Web/cariste-api/backend/` ou `/frontend/`
2. **Portainer** → **Restart** le container concerné
3. ✨ **Auto-rebuild** : le frontend détecte automatiquement les changements dans `src/` et `public/` et rebuild tout seul au redémarrage (3 min). Si jamais ça coince, mets `FORCE_REBUILD=1` dans la stack et update.

### ⚠️ Erreur "Unexpected token '<'" dans la console
Cette erreur signifie que ton navigateur charge un HTML à la place d'un fichier JS (cache de build périmé).
- **Solution** : passe `FORCE_REBUILD=1` dans la stack Portainer, update, attends le rebuild (3 min), puis **Ctrl+Shift+R** dans le navigateur.
- La version actuelle du docker-compose détecte ce cas automatiquement.

---

## 🐛 Erreurs courantes

| Erreur | Solution |
|--------|----------|
| `Access denied for user '...'@...` | Vérifie `MYSQL_USER` / `MYSQL_PASSWORD` |
| `Can't connect to MySQL` | Sur certains Asustor, remplace `host.docker.internal` par l'IP locale du NAS |
| `Ce compte n'a pas accès à My Truck` | C'est un compte `admin` ; passe-le en `bureau` ou `cariste` en SQL |
| Page blanche | Logs `cariste-frontend` → manque de RAM (besoin 2GB+) ou `yarn build` échoué |
| "Network Error" login | `REACT_APP_BACKEND_URL` mal réglé. Doit être l'URL EXACTE que tu tapes pour atteindre le NAS |
| Mixed Content (HTTPS → HTTP) | Si tu accèdes au frontend en HTTPS, ton backend doit aussi être en HTTPS (Cloudflare Tunnel = gratuit) |

---

## 🔑 Réinitialiser le code d'un utilisateur (admin)

phpMyAdmin → ta base → onglet SQL :
```sql
UPDATE users
   SET must_change_password = 1,
       password_hash = '$2b$12$Wj4l2eN7e1iVdjQYxHzqDeQX3pUDC6w8M2.HBJDp6E.k4qHQEKa0K'
 WHERE username = 'mathieu.u';
-- Le hash ci-dessus correspond au code "000000". L'utilisateur DEVRA le changer.
```

Ou plus simple : depuis l'interface My Truck (compte bureau), va dans **Paramètres → Utilisateurs**, clique **Modifier**, mets un nouveau code à 6 chiffres.

---

## 🔔 Notifications

- **Web** : fonctionne via Notifications API du navigateur. Clique "Activer" dans le bandeau du dashboard. Nécessite HTTPS pour les notifs hors onglet.
- **Notifications manuelles** : depuis **Paramètres → Notifications**, le bureau peut envoyer un message à un ou plusieurs caristes.
- **Push mobile** : nécessite Firebase Cloud Messaging (voir `MOBILE_BUILD.md`)

---

## 🌐 HTTPS via Cloudflare Tunnel (recommandé pour le futur domaine)

Le jour où tu achètes ton domaine :
1. Compte Cloudflare gratuit
2. Container `cloudflare/cloudflared` dans Portainer
3. Tunnel qui pointe sur `http://<IP-NAS>:8080` (frontend) et `http://<IP-NAS>:8002` (backend)
4. 2 URL HTTPS Cloudflare disponibles publiquement
5. Mets à jour `REACT_APP_BACKEND_URL` avec l'URL HTTPS du backend → rebuild

---

## Variables d'environnement (récap)

| Variable | Description | Exemple |
|----------|-------------|---------|
| `MYSQL_PASSWORD` | Mot de passe user MariaDB | `xxxx` |
| `MYSQL_USER` | User MariaDB | `cariste_api` ou ton user existant |
| `MYSQL_DB` | Nom de la base | `cariste_api` ou ta DB existante |
| `MYSQL_HOST` | Hôte MariaDB | `host.docker.internal` |
| `JWT_SECRET` | Clé secrète JWT (32+ chars) | (chaîne aléatoire) |
| `REACT_APP_BACKEND_URL` | URL publique du backend | `http://192.168.1.50:8002` |
| `FORCE_REBUILD` | `"1"` pour forcer un rebuild React | `"0"` |
