Initial commit — specs pré-projet SatPRO + site de présentation (viewer, annotations, gestion des accès)
This commit is contained in:
+248
@@ -0,0 +1,248 @@
|
||||
# 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é.
|
||||
Reference in New Issue
Block a user