102 lines
3.0 KiB
Python
102 lines
3.0 KiB
Python
"""
|
|
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 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
|
|
|
|
|
|
# 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):
|
|
"""
|
|
Asunto de escalación de un ticket.
|
|
|
|
Solo puede crearlo:
|
|
- El usuario que creó el ticket (created_by del Ticket)
|
|
- El CLIENT_ADMIN del mismo tenant
|
|
"""
|
|
__tablename__ = "ticket_issues"
|
|
|
|
# Multi-tenancy — siempre filtrar por esto
|
|
tenant_id: Mapped[uuid.UUID] = mapped_column(
|
|
GUID(),
|
|
ForeignKey("tenants.id", ondelete="CASCADE"),
|
|
nullable=False,
|
|
)
|
|
|
|
# Relación con el ticket padre
|
|
ticket_id: Mapped[uuid.UUID] = mapped_column(
|
|
GUID(),
|
|
ForeignKey("tickets.id", ondelete="CASCADE"),
|
|
nullable=False,
|
|
)
|
|
|
|
# Quién lo creó
|
|
created_by: Mapped[uuid.UUID] = mapped_column(
|
|
GUID(),
|
|
ForeignKey("users.id"),
|
|
nullable=False,
|
|
)
|
|
|
|
# Contenido
|
|
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,
|
|
)
|
|
|
|
# Adjunto opcional (reutiliza file_handler igual que TicketAttachment)
|
|
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)
|
|
|
|
# Relationships
|
|
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"<TicketIssue(id={self.id}, ticket={self.ticket_id}, priority={self.priority})>" |