kamau1's picture
refactor: unify storage integrations and clean up dead services
d0a01ab
"""
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"<Document(id='{self.id}', entity='{self.entity_type}:{self.entity_id}', file='{self.file_name}')>"