1
0
forked from Yara724/api

Fixed resend blame and claim sms start

This commit is contained in:
SepehrYahyaee
2026-05-30 16:18:11 +03:30
parent 7aada14551
commit 3b0db0d250
5 changed files with 87 additions and 45 deletions

View File

@@ -51,11 +51,14 @@ export function cloneResendUploadedDocuments(
}
/** How the mobile/web client should collect each resend item (no workflow-step manager). */
export type ResendItemInputKind = "document_camera" | "voice" | "video" | "text";
export type ResendItemInputKind =
| "document_camera"
| "voice"
| "video"
| "text";
export function getResendItemInputKind(item: string): ResendItemInputKind {
if (item === ResendItemType.VOICE) return "voice";
if (item === ResendItemType.VIDEO) return "video";
if (item === ResendItemType.DESCRIPTION) return "text";
return "document_camera";
}
@@ -80,13 +83,15 @@ export function isResendPartyItemSatisfied(
): boolean {
const uploaded = row.uploadedDocuments || {};
if (item === ResendItemType.DESCRIPTION) {
return !!(row.userTextDescription && String(row.userTextDescription).trim());
return !!(
row.userTextDescription && String(row.userTextDescription).trim()
);
}
if (item === ResendItemType.VOICE) {
return !!row.resendVoiceId;
}
if (item === ResendItemType.VIDEO) {
return !!row.resendVideoId;
}
// if (item === ResendItemType.VIDEO) {
// return !!row.resendVideoId;
// }
return !!uploaded[item];
}

View File

@@ -5,11 +5,10 @@ export enum ResendItemType {
CAR_CERTIFICATE = "carCertificate",
DRIVING_LICENSE = "drivingLicense",
CAR_GREEN_CARD = "carGreenCard",
PLATE = "plate",
CAR_PLATE = "carPlate",
CHASSIS_NUMBER = "chassisNumber",
// Media evidence
VOICE = "voice",
VIDEO = "video",
/** Written / text party description (maps to FIRST_DESCRIPTION / SECOND_DESCRIPTION workflow steps) */
DESCRIPTION = "description",

View File

@@ -30,7 +30,12 @@ export const DEFAULT_CAR_BODY_ACCIDENT_MAX_AGE_DAYS = 7;
* default window (see {@link DEFAULT_MEDIA_LIMITS}) and an optional
* per-client override under `settings.media.<kind>`.
*/
export type MediaKind = "video" | "image" | "voice";
export type MediaKind =
| "video"
| "image"
| "voice"
| "chassisNumber"
| "carPlate";
export interface MediaLimits {
/** Inclusive lower bound. `0` allows any size from zero up. */
@@ -63,6 +68,14 @@ export const DEFAULT_MEDIA_LIMITS: Record<MediaKind, MediaLimits> = {
minBytes: DEFAULT_MEDIA_MIN_BYTES,
maxBytes: DEFAULT_MEDIA_MAX_BYTES,
},
carPlate: {
minBytes: DEFAULT_MEDIA_MIN_BYTES,
maxBytes: DEFAULT_MEDIA_MAX_BYTES,
},
chassisNumber: {
minBytes: DEFAULT_MEDIA_MIN_BYTES,
maxBytes: DEFAULT_MEDIA_MAX_BYTES,
},
};
/** Highest multer `fileSize` used on any route for each kind (policy cannot exceed this). */
@@ -70,6 +83,8 @@ export const MEDIA_ROUTE_MAX_BYTES: Record<MediaKind, number> = {
video: DEFAULT_MEDIA_MAX_BYTES,
image: DEFAULT_MEDIA_MAX_BYTES,
voice: DEFAULT_MEDIA_MAX_BYTES,
carPlate: DEFAULT_MEDIA_MAX_BYTES,
chassisNumber: DEFAULT_MEDIA_MAX_BYTES,
};
export const CAR_BODY_ACCIDENT_MAX_AGE_DAYS_MIN = 1;

View File

@@ -6682,19 +6682,19 @@ export class RequestManagementService {
] = (voiceDoc as any)._id;
mergedRow.resendVoiceId = (voiceDoc as any)._id;
uploadedItems.push(canonKey);
} else if (canonKey === ResendItemType.VIDEO) {
const videoDoc = await this.blameVideoDbService.create({
path: file.path,
requestId: new Types.ObjectId(requestId),
fileName: file.filename,
});
updatePayload.$set[`parties.${partyIndex}.evidence.videoId`] = String(
(videoDoc as any)._id,
);
updatePayload.$set[
`expert.resend.parties.${resendIndex}.resendVideoId`
] = (videoDoc as any)._id;
mergedRow.resendVideoId = (videoDoc as any)._id;
// } else if (canonKey === ResendItemType.VIDEO) {
// const videoDoc = await this.blameVideoDbService.create({
// path: file.path,
// requestId: new Types.ObjectId(requestId),
// fileName: file.filename,
// });
// updatePayload.$set[`parties.${partyIndex}.evidence.videoId`] = String(
// (videoDoc as any)._id,
// );
// updatePayload.$set[
// `expert.resend.parties.${resendIndex}.resendVideoId`
// ] = (videoDoc as any)._id;
// mergedRow.resendVideoId = (videoDoc as any)._id;
uploadedItems.push(canonKey);
} else {
const docType = canonKey as BlameDocumentType;
@@ -6932,7 +6932,12 @@ export class RequestManagementService {
if (targetPhone) {
const publicId = String(updatedRequest.publicId);
const link = this.smsOrchestrationService.buildClaimLink(requestId);
const link = this.smsOrchestrationService.buildBlamePartyLink(
requestId,
targetPhone === request?.parties[0]?.person.phoneNumber
? "FIRST"
: "SECOND",
);
await this.smsOrchestrationService.sendThirdPartyDamagedPartyClaimLinkNotice(
{
receptor: targetPhone,

View File

@@ -22,7 +22,10 @@ import {
ApiParam,
ApiTags,
} from "@nestjs/swagger";
import { FileFieldsInterceptor, FileInterceptor } from "@nestjs/platform-express";
import {
FileFieldsInterceptor,
FileInterceptor,
} from "@nestjs/platform-express";
import { diskStorage } from "multer";
import { Request } from "express";
import { GlobalGuard } from "src/auth/guards/global.guard";
@@ -59,7 +62,7 @@ export class RequestManagementV2Controller {
constructor(
private readonly requestManagementService: RequestManagementService,
private readonly mediaPolicyService: MediaPolicyService,
) { }
) {}
@Post()
@UseGuards(GlobalGuard)
@@ -114,7 +117,11 @@ export class RequestManagementV2Controller {
@Body() body: BlameConfessionDtoV2,
@CurrentUser() user,
) {
return this.requestManagementService.blameConfessionV2(requestId, body, user);
return this.requestManagementService.blameConfessionV2(
requestId,
body,
user,
);
}
/** CAR_BODY only: submit accident type (car vs object). Call this when nextStep is CAR_BODY_ACCIDENT_TYPE. */
@@ -127,7 +134,11 @@ export class RequestManagementV2Controller {
@Body() body: CarBodyFormDto,
@CurrentUser() user,
) {
return this.requestManagementService.carBodyAccidentTypeFormV2(requestId, body, user);
return this.requestManagementService.carBodyAccidentTypeFormV2(
requestId,
body,
user,
);
}
@ApiBody({
@@ -195,7 +206,11 @@ export class RequestManagementV2Controller {
@Body() body: LocationDto,
@CurrentUser() user,
) {
return this.requestManagementService.addDetailLocationV2(requestId, body, user);
return this.requestManagementService.addDetailLocationV2(
requestId,
body,
user,
);
}
@ApiBody({
@@ -269,7 +284,11 @@ export class RequestManagementV2Controller {
@Body() body: DescriptionDto,
@CurrentUser() user,
) {
return this.requestManagementService.addDescriptionV2(requestId, body, user);
return this.requestManagementService.addDescriptionV2(
requestId,
body,
user,
);
}
@Post("add-second-party/:phoneNumber/:requestId/:frontendRoute")
@@ -355,9 +374,8 @@ export class RequestManagementV2Controller {
await this.mediaPolicyService.assertForBlame(sign, requestId, "image");
// Convert string "true"/"false" to boolean
const acceptDecision = typeof isAccept === "string"
? isAccept === "true"
: Boolean(isAccept);
const acceptDecision =
typeof isAccept === "string" ? isAccept === "true" : Boolean(isAccept);
return this.requestManagementService.userSignDecisionV2(
requestId,
@@ -405,17 +423,15 @@ export class RequestManagementV2Controller {
format: "binary",
description: "Voice recording file (if requested)",
},
video: {
carPlate: {
type: "string",
format: "binary",
description: "Video file (if requested)",
description: "car plate",
},
chassisNumber: {
type: "string",
description: "chassis number شماره شاسی",
},
description: {
type: "string",
description:
"Text description when expert requested ResendItemType.description",
},
textDescription: {
type: "string",
description:
"Alias for `description` (same semantics); either field may be used.",
@@ -431,7 +447,8 @@ export class RequestManagementV2Controller {
{ name: "nationalCertificate", maxCount: 1 },
{ name: "carGreenCard", maxCount: 1 },
{ name: "voice", maxCount: 1 },
{ name: "video", maxCount: 1 },
{ name: "carPlate", maxCount: 1 },
{ name: "chassisNumber", maxCount: 1 },
],
{
storage: diskStorage({
@@ -460,7 +477,8 @@ export class RequestManagementV2Controller {
nationalCertificate?: Express.Multer.File[];
carGreenCard?: Express.Multer.File[];
voice?: Express.Multer.File[];
video?: Express.Multer.File[];
carPlate?: Express.Multer.File[];
chassisNumber?: Express.Multer.File[];
},
@Body("description") description?: string,
@Body("textDescription") textDescription?: string,
@@ -474,7 +492,8 @@ export class RequestManagementV2Controller {
nationalCertificate: "image",
carGreenCard: "image",
voice: "voice",
video: "video",
carPlate: "carPlate",
chassisNumber: "chassisNumber",
});
const descCandidates = [description, textDescription]
@@ -490,4 +509,3 @@ export class RequestManagementV2Controller {
);
}
}