YARA-1117 and fixed completed status after in person visit has been called

This commit is contained in:
SepehrYahyaee
2026-07-14 11:51:52 +03:30
parent 4aa6e03afb
commit 168e52a475
6 changed files with 92 additions and 54 deletions

View File

@@ -9325,21 +9325,31 @@ export class RequestManagementService {
async expertUploadBlameVideoV3(
expert: any,
requestId: string,
file: Express.Multer.File,
file: Express.Multer.File | undefined,
): Promise<{
requestId: string;
publicId: string;
videoId: string;
videoId: string | undefined;
status: string;
message: string;
}> {
if (!file) throw new BadRequestException("Video file is required");
const req = await this.blameRequestDbService.findById(requestId);
if (!req) throw new NotFoundException("Request not found");
this.assertBlameV3ExpertInPerson(req);
await this.verifyExpertAccessForBlameV2(req, expert);
// Idempotent: if blame is already completed (car-capture auto-completed it
// for V4/V5, or a previous call already ran), return success immediately.
if ((req as any).status === CaseStatus.COMPLETED) {
return {
requestId: String(req._id),
publicId: req.publicId,
videoId: undefined,
status: (req as any).status,
message: "File already completed.",
};
}
if (!(req.expert?.decision as any)?.fields?.accidentWay) {
throw new BadRequestException(
"Submit accident fields before uploading the blame accident video.",
@@ -9381,19 +9391,23 @@ export class RequestManagementService {
const firstIdx = this.getPartyIndex(req, PartyRole.FIRST);
if (firstIdx === -1) throw new BadRequestException("First party not found");
const firstParty = req.parties[firstIdx];
if (firstParty?.evidence?.videoId) {
throw new ConflictException("Blame accident video already uploaded");
// Store video if provided; skip silently for V4/V5 where it is optional.
let videoId: string | undefined;
if (file) {
if (firstParty?.evidence?.videoId) {
throw new ConflictException("Blame accident video already uploaded");
}
const videoDocument = await this.blameVideoDbService.create({
fileName: file.filename,
path: file.path,
requestId: new Types.ObjectId(requestId),
} as any);
if (!firstParty.evidence) firstParty.evidence = {} as any;
firstParty.evidence.videoId = String((videoDocument as any)._id);
videoId = firstParty.evidence.videoId;
}
const videoDocument = await this.blameVideoDbService.create({
fileName: file.filename,
path: file.path,
requestId: new Types.ObjectId(requestId),
} as any);
if (!firstParty.evidence) firstParty.evidence = {} as any;
firstParty.evidence.videoId = String((videoDocument as any)._id);
this.pushWorkflowSteps(req, [
WorkflowStep.FIRST_VIDEO,
WorkflowStep.WAITING_FOR_GUILT_DECISION,
@@ -9410,7 +9424,7 @@ export class RequestManagementService {
actorName: `${expert.firstName || ""} ${expert.lastName || ""}`.trim(),
actorType: "field_expert",
},
metadata: { videoId: firstParty.evidence.videoId },
metadata: { videoId: videoId ?? null },
} as any);
if (typeof (req as any).markModified === "function") {
@@ -9449,10 +9463,11 @@ export class RequestManagementService {
return {
requestId: String(req._id),
publicId: req.publicId,
videoId: firstParty.evidence.videoId,
videoId,
status: req.status,
message:
"Blame accident video uploaded. File is now waiting for expert review.",
message: file
? "Blame accident video uploaded. File is now waiting for expert review."
: "File completed. Claim is now ready for damage expert review.",
};
}
@@ -9694,21 +9709,31 @@ export class RequestManagementService {
async expertUploadBlameVideoV5(
expert: any,
requestId: string,
file: Express.Multer.File,
file: Express.Multer.File | undefined,
): Promise<{
requestId: string;
publicId: string;
videoId: string;
videoId: string | undefined;
status: string;
message: string;
}> {
if (!file) throw new BadRequestException("Video file is required");
const req = await this.blameRequestDbService.findById(requestId);
if (!req) throw new NotFoundException("Request not found");
this.assertBlameV3ExpertInPerson(req);
await this.verifyExpertAccessForBlameV2(req, expert);
// Idempotent: blame already completed (car-capture auto-completed it for
// V4/V5, or a previous call already ran).
if ((req as any).status === CaseStatus.COMPLETED) {
return {
requestId: String(req._id),
publicId: req.publicId,
videoId: undefined,
status: (req as any).status,
message: "File already completed.",
};
}
if (!(req.expert?.decision as any)?.fields?.accidentWay) {
throw new BadRequestException(
"Submit accident fields before uploading the blame accident video.",
@@ -9750,19 +9775,23 @@ export class RequestManagementService {
const firstIdx = this.getPartyIndex(req, PartyRole.FIRST);
if (firstIdx === -1) throw new BadRequestException("First party not found");
const firstParty = req.parties[firstIdx];
if (firstParty?.evidence?.videoId) {
throw new ConflictException("Blame accident video already uploaded");
// Store video if provided; skip silently for V4/V5 where it is optional.
let videoId: string | undefined;
if (file) {
if (firstParty?.evidence?.videoId) {
throw new ConflictException("Blame accident video already uploaded");
}
const videoDocument = await this.blameVideoDbService.create({
fileName: file.filename,
path: file.path,
requestId: new Types.ObjectId(requestId),
} as any);
if (!firstParty.evidence) firstParty.evidence = {} as any;
firstParty.evidence.videoId = String((videoDocument as any)._id);
videoId = firstParty.evidence.videoId;
}
const videoDocument = await this.blameVideoDbService.create({
fileName: file.filename,
path: file.path,
requestId: new Types.ObjectId(requestId),
} as any);
if (!firstParty.evidence) firstParty.evidence = {} as any;
firstParty.evidence.videoId = String((videoDocument as any)._id);
this.pushWorkflowSteps(req, [
WorkflowStep.FIRST_VIDEO,
WorkflowStep.WAITING_FOR_GUILT_DECISION,
@@ -9779,7 +9808,7 @@ export class RequestManagementService {
actorName: `${expert.firstName || ""} ${expert.lastName || ""}`.trim(),
actorType: "file_reviewer",
},
metadata: { videoId: firstParty.evidence.videoId },
metadata: { videoId: videoId ?? null },
} as any);
if (typeof (req as any).markModified === "function") {
@@ -9825,11 +9854,11 @@ export class RequestManagementService {
return {
requestId: String(req._id),
publicId: req.publicId,
videoId: firstParty.evidence.videoId,
videoId,
status: req.status,
message:
"Blame accident video uploaded. File is now in expert review queue. " +
"After the full claim flow completes and the owner signs, the FileMaker must approve before fanavaran submission.",
message: file
? "Blame accident video uploaded. File is now in expert review queue. After the full claim flow completes and the owner signs, the FileMaker must approve before fanavaran submission."
: "File completed. Claim is now ready for damage expert review.",
};
}