# Correctifs Finaux - 14 décembre 2025, 03:00

## 🔧 Problèmes Résolus

### Problème #1: CPU Cores = 0 dans le Payload JSON

**Symptôme** : Le benchmark affichait `✓ Cores: 24%, Threads: 24` et le payload JSON contenait `"cores": 0`.

**Cause** : Le parsing de `lscpu` capturait des caractères non-numériques (ex: `%` de "CPU scaling MHz: 118%").

**Solution** : Ajout de `gsub(/[^0-9]/,"",$2)` pour ne garder que les chiffres.

**Fichier modifié** : [scripts/bench.sh:243-250](scripts/bench.sh#L243-L250)

```bash
# AVANT
cores_per_socket=$(lscpu | awk -F: '/Core\(s\) per socket/ {gsub(/^[ \t]+/,"",$2); print $2}')
sockets=$(lscpu | awk -F: '/Socket\(s\)/ {gsub(/^[ \t]+/,"",$2); print $2}')
cores=$((${cores_per_socket:-1} * ${sockets:-1}))

# APRÈS
cores_per_socket=$(lscpu | awk -F: '/Core\(s\) per socket/ {gsub(/^[ \t]+/,"",$2); gsub(/[^0-9]/,"",$2); print $2}')
sockets=$(lscpu | awk -F: '/Socket\(s\)/ {gsub(/^[ \t]+/,"",$2); gsub(/[^0-9]/,"",$2); print $2}')

# S'assurer que les valeurs sont des nombres valides
[[ -z "$cores_per_socket" || "$cores_per_socket" == "0" ]] && cores_per_socket=1
[[ -z "$sockets" || "$sockets" == "0" ]] && sockets=1

cores=$((cores_per_socket * sockets))
```

**Résultat attendu** :
- Ryzen 9 5900X : `cores = 12` ✅ (au lieu de 0)
- Intel i5-2400 : `cores = 2` ✅ (au lieu de 0)

---

### Problème #2: Backend ne met pas à jour le Hardware Snapshot

**Symptôme** : Les données du benchmark étaient envoyées (HTTP 200) mais ne s'affichaient pas dans le frontend. Les champs `ram_used_mb`, `ram_free_mb`, `bios_version` restaient null ou anciens.

**Cause** : Le backend **créait TOUJOURS un nouveau `HardwareSnapshot`** au lieu de mettre à jour le snapshot existant du device.

**Code problématique** ([benchmark.py:54](backend/app/api/benchmark.py#L54)) :
```python
snapshot = HardwareSnapshot(  # Toujours nouveau!
    device_id=device.id,
    captured_at=datetime.utcnow(),
    # ... tous les champs
)
db.add(snapshot)
```

**Solution** : Récupérer le snapshot existant et le mettre à jour.

**Fichier modifié** : [backend/app/api/benchmark.py:52-132](backend/app/api/benchmark.py#L52-L132)

```python
# 2. Get or create hardware snapshot
hw = payload.hardware

# Check if we have an existing snapshot for this device
existing_snapshot = db.query(HardwareSnapshot).filter(
    HardwareSnapshot.device_id == device.id
).order_by(HardwareSnapshot.captured_at.desc()).first()

# If we have an existing snapshot, update it instead of creating a new one
if existing_snapshot:
    snapshot = existing_snapshot
    snapshot.captured_at = datetime.utcnow()  # Update timestamp
else:
    # Create new snapshot if none exists
    snapshot = HardwareSnapshot(
        device_id=device.id,
        captured_at=datetime.utcnow()
    )

# Update all fields (whether new or existing snapshot)
snapshot.cpu_cores = hw.cpu.cores if hw.cpu else None
snapshot.ram_used_mb = hw.ram.used_mb if hw.ram else None
snapshot.ram_free_mb = hw.ram.free_mb if hw.ram else None
snapshot.bios_version = hw.motherboard.bios_version if hw.motherboard else None
# ... tous les autres champs

# Add to session only if it's a new snapshot
if not existing_snapshot:
    db.add(snapshot)

db.flush()
```

**Comportement** :
- **Premier benchmark** : Crée un nouveau snapshot
- **Benchmarks suivants** : Met à jour le snapshot existant avec les nouvelles données

**Avantages** :
- ✅ RAM utilisée/libre toujours à jour
- ✅ Température disques mise à jour
- ✅ BIOS version conservée après le premier benchmark
- ✅ Un seul snapshot par device (plus simple)

---

## 📊 Impact des Correctifs

### Avant les Correctifs

**Payload JSON envoyé** :
```json
{
  "hardware": {
    "cpu": {
      "cores": 0,  ← BUG
      "threads": 24
    },
    "ram": {
      "used_mb": 13478,
      "free_mb": 10864
    },
    "motherboard": {
      "bios_version": "F65e"
    }
  }
}
```

**Base de données** :
```json
{
  "cpu_cores": 0,  ← Ancien
  "ram_used_mb": null,  ← Non mis à jour
  "ram_free_mb": null,  ← Non mis à jour
  "bios_version": null  ← Non mis à jour
}
```

**Frontend** :
```
Cores: ? (0 affiché comme N/A)
RAM Utilisée: N/A
BIOS: N/A
```

### Après les Correctifs

**Payload JSON envoyé** :
```json
{
  "hardware": {
    "cpu": {
      "cores": 12,  ← CORRIGÉ
      "threads": 24
    },
    "ram": {
      "used_mb": 13478,
      "free_mb": 10864
    },
    "motherboard": {
      "bios_version": "F65e"
    }
  }
}
```

**Base de données** :
```json
{
  "cpu_cores": 12,  ← Mis à jour
  "ram_used_mb": 13478,  ← Mis à jour
  "ram_free_mb": 10864,  ← Mis à jour
  "bios_version": "F65e"  ← Mis à jour
}
```

**Frontend** :
```
Cores: 12
RAM Utilisée: 13 GB (28%)
BIOS: F65e
```

---

## 🧪 Tests à Effectuer

### 1. Relancer le Benchmark

```bash
cd /home/gilles/Documents/vscode/serv_benchmark
sudo bash scripts/bench.sh
```

**Vérifications** :
- ✅ Console affiche `Cores: 12, Threads: 24` (sans `%`)
- ✅ Payload JSON contient `"cores": 12`
- ✅ HTTP 200 OK

### 2. Vérifier les Données dans la DB

```bash
curl -s http://localhost:8007/api/devices/2 | jq '.last_hardware_snapshot | {
  cpu_cores,
  cpu_threads,
  ram_used_mb,
  ram_free_mb,
  bios_version,
  bios_date
}'
```

**Résultat attendu** :
```json
{
  "cpu_cores": 12,
  "cpu_threads": 24,
  "ram_used_mb": 13478,
  "ram_free_mb": 10864,
  "bios_version": "F65e",
  "bios_date": "09/20/2023"
}
```

### 3. Vérifier le Frontend

```
http://localhost:8087/device_detail.html?id=2
```

**Sections à vérifier** :
- ⚡ Carte Mère : Gigabyte B450 AORUS ELITE + BIOS F65e
- 🔲 CPU : 12 cores, 24 threads
- 💾 RAM : 47 GB total, 13 GB utilisée (28%)
- 💿 Stockage : 7 disques détectés
- 🎮 GPU : NVIDIA GeForce RTX 3060
- 🌐 Réseau : eno1 (10.0.1.109)
- 📊 Benchmarks : Score global 145.82

---

## 📁 Fichiers Modifiés

| Fichier | Lignes | Changement |
|---------|--------|------------|
| [scripts/bench.sh](scripts/bench.sh) | 243-250 | Parsing robuste cores CPU + validation |
| [backend/app/api/benchmark.py](backend/app/api/benchmark.py) | 52-132 | Update snapshot existant au lieu de créer nouveau |

---

## 🎯 Prochaines Étapes

1. ✅ Scripts correctifs appliqués
2. ✅ Backend redémarré
3. ⏳ **Relancer le benchmark sur aorus** (action requise)
4. ⏳ Vérifier que toutes les données s'affichent
5. ⏳ Tester sur d'autres devices si disponibles

---

## 📝 Notes Techniques

### Pourquoi mettre à jour au lieu de créer ?

**Avantages** :
- Un seul snapshot par device = requêtes plus rapides
- RAM usage toujours à jour
- Historique conservé dans les `Benchmark` records

**Compromis** :
- Si le hardware change physiquement (nouveau CPU, nouvelle RAM), le snapshot sera écrasé
- Pour un vrai historique hardware, il faudrait créer un nouveau snapshot seulement quand le hardware change significativement

### Alternative Future

Implémenter une logique de détection de changement hardware :
```python
def hardware_changed_significantly(old_snapshot, new_hardware):
    # Compare CPU, RAM total, GPU, nombre de disques
    return (
        old_snapshot.cpu_model != new_hardware.cpu.model or
        old_snapshot.ram_total_mb != new_hardware.ram.total_mb or
        old_snapshot.gpu_model != new_hardware.gpu.model
    )
```

Si `hardware_changed_significantly() == True` → Créer nouveau snapshot
Sinon → Mettre à jour snapshot existant

---

**Version** : Frontend 2.0.2 / Backend 1.1.1 / Script 1.2.1
**Date** : 14 décembre 2025, 03:00
**Status** : ✅ Correctifs appliqués, prêt pour test
