from sqlalchemy import ForeignKey, Integer, String, text from sqlalchemy.orm import Mapped, mapped_column from api.v1.common.base_models import TenantScopedMixin, TimestampMixin from core.database import Base class Case(Base, TenantScopedMixin, TimestampMixin): """Expediente: hilo maestro de un trámite (Oportunidad → Solicitud → Cotización → Operación → Factura). Una sola referencia (``EXP…``) que agrupa toda la historia. Nace al crear la Oportunidad y se hereda a las entidades siguientes vía ``case_id``. """ __tablename__ = "cases" __table_args__ = {"schema": "crm"} id: Mapped[int] = mapped_column(Integer, primary_key=True, index=True) reference: Mapped[str | None] = mapped_column(String(40), nullable=True, index=True) # folio EXP... account_id: Mapped[int | None] = mapped_column( Integer, ForeignKey("crm.accounts.id"), nullable=True, index=True ) title: Mapped[str | None] = mapped_column(String(255), nullable=True) # Etapa más avanzada alcanzada: oportunidad|solicitud|cotizacion|operacion|facturacion|cerrado stage: Mapped[str] = mapped_column(String(20), nullable=False, server_default=text("'oportunidad'")) # abierto | cerrado status: Mapped[str] = mapped_column(String(20), nullable=False, server_default=text("'abierto'"), index=True) created_by: Mapped[str | None] = mapped_column(String(64), nullable=True) updated_by: Mapped[str | None] = mapped_column(String(64), nullable=True)