# 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