1
0
forked from Yara724/api

daghi + expert and damage expert name in decision +

signature required added
This commit is contained in:
2026-04-20 18:19:25 +03:30
parent b63c2155bc
commit 41c44dcf23
13 changed files with 324 additions and 12 deletions

View File

@@ -39,6 +39,8 @@ import { ExpertDbService } from "src/users/entities/db-service/expert.db.service
import { BlameDocumentDbService } from "src/request-management/entities/db-service/blame-document.db.service";
import { UserSignDbService } from "src/request-management/entities/db-service/sign.db.service";
import { RequestManagementService } from "src/request-management/request-management.service";
import { snapshotFromFieldExpert } from "src/helpers/expert-profile-snapshot";
import { ExpertModel } from "src/users/entities/schema/expert.schema";
interface CheckedRequestEntry {
CheckedRequest?: {
@@ -81,6 +83,14 @@ export class ExpertBlameService {
private readonly requestManagementService: RequestManagementService,
) { }
/** Load immutable profile fields from `expert` for the acting field expert. */
private async snapshotFieldExpert(actorId: string) {
const expertDoc = await this.expertDbService.findOne({
_id: new Types.ObjectId(actorId),
});
return snapshotFromFieldExpert(expertDoc as ExpertModel);
}
async findAll(actor: any): Promise<AllRequestDtoRs> {
// 1. Fetch all potentially relevant requests from the database.
// Exclude CAR_BODY type requests as they are automatically handled and don't need expert review
@@ -767,6 +777,7 @@ export class ExpertBlameService {
}
const fifteenMinutes = new Date(Date.now() + 15 * 60 * 1000);
const lockSnapshot = await this.snapshotFieldExpert(actorDetail.sub);
const updateResult = await this.requestManagementDbService.findOneAndUpdate(
{
@@ -782,6 +793,7 @@ export class ExpertBlameService {
actorLocked: {
fullName: actorDetail.fullName,
actorId: new Types.ObjectId(actorDetail.sub),
...(lockSnapshot && { expertProfileSnapshot: lockSnapshot }),
},
},
$push: {
@@ -872,6 +884,8 @@ export class ExpertBlameService {
}
}
const lockSnapshot = await this.snapshotFieldExpert(actorDetail.sub);
// Lock the request (either unlocked or expired lock)
const updateResult = await this.blameRequestDbService.findByIdAndUpdate(
requestId,
@@ -883,6 +897,7 @@ export class ExpertBlameService {
actorId: new Types.ObjectId(actorDetail.sub),
actorName: actorDetail.fullName || "Unknown Expert",
actorRole: "expert",
...(lockSnapshot && { expertProfileSnapshot: lockSnapshot }),
},
},
},
@@ -1004,6 +1019,7 @@ export class ExpertBlameService {
}
const now = new Date();
const resendSnapshot = await this.snapshotFieldExpert(actorId);
const partyResendRequests = resendDto.parties.map((party) => {
const uid = String(party.partyId);
@@ -1026,6 +1042,7 @@ export class ExpertBlameService {
parties: partyResendRequests,
requestedAt: now,
requestedByExpertId: new Types.ObjectId(actorId),
...(resendSnapshot && { expertProfileSnapshot: resendSnapshot }),
},
status: CaseStatus.WAITING_FOR_DOCUMENT_RESEND,
},
@@ -1151,12 +1168,15 @@ export class ExpertBlameService {
const now = new Date();
const expertProfileSnapshot = await this.snapshotFieldExpert(actorId);
// Build expert decision with fields
const decisionPayload: any = {
guiltyPartyId: new Types.ObjectId(String(reply.guiltyUserId)),
description: reply.description,
decidedAt: now,
decidedByExpertId: new Types.ObjectId(actorId),
...(expertProfileSnapshot && { expertProfileSnapshot }),
fields: {
accidentWay: {
id: reply.fields.accidentWay.id,
@@ -1279,6 +1299,7 @@ export class ExpertBlameService {
}
const now = new Date();
const inPersonSnapshot = await this.snapshotFieldExpert(actorId);
// Build expert decision with fields
const decisionPayload: any = {
@@ -1286,6 +1307,7 @@ export class ExpertBlameService {
description: "حضوری مراجعه شود.",
decidedAt: now,
decidedByExpertId: new Types.ObjectId(actorId),
...(inPersonSnapshot && { expertProfileSnapshot: inPersonSnapshot }),
fields: {
accidentWay: null,
accidentReason: null,
@@ -1445,6 +1467,8 @@ export class ExpertBlameService {
);
}
const expertProfileSnapshot = await this.snapshotFieldExpert(userId);
const newReplyObject = {
description: reply.description,
submitTime: new Date(),
@@ -1466,6 +1490,7 @@ export class ExpertBlameService {
},
firstPartyComment: request.expertSubmitReply?.firstPartyComment || null,
secondPartyComment: request.expertSubmitReply?.secondPartyComment || null,
...(expertProfileSnapshot && { expertProfileSnapshot }),
};
const updatePayload: any = {
@@ -1522,6 +1547,7 @@ export class ExpertBlameService {
}
const partyType = req.route.path.split("/")[4];
const resendSnapshot = await this.snapshotFieldExpert(userId);
switch (partyType) {
case "first": {
@@ -1542,6 +1568,9 @@ export class ExpertBlameService {
"expertResendReply.firstParty.firstPartyId": firstPartyId,
"expertResendReply.firstParty.firstPartyDescription":
firstPartyDescription,
...(resendSnapshot && {
expertResendByExpertProfileSnapshot: resendSnapshot,
}),
$push: {
actorsChecker: {
[ReqBlameStatus.UserPending]: request.actorLocked,
@@ -1579,6 +1608,9 @@ export class ExpertBlameService {
"expertResendReply.secondParty.secondPartyId": secondPartyId,
"expertResendReply.secondParty.secondPartyDescription":
secondPartyDescription,
...(resendSnapshot && {
expertResendByExpertProfileSnapshot: resendSnapshot,
}),
$push: {
actorsChecker: {
[ReqBlameStatus.UserPending]: request.actorLocked,
@@ -1658,10 +1690,15 @@ export class ExpertBlameService {
throw new NotFoundException("Blame not found");
}
const visitSnapshot = await this.snapshotFieldExpert(actorDetail.sub);
const updated = await this.requestManagementDbService.findAndUpdate(
{ _id: new Types.ObjectId(requestId) },
{
blameStatus: ReqBlameStatus.InPersonVisit,
...(visitSnapshot && {
fieldExpertInPersonVisitProfileSnapshot: visitSnapshot,
}),
},
);