forked from Yara724/api
253 lines
7.5 KiB
TypeScript
253 lines
7.5 KiB
TypeScript
export type FanavaranClientKey = "parsian" | "tejaratno" | "moallem";
|
|
|
|
export const FANAVARAN_CLIENT_KEYS: readonly FanavaranClientKey[] = [
|
|
"parsian",
|
|
"tejaratno",
|
|
"moallem",
|
|
] as const;
|
|
|
|
/** Swagger `@ApiParam({ enum })` value — keep in sync with {@link FANAVARAN_CLIENT_KEYS}. */
|
|
export const FANAVARAN_CLIENT_SWAGGER_ENUM: FanavaranClientKey[] = [
|
|
...FANAVARAN_CLIENT_KEYS,
|
|
];
|
|
|
|
export function isFanavaranClientKey(
|
|
value: string,
|
|
): value is FanavaranClientKey {
|
|
const normalized = value?.trim().toLowerCase();
|
|
return (FANAVARAN_CLIENT_KEYS as readonly string[]).includes(normalized);
|
|
}
|
|
|
|
export function normalizeFanavaranClientKey(value: string): FanavaranClientKey {
|
|
const normalized = value?.trim().toLowerCase();
|
|
if (isFanavaranClientKey(normalized)) {
|
|
return normalized;
|
|
}
|
|
throw new Error(
|
|
`Invalid Fanavaran client "${value}". Expected one of: ${FANAVARAN_CLIENT_KEYS.join(", ")}`,
|
|
);
|
|
}
|
|
|
|
export interface FanavaranAuthConfig {
|
|
appName: string;
|
|
secret: string;
|
|
username: string;
|
|
password: string;
|
|
corpId: string;
|
|
contractId: string;
|
|
/**
|
|
* Vehicle-hull (بدنه) ContractId. Must not be the ثالث contract.
|
|
* When unset, body lookups fall back to `contractId`.
|
|
*/
|
|
hullContractId?: string;
|
|
location: string;
|
|
}
|
|
|
|
export interface FanavaranPayloadDefaults {
|
|
AccidentCityId: number;
|
|
AccidentReportTypeId: number;
|
|
AccidentVehicleUsedId: number;
|
|
/**
|
|
* GEN.03 base claim — کارشناس مسئول پرونده مالی
|
|
* (must NOT be the assessor role used on GEN.08).
|
|
*/
|
|
ClaimExpertId: number;
|
|
/**
|
|
* GEN.08 expertise — کارشناس ارزیاب خسارت ثالث مالی / وکیل معتمد / کارشناس تحقیق
|
|
* (Parsian: 29; Tejaratno proven: 2709).
|
|
*/
|
|
ExpertiseClaimExpertId: number;
|
|
/** GEN.06 hull RepairDuration when configured per tenant (optional). */
|
|
HullExpertiseRepairDuration?: number | null;
|
|
CompensationReferenceId: number;
|
|
CulpritLicenceTypeId: number;
|
|
CulpritTypeId: number;
|
|
DmgCaseTypeId: number;
|
|
DmgHistoryStatus: number;
|
|
PlaqueKindId: number;
|
|
PlaqueSampleId: number;
|
|
DriverIsOwner: number;
|
|
FaultPercent: number;
|
|
ClaimFileTypeId: number;
|
|
}
|
|
|
|
export interface FanavaranClientProfile {
|
|
key: FanavaranClientKey;
|
|
auth: FanavaranAuthConfig;
|
|
defaults: FanavaranPayloadDefaults;
|
|
}
|
|
|
|
/**
|
|
* Shared codebook-ish defaults. Each tenant must override ClaimExpertId /
|
|
* ExpertiseClaimExpertId (they are different Fanavaran roles).
|
|
*/
|
|
const SHARED_FANAVARAN_DEFAULTS: FanavaranPayloadDefaults = {
|
|
AccidentCityId: 701,
|
|
AccidentReportTypeId: 155,
|
|
AccidentVehicleUsedId: 1,
|
|
ClaimExpertId: 4543092,
|
|
ExpertiseClaimExpertId: 2709,
|
|
CompensationReferenceId: 167,
|
|
CulpritLicenceTypeId: 2,
|
|
CulpritTypeId: 337,
|
|
DmgCaseTypeId: 175,
|
|
DmgHistoryStatus: 5214,
|
|
PlaqueKindId: 8,
|
|
PlaqueSampleId: 10,
|
|
DriverIsOwner: 0,
|
|
FaultPercent: 100,
|
|
ClaimFileTypeId: 23,
|
|
};
|
|
|
|
/**
|
|
* Seed / code fallback profiles. On app boot these are inserted into
|
|
* `fanavaranClientConfigs` only when a key is missing (never overwrite DB edits).
|
|
* Runtime reads prefer the in-memory cache loaded from Mongo.
|
|
*/
|
|
export const SEED_FANAVARAN_CLIENT_PROFILES: Record<
|
|
FanavaranClientKey,
|
|
FanavaranClientProfile
|
|
> = {
|
|
tejaratno: {
|
|
key: "tejaratno",
|
|
auth: {
|
|
appName: "fanhab",
|
|
secret: "5Fa@N#A2B",
|
|
username: "fanhabUser",
|
|
password: "Fan#@2U$3er",
|
|
corpId: "3539",
|
|
contractId: "263",
|
|
location: "100",
|
|
},
|
|
defaults: {
|
|
...SHARED_FANAVARAN_DEFAULTS,
|
|
// GEN.03 — کارشناس مسئول پرونده مالی
|
|
ClaimExpertId: 2721,
|
|
// GEN.08 — ارزیاب (proven successful submit 2026-07-18 ClaimExpertId: 2709)
|
|
ExpertiseClaimExpertId: 2709,
|
|
ClaimFileTypeId: 23,
|
|
},
|
|
},
|
|
parsian: {
|
|
key: "parsian",
|
|
auth: {
|
|
appName: "ParsianService",
|
|
secret: "P@r30@n$erv!ce",
|
|
username: "ParsianServiceUser",
|
|
password: "P@r30@n123",
|
|
corpId: "543",
|
|
contractId: "28",
|
|
location: "210050",
|
|
},
|
|
defaults: {
|
|
...SHARED_FANAVARAN_DEFAULTS,
|
|
// GEN.03 — مسئول پرونده مالی (Fanavaran example used 154; west branch 4662)
|
|
ClaimExpertId: 154,
|
|
// GEN.08 — ارزیاب خسارت ثالث مالی (رسول کرکی / شعبه غرب → 29)
|
|
ExpertiseClaimExpertId: 29,
|
|
// GEN.07 — proven 2026-08-03 (CL68535): 63 = سایر مدارک خسارت in parsian file-types.
|
|
// Do not use 70 — not in Parsian lookup → "نوع فايل با منبع لوکاپ مطابقت ندارد".
|
|
ClaimFileTypeId: 63,
|
|
},
|
|
},
|
|
moallem: {
|
|
key: "moallem",
|
|
auth: {
|
|
appName: "ItTalie",
|
|
secret: "itT@l!3@api",
|
|
username: "itTalieUser",
|
|
password: "itT@l!3@user",
|
|
corpId: "5650",
|
|
contractId: "304",
|
|
location: "1",
|
|
},
|
|
// Expert role ids not confirmed for Moallem yet — start from shared shape.
|
|
defaults: {
|
|
...SHARED_FANAVARAN_DEFAULTS,
|
|
},
|
|
},
|
|
};
|
|
|
|
/** @deprecated Use SEED_FANAVARAN_CLIENT_PROFILES — kept alias for older imports. */
|
|
export const FANAVARAN_CLIENT_PROFILES = SEED_FANAVARAN_CLIENT_PROFILES;
|
|
|
|
/**
|
|
* Runtime cache filled by FanavaranClientConfigService on boot from Mongo.
|
|
* Until then (and in unit tests), callers fall back to seed profiles.
|
|
*/
|
|
let runtimeProfiles: Partial<
|
|
Record<FanavaranClientKey, FanavaranClientProfile>
|
|
> | null = null;
|
|
|
|
export function setFanavaranClientProfilesCache(
|
|
profiles: Partial<Record<FanavaranClientKey, FanavaranClientProfile>>,
|
|
): void {
|
|
runtimeProfiles = profiles;
|
|
}
|
|
|
|
export function clearFanavaranClientProfilesCache(): void {
|
|
runtimeProfiles = null;
|
|
}
|
|
|
|
/** Resolve active Fanavaran tenant from env (`FANAVARAN_CLIENT`) with optional CLIENT_ID fallback. */
|
|
export function resolveFanavaranClientKey(): FanavaranClientKey {
|
|
const explicit = process.env.FANAVARAN_CLIENT?.trim().toLowerCase();
|
|
if (explicit && isFanavaranClientKey(explicit)) {
|
|
return explicit;
|
|
}
|
|
|
|
// Optional deployment hint when FANAVARAN_CLIENT is not set.
|
|
if (String(process.env.CLIENT_ID ?? "") === "8") {
|
|
return "parsian";
|
|
}
|
|
|
|
return "tejaratno";
|
|
}
|
|
|
|
export function resolveFanavaranClientProfile(): FanavaranClientProfile {
|
|
return getFanavaranClientProfile(resolveFanavaranClientKey());
|
|
}
|
|
|
|
export function getFanavaranClientProfile(
|
|
clientKey: FanavaranClientKey,
|
|
): FanavaranClientProfile {
|
|
return (
|
|
runtimeProfiles?.[clientKey] ?? SEED_FANAVARAN_CLIENT_PROFILES[clientKey]
|
|
);
|
|
}
|
|
|
|
/** ثالث uses `contractId`. بدنه uses `hullContractId` when configured. */
|
|
export function resolveFanavaranProductContractId(
|
|
clientKey: FanavaranClientKey,
|
|
product: "third-party" | "car-body",
|
|
): string {
|
|
const profile = getFanavaranClientProfile(clientKey);
|
|
if (product === "car-body") {
|
|
const hull = profile.auth.hullContractId?.trim();
|
|
if (hull) return hull;
|
|
}
|
|
return profile.auth.contractId;
|
|
}
|
|
|
|
export function listFanavaranClientProfiles(): FanavaranClientProfile[] {
|
|
return FANAVARAN_CLIENT_KEYS.map((key) => getFanavaranClientProfile(key));
|
|
}
|
|
|
|
export function fanavaranPreviewPath(
|
|
clientKey: FanavaranClientKey,
|
|
claimCaseId: string,
|
|
): string {
|
|
return `/v2/fanavaran/${clientKey}/claim-cases/${claimCaseId}/base-claim/preview`;
|
|
}
|
|
|
|
export function fanavaranSubmitPath(
|
|
clientKey: FanavaranClientKey,
|
|
claimCaseId: string,
|
|
): string {
|
|
return `/v2/fanavaran/${clientKey}/claim-cases/${claimCaseId}/base-claim/submit`;
|
|
}
|
|
|
|
export function fanavaranManualSubmitPath(claimCaseId: string): string {
|
|
return fanavaranSubmitPath(resolveFanavaranClientKey(), claimCaseId);
|
|
}
|