1
0
forked from Yara724/api

Added in-person expert

This commit is contained in:
SepehrYahyaee
2026-02-24 12:16:14 +03:30
parent 0d8858f458
commit 64b6101177
13 changed files with 512 additions and 22 deletions

View File

@@ -79,6 +79,7 @@ import { JwtModule } from "@nestjs/jwt";
],
controllers: [ClaimRequestManagementController],
exports: [
ClaimRequestManagementService,
ClaimRequestManagementDbService,
DamageImageDbService,
VideoCaptureDbService,

View File

@@ -118,7 +118,12 @@ export class ClaimRequestManagementService {
// If actor is an expert, verify they're accessing an IN_PERSON claim file
// and return the claim file's userId
if (actor.role === RoleEnum.EXPERT || actor.role === RoleEnum.DAMAGE_EXPERT) {
const expertRoles = [
RoleEnum.EXPERT,
RoleEnum.DAMAGE_EXPERT,
RoleEnum.FIELD_EXPERT,
];
if (expertRoles.includes(actor.role)) {
const claim = await this.claimDbService.findOne(claimRequestId);
if (!claim) {
throw new NotFoundException("Claim file not found");
@@ -184,11 +189,16 @@ export class ClaimRequestManagementService {
// For IN_PERSON expert-initiated files, expert creates the claim
// For LINK method or regular files, user creates their own claim
const expertRoles = [
RoleEnum.EXPERT,
RoleEnum.DAMAGE_EXPERT,
RoleEnum.FIELD_EXPERT,
];
if (
blameRequest.expertInitiated &&
blameRequest.creationMethod === "IN_PERSON" &&
actor &&
(actor.role === "EXPERT" || actor.role === "DAMAGE_EXPERT")
expertRoles.includes(actor.role)
) {
// Expert is creating claim for IN_PERSON file
// Verify expert is the initiating expert
@@ -343,6 +353,69 @@ export class ClaimRequestManagementService {
}
}
/**
* Field expert completes claim-needed data for expert-initiated IN_PERSON files.
* Only the initiating expert can call this. Accepts car part damage and/or sheba, nationalCodeOfInsurer, otherParts.
*/
async expertCompleteClaimData(
claimRequestId: string,
expert: any,
dto: {
carPartDamage?: CarDamagePartDto;
sheba?: string;
nationalCodeOfInsurer?: string;
otherParts?: any[];
},
): Promise<{ success: boolean; claimRequestId: string }> {
const claim = await this.claimDbService.findOne(claimRequestId);
if (!claim) {
throw new NotFoundException("Claim file not found");
}
const blameFile = claim.blameFile as any;
if (!blameFile?.expertInitiated || blameFile?.creationMethod !== "IN_PERSON") {
throw new BadRequestException(
"This endpoint is only for expert-initiated IN_PERSON claim files.",
);
}
if (String(blameFile.initiatedBy) !== expert.sub) {
throw new ForbiddenException(
"Only the initiating field expert can complete claim data for this file.",
);
}
if (dto.carPartDamage) {
if (claim.carPartDamage && (claim.carPartDamage as any[]).length > 0) {
throw new BadRequestException("Car part damage is already set.");
}
const trueItems = this.findTrueItems(dto.carPartDamage);
const claimDoc = (await this.claimDbService.findOne(
claimRequestId,
)) as any;
if (claimDoc) {
await this.setCarPartDamageAndImage(claimDoc, trueItems);
}
await this.claimDbService.findAndUpdate(claimRequestId, {
currentStep: ClaimStepsEnum.SelectDamagePart,
nextStep: ClaimStepsEnum.SelectOtherParts,
$push: { steps: ClaimStepsEnum.SelectDamagePart },
});
}
const updates: Record<string, any> = {};
if (dto.sheba != null) updates.sheba = dto.sheba;
if (dto.nationalCodeOfInsurer != null)
updates.nationalCodeOfInsurer = dto.nationalCodeOfInsurer;
if (dto.otherParts != null) updates.otherParts = dto.otherParts;
if (Object.keys(updates).length > 0) {
await this.claimDbService.findAndUpdate(claimRequestId, {
$set: updates,
});
}
return { success: true, claimRequestId };
}
async selectCarOtherPartDamage(
requestId: string,
body: any, // Use your DTO for better type safety
@@ -1186,10 +1259,12 @@ export class ClaimRequestManagementService {
}
// For experts, return IN_PERSON claim files they initiated
if (
currentUser.role === RoleEnum.EXPERT ||
currentUser.role === RoleEnum.DAMAGE_EXPERT
) {
const expertRoles = [
RoleEnum.EXPERT,
RoleEnum.DAMAGE_EXPERT,
RoleEnum.FIELD_EXPERT,
];
if (expertRoles.includes(currentUser.role)) {
const allClaims = await this.claimDbService.findAllByAnyFilter({});
const expertClaims = allClaims.filter((claim) => {
const blameFile = claim.blameFile;