# Champ "Utilisation" pour les périphériques

## Contexte

Chaque périphérique peut être soit en stockage, soit utilisé par un appareil/hôte spécifique. Le champ `utilisation` permet de tracer où chaque périphérique est utilisé.

## Implémentation

### 1. Migration base de données

**Fichier**: `migrations/015_add_utilisation.sql`

```sql
ALTER TABLE peripherals ADD COLUMN utilisation VARCHAR(255);
CREATE INDEX idx_peripherals_utilisation ON peripherals(utilisation);
```

**Application**:
```bash
python3 backend/apply_migration_015.py
```

### 2. Modèle mis à jour

**Fichier**: `backend/app/models/peripheral.py` (ligne 60)

```python
etat = Column(String(50), default="Neuf", index=True)
localisation = Column(String(255))
proprietaire = Column(String(100))
utilisation = Column(String(255))  # Host from host.yaml or "non-utilisé"  ← NOUVEAU
tags = Column(Text)
notes = Column(Text)
```

### 3. Schéma mis à jour

**Fichier**: `backend/app/schemas/peripheral.py`

**PeripheralBase** (ligne 46):
```python
etat: Optional[str] = Field("Neuf", max_length=50)
localisation: Optional[str] = Field(None, max_length=255)
proprietaire: Optional[str] = Field(None, max_length=100)
utilisation: Optional[str] = Field(None, max_length=255)  # ← NOUVEAU
tags: Optional[str] = None
```

**PeripheralUpdate** (ligne 132):
```python
etat: Optional[str] = Field(None, max_length=50)
localisation: Optional[str] = Field(None, max_length=255)
proprietaire: Optional[str] = Field(None, max_length=100)
utilisation: Optional[str] = Field(None, max_length=255)  # ← NOUVEAU
tags: Optional[str] = None
```

### 4. Configuration des hôtes

**Fichier**: `config/host.yaml`

```yaml
hosts:
  - nom: Bureau-PC
    localisation: Bureau
  - nom: Serveur-NAS
    localisation: Salon
  - nom: Atelier-RPi
    localisation: Atelier
  - nom: Portable-Work
    localisation: Bureau
```

Les hôtes définis ici apparaissent dans le menu déroulant du champ "Utilisation".

### 5. API Endpoint

**Fichier**: `backend/app/api/endpoints/peripherals.py` (lignes 105-120)

```python
@router.get("/config/hosts", response_model=dict)
def get_hosts():
    """
    Get hosts list from host.yaml configuration.
    Returns list of hosts with their names and locations.
    """
    try:
        hosts = yaml_loader.get_hosts()

        return {
            "success": True,
            "hosts": hosts
        }

    except Exception as e:
        raise HTTPException(status_code=500, detail=f"Failed to load hosts: {str(e)}")
```

**Route**: `GET /api/peripherals/config/hosts`

**Réponse**:
```json
{
  "success": true,
  "hosts": [
    {"nom": "Bureau-PC", "localisation": "Bureau"},
    {"nom": "Serveur-NAS", "localisation": "Salon"},
    {"nom": "Atelier-RPi", "localisation": "Atelier"},
    {"nom": "Portable-Work", "localisation": "Bureau"}
  ]
}
```

### 6. Frontend

#### HTML - `frontend/peripherals.html` (lignes 243-251)

```html
<div class="form-group">
    <label for="utilisation">
        Utilisation
        <span class="help-text-inline">(Hôte ou appareil)</span>
    </label>
    <select id="utilisation" name="utilisation">
        <option value="">Chargement...</option>
    </select>
</div>
```

#### JavaScript - `frontend/js/peripherals.js`

**Fonction de chargement des hosts** (lignes 1262-1283):
```javascript
// Cache for hosts from API
let hostsCache = null;

// Load hosts from API
async function loadHostsFromAPI() {
    if (hostsCache) {
        return hostsCache;
    }

    try {
        const result = await apiRequest('/peripherals/config/hosts');
        if (result.success && result.hosts) {
            hostsCache = result.hosts;
            return result.hosts;
        }
    } catch (error) {
        console.error('Failed to load hosts from API:', error);
    }

    // Fallback to default if API fails
    return [];
}
```

**Fonction de chargement des options** (lignes 1285-1309):
```javascript
// Load utilisation options (hosts + "Non utilisé")
async function loadUtilisationOptions() {
    const utilisationSelect = document.getElementById('utilisation');
    if (!utilisationSelect) return;

    // Clear current options
    utilisationSelect.innerHTML = '';

    // Add "Non utilisé" as first option
    const nonUtiliseOption = document.createElement('option');
    nonUtiliseOption.value = 'Non utilisé';
    nonUtiliseOption.textContent = 'Non utilisé';
    utilisationSelect.appendChild(nonUtiliseOption);

    // Load hosts from API
    const hosts = await loadHostsFromAPI();

    // Add each host as an option
    hosts.forEach(host => {
        const option = document.createElement('option');
        option.value = host.nom;
        option.textContent = `${host.nom}${host.localisation ? ' (' + host.localisation + ')' : ''}`;
        utilisationSelect.appendChild(option);
    });
}
```

**Appel au chargement** (ligne 535):
```javascript
async function showAddModal() {
    document.getElementById('form-add-peripheral').reset();
    document.getElementById('modal-add').style.display = 'block';
    await loadUtilisationOptions();  // Load hosts from host.yaml
    updateUtilisationFields();
    updatePhotoUrlAddUI();
}
```

**Sauvegarde de la valeur** (lignes 566-568):
```javascript
// Handle utilisation field - store the host name or "Non utilisé"
const utilisation = document.getElementById('utilisation')?.value || 'Non utilisé';
data.utilisation = utilisation;
```

## Utilisation

### Ajouter/Modifier un périphérique

1. Ouvrir le formulaire d'ajout/modification
2. Dans la section "État et localisation", le champ **Utilisation** affiche:
   - **Non utilisé** (par défaut)
   - **Bureau-PC (Bureau)**
   - **Serveur-NAS (Salon)**
   - **Atelier-RPi (Atelier)**
   - **Portable-Work (Bureau)**
3. Sélectionner l'hôte où le périphérique est utilisé
4. Enregistrer

### Ajouter un nouvel hôte

Pour ajouter un nouvel hôte dans la liste:

1. Éditer le fichier `config/host.yaml`
2. Ajouter une entrée:
   ```yaml
   - nom: Nouveau-PC
     localisation: Chambre
   ```
3. Redémarrer le backend (si en développement) ou attendre le rechargement automatique
4. Le nouvel hôte apparaîtra automatiquement dans le menu déroulant

## Exemples de valeurs

| Valeur | Description |
|--------|-------------|
| `Non utilisé` | Périphérique en stockage |
| `Bureau-PC` | Périphérique utilisé par le PC du bureau |
| `Serveur-NAS` | Périphérique utilisé par le serveur NAS |
| `Atelier-RPi` | Périphérique utilisé par le Raspberry Pi de l'atelier |
| `Portable-Work` | Périphérique utilisé par l'ordinateur portable de travail |

## Bénéfices

✅ **Traçabilité**: Savoir où chaque périphérique est utilisé
✅ **Configuration centralisée**: Les hôtes sont définis dans `host.yaml`
✅ **Interface simplifiée**: Menu déroulant au lieu de saisie libre
✅ **Cohérence**: Évite les fautes de frappe et les variations (ex: "bureau-pc" vs "Bureau PC")
✅ **Extensible**: Facile d'ajouter de nouveaux hôtes
✅ **Indexé**: Recherches rapides par utilisation

## Requêtes utiles

### Trouver tous les périphériques non utilisés

```python
peripherals = session.query(Peripheral).filter(
    Peripheral.utilisation == 'Non utilisé'
).all()
```

### Trouver tous les périphériques d'un hôte

```python
peripherals = session.query(Peripheral).filter(
    Peripheral.utilisation == 'Bureau-PC'
).all()
```

### Compter les périphériques par hôte

```python
from sqlalchemy import func

stats = session.query(
    Peripheral.utilisation,
    func.count(Peripheral.id)
).group_by(Peripheral.utilisation).all()
```

## Fichiers modifiés

1. **migrations/015_add_utilisation.sql** - Migration SQL
2. **backend/apply_migration_015.py** - Script d'application
3. **backend/app/models/peripheral.py** - Ajout du champ
4. **backend/app/schemas/peripheral.py** - Ajout au schéma (2 endroits)
5. **backend/app/api/endpoints/peripherals.py** - Endpoint `/config/hosts`
6. **frontend/peripherals.html** - Modification du select
7. **frontend/js/peripherals.js** - Chargement dynamique des options

## Migration des données existantes

Si des périphériques existaient avant l'ajout du champ:
- La valeur par défaut est `NULL`
- Recommandé de définir à `'Non utilisé'` pour les périphériques en stockage

```sql
UPDATE peripherals SET utilisation = 'Non utilisé' WHERE utilisation IS NULL;
```

## Conclusion

Le champ `utilisation` permet un suivi précis de l'emplacement et de l'usage de chaque périphérique, avec une gestion centralisée des hôtes via le fichier `host.yaml` et un chargement dynamique dans l'interface.
