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