""" Document Model - Universal file storage with polymorphic ownership """ from sqlalchemy import Column, String, Boolean, Integer, Text, BigInteger from sqlalchemy.dialects.postgresql import UUID, JSONB from datetime import datetime from app.core.database import Base import uuid class Document(Base): """ Document model - Universal file storage for all entities Supports versioning and multiple storage providers (Cloudinary, Supabase) """ __tablename__ = "documents" id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4) # Ownership (polymorphic) entity_type = Column(Text, nullable=False) # 'user', 'project', 'ticket', 'client', 'contractor' entity_id = Column(UUID(as_uuid=True), nullable=False) # File Details file_name = Column(Text, nullable=False) file_type = Column(Text) # MIME type (e.g., 'image/jpeg', 'application/pdf') file_size = Column(BigInteger) # File size in bytes file_url = Column(Text, nullable=False) # Storage URL storage_provider = Column(Text, default='supabase') # 'cloudinary', 'supabase', 'local' # Document Classification document_type = Column(Text) # 'profile_photo', 'identity_card', 'contract', 'invoice', 'ticket_image' document_category = Column(Text) # 'legal', 'financial', 'operational', 'evidence' # Version Control version = Column(Integer, default=1) is_latest_version = Column(Boolean, default=True) previous_version_id = Column(UUID(as_uuid=True), nullable=True) # Metadata description = Column(Text) tags = Column(JSONB, default=list) # Array of tags for search additional_metadata = Column(JSONB, default=dict) # GPS, OCR text, Cloudinary response, etc. # Access Control uploaded_by_user_id = Column(UUID(as_uuid=True), nullable=True) is_public = Column(Boolean, default=False) # Timestamps created_at = Column(String(50), default=lambda: datetime.utcnow().isoformat()) updated_at = Column(String(50), default=lambda: datetime.utcnow().isoformat()) deleted_at = Column(String(50), nullable=True) def __repr__(self): return f""