From 3165a5bb59e7db35887c342b684a82e3cf8230d5 Mon Sep 17 00:00:00 2001 From: maaz519 Date: Wed, 1 Jul 2026 01:13:45 +0530 Subject: [PATCH] feat(service): P2.4 REST fallback POST /v1/threads/:id/messages (session-auth) Co-Authored-By: Claude Opus 4.8 (1M context) --- .../src/threads/send-message.dto.ts | 6 +++ .../src/threads/threads.controller.ts | 43 +++++++++++++++++-- .../src/threads/threads.module.ts | 2 + 3 files changed, 48 insertions(+), 3 deletions(-) create mode 100644 packages/iios-service/src/threads/send-message.dto.ts diff --git a/packages/iios-service/src/threads/send-message.dto.ts b/packages/iios-service/src/threads/send-message.dto.ts new file mode 100644 index 0000000..0b8d8b0 --- /dev/null +++ b/packages/iios-service/src/threads/send-message.dto.ts @@ -0,0 +1,6 @@ +import { IsOptional, IsString } from 'class-validator'; + +export class SendMessageDto { + @IsString() content!: string; + @IsOptional() @IsString() contentRef?: string; +} diff --git a/packages/iios-service/src/threads/threads.controller.ts b/packages/iios-service/src/threads/threads.controller.ts index 8fc1f64..22d5fdb 100644 --- a/packages/iios-service/src/threads/threads.controller.ts +++ b/packages/iios-service/src/threads/threads.controller.ts @@ -1,12 +1,49 @@ -import { Controller, Get, Param } from '@nestjs/common'; +import { randomUUID } from 'node:crypto'; +import { + BadRequestException, + Body, + Controller, + Get, + Headers, + HttpCode, + Param, + Post, +} from '@nestjs/common'; import { ThreadsService } from './threads.service'; +import { MessageService } from '../messaging/message.service'; +import { SessionVerifier } from '../platform/session.verifier'; +import { SendMessageDto } from './send-message.dto'; @Controller('v1/threads') export class ThreadsController { - constructor(private readonly threads: ThreadsService) {} + constructor( + private readonly threads: ThreadsService, + private readonly messages: MessageService, + private readonly session: SessionVerifier, + ) {} @Get(':id/messages') - async messages(@Param('id') id: string) { + async listMessages(@Param('id') id: string) { return this.threads.getMessages(id); } + + /** REST/polling fallback for native send (same write as the socket path). */ + @Post(':id/messages') + @HttpCode(201) + async send( + @Param('id') id: string, + @Body() body: SendMessageDto, + @Headers('authorization') authorization?: string, + @Headers('idempotency-key') idempotencyKey?: string, + ) { + const token = (authorization ?? '').replace(/^Bearer\s+/i, ''); + if (!token) throw new BadRequestException('Authorization bearer token is required'); + const principal = this.session.verify(token); + return this.messages.send( + id, + principal, + { content: body.content, contentRef: body.contentRef }, + idempotencyKey ?? randomUUID(), + ); + } } diff --git a/packages/iios-service/src/threads/threads.module.ts b/packages/iios-service/src/threads/threads.module.ts index 03e14d1..f972ecd 100644 --- a/packages/iios-service/src/threads/threads.module.ts +++ b/packages/iios-service/src/threads/threads.module.ts @@ -1,8 +1,10 @@ import { Module } from '@nestjs/common'; import { ThreadsController } from './threads.controller'; import { ThreadsService } from './threads.service'; +import { MessageModule } from '../messaging/message.module'; @Module({ + imports: [MessageModule], controllers: [ThreadsController], providers: [ThreadsService], exports: [ThreadsService],