Paillasse/CLAUDE.md

241 lines
15 KiB
Markdown
Raw Permalink Normal View History

# 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.