from datetime import datetime, timezone from typing import Any, Optional from sqlalchemy import DateTime, ForeignKey, Index, JSON, String, Text, UniqueConstraint from sqlalchemy.orm import Mapped, mapped_column from app.db import Base class ContractLifecycleTask(Base): __tablename__ = "contract_lifecycle_tasks" __table_args__ = ( UniqueConstraint("tenant_id", "task_key", name="uq_contract_lifecycle_tasks_tenant_task_key"), Index("ix_contract_lifecycle_tasks_tenant_contract", "tenant_id", "contract_id"), Index("ix_contract_lifecycle_tasks_tenant_status", "tenant_id", "status"), Index("ix_contract_lifecycle_tasks_tenant_due_at", "tenant_id", "due_at"), ) id: Mapped[str] = mapped_column(String(64), primary_key=True) tenant_id: Mapped[str] = mapped_column(String(64), nullable=False, index=True) contract_id: Mapped[str] = mapped_column(String(64), ForeignKey("generated_contracts.id"), nullable=False, index=True) task_key: Mapped[str] = mapped_column(String(160), nullable=False) task_type: Mapped[str] = mapped_column(String(64), nullable=False, index=True) title: Mapped[str] = mapped_column(String(200), nullable=False) description: Mapped[Optional[str]] = mapped_column(Text, nullable=True) priority: Mapped[str] = mapped_column(String(32), nullable=False, default="medium", index=True) status: Mapped[str] = mapped_column(String(32), nullable=False, default="open", index=True) due_at: Mapped[Optional[datetime]] = mapped_column(DateTime(timezone=True), nullable=True, index=True) completed_by: Mapped[Optional[str]] = mapped_column(String(64), nullable=True) completed_at: Mapped[Optional[datetime]] = mapped_column(DateTime(timezone=True), nullable=True) evidence_file_id: Mapped[Optional[str]] = mapped_column(String(64), ForeignKey("files.id"), nullable=True, index=True) evidence_note: Mapped[Optional[str]] = mapped_column(Text, nullable=True) metadata_json: Mapped[Optional[dict[str, Any]]] = mapped_column(JSON, nullable=True) created_by: Mapped[Optional[str]] = mapped_column(String(64), nullable=True) created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), default=lambda: datetime.now(timezone.utc), index=True) updated_at: Mapped[datetime] = mapped_column( DateTime(timezone=True), default=lambda: datetime.now(timezone.utc), onupdate=lambda: datetime.now(timezone.utc), )