"""SQLAlchemy model for image retouch results.""" import enum import uuid from datetime import datetime from typing import TYPE_CHECKING from sqlalchemy import DateTime, ForeignKey, String, Text, func from sqlalchemy.dialects.postgresql import UUID from sqlalchemy.orm import Mapped, mapped_column, relationship from app.database import Base if TYPE_CHECKING: from app.models.vehicle import Vehicle class RetouchStatus(str, enum.Enum): pending = "pending" processing = "processing" completed = "completed" failed = "failed" class RetouchResult(Base): """Retouch result entity tracking image retouching via Flux.1-Pro.""" __tablename__ = "retouch_results" id: Mapped[uuid.UUID] = mapped_column( UUID(as_uuid=True), primary_key=True, default=uuid.uuid4, ) vehicle_id: Mapped[uuid.UUID | None] = mapped_column( UUID(as_uuid=True), ForeignKey("vehicles.id", ondelete="SET NULL"), nullable=True, index=True, ) original_file_path: Mapped[str] = mapped_column(String(512), nullable=False) original_file_name: Mapped[str] = mapped_column(String(255), nullable=False) mime_type: Mapped[str] = mapped_column( String(100), nullable=False, default="image/png" ) retouched_file_path: Mapped[str | None] = mapped_column(String(512), nullable=True) status: Mapped[str] = mapped_column(String(20), nullable=False, default="pending") error_message: Mapped[str | None] = mapped_column(Text, nullable=True) created_at: Mapped[datetime] = mapped_column( DateTime(timezone=True), nullable=False, server_default=func.now(), ) updated_at: Mapped[datetime] = mapped_column( DateTime(timezone=True), nullable=False, server_default=func.now(), onupdate=func.now(), ) vehicle: Mapped["Vehicle"] = relationship("Vehicle") def __repr__(self) -> str: return f"" def to_dict(self) -> dict: """Serialize retouch result for API responses.""" return { "id": str(self.id), "vehicle_id": str(self.vehicle_id) if self.vehicle_id else None, "original_file_path": self.original_file_path, "original_file_name": self.original_file_name, "mime_type": self.mime_type, "retouched_file_path": self.retouched_file_path, "status": self.status, "error_message": self.error_message, "created_at": (self.created_at.isoformat() if self.created_at else None), "updated_at": (self.updated_at.isoformat() if self.updated_at else None), }