addon
This commit is contained in:
265
FEATURE_IMPORT_USB_CLI.md
Executable file
265
FEATURE_IMPORT_USB_CLI.md
Executable file
@@ -0,0 +1,265 @@
|
||||
# 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
|
||||
Reference in New Issue
Block a user