Paillasse/CLAUDE.md
2026-10-07 00:11:20 +02:00

240 lines
15 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# CLAUDE.md — Projet Paillasse
> Lis ce fichier en entier avant toute action. Il fait foi sur le contexte, les priorités, l'architecture, la sécurité et le style.
> Nom de travail : **Paillasse**. Porteur : Adam Belkacemi (Esquisse Formation).
---
## 1. Contexte et objectifs
**Paillasse** : une plateforme de labs Linux et réseau pour l'enseignement (lycée NSI, BTS SIO SISR, BTS CIEL, BUT R&T, titres pro TSSR). Chaque élève obtient une vraie VM Debian dans le navigateur, en moins de 5 secondes, sur un cloud **OpenStack** hébergé en Europe (Hetzner). Correction automatique par scripts. **Aucune IA dans le produit.**
Trois objectifs, dans cet ordre :
1. **Candidature Senior SRE / Cloud Engineer chez Infomaniak.** Pouvoir dire : « J'opère un cloud OpenStack en production pour des classes : voici mes métriques, ma dernière montée de version, mon dernier incident. »
2. **Candidature Backend Software Engineer (kDrive) chez Infomaniak**, en repli ou en parallèle. Pouvoir dire : « J'ai conçu une API Laravel documentée, performante (MariaDB, Redis), testée, avec stockage S3/Ceph. »
3. **Un produit professionnel** pour les établissements et organismes de formation.
Le choix de la pile (section 3) suit **la stack d'Infomaniak** : MariaDB, Laravel, Go, Redis, Grafana, ElasticSearch, S3/Ceph, WebDAV, Kubernetes. Chaque techno doit répondre à **un vrai besoin** de Paillasse, jamais être ajoutée « pour le CV ».
Cahier des charges complet : `docs/cahier-des-charges.md` (à exporter depuis l'artifact « Paillasse »).
### Règle d'or pour Claude
Adam doit **comprendre et pouvoir expliquer** tout ce qui est construit (il en parlera en entretien technique). Pour chaque étape :
- explique ce que tu vas faire et pourquoi, **avant** de le faire ;
- après, résume ce qui a changé et comment le vérifier ;
- propose à Adam de refaire lui-même les manipulations et le code clés ;
- ajoute une entrée dans `docs/journal.md` (date, ce qui a été fait, ce qui a cassé, ce qu'on a appris).
---
## 2. Priorités
Ne commence pas un bloc avant que le précédent soit terminé, sauf demande explicite d'Adam.
### Bloc A — Infra (poste SRE), semaines 1 à 8
| Semaine | Livrable | Critère de fin |
|---|---|---|
| 1 | Serveur dédié installé (Debian 13, RAID 1), durci, sauvegardé | SSH par clé seulement, pare-feu actif, `docs/runbooks/serveur.md` |
| 2 | OpenStack tout-en-un (Kolla-Ansible) fonctionnel | Une VM Debian créée, joignable en console série |
| 3 | Supervision hors du serveur (CX23) : Prometheus, **Grafana**, Uptime Kuma, alertes | Une alerte reçue lors d'une panne provoquée |
| 4 | Portail minimal **Laravel** : comptes, une classe, lancement d'un lab, console web (xterm.js) | Un élève test fait le lab « Premiers pas dans le shell » |
| 5 | Stock chaud de VM (files **Redis**) + correction automatique (agent invité QEMU) | Terminal ouvert en < 5 s (p95), vérification OK |
| 6 | Self-healing : VM figée relancée, stock reconstitué, service redémarré | Panne provoquée → réparée sans intervention, post-mortem écrit |
| 7 | Montée de version d'OpenStack documentée | Runbook + retour d'expérience |
| 8 | Pilote avec une vraie classe | Métriques réelles, retours des élèves et du prof |
### Bloc B — Backend (poste kDrive)
1. API publique Laravel versionnée (`/api/v1`), documentée en OpenAPI, tests Pest, jetons Sanctum, quotas et limites de débit dans Redis.
2. Cache Redis sur les lectures lourdes (catalogue, tableau de bord prof) ; mesure avant/après dans Grafana.
3. Optimisation MariaDB : index, `EXPLAIN`, requêtes N+1 supprimées, jeu de données de charge (ex. 500 classes, 20 000 élèves).
4. Stockage des travaux d'élèves et des rendus sur **S3** (Hetzner Object Storage), avec versioning.
### Bloc C — Plus tard
- **Ceph** comme stockage d'OpenStack (Glance, Cinder) : démo mono-serveur d'abord, vrai cluster au 2ᵉ serveur.
- **WebDAV** : dossier de l'élève montable comme lecteur réseau.
- **ElasticSearch** : recherche plein texte dans les cours et labs (seulement si le besoin est réel).
- 2ᵉ serveur, passage à **OCI** (Debian + Puppet), haute disponibilité (Galera, Ceph), **Kubernetes** pour le portail.
- MCP pour développeurs (voir section 6).
---
## 3. Architecture
```
Navigateurs (élèves, profs) Développeurs (API, MCP)
│ HTTPS 443 uniquement (réseaux scolaires filtrés)
▼
Hetzner Cloud CX23 ── Caddy (TLS) ── Front (Inertia + React) ── Laravel (API + portail)
│ MariaDB · Redis (cache, files, sessions, quotas)
│ Workers Laravel Horizon : stock chaud, ordonnanceur
│ Proxy console WebSocket (Go)
│ Prometheus · Grafana · Uptime Kuma (page de statut)
│ API OpenStack (TLS, IP du CX23 autorisée seulement)
▼
Serveur dédié Server Auction : i7-6700, 64 Go, 2 × 500 Go SSD RAID 1, Debian 13
OpenStack Kolla-Ansible tout-en-un : Keystone, Nova, Neutron (OVN), Glance, Cinder (LVM, puis Ceph),
Placement, Heat, nova-serialproxy
Un projet par établissement · un réseau par classe · pas d'IP publique par VM (NAT)
Filtrage sortant : seuls les miroirs de paquets (cache apt) sont joignables
▼
Hetzner Object Storage (S3) : travaux d'élèves, sauvegardes MariaDB, config, images
```
### Choix techniques (à respecter)
- **Console élève** : console série Nova (`nova-serialproxy`), relayée par un petit **proxy WebSocket en Go**, affichée avec **xterm.js**. Elle doit marcher même si l'élève casse le réseau de sa VM.
- **Correction** : service sur l'hyperviseur qui exécute les vérifications via **l'agent invité QEMU** (`hw_qemu_guest_agent=yes`). Pas de réseau vers la VM.
- **Topologies** : chaque lab est un **modèle Heat**.
- **Stock chaud** : N VM démarrées en permanence, gérées par des jobs Laravel dans Redis ; taille ≈ lancements/min × 45 s + marge (8 au départ). Les séances réservées pré-créent les VM 10 min avant.
- **Capacité** : ~56 VM de 768 Mo sur 64 Go (à mesurer). Refuser proprement une réservation qui dépasse.
- **Gros labs réseau** : Kathará (routeurs en conteneurs dans une seule VM).
- **Pas de Windows** avant d'avoir étudié les licences (SPLA). Utiliser Samba AD.
- **Octavia, Magnum** : pas avant le deuxième serveur.
### Pile logicielle
| Couche | Choix |
|---|---|
| Backend | PHP 8.3+, **Laravel** (Sanctum, Horizon, Pest), **MariaDB**, **Redis**, client OpenStack (API REST ou `php-opencloud/openstack`) |
| Front | Inertia.js + React + TypeScript, Tailwind CSS, shadcn/ui, Radix |
| Services en Go | Proxy console WebSocket ; correcteur sur l'hyperviseur (Go ou Python, au choix d'Adam) |
| Consoles | xterm.js (texte), noVNC (graphique, plus tard) |
| Stockage | Hetzner Object Storage (S3) ; Ceph au bloc C |
| LTI Moodle (V2) | `packbackbooks/lti-1p3-tool` |
| SSO ENT (V3) | Keycloak |
| Infra as code | Ansible, Kolla-Ansible puis OCI/Puppet, Heat, Terraform pour Hetzner Cloud |
| Supervision | Prometheus, **Grafana**, Uptime Kuma, Alertmanager ; métriques Laravel (temps de réponse, files Redis) |
| Sauvegardes | restic vers Object Storage, restauration testée chaque semaine |
| CI | **Forgejo Actions** (syntaxe proche de GitLab CI / GitHub Actions) |
| Tests | Pest, Playwright (parcours), axe-core (accessibilité) |
---
## 4. Sécurité : règles non négociables
1. **Secrets** : jamais dans le code, jamais dans Git, jamais affichés en clair. Fichier `.env` (dans `.gitignore`) ou gestionnaire de secrets. Ne demande jamais à Adam de coller un secret dans la conversation.
2. **Clé SSH dédiée** à Claude Code (`~/.ssh/paillasse_claude`), révocable. Jamais la clé personnelle d'Adam.
3. **Projet Hetzner séparé** pour Paillasse, jetons d'API aux droits minimaux. **Ne touche jamais au serveur `tripoli-cloud`** ni à ses ressources.
4. **Avant toute commande destructrice** (`installimage`, `rm -rf`, `mkfs`, suppression de ressource, `DROP`, `migrate:fresh`, réinstallation, pare-feu, routes) : explique, montre la commande exacte, vérifie la sauvegarde, **attends la confirmation explicite d'Adam**.
5. **Ne jamais te couper l'accès** : avant de modifier SSH ou le pare-feu, garde une session ouverte et prévois le retour arrière (mode rescue Hetzner).
6. **Commandes et dépenses** : jamais par Claude. Adam commande à la main.
7. **Données d'élèves** : minimisation (nom, prénom, groupe), pas d'e-mail pour les mineurs, suppression automatique 90 jours après l'archivage de fin d'année.
8. **Anti-abus** : trafic sortant des VM bloqué par défaut, quotas CPU/RAM/durée, journaux.
9. **API** : jetons hachés, droits par jeton, limites de débit, en-têtes de sécurité, validation stricte des entrées (cf. « API hardening » demandé par Infomaniak).
10. **Pas de `--dangerously-skip-permissions`** sur une machine qui touche aux serveurs.
---
## 5. Code source et dépôt
- **Forge privée Forgejo** sur le serveur d'Adam. **Aucun dépôt public** (pas de GitHub public). Le code n'est montré à un recruteur que s'il le demande.
- Licence des contenus pédagogiques : **au choix d'Adam** (à décider plus tard). Ne pas écrire de mention de licence sans son accord.
```
paillasse/
├── CLAUDE.md
├── docs/
│ ├── cahier-des-charges.md
│ ├── journal.md # journal d'apprentissage et de bord
│ ├── runbooks/ # une procédure par opération (install, upgrade, restauration…)
│ ├── postmortems/ # AAAA-MM-JJ-titre.md
│ └── adr/ # 0001-kolla-avant-oci.md, 0002-laravel-plutot-que-fastapi.md…
├── infra/
│ ├── ansible/ kolla/ heat/ images/ terraform/
├── app/ # Laravel (API + portail + front Inertia/React)
├── console-proxy/ # Go
├── grader/ # service de correction sur l'hyperviseur
├── labs/ # consignes (Markdown), vérifications, indices (format YAML du pack de contenus)
└── ops/ # supervision, alertes, tableaux de bord Grafana
```
### Conventions
- Commits en français, courts, au présent : « ajoute le stock chaud de VM ».
- Une branche par fonctionnalité, fusion après tests et relecture.
- Chaque décision structurante → un ADR. Chaque incident réel ou provoqué → un post-mortem.
- Code PHP : PSR-12, types stricts, Laravel Pint, PHPStan (Larastan) niveau 6 minimum.
- Textes de l'interface en français, du point de vue de l'utilisateur (« Lancer le lab », pas « Provisionner l'instance »).
---
## 6. Produit : points clés (détails dans le cahier des charges)
- **Rôles** : administrateur d'établissement, enseignant, élève, formateur, opérateur.
- **5 façons d'ajouter des élèves** : code ou QR de classe (validation par le prof), import CSV, saisie rapide, invitation e-mail (V2), Moodle LTI 1.3 (V2).
- **Élèves mineurs** : identifiant + code secret imprimés sur une fiche de connexion (PDF, QR à usage unique).
- **Espace de lab** : consignes à gauche, consoles au centre (un onglet par VM), topologie + vérification + indices à droite, bouton « Lever la main ».
- **Séance en direct** : tuiles par élève (étape, bloqué > 8 min, main levée), lecture et prise de main de la console, mode examen.
- **Bibliothèque** : séquences cours + TD + quiz + lab, reliées aux référentiels, « Dupliquer et adapter ». Refuser à l'import tout contenu « non commercial » (NC). Quiz en GIFT / Moodle XML.
- **Cours texte gratuits** (Linux, réseau), pratique sur VM payante.
- **API payante et MCP** : un seul cœur d'API, trois portes (site, API, MCP). Quotas par jeton dans Redis. Les classes restent prioritaires sur la capacité.
- **Tout passe par le port 443** et doit marcher sur de vieux PC, Chromebooks et connexions lentes.
---
## 7. Design : beaucoup de style, sans sacrifier la clarté
### Direction artistique
- **Idée** : la paillasse de labo et l'établi d'atelier. Précis, technique, chaleureux. Pas le look « SaaS générique ».
- **Typographies** : Bricolage Grotesque (titres, avec retenue), IBM Plex Sans (texte), IBM Plex Mono (terminal, chiffres, identifiants).
- **Palette de départ** (jetons CSS, thèmes clair et sombre) :
- encre `#13233A` · vert paillasse `#2F5D50` · ambre `#C98404` · fond `#F4F6F2`
- sémantique : succès `#3C8A5A`, alerte ambre, erreur `#A63D2A`
- **Le terminal est le héros** : couleurs, curseur, police mono soignés.
- **Deux registres** : pages vitrines expressives (effet wow) ; application sobre, dense, lisible.
- **Mouvement** : quelques moments orchestrés, jamais gratuits, respecter `prefers-reduced-motion`.
- **À éviter** : dégradé violet-bleu, emojis comme icônes, tout centré, ombres et arrondis identiques partout.
### Source de vérité : Figma
- Les jetons (couleurs, typo, espacements, rayons) sont définis en **variables Figma**, puis reportés dans `app/resources/css/tokens.css`.
- Les écrans clés sont maquettés dans Figma **avant** d'être codés. Claude lit les maquettes via le **MCP Figma** et reprend les jetons et composants existants ; il ne réinvente pas un style.
### Accessibilité (obligatoire : clients publics)
- Contraste AA, navigation au clavier, focus visible, libellés sur tous les champs.
- Tests axe-core dans la CI ; parcours clés vérifiés avec Playwright. Référence : RGAA.
### Outils de design pour Claude Code
Vérifier chaque commande dans la documentation officielle avant de la lancer.
| Outil | Rôle | Installation (à vérifier) |
|---|---|---|
| Figma MCP | Lire les maquettes et variables Figma | `claude mcp add --transport http figma https://mcp.figma.com/mcp` |
| frontend-design (Anthropic) | Direction esthétique | dépôt `anthropics/skills` |
| taste-skill | Variété, mouvement, densité | `npx skills add https://github.com/Leonxlnx/taste-skill --skill "design-taste-frontend"` |
| UI/UX Pro Max | Styles, polices, ergonomie | dépôt `nextlevelbuilder/ui-ux-pro-max-skill` |
| 21st.dev Magic MCP | Composants React pour les pages vitrines | voir `21st.dev/mcp` |
| shadcn MCP | Composants shadcn/ui | documentation shadcn |
| Playwright MCP | Voir et tester les écrans | `claude mcp add playwright npx @playwright/mcp@latest` |
| Context7 | Documentation à jour (Laravel, OpenStack…) | dépôt `upstash/context7` |
**Avant d'installer un skill** : lire son `SKILL.md`.
### Méthode
1. Jetons d'abord, puis une page `/design` qui montre tous les composants.
2. Base de l'application : shadcn/ui restylé avec nos jetons.
3. 21st.dev surtout pour les pages vitrines, chaque composant adapté aux jetons.
4. Après chaque écran : capture Playwright, comparaison avec la maquette Figma, test axe-core.
---
## 8. Ce que Claude ne doit pas faire
- Ajouter de l'IA dans le produit.
- Ajouter une techno sans besoin réel dans Paillasse.
- Commander, supprimer ou modifier des ressources payantes sans accord explicite.
- Toucher à `tripoli-cloud`.
- Publier du code ou créer un dépôt public.
- Réutiliser des contenus sous licence NC dans le catalogue.
- Intégrer une bibliothèque GPL/AGPL côté service sans signaler la question de licence.
- Commencer un bloc avant la fin du précédent (section 2), sauf demande explicite d'Adam.
- Faire à la place d'Adam une étape qu'il veut apprendre : dans le doute, demande.