diff options
| -rw-r--r-- | DOC_IMPORT_PRODUITS.md | 193 | ||||
| -rw-r--r-- | DOC_TECHNIQUE.md | 569 | ||||
| -rw-r--r-- | POSTGRES_DIAG.md | 195 | ||||
| -rw-r--r-- | backend/data/products-import.csv | 2 | ||||
| -rw-r--r-- | backend/package.json | 2 | ||||
| -rw-r--r-- | backend/scripts/import-products.js | 250 | ||||
| -rw-r--r-- | helper-cmd.md | 616 |
7 files changed, 1788 insertions, 39 deletions
diff --git a/DOC_IMPORT_PRODUITS.md b/DOC_IMPORT_PRODUITS.md new file mode 100644 index 0000000..b41cba8 --- /dev/null +++ b/DOC_IMPORT_PRODUITS.md @@ -0,0 +1,193 @@ +# Import CSV Produits (Medusa)
+
+## FR - Objectif
+Importer des produits depuis un CSV dans Medusa en mode upsert (creation ou mise a jour) sur le champ `external_id`.
+
+## FR - Prerequis
+- Backend Medusa operationnel
+- Dependances installees (`npm install` dans `backend/`)
+- Fichier CSV present dans `backend/data/products-import.csv` (ou un autre chemin)
+
+## FR - Commande rapide
+Depuis `backend/` :
+```
+npm run import:products
+```
+
+Options:
+```
+node scripts/import-products.js --file ./data/products-import.csv --report ./data/import-report.json
+node scripts/import-products.js --file ./data/products-import.csv --dry-run
+node scripts/import-products.js --file ./data/products-import.csv --currency eur
+```
+
+## FR - Schema CSV
+Colonnes minimales:
+- `external_id` (obligatoire, cle d'upsert)
+- `title` (obligatoire)
+- `handle` (optionnel, genere depuis title si absent)
+- `description` (optionnel)
+- `thumbnail` (optionnel)
+- `option_title` (optionnel, defaut: Taille)
+- `option_value` (optionnel, defaut: variant_title)
+- `variant_title` (optionnel, defaut: option_value)
+- `variant_sku` (optionnel)
+- `price_amount` (obligatoire, entier en centimes)
+- `currency_code` (optionnel, defaut: eur)
+- `inventory_quantity` (optionnel, defaut: 0)
+- `manage_inventory` (optionnel, true/false)
+
+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
+```
+
+## FR - Comportement
+- Un produit est trouve par `external_id`.
+- Si `external_id` existe: mise a jour du produit.
+- Si `external_id` n'existe pas: creation du produit.
+- Une ligne CSV = une variante. Regrouper plusieurs variantes avec le meme `external_id`.
+- Une seule option produit est supportee dans ce script (ex: Taille).
+
+## FR - Git flow (branche + push)
+Nom de branche suggere: `feature/import-csv-produits`
+
+Commandes type:
+```
+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 push -u chillka feature/import-csv-produits
+```
+
+Selon votre process:
+```
+git flow feature finish import-csv-produits
+```
+
+## FR - Troubleshoot git-flow
+**Erreur**: `Fatal: Working tree contains unstaged changes. Aborting.`
+
+Cause: git-flow exige un working tree propre.
+
+Actions:
+```
+git status
+git add -A
+git commit -m "WIP: prepare import CSV"
+git flow init -d
+```
+
+Alternative (mettre de cote):
+```
+git stash -u
+git flow init -d
+git stash pop
+```
+
+**Erreur**: `git: 'flow' is not a git command`
+
+Installe git-flow:
+```
+sudo apt update
+sudo apt install git-flow
+```
+
+---
+
+## DE - Ziel
+Produkte per CSV in Medusa importieren, mit Upsert per `external_id` (anlegen oder aktualisieren).
+
+## DE - Voraussetzungen
+- Medusa Backend laeuft
+- Abhaengigkeiten installiert (`npm install` in `backend/`)
+- CSV Datei in `backend/data/products-import.csv` (oder eigener Pfad)
+
+## DE - Schnellstart
+Aus `backend/`:
+```
+npm run import:products
+```
+
+Optionen:
+```
+node scripts/import-products.js --file ./data/products-import.csv --report ./data/import-report.json
+node scripts/import-products.js --file ./data/products-import.csv --dry-run
+node scripts/import-products.js --file ./data/products-import.csv --currency eur
+```
+
+## DE - CSV Schema
+Pflichtspalten:
+- `external_id` (Pflicht, Upsert-Schluessel)
+- `title` (Pflicht)
+- `handle` (optional, wird aus title erzeugt)
+- `description` (optional)
+- `thumbnail` (optional)
+- `option_title` (optional, Default: Taille)
+- `option_value` (optional, Default: variant_title)
+- `variant_title` (optional, Default: option_value)
+- `variant_sku` (optional)
+- `price_amount` (Pflicht, integer in Cent)
+- `currency_code` (optional, Default: eur)
+- `inventory_quantity` (optional, Default: 0)
+- `manage_inventory` (optional, true/false)
+
+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
+```
+
+## DE - Verhalten
+- Produkt wird per `external_id` gefunden.
+- Wenn `external_id` existiert: Produkt wird aktualisiert.
+- Wenn `external_id` nicht existiert: Produkt wird angelegt.
+- Eine CSV Zeile = eine Variante. Mehrere Varianten mit gleichem `external_id` gruppieren.
+- Nur eine Produktoption ist in diesem Script vorgesehen (z.B. Taille).
+
+## DE - Git flow (Branch + Push)
+Branch Vorschlag: `feature/import-csv-produits`
+
+Typische Befehle:
+```
+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 push -u chillka feature/import-csv-produits
+```
+
+Optional nach Prozess:
+```
+git flow feature finish import-csv-produits
+```
+
+## DE - Troubleshooting git-flow
+**Fehler**: `Fatal: Working tree contains unstaged changes. Aborting.`
+
+Ursache: git-flow braucht ein sauberes Working Tree.
+
+Schritte:
+```
+git status
+git add -A
+git commit -m "WIP: prepare import CSV"
+git flow init -d
+```
+
+Alternative (parken):
+```
+git stash -u
+git flow init -d
+git stash pop
+```
+
+**Fehler**: `git: 'flow' is not a git command`
+
+git-flow installieren:
+```
+sudo apt update
+sudo apt install git-flow
+```
diff --git a/DOC_TECHNIQUE.md b/DOC_TECHNIQUE.md index ffd108c..0c4b2f9 100644 --- a/DOC_TECHNIQUE.md +++ b/DOC_TECHNIQUE.md @@ -4,7 +4,7 @@ Ce document explique l'architecture, les technologies, la mise en place, les tes et la sauvegarde/restauration du magasin en ligne. Il est ecrit pour une personne
junior afin de pouvoir prendre en main le projet en autonomie.
-## 1) Vue d'ensemble
+## 1. Vue d'ensemble
Le projet est compose de :
- **Backend MedusaJS** : API ecommerce (produits, panier, commandes).
@@ -19,7 +19,7 @@ Ports principaux : - `9000` : backend (API + admin)
- `6379` : redis
-## 1.1) Redis (pourquoi et comment)
+### 1.1 Redis (pourquoi et comment)
Redis est une base cle-valeur en memoire, utilisee pour :
- **cache** : accelerer certaines lectures.
@@ -39,17 +39,17 @@ Ou le voir : - `backend/medusa-config.js` -> `eventBus` et `cacheService`.
- `docker-compose.yml` -> service `redis`.
-## 2) Technologies utilisees (liens utiles)
+## 2. Technologies utilisees (liens utiles)
-- MedusaJS : https://docs.medusajs.com/
-- Next.js : https://nextjs.org/docs
-- Docker : https://docs.docker.com/get-started/
-- 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
+- [MedusaJS](https://docs.medusajs.com/)
+- [Next.js](https://nextjs.org/docs)
+- [Docker](https://docs.docker.com/get-started/)
+- [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)
-## 3) Fichiers importants
+## 3. Fichiers importants
- `docker-compose.yml` : configuration des conteneurs.
- `backend/` : code et config Medusa.
@@ -57,7 +57,7 @@ Ou le voir : - `.env` : variables d'environnement (non versionne).
- `env-example` : modele de variables d'environnement.
-## 3.1) D'ou vient le code (YAML vs depot)
+### 3.1 D'ou vient le code (YAML vs depot)
Le fichier `docker-compose.yml` **ne contient pas le code** :
- il **decrit** comment lancer les conteneurs (services, ports, variables).
@@ -68,7 +68,7 @@ Flux reel : 2) `docker compose build` construit les images depuis les Dockerfile.
3) `docker compose up` lance les conteneurs avec les variables `.env`.
-## 3.2) Medusa (backend) - installation technique
+### 3.2 Medusa (backend) - installation technique
Etapes principales :
1) `backend/Dockerfile` copie `package.json`, installe les deps.
@@ -88,13 +88,13 @@ Briques logicielles principales : - **Redis** : cache + event bus.
- **MedusaJS** : API ecommerce (services, modules, plugins).
-## 3.3) Storefront (frontend) - fonctionnement
+### 3.3 Storefront (frontend) - fonctionnement
- Next.js compile le site au build (`npm run build`).
- La variable `NEXT_PUBLIC_MEDUSA_BACKEND_URL` est **injectee au build**.
- Le conteneur expose le site sur le port `8000`.
-## 3.4) Schema technique (ASCII)
+### 3.4 Schema technique (ASCII)
```
+----------------------+
@@ -119,7 +119,7 @@ Briques logicielles principales : +---------------+ +----------------+
```
-## 4) Installation rapide (serveur)
+## 4. Installation rapide (serveur Linux)
1. Copier la configuration :
```
@@ -141,7 +141,7 @@ COOKIE_SECRET=change_me docker compose up -d --build
```
-### 4.1) Exemple reel (ce que nous avons fait)
+### 4.1 Exemple reel (ce que nous avons fait)
Contexte : backend sur `192.168.99.22:9000`, storefront sur `192.168.99.22:8000`.
@@ -174,7 +174,13 @@ curl -v http://192.168.99.22:8000 sudo docker compose run --rm backend npm run seed
```
-## 5) Tests rapides
+5) Import CSV produits :
+```
+sudo docker compose run --rm backend npm run import:products
+```
+Doc: `DOC_IMPORT_PRODUITS.md`
+
+## 5. Tests rapides (serveur Linux)
Verifier que les conteneurs tournent :
```
@@ -197,7 +203,7 @@ docker compose logs -f backend docker compose logs -f storefront
```
-### 5.1) Logs systeme avec journalctl (systemd)
+### 5.1 Logs systeme avec journalctl (systemd)
Utiliser `journalctl` pour diagnostiquer les services systeme (Apache, dnsmasq, Docker).
@@ -242,7 +248,7 @@ sudo journalctl -n 50 --no-pager sudo journalctl -u dnsmasq -S "10 min ago" --no-pager
```
-### 5.2) Tests CORS (exemple utilise)
+### 5.2 Tests CORS (exemple utilise)
```
curl -i -H "Origin: http://192.168.99.22:8000" http://192.168.99.22:9000/store/products
@@ -250,7 +256,7 @@ curl -i -H "Origin: http://192.168.99.22:8000" http://192.168.99.22:9000/store/p - Confirme que `Access-Control-Allow-Origin` autorise le storefront.
-## 6) Ou se trouve la base de donnees ?
+## 6. Ou se trouve la base de donnees ?
Le backend lit la base de donnees via `DATABASE_URL` dans `.env`.
Le format est :
@@ -261,9 +267,9 @@ postgres://user:password@host:5432/nom_db Si PostgreSQL est externe au serveur, verifier l'ouverture du port `5432`
et les autorisations reseau (pg_hba.conf cote PostgreSQL).
-## 7) Debogage courant
+## 7. Debogage courant (serveur Linux)
-### Backend qui redemarre en boucle
+### 7.1 Backend qui redemarre en boucle
Ca arrive si :
- `DATABASE_URL` est incorrect
- les migrations ne sont pas faites
@@ -275,7 +281,7 @@ docker compose logs -f backend docker exec -it medusa-backend npm run seed
```
-### Storefront affiche "Chargement des produits..."
+### 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`
@@ -288,7 +294,7 @@ 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).
-### Admin Medusa (login qui boucle)
+### 7.3 Admin Medusa (login qui boucle)
Symptome : l'admin reste sur la page de login.
Cause frequente : cookies `Secure` bloques en HTTP si `NODE_ENV=production`.
@@ -301,7 +307,7 @@ Solution appliquee : sudo docker compose up -d --build backend
```
-### CORS admin/storefront (procedure)
+### 7.4 CORS admin/storefront (procedure)
Objectif : autoriser le navigateur a appeler l'API depuis le storefront et l'admin.
@@ -321,7 +327,7 @@ sudo docker compose up -d --build backend curl -i -H "Origin: http://<IP_DU_SERVEUR>:8000" http://<IP_DU_SERVEUR>:9000/store/products
```
-### Admin en HTTP (procedure NODE_ENV)
+### 7.5 Admin en HTTP (procedure NODE_ENV)
Objectif : eviter le blocage des cookies `Secure` en HTTP.
@@ -340,7 +346,7 @@ NODE_ENV=development sudo docker compose up -d --build backend
```
-### Patch Medusa (TypeORM update vide)
+### 7.6 Patch Medusa (TypeORM update vide)
Probleme :
- Erreur TypeORM `Empty criteria(s) are not allowed for the update method`.
@@ -367,13 +373,13 @@ sudo docker compose build --no-cache backend sudo docker compose up -d backend
```
-## 8) Mise en production (reverse proxy)
+## 8. Mise en production (reverse proxy, serveur Linux)
Pour exposer en HTTP/HTTPS, utiliser Apache ou Nginx. Exemple Apache :
- `apache-vhost.conf` dans le repo
- activer `proxy` et `proxy_http`
-## 9) Sauvegarde et restauration
+## 9. Sauvegarde et restauration (serveur Linux)
Objectif : pouvoir recuperer **tout le site** et **l'historique**.
Il faut sauvegarder :
@@ -387,7 +393,7 @@ Sur le serveur de DB : ```
pg_dump -Fc -U user nom_db > /backups/lucien-sens-bon.dump
```
-Doc officielle : https://www.postgresql.org/docs/current/app-pgdump.html
+Doc officielle : <https://www.postgresql.org/docs/current/app-pgdump.html>
### 9.2 Sauvegarde des uploads
Si le backend stocke des fichiers :
@@ -413,7 +419,7 @@ tar -czf /backups/lucien-sens-bon-config.tgz \ ```
pg_restore -U user -d nom_db /backups/lucien-sens-bon.dump
```
-Doc : https://www.postgresql.org/docs/current/app-pgrestore.html
+Doc : <https://www.postgresql.org/docs/current/app-pgrestore.html>
2) Restaurer les fichiers :
```
@@ -426,14 +432,14 @@ tar -xzf /backups/lucien-sens-bon-config.tgz -C / docker compose up -d --build
```
-## 10) Bonnes pratiques
+## 10. Bonnes pratiques
- Toujours versionner le code via Git (ne pas modifier uniquement sur serveur).
- Sauvegarder la DB quotidiennement.
- Garder un backup hors serveur (S3, autre machine).
- Tester les restaurations une fois par trimestre.
-## 11) Procedure Git (push + alignement serveur)
+## 11. Procedure Git (push + alignement serveur)
Objectif : pousser le code vers `chillka`, puis aligner `huitral` **sans perdre de changements**.
@@ -545,9 +551,9 @@ Representation locale d'une branche distante : - Quand on fait `git fetch`, Git met a jour `refs/remotes/origin/main`.
- Quand on fait `git merge origin/main`, on integre cette reference distante dans la branche locale `main`.
-### 11.5 Recuperer sur antel et nettoyer les fichiers .txt
+### 11.5 Recuperer sur antel et nettoyer les fichiers .txt (poste Windows/WSL)
-#### a) Recuperer les mises a jour depuis chillka
+#### 11.5.1 Recuperer les mises a jour depuis chillka
Sur antel :
```
cd /mnt/e/Dev/Web-Works/Lucien-sens-bon
@@ -571,7 +577,7 @@ Explication rapide : - `git commit` : sauvegarder les changements locaux.
- `git pull --rebase` : rejouer ces commits au-dessus de `origin/main` pour eviter un merge commit.
-#### b) Retirer des fichiers .txt deja stages
+#### 11.5.2 Retirer des fichiers .txt deja stages
Si des fichiers .txt ne doivent pas etre versionnes :
```
git restore --staged _fichier-avec-erreurs/*.txt
@@ -581,3 +587,492 @@ Explication rapide : - `git restore --staged` : retire les fichiers de l'index sans toucher le disque.
- `rm -f` : supprime les fichiers localement.
+## 12. Commandes et diagnostics (annexe)
+
+Cette annexe regroupe les commandes utilisees dans le projet, par theme, avec
+les objectifs, parametres importants et alternatives utiles.
+Les commandes sont separees entre **serveur Linux** et **poste Windows/WSL**.
+
+### 12.1 Serveur Linux
+
+#### 12.1.1 Docker / Docker Compose (services Medusa + Storefront + Redis)
+
+**Lancer les services**
+```
+docker compose up -d --build
+```
+- `docker compose` : plugin Compose integre (recommande).
+- `up` : cree et demarre les services.
+- `-d` : detache (retourne la main).
+- `--build` : reconstruit les images si necessaire.
+Alternatives :
+- `docker-compose up -d --build` (ancienne syntaxe).
+- `docker compose up` (sans `-d` : logs en direct).
+
+**Voir l'etat des conteneurs**
+```
+docker compose ps
+```
+- aucun : liste services, statuts, ports.
+Alternatives :
+- `docker ps` (tous les conteneurs).
+- `docker compose ps -a` (inclut les arretes).
+
+**Voir les logs**
+```
+docker compose logs -f
+docker compose logs -f backend
+docker compose logs -f storefront
+```
+- `-f` : suivi temps reel (equivalent `tail -f`).
+- `backend` / `storefront` : filtre par service.
+Alternatives :
+- `docker logs -f <container>`
+- `docker compose logs --tail=200 backend`
+
+**Redemarrer un service**
+```
+docker compose restart backend
+```
+- redemarre le service sans reconstruire l'image.
+Alternatives :
+- `docker compose up -d backend`
+- `docker compose up -d --build backend`
+
+**Rebuild force d'un service**
+```
+docker compose build --no-cache backend
+docker compose up -d --build backend
+```
+- `--no-cache` : force l'installation des deps + postinstall.
+- `--build` : rebuild puis redeploiement.
+Alternatives :
+- `docker compose build backend` (cache autorise).
+
+**Entrer dans un conteneur**
+```
+docker exec -it medusa-backend sh
+```
+- `exec` : execute une commande dans un conteneur.
+- `-it` : mode interactif + TTY.
+- `sh` : shell minimal.
+Alternatives :
+- `docker exec -it medusa-backend bash` (si `bash` present).
+- `docker compose exec backend sh`
+
+**Commande dans un conteneur temporaire**
+```
+docker compose run --rm backend <commande>
+```
+- `run` : conteneur ponctuel base sur le service.
+- `--rm` : supprime le conteneur a la fin.
+Alternatives :
+- `docker run --rm -it <image> <commande>`
+
+#### 12.1.2 PostgreSQL (connexion, diagnostic, sauvegarde)
+
+**Connexion via `DATABASE_URL`**
+```
+psql "$DATABASE_URL" -c "select 1;"
+```
+- `$DATABASE_URL` : `postgres://user:pass@host:5432/db`
+- `-c` : execute une requete et quitte.
+Alternatives :
+- `psql -h <host> -U <user> -d <db> -W`
+- `docker run --rm -it postgres:16-alpine psql "$DATABASE_URL" -c "select 1;"`
+
+**Test du port reseau PostgreSQL**
+```
+nc -vz <host_db> 5432
+```
+- `-v` : verbose.
+- `-z` : scan sans envoyer de donnees.
+Alternatives :
+- `telnet <host_db> 5432`
+- `bash -c ">/dev/tcp/<host_db>/5432"` (si bash)
+
+**Diagnostic hote (service / process)**
+```
+sudo systemctl status postgresql
+sudo service postgresql status
+ps aux | grep -E "postgres|postmaster"
+```
+- `systemctl` / `service` : verifie service systemd/sysv.
+- `ps + grep` : liste les processus.
+Alternatives :
+- `pgrep -a postgres`
+- `ss -lntp | grep 5432`
+
+**Localiser la configuration**
+```
+sudo -u postgres psql -c "SHOW config_file;"
+sudo -u postgres psql -c "SHOW hba_file;"
+sudo -u postgres psql -c "SHOW data_directory;"
+```
+- donne les chemins exacts des fichiers de config et des donnees.
+Alternatives (chemins typiques) :
+- `/etc/postgresql/*/main/postgresql.conf`
+- `/etc/postgresql/*/main/pg_hba.conf`
+- `/var/lib/pgsql/data/postgresql.conf`
+- `/var/lib/pgsql/data/pg_hba.conf`
+
+**Commandes `psql` utiles (dans psql)**
+```
+\du
+\l
+\c ma_base
+\dt
+SHOW port;
+SHOW listen_addresses;
+```
+- `\` : commandes internes psql.
+- `SHOW ...` : variables de configuration.
+Alternatives :
+- `SELECT current_user;`
+- `SELECT version();`
+
+**Sauvegarde et restauration**
+```
+pg_dump -Fc -U user nom_db > /backups/lucien-sens-bon.dump
+pg_restore -U user -d nom_db /backups/lucien-sens-bon.dump
+```
+- `-Fc` : format custom (compresse + restauration selective).
+- `-U` : utilisateur.
+Alternatives :
+- `pg_dump -U user nom_db > dump.sql`
+- `psql -U user -d nom_db < dump.sql`
+
+#### 12.1.3 Medusa / Node.js (backend)
+
+**Migrations Medusa**
+```
+docker compose run --rm backend npx medusa migrations run
+```
+- applique les migrations (creation des tables).
+- `npx` : execute la version locale de Medusa.
+Alternatives :
+- `docker exec -it medusa-backend npx medusa migrations run`
+
+**Seed de donnees**
+```
+docker compose run --rm backend npm run seed
+```
+- injecte des donnees demo si `backend/data/seed.json` existe.
+Alternatives :
+- `docker exec -it medusa-backend npm run seed`
+
+**Import CSV produits**
+```
+docker compose run --rm backend npm run import:products
+```
+- importe les produits depuis `backend/data/products-import.csv` via `external_id`.
+- doc: `DOC_IMPORT_PRODUITS.md`
+Alternatives :
+- `docker exec -it medusa-backend npm run import:products`
+
+**Creation utilisateur admin (Medusa)**
+```
+docker exec -it medusa-backend medusa user -e admin@lucien.com -p supersecret
+```
+- `-e` : email de l'admin.
+- `-p` : mot de passe.
+Alternatives :
+- `medusa user --help`
+
+**Test DB via Node (diagnostic)**
+```
+docker compose run --rm backend node -e "const { Client }=require('pg'); ... "
+```
+- `node -e` : execute un script JS en ligne.
+- `pg` : client PostgreSQL Node.
+Alternatives :
+- script JS temporaire dans le conteneur.
+- `psql` direct (plus simple si acces).
+
+#### 12.1.4 Storefront / Tests HTTP (curl)
+
+**Test de l'API Medusa**
+```
+curl http://localhost:9000/store/products
+```
+- URL endpoint public Medusa.
+Alternatives :
+- `curl -v ...`
+- `http :9000/store/products` (httpie)
+
+**Test du storefront**
+```
+curl http://localhost:8000
+```
+- verifie que le site repond.
+Alternatives :
+- `curl -I http://localhost:8000`
+
+**Test CORS**
+```
+curl -i -H "Origin: http://<IP>:8000" http://<IP>:9000/store/products
+```
+- `-i` : inclut les en-tetes.
+- `-H` : ajoute un header `Origin`.
+Alternatives :
+- `curl -v ...`
+- DevTools navigateur (onglet Network).
+
+#### 12.1.5 Apache / Reverse proxy
+
+**Statut Apache**
+```
+sudo systemctl status apache2
+```
+Alternatives :
+- `sudo service apache2 status`
+
+**Logs Apache**
+```
+sudo journalctl -u apache2 -f
+sudo tail -f /var/log/apache2/error.log
+sudo tail -f /var/log/apache2/access.log
+```
+- `-f` : suivi temps reel.
+Alternatives :
+- `journalctl -u apache2 -n 200 --no-pager`
+
+**Modules proxy**
+```
+sudo a2enmod proxy
+sudo a2enmod proxy_http
+```
+- active les modules de reverse proxy.
+Alternatives :
+- `a2enmod headers`
+- `a2enmod rewrite`
+
+**Reload Apache**
+```
+sudo systemctl reload apache2
+```
+- recharge la config sans couper les connexions actives.
+Alternatives :
+- `sudo service apache2 restart`
+
+**Activer un vhost**
+```
+sudo a2ensite lucien.conf
+sudo apache2ctl configtest
+sudo service apache2 restart
+```
+- `configtest` : verifie la syntaxe avant redemarrage.
+
+#### 12.1.6 Systemd / Logs systeme (journalctl)
+
+**Base**
+```
+sudo journalctl --disk-usage
+sudo journalctl --list-boots
+sudo journalctl -u <service> -n 50 --no-pager
+sudo journalctl -u <service> -f
+```
+- `-u` : filtre par service.
+- `-n` : n dernieres lignes.
+- `-f` : suivi temps reel.
+- `-b` : dernier boot.
+- `-S` : depuis une date (ex: `10 min ago`).
+- `--no-pager` : pas de pagination.
+
+#### 12.1.7 Reseau / Ports (diagnostic)
+
+**Ports locaux**
+```
+ss -lntp | egrep '8000|9000|5432|6379'
+netstat -lntp | egrep '8000|9000|5432|6379'
+```
+- `ss` : outil moderne (remplace netstat).
+- `-l` listening, `-n` numerique, `-t` TCP, `-p` process.
+Alternatives :
+- `lsof -iTCP -sTCP:LISTEN -n -P`
+
+**Firewall**
+```
+sudo ufw status
+```
+Alternatives :
+- `sudo iptables -S`
+- `sudo firewall-cmd --list-all`
+
+#### 12.1.8 Fichiers / Permissions
+
+**Verifier presence d'un fichier**
+```
+ls -l docker-compose.yml
+ls -l /etc/resolv.conf
+```
+- `-l` : details (droits, owner).
+Alternatives :
+- `stat <fichier>`
+
+**Corriger les permissions du depot**
+```
+sudo chown -R "$USER":"$USER" /var/www/lucien-sens-bon
+```
+- redonne les droits a l'utilisateur courant.
+Alternatives :
+- `sudo chgrp -R <groupe> <dossier>`
+- `sudo chmod -R g+w <dossier>`
+
+#### 12.1.9 Git (workflow et maintenance)
+
+**Etat et staging**
+```
+git status
+git add -A
+git reset HEAD .env output*.txt
+```
+- `add -A` : indexe ajouts + modifs + suppressions.
+- `reset HEAD ...` : retire du staging sans toucher le disque.
+Alternatives :
+- `git add <fichier>`
+- `git restore --staged <fichier>`
+
+**Commit avec identite temporaire**
+```
+GIT_AUTHOR_NAME="toshiro" GIT_AUTHOR_EMAIL="toshiro@chillka" \
+GIT_COMMITTER_NAME="toshiro" GIT_COMMITTER_EMAIL="toshiro@chillka" \
+git commit -m "local changes on huitral"
+```
+- fixe l'identite uniquement pour cette commande.
+Alternatives :
+- `git -c user.name="..." -c user.email="..." commit -m "..."`
+
+**Suivi de branche distante**
+```
+git branch --set-upstream-to=origin/docs-git-dns
+```
+- associe la branche locale a la branche distante.
+Alternatives :
+- `git push -u origin <branche>`
+
+**Mise a jour sans merge commit**
+```
+git pull --rebase
+git fetch origin
+git pull --rebase origin docs-git-dns
+```
+- `rebase` : rejoue les commits locaux au-dessus de la remote.
+Alternatives :
+- `git pull --ff-only`
+
+**Aligner strictement sur la remote (ATTENTION)**
+```
+git fetch origin
+git reset --hard origin/main
+git clean -fd
+```
+- ecrase les changements locaux + supprime les fichiers non suivis.
+Alternatives :
+- `git stash push -u -m "wip"`
+
+**Stash pour rebase**
+```
+git stash push -u -m "wip avant rebase"
+git stash pop
+```
+- sauvegarde temporaire des modifs non committes.
+Alternatives :
+- `git add -A` + `git commit` (si vous preferez un commit).
+
+**References Git**
+```
+git branch -a
+git show-ref --heads
+git show-ref --tags
+```
+- affiche les branches locales, distantes et tags.
+
+#### 12.1.10 Sauvegardes fichiers et depot
+
+**Sauvegarder les uploads**
+```
+tar -czf /backups/medusa-uploads.tgz /var/www/lucien-sens-bon/backend/uploads
+```
+- `-c` : create, `-z` : gzip, `-f` : fichier output.
+Alternatives :
+- `rsync -a` (sauvegarde incrementale).
+
+**Sauvegarder la config projet**
+```
+tar -czf /backups/lucien-sens-bon-config.tgz \
+ /var/www/lucien-sens-bon/.env \
+ /var/www/lucien-sens-bon/docker-compose.yml
+```
+- archive les fichiers critiques de config.
+
+**Sauvegarder le depot Git (bare)**
+```
+git clone --mirror toshiro@chillka:/var/data/git/repositories/lucien-sens-bon.git \
+ /backups/lucien-sens-bon.git
+```
+- `--mirror` : sauvegarde complete des refs/branches/tags.
+Alternatives :
+- `git bundle create backup.bundle --all`
+
+#### 12.1.11 Edition / fichiers d'environnement
+
+**Copier le modele `.env`**
+```
+cp env-example .env
+```
+- cree un fichier `.env` local avec les variables par defaut.
+Alternatives :
+- `cp -n env-example .env` (n'ecrase pas si `.env` existe).
+
+**Editer un fichier**
+```
+vim .env
+```
+Alternatives :
+- `nano .env`
+- `code .env`
+
+#### 12.1.12 Outils divers utiles
+
+**Tests HTTP rapides (headers only)**
+```
+curl -I http://localhost:9000/store/products
+```
+- `-I` : en-tetes uniquement (plus rapide).
+Alternatives :
+- `wget --spider <url>`
+
+**Recherche dans un conteneur**
+```
+docker compose run --rm backend sh -c "rg -n \"update\\(\\{\\},\" node_modules/@medusajs/medusa/dist/services"
+```
+- `rg -n` : recherche rapide avec numeros de lignes.
+Alternatives :
+- `grep -n <pattern> <fichier>`
+
+### 12.2 Poste Windows (et WSL)
+
+#### 12.2.1 DNS / Resolution (Windows + WSL)
+
+**DNS local (Windows)**
+```
+nslookup www.lsb.huitral.ruka.lan
+ipconfig /flushdns
+```
+Alternatives :
+- `Resolve-DnsName` (PowerShell)
+
+**DNS WSL**
+```
+dig +short www.lsb.huitral.ruka.lan
+ls -l /etc/resolv.conf
+sudo tee /etc/wsl.conf <<'EOF'
+[network]
+generateResolvConf = false
+EOF
+```
+Alternatives :
+- `nslookup`
+- `host <nom>`
+
diff --git a/POSTGRES_DIAG.md b/POSTGRES_DIAG.md index 8a07377..cb64048 100644 --- a/POSTGRES_DIAG.md +++ b/POSTGRES_DIAG.md @@ -2,6 +2,48 @@ Ce fichier regroupe les commandes essentielles pour diagnostiquer les problèmes de connexion, de droits et de performance sur PostgreSQL.
+## 0. Diagnostic sur la machine hote (avant psql)
+
+### 0.1 Savoir si PostgreSQL est installe
+```bash
+psql --version
+which psql
+```
+
+### 0.2 Savoir si PostgreSQL tourne (service ou processus)
+```bash
+sudo systemctl status postgresql
+sudo service postgresql status
+ps aux | grep -E "postgres|postmaster"
+```
+
+### 0.3 Savoir si c'est Docker ou installe localement
+```bash
+docker ps --format "table {{.Names}}\t{{.Image}}\t{{.Ports}}" | grep -i postgres
+```
+
+### 0.4 Verifier le port d'ecoute (5432 par defaut)
+```bash
+ss -lntp | grep 5432
+netstat -lntp | grep 5432
+```
+
+### 0.5 Localiser les fichiers de configuration sur la machine
+```bash
+# Si PostgreSQL tourne localement, ces commandes donnent les chemins exacts
+sudo -u postgres psql -c "SHOW config_file;"
+sudo -u postgres psql -c "SHOW hba_file;"
+sudo -u postgres psql -c "SHOW data_directory;"
+```
+
+Chemins courants (selon distribution) :
+```text
+/etc/postgresql/*/main/postgresql.conf
+/etc/postgresql/*/main/pg_hba.conf
+/var/lib/pgsql/data/postgresql.conf
+/var/lib/pgsql/data/pg_hba.conf
+```
+
## 1. Connexion au serveur (Ligne de commande)
Se connecter en tant que super-administrateur (localement) :
@@ -56,7 +98,60 @@ FROM pg_stat_activity WHERE wait_event_type = 'Lock';
```
-## 4. Gestion des Mots de Passe
+## 4. Logs des Requêtes SQL (serveur PostgreSQL)
+
+Pour voir les requêtes exécutées, les logs sont **sur le serveur PostgreSQL** (pas sur la machine Medusa).
+
+### 4.1 Activer les logs de requêtes
+Dans `postgresql.conf` :
+```text
+# Log complet (verbeux)
+log_statement = 'all'
+
+# Option moins verbeuse : toutes les requêtes lentes
+log_min_duration_statement = 0
+```
+
+Recharger la configuration :
+```sql
+SELECT pg_reload_conf();
+```
+
+### 4.2 Savoir où les logs sont écrits
+```sql
+SHOW log_directory;
+SHOW log_filename;
+SHOW logging_collector;
+```
+
+### 4.3 Requête utile (statistiques)
+Si `pg_stat_statements` est activé :
+```sql
+SELECT query, calls, total_exec_time
+FROM pg_stat_statements
+ORDER BY total_exec_time DESC
+LIMIT 20;
+```
+
+### 4.4 Voir les logs au niveau systeme
+Sur le serveur PostgreSQL :
+```bash
+# Journal systemd (Debian/Ubuntu)
+sudo journalctl -u postgresql -n 200 --no-pager
+
+# Suivre les logs en temps reel (systemd)
+sudo journalctl -u postgresql -f
+```
+
+Si les logs sont ecrits dans des fichiers (selon config) :
+```bash
+# Chemin exact indique par SHOW log_directory / log_filename
+sudo ls -lah /var/log/postgresql/
+sudo tail -n 200 /var/log/postgresql/postgresql-*.log
+sudo tail -f /var/log/postgresql/postgresql-*.log
+```
+
+## 5. Gestion des Mots de Passe
Si vous avez un doute sur un mot de passe ou une méthode de chiffrement (md5 vs scram), la meilleure solution est de le redéfinir :
@@ -65,7 +160,7 @@ Si vous avez un doute sur un mot de passe ou une méthode de chiffrement (md5 vs ALTER USER nom_utilisateur WITH PASSWORD 'nouveau_mot_de_passe';
```
-## 5. Problèmes Courants `pg_hba.conf`
+## 6. Problèmes Courants `pg_hba.conf`
Si vous avez l'erreur `no pg_hba.conf entry for host...`, vérifiez le fichier `pg_hba.conf`.
@@ -79,3 +174,99 @@ Si vous avez l'erreur `no pg_hba.conf entry for host...`, vérifiez le fichier ` ```bash
sudo systemctl reload postgresql
```
+
+## 7. Medusa - Tables concernées par des actions courantes
+
+### 6.1 Création d'un compte client (storefront)
+Tables généralement impactées :
+- `customer`
+- `customer_address` (si une adresse est fournie)
+- `customer_group_customer` (si le client est rattaché à un groupe)
+
+Requêtes SQL utiles :
+```sql
+-- Voir les tables clientes disponibles
+\dt customer*
+
+-- Consulter les derniers clients
+SELECT id, email, created_at
+FROM customer
+ORDER BY created_at DESC
+LIMIT 20;
+
+-- Adresses des clients (si table présente)
+SELECT id, customer_id, address_1, city, country_code, created_at
+FROM customer_address
+ORDER BY created_at DESC
+LIMIT 20;
+
+-- Appartenance a un groupe (si table presente)
+SELECT customer_id, customer_group_id
+FROM customer_group_customer
+LIMIT 20;
+```
+
+### 6.2 Passage d'une commande
+Tables généralement impactées :
+- `cart`
+- `line_item` (ou `cart_line_item` selon version)
+- `order`
+- `order_item`
+- `payment` / `payment_session`
+- `fulfillment` / `shipment`
+- `address` (billing / shipping)
+
+Requêtes SQL utiles :
+```sql
+-- Derniers paniers
+SELECT id, email, region_id, created_at, completed_at
+FROM cart
+ORDER BY created_at DESC
+LIMIT 20;
+
+-- Lignes de panier / lignes de commande (selon version)
+SELECT id, cart_id, order_id, title, quantity, unit_price, created_at
+FROM line_item
+ORDER BY created_at DESC
+LIMIT 20;
+
+-- Dernieres commandes
+SELECT id, status, fulfillment_status, payment_status, total, created_at
+FROM "order"
+ORDER BY created_at DESC
+LIMIT 20;
+
+-- Details d'items de commande
+SELECT id, order_id, title, quantity, unit_price, created_at
+FROM order_item
+ORDER BY created_at DESC
+LIMIT 20;
+
+-- Paiements / sessions de paiement
+SELECT id, order_id, provider_id, amount, created_at
+FROM payment
+ORDER BY created_at DESC
+LIMIT 20;
+
+SELECT id, cart_id, provider_id, amount, status, created_at
+FROM payment_session
+ORDER BY created_at DESC
+LIMIT 20;
+
+-- Fulfillment / shipments
+SELECT id, order_id, status, created_at
+FROM fulfillment
+ORDER BY created_at DESC
+LIMIT 20;
+
+SELECT id, fulfillment_id, tracking_number, created_at
+FROM shipment
+ORDER BY created_at DESC
+LIMIT 20;
+
+-- Adresses de facturation / livraison
+SELECT id, order_id, customer_id, address_1, city, country_code, created_at
+FROM address
+ORDER BY created_at DESC
+LIMIT 20;
+```
diff --git a/backend/data/products-import.csv b/backend/data/products-import.csv new file mode 100644 index 0000000..29c61c8 --- /dev/null +++ b/backend/data/products-import.csv @@ -0,0 +1,2 @@ +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
diff --git a/backend/package.json b/backend/package.json index caf9258..5d087f7 100644 --- a/backend/package.json +++ b/backend/package.json @@ -18,6 +18,7 @@ "start": "sh -c \"if [ -d src ]; then npm run build; else echo 'Skipping build: no src/ directory'; fi && medusa start\"",
"start:custom": "sh -c \"if [ -d src ]; then npm run build; else echo 'Skipping build: no src/ directory'; fi && node --preserve-symlinks index.js\"",
"dev": "sh -c \"if [ -d src ]; then npm run build; else echo 'Skipping build: no src/ directory'; fi && medusa develop\"",
+ "import:products": "node scripts/import-products.js --file ./data/products-import.csv --report ./data/import-report.json",
"seed": "medusa seed -f ./data/seed.json",
"install:cli": "npm install -g @medusajs/medusa-cli",
"postinstall": "node scripts/patch-medusa.js"
@@ -29,6 +30,7 @@ "@medusajs/cache-redis": "^1.8.9",
"@medusajs/event-bus-local": "^1.9.7",
"@medusajs/event-bus-redis": "^1.8.10",
+ "csv-parse": "^5.5.6",
"@medusajs/file-local": "^1.0.2",
"@medusajs/admin": "^7.1.14",
"body-parser": "^1.19.0",
diff --git a/backend/scripts/import-products.js b/backend/scripts/import-products.js new file mode 100644 index 0000000..04b24aa --- /dev/null +++ b/backend/scripts/import-products.js @@ -0,0 +1,250 @@ +const fs = require("fs");
+const path = require("path");
+const express = require("express");
+const { parse } = require("csv-parse/sync");
+const loaders = require("@medusajs/medusa/dist/loaders/index").default;
+
+class CsvProductImporter {
+ constructor({ filePath, reportPath, dryRun, defaultCurrency }) {
+ this.filePath = filePath;
+ this.reportPath = reportPath;
+ this.dryRun = dryRun;
+ this.defaultCurrency = defaultCurrency;
+ this.report = {
+ file: filePath,
+ dryRun,
+ startedAt: new Date().toISOString(),
+ finishedAt: null,
+ totals: {
+ processed: 0,
+ created: 0,
+ updated: 0,
+ failed: 0,
+ },
+ errors: [],
+ };
+ }
+
+ async run() {
+ this.assertFileExists();
+ const rows = this.parseCsv();
+ const productGroups = this.groupByExternalId(rows);
+
+ const { container, dbConnection } = await this.initMedusa();
+ const productService = container.resolve("productService");
+
+ for (const productData of productGroups) {
+ try {
+ await this.upsertProduct(productService, productData);
+ this.report.totals.processed += 1;
+ } catch (error) {
+ this.report.totals.failed += 1;
+ this.report.errors.push({
+ external_id: productData.external_id,
+ message: error.message,
+ });
+ }
+ }
+
+ this.report.finishedAt = new Date().toISOString();
+ this.writeReport();
+ await dbConnection.close();
+ }
+
+ assertFileExists() {
+ if (!fs.existsSync(this.filePath)) {
+ throw new Error(`CSV introuvable: ${this.filePath}`);
+ }
+ }
+
+ parseCsv() {
+ const input = fs.readFileSync(this.filePath, "utf-8");
+ return parse(input, {
+ columns: true,
+ skip_empty_lines: true,
+ trim: true,
+ }).map((row) => this.normalizeRow(row));
+ }
+
+ normalizeRow(row) {
+ const toBool = (value, defaultValue) => {
+ if (value === undefined || value === "") {
+ return defaultValue;
+ }
+ const normalized = String(value).toLowerCase();
+ return ["true", "1", "yes", "y"].includes(normalized);
+ };
+
+ return {
+ external_id: row.external_id || "",
+ title: row.title || "",
+ handle: row.handle || this.slugify(row.title || ""),
+ description: row.description || "",
+ thumbnail: row.thumbnail || "",
+ option_title: row.option_title || "Taille",
+ option_value: row.option_value || row.variant_title || "Default",
+ variant_title: row.variant_title || row.option_value || "Default",
+ variant_sku: row.variant_sku || "",
+ price_amount: Number.parseInt(row.price_amount, 10) || 0,
+ currency_code: row.currency_code || this.defaultCurrency,
+ inventory_quantity: Number.parseInt(row.inventory_quantity, 10) || 0,
+ manage_inventory: toBool(row.manage_inventory, true),
+ };
+ }
+
+ groupByExternalId(rows) {
+ const groups = new Map();
+
+ for (const row of rows) {
+ if (!row.external_id) {
+ throw new Error("Champ requis manquant: external_id");
+ }
+ if (!row.title) {
+ throw new Error(`Champ requis manquant: title (external_id=${row.external_id})`);
+ }
+
+ const existing = groups.get(row.external_id);
+ const variant = {
+ title: row.variant_title,
+ sku: row.variant_sku || undefined,
+ prices: [
+ {
+ currency_code: row.currency_code,
+ amount: row.price_amount,
+ },
+ ],
+ options: [
+ {
+ value: row.option_value,
+ },
+ ],
+ inventory_quantity: row.inventory_quantity,
+ manage_inventory: row.manage_inventory,
+ };
+
+ if (!existing) {
+ groups.set(row.external_id, {
+ external_id: row.external_id,
+ title: row.title,
+ handle: row.handle,
+ description: row.description,
+ thumbnail: row.thumbnail || undefined,
+ options: [{ title: row.option_title }],
+ variants: [variant],
+ });
+ } else {
+ if (existing.options[0].title !== row.option_title) {
+ throw new Error(
+ `option_title incoherent pour external_id=${row.external_id} (${existing.options[0].title} vs ${row.option_title})`
+ );
+ }
+ existing.variants.push(variant);
+ }
+ }
+
+ return Array.from(groups.values());
+ }
+
+ async initMedusa() {
+ const app = express();
+ const directory = path.resolve(__dirname, "..");
+ return loaders({ directory, expressApp: app });
+ }
+
+ async upsertProduct(productService, productData) {
+ const existing = await this.findByExternalId(productService, productData.external_id);
+ const action = existing ? "update" : "create";
+
+ if (this.dryRun) {
+ console.log(`[dry-run] ${action} product external_id=${productData.external_id}`);
+ if (existing) {
+ this.report.totals.updated += 1;
+ } else {
+ this.report.totals.created += 1;
+ }
+ return;
+ }
+
+ if (existing) {
+ await productService.update(existing.id, productData);
+ this.report.totals.updated += 1;
+ return;
+ }
+
+ await productService.create(productData);
+ this.report.totals.created += 1;
+ }
+
+ async findByExternalId(productService, externalId) {
+ const results = await productService.list({ external_id: externalId }, { take: 1 });
+ return results[0] || null;
+ }
+
+ writeReport() {
+ if (!this.reportPath) {
+ return;
+ }
+ fs.writeFileSync(this.reportPath, JSON.stringify(this.report, null, 2), "utf-8");
+ }
+
+ slugify(value) {
+ return String(value)
+ .toLowerCase()
+ .trim()
+ .replace(/[^a-z0-9]+/g, "-")
+ .replace(/^-+|-+$/g, "");
+ }
+}
+
+function parseArgs(argv) {
+ const args = {
+ file: null,
+ report: null,
+ dryRun: false,
+ currency: "eur",
+ };
+
+ for (let i = 0; i < argv.length; i += 1) {
+ const current = argv[i];
+ if (current === "--file") {
+ args.file = argv[i + 1];
+ i += 1;
+ } else if (current === "--report") {
+ args.report = argv[i + 1];
+ i += 1;
+ } else if (current === "--dry-run") {
+ args.dryRun = true;
+ } else if (current === "--currency") {
+ args.currency = argv[i + 1];
+ i += 1;
+ }
+ }
+
+ return args;
+}
+
+async function main() {
+ const directory = path.resolve(__dirname, "..");
+ const args = parseArgs(process.argv.slice(2));
+ const filePath = args.file
+ ? path.resolve(directory, args.file)
+ : path.resolve(directory, "data", "products-import.csv");
+ const reportPath = args.report
+ ? path.resolve(directory, args.report)
+ : path.resolve(directory, "data", "import-report.json");
+
+ const importer = new CsvProductImporter({
+ filePath,
+ reportPath,
+ dryRun: args.dryRun,
+ defaultCurrency: args.currency,
+ });
+
+ await importer.run();
+ console.log("Import termine.");
+}
+
+main().catch((error) => {
+ console.error("Echec import:", error);
+ process.exitCode = 1;
+});
diff --git a/helper-cmd.md b/helper-cmd.md new file mode 100644 index 0000000..7edef87 --- /dev/null +++ b/helper-cmd.md @@ -0,0 +1,616 @@ +# Helper - Commandes du projet Lucien-sens-bon
+
+Ce document explique les commandes utilisées dans ce projet, classées par thème.
+Pour chaque commande : objectif, paramètres importants, et alternatives utiles.
+
+## 1. Docker / Docker Compose (services Medusa + Storefront + Redis)
+
+### 1.1 Lancer les services
+**Commande**
+```
+docker compose up -d --build
+```
+**Explication**
+- `docker compose` : plugin Compose intégré (recommandé).
+- `up` : crée et démarre les services.
+- `-d` : détaché (retourne la main).
+- `--build` : reconstruit les images si nécessaire.
+
+**Alternatives**
+- `docker-compose up -d --build` (ancienne syntaxe).
+- `docker compose up` (sans `-d` : logs en direct).
+
+### 1.2 Voir l'état des conteneurs
+**Commande**
+```
+docker compose ps
+```
+**Paramètres**
+- aucun : liste services, statuts, ports.
+
+**Alternatives**
+- `docker ps` : tous les conteneurs (tous projets).
+- `docker compose ps -a` : inclut les conteneurs arrêtés.
+
+### 1.3 Voir les logs
+**Commande**
+```
+docker compose logs -f
+docker compose logs -f backend
+docker compose logs -f storefront
+```
+**Paramètres**
+- `-f` : suivi temps réel (équivalent `tail -f`).
+- `backend` / `storefront` : filtre par service.
+
+**Alternatives**
+- `docker logs -f <container>`
+- `docker compose logs --tail=200 backend`
+
+### 1.4 Redémarrer un service
+**Commande**
+```
+docker compose restart backend
+```
+**Explication**
+- redémarre le service sans reconstruire l’image.
+
+**Alternatives**
+- `docker compose up -d backend`
+- `docker compose up -d --build backend`
+
+### 1.5 Rebuild forcé d’un service
+**Commande**
+```
+docker compose build --no-cache backend
+docker compose up -d --build backend
+```
+**Paramètres**
+- `--no-cache` : force l’installation des deps + postinstall.
+- `--build` : rebuild puis redeploiement.
+
+**Alternatives**
+- `docker compose build backend` (cache autorisé).
+
+### 1.6 Entrer dans un conteneur
+**Commande**
+```
+docker exec -it medusa-backend sh
+```
+**Paramètres**
+- `exec` : exécute une commande dans un conteneur.
+- `-it` : mode interactif + TTY.
+- `sh` : shell minimal.
+
+**Alternatives**
+- `docker exec -it medusa-backend bash` (si `bash` présent).
+- `docker compose exec backend sh`
+
+### 1.7 Commande dans un conteneur temporaire
+**Commande**
+```
+docker compose run --rm backend <commande>
+```
+**Paramètres**
+- `run` : conteneur ponctuel basé sur le service.
+- `--rm` : supprime le conteneur à la fin.
+
+**Alternatives**
+- `docker run --rm -it <image> <commande>`
+
+## 2. PostgreSQL (connexion, diagnostic, sauvegarde)
+
+### 2.1 Connexion via `DATABASE_URL`
+**Commande**
+```
+psql "$DATABASE_URL" -c "select 1;"
+```
+**Paramètres**
+- `$DATABASE_URL` : `postgres://user:pass@host:5432/db`
+- `-c` : exécute une requête et quitte.
+
+**Alternatives**
+- `psql -h <host> -U <user> -d <db> -W`
+- `docker run --rm -it postgres:16-alpine psql "$DATABASE_URL" -c "select 1;"`
+
+### 2.2 Test du port réseau PostgreSQL
+**Commande**
+```
+nc -vz <host_db> 5432
+```
+**Paramètres**
+- `-v` : verbose.
+- `-z` : scan sans envoyer de données.
+
+**Alternatives**
+- `telnet <host_db> 5432`
+- `bash -c ">/dev/tcp/<host_db>/5432"` (si bash)
+
+### 2.3 Diagnostic hôte (service / process)
+**Commandes**
+```
+sudo systemctl status postgresql
+sudo service postgresql status
+ps aux | grep -E "postgres|postmaster"
+```
+**Paramètres**
+- `systemctl` / `service` : vérifie service systemd/sysv.
+- `ps + grep` : liste les processus.
+
+**Alternatives**
+- `pgrep -a postgres`
+- `ss -lntp | grep 5432`
+
+### 2.4 Localiser la configuration
+**Commandes**
+```
+sudo -u postgres psql -c "SHOW config_file;"
+sudo -u postgres psql -c "SHOW hba_file;"
+sudo -u postgres psql -c "SHOW data_directory;"
+```
+**Explication**
+- donne les chemins exacts des fichiers de config et des données.
+
+**Alternatives (chemins typiques)**
+- `/etc/postgresql/*/main/postgresql.conf`
+- `/etc/postgresql/*/main/pg_hba.conf`
+- `/var/lib/pgsql/data/postgresql.conf`
+- `/var/lib/pgsql/data/pg_hba.conf`
+
+### 2.5 Commandes `psql` utiles (dans psql)
+**Commandes**
+```
+\du
+\l
+\c ma_base
+\dt
+SHOW port;
+SHOW listen_addresses;
+```
+**Paramètres**
+- `\` : commandes internes psql.
+- `SHOW ...` : variables de configuration.
+
+**Alternatives**
+- `SELECT current_user;`
+- `SELECT version();`
+
+### 2.6 Sauvegarde et restauration
+**Commandes**
+```
+pg_dump -Fc -U user nom_db > /backups/lucien-sens-bon.dump
+pg_restore -U user -d nom_db /backups/lucien-sens-bon.dump
+```
+**Paramètres**
+- `-Fc` : format custom (compressé + restauration sélective).
+- `-U` : utilisateur.
+
+**Alternatives**
+- `pg_dump -U user nom_db > dump.sql`
+- `psql -U user -d nom_db < dump.sql`
+
+## 3. Medusa / Node.js (backend)
+
+### 3.1 Migrations Medusa
+**Commande**
+```
+docker compose run --rm backend npx medusa migrations run
+```
+**Explication**
+- applique les migrations (création des tables).
+
+**Paramètres**
+- `npx` : exécute la version locale de Medusa.
+
+**Alternatives**
+- `docker exec -it medusa-backend npx medusa migrations run`
+
+### 3.2 Seed de données
+**Commande**
+```
+docker compose run --rm backend npm run seed
+```
+**Explication**
+- injecte des données de démo si `backend/data/seed.json` existe.
+
+**Alternatives**
+- `docker exec -it medusa-backend npm run seed`
+
+### 3.3 Import CSV produits (Medusa)
+**Commande**
+```
+docker compose run --rm backend npm run import:products
+```
+**Explication**
+- importe des produits depuis `backend/data/products-import.csv` (upsert via `external_id`).
+
+**Alternatives**
+- `docker exec -it medusa-backend npm run import:products`
+- `node backend/scripts/import-products.js --file backend/data/products-import.csv --dry-run`
+
+**Doc**
+- voir `DOC_IMPORT_PRODUITS.md`
+
+### 3.4 Création utilisateur admin (Medusa)
+**Commande**
+```
+docker exec -it medusa-backend medusa user -e admin@lucien.com -p supersecret
+```
+**Paramètres**
+- `-e` : email de l’admin.
+- `-p` : mot de passe.
+
+**Alternatives**
+- `medusa user --help`
+
+### 3.5 Test DB via Node (diagnostic)
+**Commande**
+```
+docker compose run --rm backend node -e "const { Client }=require('pg'); ... "
+```
+**Explication**
+- `node -e` : exécute un script JS en ligne.
+- `pg` : client PostgreSQL Node.
+
+**Alternatives**
+- script JS temporaire dans le conteneur.
+- `psql` direct (plus simple si accès).
+
+## 4. Storefront / Tests HTTP (curl)
+
+### 4.1 Test de l’API Medusa
+**Commande**
+```
+curl http://localhost:9000/store/products
+```
+**Paramètres**
+- URL endpoint public Medusa.
+
+**Alternatives**
+- `curl -v ...`
+- `http :9000/store/products` (httpie)
+
+### 4.2 Test du storefront
+**Commande**
+```
+curl http://localhost:8000
+```
+**Explication**
+- vérifie que le site répond.
+
+**Alternatives**
+- `curl -I http://localhost:8000`
+
+### 4.3 Test CORS
+**Commande**
+```
+curl -i -H "Origin: http://<IP>:8000" http://<IP>:9000/store/products
+```
+**Paramètres**
+- `-i` : inclut les en-têtes.
+- `-H` : ajoute un header `Origin`.
+
+**Alternatives**
+- `curl -v ...`
+- DevTools navigateur (onglet Network).
+
+## 5. Apache / Reverse proxy
+
+### 5.1 Statut Apache
+**Commande**
+```
+sudo systemctl status apache2
+```
+**Alternatives**
+- `sudo service apache2 status`
+
+### 5.2 Logs Apache
+**Commandes**
+```
+sudo journalctl -u apache2 -f
+sudo tail -f /var/log/apache2/error.log
+sudo tail -f /var/log/apache2/access.log
+```
+**Paramètres**
+- `-f` : suivi temps réel.
+
+**Alternatives**
+- `journalctl -u apache2 -n 200 --no-pager`
+
+### 5.3 Modules proxy
+**Commandes**
+```
+sudo a2enmod proxy
+sudo a2enmod proxy_http
+```
+**Explication**
+- active les modules de reverse proxy.
+
+**Alternatives**
+- `a2enmod headers`
+- `a2enmod rewrite`
+
+### 5.4 Reload Apache
+**Commande**
+```
+sudo systemctl reload apache2
+```
+**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.
+
+## 6. DNS / Résolution (Windows + Linux)
+
+### 6.1 DNS local (Windows)
+**Commandes**
+```
+nslookup www.lsb.huitral.ruka.lan
+ipconfig /flushdns
+```
+**Alternatives**
+- `Resolve-DnsName` (PowerShell)
+
+### 6.2 DNS Linux
+**Commandes**
+```
+dig +short www.lsb.huitral.ruka.lan
+ls -l /etc/resolv.conf
+sudo tee /etc/wsl.conf <<'EOF'
+[network]
+generateResolvConf = false
+EOF
+```
+**Alternatives**
+- `nslookup`
+- `host <nom>`
+
+## 7. Systemd / Logs système (journalctl)
+
+### 7.1 Base
+**Commandes**
+```
+sudo journalctl --disk-usage
+sudo journalctl --list-boots
+sudo journalctl -u <service> -n 50 --no-pager
+sudo journalctl -u <service> -f
+```
+**Paramètres**
+- `-u` : filtre par service.
+- `-n` : n dernières lignes.
+- `-f` : suivi temps réel.
+- `-b` : dernier boot.
+- `-S` : depuis une date (ex: `10 min ago`).
+- `--no-pager` : pas de pagination.
+
+## 8. Réseau / Ports (diagnostic)
+
+### 8.1 Ports locaux
+**Commandes**
+```
+ss -lntp | egrep '8000|9000|5432|6379'
+netstat -lntp | egrep '8000|9000|5432|6379'
+```
+**Paramètres**
+- `ss` : outil moderne (remplace netstat).
+- `-l` listening, `-n` numérique, `-t` TCP, `-p` process.
+
+**Alternatives**
+- `lsof -iTCP -sTCP:LISTEN -n -P`
+
+### 8.2 Firewall
+**Commande**
+```
+sudo ufw status
+```
+**Alternatives**
+- `sudo iptables -S`
+- `sudo firewall-cmd --list-all`
+
+## 9. Fichiers / Permissions
+
+### 9.1 Vérifier présence d’un fichier
+**Commandes**
+```
+ls -l docker-compose.yml
+ls -l /etc/resolv.conf
+```
+**Explication**
+- `-l` : détails (droits, owner).
+
+**Alternatives**
+- `stat <fichier>`
+
+### 9.2 Corriger les permissions du dépôt
+**Commande**
+```
+sudo chown -R "$USER":"$USER" /var/www/lucien-sens-bon
+```
+**Explication**
+- redonne les droits à l’utilisateur courant.
+
+**Alternatives**
+- `sudo chgrp -R <groupe> <dossier>`
+- `sudo chmod -R g+w <dossier>`
+
+## 10. Git (workflow et maintenance)
+
+### 10.1 État et staging
+**Commandes**
+```
+git status
+git add -A
+git reset HEAD .env output*.txt
+```
+**Paramètres**
+- `add -A` : indexe ajouts + modifs + suppressions.
+- `reset HEAD ...` : retire du staging sans toucher au disque.
+
+**Alternatives**
+- `git add <fichier>`
+- `git restore --staged <fichier>`
+
+### 10.2 Commit avec identité temporaire
+**Commande**
+```
+GIT_AUTHOR_NAME="toshiro" GIT_AUTHOR_EMAIL="toshiro@chillka" \
+GIT_COMMITTER_NAME="toshiro" GIT_COMMITTER_EMAIL="toshiro@chillka" \
+git commit -m "local changes on huitral"
+```
+**Explication**
+- fixe l’identité uniquement pour cette commande.
+
+**Alternatives**
+- `git -c user.name="..." -c user.email="..." commit -m "..."`
+
+### 10.3 Suivi de branche distante
+**Commande**
+```
+git branch --set-upstream-to=origin/docs-git-dns
+```
+**Explication**
+- associe la branche locale à la branche distante.
+
+**Alternatives**
+- `git push -u origin <branche>`
+
+### 10.4 Mise à jour sans merge commit
+**Commandes**
+```
+git pull --rebase
+git fetch origin
+git pull --rebase origin docs-git-dns
+```
+**Explication**
+- `rebase` : rejoue les commits locaux au-dessus de la remote.
+
+**Alternatives**
+- `git pull --ff-only`
+
+### 10.5 Aligner strictement sur la remote (ATTENTION)
+**Commandes**
+```
+git fetch origin
+git reset --hard origin/main
+git clean -fd
+```
+**Explication**
+- écrase les changements locaux + supprime les fichiers non suivis.
+
+**Alternatives**
+- `git stash push -u -m "wip"`
+
+### 10.6 Stash pour rebase
+**Commandes**
+```
+git stash push -u -m "wip avant rebase"
+git stash pop
+```
+**Explication**
+- sauvegarde temporaire des modifs non committés.
+
+**Alternatives**
+- `git add -A` + `git commit` (si vous préférez un commit).
+
+### 10.7 Références Git
+**Commandes**
+```
+git branch -a
+git show-ref --heads
+git show-ref --tags
+```
+**Explication**
+- affiche les branches locales, distantes et tags.
+
+## 11. Sauvegardes fichiers et dépôt
+
+### 11.1 Sauvegarder les uploads
+**Commande**
+```
+tar -czf /backups/medusa-uploads.tgz /var/www/lucien-sens-bon/backend/uploads
+```
+**Paramètres**
+- `-c` : create, `-z` : gzip, `-f` : fichier output.
+
+**Alternatives**
+- `rsync -a` (sauvegarde incrémentale).
+
+### 11.2 Sauvegarder la config projet
+**Commande**
+```
+tar -czf /backups/lucien-sens-bon-config.tgz \
+ /var/www/lucien-sens-bon/.env \
+ /var/www/lucien-sens-bon/docker-compose.yml
+```
+**Explication**
+- archive les fichiers critiques de config.
+
+### 11.3 Sauvegarder le dépôt Git (bare)
+**Commande**
+```
+git clone --mirror toshiro@chillka:/var/data/git/repositories/lucien-sens-bon.git \
+ /backups/lucien-sens-bon.git
+```
+**Paramètres**
+- `--mirror` : sauvegarde complète des refs/branches/tags.
+
+**Alternatives**
+- `git bundle create backup.bundle --all`
+
+## 12. Édition / fichiers d’environnement
+
+### 12.1 Copier le modèle `.env`
+**Commande**
+```
+cp env-example .env
+```
+**Explication**
+- crée un fichier `.env` local avec les variables par défaut.
+
+**Alternatives**
+- `cp -n env-example .env` (n’écrase pas si `.env` existe).
+
+### 12.2 Éditer un fichier
+**Commande**
+```
+vim .env
+```
+**Alternatives**
+- `nano .env`
+- `code .env`
+
+## 13. Outils divers utiles
+
+### 13.1 Tests HTTP rapides (headers only)
+**Commande**
+```
+curl -I http://localhost:9000/store/products
+```
+**Explication**
+- `-I` : en-têtes uniquement (plus rapide).
+
+**Alternatives**
+- `wget --spider <url>`
+
+### 13.2 Recherche dans un conteneur
+**Commande**
+```
+docker compose run --rm backend sh -c "rg -n \"update\\(\\{\\},\" node_modules/@medusajs/medusa/dist/services"
+```
+**Explication**
+- `rg -n` : recherche rapide avec numéros de lignes.
+
+**Alternatives**
+- `grep -n <pattern> <fichier>`
+
|
