266 lines
6.9 KiB
Markdown
Executable File
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
|