# SatPRO — Site de présentation des specs (pré-projet) Site web privé pour **présenter les specs métier SatPRO** (les fichiers Markdown de `../docs/specs-pre-projet/`) en séance d'atelier. - **Viewer Markdown** : navigation entre les documents, rendu GFM + tableaux + diagrammes Mermaid. - **Lecture en direct** : le site lit les fichiers `.md` sur le disque. Quand les specs sont éditées (dans l'IDE), un simple **Rafraîchir** affiche la dernière version. Aucune recompilation, aucune duplication de contenu. - **Accès gérés dans le site** : un **administrateur** unique est défini dans `.env` ; tous les autres comptes se créent/gèrent via la page **Gestion des accès** (rôles consultation / contributeur / désactivé, réinitialisation de mot de passe, changement imposé à la première connexion). Session JWT. - **Annotations en ligne** : chaque utilisateur peut annoter une section (ajout / correction / question / remarque). Les annotations sont stockées côté serveur et **exportables** (admin) en Markdown de synthèse ou JSON, pour transmission et mise à jour des `.md`. - **Non indexable** : `robots.txt`, balise ``, en-tête `X-Robots-Tag` (nginx + Caddy). > **Note sur le chat IA.** Ce site est volontairement **sans chat** (Option B). L'assistant > (Kiro) vit dans l'IDE : pendant l'atelier, les questions se posent dans l'IDE, les specs > y sont éditées, et le site reflète les changements. Le site **présente**, il ne discute pas. ## Architecture ``` site/ ├─ frontend/ Angular 22 (viewer : marked + DOMPurify + mermaid), servi par nginx ├─ backend/ API Node/Express : auth + /api/specs + /api/annotations + /api/users ├─ annotations/ Données d'annotations (1 JSON par document) — volume RW, non commité ├─ users/ Comptes gérés (users.json, mots de passe bcrypt) — volume RW, non commité ├─ docker-compose.yml ├─ Caddyfile.example (reverse-proxy HTTPS pour satpro.madjax.fr) ├─ .env.example (comptes + secret JWT — à copier en .env, NON commité) └─ .gitignore ``` Les specs ne sont **pas** copiées dans l'image : le dossier `../docs/specs-pre-projet` est monté **en lecture seule** (`:ro`) dans le conteneur backend sur `/specs`. Les annotations, elles, sont écrites dans `./annotations` (monté **en lecture-écriture** sur `/annotations`), donc persistées sur l'hôte et faciles à récupérer. ## Configuration (.env) ```bash cp .env.example .env ``` Puis éditez `.env` : | Variable | Rôle | |----------|------| | `JWT_SECRET` | Secret de signature des sessions (**obligatoire**, ≥ 32 caractères). Ex. `openssl rand -hex 32` | | `JWT_EXPIRATION_MINUTES` | Durée de session (défaut 720 = 12 h) | | `ADMIN_USER` | Login de l'**administrateur** unique (seul compte défini hors application). Ex. `madjax` | | `ADMIN_PASSWORD` | Mot de passe de l'administrateur. Ex. `Change-moi` | | `SEED_USERS` | *(facultatif)* Comptes amorcés au **premier** démarrage si le store est vide : `login:mdp:role,...` (`role` ∈ `consultation`/`contributeur`/`desactive`). Vide = amorçage par défaut intégré. Sans effet une fois `users/users.json` créé. | > Seul l'`ADMIN_USER` vit dans `.env`. **Tous les autres comptes** se créent et se gèrent > dans l'application (page **Gestion des accès**, accessible à l'admin) et sont persistés > dans `users/users.json` (mots de passe hachés bcrypt). ## Lancement en production (Docker) Depuis `site/` : ```bash docker compose up -d --build ``` - Le frontend (nginx) est publié sur le port **2002** de la machine Docker. - Le backend reste interne au réseau Compose (non publié). - Vérifier : `curl http://localhost:2002/health` → `{"statut":"ok"}`. ### Exposition HTTPS (Caddy) — satpro.madjax.fr ```bash cp Caddyfile.example Caddyfile # puis adapter l'IP de la machine Docker ``` Caddy termine le TLS (Let's Encrypt) et proxifie vers le port 2002. Voir les notes de sécurité réseau dans `Caddyfile.example` (filtrage du port 2002, réseau privé/VPN). Prérequis DNS : `satpro.madjax.fr` doit pointer vers la machine qui exécute Caddy. ## Développement local (sans Docker) ### Méthode recommandée : `run-dev.sh` Depuis `site/` : ```bash ./run-dev.sh ``` Le script : - charge `JWT_SECRET`, `ADMIN_USER`/`ADMIN_PASSWORD` et `SEED_USERS` depuis `.env` s'il existe (sinon : secret de dev aléatoire + admin par défaut `admin` / `admin`) ; - installe les dépendances si `node_modules` manque (back et front) ; - démarre le **backend** Node sur `:8080` (specs lues en direct dans `../docs/specs-pre-projet`) et le **frontend** Angular sur `:4200` ; - attend que le frontend soit réellement prêt (HTTP 200) avant d'afficher le récapitulatif ; - arrête proprement les deux processus à `Ctrl+C`. Ouvrir ensuite http://localhost:4200 (admin `admin` / `admin` par défaut en dev, ou les valeurs de `.env` ; les comptes amorcés devront changer leur mot de passe à la 1re connexion). ### Méthode manuelle (deux terminaux) ```bash # 1) Backend (port 8080) cd backend npm install JWT_SECRET="dev-secret-32-caracteres-minimum-ok" \ ADMIN_USER="admin" ADMIN_PASSWORD="admin" \ npm start # 2) Frontend (port 4200, proxy vers :8080 via environment.ts) cd frontend npm install npm start ``` ## Ajouter / modifier un document 1. Créez ou éditez un fichier dans `../docs/specs-pre-projet/` (ex. `14-annexes.md`). 2. Le **menu se met à jour automatiquement** : les fichiers `.md` sont listés par ordre de nom (préfixes `00`, `01`, …) et le titre est tiré du premier titre `#` du fichier. 3. En séance : cliquez **Rafraîchir** (ou rechargez la page) pour voir la dernière version. ## Gestion des accès (administrateur) L'administrateur (défini dans `.env`) dispose d'un bouton **Gestion des accès** dans l'en-tête. Cette page permet de : - **Créer un compte** : login + mot de passe par défaut + rôle. Le compte devra **changer son mot de passe à la première connexion**. - **Changer le rôle** d'un compte : - **Consultation** — lecture seule (consulte les specs et les annotations, ne peut pas annoter) ; - **Contributeur** — peut annoter (créer / éditer / supprimer ses propres annotations) ; - **Désactivé** — connexion refusée (idéal pour couper un accès entre deux ateliers sans le supprimer). - **Réinitialiser le mot de passe** d'un compte (si l'utilisateur l'a oublié) : un nouveau mot de passe par défaut est fixé et le changement est de nouveau imposé à la connexion suivante. - **Supprimer** un compte (pour un usage entre ateliers, préférez **Désactivé**). Les changements de rôle et les désactivations prennent effet **immédiatement**, sans que l'utilisateur ait à se reconnecter. Les comptes sont persistés dans `users/users.json` (mots de passe hachés bcrypt) et conservés entre les ateliers. > L'administrateur n'apparaît pas dans cette liste : il se configure uniquement dans `.env` > (`ADMIN_USER` / `ADMIN_PASSWORD`). ## Annotations (retours des utilisateurs) Pendant l'atelier, chaque utilisateur **contributeur** (ou l'admin) peut annoter les specs (un compte en **consultation** voit les annotations mais ne peut pas en ajouter) : 1. Dans un document, survoler un titre de section fait apparaître un bouton **💬**. Cliquer dessus ouvre le panneau d'annotation avec la section préremplie. 2. Choisir un **type** (remarque / ajout / correction / question), saisir le texte, **Ajouter**. 3. Le bouton **💬 Annotations** (barre du haut) ouvre/ferme le panneau latéral qui liste toutes les annotations du document. Un badge indique le nombre d'annotations **ouvertes**. 4. Chaque utilisateur peut **éditer / supprimer ses propres** annotations et basculer leur statut (ouverte ↔ traitée). Un **administrateur** (`ADMIN_USERS`) peut gérer **toutes** les annotations. ### Stockage - Un fichier JSON par document dans `site/annotations/` (ex. `06-prestations.json`). - Persisté sur l'hôte (volume Docker RW). Les `.json` ne sont pas commités (`.gitignore`). ### Export et transmission (admin) Dans le panneau d'annotations, un administrateur dispose de deux exports : - **Markdown** (`annotations-satpro.md`) : synthèse lisible, regroupée par document puis par section — c'est le format à **transmettre à Kiro** pour mettre à jour les `.md`. - **JSON** (`annotations-satpro.json`) : données brutes. Alternative sans l'UI : récupérer directement les fichiers de `site/annotations/*.json` sur le serveur (ils constituent la source complète des retours). Le flux de bout en bout : *les utilisateurs annotent → l'admin exporte le Markdown → vous me le transmettez → je mets à jour les fichiers de `docs/specs-pre-projet/`.* ## Déploiement par archive (tar) Le `docker-compose.yml` monte `../docs/specs-pre-projet` : l'archive doit donc contenir **`site/` ET `docs/specs-pre-projet/`** avec la même arborescence relative. On se place à la racine `DEKRA/SatPRO` : ```bash cd /home/madjax/KiroProject/DEKRA/SatPRO tar czf satpro-site.tar.gz \ --exclude='site/frontend/node_modules' \ --exclude='site/backend/node_modules' \ --exclude='site/frontend/dist' \ --exclude='site/frontend/.angular' \ --exclude='site/.env' \ --exclude='site/annotations/*.json' \ --exclude='site/users/*.json' \ site docs/specs-pre-projet ``` > On exclut `site/.env` (identifiants) — à recréer sur le serveur — et les annotations > `*.json` (données d'exécution). Le dossier `site/annotations/` reste inclus (via `.gitkeep`) > pour que le volume RW ait son point de montage. Côté serveur : ```bash scp satpro-site.tar.gz user@serveur:/chemin/cible/ # puis sur le serveur : cd /chemin/cible && tar xzf satpro-site.tar.gz cd site cp .env.example .env # renseigner JWT_SECRET, ADMIN_USER, ADMIN_PASSWORD docker compose up -d --build ``` Le site répond sur le port **2002**, prêt à être exposé en HTTPS via Caddy. > Mise à jour ultérieure des specs sur le serveur : recopier `docs/specs-pre-projet/` > (pas besoin de rebuilder). Les annotations existantes dans `site/annotations/` sont conservées. ## Points de sécurité - `.env` n'est **jamais** commité (`.gitignore`). - Le backend refuse de démarrer sans `JWT_SECRET` (≥ 32 caractères) ni comptes. - Les specs sont montées **en lecture seule** : le site ne peut pas modifier les fichiers. - Les annotations sont écrites dans un volume **séparé** (`/annotations`), jamais dans les specs. - Protection contre la traversée de répertoire sur `/api/specs/:cle` et `/api/annotations/:cle`. - Modification/suppression d'une annotation réservée à son **auteur** ou à un **admin** ; export global réservé aux **admins**. - Contenu non indexable (robots.txt + meta + `X-Robots-Tag`) **et** protégé par login. ## Vérifications effectuées - Build frontend production : OK (`dist/satpro-specs-frontend/browser`). - Backend : `/health`, login multi-comptes (succès/échec), liste des 14 documents, lecture de contenu en direct, en-tête `X-Robots-Tag`, blocage de la traversée de répertoire. - Annotations : création, édition (auteur), bascule de statut, suppression, droits auteur/admin, export Markdown et JSON (réservé admin, `403` sinon). - Gestion des accès : admin unique via `.env`, comptes gérés en JSON (bcrypt), rôles consultation/contributeur/désactivé appliqués côté serveur, changement de mot de passe imposé à la 1re connexion et après réinitialisation, effet immédiat des changements de rôle. - `docker compose config` : port publié `2002`, montages `../docs/specs-pre-projet` → `/specs` (ro), `./annotations` → `/annotations` (rw) et `./users` → `/users` (rw), `ADMIN_USER` injecté.