import { Body, Controller, Get, Inject, Param, Post, Query, UseGuards } from '@nestjs/common'; import type { LogService } from '@mosaic/log'; import { LOG_SERVICE } from './log.tokens.js'; import { AuthGuard } from '../auth/auth.guard.js'; import type { IngestLogDto, QueryLogsDto } from './log.dto.js'; @Controller('api/logs') @UseGuards(AuthGuard) export class LogController { constructor(@Inject(LOG_SERVICE) private readonly logService: LogService) {} @Post() async ingest(@Query('userId') userId: string, @Body() dto: IngestLogDto) { return this.logService.logs.ingest({ sessionId: dto.sessionId, userId, level: dto.level, category: dto.category, content: dto.content, metadata: dto.metadata, }); } @Post('batch') async ingestBatch(@Query('userId') userId: string, @Body() dtos: IngestLogDto[]) { const entries = dtos.map((dto) => ({ sessionId: dto.sessionId, userId, level: dto.level as 'debug' | 'info' | 'warn' | 'error' | undefined, category: dto.category as | 'decision' | 'tool_use' | 'learning' | 'error' | 'general' | undefined, content: dto.content, metadata: dto.metadata, })); return this.logService.logs.ingestBatch(entries); } @Get() async query(@Query('userId') userId: string, @Query() params: QueryLogsDto) { return this.logService.logs.query({ userId, sessionId: params.sessionId, level: params.level, category: params.category, tier: params.tier, since: params.since ? new Date(params.since) : undefined, until: params.until ? new Date(params.until) : undefined, limit: params.limit ? Number(params.limit) : undefined, offset: params.offset ? Number(params.offset) : undefined, }); } @Get(':id') async findOne(@Param('id') id: string) { return this.logService.logs.findById(id); } }