summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorertopogo <erwin.t.pombett@gmail.com>2026-02-21 03:50:58 +0100
committerertopogo <erwin.t.pombett@gmail.com>2026-02-21 03:50:58 +0100
commit8b2e56c73ca7aaca52785fe228ca3b4401db3d82 (patch)
tree88c61c0629fc32499d8048d7878f493eb0936104
parentaa494fd8e24b0aabcc890655370a15358f9e6755 (diff)
feat: attributs bougies (metadata) + Caddy/DNS docs
-rw-r--r--DOC_IMPORT_PRODUITS.md169
-rw-r--r--DOC_TECHNIQUE.md168
-rw-r--r--INSTALLATION.md144
-rw-r--r--app-management.md83
-rw-r--r--backend/data/products-import.csv13
-rw-r--r--backend/scripts/import-products.js10
-rw-r--r--env-example16
-rw-r--r--helper-cmd.md62
-rw-r--r--storefront/pages/index.js26
9 files changed, 485 insertions, 206 deletions
diff --git a/DOC_IMPORT_PRODUITS.md b/DOC_IMPORT_PRODUITS.md
index b41cba8..784e83b 100644
--- a/DOC_IMPORT_PRODUITS.md
+++ b/DOC_IMPORT_PRODUITS.md
@@ -37,10 +37,20 @@ Colonnes minimales:
- `inventory_quantity` (optionnel, defaut: 0)
- `manage_inventory` (optionnel, true/false)
+Colonnes attributs (optionnelles, stockees dans `product.metadata`):
+- `volume` (ex: 200ml, 500ml)
+- `type_meche` (ex: bois, coton)
+- `parfum` (ex: lavande, vanille)
+- `couleur` (ex: blanche, bleue)
+- `type_cire` (ex: soja, colza, abeille)
+
+Ces attributs sont descriptifs (pas de variantes). Ils sont affiches sur la
+fiche produit du storefront. Si une colonne est vide, l'attribut n'est pas affiche.
+
Exemple:
```
-external_id,title,handle,description,thumbnail,option_title,option_value,variant_title,variant_sku,price_amount,currency_code,inventory_quantity,manage_inventory
-prod-001,Savon Lavande,savon-lavande,"Savon artisanal a la lavande.",https://via.placeholder.com/600x600.png?text=Savon+Lavande,Taille,100g,100g,SKU-SAV-100,650,eur,100,true
+external_id,title,handle,description,thumbnail,option_title,option_value,variant_title,variant_sku,price_amount,currency_code,inventory_quantity,manage_inventory,volume,type_meche,parfum,couleur,type_cire
+prod-001,Bougie Lavande,bougie-lavande,"Bougie artisanale a la lavande.",,Taille,200ml,200ml,SKU-BOU-LAV-200,1200,eur,50,true,200ml,coton,lavande,blanche,soja
```
## FR - Comportement
@@ -53,18 +63,82 @@ prod-001,Savon Lavande,savon-lavande,"Savon artisanal a la lavande.",https://via
## FR - Git flow (branche + push)
Nom de branche suggere: `feature/import-csv-produits`
-Commandes type:
+### Creer et developper la feature
```
git flow feature start import-csv-produits
git status
-git add backend/scripts/import-products.js backend/data/products-import.csv backend/package.json DOC_IMPORT_PRODUITS.md helper-cmd.md DOC_TECHNIQUE.md
-git commit -m "Add product CSV import script and docs"
+git add -A
+git commit -m "feat: attributs bougies (metadata) + import CSV"
git push -u chillka feature/import-csv-produits
```
-Selon votre process:
+### Tester sur huitral (avant de finir la feature)
```
+# Sur huitral
+cd /var/www/lucien-sens-bon
+git fetch origin
+git checkout feature/import-csv-produits
+git reset --hard origin/feature/import-csv-produits
+
+# Dry-run (test sans ecriture en base)
+docker compose run --rm backend npm run import:products -- --dry-run
+
+# Import reel
+docker compose run --rm backend npm run import:products
+
+# Rebuild storefront (pour afficher les attributs metadata)
+docker compose up -d --build storefront
+
+# Verifier
+curl -s http://localhost:9000/store/products | python3 -m json.tool | head -30
+```
+
+### Finir la feature et merger dans develop
+```
+# Sur le poste de dev
git flow feature finish import-csv-produits
+git push chillka develop
+git push chillka --delete feature/import-csv-produits
+```
+
+### Deployer develop sur huitral
+```
+# Sur huitral
+cd /var/www/lucien-sens-bon
+git fetch origin
+git checkout develop
+git reset --hard origin/develop
+docker compose up -d --build storefront
+```
+
+## FR - Alternative : remettre la branche feature dans main (sans git-flow)
+Si tu veux ramener le contenu de la feature vers `main` directement :
+```
+git checkout main
+git merge feature/import-csv-produits
+git push origin main
+```
+
+Si tu veux utiliser la branche distante directement :
+```
+git checkout main
+git merge origin/feature/import-csv-produits
+git push origin main
+```
+
+## FR - Cas courant: commit fait sur main avant la feature
+Si un commit a ete fait sur `main` avant la creation de la feature, il faut le recuperer:
+```
+git log --oneline main -n 5
+git cherry-pick <hash_du_commit>
+```
+Alternative si plusieurs commits:
+```
+git cherry-pick <hash1> <hash2>
+```
+Ou merger `main` (si votre process l'autorise):
+```
+git merge main
```
## FR - Troubleshoot git-flow
@@ -134,10 +208,20 @@ Pflichtspalten:
- `inventory_quantity` (optional, Default: 0)
- `manage_inventory` (optional, true/false)
+Attribut-Spalten (optional, in `product.metadata` gespeichert):
+- `volume` (z.B. 200ml, 500ml)
+- `type_meche` (z.B. bois, coton)
+- `parfum` (z.B. lavande, vanille)
+- `couleur` (z.B. blanche, bleue)
+- `type_cire` (z.B. soja, colza, abeille)
+
+Diese Attribute sind beschreibend (keine Varianten). Sie werden auf der
+Produktseite im Storefront angezeigt. Leere Spalten werden nicht angezeigt.
+
Beispiel:
```
-external_id,title,handle,description,thumbnail,option_title,option_value,variant_title,variant_sku,price_amount,currency_code,inventory_quantity,manage_inventory
-prod-001,Savon Lavande,savon-lavande,"Savon artisanal a la lavande.",https://via.placeholder.com/600x600.png?text=Savon+Lavande,Taille,100g,100g,SKU-SAV-100,650,eur,100,true
+external_id,title,handle,description,thumbnail,option_title,option_value,variant_title,variant_sku,price_amount,currency_code,inventory_quantity,manage_inventory,volume,type_meche,parfum,couleur,type_cire
+prod-001,Bougie Lavande,bougie-lavande,"Bougie artisanale a la lavande.",,Taille,200ml,200ml,SKU-BOU-LAV-200,1200,eur,50,true,200ml,coton,lavande,blanche,soja
```
## DE - Verhalten
@@ -150,18 +234,79 @@ prod-001,Savon Lavande,savon-lavande,"Savon artisanal a la lavande.",https://via
## DE - Git flow (Branch + Push)
Branch Vorschlag: `feature/import-csv-produits`
-Typische Befehle:
+### Feature erstellen und entwickeln
```
git flow feature start import-csv-produits
git status
-git add backend/scripts/import-products.js backend/data/products-import.csv backend/package.json DOC_IMPORT_PRODUITS.md helper-cmd.md DOC_TECHNIQUE.md
-git commit -m "Add product CSV import script and docs"
+git add -A
+git commit -m "feat: Kerzen-Attribute (metadata) + CSV Import"
git push -u chillka feature/import-csv-produits
```
-Optional nach Prozess:
+### Auf huitral testen (vor Feature-Abschluss)
+```
+# Auf huitral
+cd /var/www/lucien-sens-bon
+git fetch origin
+git checkout feature/import-csv-produits
+git reset --hard origin/feature/import-csv-produits
+
+# Dry-run (Test ohne DB-Schreibvorgang)
+docker compose run --rm backend npm run import:products -- --dry-run
+
+# Echter Import
+docker compose run --rm backend npm run import:products
+
+# Storefront neu bauen (fuer Metadata-Attribute)
+docker compose up -d --build storefront
```
+
+### Feature abschliessen und in develop mergen
+```
+# Auf dem Entwicklungsrechner
git flow feature finish import-csv-produits
+git push chillka develop
+git push chillka --delete feature/import-csv-produits
+```
+
+### Develop auf huitral deployen
+```
+# Auf huitral
+cd /var/www/lucien-sens-bon
+git fetch origin
+git checkout develop
+git reset --hard origin/develop
+docker compose up -d --build storefront
+```
+
+## DE - Alternative: Feature-Branch direkt in main (ohne git-flow)
+Wenn du den Feature-Branch direkt nach `main` holen willst:
+```
+git checkout main
+git merge feature/import-csv-produits
+git push origin main
+```
+
+Wenn du direkt den Remote-Branch verwenden willst:
+```
+git checkout main
+git merge origin/feature/import-csv-produits
+git push origin main
+```
+
+## DE - Typisch: Commit auf main vor der Feature
+Wenn ein Commit bereits auf `main` erstellt wurde, muss er in die Feature:
+```
+git log --oneline main -n 5
+git cherry-pick <commit_hash>
+```
+Alternative fuer mehrere Commits:
+```
+git cherry-pick <hash1> <hash2>
+```
+Oder `main` mergen (falls erlaubt):
+```
+git merge main
```
## DE - Troubleshooting git-flow
diff --git a/DOC_TECHNIQUE.md b/DOC_TECHNIQUE.md
index 0c4b2f9..b5576a6 100644
--- a/DOC_TECHNIQUE.md
+++ b/DOC_TECHNIQUE.md
@@ -12,7 +12,7 @@ Le projet est compose de :
- **PostgreSQL** : base de donnees principale (clients, commandes, produits).
- **Redis** : cache et event bus.
- **Docker Compose** : orchestration des services.
-- **Apache** (optionnel) : reverse proxy pour publier en 80/443.
+- **Caddy** (sur araucaria) : reverse proxy + HTTPS automatique.
Ports principaux :
- `8000` : storefront (site public)
@@ -47,7 +47,7 @@ Ou le voir :
- [Docker Compose](https://docs.docker.com/compose/)
- [PostgreSQL](https://www.postgresql.org/docs/)
- [Redis](https://redis.io/docs/latest/)
-- [Apache reverse proxy](https://httpd.apache.org/docs/2.4/howto/reverse_proxy.html)
+- [Caddy reverse proxy](https://caddyserver.com/docs/caddyfile/directives/reverse_proxy)
## 3. Fichiers importants
@@ -97,26 +97,38 @@ Briques logicielles principales :
### 3.4 Schema technique (ASCII)
```
- +----------------------+
- | Storefront |
- | Next.js (Node) |
- | :8000 |
- +----------+-----------+
- |
- | HTTP (API)
- v
- +----------------------+
- | MedusaJS |
- | Node + Express |
- | :9000 (API/Admin) |
- +-----+----------+-----+
- | |
- SQL | | Cache/Event bus
- v v
- +---------------+ +----------------+
- | PostgreSQL | | Redis |
- | :5432 | | :6379 |
- +---------------+ +----------------+
+ Internet / LAN
+ |
+ v
+ +---------------------------+
+ | araucaria (Caddy) |
+ | HTTPS / reverse proxy |
+ | lsb.arauco.online |
+ | api-lsb.arauco.online |
+ +------------+--------------+
+ |
+ v
+ +---------------------------+ huitral
+ | |
+ | +--------------------+ |
+ | | Storefront | |
+ | | Next.js :8000 | |
+ | +--------+-----------+ |
+ | | |
+ | | HTTP (API) |
+ | v |
+ | +--------------------+ |
+ | | MedusaJS | |
+ | | :9000 (API) | |
+ | +-----+--------+----+ |
+ | | | |
+ | SQL | | Cache |
+ | v v |
+ | +----------+ +-------+ |
+ | |PostgreSQL| | Redis | |
+ | | :5432 | | :6379 | |
+ | +----------+ +-------+ |
+ +---------------------------+
```
## 4. Installation rapide (serveur Linux)
@@ -143,16 +155,16 @@ docker compose up -d --build
### 4.1 Exemple reel (ce que nous avons fait)
-Contexte : backend sur `192.168.99.22:9000`, storefront sur `192.168.99.22:8000`.
+Contexte : backend sur huitral:9000, storefront sur huitral:8000, Caddy sur araucaria.
-1) Variables d'environnement (exemple utilise) :
+1) Variables d'environnement (production) :
```
DATABASE_URL=postgres://luciensbdb:********@192.168.99.35:5432/sens_bon_db
JWT_SECRET=supersecret
COOKIE_SECRET=supersecret
-ADMIN_CORS=http://192.168.99.22:9000
-STORE_CORS=http://192.168.99.22:8000
-NEXT_PUBLIC_MEDUSA_BACKEND_URL=http://192.168.99.22:9000
+NEXT_PUBLIC_MEDUSA_BACKEND_URL=https://api-lsb.arauco.online
+ADMIN_CORS=https://api-lsb.arauco.online,https://lsb.arauco.online,http://api-lsb.huitral.ruka.lan,http://lsb.huitral.ruka.lan
+STORE_CORS=https://lsb.arauco.online,http://lsb.huitral.ruka.lan
NODE_ENV=development
```
@@ -205,7 +217,7 @@ docker compose logs -f storefront
### 5.1 Logs systeme avec journalctl (systemd)
-Utiliser `journalctl` pour diagnostiquer les services systeme (Apache, dnsmasq, Docker).
+Utiliser `journalctl` pour diagnostiquer les services systeme (Caddy, dnsmasq, Docker).
Ou sont stockes les logs systeme :
- **Persistant** : `/var/log/journal/` (apres reboot)
@@ -251,10 +263,11 @@ sudo journalctl -u dnsmasq -S "10 min ago" --no-pager
### 5.2 Tests CORS (exemple utilise)
```
-curl -i -H "Origin: http://192.168.99.22:8000" http://192.168.99.22:9000/store/products
+curl -i -H "Origin: https://lsb.arauco.online" https://api-lsb.arauco.online/store/products
```
- Confirme que `Access-Control-Allow-Origin` autorise le storefront.
+- Pour le LAN : remplacer par `http://lsb.huitral.ruka.lan` et `http://api-lsb.huitral.ruka.lan`.
## 6. Ou se trouve la base de donnees ?
@@ -282,17 +295,36 @@ docker exec -it medusa-backend npm run seed
```
### 7.2 Storefront affiche "Chargement des produits..."
-Le storefront attend l'API backend. Verifier :
-- `NEXT_PUBLIC_MEDUSA_BACKEND_URL` dans `.env`
-- le backend repond sur `:9000`
+Le storefront attend l'API backend. Verifier dans l'ordre :
-Si le backend repond, mais que rien ne s'affiche :
-- verifier que le storefront a ete **rebuild** apres changement de `.env` :
+1) `NEXT_PUBLIC_MEDUSA_BACKEND_URL` dans `.env` doit pointer vers l'API
+ via Caddy (`https://api-lsb.arauco.online`), pas `localhost`.
+
+2) Le backend repond sur `:9000` :
+```
+curl http://localhost:9000/store/products
+```
+
+3) Le storefront a ete **rebuild** apres changement de `.env`
+ (`NEXT_PUBLIC_*` est injecte au build, pas au runtime) :
```
sudo docker compose up -d --build storefront
```
-- verifier que `storefront/pages/_app.js` utilise
-`process.env.NEXT_PUBLIC_MEDUSA_BACKEND_URL` (pas `localhost` en dur).
+
+4) Les CORS sont corrects — `STORE_CORS` doit lister l'origine du storefront.
+ Apres modification, recreer le conteneur (pas juste restart) :
+```
+sudo docker compose up -d backend
+```
+
+5) Le DNS LAN pointe vers **araucaria** (Caddy), pas vers huitral :
+```
+dig +short lsb.arauco.online
+dig +short api-lsb.arauco.online
+```
+ Les deux doivent retourner l'IP d'araucaria. Si ca retourne l'IP de
+ huitral, les navigateurs LAN contournent Caddy → `CONNECTION_REFUSED`
+ sur le port 443. Corriger dans `/etc/dnsmasq.d/lsb.conf` sur araucaria.
### 7.3 Admin Medusa (login qui boucle)
@@ -313,8 +345,9 @@ Objectif : autoriser le navigateur a appeler l'API depuis le storefront et l'adm
1) Verifier `.env` :
```
-ADMIN_CORS=http://<IP_DU_SERVEUR>:9000
-STORE_CORS=http://<IP_DU_SERVEUR>:8000
+NEXT_PUBLIC_MEDUSA_BACKEND_URL=https://api-lsb.arauco.online
+ADMIN_CORS=https://api-lsb.arauco.online,https://lsb.arauco.online,http://api-lsb.huitral.ruka.lan,http://lsb.huitral.ruka.lan
+STORE_CORS=https://lsb.arauco.online,http://lsb.huitral.ruka.lan
```
2) Rebuild backend pour appliquer les variables :
@@ -324,7 +357,7 @@ sudo docker compose up -d --build backend
3) Test CORS (storefront) :
```
-curl -i -H "Origin: http://<IP_DU_SERVEUR>:8000" http://<IP_DU_SERVEUR>:9000/store/products
+curl -i -H "Origin: https://lsb.arauco.online" https://api-lsb.arauco.online/store/products
```
### 7.5 Admin en HTTP (procedure NODE_ENV)
@@ -373,11 +406,16 @@ sudo docker compose build --no-cache backend
sudo docker compose up -d backend
```
-## 8. Mise en production (reverse proxy, serveur Linux)
+## 8. Mise en production (reverse proxy via Caddy sur araucaria)
+
+Le reverse proxy est gere par **Caddy** sur `araucaria` (pas sur huitral).
+Caddy gere automatiquement les certificats HTTPS via Let's Encrypt.
+
+Configuration dans `/etc/caddy/Caddyfile` sur araucaria :
+- `lsb.arauco.online` → huitral:8000 (storefront)
+- `api-lsb.arauco.online` → huitral:9000 (backend)
-Pour exposer en HTTP/HTTPS, utiliser Apache ou Nginx. Exemple Apache :
-- `apache-vhost.conf` dans le repo
-- activer `proxy` et `proxy_http`
+Voir `INSTALLATION.md` section 5 pour le detail.
## 9. Sauvegarde et restauration (serveur Linux)
@@ -818,50 +856,38 @@ Alternatives :
- `curl -v ...`
- DevTools navigateur (onglet Network).
-#### 12.1.5 Apache / Reverse proxy
+#### 12.1.5 Caddy / Reverse proxy (sur araucaria)
-**Statut Apache**
+**Statut Caddy**
```
-sudo systemctl status apache2
+sudo systemctl status caddy
```
-Alternatives :
-- `sudo service apache2 status`
-**Logs Apache**
+**Logs Caddy**
```
-sudo journalctl -u apache2 -f
-sudo tail -f /var/log/apache2/error.log
-sudo tail -f /var/log/apache2/access.log
+sudo journalctl -u caddy -f
+sudo journalctl -u caddy -n 200 --no-pager
```
- `-f` : suivi temps reel.
-Alternatives :
-- `journalctl -u apache2 -n 200 --no-pager`
-**Modules proxy**
+**Editer le Caddyfile**
```
-sudo a2enmod proxy
-sudo a2enmod proxy_http
+sudo nano /etc/caddy/Caddyfile
```
-- active les modules de reverse proxy.
-Alternatives :
-- `a2enmod headers`
-- `a2enmod rewrite`
-**Reload Apache**
+**Valider la config**
```
-sudo systemctl reload apache2
+caddy validate --config /etc/caddy/Caddyfile
```
-- recharge la config sans couper les connexions actives.
-Alternatives :
-- `sudo service apache2 restart`
-**Activer un vhost**
+**Reload Caddy**
```
-sudo a2ensite lucien.conf
-sudo apache2ctl configtest
-sudo service apache2 restart
+sudo systemctl reload caddy
```
-- `configtest` : verifie la syntaxe avant redemarrage.
+- recharge la config sans couper les connexions actives.
+Alternatives :
+- `sudo systemctl restart caddy`
+- `caddy reload --config /etc/caddy/Caddyfile`
#### 12.1.6 Systemd / Logs systeme (journalctl)
diff --git a/INSTALLATION.md b/INSTALLATION.md
index 53c8215..a0ac486 100644
--- a/INSTALLATION.md
+++ b/INSTALLATION.md
@@ -1,13 +1,13 @@
# Guide d'Installation Complet - Lucien-sens-bon
-Ce guide détaille comment installer votre boutique MedusaJS (Backend) + Next.js (Frontend) sur votre serveur "huitral" avec Docker et Apache.
+Ce guide détaille comment installer votre boutique MedusaJS (Backend) + Next.js (Frontend) sur votre serveur "huitral" avec Docker, et l'exposer via Caddy (reverse proxy sur araucaria).
## 1. Pré-requis
Assurez-vous d'avoir :
-- **Docker** et **Docker Compose** installés.
+- **Docker** et **Docker Compose** installés sur `huitral`.
- Une base de données **PostgreSQL** accessible (version 12+ recommandée).
-- **Apache** installé sur la machine hôte.
+- **Caddy** installé sur `araucaria` (reverse proxy + HTTPS automatique).
## 1.1 Nomenclature DNS (ruka.lan)
@@ -42,16 +42,20 @@ IP_DE_HUITRAL www.lsb.huitral.ruka.lan
IP_DE_HUITRAL api.lsb.huitral.ruka.lan
```
-**Cas 3 — DNS public**
-Créez des enregistrements A (et AAAA si IPv6) vers l'IP publique :
-- `www.lucien-sens-bon.com` → `IP_PUBLIQUE`
-- `api.lucien-sens-bon.com` → `IP_PUBLIQUE`
+**Cas 3 — DNS public (arauco.online)**
+Le DynDNS sync `*`, `@` et `git` pour `arauco.online`. Le wildcard `*` couvre tous
+les sous-domaines, donc `lsb.arauco.online` et `api-lsb.arauco.online` résolvent
+automatiquement vers l'IP publique. Pas besoin d'ajouter d'enregistrements.
+
+URLs publiques utilisées :
+- `https://lsb.arauco.online` → storefront
+- `https://api-lsb.arauco.online` → API Medusa
**Bonnes pratiques**
-- Utilisez les mêmes noms partout (DNS, Apache, variables d'environnement).
-- Évitez les ports dans les URLs publiques (Apache s'en charge).
+- Utilisez les mêmes noms partout (DNS, Caddy, variables d'environnement).
+- Évitez les ports dans les URLs publiques (Caddy s'en charge).
- Quand vous basculez en DNS public, mettez à jour `NEXT_PUBLIC_MEDUSA_BACKEND_URL`,
- `ADMIN_CORS` et `STORE_CORS` dans `.env`, puis redémarrez les conteneurs.
+ `ADMIN_CORS` et `STORE_CORS` dans `.env`, puis rebuild le storefront.
### 1.3 DNS interne avec dnsmasq (araucaria)
@@ -62,12 +66,26 @@ sudo nano /etc/dnsmasq.d/lsb.conf
Contenu recommandé :
```
-# Lucien Sens Bon - ruka.lan
-address=/www.lsb.huitral.ruka.lan/IP_DE_HUITRAL
-address=/api.lsb.huitral.ruka.lan/IP_DE_HUITRAL
-address=/admin.lsb.huitral.ruka.lan/IP_DE_HUITRAL
+# Lucien Sens Bon - domaines publics
+# Doivent pointer vers araucaria (Caddy) et non vers huitral directement,
+# sinon les clients LAN contournent Caddy et tombent sur un port sans HTTPS.
+address=/lsb.arauco.online/IP_DE_ARAUCARIA
+address=/api-lsb.arauco.online/IP_DE_ARAUCARIA
+
+# Lucien Sens Bon - domaines internes ruka.lan
+# Pointent aussi vers araucaria (Caddy gere le proxy HTTP pour ces domaines).
+address=/lsb.huitral.ruka.lan/IP_DE_ARAUCARIA
+address=/api-lsb.huitral.ruka.lan/IP_DE_ARAUCARIA
```
+Remplacez `IP_DE_ARAUCARIA` par l'IP LAN d'araucaria (ex: `192.168.99.50`).
+
+> **Important** : ne pas pointer les domaines `arauco.online` vers huitral
+> directement. Depuis l'extérieur, le DynDNS résout vers l'IP publique qui
+> arrive sur araucaria (Caddy). Depuis le LAN, dnsmasq doit aussi envoyer
+> vers araucaria, sinon les navigateurs se connectent à huitral:443 où rien
+> n'écoute → `CONNECTION_REFUSED`.
+
Rechargez dnsmasq :
```bash
sudo systemctl restart dnsmasq
@@ -76,8 +94,10 @@ sudo systemctl status dnsmasq --no-pager
Tests rapides depuis un client :
```bash
-dig +short www.lsb.huitral.ruka.lan
-dig +short api.lsb.huitral.ruka.lan
+dig +short lsb.arauco.online # doit retourner IP_DE_ARAUCARIA
+dig +short api-lsb.arauco.online # doit retourner IP_DE_ARAUCARIA
+dig +short lsb.huitral.ruka.lan # doit retourner IP_DE_ARAUCARIA
+dig +short api-lsb.huitral.ruka.lan # doit retourner IP_DE_ARAUCARIA
```
### 1.4 Procédure complète DNS (Windows + WSL)
@@ -148,9 +168,9 @@ dig +short www.lsb.huitral.ruka.lan
Exemple de valeurs utilisées dans ce projet (PostgreSQL sur `npagnun`) :
```ini
DATABASE_URL=postgres://luciensbdb:VOTRE_MOT_DE_PASSE_DB@192.168.99.35:5432/sens_bon_db
- NEXT_PUBLIC_MEDUSA_BACKEND_URL=http://api.lucien-sens-bon.com
- ADMIN_CORS=http://api.lucien-sens-bon.com
- STORE_CORS=http://lucien-sens-bon.com
+ NEXT_PUBLIC_MEDUSA_BACKEND_URL=https://api-lsb.arauco.online
+ ADMIN_CORS=https://api-lsb.arauco.online,https://lsb.arauco.online,http://api-lsb.huitral.ruka.lan,http://lsb.huitral.ruka.lan
+ STORE_CORS=https://lsb.arauco.online,http://lsb.huitral.ruka.lan
```
Édition avec `vim` :
@@ -244,59 +264,69 @@ Une fois les conteneurs démarrés, vous devez initialiser la base de données M
```
*(Remplacez l'email et le mot de passe par les vôtres).*
-## 5. Configuration Apache (Reverse Proxy)
+## 5. Configuration Caddy (Reverse Proxy sur araucaria)
-Objectif : exposer proprement le site et l'API en HTTP/HTTPS via Apache, sans exposer les ports 8000/9000 aux utilisateurs.
+Objectif : exposer proprement le site et l'API en HTTPS via Caddy sur `araucaria`,
+sans exposer les ports 8000/9000 aux utilisateurs.
-### 5.1 Créer le vhost Apache
-1. **Copiez la configuration fournie** :
- ```bash
- sudo cp apache-vhost.conf /etc/apache2/sites-available/lucien.conf
- ```
- *Le fichier définit 2 vhosts :*
- - `www.lsb.huitral.ruka.lan` → storefront (port 8000)
- - `api.lsb.huitral.ruka.lan` → backend Medusa (port 9000)
+Architecture :
+```
+Internet → araucaria (Caddy, HTTPS) → huitral (Docker containers)
+LAN → araucaria (Caddy, HTTP) → huitral (Docker containers)
+```
-2. **Vérifiez/ajustez les ServerName** selon vos DNS internes/publics.
- Si vous n'avez pas encore de DNS, ajoutez temporairement dans `/etc/hosts` :
- ```
- 127.0.0.1 www.lsb.huitral.ruka.lan
- 127.0.0.1 api.lsb.huitral.ruka.lan
- ```
+### 5.1 Éditer le Caddyfile sur araucaria
-### 5.2 Activer les modules nécessaires
-```bash
-sudo a2enmod proxy
-sudo a2enmod proxy_http
-```
-*(optionnel mais recommandé si vous ajoutez du HTTPS plus tard : `headers`, `rewrite`)*
-```bash
-sudo a2enmod headers
-sudo a2enmod rewrite
+Sur `araucaria`, éditez `/etc/caddy/Caddyfile` et ajoutez :
+
+```caddyfile
+# Lucien-sens-bon — acces public (HTTPS automatique)
+lsb.arauco.online {
+ reverse_proxy IP_DE_HUITRAL:8000
+}
+
+api-lsb.arauco.online {
+ reverse_proxy IP_DE_HUITRAL:9000
+}
+
+# Lucien-sens-bon — acces LAN (HTTP, pas de certificat)
+http://lsb.huitral.ruka.lan {
+ reverse_proxy IP_DE_HUITRAL:8000
+}
+
+http://api-lsb.huitral.ruka.lan {
+ reverse_proxy IP_DE_HUITRAL:9000
+}
```
-### 5.3 Activer le site et redémarrer Apache
+Remplacez `IP_DE_HUITRAL` par l'IP LAN de huitral (ex: `192.168.99.22`).
+
+### 5.2 Recharger Caddy
+
```bash
-sudo a2ensite lucien.conf
-sudo apache2ctl configtest
-sudo service apache2 restart
+sudo systemctl reload caddy
+sudo systemctl status caddy
```
-### 5.4 Bénéfices de ce reverse proxy
-- **URL propres** : accès en `http://www...` et `http://api...` sans ports.
-- **Centralisation HTTPS** : un seul endroit pour gérer les certificats (Certbot).
-- **Sécurité** : vous pouvez restreindre l'accès direct aux ports 8000/9000.
-- **Logs clairs** : logs séparés pour storefront et API.
+### 5.3 Bénéfices de ce reverse proxy
+- **HTTPS automatique** : Caddy obtient et renouvelle les certificats Let's Encrypt.
+- **URL propres** : accès en `https://lsb...` et `https://api-lsb...` sans ports.
+- **Double accès** : public via `arauco.online`, local via `ruka.lan`.
+- **Sécurité** : les ports 8000/9000 ne sont pas exposés directement.
+
+### 5.4 Vérification Caddy
-### 5.5 Option HTTPS (recommandé en production)
```bash
-sudo certbot --apache -d www.lsb.huitral.ruka.lan -d api.lsb.huitral.ruka.lan
+# Sur araucaria
+sudo systemctl status caddy
+curl -I https://lsb.arauco.online
+curl -I https://api-lsb.arauco.online/store/products
```
## 6. Vérification
-- **Storefront** : Accédez à `http://lucien-sens-bon.com` (ou votre domaine). Vous devriez voir la page d'accueil.
-- **Admin** : Accédez à `http://api.lucien-sens-bon.com/app` (le dashboard admin est servi par le backend). Connectez-vous avec l'utilisateur créé à l'étape 4.
+- **Storefront** : Accédez à `https://lsb.arauco.online` (ou `http://lsb.huitral.ruka.lan` en local). Vous devriez voir la page d'accueil.
+- **Admin** : Accédez à `https://api-lsb.arauco.online/app` (le dashboard admin est servi par le backend). Connectez-vous avec l'utilisateur créé à l'étape 4.
## 7. Dépôt Git (Chillka) et déploiement sur Huitral
diff --git a/app-management.md b/app-management.md
index 8fcb3db..26ca251 100644
--- a/app-management.md
+++ b/app-management.md
@@ -1,7 +1,7 @@
# App management - Lucien-sens-bon
Ce document explique comment diagnostiquer les conteneurs, la base de donnees
-et le reverse proxy (Apache).
+et le reverse proxy (Caddy sur araucaria).
## 1) Diagnostic Docker
@@ -115,19 +115,29 @@ curl -v http://localhost:9000/store/products
### C.1) Test CORS (depuis le serveur)
+Via le domaine public :
+```
+curl -i -H "Origin: https://lsb.arauco.online" https://api-lsb.arauco.online/store/products
+```
+
+Via le LAN :
+```
+curl -i -H "Origin: http://lsb.huitral.ruka.lan" http://api-lsb.huitral.ruka.lan/store/products
+```
+
+Via IP directe (sans reverse proxy) :
```
curl -i -H "Origin: http://192.168.99.22:8000" http://192.168.99.22:9000/store/products
```
- `-i` : affiche les en-tetes HTTP de la reponse (utile pour CORS).
- `-H "Origin: ..."` : simule l'origine du navigateur (storefront).
-- `http://192.168.99.22:9000/store/products` : endpoint backend teste.
-- Attendu : `Access-Control-Allow-Origin: http://192.168.99.22:8000`.
+- Attendu : `Access-Control-Allow-Origin` avec l'origine envoyee.
Retour attendu (exemple) :
```
HTTP/1.1 200 OK
-Access-Control-Allow-Origin: http://192.168.99.22:8000
+Access-Control-Allow-Origin: https://lsb.arauco.online
Vary: Origin
Access-Control-Allow-Credentials: true
Content-Type: application/json; charset=utf-8
@@ -326,7 +336,7 @@ curl -v http://localhost:9000/store/products
Verifier `NEXT_PUBLIC_MEDUSA_BACKEND_URL` dans `.env` :
```
-NEXT_PUBLIC_MEDUSA_BACKEND_URL=http://api.lsb.huitral.ruka.lan
+NEXT_PUBLIC_MEDUSA_BACKEND_URL=https://api-lsb.arauco.online
```
Puis reconstruire le storefront :
@@ -334,56 +344,83 @@ Puis reconstruire le storefront :
sudo docker compose up -d --build storefront
```
-Si on travaille en local (pas via Apache), utiliser l'URL directe :
+Si on travaille en local (pas via Caddy), utiliser l'URL directe :
```
NEXT_PUBLIC_MEDUSA_BACKEND_URL=http://<IP_DU_SERVEUR>:9000
```
-## 4) Apache / Reverse proxy
+## 4) Caddy / Reverse proxy (sur araucaria)
+
+Le reverse proxy est gere par Caddy sur `araucaria`, pas sur `huitral`.
-Verifier les services Apache :
+Verifier le service Caddy (sur araucaria) :
```
-sudo systemctl status apache2
+sudo systemctl status caddy
```
-Logs Apache :
+Logs Caddy :
```
-sudo journalctl -u apache2 -f
-sudo tail -f /var/log/apache2/error.log
-sudo tail -f /var/log/apache2/access.log
+sudo journalctl -u caddy -f
+sudo journalctl -u caddy -n 200 --no-pager
```
-Modules proxy :
+Editer le Caddyfile :
```
-sudo a2enmod proxy
-sudo a2enmod proxy_http
+sudo nano /etc/caddy/Caddyfile
```
-Reload Apache :
+Valider et recharger :
```
-sudo systemctl reload apache2
+caddy validate --config /etc/caddy/Caddyfile
+sudo systemctl reload caddy
```
-Documentation Apache reverse proxy :
-https://httpd.apache.org/docs/2.4/howto/reverse_proxy.html
+Documentation Caddy :
+https://caddyserver.com/docs/caddyfile/directives/reverse_proxy
## 5) Ports a verifier
-- `8000` : storefront
-- `9000` : backend
+- `8000` : storefront (huitral)
+- `9000` : backend (huitral)
- `5432` : PostgreSQL
- `6379` : Redis
+- `80/443` : Caddy (araucaria)
-Verifier l'ouverture locale :
+Verifier l'ouverture sur huitral :
```
ss -lntp | egrep '8000|9000|5432|6379'
```
+Verifier Caddy sur araucaria :
+```
+ss -lntp | grep caddy
+```
+
Verifier le firewall (UFW) :
```
sudo ufw status
```
+## 5.1) DNS LAN (piege courant)
+
+Si le site est accessible depuis l'exterieur mais pas depuis le LAN,
+verifier la resolution DNS :
+```
+dig +short lsb.arauco.online
+dig +short api-lsb.arauco.online
+```
+
+Les deux doivent retourner l'IP d'**araucaria** (ex: `192.168.99.50`),
+pas celle de huitral. Si dnsmasq renvoie l'IP de huitral, les navigateurs
+se connectent directement a huitral:443 ou rien n'ecoute → `CONNECTION_REFUSED`.
+
+Corriger dans `/etc/dnsmasq.d/lsb.conf` sur araucaria :
+```
+address=/lsb.arauco.online/192.168.99.50
+address=/api-lsb.arauco.online/192.168.99.50
+```
+Puis `sudo systemctl restart dnsmasq`.
+
## 6) Git - Remise en ordre apres modifications locales
Cette section documente les commandes utilisees pour remettre la branche locale
diff --git a/backend/data/products-import.csv b/backend/data/products-import.csv
index 29c61c8..5321a92 100644
--- a/backend/data/products-import.csv
+++ b/backend/data/products-import.csv
@@ -1,2 +1,11 @@
-external_id,title,handle,description,thumbnail,option_title,option_value,variant_title,variant_sku,price_amount,currency_code,inventory_quantity,manage_inventory
-prod-001,Savon Lavande,savon-lavande,"Savon artisanal a la lavande.",https://via.placeholder.com/600x600.png?text=Savon+Lavande,Taille,100g,100g,SKU-SAV-100,650,eur,100,true
+external_id,title,handle,description,thumbnail,option_title,option_value,variant_title,variant_sku,price_amount,currency_code,inventory_quantity,manage_inventory,volume,type_meche,parfum,couleur,type_cire
+prod-001,Bougie Lavande Classique,bougie-lavande-classique,"Bougie artisanale a la lavande, cire de soja naturelle.",,Taille,200ml,200ml,SKU-BOU-LAV-200,1200,eur,50,true,200ml,coton,lavande,blanche,soja
+prod-002,Bougie Vanille Boisee,bougie-vanille-boisee,"Notes chaudes de vanille et bois de santal.",,Taille,150ml,150ml,SKU-BOU-VAN-150,950,eur,40,true,150ml,bois,vanille,creme,soja
+prod-003,Bougie Fleur d'Oranger,bougie-fleur-oranger,"Parfum delicat de fleur d'oranger mediterraneenne.",,Taille,300ml,300ml,SKU-BOU-FLO-300,1800,eur,30,true,300ml,coton,fleur d'oranger,orange,colza
+prod-004,Bougie Cedre & Mousse,bougie-cedre-mousse,"Ambiance forestiere avec des notes de cedre et de mousse.",,Taille,200ml,200ml,SKU-BOU-CED-200,1400,eur,25,true,200ml,bois,cedre et mousse,verte,soja
+prod-005,Bougie Cannelle Epices,bougie-cannelle-epices,"Melange epice de cannelle, girofle et muscade.",,Taille,150ml,150ml,SKU-BOU-CAN-150,1050,eur,35,true,150ml,coton,cannelle epices,rouge,abeille
+prod-006,Bougie Rose Ancienne,bougie-rose-ancienne,"Senteur classique de rose de Grasse.",,Taille,200ml,200ml,SKU-BOU-ROS-200,1500,eur,20,true,200ml,coton,rose,rose,soja
+prod-007,Bougie Ambre Oriental,bougie-ambre-oriental,"Notes profondes d'ambre, oud et resine.",,Taille,500ml,500ml,SKU-BOU-AMB-500,2800,eur,15,true,500ml,bois,ambre oriental,doree,colza
+prod-008,Bougie Citron Basilic,bougie-citron-basilic,"Fraicheur mediterraneenne, citron et basilic.",,Taille,150ml,150ml,SKU-BOU-CIT-150,900,eur,45,true,150ml,coton,citron basilic,jaune,soja
+prod-009,Bougie Figue Sauvage,bougie-figue-sauvage,"Douceur sucree de la figue de Provence.",,Taille,300ml,300ml,SKU-BOU-FIG-300,1700,eur,20,true,300ml,bois,figue sauvage,violette,colza
+prod-010,Bougie Bois de Oud,bougie-bois-de-oud,"Oud rare et precieux, intensite boisee.",,Taille,200ml,200ml,SKU-BOU-OUD-200,2200,eur,10,true,200ml,bois,oud,noire,abeille
diff --git a/backend/scripts/import-products.js b/backend/scripts/import-products.js
index 04b24aa..bd0db24 100644
--- a/backend/scripts/import-products.js
+++ b/backend/scripts/import-products.js
@@ -75,6 +75,14 @@ class CsvProductImporter {
return ["true", "1", "yes", "y"].includes(normalized);
};
+ const metadata = {};
+ const metadataFields = ["volume", "type_meche", "parfum", "couleur", "type_cire"];
+ for (const field of metadataFields) {
+ if (row[field] && row[field].trim()) {
+ metadata[field] = row[field].trim();
+ }
+ }
+
return {
external_id: row.external_id || "",
title: row.title || "",
@@ -89,6 +97,7 @@ class CsvProductImporter {
currency_code: row.currency_code || this.defaultCurrency,
inventory_quantity: Number.parseInt(row.inventory_quantity, 10) || 0,
manage_inventory: toBool(row.manage_inventory, true),
+ metadata,
};
}
@@ -129,6 +138,7 @@ class CsvProductImporter {
handle: row.handle,
description: row.description,
thumbnail: row.thumbnail || undefined,
+ metadata: Object.keys(row.metadata).length > 0 ? row.metadata : undefined,
options: [{ title: row.option_title }],
variants: [variant],
});
diff --git a/env-example b/env-example
index c8e63b7..64d329a 100644
--- a/env-example
+++ b/env-example
@@ -14,18 +14,22 @@ COOKIE_SECRET=supersecret
# --------------------------------------------------------
# CONFIGURATION DES URLS
-# Pour la production, mettez vos vrais domaines (ex: https://api.monsite.com)
+# Production : domaines publics via Caddy (araucaria)
+# Local : domaines internes ruka.lan
# --------------------------------------------------------
-# URL du Backend (API) accessible par le navigateur
-NEXT_PUBLIC_MEDUSA_BACKEND_URL=http://api.lsb.huitral.ruka.lan
+# URL du Backend (API) accessible par le navigateur (une seule URL, injectée au build)
+# Production :
+NEXT_PUBLIC_MEDUSA_BACKEND_URL=https://api-lsb.arauco.online
+# Local uniquement :
+# NEXT_PUBLIC_MEDUSA_BACKEND_URL=http://api-lsb.huitral.ruka.lan
# CORS Admin : Quels domaines peuvent accéder à l'admin ?
-ADMIN_CORS=http://api.lsb.huitral.ruka.lan
+# Lister toutes les origines (public + local)
+ADMIN_CORS=https://api-lsb.arauco.online,https://lsb.arauco.online,http://api-lsb.huitral.ruka.lan,http://lsb.huitral.ruka.lan
# CORS Store : Quels domaines (le frontend) peuvent accéder à l'API ?
-# En production, ce sera https://monsite.com
-STORE_CORS=http://www.lsb.huitral.ruka.lan
+STORE_CORS=https://lsb.arauco.online,http://lsb.huitral.ruka.lan
# --------------------------------------------------------
# PAIEMENTS (Optionnel)
diff --git a/helper-cmd.md b/helper-cmd.md
index 7edef87..9b87ea2 100644
--- a/helper-cmd.md
+++ b/helper-cmd.md
@@ -282,9 +282,13 @@ curl http://localhost:8000
- `curl -I http://localhost:8000`
### 4.3 Test CORS
-**Commande**
+**Commande (public)**
+```
+curl -i -H "Origin: https://lsb.arauco.online" https://api-lsb.arauco.online/store/products
+```
+**Commande (LAN)**
```
-curl -i -H "Origin: http://<IP>:8000" http://<IP>:9000/store/products
+curl -i -H "Origin: http://lsb.huitral.ruka.lan" http://api-lsb.huitral.ruka.lan/store/products
```
**Paramètres**
- `-i` : inclut les en-têtes.
@@ -294,62 +298,50 @@ curl -i -H "Origin: http://<IP>:8000" http://<IP>:9000/store/products
- `curl -v ...`
- DevTools navigateur (onglet Network).
-## 5. Apache / Reverse proxy
+## 5. Caddy / Reverse proxy (sur araucaria)
-### 5.1 Statut Apache
+Le reverse proxy est géré par Caddy sur `araucaria`, pas sur `huitral`.
+
+### 5.1 Statut Caddy
**Commande**
```
-sudo systemctl status apache2
+sudo systemctl status caddy
```
-**Alternatives**
-- `sudo service apache2 status`
-### 5.2 Logs Apache
+### 5.2 Logs Caddy
**Commandes**
```
-sudo journalctl -u apache2 -f
-sudo tail -f /var/log/apache2/error.log
-sudo tail -f /var/log/apache2/access.log
+sudo journalctl -u caddy -f
+sudo journalctl -u caddy -n 200 --no-pager
```
**Paramètres**
- `-f` : suivi temps réel.
-**Alternatives**
-- `journalctl -u apache2 -n 200 --no-pager`
+### 5.3 Éditer le Caddyfile
+**Commande**
+```
+sudo nano /etc/caddy/Caddyfile
+```
-### 5.3 Modules proxy
-**Commandes**
+### 5.4 Valider la config
+**Commande**
```
-sudo a2enmod proxy
-sudo a2enmod proxy_http
+caddy validate --config /etc/caddy/Caddyfile
```
**Explication**
-- active les modules de reverse proxy.
+- vérifie la syntaxe avant rechargement.
-**Alternatives**
-- `a2enmod headers`
-- `a2enmod rewrite`
-
-### 5.4 Reload Apache
+### 5.5 Reload Caddy
**Commande**
```
-sudo systemctl reload apache2
+sudo systemctl reload caddy
```
**Explication**
- recharge la config sans couper les connexions actives.
**Alternatives**
-- `sudo service apache2 restart`
-
-### 5.5 Activer un vhost
-**Commandes**
-```
-sudo a2ensite lucien.conf
-sudo apache2ctl configtest
-sudo service apache2 restart
-```
-**Paramètres**
-- `configtest` : vérifie la syntaxe avant redémarrage.
+- `sudo systemctl restart caddy`
+- `caddy reload --config /etc/caddy/Caddyfile`
## 6. DNS / Résolution (Windows + Linux)
diff --git a/storefront/pages/index.js b/storefront/pages/index.js
index dda2a6d..43ebeb7 100644
--- a/storefront/pages/index.js
+++ b/storefront/pages/index.js
@@ -4,6 +4,31 @@ import { medusaClient } from "../lib/medusa-client"
import { ensureCart } from "../lib/storefront"
import { formatAmount } from "../lib/format"
+const METADATA_LABELS = {
+ volume: "Volume",
+ type_meche: "Mèche",
+ parfum: "Parfum",
+ couleur: "Couleur",
+ type_cire: "Cire",
+}
+
+function ProductAttributes({ metadata }) {
+ if (!metadata) return null
+ const entries = Object.entries(METADATA_LABELS)
+ .filter(([key]) => metadata[key])
+ .map(([key, label]) => ({ label, value: metadata[key] }))
+ if (entries.length === 0) return null
+ return (
+ <ul style={{ listStyle: "none", padding: 0, margin: "0.5rem 0", fontSize: "0.85rem", color: "#555" }}>
+ {entries.map(({ label, value }) => (
+ <li key={label}>
+ <strong>{label}:</strong> {value}
+ </li>
+ ))}
+ </ul>
+ )
+}
+
export default function Home() {
const { products, isLoading } = useProducts()
const [status, setStatus] = useState("")
@@ -44,6 +69,7 @@ export default function Home() {
<div key={product.id} style={{ border: "1px solid #ccc", padding: "1rem", borderRadius: "8px" }}>
<h3>{product.title}</h3>
<p>{product.description}</p>
+ <ProductAttributes metadata={product.metadata} />
<p style={{ fontWeight: 600 }}>
{formatAmount(
product?.variants?.[0]?.prices?.[0]?.amount,