249 lines
12 KiB
Markdown
249 lines
12 KiB
Markdown
# 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 `<meta robots>`, 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é.
|