forked from Shared/esg
141 lines
5.5 KiB
TypeScript
141 lines
5.5 KiB
TypeScript
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<BaseInquiryResponseDto<PersonInquiryDataDto>> {
|
|
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<string, unknown>,
|
|
@Req() req: Request & { requestId?: string; trackingCode?: string },
|
|
): Promise<BaseInquiryResponseDto<Record<string, unknown>>> {
|
|
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<BaseInquiryResponseDto<Record<string, unknown>>> {
|
|
return this.inquireGeneric(InquiryType.SHEBA, payload as unknown as Record<string, unknown>, 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<BaseInquiryResponseDto<Record<string, unknown>>> {
|
|
return this.inquireGeneric(
|
|
InquiryType.SHAHKAR,
|
|
payload as unknown as Record<string, unknown>,
|
|
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<BaseInquiryResponseDto<Record<string, unknown>>> {
|
|
return this.inquireGeneric(
|
|
InquiryType.POSTAL_CODE,
|
|
payload as unknown as Record<string, unknown>,
|
|
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<string, unknown>,
|
|
@Req() req: Request & { requestId?: string; trackingCode?: string },
|
|
): Promise<BaseInquiryResponseDto<Record<string, unknown>>> {
|
|
return this.inquireGeneric(InquiryType.LEGAL_PERSON, payload, req);
|
|
}
|
|
|
|
private async inquireGeneric(
|
|
inquiryType: InquiryType,
|
|
payload: Record<string, unknown>,
|
|
req: Request & { requestId?: string; trackingCode?: string },
|
|
): Promise<BaseInquiryResponseDto<Record<string, unknown>>> {
|
|
const requestId = req.requestId ?? 'unknown';
|
|
const result = await this.inquiryService.inquire(inquiryType, payload, requestId);
|
|
req.trackingCode = result.trackingCode;
|
|
return result;
|
|
}
|
|
}
|