feat(p8): /v1/calendar REST + kernel-client methods + @insignia/iios-meeting-web
Task 8.6: CalendarController exposes schedule/request(+fromCallback/fromClaim)/ list/get/consent/transcript/summarize/action-items/providers(+sync) (session-auth). kernel-client RestClient gains scheduleMeeting/requestMeeting/listMeetings/ getMeeting/setConsent/generateTranscript/summarizeMeeting/listActionItems/ connect+syncCalendarProvider + Meeting/MeetingParticipant/MeetingActionItem types. New @insignia/iios-meeting-web (MeetingProvider + useMeetings/useMeeting/useSchedule/ useConsent/useSummarize/useActionItems). Boundary: meeting-web -> contracts + kernel-client (fails on meeting-web->service). 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, Ticket, TicketState, CallbackRequest, RouteBinding, RouteDecision, AiArtifact, AiJobResult } from './types';
|
||||
import type { Message, InboxItem, InboxState, Ticket, TicketState, CallbackRequest, RouteBinding, RouteDecision, AiArtifact, AiJobResult, Meeting, MeetingActionItem } from './types';
|
||||
|
||||
export interface RestConfig {
|
||||
serviceUrl: string;
|
||||
@@ -149,6 +149,55 @@ export class RestClient {
|
||||
return this.post<AiArtifact>(`/v1/ai/artifacts/${id}/reject`, {});
|
||||
}
|
||||
|
||||
// ─── Calendar & Meeting (P8) ──────────────────────────────────
|
||||
async scheduleMeeting(input: {
|
||||
meetingType: string;
|
||||
title: string;
|
||||
startAt: string;
|
||||
endAt?: string;
|
||||
timezone?: string;
|
||||
attendees?: { userId: string; displayName?: string; role?: string; visibility?: string }[];
|
||||
}): Promise<Meeting> {
|
||||
return this.post<Meeting>('/v1/calendar/meetings', input);
|
||||
}
|
||||
async requestMeeting(input: { requestedWindow: Record<string, unknown>; meetingType?: string }, opts?: { fromCallback?: string; fromClaim?: string }): Promise<unknown> {
|
||||
const q = new URLSearchParams();
|
||||
if (opts?.fromCallback) q.set('fromCallback', opts.fromCallback);
|
||||
if (opts?.fromClaim) q.set('fromClaim', opts.fromClaim);
|
||||
const qs = q.toString();
|
||||
return this.post(`/v1/calendar/requests${qs ? `?${qs}` : ''}`, input);
|
||||
}
|
||||
async listMeetings(): Promise<Meeting[]> {
|
||||
const r = await fetch(this.url('/v1/calendar/meetings'), { headers: this.headers() });
|
||||
if (!r.ok) throw new Error(`listMeetings ${r.status}`);
|
||||
return (await r.json()) as Meeting[];
|
||||
}
|
||||
async getMeeting(id: string): Promise<Meeting> {
|
||||
const r = await fetch(this.url(`/v1/calendar/meetings/${id}`), { headers: this.headers() });
|
||||
if (!r.ok) throw new Error(`getMeeting ${r.status}`);
|
||||
return (await r.json()) as Meeting;
|
||||
}
|
||||
async setConsent(meetingId: string, actorRefId: string, status: string): Promise<unknown> {
|
||||
return this.post(`/v1/calendar/meetings/${meetingId}/consent`, { actorRefId, status });
|
||||
}
|
||||
async generateTranscript(meetingId: string): Promise<unknown> {
|
||||
return this.post(`/v1/calendar/meetings/${meetingId}/transcript`, {});
|
||||
}
|
||||
async summarizeMeeting(meetingId: string): Promise<Meeting> {
|
||||
return this.post<Meeting>(`/v1/calendar/meetings/${meetingId}/summarize`, {});
|
||||
}
|
||||
async listActionItems(meetingId: string): Promise<MeetingActionItem[]> {
|
||||
const r = await fetch(this.url(`/v1/calendar/meetings/${meetingId}/action-items`), { headers: this.headers() });
|
||||
if (!r.ok) throw new Error(`listActionItems ${r.status}`);
|
||||
return (await r.json()) as MeetingActionItem[];
|
||||
}
|
||||
async connectCalendarProvider(): Promise<{ id: string }> {
|
||||
return this.post<{ id: string }>('/v1/calendar/providers', {});
|
||||
}
|
||||
async syncCalendarProvider(id: string): Promise<{ pulled: number; cursor: string }> {
|
||||
return this.post(`/v1/calendar/providers/${id}/sync`, {});
|
||||
}
|
||||
|
||||
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}`);
|
||||
|
||||
Reference in New Issue
Block a user