""" TicketIssue Model - ServiceManagerWeb Asuntos de escalación asociados a tickets. Creados por el dueño del ticket o el CLIENT_ADMIN del tenant. """ from sqlalchemy import String, ForeignKey, Text, Table, Column from sqlalchemy.orm import Mapped, mapped_column, relationship from typing import Optional, List from datetime import datetime import enum import uuid from app.core.database import Base, GUID from app.models.ticket import TicketPriority from sqlalchemy import Enum as SAEnum from sqlalchemy.dialects.postgresql import ENUM as PG_ENUM class IssueStatus(str, enum.Enum): OPEN = "OPEN" IN_PROGRESS = "IN_PROGRESS" RESOLVED = "RESOLVED" CLOSED = "CLOSED" # Tabla de relación N:M entre TicketIssue y User (usuarios etiquetados) ticket_issue_tagged_users = Table( "ticket_issue_tagged_users", Base.metadata, Column( "issue_id", GUID(), ForeignKey("ticket_issues.id", ondelete="CASCADE"), primary_key=True, nullable=False, ), Column( "user_id", GUID(), ForeignKey("users.id", ondelete="CASCADE"), primary_key=True, nullable=False, ), ) class TicketIssue(Base): __tablename__ = "ticket_issues" tenant_id: Mapped[uuid.UUID] = mapped_column( GUID(), ForeignKey("tenants.id", ondelete="CASCADE"), nullable=False, ) ticket_id: Mapped[uuid.UUID] = mapped_column( GUID(), ForeignKey("tickets.id", ondelete="CASCADE"), nullable=False, ) created_by: Mapped[uuid.UUID] = mapped_column( GUID(), ForeignKey("users.id"), nullable=False, ) content: Mapped[str] = mapped_column(Text, nullable=False) priority: Mapped[TicketPriority] = mapped_column( SAEnum(TicketPriority, name="ticket_priority_enum", native_enum=False).with_variant( PG_ENUM(TicketPriority, name="ticket_priority_enum", create_type=True), "postgresql", ), default=TicketPriority.MEDIUM, nullable=False, ) status: Mapped[IssueStatus] = mapped_column( SAEnum(IssueStatus, name="issue_status_enum", native_enum=False).with_variant( PG_ENUM(IssueStatus, name="issue_status_enum", create_type=True), "postgresql", ), default=IssueStatus.OPEN, nullable=False, ) attachment_path: Mapped[Optional[str]] = mapped_column(String(500), nullable=True) attachment_filename: Mapped[Optional[str]] = mapped_column(String(255), nullable=True) attachment_mime_type: Mapped[Optional[str]] = mapped_column(String(100), nullable=True) ticket: Mapped["Ticket"] = relationship("Ticket", back_populates="issues") created_by_user: Mapped["User"] = relationship("User", foreign_keys=[created_by]) tagged_users: Mapped[List["User"]] = relationship( "User", secondary=ticket_issue_tagged_users, ) def __repr__(self) -> str: return f""