# 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 `<html>`. Sans ça, l'UI casse silencieusement.
- **Composants** dans `ui-kit.jsx` avant d'en créer de nouveaux.
- **Icônes** : Font Awesome via `<Icon name="…">` 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 |
