docs: initialize plan.md and update CLAUDE.md after phase 1

plan.md:
- Phase 1 détaillée et cochée (backend, frontend, infra, décisions techniques)
- Phases 2 (Nmap/Celery), 3 (vulns/CVE), 4 (PDF/dashboard) planifiées avec tâches
- Prochaine étape : feature/phase-2-nmap

CLAUDE.md:
- Structure de dossiers mise à jour (route groups, lib, core)
- Commandes corrigées (uvicorn backend.main:app, alembic depuis racine)
- Conventions Phase 1 : imports backend.xxx, Pydantic v2, PATCH pattern,
  selectinload, TimestampMixin, guard auth frontend, camelCase types TS
- Pièges à éviter documentés

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-21 17:24:47 +01:00
parent 0fe1a1b751
commit 2df14dcc73
2 changed files with 288 additions and 14 deletions

View File

@@ -15,17 +15,33 @@ Outil d'audit infrastructure et sécurité pour clients MSP. Permet de lancer de
## Structure
```
frontend/
app/ # Next.js App Router
components/ # Composants réutilisables
lib/ # Utilitaires, API client
app/
(auth)/login/ # Page login (pas de layout dashboard)
(dashboard)/ # Pages protégées avec sidebar
layout.tsx # Guard auth + layout sidebar+main
dashboard/ # Stats globales
clients/ # CRUD clients
audits/ # CRUD audits
components/
layout/ # Sidebar, Header
ui/ # shadcn/ui : Button, Card, Input, Badge, Label
lib/
api.ts # Client fetch typé (authApi, clientsApi, auditsApi)
auth.ts # Helpers JWT localStorage
utils.ts # cn() (tailwind-merge + clsx)
backend/
api/ # Routes FastAPI
scanners/ # Orchestration Nmap, OpenVAS, Metasploit, AD
models/ # Modèles SQLAlchemy
reports/ # Génération PDF
api/ # Routes FastAPI (auth, clients, audits)
core/ # config.py, database.py, security.py
models/ # SQLAlchemy ORM (base.py + TimestampMixin)
schemas/ # Pydantic v2 (séparés des modèles)
scanners/ # Placeholder Phase 2 (Nmap, OpenVAS...)
reports/ # Placeholder Phase 4 (WeasyPrint PDF)
tests/ # pytest async avec SQLite in-memory
alembic/ # Migrations (env.py configuré)
main.py # App FastAPI : CORS, rate limiting, routers
docker/
docker-compose.yml
docker-compose.prod.yml
docker-compose.yml # Dev : postgres, redis, backend, frontend
docker-compose.prod.yml # Prod : images registry + labels Traefik
```
## Commandes
@@ -33,17 +49,23 @@ docker/
# Frontend
cd frontend && npm install && npm run dev
# Backend
cd backend && pip install -r requirements.txt && uvicorn main:app --reload
# Backend (lancer depuis la racine du projet, pas depuis backend/)
pip install -r backend/requirements.txt
uvicorn backend.main:app --reload
# Docker complet
docker compose -f docker/docker-compose.yml up -d
# Migrations BDD
cd backend && alembic upgrade head
# Migrations BDD (depuis la racine, pas depuis backend/)
alembic -c backend/alembic.ini upgrade head
# Créer une migration :
alembic -c backend/alembic.ini revision --autogenerate -m "description"
# Tests
pytest backend/tests/
# Typecheck frontend
cd frontend && npm run typecheck
```
## Modèle de données
@@ -77,8 +99,49 @@ Gitea Actions → Docker → NAS ou VPS selon le client
Voir @docker/docker-compose.yml et @.gitea/workflows/deploy.yml
## Ce que Claude doit savoir sur CE projet
### Domaine métier
- Les scans sont des opérations longues → utiliser des jobs asynchrones (Celery ou BackgroundTasks FastAPI)
- Le rapport PDF doit être compréhensible par un dirigeant non-technique
- Toujours traduire les CVE en langage clair dans les rapports
- La BDD utilise snake_case, le frontend TypeScript utilise camelCase
- Les criticités : critique (CVSS 9-10), important (7-8.9), modéré (4-6.9), faible (0-3.9)
- Un scan ne peut se lancer que sur des cibles dont `validee = True` (sécurité obligatoire)
### Conventions de code établies en Phase 1
**Backend :**
- Imports toujours en `backend.xxx` (ex: `from backend.models.user import User`), jamais en relatif — le module s'appelle `backend`
- Uvicorn se lance avec `uvicorn backend.main:app`, pas `uvicorn main:app`
- Alembic se lance depuis la racine avec `-c backend/alembic.ini`
- Les enums Python sont aussi `str` (`class Criticite(str, enum.Enum)`) pour sérialisation JSON automatique
- Pydantic v2 : utiliser `model_dump()` (pas `.dict()`), `model_config = {"from_attributes": True}` (pas `orm_mode`)
- Pattern PATCH : `payload.model_dump(exclude_unset=True)` pour ne pas écraser les champs non fournis
- `get_current_user` est une dépendance FastAPI — toujours l'injecter sur les routes protégées
- `selectinload()` pour les relations dans les endpoints "detail" (évite le N+1)
- `TimestampMixin` à hériter sur tous les nouveaux modèles
- `pool_pre_ping=True` sur l'engine SQLAlchemy pour les connexions longues durée
**Frontend :**
- Les types TypeScript sont en camelCase même si l'API renvoie du snake_case (mapping à faire côté fetch)
- `"use client"` obligatoire sur toutes les pages/composants utilisant des hooks React ou des effets
- Guard auth dans `(dashboard)/layout.tsx` via `useEffect` + `getToken()` — pas de middleware Next.js
- Le client API (`lib/api.ts`) passe toujours le token en paramètre explicite — pas de contexte global
- Les nouvelles pages du dashboard vont dans `app/(dashboard)/[section]/page.tsx`
- Les nouveaux composants UI shadcn vont dans `components/ui/`, les composants métier dans `components/`
- Les rewrites `next.config.ts` proxifient `/api/*` vers le backend — en dev, définir `NEXT_PUBLIC_API_URL=http://localhost:8000`
- JWT stocké dans localStorage (simple pour MVP, à migrer vers HttpOnly cookie plus tard)
**Infrastructure :**
- Le service `backend` dans docker-compose dépend de `postgres` avec `condition: service_healthy`
- Le build frontend Next.js utilise `output: "standalone"` → le Dockerfile copie `.next/standalone`
- Les variables d'env préfixées `NEXT_PUBLIC_` sont embarquées au build (pas au runtime)
- `docker-compose.prod.yml` attend des images pré-buildées depuis `${REGISTRY}` — pas de build local
### Pièges à éviter
- Ne pas lancer `uvicorn main:app` depuis `backend/` — toujours depuis la racine avec le module complet
- Ne pas oublier `"use client"` sur les pages avec `useEffect`, `useState`, `useRouter`
- Ne pas utiliser `.dict()` Pydantic v1 — c'est `.model_dump()` en v2
- Ne pas faire de scans sans vérifier `cible.validee == True` côté backend
- Ne pas commiter `.env` — seulement `.env.example`
- Alembic `env.py` importe les modèles depuis `backend.models` — ajouter tout nouveau modèle dans `backend/models/__init__.py`

211
plan.md Normal file
View File

@@ -0,0 +1,211 @@
# AuditShield — Plan de développement
## Vue d'ensemble
Outil d'audit infrastructure et sécurité pour clients MSP.
Scans réseau + vulnérabilités + pentest → rapports PDF compréhensibles pour non-techniciens.
---
## ✅ Phase 1 — Socle (terminée)
> Branche : `feature/phase-1-socle` → mergée dans `dev`
### Ce qui a été créé
**Backend (FastAPI + SQLAlchemy)**
- `backend/core/` — config (pydantic-settings), database (SQLAlchemy 2.0), security (JWT + bcrypt)
- `backend/models/` — 7 modèles : User, Client, Audit, Cible, Vulnérabilité, Action + TimestampMixin
- `backend/schemas/` — Pydantic v2 : UserCreate/Read, ClientCreate/Update/Read, AuditCreate/Update/Read/Detail, CibleCreate/Read, VulnerabiliteCreate/Read, ActionCreate/Update/Read
- `backend/api/auth.py` — POST /register, POST /login (OAuth2), GET /me
- `backend/api/clients.py` — CRUD complet (GET list, POST, GET/{id}, PATCH/{id}, DELETE/{id})
- `backend/api/audits.py` — CRUD audit + nested : cibles (add/valider), vulnérabilités (add), actions (add/update)
- `backend/main.py` — FastAPI app, CORS (localhost:3000), rate limiting (slowapi), docs /api/docs en DEBUG
- `backend/alembic/` — migrations configurées (env.py prêt avec models importés)
- `backend/tests/test_auth.py` — test async register + login avec SQLite in-memory
**Frontend (Next.js 14 App Router)**
- Route groups : `(auth)` pour login, `(dashboard)` pour pages protégées
- `app/(auth)/login/page.tsx` — formulaire login avec gestion JWT
- `app/(dashboard)/layout.tsx` — guard auth (redirect /login), layout sidebar + main
- `app/(dashboard)/dashboard/page.tsx` — 4 stat cards + 5 audits récents
- `app/(dashboard)/clients/page.tsx` — grille clients avec recherche
- `app/(dashboard)/audits/page.tsx` — liste audits avec badges statut + recherche
- `components/layout/sidebar.tsx` — navigation (Dashboard, Clients, Audits) + déconnexion
- `components/ui/` — Button (CVA variants), Card, Input, Label, Badge (+ variantes criticité)
- `lib/api.ts` — client fetch générique typé : authApi, clientsApi, auditsApi
- `lib/auth.ts` — helpers localStorage pour token JWT
**Infrastructure**
- `docker/docker-compose.yml` — 4 services : postgres:16, redis:7, backend, frontend
- `docker/docker-compose.prod.yml` — images registry + labels Traefik + Let's Encrypt
- `backend/Dockerfile` — Python 3.11-slim + WeasyPrint deps + alembic upgrade
- `frontend/Dockerfile` — multi-stage Node 20 (deps → builder → runner standalone)
- `.env.example` — toutes les variables documentées
### Décisions techniques
| Décision | Raison |
|----------|--------|
| SQLAlchemy 2.0 avec type hints Mapped[] | API moderne, meilleure inference TypeScript équivalente côté Python |
| Pydantic v2 séparé des modèles ORM | Découplage validation/persistance, évite circular imports |
| JWT HS256 + 24h expiration | Simple à implémenter, stateless, suffisant pour MVP |
| slowapi pour rate limiting | Compatible FastAPI/Starlette, minimal |
| TimestampMixin | DRY pour created_at/updated_at sur tous les modèles |
| Cascade delete | Intégrité référentielle (supprimer client → supprime tout) |
| Celery + Redis (infra seulement) | Prêt pour les jobs asynchrones de scan (Phase 2) |
| Next.js App Router + route groups | Layouts différents auth/dashboard sans duplication |
| shadcn/ui + Radix | Accessibilité, composants non-opinionnés, facilement personnalisables |
| JWT dans localStorage | Simple pour MVP — à migrer vers HttpOnly cookie en Phase 3 |
| camelCase pour types TS, snake_case en DB | Convention JS vs convention Python/SQL |
| Rewrites next.config.ts vers backend | Pas de CORS en prod, tout passe par Next.js |
### État fonctionnel
- ✅ Register/Login utilisateur avec JWT
- ✅ CRUD clients complet
- ✅ CRUD audits + cibles + vulnérabilités + actions
- ✅ Dashboard avec stats temps réel
- ✅ Pages liste clients et audits avec recherche
- ✅ Guard auth côté frontend
- ✅ Docker dev + prod prêt
- ⏳ Pages de formulaire (création/édition) non créées
- ⏳ Pages détail client et audit non créées
- ⏳ Scanners : dossier vide (placeholder Phase 2)
- ⏳ Génération PDF : dossier vide (placeholder Phase 4)
---
## 🔲 Phase 2 — Scanners réseau (Nmap)
> Branche : `feature/phase-2-nmap`
### Objectif
Permettre le lancement d'un scan Nmap sur des cibles validées, afficher les résultats en temps réel, et les persister en base.
### Tâches backend
- [ ] **Celery worker** — configurer `backend/celery_app.py`, worker Docker dans docker-compose
- [ ] **Scanner Nmap**`backend/scanners/nmap.py`
- Wrapper autour de `python-nmap`
- Parse les résultats : ports ouverts, services, OS
- Vérification que la cible est `validee = True` avant tout scan
- Log de chaque scan en BDD (model `ScanLog`)
- [ ] **Model ScanLog**`backend/models/scan_log.py`
- audit_id, cible_id, type_scan, statut, résultat (JSON), durée
- [ ] **Tâche Celery**`backend/scanners/tasks.py`
- `task_scan_nmap(audit_id, cible_ids)` — async, met à jour statut
- Retour des résultats via polling ou WebSocket
- [ ] **Routes scan**`backend/api/scans.py`
- `POST /audits/{audit_id}/scans/nmap` — lance le scan (en background)
- `GET /audits/{audit_id}/scans` — liste les scans passés
- `GET /audits/{audit_id}/scans/{scan_id}` — détail d'un scan
- [ ] **Parsing Nmap → Vulnérabilités** — déduire des vulnérabilités simples (ports dangereux, services obsolètes)
### Tâches frontend
- [ ] **Page détail audit**`app/(dashboard)/audits/[id]/page.tsx`
- Affiche : infos audit, liste cibles (avec bouton "Valider"), liste vulnérabilités, liste actions
- Bouton "Lancer un scan Nmap"
- Statut du scan en temps réel (polling GET /scans)
- [ ] **Page détail client**`app/(dashboard)/clients/[id]/page.tsx`
- Infos client + liste des audits du client
- Bouton "Nouvel audit"
- [ ] **Formulaire nouveau client**`app/(dashboard)/clients/nouveau/page.tsx`
- [ ] **Formulaire nouvel audit**`app/(dashboard)/audits/nouveau/page.tsx`
- [ ] **Formulaire ajout cible** — Modal ou inline dans détail audit
- [ ] **Composant ScanStatus** — affiche statut scan (en cours / terminé / erreur)
- [ ] **Toast notifications** — feedback utilisateur (succès, erreur)
### Tâches infra
- [ ] Ajouter service `worker` dans docker-compose (image backend + command: celery worker)
- [ ] Ajouter `python-nmap` dans requirements.txt
- [ ] Première migration Alembic : `alembic revision --autogenerate -m "init"`
---
## 🔲 Phase 3 — Vulnérabilités avancées + Actions
> Branche : `feature/phase-3-vulnerabilites`
### Objectif
Enrichissement des vulnérabilités avec CVE, scoring CVSS automatique, workflow de gestion des actions, et calcul du score global d'audit.
### Tâches backend
- [ ] **Intégration CVE/NVD**`backend/scanners/cve.py`
- Lookup CVE via NVD API (gratuit)
- Traduction automatique en langage clair (résumé simplifié)
- Auto-remplissage criticité depuis CVSS score
- [ ] **Calcul score global audit** — méthode sur le model Audit
- Pondération : critique × 4, important × 3, modéré × 2, faible × 1
- Normalisé sur 10, mis à jour à chaque vulnérabilité ajoutée
- [ ] **OpenVAS optionnel**`backend/scanners/openvas.py`
- Wrapper GVM (Greenbone Vulnerability Management)
- Si disponible, scan plus profond
- [ ] **Notifications** — model `Notification`, endpoint SSE ou WebSocket
- Alertes nouvelles vulnérabilités critiques
- Changements de statut d'action
### Tâches frontend
- [ ] **Page détail vulnérabilité**`app/(dashboard)/audits/[id]/vulnerabilites/[vulnId]/page.tsx`
- Affiche : titre, criticité (badge coloré), CVE, CVSS, description, recommandation
- Liste des actions liées + bouton "Ajouter une action"
- Formulaire d'action inline
- [ ] **Composant CriticiteBar** — représentation visuelle du score global
- [ ] **Page gestion des actions** — tableau kanban simple (Ouvert → En cours → Résolu)
- [ ] **Filtres et tri** — sur les listes de vulnérabilités (par criticité, statut)
- [ ] **Pagination** — composant `<Pagination>` réutilisable
---
## 🔲 Phase 4 — Rapports PDF + Dashboard avancé
> Branche : `feature/phase-4-rapports`
### Objectif
Génération de rapports PDF professionnels compréhensibles par un dirigeant non-technique, et dashboard enrichi avec graphiques.
### Tâches backend
- [ ] **Moteur PDF**`backend/reports/pdf.py`
- WeasyPrint + Jinja2 templates HTML
- Template rapport : page de garde, résumé exécutif, score global, vulnérabilités par criticité, recommandations, plan d'actions
- Langage client : pas de jargon technique, CVE traduits en langage clair
- [ ] **Templates HTML**`backend/reports/templates/`
- `rapport_audit.html` — template principal
- `_vulnerabilite.html` — bloc par vulnérabilité
- CSS intégré (compatible WeasyPrint)
- [ ] **Route export**`GET /audits/{audit_id}/rapport.pdf`
- Génère et streame le PDF
- Header `Content-Disposition: attachment`
- [ ] **Tâche Celery** — génération PDF asynchrone pour audits longs
### Tâches frontend
- [ ] **Bouton "Exporter PDF"** — dans la page détail audit
- [ ] **Dashboard avancé** — graphiques :
- Répartition vulnérabilités par criticité (donut chart)
- Évolution des audits dans le temps (line chart)
- Taux de résolution des actions (progress bar)
- Utiliser `recharts` ou `chart.js`
- [ ] **Page rapports**`app/(dashboard)/rapports/page.tsx`
- Liste des rapports générés, téléchargement
- [ ] **Mode impression** — CSS @media print pour la page détail audit
---
## Prochaine étape
```bash
git checkout dev
git checkout -b feature/phase-2-nmap
```
Commencer par :
1. Configurer Celery dans `docker-compose.yml` (service worker)
2. Créer `backend/models/scan_log.py`
3. Créer `backend/scanners/nmap.py`
4. Générer la première migration Alembic
5. Créer les pages frontend manquantes (détail audit, formulaires)