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

15 KiB
Raw Blame 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.