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); } }