add go bench client
This commit is contained in:
302
docs/FEATURE_UTILISATION_FIELD.md
Normal file
302
docs/FEATURE_UTILISATION_FIELD.md
Normal file
@@ -0,0 +1,302 @@
|
||||
# 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.
|
||||
Reference in New Issue
Block a user