forked from Yara724/api
Fixed Participants
This commit is contained in:
@@ -18,11 +18,6 @@ export interface ResolvedInquiryParticipant {
|
||||
hasDrivingLicense?: boolean;
|
||||
licenseNumber?: string;
|
||||
licenseType?: string;
|
||||
unknown?: boolean;
|
||||
}
|
||||
|
||||
export interface InquiryParticipantResolutionOptions {
|
||||
allowUnknownThirdPartyPolicyholder?: boolean;
|
||||
}
|
||||
|
||||
export interface InquiryParticipantRoleAssignments {
|
||||
@@ -96,6 +91,22 @@ export type ResolvedInquiryVehicle = InquiryVehicleInputDto & {
|
||||
registrationState: VehicleRegistrationState;
|
||||
};
|
||||
|
||||
function assertCompleteInquiryPlate(
|
||||
plate: InquiryVehicleInputDto["currentPlate"],
|
||||
path: "vehicle.currentPlate" | "vehicle.previousPlate",
|
||||
): void {
|
||||
for (const field of [
|
||||
"leftDigits",
|
||||
"centerAlphabet",
|
||||
"centerDigits",
|
||||
"ir",
|
||||
] as const) {
|
||||
if (plate?.[field] == null || String(plate[field]).trim() === "") {
|
||||
throw new BadRequestException(`${path}.${field} is required.`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export function participantForRole(
|
||||
resolved: ResolvedInquiryParticipants,
|
||||
role: InquiryParticipantRole,
|
||||
@@ -127,6 +138,23 @@ export function participantForStoredPartyRole(
|
||||
);
|
||||
}
|
||||
|
||||
/** Remove fields retired from the participant contract from historical records. */
|
||||
export function sanitizeStoredInquiryParticipants(
|
||||
participants: unknown,
|
||||
): Array<Record<string, any>> | undefined {
|
||||
if (!Array.isArray(participants)) return undefined;
|
||||
return participants.map((participant) => {
|
||||
const plain =
|
||||
participant &&
|
||||
typeof participant === "object" &&
|
||||
typeof (participant as { toObject?: unknown }).toObject === "function"
|
||||
? (participant as { toObject: () => Record<string, any> }).toObject()
|
||||
: { ...(participant as Record<string, any>) };
|
||||
delete plain.unknown;
|
||||
return plain;
|
||||
});
|
||||
}
|
||||
|
||||
const ROLE_FIELDS: Record<
|
||||
InquiryParticipantRole,
|
||||
keyof InquiryParticipantFieldsDto
|
||||
@@ -185,7 +213,6 @@ function requiredIdentity(
|
||||
export function resolveInquiryParticipants(
|
||||
caseType: BlameRequestType,
|
||||
input: Partial<InquiryParticipantFieldsDto> & Record<string, any>,
|
||||
options: InquiryParticipantResolutionOptions = {},
|
||||
): ResolvedInquiryParticipants {
|
||||
assertStructuredInquiryInput(input);
|
||||
const hasRoleCompleteInput = Object.values(ROLE_FIELDS).some(
|
||||
@@ -232,32 +259,7 @@ export function resolveInquiryParticipants(
|
||||
|
||||
resolving.add(role);
|
||||
let participantId: string;
|
||||
if (
|
||||
role === InquiryParticipantRole.THIRD_PARTY_POLICYHOLDER &&
|
||||
value.unknown === true
|
||||
) {
|
||||
if (!options.allowUnknownThirdPartyPolicyholder) {
|
||||
throw new BadRequestException(
|
||||
"An unknown third-party policyholder is allowed only for the damaged party.",
|
||||
);
|
||||
}
|
||||
const hasIdentityFields = Object.entries(value).some(
|
||||
([field, fieldValue]) => field !== "unknown" && fieldValue != null,
|
||||
);
|
||||
if (hasIdentityFields) {
|
||||
throw new BadRequestException(
|
||||
`${role} must contain either unknown=true or person fields, not both.`,
|
||||
);
|
||||
}
|
||||
const participant: ResolvedInquiryParticipant = {
|
||||
participantId: role,
|
||||
nationalCode: "",
|
||||
birthday: "",
|
||||
unknown: true,
|
||||
};
|
||||
participants.set(participant.participantId, participant);
|
||||
participantId = participant.participantId;
|
||||
} else if (value.unknown != null) {
|
||||
if (Object.prototype.hasOwnProperty.call(value, "unknown")) {
|
||||
throw new BadRequestException(
|
||||
`${role} does not support the unknown option.`,
|
||||
);
|
||||
@@ -314,28 +316,59 @@ export function resolveInquiryParticipants(
|
||||
export function resolveInquiryVehicle(
|
||||
input: InquiryVehicleInputDto,
|
||||
): ResolvedInquiryVehicle {
|
||||
if (!input) {
|
||||
throw new BadRequestException("vehicle is required.");
|
||||
}
|
||||
const registrationState =
|
||||
input.registrationState ?? VehicleRegistrationState.CURRENT;
|
||||
if (!Object.values(VehicleRegistrationState).includes(registrationState)) {
|
||||
throw new BadRequestException(
|
||||
"vehicle.registrationState must be CURRENT or RECENTLY_TRANSFERRED.",
|
||||
);
|
||||
}
|
||||
if (input.isNewCar != null && typeof input.isNewCar !== "boolean") {
|
||||
throw new BadRequestException("vehicle.isNewCar must be a boolean.");
|
||||
}
|
||||
const previousPolicyholderNationalCode = String(
|
||||
input.previousPolicyholderNationalCode ?? "",
|
||||
).trim();
|
||||
if (!input.currentPlate) {
|
||||
throw new BadRequestException("vehicle.currentPlate is required.");
|
||||
}
|
||||
assertCompleteInquiryPlate(input.currentPlate, "vehicle.currentPlate");
|
||||
const vin = String(input.vin ?? "").trim();
|
||||
if (vin && vin.length !== 17) {
|
||||
throw new BadRequestException(
|
||||
"vehicle.vin must contain exactly 17 characters.",
|
||||
);
|
||||
}
|
||||
if (
|
||||
registrationState === VehicleRegistrationState.RECENTLY_TRANSFERRED &&
|
||||
(!input.previousPlate || !String(input.vin ?? "").trim())
|
||||
(!input.previousPlate || !vin || !previousPolicyholderNationalCode)
|
||||
) {
|
||||
throw new BadRequestException(
|
||||
"RECENTLY_TRANSFERRED requires previousPlate and vin.",
|
||||
"RECENTLY_TRANSFERRED requires previousPlate, vin, and previousPolicyholderNationalCode.",
|
||||
);
|
||||
}
|
||||
if (
|
||||
registrationState !== VehicleRegistrationState.RECENTLY_TRANSFERRED &&
|
||||
input.previousPlate
|
||||
(input.previousPlate || input.previousPolicyholderNationalCode != null)
|
||||
) {
|
||||
throw new BadRequestException(
|
||||
"previousPlate is only allowed for RECENTLY_TRANSFERRED vehicles.",
|
||||
"previousPlate and previousPolicyholderNationalCode are only allowed for RECENTLY_TRANSFERRED vehicles.",
|
||||
);
|
||||
}
|
||||
return { ...input, registrationState };
|
||||
if (input.previousPlate) {
|
||||
assertCompleteInquiryPlate(input.previousPlate, "vehicle.previousPlate");
|
||||
}
|
||||
return {
|
||||
...input,
|
||||
registrationState,
|
||||
...(vin ? { vin } : {}),
|
||||
...(previousPolicyholderNationalCode
|
||||
? { previousPolicyholderNationalCode }
|
||||
: {}),
|
||||
};
|
||||
}
|
||||
|
||||
export function vehiclePlateCandidates(input?: ResolvedInquiryVehicle): Array<{
|
||||
@@ -459,7 +492,10 @@ export function isPolicyNotFoundError(error: unknown): boolean {
|
||||
export async function runPlateInquiryWithFallback<T>(options: {
|
||||
vehicle?: ResolvedInquiryVehicle;
|
||||
fallbackCurrentPlate: InquiryVehicleInputDto["currentPlate"];
|
||||
query: (plate: InquiryVehicleInputDto["currentPlate"]) => Promise<T>;
|
||||
query: (
|
||||
plate: InquiryVehicleInputDto["currentPlate"],
|
||||
plateKind: "CURRENT" | "PREVIOUS",
|
||||
) => Promise<T>;
|
||||
isUsable: (value: T) => boolean;
|
||||
mappedValue: (value: T) => Record<string, any>;
|
||||
shouldFallbackOnError?: (error: unknown) => boolean;
|
||||
@@ -492,7 +528,7 @@ export async function runPlateInquiryWithFallback<T>(options: {
|
||||
const candidate = candidates[index];
|
||||
const isLast = index === candidates.length - 1;
|
||||
try {
|
||||
const value = await options.query(candidate.plate);
|
||||
const value = await options.query(candidate.plate, candidate.kind);
|
||||
const usable = options.isUsable(value);
|
||||
if (!usable) {
|
||||
attempts.push({
|
||||
@@ -562,13 +598,8 @@ export async function runPlateInquiryWithFallback<T>(options: {
|
||||
export function normalizeInquirySubmission<T extends Record<string, any>>(
|
||||
caseType: BlameRequestType,
|
||||
input: T,
|
||||
options: InquiryParticipantResolutionOptions = {},
|
||||
): NormalizedInquirySubmission<T> {
|
||||
const participants = resolveInquiryParticipants(
|
||||
caseType,
|
||||
input as any,
|
||||
options,
|
||||
);
|
||||
const participants = resolveInquiryParticipants(caseType, input as any);
|
||||
const driver = participantForRole(
|
||||
participants,
|
||||
InquiryParticipantRole.DRIVER,
|
||||
|
||||
Reference in New Issue
Block a user