refactor: handle kyc journey for customers

This commit is contained in:
Abdalhamid Alhamad
2025-02-20 16:18:06 +03:00
parent 270753cfd7
commit dae9cb6323
74 changed files with 1116 additions and 477 deletions

View File

@ -4,36 +4,40 @@ import { Roles } from '~/auth/enums';
import { PageOptionsRequestDto } from '~/core/dtos';
import { CustomerService } from '~/customer/services';
import { DocumentService, OciService } from '~/document/services';
import { UserType } from '~/user/enums';
import { UserService } from '~/user/services';
import { UserTokenService } from '~/user/services/user-token.service';
import { CreateJuniorRequestDto, SetThemeRequestDto } from '../dtos/request';
import { Junior } from '../entities';
import { JuniorRepository } from '../repositories';
import { JuniorTokenService } from './junior-token.service';
import { QrcodeService } from './qrcode.service';
@Injectable()
export class JuniorService {
private readonly logger = new Logger(JuniorService.name);
constructor(
private readonly juniorRepository: JuniorRepository,
private readonly juniorTokenService: JuniorTokenService,
private readonly userService: UserService,
private readonly userTokenService: UserTokenService,
private readonly customerService: CustomerService,
private readonly documentService: DocumentService,
private readonly ociService: OciService,
private readonly qrCodeService: QrcodeService,
) {}
@Transactional()
async createJuniors(body: CreateJuniorRequestDto, guardianId: string) {
this.logger.log(`Creating junior for guardian ${guardianId}`);
const existingUser = await this.userService.findUser([{ email: body.email }, { phoneNumber: body.phoneNumber }]);
const existingUser = await this.userService.findUser([
{ email: body.email },
{ phoneNumber: body.phoneNumber, countryCode: body.countryCode },
]);
if (existingUser) {
this.logger.error(`User with email ${body.email} or phone number ${body.phoneNumber} already exists`);
throw new BadRequestException('USER.ALREADY_EXISTS');
}
await this.validateJuniorDocuments(guardianId, body.civilIdFrontId, body.civilIdBackId);
const user = await this.userService.createUser({
email: body.email,
countryCode: body.countryCode,
@ -41,11 +45,17 @@ export class JuniorService {
roles: [Roles.JUNIOR],
});
await this.customerService.createJuniorCustomer(guardianId, user.id, body);
const customer = await this.customerService.createJuniorCustomer(guardianId, user.id, body);
await this.juniorRepository.createJunior(user.id, {
guardianId,
relationship: body.relationship,
customerId: customer.id,
});
this.logger.log(`Junior ${user.id} created successfully`);
return this.juniorTokenService.generateToken(user.id);
return this.generateToken(user.id);
}
async findJuniorById(juniorId: string, withGuardianRelation = false, guardianId?: string) {
@ -90,13 +100,16 @@ export class JuniorService {
async validateToken(token: string) {
this.logger.log(`Validating token ${token}`);
const juniorId = await this.juniorTokenService.validateToken(token);
return this.findJuniorById(juniorId, true);
const juniorId = await this.userTokenService.validateToken(token, UserType.JUNIOR);
return this.findJuniorById(juniorId!, true);
}
generateToken(juniorId: string) {
async generateToken(juniorId: string) {
this.logger.log(`Generating token for junior ${juniorId}`);
return this.juniorTokenService.generateToken(juniorId);
const token = await this.userTokenService.generateToken(juniorId, UserType.JUNIOR);
return this.qrCodeService.generateQrCode(token);
}
async doesJuniorBelongToGuardian(guardianId: string, juniorId: string) {
@ -106,38 +119,6 @@ export class JuniorService {
return !!junior;
}
private async validateJuniorDocuments(userId: string, civilIdFrontId: string, civilIdBackId: string) {
this.logger.log(`Validating junior documents`);
if (!civilIdFrontId || !civilIdBackId) {
this.logger.error('Civil id front and back are required');
throw new BadRequestException('JUNIOR.CIVIL_ID_REQUIRED');
}
const [civilIdFront, civilIdBack] = await Promise.all([
this.documentService.findDocumentById(civilIdFrontId),
this.documentService.findDocumentById(civilIdBackId),
]);
if (!civilIdFront || !civilIdBack) {
this.logger.error('Civil id front or back not found');
throw new BadRequestException('JUNIOR.CIVIL_ID_REQUIRED');
}
if (civilIdFront.createdById !== userId || civilIdBack.createdById !== userId) {
this.logger.error(`Civil id front or back not created by user with id ${userId}`);
throw new BadRequestException('JUNIOR.CIVIL_ID_NOT_CREATED_BY_GUARDIAN');
}
const juniorWithSameCivilId = await this.juniorRepository.findJuniorByCivilId(civilIdFrontId, civilIdBackId);
if (juniorWithSameCivilId) {
this.logger.error(
`Junior with civil id front ${civilIdFrontId} and civil id back ${civilIdBackId} already exists`,
);
throw new BadRequestException('JUNIOR.CIVIL_ID_ALREADY_EXISTS');
}
}
private async prepareJuniorImages(juniors: Junior[]) {
this.logger.log(`Preparing junior images`);
await Promise.all(