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:
@@ -0,0 +1,89 @@
|
||||
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);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user