use serde::{Deserialize, Serialize}; use chrono::{DateTime, Utc}; use uuid::Uuid; /// Represents the status of a support ticket #[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] pub enum TicketStatus { /// Ticket has been opened but not yet addressed Open, /// Ticket is currently being worked on InProgress, /// Ticket is waiting for customer response WaitingForCustomer, /// Ticket has been resolved Resolved, /// Ticket has been closed without resolution Closed, } impl std::fmt::Display for TicketStatus { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match self { TicketStatus::Open => write!(f, "Open"), TicketStatus::InProgress => write!(f, "In Progress"), TicketStatus::WaitingForCustomer => write!(f, "Waiting for Customer"), TicketStatus::Resolved => write!(f, "Resolved"), TicketStatus::Closed => write!(f, "Closed"), } } } /// Represents the priority of a support ticket #[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] pub enum TicketPriority { /// Low priority ticket Low, /// Medium priority ticket Medium, /// High priority ticket High, /// Critical priority ticket Critical, } impl std::fmt::Display for TicketPriority { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match self { TicketPriority::Low => write!(f, "Low"), TicketPriority::Medium => write!(f, "Medium"), TicketPriority::High => write!(f, "High"), TicketPriority::Critical => write!(f, "Critical"), } } } /// Represents a support ticket in the system #[derive(Debug, Clone, Serialize, Deserialize)] pub struct Ticket { /// Unique identifier for the ticket pub id: String, /// User ID of the ticket creator pub user_id: i32, /// Title of the ticket pub title: String, /// Description of the issue pub description: String, /// Current status of the ticket pub status: TicketStatus, /// Priority level of the ticket pub priority: TicketPriority, /// When the ticket was created pub created_at: DateTime, /// When the ticket was last updated pub updated_at: DateTime, /// User ID of the assigned support agent (if any) pub assigned_to: Option, } impl Ticket { /// Creates a new ticket pub fn new(user_id: i32, title: String, description: String, priority: TicketPriority) -> Self { let now = Utc::now(); Self { id: Uuid::new_v4().to_string(), user_id, title, description, status: TicketStatus::Open, priority, created_at: now, updated_at: now, assigned_to: None, } } /// Updates the ticket status pub fn update_status(&mut self, status: TicketStatus) { self.status = status; self.updated_at = Utc::now(); } /// Assigns the ticket to a support agent pub fn assign(&mut self, agent_id: i32) { self.assigned_to = Some(agent_id); self.updated_at = Utc::now(); } /// Unassigns the ticket from any support agent pub fn unassign(&mut self) { self.assigned_to = None; self.updated_at = Utc::now(); } /// Updates the ticket priority pub fn update_priority(&mut self, priority: TicketPriority) { self.priority = priority; self.updated_at = Utc::now(); } } /// Represents a comment on a support ticket #[derive(Debug, Clone, Serialize, Deserialize)] pub struct TicketComment { /// Unique identifier for the comment pub id: String, /// ID of the ticket this comment belongs to pub ticket_id: String, /// User ID of the comment author pub user_id: i32, /// Content of the comment pub content: String, /// When the comment was created pub created_at: DateTime, /// Whether this comment is from a support agent pub is_support_response: bool, } impl TicketComment { /// Creates a new ticket comment pub fn new(ticket_id: String, user_id: i32, content: String, is_support_response: bool) -> Self { Self { id: Uuid::new_v4().to_string(), ticket_id, user_id, content, created_at: Utc::now(), is_support_response, } } } /// Represents a filter for searching tickets #[derive(Debug, Clone, Serialize, Deserialize)] pub struct TicketFilter { /// Filter by ticket status pub status: Option, /// Filter by ticket priority pub priority: Option, /// Filter by assigned agent pub assigned_to: Option, /// Filter by user who created the ticket pub user_id: Option, /// Search term for title and description pub search_term: Option, } impl Default for TicketFilter { fn default() -> Self { Self { status: None, priority: None, assigned_to: None, user_id: None, search_term: None, } } }