PromptWar / models /queue.py
Mr-TD's picture
feat: Add operator dashboard, alerts, analytics, and simulator pages
aefe381
"""Queue and wait-time models."""
from dataclasses import dataclass, field
from datetime import datetime
from typing import Optional
from enum import Enum
import uuid
class QueueCategory(Enum):
"""Category of service queue."""
FOOD = "food"
MERCHANDISE = "merch"
RESTROOM = "restroom"
ENTRY = "entry"
EXIT = "exit"
TICKET = "ticket"
@property
def icon(self):
return {
"food": "πŸ•",
"merch": "πŸ›οΈ",
"restroom": "🚻",
"entry": "πŸšͺ",
"exit": "🚢",
"ticket": "🎫",
}[self.value]
@property
def label(self):
return {
"food": "Food & Beverages",
"merch": "Merchandise",
"restroom": "Restrooms",
"entry": "Entry Gates",
"exit": "Exit Gates",
"ticket": "Ticket Counter",
}[self.value]
@dataclass
class QueueStation:
"""A single service station (e.g., one food stall)."""
id: str
name: str
category: str # QueueCategory value
zone_id: str
current_length: int = 0
avg_service_time_sec: float = 45.0
is_open: bool = True
lat: float = 0.0
lng: float = 0.0
@property
def estimated_wait_minutes(self) -> float:
if not self.is_open or self.current_length == 0:
return 0.0
return round((self.current_length * self.avg_service_time_sec) / 60, 1)
@property
def wait_level(self) -> str:
wait = self.estimated_wait_minutes
if wait < 5:
return "short"
elif wait < 15:
return "moderate"
elif wait < 30:
return "long"
else:
return "very_long"
@property
def wait_color(self) -> str:
return {
"short": "#22c55e",
"moderate": "#f59e0b",
"long": "#ef4444",
"very_long": "#18181b",
}[self.wait_level]
def to_dict(self) -> dict:
return {
"id": self.id,
"name": self.name,
"category": self.category,
"category_icon": QueueCategory(self.category).icon,
"category_label": QueueCategory(self.category).label,
"zone_id": self.zone_id,
"current_length": self.current_length,
"estimated_wait_minutes": self.estimated_wait_minutes,
"wait_level": self.wait_level,
"wait_color": self.wait_color,
"is_open": self.is_open,
"lat": self.lat,
"lng": self.lng,
}
@dataclass
class VirtualQueueTicket:
"""A virtual queue reservation for an attendee."""
id: str = field(default_factory=lambda: str(uuid.uuid4())[:8].upper())
user_id: str = ""
station_id: str = ""
station_name: str = ""
category: str = ""
position: int = 0
estimated_ready_time: Optional[datetime] = None
status: str = "waiting" # waiting, ready, served, expired
created_at: datetime = field(default_factory=datetime.utcnow)
def to_dict(self) -> dict:
return {
"id": self.id,
"user_id": self.user_id,
"station_id": self.station_id,
"station_name": self.station_name,
"category": self.category,
"category_icon": QueueCategory(self.category).icon if self.category else "",
"position": self.position,
"estimated_ready_time": (
self.estimated_ready_time.isoformat()
if self.estimated_ready_time
else None
),
"status": self.status,
"created_at": self.created_at.isoformat(),
}