feat: P4.4 support REST (tickets/escalate/callbacks/queue admin) + kernel-client methods
8 routes under /v1/support (session-auth). RestClient gains createTicket/escalate/ listTickets/patchTicket/requestCallback/createQueue/joinQueue/setAvailability + Ticket/CallbackRequest types. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
import type { IngestInteractionRequest } from '@insignia/iios-contracts';
|
||||
import type { Message, InboxItem, InboxState } from './types';
|
||||
import type { Message, InboxItem, InboxState, Ticket, TicketState, CallbackRequest } from './types';
|
||||
|
||||
export interface RestConfig {
|
||||
serviceUrl: string;
|
||||
@@ -57,6 +57,52 @@ export class RestClient {
|
||||
return (await r.json()) as InboxItem;
|
||||
}
|
||||
|
||||
// ─── support ──────────────────────────────────────────────────
|
||||
async createTicket(body: { subject: string; priority?: string; threadId?: string }): Promise<Ticket> {
|
||||
return this.post<Ticket>('/v1/support/tickets', body);
|
||||
}
|
||||
async escalate(threadId: string, subject?: string): Promise<Ticket> {
|
||||
return this.post<Ticket>('/v1/support/escalate', { threadId, subject });
|
||||
}
|
||||
async listTickets(scope: 'mine' | 'assigned' = 'mine'): Promise<Ticket[]> {
|
||||
const r = await fetch(this.url(`/v1/support/tickets?scope=${scope}`), { headers: this.headers() });
|
||||
if (!r.ok) throw new Error(`listTickets ${r.status}`);
|
||||
return (await r.json()) as Ticket[];
|
||||
}
|
||||
async patchTicket(id: string, state: TicketState): Promise<Ticket> {
|
||||
const r = await fetch(this.url(`/v1/support/tickets/${id}`), {
|
||||
method: 'PATCH',
|
||||
headers: this.headers(),
|
||||
body: JSON.stringify({ state }),
|
||||
});
|
||||
if (!r.ok) throw new Error(`patchTicket ${r.status}`);
|
||||
return (await r.json()) as Ticket;
|
||||
}
|
||||
async requestCallback(body: { preferChannel: string; preferredTime?: string; notes?: string; ticketId?: string }): Promise<CallbackRequest> {
|
||||
return this.post<CallbackRequest>('/v1/support/callbacks', body);
|
||||
}
|
||||
async createQueue(name: string): Promise<{ id: string }> {
|
||||
return this.post<{ id: string }>('/v1/support/queues', { name });
|
||||
}
|
||||
async joinQueue(queueId: string): Promise<unknown> {
|
||||
return this.post('/v1/support/queues/' + queueId + '/members', {});
|
||||
}
|
||||
async setAvailability(state: string): Promise<unknown> {
|
||||
const r = await fetch(this.url('/v1/support/members/me/availability'), {
|
||||
method: 'PATCH',
|
||||
headers: this.headers(),
|
||||
body: JSON.stringify({ state }),
|
||||
});
|
||||
if (!r.ok) throw new Error(`setAvailability ${r.status}`);
|
||||
return r.json();
|
||||
}
|
||||
|
||||
private async post<T>(path: string, body: unknown): Promise<T> {
|
||||
const r = await fetch(this.url(path), { method: 'POST', headers: this.headers(), body: JSON.stringify(body) });
|
||||
if (!r.ok) throw new Error(`POST ${path} ${r.status}`);
|
||||
return (await r.json()) as T;
|
||||
}
|
||||
|
||||
async ingest(body: IngestInteractionRequest, idempotencyKey: string): Promise<unknown> {
|
||||
const r = await fetch(this.url('/v1/interactions/ingest'), {
|
||||
method: 'POST',
|
||||
|
||||
Reference in New Issue
Block a user