forked from Yara724/api
Added sign links and data to expert-claim API
This commit is contained in:
@@ -16,6 +16,7 @@ import { distance as stringDistance } from "fastest-levenshtein"; // حتما ن
|
||||
import { Types } from "mongoose";
|
||||
import { lastValueFrom } from "rxjs";
|
||||
import { ClaimRequestManagementDbService } from "src/claim-request-management/entites/db-service/claim-request-management.db.service";
|
||||
import { ClaimSignDbService } from "src/claim-request-management/entites/db-service/claim-sign.db.service";
|
||||
import { DamageImageDbService } from "src/claim-request-management/entites/db-service/damage-image.db.service";
|
||||
import { VideoCaptureDbService } from "src/claim-request-management/entites/db-service/video-capture.db.service";
|
||||
import { ClientDbService } from "src/client/entities/db-service/client.db.service";
|
||||
@@ -216,8 +217,68 @@ export class ExpertClaimService {
|
||||
private readonly smsOrchestrationService: SmsOrchestrationService,
|
||||
private readonly userDbService: UserDbService,
|
||||
private readonly expertFileActivityDbService: ExpertFileActivityDbService,
|
||||
private readonly claimSignDbService: ClaimSignDbService,
|
||||
) { }
|
||||
|
||||
/**
|
||||
* Resolve a `claim-sign` document id to a downloadable file URL.
|
||||
* Mirrors the helper used in `ExpertInsurerService` so signature links are
|
||||
* exposed identically across the two expert-facing detail endpoints.
|
||||
*/
|
||||
private async claimSignLinkFromId(
|
||||
signDetailId: unknown,
|
||||
): Promise<string | undefined> {
|
||||
if (signDetailId == null || signDetailId === "") return undefined;
|
||||
const id = String(signDetailId);
|
||||
if (!Types.ObjectId.isValid(id)) return undefined;
|
||||
const doc = await this.claimSignDbService.findOne({
|
||||
_id: new Types.ObjectId(id),
|
||||
});
|
||||
const path = (doc as any)?.path;
|
||||
return path ? buildFileLink(String(path)) : undefined;
|
||||
}
|
||||
|
||||
/**
|
||||
* Build a deep-cloned `evaluation` payload with resolved `signLink`s for the
|
||||
* fields that carry a user signature:
|
||||
*
|
||||
* - `damageExpertReply.userComment.signLink`
|
||||
* - `damageExpertReplyFinal.userComment.signLink`
|
||||
* - `ownerInsurerApproval.signLink`
|
||||
* - `ownerPricedPartsApproval.signLink`
|
||||
*
|
||||
* Returns `undefined` when there's no evaluation to enrich.
|
||||
*/
|
||||
private async enrichClaimEvaluationForExpert(
|
||||
evaluation: Record<string, unknown> | undefined | null,
|
||||
): Promise<Record<string, unknown> | undefined> {
|
||||
if (!evaluation || typeof evaluation !== "object") return undefined;
|
||||
const ev = JSON.parse(JSON.stringify(evaluation)) as Record<string, unknown>;
|
||||
|
||||
const enrichReplyUserComment = async (key: string) => {
|
||||
const reply = ev[key] as Record<string, unknown> | undefined;
|
||||
const uc = reply?.userComment as Record<string, unknown> | undefined;
|
||||
if (uc?.signDetailId != null) {
|
||||
const signLink = await this.claimSignLinkFromId(uc.signDetailId);
|
||||
(reply as Record<string, unknown>).userComment = { ...uc, signLink };
|
||||
}
|
||||
};
|
||||
await enrichReplyUserComment("damageExpertReply");
|
||||
await enrichReplyUserComment("damageExpertReplyFinal");
|
||||
|
||||
const enrichApproval = async (key: string) => {
|
||||
const o = ev[key] as Record<string, unknown> | undefined;
|
||||
if (o?.signDetailId != null) {
|
||||
const signLink = await this.claimSignLinkFromId(o.signDetailId);
|
||||
ev[key] = { ...o, signLink };
|
||||
}
|
||||
};
|
||||
await enrichApproval("ownerInsurerApproval");
|
||||
await enrichApproval("ownerPricedPartsApproval");
|
||||
|
||||
return ev;
|
||||
}
|
||||
|
||||
/** Load immutable profile fields from `damage-expert` for the acting expert. */
|
||||
private async snapshotDamageExpert(actorId: string) {
|
||||
const doc = await this.damageExpertDbService.findById(actorId);
|
||||
@@ -3473,6 +3534,46 @@ export class ExpertClaimService {
|
||||
)
|
||||
: undefined;
|
||||
|
||||
// Enrich the full evaluation block with `signLink`s for every place a user
|
||||
// signature is referenced, then assemble the response slice.
|
||||
//
|
||||
// We always expose owner approval blocks (when present in the DB) because
|
||||
// the signature URL is needed across all phases of the claim. The expert
|
||||
// reply payloads are still gated on `isFactorValidationPending` to match
|
||||
// the historical contract of this endpoint.
|
||||
const claimEvaluationRaw = (claim as any).evaluation as
|
||||
| Record<string, unknown>
|
||||
| undefined;
|
||||
const enrichedEvaluation = await this.enrichClaimEvaluationForExpert(
|
||||
claimEvaluationRaw,
|
||||
);
|
||||
|
||||
let evaluationForApi: Record<string, unknown> | undefined;
|
||||
if (enrichedEvaluation) {
|
||||
evaluationForApi = {};
|
||||
if (isFactorValidationPending) {
|
||||
if (enrichedEvaluation.damageExpertReply !== undefined) {
|
||||
evaluationForApi.damageExpertReply =
|
||||
enrichedEvaluation.damageExpertReply;
|
||||
}
|
||||
if (enrichedEvaluation.damageExpertReplyFinal !== undefined) {
|
||||
evaluationForApi.damageExpertReplyFinal =
|
||||
enrichedEvaluation.damageExpertReplyFinal;
|
||||
}
|
||||
}
|
||||
if (enrichedEvaluation.ownerInsurerApproval !== undefined) {
|
||||
evaluationForApi.ownerInsurerApproval =
|
||||
enrichedEvaluation.ownerInsurerApproval;
|
||||
}
|
||||
if (enrichedEvaluation.ownerPricedPartsApproval !== undefined) {
|
||||
evaluationForApi.ownerPricedPartsApproval =
|
||||
enrichedEvaluation.ownerPricedPartsApproval;
|
||||
}
|
||||
if (Object.keys(evaluationForApi).length === 0) {
|
||||
evaluationForApi = undefined;
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
claimRequestId: claim._id.toString(),
|
||||
publicId: claim.publicId,
|
||||
@@ -3511,12 +3612,9 @@ export class ExpertClaimService {
|
||||
carAngles,
|
||||
damagedParts,
|
||||
awaitingFactorValidation: isFactorValidationPending,
|
||||
evaluation: isFactorValidationPending
|
||||
? {
|
||||
damageExpertReply: (claim as any).evaluation?.damageExpertReply,
|
||||
damageExpertReplyFinal: (claim as any).evaluation?.damageExpertReplyFinal,
|
||||
}
|
||||
: undefined,
|
||||
evaluation: evaluationForApi as
|
||||
| ClaimDetailV2ResponseDto["evaluation"]
|
||||
| undefined,
|
||||
objection,
|
||||
videoCapture,
|
||||
blameCase: blameCaseForApi,
|
||||
|
||||
Reference in New Issue
Block a user