From 4f8cb438830c1027c8913e5e9ad3efd12cdff50c Mon Sep 17 00:00:00 2001 From: SepehrYahyaee <7heycallmegray@gmail.com> Date: Sun, 26 Apr 2026 09:31:50 +0330 Subject: [PATCH] YARA-832 --- .../schema/claim-case.workflow.schema.ts | 4 ++++ src/expert-blame/expert-blame.service.ts | 13 ++++++++++++- src/expert-claim/dto/claim-detail-v2.dto.ts | 1 + src/expert-claim/expert-claim.service.ts | 17 ++++++++++++++++- .../entities/schema/workflow.type.ts | 4 ++++ 5 files changed, 37 insertions(+), 2 deletions(-) diff --git a/src/claim-request-management/entites/schema/claim-case.workflow.schema.ts b/src/claim-request-management/entites/schema/claim-case.workflow.schema.ts index 5fdca80..1eb09ba 100644 --- a/src/claim-request-management/entites/schema/claim-case.workflow.schema.ts +++ b/src/claim-request-management/entites/schema/claim-case.workflow.schema.ts @@ -40,6 +40,10 @@ export class ClaimWorkflow { @Prop({ type: Date }) lockedAt?: Date; + /** Lock expiry used by UI countdown (typically lockedAt + 15m). */ + @Prop({ type: Date }) + expiredAt?: Date; + @Prop({ type: ClaimActorLockSchema }) lockedBy?: ClaimActorLock; } diff --git a/src/expert-blame/expert-blame.service.ts b/src/expert-blame/expert-blame.service.ts index 414df9d..798b959 100644 --- a/src/expert-blame/expert-blame.service.ts +++ b/src/expert-blame/expert-blame.service.ts @@ -325,6 +325,7 @@ export class ExpertBlameService { if (w) { w.locked = false; delete w.lockedAt; + delete w.expiredAt; delete w.lockedBy; } } @@ -444,7 +445,11 @@ export class ExpertBlameService { filter as any, { $set: { "workflow.locked": false }, - $unset: { "workflow.lockedAt": "", "workflow.lockedBy": "" }, + $unset: { + "workflow.lockedAt": "", + "workflow.expiredAt": "", + "workflow.lockedBy": "", + }, }, { new: false }, ); @@ -953,6 +958,9 @@ export class ExpertBlameService { $set: { "workflow.locked": true, "workflow.lockedAt": now, + "workflow.expiredAt": new Date( + now.getTime() + this.blameV2LockTtlMs, + ), "workflow.lockedBy": { actorId: new Types.ObjectId(actorDetail.sub), actorName: actorDetail.fullName || "Unknown Expert", @@ -1125,6 +1133,7 @@ export class ExpertBlameService { }, $unset: { "workflow.lockedAt": "", + "workflow.expiredAt": "", "workflow.lockedBy": "", }, }; @@ -1308,6 +1317,7 @@ export class ExpertBlameService { }, $unset: { "workflow.lockedAt": "", + "workflow.expiredAt": "", "workflow.lockedBy": "", }, }; @@ -1450,6 +1460,7 @@ export class ExpertBlameService { }, $unset: { "workflow.lockedAt": "", + "workflow.expiredAt": "", "workflow.lockedBy": "", }, }; diff --git a/src/expert-claim/dto/claim-detail-v2.dto.ts b/src/expert-claim/dto/claim-detail-v2.dto.ts index 26951b3..45f9caf 100644 --- a/src/expert-claim/dto/claim-detail-v2.dto.ts +++ b/src/expert-claim/dto/claim-detail-v2.dto.ts @@ -28,6 +28,7 @@ export class ClaimDetailV2ResponseDto { actorId: string; actorName: string; lockedAt: string; + expiredAt?: string; }; @ApiPropertyOptional() diff --git a/src/expert-claim/expert-claim.service.ts b/src/expert-claim/expert-claim.service.ts index d37dc20..44aa4c5 100644 --- a/src/expert-claim/expert-claim.service.ts +++ b/src/expert-claim/expert-claim.service.ts @@ -2104,12 +2104,15 @@ export class ExpertClaimService { } const lockSnapshot = await this.snapshotDamageExpert(actor.sub); + const lockAt = new Date(); + const expiredAt = new Date(lockAt.getTime() + this.claimV2WorkflowLockTtlMs); await this.claimCaseDbService.findByIdAndUpdate(claimRequestId, { status: ClaimCaseStatus.EXPERT_REVIEWING, claimStatus: ClaimStatus.UNDER_REVIEW, 'workflow.locked': true, - 'workflow.lockedAt': new Date(), + 'workflow.lockedAt': lockAt, + 'workflow.expiredAt': expiredAt, 'workflow.lockedBy': { actorId: new Types.ObjectId(actor.sub), actorName: actor.fullName, @@ -2206,6 +2209,7 @@ export class ExpertClaimService { }, $unset: { "workflow.lockedAt": "", + "workflow.expiredAt": "", "workflow.lockedBy": "", }, $push: { @@ -2372,6 +2376,11 @@ export class ExpertClaimService { status: nextCaseStatus, claimStatus: nextClaimStatus, 'workflow.locked': false, + $unset: { + 'workflow.lockedAt': '', + 'workflow.expiredAt': '', + 'workflow.lockedBy': '', + }, 'workflow.currentStep': nextStep, 'workflow.nextStep': needsFactorUpload ? ClaimWorkflowStep.INSURER_REVIEW @@ -2486,6 +2495,11 @@ export class ExpertClaimService { await this.claimCaseDbService.findByIdAndUpdate(claimRequestId, { claimStatus: ClaimStatus.NEEDS_REVISION, 'workflow.locked': false, + $unset: { + 'workflow.lockedAt': '', + 'workflow.expiredAt': '', + 'workflow.lockedBy': '', + }, ...(note ? { 'evaluation.visitLocation': note } : {}), ...(visitSnapshot && { 'evaluation.inPersonVisitExpertProfileSnapshot': visitSnapshot, @@ -2952,6 +2966,7 @@ export class ExpertClaimService { actorId: claim.workflow.lockedBy.actorId?.toString(), actorName: claim.workflow.lockedBy.actorName, lockedAt: (claim.workflow as any).lockedAt?.toISOString(), + expiredAt: (claim.workflow as any).expiredAt?.toISOString(), } : undefined, owner: claim.owner diff --git a/src/request-management/entities/schema/workflow.type.ts b/src/request-management/entities/schema/workflow.type.ts index 11333b9..a2d30bb 100644 --- a/src/request-management/entities/schema/workflow.type.ts +++ b/src/request-management/entities/schema/workflow.type.ts @@ -42,6 +42,10 @@ export class Workflow { @Prop({ type: Date }) lockedAt?: Date; + /** Lock expiry used by UI countdown (typically lockedAt + 15m). */ + @Prop({ type: Date }) + expiredAt?: Date; + @Prop({ type: ActorLockSchema }) lockedBy?: ActorLock; }