import { Body, Controller, Post, Req, UseGuards, UseInterceptors, } from '@nestjs/common'; import { ApiBearerAuth, ApiOperation, ApiResponse, ApiTags, } from '@nestjs/swagger'; import { Throttle } from '@nestjs/throttler'; import { Request } from 'express'; import { JwtAuthGuard } from '../auth/guards/jwt-auth.guard'; import { InquiryAccessGuard } from '../auth/guards/inquiry-access.guard'; import { InquiryAccess } from '../auth/decorators/inquiry-access.decorator'; import { InquiryType } from '../common/enums/inquiry-type.enum'; import { BaseInquiryResponseDto } from '../common/dto/base-inquiry-response.dto'; import { ResponseTransformInterceptor } from '../common/interceptors/response-transform.interceptor'; import { UserRateLimitGuard } from '../rate-limit/user-rate-limit.guard'; import { PersonInquiryRequestDto } from './dto/person-inquiry-request.dto'; import { PersonInquiryDataDto } from './dto/person-inquiry-data.dto'; import { PersonInquiryResponseDto } from './dto/person-inquiry-response.dto'; import { GenericInquiryResponseDto } from './dto/generic-inquiry-response.dto'; import { PostalCodeRequestDto } from './dto/postal-code-request.dto'; import { ShahkarRequestDto } from './dto/shahkar-request.dto'; import { SayahRequestDto } from './dto/sayah-request.dto'; import { InquiryService } from './inquiry.service'; /** * Unified inquiry endpoints — protected by JWT, inquiry RBAC, and rate limits. */ @ApiTags('Inquiries') @ApiBearerAuth() @Controller('inquiry') @UseGuards(JwtAuthGuard, InquiryAccessGuard, UserRateLimitGuard) @UseInterceptors(ResponseTransformInterceptor) export class InquiryController { constructor(private readonly inquiryService: InquiryService) {} @Post('person') @InquiryAccess(InquiryType.PERSON) @Throttle({ default: { limit: 30, ttl: 60000 } }) @ApiOperation({ summary: 'Person identity inquiry' }) @ApiResponse({ status: 200, type: PersonInquiryResponseDto }) @ApiResponse({ status: 401, description: 'Unauthorized' }) @ApiResponse({ status: 403, description: 'Inquiry access denied' }) @ApiResponse({ status: 429, description: 'Too many requests' }) async inquirePerson( @Body() dto: PersonInquiryRequestDto, @Req() req: Request & { requestId?: string; trackingCode?: string }, ): Promise> { const requestId = req.requestId ?? 'unknown'; const result = await this.inquiryService.inquirePerson(dto, requestId); req.trackingCode = result.trackingCode; return result; } @Post('realEstate') @InquiryAccess(InquiryType.REAL_ESTATE) @Throttle({ default: { limit: 30, ttl: 60000 } }) @ApiOperation({ summary: 'Real estate inquiry' }) @ApiResponse({ status: 200, type: GenericInquiryResponseDto }) async inquireRealEstate( @Body() payload: Record, @Req() req: Request & { requestId?: string; trackingCode?: string }, ): Promise>> { return this.inquireGeneric(InquiryType.REAL_ESTATE, payload, req); } @Post('sheba') @InquiryAccess(InquiryType.SHEBA) @Throttle({ default: { limit: 30, ttl: 60000 } }) @ApiOperation({ summary: 'Sheba inquiry' }) @ApiResponse({ status: 200, type: GenericInquiryResponseDto }) async inquireSheba( @Body() payload: SayahRequestDto, @Req() req: Request & { requestId?: string; trackingCode?: string }, ): Promise>> { return this.inquireGeneric(InquiryType.SHEBA, payload as unknown as Record, req); } @Post('shahkar') @InquiryAccess(InquiryType.SHAHKAR) @Throttle({ default: { limit: 30, ttl: 60000 } }) @ApiOperation({ summary: 'Shahkar inquiry' }) @ApiResponse({ status: 200, type: GenericInquiryResponseDto }) async inquireShahkar( @Body() payload: ShahkarRequestDto, @Req() req: Request & { requestId?: string; trackingCode?: string }, ): Promise>> { return this.inquireGeneric( InquiryType.SHAHKAR, payload as unknown as Record, req, ); } @Post('postalCode') @InquiryAccess(InquiryType.POSTAL_CODE) @Throttle({ default: { limit: 30, ttl: 60000 } }) @ApiOperation({ summary: 'Postal code inquiry' }) @ApiResponse({ status: 200, type: GenericInquiryResponseDto }) async inquirePostalCode( @Body() payload: PostalCodeRequestDto, @Req() req: Request & { requestId?: string; trackingCode?: string }, ): Promise>> { return this.inquireGeneric( InquiryType.POSTAL_CODE, payload as unknown as Record, req, ); } @Post('legalPerson') @InquiryAccess(InquiryType.LEGAL_PERSON) @Throttle({ default: { limit: 30, ttl: 60000 } }) @ApiOperation({ summary: 'Legal person inquiry' }) @ApiResponse({ status: 200, type: GenericInquiryResponseDto }) async inquireLegalPerson( @Body() payload: Record, @Req() req: Request & { requestId?: string; trackingCode?: string }, ): Promise>> { return this.inquireGeneric(InquiryType.LEGAL_PERSON, payload, req); } private async inquireGeneric( inquiryType: InquiryType, payload: Record, req: Request & { requestId?: string; trackingCode?: string }, ): Promise>> { const requestId = req.requestId ?? 'unknown'; const result = await this.inquiryService.inquire(inquiryType, payload, requestId); req.trackingCode = result.trackingCode; return result; } }