perf: switch ticket modal from live API to Postgres

- New GET /api/tickets/by-number/[ticketNumber]: single query with resources
  join, returns ticket + picklist labels (status/priority cached per deploy)
- /api/tickets/[id]/notes: Postgres ticket_notes + resources join (was N+1 API calls)
- /api/tickets/[id]/time-entries: Postgres time_entries + resources join (was N+1 API calls)
- Modal: replaces 2-step fetch (all tickets → by id) with single by-number lookup
This commit is contained in:
lorentz 2026-03-23 11:09:29 -04:00
parent cb4552a3eb
commit 5dfd68affd
4 changed files with 112 additions and 82 deletions

View file

@ -66,23 +66,14 @@ export function TicketDetailModal({ ticketNumber, open, onOpenChange }: TicketDe
setTimelineOpen(false);
setShowSystem(false);
try {
const response = await fetch('/api/tickets');
const response = await fetch(`/api/tickets/by-number/${encodeURIComponent(ticketNumber)}`);
if (response.ok) {
const data = await response.json();
const matchingTicket = data.tickets?.find((t: any) => t.ticketNumber === ticketNumber);
if (matchingTicket) {
const detailResponse = await fetch(`/api/tickets/${matchingTicket.id}`);
if (detailResponse.ok) {
const detailData = await detailResponse.json();
setTicket(detailData.ticket);
} else {
setError('Failed to fetch ticket details');
}
} else {
setError(`Ticket ${ticketNumber} not found`);
}
setTicket(data.ticket);
} else if (response.status === 404) {
setError(`Ticket ${ticketNumber} not found`);
} else {
setError('Failed to fetch tickets list');
setError('Failed to fetch ticket details');
}
} catch (err) {
setError('Failed to fetch ticket');