nhcx-fhir-coverage-eligibility
Version:
NHCX FHIR CoverageEligibilityRequest resource creation and validation library.
198 lines (197 loc) • 7.54 kB
JavaScript
;
// fhir/coverageEligibilityRequest/createCoverageEligibilityRequest.ts
Object.defineProperty(exports, "__esModule", { value: true });
exports.createCoverageEligibilityRequest = createCoverageEligibilityRequest;
// --- NHCX FHIR Profile Definitions ---
const ALLOWED_STATUS = ["active", "cancelled", "draft", "entered-in-error"];
const ALLOWED_PURPOSE = [
"auth-requirements",
"benefits",
"discovery",
"validation",
];
// Cardinality and allowed fields for each structure
const PROFILE_FIELDS = {
id: { min: 0, max: 1 },
meta: { min: 0, max: 1 },
implicitRules: { min: 0, max: 1 },
language: { min: 0, max: 1 },
text: { min: 0, max: 1 },
contained: { min: 0, max: Infinity },
extension: { min: 0, max: Infinity },
modifierExtension: { min: 0, max: Infinity },
identifier: { min: 1, max: 1 },
status: { min: 1, max: 1 },
priority: { min: 1, max: 1 },
purpose: { min: 1, max: Infinity },
patient: { min: 1, max: 1 },
servicedDate: { min: 0, max: 1 },
servicedPeriod: { min: 0, max: 1 },
created: { min: 1, max: 1 },
enterer: { min: 1, max: 1 },
provider: { min: 1, max: 1 },
insurer: { min: 1, max: 1 },
facility: { min: 1, max: 1 },
supportingInfo: { min: 0, max: Infinity },
insurance: { min: 1, max: Infinity },
item: { min: 0, max: Infinity },
};
const SUPPORTING_INFO_FIELDS = {
id: { min: 0, max: 1 },
extension: { min: 0, max: Infinity },
modifierExtension: { min: 0, max: Infinity },
sequence: { min: 1, max: 1 },
information: { min: 1, max: 1 },
appliesToAll: { min: 0, max: 1 },
};
const INSURANCE_FIELDS = {
id: { min: 0, max: 1 },
extension: { min: 0, max: Infinity },
modifierExtension: { min: 0, max: Infinity },
focal: { min: 0, max: 1 },
coverage: { min: 1, max: 1 },
businessArrangement: { min: 0, max: 1 },
};
const ITEM_FIELDS = {
id: { min: 0, max: 1 },
extension: { min: 0, max: Infinity },
modifierExtension: { min: 0, max: Infinity },
supportingInfoSequence: { min: 0, max: Infinity },
category: { min: 0, max: 1 },
productOrService: { min: 1, max: 1 },
modifier: { min: 0, max: Infinity },
provider: { min: 0, max: 1 },
quantity: { min: 0, max: 1 },
unitPrice: { min: 0, max: 1 },
facility: { min: 0, max: 1 },
diagnosis: { min: 0, max: Infinity },
detail: { min: 0, max: Infinity },
};
const ITEM_DIAGNOSIS_FIELDS = {
id: { min: 0, max: 1 },
extension: { min: 0, max: Infinity },
modifierExtension: { min: 0, max: Infinity },
diagnosisCodeableConcept: { min: 0, max: 1 },
diagnosisReference: { min: 0, max: 1 },
};
// --- Utility: Field Validation ---
function validateFields(input, profile, path = "") {
// Check for unsupported fields
for (const key of Object.keys(input)) {
if (!profile[key]) {
throw new Error(`Unsupported field '${path}${key}' in input`);
}
}
// Check cardinality and required fields
for (const [key, { min, max }] of Object.entries(profile)) {
const value = input[key];
if (min > 0 && (value === undefined || value === null || (Array.isArray(value) && value.length < min))) {
throw new Error(`Missing required field '${path}${key}'`);
}
if (value !== undefined) {
if (Array.isArray(value)) {
if (value.length < min)
throw new Error(`Field '${path}${key}' must have at least ${min} item(s)`);
if (max !== Infinity && value.length > max)
throw new Error(`Field '${path}${key}' must have at most ${max} item(s)`);
}
}
}
}
function validateSupportingInfo(arr, path = "supportingInfo[") {
arr.forEach((info, i) => {
validateFields(info, SUPPORTING_INFO_FIELDS, `${path}${i}].`);
});
}
function validateInsurance(arr, path = "insurance[") {
arr.forEach((ins, i) => {
validateFields(ins, INSURANCE_FIELDS, `${path}${i}].`);
});
}
function validateItem(arr, path = "item[") {
arr.forEach((item, i) => {
validateFields(item, ITEM_FIELDS, `${path}${i}].`);
if (item.diagnosis) {
item.diagnosis.forEach((diag, j) => {
validateFields(diag, ITEM_DIAGNOSIS_FIELDS, `${path}${i}].diagnosis[${j}].`);
});
}
});
}
// Helper to generate UUID (uses crypto.randomUUID if available, else fallback)
function generateUUID() {
if (typeof crypto !== 'undefined' && typeof crypto.randomUUID === 'function') {
return crypto.randomUUID();
}
// Fallback: RFC4122 version 4 compliant UUID
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
const r = (Math.random() * 16) | 0, v = c === 'x' ? r : (r & 0x3) | 0x8;
return v.toString(16);
});
}
/**
* Creates a valid NHCX FHIR CoverageEligibilityRequest resource.
* @param input - The resource fields (see CoverageEligibilityRequestInput for details).
* @returns The validated and defaulted FHIR resource.
* @throws Error if required fields are missing or invalid.
*/
function createCoverageEligibilityRequest(input) {
// Top-level validation
validateFields(input, PROFILE_FIELDS);
// Enum validation
if (!ALLOWED_STATUS.includes(input.status)) {
throw new Error(`Invalid status: '${input.status}'. Allowed: ${ALLOWED_STATUS.join(", ")}`);
}
if (!Array.isArray(input.purpose) || input.purpose.length === 0) {
throw new Error(`'purpose' must be a non-empty array`);
}
const invalidPurposes = input.purpose.filter((p) => !ALLOWED_PURPOSE.includes(p));
if (invalidPurposes.length > 0) {
throw new Error(`Invalid purpose(s): ${invalidPurposes.join(", ")}. Allowed: ${ALLOWED_PURPOSE.join(", ")}`);
}
if (input.servicedDate && input.servicedPeriod) {
throw new Error(`Only one of 'servicedDate' or 'servicedPeriod' may be provided`);
}
// Business logic: priority is required, no default
if (!input.priority) {
throw new Error(`Missing required field 'priority'`);
}
// Nested validation
if (input.supportingInfo)
validateSupportingInfo(input.supportingInfo);
if (input.insurance)
validateInsurance(input.insurance);
if (input.item)
validateItem(input.item);
// Set defaults
const created = input.created || new Date().toISOString();
const id = input.id || generateUUID();
let meta = input.meta;
if (!meta) {
meta = {
profile: [
"https://nrces.in/ndhm/fhir/r4/StructureDefinition/CoverageEligibilityRequest"
],
versionId: "1",
lastUpdated: new Date().toISOString()
};
}
else {
if (!meta.profile) {
meta.profile = [
"https://nrces.in/ndhm/fhir/r4/StructureDefinition/CoverageEligibilityRequest"
];
}
if (!meta.versionId) {
meta.versionId = "1";
}
if (!meta.lastUpdated) {
meta.lastUpdated = new Date().toISOString();
}
}
// Ensure meta fields are not undefined
const safeMeta = Object.assign(Object.assign({}, meta), { profile: meta.profile, versionId: meta.versionId, lastUpdated: meta.lastUpdated });
// Build resource
const resource = Object.assign(Object.assign({}, input), { resourceType: "CoverageEligibilityRequest", id, meta: safeMeta, created });
return resource;
}