"""Modèle SQLAlchemy pour les documents attachés aux objets. Les documents peuvent être des photos, notices d'utilisation, factures, etc. Ils sont stockés sur le système de fichiers local. """ from datetime import datetime from typing import TYPE_CHECKING from sqlalchemy import DateTime, Enum, ForeignKey, Integer, String from sqlalchemy.orm import Mapped, mapped_column, relationship from sqlalchemy.sql import func from app.core.database import Base if TYPE_CHECKING: from app.models.item import Item import enum class DocumentType(str, enum.Enum): """Type de document.""" PHOTO = "photo" # Photo de l'objet MANUAL = "manual" # Notice d'utilisation INVOICE = "invoice" # Facture d'achat WARRANTY = "warranty" # Garantie OTHER = "other" # Autre class Document(Base): """Document attaché à un objet. Attributes: id: Identifiant unique auto-incrémenté filename: Nom du fichier sur le disque (UUID + extension) original_name: Nom original du fichier uploadé type: Type de document (photo/manual/invoice/warranty/other) mime_type: Type MIME (ex: "image/jpeg", "application/pdf") size_bytes: Taille du fichier en octets file_path: Chemin relatif du fichier (ex: "uploads/photos/uuid.jpg") description: Description optionnelle item_id: ID de l'objet associé (FK) created_at: Date/heure de création (auto) updated_at: Date/heure de dernière modification (auto) item: Relation vers l'objet """ __tablename__ = "documents" # Colonnes id: Mapped[int] = mapped_column(primary_key=True, autoincrement=True) filename: Mapped[str] = mapped_column(String(255), nullable=False, unique=True) original_name: Mapped[str] = mapped_column(String(255), nullable=False) type: Mapped[DocumentType] = mapped_column( Enum(DocumentType, native_enum=False, length=20), nullable=False ) mime_type: Mapped[str] = mapped_column(String(100), nullable=False) size_bytes: Mapped[int] = mapped_column(Integer, nullable=False) file_path: Mapped[str] = mapped_column(String(500), nullable=False) description: Mapped[str | None] = mapped_column(String(500), nullable=True) # Foreign Key item_id: Mapped[int] = mapped_column( Integer, ForeignKey("items.id", ondelete="CASCADE"), nullable=False, index=True ) # Timestamps created_at: Mapped[datetime] = mapped_column( DateTime(timezone=True), server_default=func.now(), nullable=False ) updated_at: Mapped[datetime] = mapped_column( DateTime(timezone=True), server_default=func.now(), onupdate=func.now(), nullable=False, ) # Relations item: Mapped["Item"] = relationship("Item", back_populates="documents") def __repr__(self) -> str: """Représentation string du document.""" return f""