177 lines
4.3 KiB
TypeScript
177 lines
4.3 KiB
TypeScript
|
|
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,
|
||
|
|
},
|
||
|
|
};
|
||
|
|
}
|
||
|
|
}
|