Files
serv_benchmark/FEATURE_IMPORT_USB_CLI.md
Gilles Soulier c67befc549 addon
2026-01-05 16:08:01 +01:00

266 lines
6.9 KiB
Markdown
Executable File

# Feature: Import USB avec sélection de périphérique
## Vue d'ensemble
Implémentation complète de l'import USB avec détection automatique, sélection par boutons radio, et stockage du CLI formaté en markdown.
## Flow utilisateur
### Étape 1 : Instructions et saisie CLI
1. Utilisateur clique sur **"Importer USB"**
2. **Popup 1** s'affiche avec :
- Commande `lsusb -v` avec bouton **Copier**
- Zone de texte pour coller la sortie
- Boutons **Annuler** et **Importer**
### Étape 2 : Sélection du périphérique
3. Backend détecte tous les périphériques (lignes commençant par "Bus")
4. **Popup 2** s'affiche avec :
- Liste des périphériques détectés
- **Boutons radio** (un seul sélectionnable à la fois)
- Bouton **Finaliser** (désactivé par défaut)
5. Utilisateur sélectionne UN périphérique → bouton **Finaliser** s'active
6. Utilisateur clique sur **Finaliser**
### Étape 3 : Pré-remplissage et création
7. Backend extrait et filtre le CLI pour ce périphérique
8. Formate le CLI en markdown :
```markdown
# Sortie lsusb -v
Bus 002 Device 003
```
[sortie filtrée]
```
```
9. Pré-remplit le formulaire avec :
- `nom`, `marque`, `modele`, `numero_serie`
- `type_principal`, `sous_type` (chargés depuis YAML)
- `cli` (markdown formaté)
- `caracteristiques_specifiques` (vendor_id, product_id, etc.)
10. Utilisateur complète et enregistre
## Fichiers modifiés
### Backend
#### 1. Database Schema
- **`backend/app/models/peripheral.py:124`**
```python
cli = Column(Text) # Sortie CLI (lsusb -v) filtrée
```
- **`backend/app/schemas/peripheral.py:50`**
```python
cli: Optional[str] = None # Sortie CLI (lsusb -v) filtrée
```
#### 2. Parsers
- **`backend/app/utils/lsusb_parser.py`** (NOUVEAU)
- `detect_usb_devices()` - Détecte lignes "Bus"
- `extract_device_section()` - Filtre pour un périphérique
- `parse_device_info()` - Parse les infos détaillées
#### 3. API Endpoints
- **`backend/app/api/endpoints/peripherals.py:665`**
- `POST /peripherals/import/usb-cli/detect` - Détecte périphériques
- `POST /peripherals/import/usb-cli/extract` - Extrait périphérique sélectionné
- `GET /peripherals/config/types` - Charge types depuis YAML
#### 4. Configuration
- **`config/peripheral_types.yaml:115`**
- Ajout type `usb_wifi` (Adaptateur WiFi USB)
### Frontend
#### 1. HTML
- **`frontend/peripherals.html:250-318`**
- Popup step 1 : Instructions + commande + zone texte
- Popup step 2 : Liste avec radio buttons
#### 2. CSS
- **`frontend/css/peripherals.css:540-666`**
- `.import-instructions` - Boîte d'instructions
- `.command-box` - Affichage commande avec bouton copier
- `.btn-copy` - Bouton copier stylisé
- `.usb-devices-list` - Liste périphériques
- `.usb-device-item` - Item cliquable avec radio
#### 3. JavaScript
- **`frontend/js/peripherals.js`**
- `copyUSBCommand()` - Copie commande dans presse-papiers
- `detectUSBDevices()` - Appelle API detect
- `selectUSBDevice()` - Active bouton Finaliser
- `importSelectedUSBDevice()` - Import final
- `loadPeripheralTypesFromAPI()` - Charge types depuis YAML
## Endpoints API
### 1. Détection périphériques
```
POST /api/peripherals/import/usb-cli/detect
Content-Type: multipart/form-data
Parameters:
lsusb_output: string (sortie complète lsusb -v)
Response:
{
"success": true,
"devices": [
{
"bus_line": "Bus 002 Device 003: ID 0781:55ab ...",
"bus": "002",
"device": "003",
"id": "0781:55ab",
"vendor_id": "0x0781",
"product_id": "0x55ab",
"description": "SanDisk Corp. ..."
}
],
"total_devices": 5
}
```
### 2. Extraction périphérique
```
POST /api/peripherals/import/usb-cli/extract
Content-Type: multipart/form-data
Parameters:
lsusb_output: string
bus: string (ex: "002")
device: string (ex: "003")
Response (nouveau):
{
"success": true,
"already_exists": false,
"suggested_peripheral": {
"nom": "SanDisk 3.2Gen1",
"type_principal": "USB",
"sous_type": "Clé USB",
"marque": "SanDisk",
"modele": "3.2Gen1",
"numero_serie": "...",
"cli": "# Sortie lsusb -v\n\nBus 002 Device 003\n\n```\n...\n```",
"caracteristiques_specifiques": {
"vendor_id": "0x0781",
"product_id": "0x55ab",
...
}
}
}
Response (existant):
{
"success": true,
"already_exists": true,
"existing_peripheral_id": 42,
"existing_peripheral": { ... }
}
```
### 3. Types de périphériques
```
GET /api/peripherals/config/types
Response:
{
"success": true,
"types": {
"USB": ["Clavier", "Souris", "Hub", "Clé USB", "Webcam", "Adaptateur WiFi", "Autre"],
"Bluetooth": ["Clavier", "Souris", "Audio", "Autre"],
"Réseau": ["Wi-Fi", "Ethernet", "Autre"],
...
},
"full_types": [ ... ] // Données complètes du YAML
}
```
## Migration base de données
Colonnes ajoutées à la table `peripherals` :
- `description` (TEXT) - Description courte
- `synthese` (TEXT) - Synthèse markdown complète
- `cli` (TEXT) - Sortie CLI formatée en markdown
**Migration exécutée automatiquement au démarrage du backend.**
## Chargement dynamique des types
Les sous-types sont maintenant **chargés depuis le YAML** via l'API :
1. Frontend appelle `/api/peripherals/config/types`
2. Backend lit `config/peripheral_types.yaml`
3. Frontend met en cache et affiche dans dropdown
4. **Fallback** sur hardcodé si API échoue
**Avantage** : Ajouter un type dans le YAML suffit, pas besoin de modifier le JS !
## Format CLI stocké
```markdown
# Sortie lsusb -v
Bus 002 Device 003
```
Bus 002 Device 003: ID 0781:55ab SanDisk Corp. Cruzer Blade
Device Descriptor:
bLength 18
bDescriptorType 1
bcdUSB 3.20
bDeviceClass 0
...
```
```
## Détection de doublons
Basée sur `vendor_id` + `product_id` :
- Si existe déjà → propose de voir la fiche
- Sinon → pré-remplit formulaire
## Tests
Pour tester l'import USB complet :
```bash
# 1. Obtenir la sortie lsusb
lsusb -v > /tmp/lsusb_output.txt
# 2. Dans l'interface :
- Cliquer "Importer USB"
- Copier la commande avec le bouton
- Coller le contenu de /tmp/lsusb_output.txt
- Cliquer "Importer"
- Sélectionner un périphérique avec le bouton radio
- Cliquer "Finaliser"
- Vérifier le pré-remplissage du formulaire
- Enregistrer
```
## Améliorations futures possibles
1. **Prévisualisation CLI** dans la fiche périphérique avec coloration syntaxique
2. **Export CLI** depuis une fiche existante
3. **Comparaison** de deux CLI (avant/après)
4. **Historique** des CLI (tracking modifications matériel)
5. **Import batch** : sélectionner plusieurs périphériques à la fois
## Notes techniques
- **Radio buttons** utilisés pour sélection unique (pas checkboxes)
- **Bouton Finaliser** désactivé jusqu'à sélection
- **CLI formaté** en markdown pour meilleure lisibilité
- **Cache** des types pour performance
- **Gestion erreurs** complète avec messages utilisateur