import { Controller, Post, Get, Param, Query, HttpCode, HttpStatus, } from '@nestjs/common'; import { ApiTags, ApiOperation, ApiResponse, ApiQuery, ApiParam } from '@nestjs/swagger'; import { Not, IsNull } from 'typeorm'; import { ProcessingService } from './processing.service'; @ApiTags('processing') @Controller('api/processing') export class ProcessingController { constructor(private readonly processingService: ProcessingService) {} @Post('process') @HttpCode(HttpStatus.OK) @ApiOperation({ summary: 'Process unprocessed messages', description: 'Extract text and determine message types for messages that have not been processed yet', }) @ApiQuery({ name: 'limit', required: false, type: Number, description: 'Maximum number of messages to process (default: 1000)', }) @ApiResponse({ status: 200, description: 'Processing complete', schema: { example: { success: true, data: { processed: 150, errors: 2, messages: [ { id: 'uuid-1', messageType: 'text', textExtracted: true }, { id: 'uuid-2', messageType: 'attachment', textExtracted: false }, ], }, }, }, }) async processMessages(@Query('limit') limit?: string) { const result = await this.processingService.processUnprocessedMessages( limit ? parseInt(limit, 10) : 1000, ); return { success: true, data: result, }; } @Post('reprocess') @HttpCode(HttpStatus.OK) @ApiOperation({ summary: 'Reprocess all messages', description: 'Clear processing state and reprocess all messages. Use after schema changes or algorithm updates.', }) @ApiQuery({ name: 'limit', required: false, type: Number, description: 'Maximum number of messages to reprocess (default: 10000)', }) @ApiResponse({ status: 200, description: 'Reprocessing complete', schema: { example: { success: true, data: { processed: 5000, errors: 10, }, }, }, }) async reprocessMessages(@Query('limit') limit?: string) { const result = await this.processingService.reprocessAllMessages( limit ? parseInt(limit, 10) : 10000, ); return { success: true, data: result, }; } @Post('reprocess/:id') @HttpCode(HttpStatus.OK) @ApiOperation({ summary: 'Reprocess a single message', description: 'Reprocess a specific message by ID', }) @ApiParam({ name: 'id', description: 'Message UUID', format: 'uuid', }) @ApiResponse({ status: 200, description: 'Message reprocessed', schema: { example: { success: true, data: { id: 'uuid-1', messageType: 'text', text: 'Hello world', processedAt: '2024-01-01T12:00:00Z', }, }, }, }) @ApiResponse({ status: 404, description: 'Message not found' }) async reprocessMessage(@Param('id') id: string) { const message = await this.processingService.reprocessMessage(id); if (!message) { return { success: false, error: { message: 'Message not found' }, }; } return { success: true, data: { id: message.id, messageType: message.messageType, text: message.text, processedAt: message.processedAt?.toISOString(), }, }; } @Get('stats') @ApiOperation({ summary: 'Get processing statistics', description: 'Returns counts of processed and unprocessed messages', }) @ApiResponse({ status: 200, description: 'Processing statistics', schema: { example: { success: true, data: { total: 5000, processed: 4950, unprocessed: 50, }, }, }, }) async getStats() { // This would need a separate method in the service, but for now we'll inline it const { processingService } = this; const total = await processingService['messageRepository'].count(); const processed = await processingService['messageRepository'].count({ where: { processedAt: Not(IsNull()) }, }); const unprocessed = total - processed; return { success: true, data: { total, processed, unprocessed, }, }; } }