Files
denya-onecare/app/schemas/ticket.py

118 lines
3.4 KiB
Python

"""Pydantic schemas for ticket CRUD, timeline, photos, and SLA."""
from __future__ import annotations
from datetime import datetime
from decimal import Decimal
from pydantic import BaseModel, Field
# ── Category ─────────────────────────────────────────────────────────
class CategoryOut(BaseModel):
id: int
type: str
name: str
parent_id: int | None = None
sla_urgency: str | None = None
model_config = {"from_attributes": True}
class CategoryTreeOut(CategoryOut):
children: list[CategoryTreeOut] = []
# ── Ticket ───────────────────────────────────────────────────────────
class TicketCreate(BaseModel):
unit_id: int | None = None
category_id: int | None = None
priority: str | None = None # urgent, high, medium, low
reporter: str | None = None
reported_via: str | None = None # whatsapp, phone, walk-in, qr, agent
description: str | None = None
assigned_to: int | None = None
class TicketUpdate(BaseModel):
status: str | None = None
unit_id: int | None = None
category_id: int | None = None
priority: str | None = None
reporter: str | None = None
reported_via: str | None = None
description: str | None = None
assigned_to: int | None = None
eta: datetime | None = None
cost: Decimal | None = None
parts_used: str | None = None
class TicketTimelineOut(BaseModel):
id: int
ticket_id: int
from_status: str | None = None
to_status: str | None = None
note: str | None = None
user_id: int | None = None
created_at: datetime
model_config = {"from_attributes": True}
class TicketPhotoOut(BaseModel):
id: int
ticket_id: int
photo_url: str
is_before: bool
model_config = {"from_attributes": True}
class TicketBrief(BaseModel):
"""Summary view for list endpoints."""
id: int
ticket_number: str
status: str
priority: str | None = None
unit_id: int | None = None
category_id: int | None = None
assigned_to: int | None = None
reporter: str | None = None
description: str | None = None
sla_deadline: datetime | None = None
reopen_count: int = 0
created_at: datetime
updated_at: datetime
model_config = {"from_attributes": True}
class TicketOut(TicketBrief):
"""Full ticket detail with relations."""
closed_at: datetime | None = None
eta: datetime | None = None
cost: Decimal | None = None
parts_used: str | None = None
customer_rating: int | None = None
timeline: list[TicketTimelineOut] = []
photos: list[TicketPhotoOut] = []
sla_status: dict | None = None
class TicketListResponse(BaseModel):
items: list[TicketBrief]
total: int
page: int
page_size: int
# ── SLA ──────────────────────────────────────────────────────────────
class SLAStatusOut(BaseModel):
priority: str | None = None
response_deadline: str | None = None
resolution_deadline: str | None = None
response_breached: bool = False
resolution_breached: bool = False
current_status: str | None = None