Files
karibeo_api/src/modules/content-generator/content-generator.controller.ts
ellecio2 8b6483aa7d Agregar campo username a User entity y DTO
- Columna username (unique, nullable) en auth.users
- Campo username en CreateUserDto y UpdateUserDto

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-03-17 11:47:37 -04:00

101 lines
3.6 KiB
TypeScript

import {
Controller,
Post,
Get,
Query,
UseGuards,
Body,
} from '@nestjs/common';
import {
ApiTags,
ApiOperation,
ApiResponse,
ApiBearerAuth,
ApiQuery,
} from '@nestjs/swagger';
import { ContentGeneratorService, GenerationResult } from './content-generator.service';
import { JwtAuthGuard } from '../../common/guards/jwt-auth.guard';
import { RolesGuard } from '../../common/guards/roles.guard';
import { Roles } from '../../common/decorators/roles.decorator';
@ApiTags('Content Generator')
@Controller('content-generator')
@UseGuards(JwtAuthGuard, RolesGuard)
@Roles('admin')
@ApiBearerAuth('JWT-auth')
export class ContentGeneratorController {
constructor(private readonly contentGeneratorService: ContentGeneratorService) {}
@Get('stats')
@ApiOperation({ summary: 'Get content generation statistics' })
@ApiResponse({ status: 200, description: 'Statistics retrieved successfully' })
async getStats() {
return this.contentGeneratorService.getStats();
}
@Post('generate-descriptions')
@ApiOperation({ summary: 'Generate descriptions for monuments (Admin only)' })
@ApiQuery({ name: 'limit', required: false, type: Number, description: 'Max places to process (default: 10)' })
@ApiQuery({ name: 'languages', required: false, type: String, description: 'Comma-separated language codes (default: es,en,fr,it,de)' })
@ApiQuery({ name: 'onlyMissing', required: false, type: Boolean, description: 'Only process places without description (default: true)' })
@ApiResponse({ status: 200, description: 'Descriptions generated successfully' })
async generateDescriptions(
@Query('limit') limit?: number,
@Query('languages') languages?: string,
@Query('onlyMissing') onlyMissing?: boolean,
) {
const languageList = languages ? languages.split(',').map(l => l.trim()) : undefined;
const results = await this.contentGeneratorService.generateAllDescriptions({
limit: limit || 10,
languages: languageList,
onlyMissing: onlyMissing !== false,
});
return {
success: true,
processed: results.length,
successful: results.filter(r => r.success).length,
failed: results.filter(r => !r.success).length,
results,
};
}
@Post('generate-audios')
@ApiOperation({ summary: 'Generate audio files for monuments (Admin only)' })
@ApiQuery({ name: 'limit', required: false, type: Number, description: 'Max places to process (default: 10)' })
@ApiQuery({ name: 'languages', required: false, type: String, description: 'Comma-separated language codes (default: es,en,fr,it,de)' })
@ApiResponse({ status: 200, description: 'Audios generated successfully' })
async generateAudios(
@Query('limit') limit?: number,
@Query('languages') languages?: string,
) {
const languageList = languages ? languages.split(',').map(l => l.trim()) : undefined;
const results = await this.contentGeneratorService.generateAllAudios({
limit: limit || 10,
languages: languageList,
});
return {
success: true,
processed: results.length,
successful: results.filter(r => r.success).length,
failed: results.filter(r => !r.success).length,
results,
};
}
@Post('generate-single')
@ApiOperation({ summary: 'Generate content for a single place' })
async generateSingle(
@Body() body: { placeId: number; languages?: string[] },
) {
// This would be implemented to generate content for a specific place
return {
message: 'Single place generation not yet implemented',
placeId: body.placeId,
};
}
}