# 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 à 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 : `
` 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 .
```