102 lines
3.9 KiB
Python
102 lines
3.9 KiB
Python
from fastapi import APIRouter, Depends, Query
|
|
from uuid import UUID
|
|
from sqlalchemy.ext.asyncio import AsyncSession
|
|
from database.postgres import get_pg_session
|
|
from auth.dependencies import require_permission
|
|
from auth.models import TokenPayload
|
|
from tickets import service
|
|
from tickets.models import TicketCreate, TicketUpdate, MessageCreate, EscalateIn, TicketOut, TicketListResponse
|
|
from shared.audit import log_action
|
|
|
|
router = APIRouter(prefix="/api/tickets", tags=["tickets"])
|
|
|
|
|
|
@router.get("", response_model=TicketListResponse)
|
|
async def list_tickets(
|
|
status: str | None = Query(None),
|
|
priority: str | None = Query(None),
|
|
customer_id: str | None = Query(None),
|
|
page: int = Query(1, ge=1),
|
|
limit: int = Query(25, ge=1, le=100),
|
|
db: AsyncSession = Depends(get_pg_session),
|
|
_user: TokenPayload = Depends(require_permission("crm", "view")),
|
|
):
|
|
rows, total = await service.list_tickets(db, status, priority, customer_id, page, limit)
|
|
return {"data": rows, "pagination": {"page": page, "limit": limit, "total": total}}
|
|
|
|
|
|
@router.get("/by-customer/{customer_id}", response_model=list[TicketOut])
|
|
async def list_by_customer(
|
|
customer_id: str,
|
|
db: AsyncSession = Depends(get_pg_session),
|
|
_user: TokenPayload = Depends(require_permission("crm", "view")),
|
|
):
|
|
return await service.list_by_customer(db, customer_id)
|
|
|
|
|
|
@router.get("/by-device/{device_id}", response_model=list[TicketOut])
|
|
async def list_by_device(
|
|
device_id: str,
|
|
db: AsyncSession = Depends(get_pg_session),
|
|
_user: TokenPayload = Depends(require_permission("crm", "view")),
|
|
):
|
|
return await service.list_by_device(db, device_id)
|
|
|
|
|
|
@router.get("/{ticket_id}", response_model=TicketOut)
|
|
async def get_ticket(
|
|
ticket_id: UUID,
|
|
db: AsyncSession = Depends(get_pg_session),
|
|
_user: TokenPayload = Depends(require_permission("crm", "view")),
|
|
):
|
|
return await service.get_ticket(db, ticket_id)
|
|
|
|
|
|
@router.post("", response_model=TicketOut, status_code=201)
|
|
async def create_ticket(
|
|
body: TicketCreate,
|
|
db: AsyncSession = Depends(get_pg_session),
|
|
_user: TokenPayload = Depends(require_permission("crm", "add")),
|
|
):
|
|
ticket = await service.create_ticket(db, body)
|
|
await log_action(db, _user.sub, _user.name or _user.email, "CREATE", "ticket",
|
|
str(ticket.id), ticket.subject)
|
|
return ticket
|
|
|
|
|
|
@router.patch("/{ticket_id}", response_model=TicketOut)
|
|
async def update_ticket(
|
|
ticket_id: UUID, body: TicketUpdate,
|
|
db: AsyncSession = Depends(get_pg_session),
|
|
_user: TokenPayload = Depends(require_permission("crm", "edit")),
|
|
):
|
|
ticket = await service.update_ticket(db, ticket_id, body)
|
|
action = "STATUS_CHANGE" if body.status is not None else "UPDATE"
|
|
await log_action(db, _user.sub, _user.name or _user.email, action, "ticket",
|
|
str(ticket_id), ticket.subject)
|
|
return ticket
|
|
|
|
|
|
@router.post("/{ticket_id}/messages", response_model=TicketOut)
|
|
async def add_message(
|
|
ticket_id: UUID, body: MessageCreate,
|
|
db: AsyncSession = Depends(get_pg_session),
|
|
_user: TokenPayload = Depends(require_permission("crm", "edit")),
|
|
):
|
|
ticket = await service.add_message(db, ticket_id, body)
|
|
await log_action(db, _user.sub, _user.name or _user.email, "UPDATE", "ticket",
|
|
str(ticket_id), ticket.subject, meta={"action_detail": "message_added"})
|
|
return ticket
|
|
|
|
|
|
@router.post("/{ticket_id}/escalate", response_model=TicketOut)
|
|
async def escalate(
|
|
ticket_id: UUID, body: EscalateIn,
|
|
db: AsyncSession = Depends(get_pg_session),
|
|
_user: TokenPayload = Depends(require_permission("crm", "edit")),
|
|
):
|
|
ticket = await service.escalate_to_issue(db, ticket_id, body.entry_id)
|
|
await log_action(db, _user.sub, _user.name or _user.email, "STATUS_CHANGE", "ticket",
|
|
str(ticket_id), ticket.subject, meta={"action_detail": "escalated_to_issue"})
|
|
return ticket
|