fix(fanavaran): select latest active policy by end date

Why:
- Fanavaran policy inquiry response order is inconsistent, so selecting the last item can choose an old or expired policy.

Changes:
- Select the policy with the latest Jalali EndDate.
- Reject empty policy responses, expired latest policies, and latest policies without a valid PolicyId.
- Stop Fanavaran submission when PolicyId cannot be resolved.

Impact:
- Fanavaran submit now fails clearly instead of continuing with PolicyId: null.
This commit is contained in:
2026-06-30 11:51:11 +03:30
parent f3686575ca
commit 8d396762a2
3 changed files with 187 additions and 55 deletions

View File

@@ -176,6 +176,7 @@ import {
FanavaranAuditStatus,
FanavaranAuditStep,
} from "src/fanavaran/schema/fanavaran-audit-log.schema";
import { selectLatestActiveFanavaranPolicy } from "./fanavaran-policy-selection";
export interface FanavaranAutoSubmitResult {
attempted: boolean;
@@ -3438,17 +3439,13 @@ export class ClaimRequestManagementService {
this.applyFanavaranDefaultFields(result);
try {
const policyId = await input.resolvePolicyId();
if (policyId !== undefined && policyId !== null) {
result.PolicyId = policyId;
}
} catch (error) {
this.logger.error(
`${input.logPrefix} Failed to get PolicyId from external API:`,
error,
const policyId = await input.resolvePolicyId();
if (policyId === undefined || policyId === null) {
throw new BadRequestException(
`${input.logPrefix} PolicyId is required for Fanavaran submit. Policy inquiry returned no valid policy; contact the administrator.`,
);
}
result.PolicyId = policyId;
return result;
}
@@ -3567,15 +3564,18 @@ export class ClaimRequestManagementService {
blameRequest,
claimRequestId,
);
if (policyId) {
result.PolicyId = policyId;
if (!policyId) {
throw new BadRequestException(
`[Fanavaran Submit] PolicyId is required for Fanavaran submit. Policy inquiry returned no valid policy; contact the administrator.`,
);
}
result.PolicyId = policyId;
} catch (error) {
this.logger.error(
`[Fanavaran Submit] Failed to get PolicyId from external API:`,
error,
);
// Continue without PolicyId if API call fails
throw error;
}
return result;
@@ -3866,11 +3866,7 @@ export class ClaimRequestManagementService {
}),
);
const policyCount = Array.isArray(response.data)
? response.data.length
: 0;
const lastPolicy =
policyCount > 0 ? response.data[policyCount - 1] : null;
const policyCount = Array.isArray(response.data) ? response.data.length : 0;
this.logger.log(
`${logPrefix} Policy inquiry response status=${response.status} count=${policyCount}`,
@@ -3882,39 +3878,11 @@ export class ClaimRequestManagementService {
2,
)}`,
);
if (lastPolicy && typeof lastPolicy === "object") {
this.logger.log(
`${logPrefix} Policy inquiry last policy keys: ${Object.keys(
lastPolicy,
).join(", ")}`,
);
}
const selectedPolicy = selectLatestActiveFanavaranPolicy(response.data);
this.logger.log(
`${logPrefix} Selected latest active policy PolicyId=${selectedPolicy.policyId} EndDate=${selectedPolicy.endDate}`,
);
if (Array.isArray(response.data) && response.data.length > 0) {
const policyId = lastPolicy?.PolicyId;
if (policyId !== undefined && policyId !== null) {
this.logger.log(
`${logPrefix} Successfully retrieved PolicyId from last policy entry: ${policyId}`,
);
if (auditSession) {
await this.fanavaranAuditService.recordStep({
session: auditSession,
step: FanavaranAuditStep.POLICY_INQUIRY,
status: FanavaranAuditStatus.SUCCESS,
requestUrl: policyInquiryUrl,
httpStatus: response.status,
responseMeta: {
policyId,
policyCount: response.data.length,
},
durationMs: Date.now() - startedAt,
});
}
return policyId;
}
}
this.logger.warn(`${logPrefix} No PolicyId found in API response`);
if (auditSession) {
await this.fanavaranAuditService.recordStep({
session: auditSession,
@@ -3923,15 +3891,15 @@ export class ClaimRequestManagementService {
requestUrl: policyInquiryUrl,
httpStatus: response.status,
responseMeta: {
policyId: null,
policyCount: Array.isArray(response.data)
? response.data.length
: 0,
policyId: selectedPolicy.policyId,
policyEndDate: selectedPolicy.endDate,
policyEndDateGregorian: selectedPolicy.endDateGregorian,
policyCount,
},
durationMs: Date.now() - startedAt,
});
}
return null;
return selectedPolicy.policyId;
} catch (error) {
const errorMessage =
error instanceof Error ? error.message : "unknown policy inquiry error";
@@ -3948,8 +3916,11 @@ export class ClaimRequestManagementService {
});
}
this.logger.warn(
`${logPrefix} Policy inquiry failed; continuing with empty PolicyId: ${errorMessage}`,
`${logPrefix} Policy inquiry failed: ${errorMessage}`,
);
if (error instanceof BadRequestException) {
throw error;
}
return null;
}
}
@@ -4011,6 +3982,9 @@ export class ClaimRequestManagementService {
`[Fanavaran Submit] Error getting PolicyId from external API:`,
error,
);
if (error instanceof BadRequestException) {
throw error;
}
return null;
}
}