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

@@ -0,0 +1,32 @@
import { ApiPropertyOptional } from "@nestjs/swagger";
import { CarDamagePartDto } from "src/claim-request-management/dto/car-part.dto";
/**
* DTO for field expert to submit claim-needed data in one go (IN_PERSON flow).
* All fields optional so expert can submit in one or two steps (e.g. car parts first, then sheba/other).
*/
export class ExpertCompleteClaimDataDto {
@ApiPropertyOptional({
description: "Car part damage selection (same as selectCarPartDamage). Required for first claim data step.",
type: CarDamagePartDto,
})
carPartDamage?: CarDamagePartDto;
@ApiPropertyOptional({
description: "Sheba number",
example: "IR123456789012345678901234",
})
sheba?: string;
@ApiPropertyOptional({
description: "National code of insurer",
example: "1234567890",
})
nationalCodeOfInsurer?: string;
@ApiPropertyOptional({
description: "Other parts / extra damage items",
example: [{ "حسگر درها": true }],
})
otherParts?: any[];
}

View File

@@ -34,17 +34,83 @@ import { CreateExpertInitiatedFileDto } from "./dto/expert-initiated.dto";
import { ExpertCompleteThirdPartyFormDto } from "./dto/expert-complete-third-party-form.dto";
import { ExpertCompleteCarBodyFormDto } from "./dto/expert-complete-car-body-form.dto";
import { ExpertAccidentFieldsDto } from "./dto/expert-accident-fields.dto";
import { ExpertCompleteClaimDataDto } from "./dto/expert-complete-claim-data.dto";
import { ClaimRequestManagementService } from "src/claim-request-management/claim-request-management.service";
@ApiTags("expert-initiated-blame")
@Controller("expert-initiated-blame")
@ApiBearerAuth()
@UseGuards(LocalActorAuthGuard, RolesGuard)
@Roles(RoleEnum.EXPERT, RoleEnum.DAMAGE_EXPERT)
@Roles(RoleEnum.FIELD_EXPERT)
export class ExpertInitiatedController {
constructor(
private readonly requestManagementService: RequestManagementService,
private readonly claimRequestManagementService: ClaimRequestManagementService,
) {}
@Get("my-files")
@ApiOperation({
summary: "List my expert-initiated files",
description:
"Returns all blame files created by the current field expert (their panel).",
})
@ApiResponse({ status: 200, description: "List of expert-initiated files" })
async getMyFiles(@CurrentUser() expert: any) {
return await this.requestManagementService.getMyExpertInitiatedFiles(
expert,
);
}
@Post("complete-blame-data/:requestId")
@ApiOperation({
summary: "Submit all blame-needed data",
description:
"Single endpoint to complete blame form: send THIRD_PARTY or CAR_BODY form data according to file type. " +
"Video and voice can be uploaded separately.",
})
@ApiParam({ name: "requestId", description: "ID of the expert-initiated file" })
@ApiBody({
description:
"Send ExpertCompleteThirdPartyFormDto for THIRD_PARTY files or ExpertCompleteCarBodyFormDto for CAR_BODY files (according to file type).",
})
@ApiResponse({ status: 200, description: "Blame form completed successfully" })
async completeBlameData(
@CurrentUser() expert: any,
@Param("requestId") requestId: string,
@Body() formData: any,
) {
return await this.requestManagementService.completeBlameData(
expert,
requestId,
formData,
);
}
@Post("complete-claim-data/:claimRequestId")
@ApiOperation({
summary: "Submit claim-needed data",
description:
"Field expert fills claim data for expert-initiated IN_PERSON files (car part damage, sheba, national code, other parts). " +
"Only the initiating expert can call this.",
})
@ApiParam({
name: "claimRequestId",
description: "ID of the claim file (created from the expert-initiated blame file)",
})
@ApiBody({ type: ExpertCompleteClaimDataDto })
@ApiResponse({ status: 200, description: "Claim data updated successfully" })
async completeClaimData(
@CurrentUser() expert: any,
@Param("claimRequestId") claimRequestId: string,
@Body() dto: ExpertCompleteClaimDataDto,
) {
return await this.claimRequestManagementService.expertCompleteClaimData(
claimRequestId,
expert,
dto,
);
}
@Post("create")
@ApiOperation({
summary: "Create expert-initiated blame file",

View File

@@ -2005,8 +2005,13 @@ export class RequestManagementService {
request: RequestManagementModel,
user: any,
): Promise<void> {
// If user is not an expert, no verification needed (normal flow)
if (user.role !== RoleEnum.EXPERT && user.role !== RoleEnum.DAMAGE_EXPERT) {
// If user is not an expert type, no verification needed (normal flow)
const expertRoles = [
RoleEnum.EXPERT,
RoleEnum.DAMAGE_EXPERT,
RoleEnum.FIELD_EXPERT,
];
if (!expertRoles.includes(user.role)) {
return;
}
@@ -2155,6 +2160,60 @@ export class RequestManagementService {
};
}
/**
* List all expert-initiated blame files for the current field expert (their panel).
* Only files where initiatedBy === current user are returned.
*/
async getMyExpertInitiatedFiles(expert: any): Promise<any[]> {
const expertId = new Types.ObjectId(expert.sub);
const files = await this.requestManagementDbService.findAll({
expertInitiated: true,
initiatedBy: expertId,
});
return (files || []).map((f) => ({
_id: f._id,
requestNumber: f.requestNumber,
type: f.type,
creationMethod: f.creationMethod,
blameStatus: f.blameStatus,
currentStep: f.currentStep,
nextStep: f.nextStep,
createdAt: f.createdAt,
steps: f.steps,
}));
}
/**
* Single endpoint handler: complete all blame-needed data.
* Routes to THIRD_PARTY or CAR_BODY completion based on request type.
*/
async completeBlameData(
expert: any,
requestId: string,
formData: any,
): Promise<RequestManagementDtoRs> {
const request = await this.requestManagementDbService.findOne(requestId);
if (!request) {
throw new NotFoundException("Request not found");
}
if (!request.expertInitiated) {
throw new BadRequestException(
"This endpoint is only for expert-initiated files",
);
}
await this.verifyExpertAccess(request, expert);
if (request.type === "THIRD_PARTY") {
return this.expertCompleteThirdPartyForm(expert, requestId, formData);
}
if (request.type === "CAR_BODY") {
return this.expertCompleteCarBodyForm(expert, requestId, formData);
}
throw new BadRequestException(
"Unknown file type. Must be THIRD_PARTY or CAR_BODY.",
);
}
/**
* Expert completes all information for IN_PERSON THIRD_PARTY file at once
* This replaces the step-by-step flow for experts filling files on-site