feat(tickets): complete governed ticket workspace

This commit is contained in:
2026-08-22 11:57:53 +02:00
parent c128d51844
commit a9faafb2dc
6 changed files with 377 additions and 5 deletions
+50
View File
@@ -65,6 +65,15 @@ export type TicketAvailability = {
consequences: Record<string, string>;
};
export type TicketHistoryEntry = {
revision: number;
event_type: string;
occurred_at: string;
actor_id?: string | null;
reason: string;
details: Record<string, unknown>;
};
export function listTickets(
settings: ApiSettings,
options: { statuses?: string[]; priorities?: string[]; ticketTypes?: string[]; queueRef?: string; query?: string; limit?: number },
@@ -84,6 +93,14 @@ export function getTicketAvailability(settings: ApiSettings, signal?: AbortSigna
return apiFetch(settings, "/api/v1/tickets/availability", { signal });
}
export function getTicket(settings: ApiSettings, ticketId: string, signal?: AbortSignal): Promise<TicketRecord> {
return apiFetch(settings, `/api/v1/tickets/${encodeURIComponent(ticketId)}`, { signal });
}
export function listTicketHistory(settings: ApiSettings, ticketId: string, signal?: AbortSignal): Promise<{ history: TicketHistoryEntry[] }> {
return apiFetch(settings, `/api/v1/tickets/${encodeURIComponent(ticketId)}/history`, { signal });
}
export function createTicket(settings: ApiSettings, record: TicketRecord): Promise<TicketRecord> {
return apiFetch(settings, "/api/v1/tickets", {
method: "POST",
@@ -114,6 +131,27 @@ export function assignTicket(settings: ApiSettings, record: TicketRecord, assign
});
}
export function replaceTicketParticipants(settings: ApiSettings, record: TicketRecord, participants: TicketSubject[], changeReason: string): Promise<TicketRecord> {
return apiFetch(settings, `/api/v1/tickets/${encodeURIComponent(record.ticket_id)}/participants`, {
method: "PUT",
body: JSON.stringify({ ...mutation(record, changeReason), participants })
});
}
export function addTicketLink(settings: ApiSettings, record: TicketRecord, link: TicketLink, changeReason: string): Promise<TicketRecord> {
return apiFetch(settings, `/api/v1/tickets/${encodeURIComponent(record.ticket_id)}/links`, {
method: "POST",
body: JSON.stringify({ ...mutation(record, changeReason), link })
});
}
export function removeTicketLink(settings: ApiSettings, record: TicketRecord, linkId: string, changeReason: string): Promise<TicketRecord> {
return apiFetch(settings, `/api/v1/tickets/${encodeURIComponent(record.ticket_id)}/links/${encodeURIComponent(linkId)}`, {
method: "DELETE",
body: JSON.stringify({ ...mutation(record, changeReason), changes: {} })
});
}
export function resolveTicket(
settings: ApiSettings,
record: TicketRecord,
@@ -153,3 +191,15 @@ export function escalateTicket(settings: ApiSettings, record: TicketRecord, case
})
}) as Promise<{ ticket: TicketRecord; escalation: Record<string, unknown> }>;
}
export function deleteTicket(settings: ApiSettings, record: TicketRecord, reason: string): Promise<TicketRecord> {
return apiFetch(settings, `/api/v1/tickets/${encodeURIComponent(record.ticket_id)}`, {
method: "DELETE",
body: JSON.stringify({
expected_revision: record.revision,
occurred_at: new Date().toISOString(),
reason,
idempotency_key: crypto.randomUUID()
})
});
}