# Corrections Appliquées - Erreur HTTP 422

## Problème Initial

Lors de l'exécution de `bench.sh`, erreur HTTP 422 :

```
{"detail":[{
  "type":"int_from_float",
  "loc":["body","hardware","storage","devices",0,"capacity_gb"],
  "msg":"Input should be a valid integer, got a number with a fractional part",
  "input":447.1
}]}
```

## Cause

Le schéma Pydantic `StorageDevice` définissait `capacity_gb` comme `int`, mais le script `bench.sh` envoyait un `float` (447.1).

## Solutions Appliquées

### 1. ✅ Schéma StorageDevice ([backend/app/schemas/hardware.py](backend/app/schemas/hardware.py:59))

**Avant** :
```python
class StorageDevice(BaseModel):
    capacity_gb: Optional[int] = None
```

**Après** :
```python
class StorageDevice(BaseModel):
    capacity_gb: Optional[float] = None  # Changed from int to float
```

### 2. ✅ Schéma RAMInfo ([backend/app/schemas/hardware.py](backend/app/schemas/hardware.py:35-44))

Ajout des nouveaux champs pour les statistiques RAM :

```python
class RAMInfo(BaseModel):
    total_mb: int
    used_mb: Optional[int] = None      # NEW
    free_mb: Optional[int] = None      # NEW
    shared_mb: Optional[int] = None    # NEW
    slots_total: Optional[int] = None
    slots_used: Optional[int] = None
    ecc: Optional[bool] = None
    layout: Optional[List[RAMSlot]] = None
```

### 3. ✅ API Backend ([backend/app/api/benchmark.py](backend/app/api/benchmark.py:72-80))

Sauvegarde des nouveaux champs RAM :

```python
# RAM
ram_total_mb=hw.ram.total_mb if hw.ram else None,
ram_used_mb=hw.ram.used_mb if hw.ram else None,      # NEW
ram_free_mb=hw.ram.free_mb if hw.ram else None,      # NEW
ram_shared_mb=hw.ram.shared_mb if hw.ram else None,  # NEW
ram_slots_total=hw.ram.slots_total if hw.ram else None,
# ...
```

### 4. ✅ Modèle de Base de Données ([backend/app/models/hardware_snapshot.py](backend/app/models/hardware_snapshot.py:35-43))

Ajout des colonnes dans la table `hardware_snapshots` :

```python
# RAM
ram_total_mb = Column(Integer, nullable=True)
ram_used_mb = Column(Integer, nullable=True)      # NEW
ram_free_mb = Column(Integer, nullable=True)      # NEW
ram_shared_mb = Column(Integer, nullable=True)    # NEW
ram_slots_total = Column(Integer, nullable=True)
# ...
```

### 5. ✅ Migration SQL ([backend/migrations/001_add_ram_stats_and_smart.sql](backend/migrations/001_add_ram_stats_and_smart.sql))

Script SQL pour mettre à jour une base existante :

```sql
ALTER TABLE hardware_snapshots ADD COLUMN ram_used_mb INTEGER;
ALTER TABLE hardware_snapshots ADD COLUMN ram_free_mb INTEGER;
ALTER TABLE hardware_snapshots ADD COLUMN ram_shared_mb INTEGER;
```

### 6. ✅ Script d'Application de Migration ([backend/apply_migration.py](backend/apply_migration.py))

Script Python pour appliquer automatiquement la migration :

```bash
python3 backend/apply_migration.py
```

## Test de Validation

```bash
# Test des schémas Pydantic
python3 -c "
from app.schemas.hardware import RAMInfo, StorageDevice

# Test RAMInfo avec nouveaux champs
ram = RAMInfo(total_mb=8000, used_mb=6000, free_mb=1500, shared_mb=500)
print('✅ RAMInfo OK')

# Test StorageDevice avec float
storage = StorageDevice(name='/dev/sda', capacity_gb=447.1)
print(f'✅ StorageDevice OK - capacity_gb={storage.capacity_gb}')
"
```

Résultat :
```
✅ RAMInfo OK
✅ StorageDevice OK - capacity_gb=447.1
```

## Prochaines Étapes pour le Déploiement

### Option 1 : Nouvelle Base de Données (Recommandé pour les tests)

```bash
# Arrêter les services
docker-compose down

# Supprimer l'ancienne base
rm -f backend/data/data.db

# Redémarrer (la base sera recréée automatiquement avec les nouveaux champs)
docker-compose up -d
```

### Option 2 : Migration de la Base Existante (Production)

```bash
# Arrêter les services
docker-compose down

# Appliquer la migration
python3 backend/apply_migration.py

# Redémarrer
docker-compose up -d
```

## Vérification

### 1. Tester avec le script bench.sh

```bash
sudo bash scripts/bench.sh
```

Vous devriez voir :
```
[8/8] Construction du payload JSON et envoi au serveur
  ✓ Envoi du payload vers: http://10.0.0.50:8007/api/benchmark
  ✓ Payload envoyé avec succès (HTTP 200)
```

### 2. Vérifier la base de données

```bash
sqlite3 backend/data/data.db

# Vérifier les nouvelles colonnes
PRAGMA table_info(hardware_snapshots);

# Voir les données
SELECT
    d.hostname,
    h.ram_total_mb,
    h.ram_used_mb,
    h.ram_free_mb,
    h.ram_shared_mb
FROM hardware_snapshots h
JOIN devices d ON h.device_id = d.id
ORDER BY h.captured_at DESC
LIMIT 1;
```

### 3. Vérifier les logs backend

```bash
docker-compose logs backend | grep -i error
```

Pas d'erreurs = succès ! ✅

## Résumé des Fichiers Modifiés

| Fichier | Modification | Status |
|---------|-------------|--------|
| [backend/app/schemas/hardware.py](backend/app/schemas/hardware.py) | `capacity_gb: int` → `float`, ajout champs RAM | ✅ |
| [backend/app/api/benchmark.py](backend/app/api/benchmark.py) | Sauvegarde nouveaux champs RAM | ✅ |
| [backend/app/models/hardware_snapshot.py](backend/app/models/hardware_snapshot.py) | Ajout colonnes RAM | ✅ |
| [backend/migrations/001_add_ram_stats_and_smart.sql](backend/migrations/001_add_ram_stats_and_smart.sql) | Migration SQL | ✅ |
| [backend/apply_migration.py](backend/apply_migration.py) | Script d'application | ✅ |

## Données Maintenant Collectées

### Avant
```json
{
  "ram": {
    "total_mb": 8000
  },
  "storage": {
    "devices": [{
      "capacity_gb": 500  // int uniquement
    }]
  }
}
```

### Après
```json
{
  "ram": {
    "total_mb": 7771,
    "used_mb": 6123,     // ✨ NOUVEAU
    "free_mb": 923,      // ✨ NOUVEAU
    "shared_mb": 760     // ✨ NOUVEAU
  },
  "storage": {
    "devices": [{
      "capacity_gb": 447.1  // ✨ Supporte maintenant les décimales
    }]
  }
}
```

## Notes

- ✅ Les modifications sont **rétrocompatibles** : les anciens benchmarks sans `used_mb`/`free_mb`/`shared_mb` continueront de fonctionner
- ✅ Le script `bench.sh` est maintenant **totalement autonome** et ne dépend plus de `script_test.sh`
- ✅ Le payload JSON est **conforme** au format attendu par l'API
- ✅ La validation Pydantic fonctionne correctement

## Support

En cas de problème, consulter :
1. [DEPLOYMENT_GUIDE.md](DEPLOYMENT_GUIDE.md) - Guide complet de déploiement
2. [IMPLEMENTATION_STATUS.md](IMPLEMENTATION_STATUS.md) - État d'implémentation
3. Logs Docker : `docker-compose logs -f backend`
