Files
serv_benchmark/backend/app/schemas/peripheral.py
Gilles Soulier c67befc549 addon
2026-01-05 16:08:01 +01:00

393 lines
12 KiB
Python
Executable File

"""
Linux BenchTools - Peripheral Schemas
"""
from pydantic import BaseModel, Field
from typing import Optional, List, Dict, Any
from datetime import date, datetime
# ========================================
# BASE SCHEMAS
# ========================================
class PeripheralBase(BaseModel):
"""Base schema for peripherals"""
nom: str = Field(..., min_length=1, max_length=255)
type_principal: str = Field(..., min_length=1, max_length=100)
sous_type: Optional[str] = Field(None, max_length=100)
marque: Optional[str] = Field(None, max_length=100)
modele: Optional[str] = Field(None, max_length=255)
fabricant: Optional[str] = Field(None, max_length=255)
produit: Optional[str] = Field(None, max_length=255)
numero_serie: Optional[str] = Field(None, max_length=255)
ean_upc: Optional[str] = Field(None, max_length=50)
# Achat
boutique: Optional[str] = Field(None, max_length=255)
date_achat: Optional[date] = None
prix: Optional[float] = Field(None, ge=0)
devise: Optional[str] = Field("EUR", max_length=10)
garantie_duree_mois: Optional[int] = Field(None, ge=0)
garantie_expiration: Optional[date] = None
# Évaluation
rating: Optional[float] = Field(0.0, ge=0, le=5)
# Stock
quantite_totale: Optional[int] = Field(1, ge=0)
quantite_disponible: Optional[int] = Field(1, ge=0)
seuil_alerte: Optional[int] = Field(0, ge=0)
# Métadonnées
etat: Optional[str] = Field("Neuf", max_length=50)
localisation: Optional[str] = Field(None, max_length=255)
proprietaire: Optional[str] = Field(None, max_length=100)
tags: Optional[str] = None # JSON string
# Documentation
description: Optional[str] = None # Description courte
synthese: Optional[str] = None # Synthèse complète markdown
cli: Optional[str] = None # DEPRECATED: Sortie CLI (lsusb -v) filtrée
cli_yaml: Optional[str] = None # Données structurées CLI au format YAML
cli_raw: Optional[str] = None # Sortie CLI brute (Markdown)
specifications: Optional[str] = None # Spécifications techniques (Markdown)
notes: Optional[str] = None # Notes libres (Markdown)
# Linux
device_path: Optional[str] = Field(None, max_length=255)
sysfs_path: Optional[str] = Field(None, max_length=500)
vendor_id: Optional[str] = Field(None, max_length=20)
product_id: Optional[str] = Field(None, max_length=20)
usb_device_id: Optional[str] = Field(None, max_length=20)
iManufacturer: Optional[str] = None # USB manufacturer string
iProduct: Optional[str] = None # USB product string
class_id: Optional[str] = Field(None, max_length=20)
driver_utilise: Optional[str] = Field(None, max_length=100)
modules_kernel: Optional[str] = None # JSON string
udev_rules: Optional[str] = None
identifiant_systeme: Optional[str] = None
# Installation
installation_auto: Optional[bool] = False
driver_requis: Optional[str] = None
firmware_requis: Optional[str] = None
paquets_necessaires: Optional[str] = None # JSON string
commandes_installation: Optional[str] = None
problemes_connus: Optional[str] = None
solutions: Optional[str] = None
compatibilite_noyau: Optional[str] = Field(None, max_length=100)
# Connectivité
interface_connexion: Optional[str] = Field(None, max_length=100)
connecte_a: Optional[str] = Field(None, max_length=255)
consommation_electrique_w: Optional[float] = Field(None, ge=0)
# Localisation physique
location_id: Optional[int] = None
location_details: Optional[str] = Field(None, max_length=500)
location_auto: Optional[bool] = True
# Appareil complet
is_complete_device: Optional[bool] = False
device_type: Optional[str] = Field(None, max_length=50)
linked_device_id: Optional[int] = None
device_id: Optional[int] = None
# Données spécifiques
caracteristiques_specifiques: Optional[Dict[str, Any]] = None
class PeripheralCreate(PeripheralBase):
"""Schema for creating a peripheral"""
pass
class PeripheralUpdate(BaseModel):
"""Schema for updating a peripheral (all fields optional)"""
nom: Optional[str] = Field(None, min_length=1, max_length=255)
type_principal: Optional[str] = Field(None, min_length=1, max_length=100)
sous_type: Optional[str] = Field(None, max_length=100)
marque: Optional[str] = Field(None, max_length=100)
modele: Optional[str] = Field(None, max_length=255)
fabricant: Optional[str] = Field(None, max_length=255)
produit: Optional[str] = Field(None, max_length=255)
numero_serie: Optional[str] = Field(None, max_length=255)
ean_upc: Optional[str] = Field(None, max_length=50)
boutique: Optional[str] = Field(None, max_length=255)
date_achat: Optional[date] = None
prix: Optional[float] = Field(None, ge=0)
devise: Optional[str] = Field(None, max_length=10)
garantie_duree_mois: Optional[int] = Field(None, ge=0)
garantie_expiration: Optional[date] = None
rating: Optional[float] = Field(None, ge=0, le=5)
quantite_totale: Optional[int] = Field(None, ge=0)
quantite_disponible: Optional[int] = Field(None, ge=0)
seuil_alerte: Optional[int] = Field(None, ge=0)
etat: Optional[str] = Field(None, max_length=50)
localisation: Optional[str] = Field(None, max_length=255)
proprietaire: Optional[str] = Field(None, max_length=100)
tags: Optional[str] = None
notes: Optional[str] = None
device_path: Optional[str] = Field(None, max_length=255)
vendor_id: Optional[str] = Field(None, max_length=20)
product_id: Optional[str] = Field(None, max_length=20)
usb_device_id: Optional[str] = Field(None, max_length=20)
iManufacturer: Optional[str] = None
iProduct: Optional[str] = None
connecte_a: Optional[str] = Field(None, max_length=255)
location_id: Optional[int] = None
location_details: Optional[str] = Field(None, max_length=500)
is_complete_device: Optional[bool] = None
device_type: Optional[str] = Field(None, max_length=50)
linked_device_id: Optional[int] = None
device_id: Optional[int] = None
caracteristiques_specifiques: Optional[Dict[str, Any]] = None
class PeripheralSummary(BaseModel):
"""Summary schema for peripheral lists"""
id: int
nom: str
type_principal: str
sous_type: Optional[str]
marque: Optional[str]
modele: Optional[str]
etat: str
rating: float
prix: Optional[float]
en_pret: bool
is_complete_device: bool
quantite_disponible: int
thumbnail_url: Optional[str] = None
class Config:
from_attributes = True
class PeripheralDetail(PeripheralBase):
"""Detailed schema with all information"""
id: int
date_creation: datetime
date_modification: Optional[datetime]
en_pret: bool
pret_actuel_id: Optional[int]
prete_a: Optional[str]
class Config:
from_attributes = True
class PeripheralListResponse(BaseModel):
"""Paginated list response"""
items: List[PeripheralSummary]
total: int
page: int
page_size: int
total_pages: int
# ========================================
# PHOTO SCHEMAS
# ========================================
class PeripheralPhotoBase(BaseModel):
"""Base schema for peripheral photos"""
description: Optional[str] = None
is_primary: Optional[bool] = False
class PeripheralPhotoCreate(PeripheralPhotoBase):
"""Schema for creating a photo"""
peripheral_id: int
filename: str
stored_path: str
mime_type: Optional[str]
size_bytes: Optional[int]
class PeripheralPhotoSchema(PeripheralPhotoBase):
"""Full photo schema"""
id: int
peripheral_id: int
filename: str
stored_path: str
thumbnail_path: Optional[str]
mime_type: Optional[str]
size_bytes: Optional[int]
uploaded_at: datetime
class Config:
from_attributes = True
# ========================================
# DOCUMENT SCHEMAS
# ========================================
class PeripheralDocumentBase(BaseModel):
"""Base schema for peripheral documents"""
doc_type: str = Field(..., max_length=50) # manual, warranty, invoice, datasheet, other
description: Optional[str] = None
class PeripheralDocumentCreate(PeripheralDocumentBase):
"""Schema for creating a document"""
peripheral_id: int
filename: str
stored_path: str
mime_type: Optional[str]
size_bytes: Optional[int]
class PeripheralDocumentSchema(PeripheralDocumentBase):
"""Full document schema"""
id: int
peripheral_id: int
filename: str
stored_path: str
mime_type: Optional[str]
size_bytes: Optional[int]
uploaded_at: datetime
class Config:
from_attributes = True
# ========================================
# LINK SCHEMAS
# ========================================
class PeripheralLinkBase(BaseModel):
"""Base schema for peripheral links"""
link_type: str = Field(..., max_length=50) # manufacturer, support, drivers, documentation, custom
label: str = Field(..., min_length=1, max_length=255)
url: str
class PeripheralLinkCreate(PeripheralLinkBase):
"""Schema for creating a link"""
peripheral_id: int
class PeripheralLinkSchema(PeripheralLinkBase):
"""Full link schema"""
id: int
peripheral_id: int
class Config:
from_attributes = True
# ========================================
# LOAN SCHEMAS
# ========================================
class LoanBase(BaseModel):
"""Base schema for loans"""
emprunte_par: str = Field(..., min_length=1, max_length=255)
email_emprunteur: Optional[str] = Field(None, max_length=255)
telephone: Optional[str] = Field(None, max_length=50)
date_pret: date
date_retour_prevue: date
caution_montant: Optional[float] = Field(None, ge=0)
etat_depart: Optional[str] = Field(None, max_length=50)
raison_pret: Optional[str] = None
notes: Optional[str] = None
class LoanCreate(LoanBase):
"""Schema for creating a loan"""
peripheral_id: int
class LoanReturn(BaseModel):
"""Schema for returning a loan"""
date_retour_effectif: date
etat_retour: Optional[str] = Field(None, max_length=50)
problemes_retour: Optional[str] = None
caution_rendue: bool = True
notes: Optional[str] = None
class LoanSchema(LoanBase):
"""Full loan schema"""
id: int
peripheral_id: int
date_retour_effectif: Optional[date]
statut: str
caution_rendue: bool
etat_retour: Optional[str]
problemes_retour: Optional[str]
created_by: Optional[str]
rappel_envoye: bool
date_rappel: Optional[datetime]
class Config:
from_attributes = True
# ========================================
# LOCATION SCHEMAS
# ========================================
class LocationBase(BaseModel):
"""Base schema for locations"""
nom: str = Field(..., min_length=1, max_length=255)
type: str = Field(..., max_length=50) # root, piece, placard, tiroir, etagere, meuble, boite
parent_id: Optional[int] = None
description: Optional[str] = None
ordre_affichage: Optional[int] = 0
class LocationCreate(LocationBase):
"""Schema for creating a location"""
pass
class LocationUpdate(BaseModel):
"""Schema for updating a location"""
nom: Optional[str] = Field(None, min_length=1, max_length=255)
type: Optional[str] = Field(None, max_length=50)
parent_id: Optional[int] = None
description: Optional[str] = None
ordre_affichage: Optional[int] = None
class LocationSchema(LocationBase):
"""Full location schema"""
id: int
image_path: Optional[str]
qr_code_path: Optional[str]
class Config:
from_attributes = True
class LocationTreeNode(LocationSchema):
"""Location with children for tree view"""
children: List['LocationTreeNode'] = []
class Config:
from_attributes = True
# ========================================
# HISTORY SCHEMAS
# ========================================
class PeripheralHistorySchema(BaseModel):
"""Peripheral location history schema"""
id: int
peripheral_id: int
from_location_id: Optional[int]
to_location_id: Optional[int]
from_device_id: Optional[int]
to_device_id: Optional[int]
action: str
timestamp: datetime
notes: Optional[str]
user: Optional[str]
class Config:
from_attributes = True