diff --git a/docs/proposer-whoami-gate.md b/docs/proposer-whoami-gate.md new file mode 100644 index 0000000..06de1e7 --- /dev/null +++ b/docs/proposer-whoami-gate.md @@ -0,0 +1,69 @@ +# “Proposer” protégé par groupe (whoami / editors) + +## But +Le bouton **Proposer** (création d’issue Gitea pré-remplie) doit être : +- visible **uniquement** pour les membres du groupe `editors`, +- **absent** pour les autres utilisateurs, +- robuste (fail-closed), mais **non-collant** (pas de “bloqué” après un échec transitoire). + +## Pré-requis (build-time) +Les variables publiques Astro doivent être injectées au build : +- `PUBLIC_GITEA_BASE` +- `PUBLIC_GITEA_OWNER` +- `PUBLIC_GITEA_REPO` + +Si une seule manque → `giteaReady=false` → Proposer est désactivé. + +### Vérification NAS (slots blue/green) +Exemple : +- blue : http://127.0.0.1:8081/... +- green : http://127.0.0.1:8082/... + +Commande (ex) : +`curl -sS http://127.0.0.1:8081/archicratie/archicrat-ia/chapitre-4/ | grep -n "const GITEA_" | head` + +## Signal d’auth (runtime) : `/_auth/whoami` +Le site appelle `/_auth/whoami` (same-origin) pour récupérer : +- `Remote-User` +- `Remote-Groups` +Ces headers sont injectés par la chaîne edge (Traefik → Authelia forward-auth). + +### Appel robuste +- cache-bust : `?_=${Date.now()}` +- `cache: "no-store"` +- `credentials: "include"` + +### Critère +`groups.includes("editors")` + +## Comportement attendu (UX) +- utilisateur editors : le bouton “Proposer” est visible, ouvre la modal, puis ouvre Gitea. +- utilisateur non editors : le bouton “Proposer” n’existe pas (retiré du DOM). + +## Pièges connus +1) Tester en direct 8081/8082 ne reflète pas toujours la chaîne Traefik+Authelia. +2) Un gate “collant” peut rester OFF si l’échec est mis en cache trop agressivement. +3) Si “Proposer” est caché via `style.display="none"`, il faut le réafficher via `style.display=""` (pas via `hidden=false`). + +## Debug rapide (console navigateur) +en js : + +(async () => { + const r = await fetch("/_auth/whoami?_=" + Date.now(), { + credentials: "include", + cache: "no-store", + redirect: "follow", + }); + const t = await r.text(); + const groups = (t.match(/^Remote-Groups:\s*(.*)$/mi)?.[1] || "") + .split(",").map(s => s.trim()).filter(Boolean); + console.log({ ok: r.ok, status: r.status, groups, raw: t.slice(0, 220) + "..." }); +})(); + +## Définition “done” + +Archicratia (editors) voit Proposer et peut ouvrir un ticket. + +s-FunX (non editors) ne voit pas Proposer. + +Les deux slots blue/green injectent les constantes Gitea dans le HTML. diff --git a/docs/runbook-deploiement-web-blue-green.md b/docs/runbook-deploiement-web-blue-green.md new file mode 100644 index 0000000..fcaf902 --- /dev/null +++ b/docs/runbook-deploiement-web-blue-green.md @@ -0,0 +1,82 @@ +# Runbook — Déploiement Archicratie Web Édition (Blue/Green) + +## Arborescence NAS (repère) +- `/volume2/docker/archicratie-web/current/` : état courant (Dockerfile, docker-compose.yml, dist buildé en image) +- `/volume2/docker/archicratie-web/releases/` : historiques éventuels +- `/volume2/docker/edge/` : Traefik + config dynamique + +> Important : les commandes `docker compose -f ...` doivent viser le **docker-compose.yml présent dans `current/`**. + +--- + +## Pré-requis Synology +Sur NAS, les commandes ont été exécutées avec : +en bash +sudo env DOCKER_API_VERSION=1.43 docker ... + +(contexte DSM / compat API) + +### 1) Variables de build (Gitea) + +Dans /volume2/docker/archicratie-web/current créer/maintenir : + +cat > .env <<'EOF' +PUBLIC_GITEA_BASE=https://gitea.archicratie.trans-hands.synology.me +PUBLIC_GITEA_OWNER=Archicratia +PUBLIC_GITEA_REPO=archicratie-edition +EOF + +### 2) Build images (blue + green) — méthode robuste + +cd /volume2/docker/archicratie-web/current + +sudo env DOCKER_API_VERSION=1.43 docker compose -f docker-compose.yml build --no-cache web_blue web_green + +Puis recréer les conteneurs sans rebuild : + +sudo env DOCKER_API_VERSION=1.43 docker compose -f docker-compose.yml up -d --force-recreate --no-build web_blue web_green + +### 3) Vérifier que les deux slots sont OK + +curl -sS -D- http://127.0.0.1:8081/ | head -n 12 +curl -sS -D- http://127.0.0.1:8082/ | head -n 12 + +Attendu : + +HTTP/1.1 200 OK + +Server: nginx/... + +### 4) Traefik : s’assurer qu’un seul backend est actif + +Fichier : +/volume2/docker/edge/config/dynamic/20-archicratie-backend.yml + +Attendu : une seule URL (8081 OU 8082) + +http: + services: + archicratie_web: + loadBalancer: + servers: + - url: "http://127.0.0.1:8081" + +### 5) Smoke via Traefik (entrée réelle) + +curl -sS -H 'Host: archicratie.trans-hands.synology.me' http://127.0.0.1:18080/ | head -n 20 + +Attendu : + +si non loggé : 302 vers Authelia + +si loggé : HTML du site + +### 6) Piège classique : conflit de nom de conteneur + +Si : +Conflict. The container name "/archicratie-web-blue" is already in use... + +Faire : + +sudo docker rm -f archicratie-web-blue +sudo env DOCKER_API_VERSION=1.43 docker compose -f docker-compose.yml up -d --force-recreate --no-build web_blue \ No newline at end of file diff --git a/docs/runbook-gitea-branches-pr.md b/docs/runbook-gitea-branches-pr.md new file mode 100644 index 0000000..a31edad --- /dev/null +++ b/docs/runbook-gitea-branches-pr.md @@ -0,0 +1,71 @@ +# Runbook — Gitea : Branches, PR, Merge (sans se faire piéger) + +## Règle n°1 (hyper importante) +Une PR n’apparaît dans Gitea que si la branche contient **au moins 1 commit différent de `main`**. + +Symptôme typique : +- `git push -u origin fix/xxx` +- et tu vois : `Total 0 ...` +→ ça veut dire : **aucun nouveau commit** → la branche est identique à main → pas de vraie PR à proposer. + +--- + +## Workflow “propre” (pas à pas) +### 1) Remettre `main` propre +en bash + +git checkout main +git pull --ff-only + +### 2) Créer une branche de travail + +git checkout -b fix/mon-fix + +### 3) Faire un changement réel + +Modifier le fichier (ex : src/layouts/EditionLayout.astro) + +Vérifier : + +git status -sb + +→ doit montrer un fichier modifié. + +### 4) Tester + +npm test + +### 5) Commit + +git add src/layouts/EditionLayout.astro +git commit -m "Fix: ..." + +### 6) Push + +git push -u origin fix/mon-fix + +### 7) Créer la PR dans l’UI Gitea + +# Aller dans Pull Requests + +# New Pull Request + +Base : main + +Compare : fix/mon-fix + +Branch protection (si “Not allowed to push to protected branch main”) + +# C’est normal si main est protégé : + +On ne pousse jamais directement sur main. + +On merge via PR (UI), avec un compte autorisé. + +Si Gitea refuse de merger automatiquement : + +soit tu actives le réglage côté Gitea “manual merge detection” (admin), + +soit tu fais le merge localement MAIS tu ne pourras pas pousser sur main si la protection l’interdit. + +Conclusion : la voie “pro” = PR + merge UI. \ No newline at end of file diff --git a/docs/runbook-proposer-gitea.md b/docs/runbook-proposer-gitea.md new file mode 100644 index 0000000..0c8db6a --- /dev/null +++ b/docs/runbook-proposer-gitea.md @@ -0,0 +1,67 @@ +# Runbook — Bouton “Proposer” (site → Gitea issue) + Gate Authelia + +## Objectif +Permettre une proposition de correction éditoriale depuis un paragraphe du site, en créant une *issue* Gitea pré-remplie, uniquement pour les membres du groupe `editors`. + +--- + +## Pré-requis +- Traefik (edge) en front +- Authelia (forwardAuth) opérationnel +- Router `/_auth/whoami` exposé (whoami) +- Variables `PUBLIC_GITEA_*` injectées au build du site + +--- + +## Vérification rapide (navigateur) +### 1) Qui suis-je ? (groupes) +Dans la console : +en js : +await fetch("/_auth/whoami?_=" + Date.now(), { + credentials: "include", + cache: "no-store", +}).then(r => r.text()); + +Attendu (extraits) : + +Remote-User: + +Remote-Groups: ...,editors,... pour un éditeur + +### 2) Le bouton existe ? +document.querySelectorAll(".para-propose").length + +> 0 si editors + +0 si non-editor + +## Vérification côté NAS (build vars) +### 1) Blue et Green contiennent les constantes ? + +P="/archicratie/archicrat-ia/chapitre-4/" + +curl -sS "http://127.0.0.1:8081$P" | grep -n "const GITEA_BASE" | head -n 2 +curl -sS "http://127.0.0.1:8082$P" | grep -n "const GITEA_BASE" | head -n 2 + +### 2) Si une des deux est vide → rebuild propre + +Dans /volume2/docker/archicratie-web/current : + +cat > .env <<'EOF' +PUBLIC_GITEA_BASE=https://gitea.archicratie.trans-hands.synology.me +PUBLIC_GITEA_OWNER=Archicratia +PUBLIC_GITEA_REPO=archicratie-edition +EOF + +sudo env DOCKER_API_VERSION=1.43 docker compose -f docker-compose.yml build --no-cache web_blue web_green +sudo env DOCKER_API_VERSION=1.43 docker compose -f docker-compose.yml up -d --force-recreate --no-build web_blue web_green + +## Dépannage (si Proposer “disparaît”) + +Vérifier groupes via /_auth/whoami + +Vérifier const GITEA_BASE via curl sur le slot actif + +Vérifier que Traefik sert bien le slot actif (grep via curl -H Host: ... http://127.0.0.1:18080/...) + +Ouvrir la console : vérifier qu’aucune erreur JS n’empêche l’injection des outils paragraphe \ No newline at end of file