commit 8e44b2f33581d0fdb606da4963d578c1b130d498 Author: Gilles Soulier Date: Fri May 22 07:57:09 2026 +0200 Initial commit: CLAUDE.md + spec de design Nanometrics Co-Authored-By: Claude Sonnet 4.6 diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 0000000..6f1ab06 --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,166 @@ +# CLAUDE.md + +This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. + +> **Langue** : réponds toujours en français. + +--- + +## Skills et outils à utiliser + +Toujours utiliser les skills appropriés avant d'agir : + +- **brainstorming** — avant toute création de feature, composant ou choix d'architecture +- **writing-plans / executing-plans** — pour toute tâche multi-étapes, planifier avant de coder +- **test-driven-development** — avant d'écrire le code d'implémentation +- **systematic-debugging** — avant de proposer un fix sur un bug ou test qui échoue +- **WebSearch** — rechercher la doc, les crates Rust, les packages Go, les conventions +- **verification-before-completion** — vérifier que ça fonctionne réellement avant de déclarer terminé +- utiliser rtk pour reduire la consommation de token +--- + +## Vue d'ensemble du projet + +**Nanometrics** — système client-serveur de surveillance matérielle (CPU, RAM, disque) avec empreinte quasi nulle sur les machines Debian. + +Trois composants : +- **Agent Rust** (`agent/`) — collecte les métriques, envoie via UDP et/ou MQTT +- **Serveur Go** (`server/`) — reçoit les données, expose `/metrics` Prometheus + API REST + WebSocket +- **Dashboard web** (`dashboard/`) — UI servi par Nginx dans Docker, temps réel via WebSocket + +Un `README.md` doit être écrit à la racine : installation de l'agent et du serveur, liste des features. + +## Métriques collectées + +Métriques actuelles : `hostname`, `ip`, `memory_free`, `memory_used`, `hdd_total`, `hdd_free`, `hdd_used`, `cpu_percent`, `status` (online/offline), `uptime`. + +L'agent a une **architecture modulaire** : chaque métrique est un module indépendant activable/désactivable via config. Ajouter une métrique = ajouter un module sans toucher au cœur. + +## Commandes de build + +```bash +# Agent Rust +rtk cargo build --release --manifest-path agent/Cargo.toml +rtk cargo test --manifest-path agent/Cargo.toml +rtk cargo clippy --manifest-path agent/Cargo.toml + +# Serveur Go +rtk go test ./server/... +``` + +## Agent Rust — contraintes non négociables + +- **Pas de runtime async** (pas de Tokio). Boucle mono-thread avec `std::thread::sleep` pour les fréquences différenciées (CPU 2s, réseau/uptime 10s, disque 60s). +- **sysinfo avec `default-features = false`** — empêche les threads de fond qui gonflent la RAM. +- **Profil release** : `strip = true`, `opt-level = "z"`, `lto = true`. +- **Config via `config.toml`** (serde) — paramètres serveur, métriques activées, protocoles. Rien de codé en dur. +- **Deux protocoles supportables simultanément** : + - `UDP` — fire-and-forget JSON vers `server_ip:server_port` + - `MQTT` — bidirectionnel vers broker `mqtt_host:mqtt_port` (défaut 10.0.0.3:1883, sans auth) +- **Échange de config au démarrage** : à la connexion, l'agent envoie un message "birth" et récupère sa config depuis le serveur (push/pull bidirectionnel). Le serveur peut envoyer une nouvelle config à l'agent à tout moment. +- **Architecture future** : prévoir un canal de réception de commandes (reboot, shutdown, screen off, update, upgrade, shell cmd…) sans refonte du cœur. + +### MQTT — options de l'agent + +- **Auto-discovery** : publication du topic de découverte compatible Home Assistant +- **Birth message** : publié à la connexion sur `{topic_base}/{hostname}/status` = `online` +- **Last Will message** : configuré au connect, publié automatiquement par le broker si l'agent disparaît = `offline` +- **Topic base** configurable (défaut : `nanometrics/agents`) + +## Serveur Go — contraintes non négociables + +- Déployé dans **Docker** — `docker-compose.yml` fourni avec Nginx pour le dashboard. +- Goroutine par datagramme UDP reçu pour la désérialisation JSON. +- Écoute MQTT en parallèle (subscribe sur `{topic_base}/#`). +- Métriques exposées via `github.com/prometheus/client_golang` (Gauges) sur `/metrics`. +- **API REST** — endpoints pour le dashboard : agents, métriques, historique, config agents, icônes. +- **WebSocket** — push temps réel vers le dashboard (mise à jour des métriques et changements de statut). +- **SQLite** — persistance des métriques historiques avec rétention configurable. +- **Config agent** : le serveur stocke la config de chaque agent (métriques actives, protocoles, options MQTT). Envoyée à l'agent au birth et pushée si modifiée depuis le dashboard. + +## Déploiement systemd (agent) + +Le fichier `.service` doit utiliser : +- `DynamicUser=yes` — utilisateur éphémère, `ProtectSystem=strict` + `ProtectHome=read-only` automatiques +- `ConfigurationDirectory=` — accès sécurisé au TOML de config + +## Dashboard web — spécifications UI + +### Grille principale +- **Une tuile rectangulaire par agent** — grille `auto-fill minmax(220px, 1fr)` responsive. +- Métriques en **icônes** (pas de texte) avec **tooltips** sur chaque icône. +- **Jauges barre** pour CPU, RAM, disque dans les tuiles. +- **Effets** : halo lumineux au survol (couleur selon statut), pression 3D au clic. +- **Tooltips globaux** : positionnés en `position:fixed` via JS (jamais clippés). +- **Jusqu'à 20+ agents** — taille de tuiles configurable. + +### SMART disque +- L'agent vérifie si `smartctl` est disponible sur la machine cible. +- Si disponible : collecte l'état SMART simplifié (`PASSED` / `FAILED` + température + reallocated sectors). +- Le popup détail affiche un **bouton SMART** dans la section Stockage (couleur ok/warn/err selon état). +- Clic sur le bouton → popup SMART complet, lisible par un non-expert, **en français** : état général, température, durée de vie estimée, secteurs défectueux, explications simples. + +### Popup détail agent (clic sur tuile) +- **Redimensionnable** en largeur et hauteur — dernière taille sauvegardée sur le serveur. +- Pas de bouton "Fermer" — uniquement la croix en haut à droite. +- Icône agent cliquable pour upload custom (SVG/JPG/PNG/WEBP, redim. canvas max 128×128 px ratio préservé, sauvegardée sur le serveur). +- KPIs actuels + **courbes historiques** (SVG) pour CPU et RAM. +- Stockage en jauges barre. +- Protocoles actifs affichés en badges. +- **Bouton icône `fa-gears`** en bas à droite → ouvre le popup de configuration de l'agent. + +### Popup configuration agent +- Accessible depuis le popup détail via l'icône gears (bas à droite). +- **Tableau métriques — 3 colonnes** : MÉTRIQUE / UDP / MQTT — une case à cocher par métrique par protocole, indépendantes. Pas d'activation générale du protocole. + - Métriques : cpu, memory, disk, smart, uptime, network, temperature + - Chaque case peut être cochée/décochée indépendamment (ex : CPU via UDP uniquement, température via MQTT uniquement) +- **Paramètres MQTT** : broker, port, topic base, auto-discovery (Home Assistant) toggle, birth message toggle, last will toggle. +- **Commandes distantes** : section affichée mais désactivée (bientôt) — reboot, shutdown, screen off, update, upgrade, shell cmd. +- **Bouton "Envoyer à l'agent"** — pousse la config via API REST → serveur → agent. + +### Header +- Logo + LED animée + compteurs agents (total / ok / warn / err). +- Bouton thème clair/sombre. +- Bouton configuration interface (taille tuiles, texte, seuils, rétention historique) — config sauvegardée sur le serveur. + +### Footer (status bar) +- Mode LIVE en fond accent (style tmux). +- CPU et RAM du **serveur** avec mini-jauges. +- Horodatage de la dernière actualisation. + +### Stockage local des assets +Toutes les ressources web versionnées localement — pas de CDN en production : +``` +dashboard/ +├── fonts/ (Inter, JetBrains Mono, Share Tech Mono) +├── vendor/ +│ └── fontawesome/ +├── design_system/ +│ ├── tokens/tokens.css +│ └── components/ui-kit.jsx +``` + +## Design System — règles obligatoires + +Toute UI utilise `design_system/`. Lire `design_system/consigne_design_system.md` entièrement avant d'écrire du code UI. + +Règles clés : +- **Toujours les variables CSS** — jamais de hex en dur. +- **`data-theme`** obligatoire sur ``. Sans ça, l'UI casse silencieusement. +- **Composants** dans `ui-kit.jsx` avant d'en créer de nouveaux. +- **Icônes** : Font Awesome via `` uniquement — pas d'emoji, pas de SVG inline. +- **Polices** : Inter (UI), JetBrains Mono (valeurs numériques), Share Tech Mono (logs/terminal). +- **Labels** : uppercase + `letter-spacing: 0.08em`. +- **Border-radius** : tuiles 10-12px, boutons 8px, pastilles 999px. +- **`user-select:none`** : uniquement sur les éléments purement interactifs (`.hbtn`, `.btn`, `.pop-close`, `.cbox`, `.btn-agent-cfg`, `.tile-head`, `.tile-foot`). Jamais sur les conteneurs de contenu : le texte (hostname, IP, valeurs, labels) et les icônes doivent rester sélectionnables. + +### Tokens de statut + +| Token | Usage | +|-------|-------| +| `--ok` | état nominal | +| `--warn` | attention, seuil élevé | +| `--err` | erreur, alerte critique | +| `--accent` | action principale (orange Gruvbox) | +| `--blue` | datavis CPU / secondaire | +| `--purple` | MQTT / datavis tertiaire | diff --git a/docs/superpowers/specs/2026-05-22-nanometrics-design.md b/docs/superpowers/specs/2026-05-22-nanometrics-design.md new file mode 100644 index 0000000..dcfd6cf --- /dev/null +++ b/docs/superpowers/specs/2026-05-22-nanometrics-design.md @@ -0,0 +1,192 @@ +# Nanometrics — Spec de design + +**Date** : 2026-05-22 +**Statut** : Validé + +--- + +## 1. Vue d'ensemble + +Nanometrics est un système client-serveur de surveillance matérielle (CPU, RAM, disque, réseau, uptime) avec empreinte quasi nulle sur des machines Debian. L'objectif est de monitorer un LAN (≤20 machines) sans dépendance externe, sans authentification (réseau LAN de confiance), avec un dashboard web temps réel. + +**Trois composants :** +- **Agent Rust** (`agent/`) — collecte et envoie les métriques +- **Serveur Go** (`server/`) — reçoit, persiste, expose +- **Dashboard web** (`dashboard/`) — UI Nginx, temps réel WebSocket + +--- + +## 2. Architecture : SQLite + WebSocket + +Le serveur Go reçoit les données via UDP et/ou MQTT, les persiste en SQLite, et pousse les mises à jour en temps réel via WebSocket vers le dashboard. Le dashboard est servi par un conteneur Nginx séparé. + +``` +Agent Rust ──UDP JSON──► Serveur Go ──WebSocket──► Dashboard Nginx + ──MQTT──────► ──REST API──► + ──/metrics──► Prometheus + SQLite ◄──────────────── +``` + +**Échanges bidirectionnels :** à la connexion l'agent envoie un birth message, le serveur répond avec la config. Le dashboard peut modifier la config d'un agent via REST → serveur → agent (MQTT ou UDP). + +--- + +## 3. Agent Rust + +### Contraintes +- Pas de runtime async (pas de Tokio) — boucle mono-thread avec `std::thread::sleep` +- `sysinfo` avec `default-features = false` (pas de threads de fond) +- Profil release : `strip = true`, `opt-level = "z"`, `lto = true` +- Config via `config.toml` (serde) — rien de codé en dur + +### Fréquences de collecte +- CPU, RAM : toutes les 2 s +- Réseau, uptime : toutes les 10 s +- Disque, SMART : toutes les 60 s + +### Métriques +`hostname`, `ip`, `cpu_percent`, `memory_used`, `memory_free`, `hdd_total`, `hdd_used`, `hdd_free`, `uptime`, `network_rx`, `network_tx`, `status` (online/offline), `temperature` (optionnel), `smart` (optionnel — si `smartctl` disponible). + +### Protocoles +Chaque métrique est configurable indépendamment par protocole : +- **UDP** : fire-and-forget JSON vers `server_ip:server_port` +- **MQTT** : bidirectionnel vers `mqtt_host:mqtt_port` (défaut 10.0.0.3:1883, sans auth) + - Auto-discovery compatible Home Assistant + - Birth message : `{topic_base}/{hostname}/status` = `online` + - Last Will message : `offline` (configuré au connect, publié par le broker si l'agent disparaît) + - Topic base configurable (défaut : `nanometrics/agents`) + +### SMART +L'agent vérifie si `smartctl` est disponible (`which smartctl`). Si oui, il collecte : état général (PASSED/FAILED), température, secteurs réalloués, heures de fonctionnement, usure SSD. Envoyé au format JSON simplifié. + +### Architecture future +Prévoir un canal de réception de commandes (reboot, shutdown, screen off, update, upgrade, shell cmd) sans refonte du cœur. + +--- + +## 4. Serveur Go + +### Responsabilités +- Écoute UDP (goroutine par datagramme) +- Subscribe MQTT (`{topic_base}/#`) +- Persiste en SQLite (métriques historiques, config agents, icônes) +- Expose `/metrics` Prometheus (Gauges) +- API REST pour le dashboard +- WebSocket push temps réel (métriques + changements de statut) +- Stockage et push de la config par agent + +### API REST (endpoints principaux) +- `GET /api/agents` — liste des agents avec dernière métrique +- `GET /api/agents/{id}/metrics?from=&to=` — historique +- `GET /api/agents/{id}/config` — config courante de l'agent +- `PUT /api/agents/{id}/config` — mise à jour config → push à l'agent +- `POST /api/agents/{id}/icon` — upload icône (max 128×128px, ratio préservé) +- `GET /api/config` — config serveur/UI +- `PUT /api/config` — mise à jour config serveur/UI (taille popups incluse) + +### SQLite +Tables : `agents`, `metrics` (avec horodatage), `agent_config`, `server_config`, `agent_icons`. Rétention configurable (défaut 30 jours). + +### Déploiement +Docker Compose : conteneur Go (serveur) + conteneur Nginx (dashboard). Pas d'auth, LAN uniquement. + +### Agent systemd +Fichier `.service` avec `DynamicUser=yes`, `ConfigurationDirectory=`, `ProtectSystem=strict`. + +--- + +## 5. Dashboard web + +### Structure +``` +dashboard/ +├── index.html +├── fonts/ (Inter, JetBrains Mono, Share Tech Mono — locaux) +├── vendor/ +│ └── fontawesome/ +└── design_system/ + ├── tokens/tokens.css + └── components/ui-kit.jsx +``` + +### Grille principale +Grille responsive `auto-fill minmax(220px, 1fr)`. Une tuile rectangulaire par agent. Taille minimale configurable via le panneau serveur. + +**Tuile :** +- Icône agent (custom ou défaut), hostname, IP, LED de statut (ok/warn/err/offline) +- Jauges barre : CPU, RAM, disque +- Effets : halo lumineux au survol (couleur selon statut), pression 3D au clic +- Uptime en pied de tuile +- Clic → popup détail + +### Popup détail agent +- Redimensionnable (`resize:both`) — taille sauvegardée via `PUT /api/config` +- Croix pour fermer (pas de bouton "Fermer") +- Icône cliquable pour upload (SVG/JPG/PNG/WEBP, max 128×128px, ratio préservé) +- KPIs actuels (CPU, RAM, disque, uptime) +- Courbes SVG historiques CPU et RAM (30 min par défaut) +- Section stockage : jauge + bouton SMART (si disponible) +- Infos : hostname, IP, protocoles actifs (badges UDP/MQTT), dernier contact +- Bouton gears (bas à droite) → popup config agent + +### Popup SMART +- Verdict général (PASSED/FAILED) avec explication en français +- Indicateurs : température, secteurs défectueux, heures de fonctionnement, durée de vie SSD +- Tableau attributs détaillés avec explications non-expertes en français + +### Popup configuration agent +- Tableau 3 colonnes : **MÉTRIQUE / UDP / MQTT** +- Une case à cocher indépendante par métrique par protocole +- Métriques : cpu, memory, disk, smart, uptime, network, temperature +- Section paramètres MQTT : broker, port, topic base, auto-discovery, birth, last will +- Section commandes distantes (désactivée, placeholder) : reboot, shutdown, screen off, update, upgrade, shell cmd +- Bouton "Envoyer à l'agent" → `PUT /api/agents/{id}/config` + +### Popup configuration serveur/UI (header) +- Affichage tuiles : largeur minimale, taille texte +- Seuils d'alerte par défaut : warning/erreur CPU, RAM, disque +- Données : durée de rétention historique, durée des courbes +- Comportement : masquer agents hors ligne, notifications navigateur, mémoriser taille popups +- Sauvegardé via `PUT /api/config` + +### Header +- Logo + LED animée blink + compteurs (total / ok / warn / err) +- Bouton thème clair/sombre (`data-theme="dark|light"` sur ``) +- Bouton configuration interface (icône sliders) + +### Footer +- Badge LIVE en fond accent +- CPU + RAM du serveur avec mini-jauges +- Horodatage dernière actualisation + +### Tooltips +Système global : un seul `
` en `position:fixed`, mis à jour par JS (`mouseover` + `mousemove`). Jamais clippé par le parent. Délai 120ms à l'apparition. + +--- + +## 6. Design system + +**Palette :** Gruvbox seventies dark/light via variables CSS uniquement — jamais de hex en dur. +**Polices :** Inter (UI), JetBrains Mono (valeurs numériques), Share Tech Mono (labels terminal/mono). +**Icônes :** Font Awesome 6 uniquement. + +### Variables clés +- `--accent` : action principale (orange) +- `--ok` / `--warn` / `--err` : statuts +- `--blue` : datavis CPU / UDP +- `--purple` : MQTT / datavis secondaire +- `--bg-0` à `--bg-5` : niveaux de fond +- `--ink-1` à `--ink-4` : niveaux de texte + +### Règles `user-select` +`user-select:none` uniquement sur les éléments purement interactifs : `.hbtn`, `.btn`, `.pop-close`, `.cbox`, `.btn-agent-cfg`, `.tile-head`, `.tile-foot`. Le contenu (hostname, IP, valeurs, icônes) reste sélectionnable. + +--- + +## 7. Hors périmètre (v1) + +- Authentification / autorisation +- Support multi-utilisateurs +- Alertes par email/webhook +- Commandes distantes (placeholder uniquement) +- Support Windows/macOS pour l'agent