From aa494fd8e24b0aabcc890655370a15358f9e6755 Mon Sep 17 00:00:00 2001 From: ertopogo Date: Thu, 5 Feb 2026 23:48:50 +0100 Subject: WIP: prepare import csv --- DOC_IMPORT_PRODUITS.md | 193 ++++++++++++ DOC_TECHNIQUE.md | 569 +++++++++++++++++++++++++++++++--- POSTGRES_DIAG.md | 195 +++++++++++- backend/data/products-import.csv | 2 + backend/package.json | 2 + backend/scripts/import-products.js | 250 +++++++++++++++ helper-cmd.md | 616 +++++++++++++++++++++++++++++++++++++ 7 files changed, 1788 insertions(+), 39 deletions(-) create mode 100644 DOC_IMPORT_PRODUITS.md create mode 100644 backend/data/products-import.csv create mode 100644 backend/scripts/import-products.js create mode 100644 helper-cmd.md 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://:8000" http://: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 : ### 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 : 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 ` +- `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 +``` +- `run` : conteneur ponctuel base sur le service. +- `--rm` : supprime le conteneur a la fin. +Alternatives : +- `docker run --rm -it ` + +#### 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 -U -d -W` +- `docker run --rm -it postgres:16-alpine psql "$DATABASE_URL" -c "select 1;"` + +**Test du port reseau PostgreSQL** +``` +nc -vz 5432 +``` +- `-v` : verbose. +- `-z` : scan sans envoyer de donnees. +Alternatives : +- `telnet 5432` +- `bash -c ">/dev/tcp//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://:8000" http://: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 -n 50 --no-pager +sudo journalctl -u -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 ` + +**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 ` +- `sudo chmod -R g+w ` + +#### 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 ` +- `git restore --staged ` + +**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 ` + +**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 ` + +**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 ` + +### 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 ` + 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 ` +- `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 +``` +**Paramètres** +- `run` : conteneur ponctuel basé sur le service. +- `--rm` : supprime le conteneur à la fin. + +**Alternatives** +- `docker run --rm -it ` + +## 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 -U -d -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 5432 +``` +**Paramètres** +- `-v` : verbose. +- `-z` : scan sans envoyer de données. + +**Alternatives** +- `telnet 5432` +- `bash -c ">/dev/tcp//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://:8000" http://: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 ` + +## 7. Systemd / Logs système (journalctl) + +### 7.1 Base +**Commandes** +``` +sudo journalctl --disk-usage +sudo journalctl --list-boots +sudo journalctl -u -n 50 --no-pager +sudo journalctl -u -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 ` + +### 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 ` +- `sudo chmod -R g+w ` + +## 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 ` +- `git restore --staged ` + +### 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 ` + +### 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 ` + +### 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 ` + -- cgit v1.2.3