ca9498ce83
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>
90 lines
3.4 KiB
TypeScript
90 lines
3.4 KiB
TypeScript
import { BadRequestException, Body, Controller, Get, Headers, Param, Post, Query } from '@nestjs/common';
|
|
import { IiosConsentStatus, IiosMeetingType } from '@prisma/client';
|
|
import { CalendarService } from './calendar.service';
|
|
import { CalendarAdapter } from './calendar-adapter';
|
|
import { SessionVerifier } from '../platform/session.verifier';
|
|
import type { MessagePrincipal } from '../identity/actor.resolver';
|
|
import { ConsentDto, RequestMeetingDto, ScheduleMeetingDto } from './calendar.dto';
|
|
|
|
@Controller('v1/calendar')
|
|
export class CalendarController {
|
|
constructor(
|
|
private readonly calendar: CalendarService,
|
|
private readonly adapter: CalendarAdapter,
|
|
private readonly session: SessionVerifier,
|
|
) {}
|
|
|
|
@Post('meetings')
|
|
async schedule(@Body() body: ScheduleMeetingDto, @Headers('authorization') auth?: string) {
|
|
return this.calendar.scheduleDirect(this.principal(auth), { ...body, meetingType: body.meetingType as IiosMeetingType });
|
|
}
|
|
|
|
@Post('requests')
|
|
async request(
|
|
@Body() body: RequestMeetingDto,
|
|
@Query('fromCallback') fromCallback?: string,
|
|
@Query('fromClaim') fromClaim?: string,
|
|
@Headers('authorization') auth?: string,
|
|
) {
|
|
const principal = this.principal(auth);
|
|
if (fromCallback) return this.calendar.fromCallback(principal, fromCallback, body.requestedWindow);
|
|
if (fromClaim) return this.calendar.fromEventClaim(principal, fromClaim, body.requestedWindow);
|
|
return this.calendar.requestMeeting(principal, {
|
|
requestedWindow: body.requestedWindow,
|
|
meetingType: body.meetingType as IiosMeetingType | undefined,
|
|
interactionId: body.interactionId,
|
|
targetActorId: body.targetActorId,
|
|
});
|
|
}
|
|
|
|
@Get('meetings')
|
|
async list(@Headers('authorization') auth?: string) {
|
|
return this.calendar.listMeetings(this.principal(auth));
|
|
}
|
|
|
|
@Get('meetings/:id')
|
|
async get(@Param('id') id: string, @Headers('authorization') auth?: string) {
|
|
this.principal(auth);
|
|
return this.calendar.getMeeting(id);
|
|
}
|
|
|
|
@Post('meetings/:id/consent')
|
|
async consent(@Param('id') id: string, @Body() body: ConsentDto, @Headers('authorization') auth?: string) {
|
|
this.principal(auth);
|
|
return this.calendar.setConsent(id, body.actorRefId, body.status as IiosConsentStatus);
|
|
}
|
|
|
|
@Post('meetings/:id/transcript')
|
|
async transcript(@Param('id') id: string, @Headers('authorization') auth?: string) {
|
|
return this.calendar.generateTranscript(id, this.principal(auth));
|
|
}
|
|
|
|
@Post('meetings/:id/summarize')
|
|
async summarize(@Param('id') id: string, @Headers('authorization') auth?: string) {
|
|
return this.calendar.summarize(id, this.principal(auth));
|
|
}
|
|
|
|
@Get('meetings/:id/action-items')
|
|
async actionItems(@Param('id') id: string, @Headers('authorization') auth?: string) {
|
|
this.principal(auth);
|
|
return this.calendar.listActionItems(id);
|
|
}
|
|
|
|
@Post('providers')
|
|
async connect(@Headers('authorization') auth?: string) {
|
|
return this.adapter.connectProvider(this.principal(auth));
|
|
}
|
|
|
|
@Post('providers/:id/sync')
|
|
async sync(@Param('id') id: string, @Headers('authorization') auth?: string) {
|
|
this.principal(auth);
|
|
return this.adapter.syncOnce(id);
|
|
}
|
|
|
|
private principal(authorization?: string): MessagePrincipal {
|
|
const token = (authorization ?? '').replace(/^Bearer\s+/i, '');
|
|
if (!token) throw new BadRequestException('Authorization bearer token is required');
|
|
return this.session.verify(token);
|
|
}
|
|
}
|