import { Body, Controller, Get, NotFoundException, Param, Post, UseGuards } from '@nestjs/common'; import { CommandBus, QueryBus } from '@nestjs/cqrs'; import { ApiBearerAuth, ApiOperation, ApiParam, ApiResponse, ApiTags, } from '@nestjs/swagger'; import { type JwtPayload, CurrentUser, JwtAuthGuard, RolesGuard, Roles, } from '@modules/auth'; import { RecalculateQualityScoreCommand } from '../../application/commands/recalculate-quality-score/recalculate-quality-score.command'; import { UpgradeToAgentCommand } from '../../application/commands/upgrade-to-agent/upgrade-to-agent.command'; import { type UpgradeToAgentResult } from '../../application/commands/upgrade-to-agent/upgrade-to-agent.handler'; import { GetAgentDashboardQuery } from '../../application/queries/get-agent-dashboard/get-agent-dashboard.query'; import { GetAgentPublicProfileQuery } from '../../application/queries/get-agent-public-profile/get-agent-public-profile.query'; import { type AgentDashboardData, type AgentPublicProfileData } from '../../domain/repositories/agent.repository'; import { UpgradeToAgentDto } from '../dto/upgrade-to-agent.dto'; @ApiTags('agents') @Controller('agents') export class AgentsController { constructor( private readonly commandBus: CommandBus, private readonly queryBus: QueryBus, ) {} @ApiBearerAuth('JWT') @ApiOperation({ summary: 'Get agent dashboard stats' }) @ApiResponse({ status: 200, description: 'Agent dashboard data' }) @ApiResponse({ status: 401, description: 'Unauthorized' }) @ApiResponse({ status: 403, description: 'Forbidden — only agents' }) @ApiResponse({ status: 404, description: 'Agent profile not found' }) @UseGuards(JwtAuthGuard, RolesGuard) @Roles('AGENT') @Get('me/dashboard') async getDashboard( @CurrentUser() user: JwtPayload, ): Promise { return this.queryBus.execute(new GetAgentDashboardQuery(user.sub)); } @ApiOperation({ summary: 'Get public agent profile' }) @ApiParam({ name: 'agentId', description: 'Agent ID' }) @ApiResponse({ status: 200, description: 'Agent public profile data' }) @ApiResponse({ status: 404, description: 'Agent not found' }) @Get(':agentId/profile') async getPublicProfile( @Param('agentId') agentId: string, ): Promise { const profile = await this.queryBus.execute( new GetAgentPublicProfileQuery(agentId), ); if (!profile) { throw new NotFoundException('Không tìm thấy môi giới'); } return profile; } @ApiBearerAuth('JWT') @ApiOperation({ summary: 'Nâng cấp tài khoản lên đại lý' }) @ApiResponse({ status: 201, description: 'Tài khoản đã được nâng cấp lên đại lý (chưa xác minh)' }) @ApiResponse({ status: 401, description: 'Unauthorized' }) @ApiResponse({ status: 404, description: 'Không tìm thấy người dùng' }) @ApiResponse({ status: 409, description: 'Tài khoản đã là đại lý hoặc không được phép nâng cấp' }) @UseGuards(JwtAuthGuard) @Post('me/upgrade') async upgradeToAgent( @CurrentUser() user: JwtPayload, @Body() dto: UpgradeToAgentDto, ): Promise { return this.commandBus.execute( new UpgradeToAgentCommand( user.sub, dto.licenseNumber, dto.agency, dto.bio, dto.serviceAreas, ), ); } @ApiBearerAuth('JWT') @ApiOperation({ summary: 'Recalculate quality score (admin/system)' }) @ApiParam({ name: 'agentId', description: 'Agent ID' }) @ApiResponse({ status: 201, description: 'Quality score recalculated' }) @ApiResponse({ status: 401, description: 'Unauthorized' }) @ApiResponse({ status: 403, description: 'Forbidden — only admins' }) @UseGuards(JwtAuthGuard, RolesGuard) @Roles('ADMIN') @Post(':agentId/recalculate-score') async recalculateScore( @Param('agentId') agentId: string, ): Promise<{ message: string }> { await this.commandBus.execute( new RecalculateQualityScoreCommand(agentId), ); return { message: 'Quality score recalculated' }; } }