102 lines
3.4 KiB
Python
102 lines
3.4 KiB
Python
"""
|
|
Support ticket models for help desk functionality
|
|
"""
|
|
from sqlalchemy import Column, Integer, String, Text, DateTime, Boolean, ForeignKey, Enum
|
|
from sqlalchemy.orm import relationship
|
|
from datetime import datetime
|
|
import enum
|
|
|
|
from app.models.base import BaseModel
|
|
|
|
|
|
class TicketStatus(enum.Enum):
|
|
OPEN = "open"
|
|
IN_PROGRESS = "in_progress"
|
|
RESOLVED = "resolved"
|
|
CLOSED = "closed"
|
|
|
|
|
|
class TicketPriority(enum.Enum):
|
|
LOW = "low"
|
|
MEDIUM = "medium"
|
|
HIGH = "high"
|
|
URGENT = "urgent"
|
|
|
|
|
|
class TicketCategory(enum.Enum):
|
|
BUG_REPORT = "bug_report"
|
|
QA_ISSUE = "qa_issue"
|
|
FEATURE_REQUEST = "feature_request"
|
|
DATABASE_ISSUE = "database_issue"
|
|
SYSTEM_ERROR = "system_error"
|
|
USER_ACCESS = "user_access"
|
|
PERFORMANCE = "performance"
|
|
DOCUMENTATION = "documentation"
|
|
CONFIGURATION = "configuration"
|
|
TESTING = "testing"
|
|
|
|
|
|
class SupportTicket(BaseModel):
|
|
"""
|
|
Support ticket for user help requests
|
|
"""
|
|
__tablename__ = "support_tickets"
|
|
|
|
id = Column(Integer, primary_key=True, autoincrement=True)
|
|
ticket_number = Column(String(20), unique=True, nullable=False, index=True) # Auto-generated like ST-2024-001
|
|
|
|
# Ticket details
|
|
subject = Column(String(200), nullable=False)
|
|
description = Column(Text, nullable=False)
|
|
category = Column(Enum(TicketCategory), default=TicketCategory.BUG_REPORT)
|
|
priority = Column(Enum(TicketPriority), default=TicketPriority.MEDIUM)
|
|
status = Column(Enum(TicketStatus), default=TicketStatus.OPEN)
|
|
|
|
# User information
|
|
user_id = Column(Integer, ForeignKey("users.id"), nullable=True) # Null for anonymous submissions
|
|
contact_name = Column(String(100), nullable=False)
|
|
contact_email = Column(String(100), nullable=False)
|
|
|
|
# System information (auto-detected)
|
|
current_page = Column(String(100)) # Which page they were on
|
|
browser_info = Column(String(200)) # User agent
|
|
ip_address = Column(String(45)) # IP address
|
|
|
|
# Timestamps
|
|
created_at = Column(DateTime, default=datetime.utcnow, nullable=False)
|
|
updated_at = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow)
|
|
resolved_at = Column(DateTime)
|
|
|
|
# Admin assignment
|
|
assigned_to = Column(Integer, ForeignKey("users.id"))
|
|
|
|
# Relationships
|
|
submitter = relationship("User", foreign_keys=[user_id], back_populates="submitted_tickets")
|
|
assigned_admin = relationship("User", foreign_keys=[assigned_to])
|
|
responses = relationship("TicketResponse", back_populates="ticket", cascade="all, delete-orphan")
|
|
|
|
|
|
class TicketResponse(BaseModel):
|
|
"""
|
|
Responses/comments on support tickets
|
|
"""
|
|
__tablename__ = "ticket_responses"
|
|
|
|
id = Column(Integer, primary_key=True, autoincrement=True)
|
|
ticket_id = Column(Integer, ForeignKey("support_tickets.id"), nullable=False)
|
|
|
|
# Response details
|
|
message = Column(Text, nullable=False)
|
|
is_internal = Column(Boolean, default=False) # Internal admin notes vs public responses
|
|
|
|
# Author information
|
|
user_id = Column(Integer, ForeignKey("users.id"), nullable=True)
|
|
author_name = Column(String(100)) # For non-user responses
|
|
author_email = Column(String(100)) # For non-user responses
|
|
|
|
# Timestamps
|
|
created_at = Column(DateTime, default=datetime.utcnow, nullable=False)
|
|
|
|
# Relationships
|
|
ticket = relationship("SupportTicket", back_populates="responses")
|
|
author = relationship("User") |