import { Controller, Post, Body, UseGuards } from "@nestjs/common"; import { Throttle } from "@nestjs/throttler"; import { StitcherService } from "./stitcher.service"; import { WebhookPayloadDto, DispatchJobDto } from "./dto"; import type { JobDispatchResult, JobDispatchContext } from "./interfaces"; import { ApiKeyGuard } from "../common/guards"; /** * StitcherController - Webhook and job dispatch endpoints * * SECURITY: * - All endpoints require API key authentication via X-API-Key header * - Rate limiting: 60 requests per minute per IP/API key * * Handles incoming webhooks from @mosaic bot and provides * endpoints for manual job dispatch */ @Controller("stitcher") @UseGuards(ApiKeyGuard) @Throttle({ default: { ttl: 60000, limit: 60 } }) // 60 requests per minute export class StitcherController { constructor(private readonly stitcherService: StitcherService) {} /** * Webhook endpoint for @mosaic bot * * Rate limit: 60 requests per minute per IP/API key */ @Post("webhook") @Throttle({ default: { ttl: 60000, limit: 60 } }) async webhook(@Body() payload: WebhookPayloadDto): Promise { return this.stitcherService.handleWebhook(payload); } /** * Manual job dispatch endpoint * * Rate limit: 60 requests per minute per IP/API key */ @Post("dispatch") @Throttle({ default: { ttl: 60000, limit: 60 } }) async dispatch(@Body() dto: DispatchJobDto): Promise { const context: JobDispatchContext = { workspaceId: dto.workspaceId, type: dto.type, ...(dto.context !== undefined && { metadata: dto.context }), }; return this.stitcherService.dispatchJob(context); } }