47 lines
2.3 KiB
Python
47 lines
2.3 KiB
Python
import uuid
|
|
from datetime import datetime, timezone
|
|
from sqlalchemy import Column, String, Text, DateTime, Boolean, ForeignKey
|
|
from sqlalchemy.dialects.postgresql import UUID
|
|
from sqlalchemy.orm import relationship
|
|
from database.postgres import Base
|
|
|
|
|
|
def _now():
|
|
return datetime.now(timezone.utc)
|
|
|
|
|
|
class SupportTicket(Base):
|
|
__tablename__ = "support_tickets"
|
|
|
|
id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
|
|
customer_id = Column(String(128), nullable=False) # Firestore ID (moves to UUID when customers migrate)
|
|
customer_name = Column(String(255), nullable=True) # denormalized snapshot
|
|
device_id = Column(String(128), nullable=True) # Firestore ID
|
|
device_serial = Column(String(64), nullable=True) # denormalized snapshot
|
|
subject = Column(String(500), nullable=False)
|
|
status = Column(String(30), nullable=False, default="open")
|
|
# open | waiting_on_customer | waiting_on_staff | resolved | closed
|
|
priority = Column(String(10), nullable=True) # low | medium | high | urgent
|
|
opened_via = Column(String(20), nullable=True) # app | email | phone | staff
|
|
linked_entry_id = Column(UUID(as_uuid=True), ForeignKey("crm_entries.id", ondelete="SET NULL"), nullable=True)
|
|
created_at = Column(DateTime(timezone=True), nullable=False, default=_now)
|
|
updated_at = Column(DateTime(timezone=True), nullable=False, default=_now, onupdate=_now)
|
|
|
|
messages = relationship("TicketMessage", back_populates="ticket",
|
|
cascade="all, delete-orphan", order_by="TicketMessage.created_at", lazy="noload")
|
|
|
|
|
|
class TicketMessage(Base):
|
|
__tablename__ = "ticket_messages"
|
|
|
|
id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
|
|
ticket_id = Column(UUID(as_uuid=True), ForeignKey("support_tickets.id", ondelete="CASCADE"), nullable=False)
|
|
sender_type = Column(String(10), nullable=False) # 'staff' | 'customer'
|
|
sender_id = Column(String(128), nullable=False)
|
|
sender_name = Column(String(255), nullable=True)
|
|
body = Column(Text, nullable=False)
|
|
is_internal = Column(Boolean, nullable=False, default=False)
|
|
created_at = Column(DateTime(timezone=True), nullable=False, default=_now)
|
|
|
|
ticket = relationship("SupportTicket", back_populates="messages")
|