Files
home_stock/backend/app/models/document.py
2026-01-28 19:22:30 +01:00

86 lines
2.9 KiB
Python

"""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"<Document(id={self.id}, type={self.type.value}, filename='{self.filename}')>"