generated from gilles/template-webapp
86 lines
2.9 KiB
Python
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}')>"
|