# Changelog

## 2025-12-31 - Améliorations UI/UX, Font Awesome Local & Correction Docker Images

### Added
- **🖼️ Génération automatique de miniatures**
  - Nouveau champ `thumbnail_path` dans `peripheral_photos`
  - Génération automatique lors de l'upload (48px large, ratio conservé @ 75% qualité)
  - Structure : `original/`, image redimensionnée, `thumbnail/`
  - API retourne `thumbnail_path` + `stored_path`
  - Gain performance : ~94% poids en moins + conservation ratio d'aspect
  - Migration 009 appliquée
  - Documentation : `docs/SESSION_2025-12-31_THUMBNAILS.md`, `docs/THUMBNAILS_ASPECT_RATIO.md`

- **✏️ Fonction "Modifier" complète dans page détail**
  - Modale d'édition avec tous les champs du périphérique (22 champs)
  - Système d'étoiles cliquables pour la note
  - Pré-remplissage automatique des données actuelles
  - Sauvegarde via API PUT + rechargement automatique
  - Modale large (1400px max) pour affichage optimal
  - Documentation : `docs/FEATURE_EDIT_PERIPHERAL.md`

- **📸 Icône cliquable pour photo principale**
  - Icône ⭕/✅ en bas à gauche de chaque photo dans la galerie
  - Un clic pour définir/changer la photo principale (vignette)
  - États visuels : normal (gris), hover (bleu), active (cyan)
  - API POST `/peripherals/{id}/photos/{photo_id}/set-primary`
  - Une seule photo principale garantie par périphérique
  - Documentation : `docs/FEATURE_PRIMARY_PHOTO_TOGGLE.md`

### Improved
- **ℹ️ Aide contextuelle pour "Photo principale"**
  - Texte explicatif avec icône <i class="fas fa-info-circle"></i> à côté du checkbox
  - Badge "★ Principale" avec étoile dans la galerie photos
  - Clarification : une seule photo principale par périphérique

### Fixed
- **🐳 Docker : Images périphériques accessibles**
  - Problème : Images uploadées retournaient 404 (read-only filesystem)
  - Solution : Montage simplifié `./uploads:/uploads:ro`
  - Ajout configuration nginx personnalisée (`frontend/nginx.conf`)
  - Conversion chemins API : `/app/uploads/...` → `/uploads/...`
  - Cache navigateur 1 jour + en-têtes sécurité
  - Documentation : `docs/SESSION_2025-12-31_DOCKER_IMAGES_FIX.md`

## 2025-12-31 - Améliorations UI/UX & Font Awesome Local

### Added
- **🎨 Font Awesome 6.4.0 en local (polices + SVG)**
  - **Polices** : Remplacement du CDN par hébergement local (378 KB total)
    - Fichiers : all.min.css + 3 fichiers woff2 (solid, regular, brands)
    - Dossier : `frontend/fonts/fontawesome/`
  - **Icônes SVG** : 2020 icônes téléchargées (8.1 MB)
    - Solid : 1347 icônes | Regular : 164 icônes | Brands : 509 icônes
    - Dossier : `frontend/icons/svg/fa/`
    - Utilisation : `<img src="...">` ou SVG inline
  - Avantages : hors ligne, RGPD-friendly, meilleure performance, qualité vectorielle
  - Documentation ajoutée dans `config/locations.yaml` et `config/peripheral_types.yaml`

- **🗂️ Endpoint API `/config/location-types`**
  - Charge les types de localisation depuis `config/locations.yaml`
  - Permet construction d'interface hiérarchique de localisation
  - Retourne icônes, couleurs, règles de hiérarchie (`peut_contenir`)

- **📋 Champ Spécifications techniques**
  - Nouveau champ `specifications` (format Markdown)
  - Destiné au contenu brut importé depuis fichiers .md
  - Séparation claire : CLI → Spécifications → Notes
  - Migration 008 appliquée

- **⭐ Système d'étoiles cliquables pour la note**
  - Remplacement du champ numérique par 5 étoiles interactives
  - Effet hover pour prévisualisation
  - CSS : étoiles actives en doré (#f1c40f) avec ombre
  - Fonction `setRating()` pour pré-remplissage lors de l'édition

- **📋 Tooltip "Copié !" sur bouton copier**
  - Implémentation copie presse-papiers via `navigator.clipboard`
  - Tooltip avec animation fade in/out (2 secondes)
  - Design cohérent avec thème Monokai

- **🖥️ Dropdown assignation d'hôtes**
  - Sélection de l'hôte dans la section "État et localisation"
  - Format : `hostname (location)` ou `hostname`
  - Option par défaut : "En stock (non assigné)"
  - Endpoint API : `/api/peripherals/config/devices`

### Changed
- **📝 Séparation CLI : YAML + Markdown**
  - Champ `cli_yaml` : données structurées au format YAML
  - Champ `cli_raw` : sortie CLI brute (sudo lsusb -v, lshw, etc.)
  - Ancien champ `cli` marqué DEPRECATED (conservé pour compatibilité)
  - Migration 007 appliquée : `cli` → `cli_raw`

- **📐 Optimisation espace formulaire (-25-30% scroll)**
  - Modal padding : 2rem → 1.25rem (-37%)
  - Form grid gap : 2rem → 0.9rem (-55%)
  - Section padding : 1.5rem → 0.9rem (-40%)
  - Form group margin : 1.25rem → 0.8rem (-36%)
  - Input padding : 0.75rem → 0.5rem 0.65rem (-33%)
  - Textarea line-height : 1.4 → 1.3
  - Textarea min-height : 80px → 70px (-12.5%)

- **🖼️ Configuration compression photo par niveaux**
  - Format entrée : jpg, png, webp
  - Format sortie : PNG
  - Structure : `original/` (fichiers originaux) + `thumbnail/` (miniatures)
  - 4 niveaux : high (92%, 2560×1920), medium (85%, 1920×1080), low (75%, 1280×720), minimal (65%, 800×600)
  - Fichier : `config/image_compression.yaml`

- **🔧 Consolidation config/**
  - Un seul dossier `config/` à la racine du projet
  - Suppression de `backend/config/`
  - Chemins mis à jour dans `image_config_loader.py`

### Fixed
- **🔧 Correction commande USB**
  - Toutes références mises à jour : `lsusb -v` → `sudo lsusb -v`
  - Fichiers : peripherals.html, README.md, README_PERIPHERALS.md, CHANGELOG.md
  - Raison : accès aux descripteurs complets nécessite privilèges root

### Documentation
- `docs/SESSION_2025-12-31_UI_IMPROVEMENTS.md` : Session complète UI/UX
- Commentaires icônes dans `config/locations.yaml` et `config/peripheral_types.yaml`

---

## 2025-12-31 - Conformité Spécifications USB & Classification Intelligente

### Added
- **🧠 Classification intelligente des périphériques CONFORME AUX SPÉCIFICATIONS USB**
  - **CRITIQUE** : Utilisation de `bInterfaceClass` (normative) au lieu de `bDeviceClass` pour détection Mass Storage (classe 08)
  - Détection automatique de `type_principal` et `sous_type` basée sur l'analyse du contenu
  - Support de multiples stratégies : USB **interface** class (prioritaire), device class (fallback), vendor/product IDs, analyse de mots-clés
  - Patterns pour WiFi, Bluetooth, Storage, Hub, Clavier, Souris, Webcam, Ethernet
  - Système de scoring pour sélectionner le type le plus probable
  - Fonctionne avec import USB (sudo lsusb -v) ET import markdown (.md)
  - Nouveau classificateur : [backend/app/utils/device_classifier.py](backend/app/utils/device_classifier.py)
  - Documentation complète : [docs/FEATURE_INTELLIGENT_CLASSIFICATION.md](docs/FEATURE_INTELLIGENT_CLASSIFICATION.md)

- **⚡ Détection normative du type USB basée sur la vitesse négociée** (pas bcdUSB)
  - Low Speed (1.5 Mbps) → USB 1.1
  - Full Speed (12 Mbps) → USB 1.1
  - High Speed (480 Mbps) → USB 2.0
  - SuperSpeed (5 Gbps) → USB 3.0
  - SuperSpeed+ (10 Gbps) → USB 3.1
  - SuperSpeed Gen 2x2 (20 Gbps) → USB 3.2

- **🔌 Analyse de puissance USB normative**
  - Extraction MaxPower (en mA) et bmAttributes
  - Détection Bus Powered vs Self Powered
  - Calcul suffisance alimentation basé sur capacité normative du port :
    - USB 2.0 : 500 mA @ 5V = 2,5 W
    - USB 3.x : 900 mA @ 5V = 4,5 W

- **🛠️ Détection firmware requis**
  - Classe Vendor Specific (255) → `requires_firmware: true`
  - Indication que le périphérique nécessite un pilote + microcode spécifique

- **📋 Mappings de champs conformes aux spécifications USB**
  - `marque` = `idVendor` (vendor_id, ex: 0x0781)
  - `modele` = `iProduct` (product string, ex: "SanDisk 3.2Gen1")
  - `fabricant` = `iManufacturer` (manufacturer string, ex: "SanDisk Corp.")
  - `caracteristiques_specifiques` enrichi avec :
    - `vendor_id` / `product_id` (idVendor / idProduct)
    - `fabricant` (iManufacturer)
    - `usb_version_declared` (bcdUSB - déclaré, non définitif)
    - `usb_type` (type réel basé sur vitesse négociée)
    - `negotiated_speed` (vitesse négociée, ex: "High Speed")
    - `interface_classes` (CRITIQUE : liste des bInterfaceClass)
    - `requires_firmware` (true si classe 255)
    - `max_power_ma` (MaxPower en mA)
    - `is_bus_powered` / `is_self_powered`
    - `power_sufficient` (comparaison MaxPower vs capacité port)

- **📋 Champs de documentation enrichis**
  - Nouveau champ `synthese` (TEXT) - Stockage complet du markdown importé
  - Nouveau champ `cli` (TEXT) - Sortie CLI formatée en markdown avec coloration syntaxique
  - Nouveau champ `description` (TEXT) - Description courte du périphérique
  - Migration automatique de la base de données

- **🔌 Import USB amélioré avec workflow 2 étapes**
  - **Étape 1** : Affichage de la commande `sudo lsusb -v` avec bouton "Copier"
  - Zone de texte pour coller la sortie complète
  - **Étape 2** : Liste des périphériques détectés avec **radio buttons** (sélection unique)
  - Bouton "Finaliser" activé uniquement après sélection
  - Filtrage CLI pour ne garder que le périphérique sélectionné
  - Formatage markdown automatique du CLI stocké
  - Pré-remplissage intelligent du formulaire avec détection automatique du type
  - Nouveau parser : [backend/app/utils/lsusb_parser.py](backend/app/utils/lsusb_parser.py)
  - Documentation : [FEATURE_IMPORT_USB_CLI.md](FEATURE_IMPORT_USB_CLI.md)

- **📝 Import markdown amélioré**
  - Stockage du contenu complet dans le champ `synthese`
  - Classification intelligente basée sur l'analyse du markdown
  - Détection automatique du type depuis le contenu textuel

- **📊 Import USB avec informations structurées** (NOUVEAU)
  - Nouveau bouton "Importer USB (Info)" pour informations formatées
  - Support du format texte structuré (Bus, Vendor ID, Product ID, etc.)
  - Parser intelligent : [backend/app/utils/usb_info_parser.py](backend/app/utils/usb_info_parser.py)
  - Stockage CLI en **format YAML structuré** (+ sortie brute)
  - Endpoint `/api/peripherals/import/usb-structured`
  - Détection automatique type/sous-type
  - Organisation YAML : identification, usb, classe, alimentation, interfaces, endpoints
  - Documentation : [docs/FEATURE_USB_STRUCTURED_IMPORT.md](docs/FEATURE_USB_STRUCTURED_IMPORT.md)

- **💾 Sous-types de stockage détaillés**
  - Ajout "Clé USB", "Disque dur externe", "Lecteur de carte" dans [config/peripheral_types.yaml](config/peripheral_types.yaml)
  - Distinction automatique entre flash drive, HDD/SSD, et card reader
  - Méthode `refine_storage_subtype()` dans le classificateur
  - Patterns pour marques : SanDisk Cruzer, WD Passport, Seagate Expansion, etc.

- **🏠 Nouveaux types IoT et biométrie**
  - Ajout type "ZigBee" pour dongles domotique (ConBee, CC2531, CC2652, Thread)
  - Ajout type "Lecteur biométrique" pour lecteurs d'empreintes digitales
  - Détection automatique avec patterns : dresden elektronik, conbee, fingerprint, fingprint (typo)
  - Support des principaux fabricants : Validity, Synaptics, Goodix, Elan
  - Caractéristiques spécifiques : protocole ZigBee, firmware, type de capteur, résolution DPI

### Changed
- **Backend**
  - Endpoint `/api/peripherals/import/usb-cli/extract` - Ajout classification intelligente
  - Endpoint `/api/peripherals/import/markdown` - Ajout classification + stockage synthèse
  - Modèle `Peripheral` - Ajout colonnes `description`, `synthese`, `cli`
  - Schéma `PeripheralBase` - Ajout champs optionnels documentation

- **Frontend**
  - [frontend/peripherals.html](frontend/peripherals.html) - Modal USB en 2 étapes avec radio buttons
  - [frontend/peripherals.html](frontend/peripherals.html) - Ajout section "Documentation technique" avec champs `synthese` et `cli`
  - [frontend/css/peripherals.css](frontend/css/peripherals.css) - Styles pour bouton copier, liste USB, help text inline
  - [frontend/js/peripherals.js](frontend/js/peripherals.js) - Logique robuste de pré-sélection avec retry logic
  - Pré-sélection automatique de `type_principal` et `sous_type` après import

- **Configuration**
  - [config/peripheral_types.yaml](config/peripheral_types.yaml) - Ajout type "Adaptateur WiFi" (USB)
  - Chargement dynamique des types depuis YAML via API

### Fixed
- Problème de sélection des sous-types après import (timeout non fiable remplacé par retry logic)
- WiFi manquant dans les sous-types USB (maintenant chargé depuis YAML)
- Types hardcodés dans le frontend (maintenant dynamiques depuis l'API)

## 2025-12-30 - Module Périphériques (v1.0)

### Added
- **🔌 Module complet de gestion d'inventaire de périphériques**
  - Base de données séparée (`peripherals.db`) avec 7 tables
  - 30+ types de périphériques configurables via YAML
  - Support : USB, Bluetooth, Réseau, Stockage, Video, Audio, Câbles, Consoles, Microcontrôleurs, Quincaillerie
  - CRUD complet avec API REST (20+ endpoints)
  - Système de prêts avec rappels automatiques
  - Localisations hiérarchiques avec génération de QR codes
  - Import automatique depuis `sudo lsusb -v`
  - Import depuis fichiers .md de spécifications
  - Upload de photos avec compression WebP automatique
  - Upload de documents (PDF, factures, manuels)
  - Gestion de liens externes (fabricant, support, drivers)
  - Historique complet de tous les mouvements
  - Cross-database queries (périphériques ↔ devices)
  - Statistiques en temps réel

- **Backend**
  - Modèles SQLAlchemy : `Peripheral`, `PeripheralPhoto`, `PeripheralDocument`, `PeripheralLink`, `PeripheralLoan`, `Location`, `PeripheralLocationHistory`
  - Schémas Pydantic : 400+ lignes de validation
  - Services : `PeripheralService`, `LocationService`
  - Utilitaires : `usb_parser.py`, `md_parser.py`, `image_processor.py`, `qr_generator.py`, `yaml_loader.py`
  - API endpoints : `/api/peripherals/*`, `/api/locations/*`, `/api/peripherals/import/markdown`
  - Configuration YAML : `peripheral_types.yaml`, `locations.yaml`, `image_processing.yaml`, `notifications.yaml`

- **Frontend**
  - Page principale : [frontend/peripherals.html](frontend/peripherals.html)
  - Page détail : [frontend/peripheral-detail.html](frontend/peripheral-detail.html)
  - Thème Monokai dark complet
  - Liste paginée avec recherche et filtres multiples
  - Tri sur toutes les colonnes
  - Modal d'ajout, d'import USB et d'import fichiers .md
  - Gestion complète des photos, documents, liens

- **Docker**
  - Volumes ajoutés pour `config/` et `uploads/peripherals/`
  - Variables d'environnement pour le module
  - Documentation de déploiement : [DOCKER_DEPLOYMENT.md](DOCKER_DEPLOYMENT.md)

- **Documentation**
  - [README_PERIPHERALS.md](README_PERIPHERALS.md) - Guide complet
  - [docs/PERIPHERALS_MODULE_SPECIFICATION.md](docs/PERIPHERALS_MODULE_SPECIFICATION.md) - Spécifications
  - [DOCKER_DEPLOYMENT.md](DOCKER_DEPLOYMENT.md) - Déploiement

- **Dépendances**
  - `Pillow==10.2.0` - Traitement d'images
  - `qrcode[pil]==7.4.2` - Génération QR codes
  - `PyYAML==6.0.1` - Configuration YAML

### Changed
- [docker-compose.yml](docker-compose.yml) - Ajout volumes et variables pour périphériques
- [.env.example](.env.example) - Variables du module périphériques
- [README.md](README.md) - Documentation du module
- [frontend/js/utils.js](frontend/js/utils.js) - Fonctions `apiRequest`, `formatDateTime`, `formatBytes`, `showSuccess`, `showInfo`

### Files Added (25+)
- Backend: 12 fichiers (models, schemas, services, utils, routes)
- Frontend: 5 fichiers (HTML, JS, CSS)
- Config: 4 fichiers YAML
- Documentation: 3 fichiers markdown

## 2025-12-20 - Backend Schema Fix

### Fixed
- **Backend Schema Validation**: Increased upper bound constraints on score fields to accommodate high-performance hardware
  - File: [backend/app/schemas/benchmark.py](backend/app/schemas/benchmark.py)
  - Issue: CPU multi-core scores (25000+) and other raw benchmark values were being rejected with HTTP 422 errors
  - Solution: Increased constraints to realistic maximum values:
    - `cpu.score`: 10000 → 100000
    - `cpu.score_single`: 10000 → 50000
    - `cpu.score_multi`: 10000 → 100000
    - `memory.score`: 10000 → 100000
    - `disk.score`: 10000 → 50000
    - `network.score`: 10000 → 100000
    - `gpu.score`: 10000 → 50000
    - `global_score`: 10000 → 100000

# Changelog - script_test.sh

## Version 1.0.1 - Améliorations demandées

### Nouvelles fonctionnalités

#### 1. Wake-on-LAN pour cartes Ethernet
- **Fichier** : [script_test.sh:546-555](script_test.sh#L546-L555)
- Détection automatique du support Wake-on-LAN via `ethtool`
- Ajout du champ `wake_on_lan` (true/false/null) dans les informations réseau
- Vérifie si la carte supporte le "magic packet" (flag 'g')

```json
{
  "name": "eth0",
  "type": "ethernet",
  "wake_on_lan": true
}
```

#### 2. Statistiques RAM détaillées
- **Fichier** : [script_test.sh:298-303](script_test.sh#L298-L303) et [script_test.sh:367-385](script_test.sh#L367-L385)
- Ajout de la RAM utilisée (`used_mb`)
- Ajout de la RAM libre (`free_mb`)
- Ajout de la RAM partagée (`shared_mb`) - inclut tmpfs, vidéo partagée, etc.
- Distinction entre RAM physique totale et RAM disponible dans l'OS

```json
{
  "total_mb": 16384,
  "used_mb": 8192,
  "free_mb": 7500,
  "shared_mb": 692
}
```

#### 3. Test réseau iperf3 vers 10.0.0.50
- **Fichier** : [script_test.sh:675-726](script_test.sh#L675-L726)
- Test de connectivité préalable avec `ping`
- Test upload (client → serveur) pendant 10 secondes
- Test download (serveur → client avec `-R`) pendant 10 secondes
- Mesure du ping moyen (5 paquets)
- Calcul du score réseau basé sur la moyenne upload/download

**Prérequis** : Le serveur 10.0.0.50 doit avoir `iperf3 -s` en cours d'exécution.

```bash
# Sur le serveur 10.0.0.50
iperf3 -s
```

```json
{
  "upload_mbps": 940.50,
  "download_mbps": 950.20,
  "ping_ms": 0.5,
  "score": 94.54
}
```

#### 4. Données SMART de vieillissement des disques
- **Fichier** : [script_test.sh:492-602](script_test.sh#L492-L602)
- Extraction complète des données SMART pour chaque disque via `smartctl`
- **Indicateurs de santé globale** :
  - `health_status` : PASSED/FAILED (test auto-diagnostic SMART)
  - `temperature_celsius` : Température actuelle du disque

- **Indicateurs de vieillissement** :
  - `power_on_hours` : Heures de fonctionnement totales
  - `power_cycle_count` : Nombre de démarrages/arrêts
  - `reallocated_sectors` : Secteurs défectueux réalloués (⚠️ signe de défaillance)
  - `pending_sectors` : Secteurs en attente de réallocation (⚠️ attention)
  - `udma_crc_errors` : Erreurs de transmission (câble/interface)

- **Pour SSD uniquement** :
  - `wear_leveling_count` : Compteur d'usure des cellules
  - `total_lbas_written` : Volume total de données écrites

**Interprétation** :
- ✅ `health_status: "PASSED"` + `reallocated_sectors: 0` = Disque sain
- ⚠️ `reallocated_sectors > 0` = Début de défaillance, surveiller
- 🔴 `pending_sectors > 0` = Défaillance imminente, sauvegarder immédiatement
- 🔴 `health_status: "FAILED"` = Disque défaillant, remplacer

```json
{
  "device": "sda",
  "model": "Samsung SSD 970 EVO Plus 500GB",
  "type": "ssd",
  "smart": {
    "health_status": "PASSED",
    "power_on_hours": 12543,
    "power_cycle_count": 1876,
    "temperature_celsius": 42,
    "reallocated_sectors": 0,
    "pending_sectors": 0,
    "udma_crc_errors": 0,
    "wear_leveling_count": 97,
    "total_lbas_written": 45678901234
  }
}
```

#### 5. Correction du calcul global_score
- **Fichier** : [script_test.sh:732-760](script_test.sh#L732-L760)
- Le score global n'inclut **que** CPU, RAM et Disk (pas réseau, pas GPU)
- Nouvelle pondération :
  - **CPU** : 40%
  - **RAM** : 30%
  - **Disk** : 30%
- Normalisation automatique si certains benchmarks sont manquants
- Score sur 100

### Corrections

- **PATH Fix** : Ajout de `/usr/sbin` et `/sbin` au PATH ([script_test.sh:30](script_test.sh#L30))
  - Résout le problème de détection de `dmidecode`, `smartctl`, `ethtool`

### Format JSON mis à jour

```json
{
  "hardware": {
    "ram": {
      "total_mb": 16384,
      "used_mb": 8192,
      "free_mb": 7500,
      "shared_mb": 692,
      "slots_total": 4,
      "slots_used": 2,
      "ecc": false,
      "layout": [...]
    },
    "network": [
      {
        "name": "eth0",
        "type": "ethernet",
        "mac": "00:11:22:33:44:55",
        "ip_address": "10.0.1.100",
        "speed_mbps": 1000,
        "wake_on_lan": true
      }
    ]
  },
  "benchmarks": {
    "cpu": {
      "events_per_sec": 5234.89,
      "duration_s": 10.0,
      "score": 52.35
    },
    "memory": {
      "throughput_mib_s": 15234.5,
      "score": 76.17
    },
    "disk": {
      "read_mb_s": 450.0,
      "write_mb_s": 420.0,
      "iops_read": 112000,
      "iops_write": 105000,
      "latency_ms": 0.08,
      "score": 43.50
    },
    "network": {
      "upload_mbps": 940.5,
      "download_mbps": 950.2,
      "ping_ms": 0.5,
      "score": 94.54
    },
    "gpu": null,
    "global_score": 57.00
  }
}
```

### Notes d'utilisation

1. **Serveur iperf3** : Assurez-vous que `iperf3 -s` tourne sur 10.0.0.50 avant de lancer le script
2. **Permissions** : Le script nécessite `sudo` pour dmidecode, smartctl, ethtool
3. **Durée** : Le script prend environ 3-4 minutes (10s iperf3 upload + 10s download + 30s disk)

### Commande de test

```bash
# Lancer le serveur iperf3 sur 10.0.0.50
ssh user@10.0.0.50 'iperf3 -s -D'

# Lancer le script de test
sudo bash script_test.sh

# Voir le résultat
cat result.json | jq .
```
