/**
* DKAN API Query Functions
*
* Alternative to CSV downloads - query data directly via DKAN API
* Works for large datasets (drug utilization, drug rebate) without downloading entire files
*/
const axios = require('axios');
/**
* Query DKAN datastore API using POST with conditions for server-side filtering
* @param {string} datasetId - Dataset UUID
* @param {Object} params - Query parameters
* @param {Array} conditions - Array of filter conditions [{property, value, operator}]
* @returns {Promise<Object>} Query results
*/
async function queryDKAN(datasetId, params = {}, conditions = []) {
const url = `https://data.medicaid.gov/api/1/datastore/query/${datasetId}/0`;
try {
// Build POST body for server-side filtering
const postBody = {
limit: params.limit || 100,
offset: params.offset || 0
};
// Add conditions for server-side filtering (much more efficient than client-side)
if (conditions && conditions.length > 0) {
postBody.conditions = conditions;
}
const response = await axios.post(url, postBody, {
headers: { 'Content-Type': 'application/json' },
timeout: 60000 // Increased timeout for larger queries
});
return {
results: response.data.results || [],
count: response.data.count || 0,
schema: response.data.schema || {}
};
} catch (error) {
throw new Error(`DKAN API error: ${error.message}`);
}
}
/**
* Query drug utilization data via DKAN API with server-side filtering
*/
async function queryDrugUtilization(params) {
const datasetId = '61729e5a-7aa8-448c-8903-ba3e0cd0ea3c'; // 2024 drug utilization
const userLimit = params.limit || 100;
// Build server-side filter conditions
const conditions = [];
// Drug name filter using LIKE for partial matching
if (params.drug_name) {
conditions.push({
property: 'product_name',
value: `%${params.drug_name.toUpperCase()}%`,
operator: 'LIKE'
});
}
// State filter using exact match
if (params.state) {
conditions.push({
property: 'state',
value: params.state.toUpperCase(),
operator: '='
});
}
// NDC filter using exact match
if (params.ndc) {
conditions.push({
property: 'ndc',
value: params.ndc,
operator: '='
});
}
// Year filter
if (params.year) {
conditions.push({
property: 'year',
value: String(params.year),
operator: '='
});
}
// Quarter filter
if (params.quarter) {
conditions.push({
property: 'quarter',
value: String(params.quarter),
operator: '='
});
}
// Query with server-side filtering
const response = await queryDKAN(datasetId, {
limit: userLimit,
offset: params.offset || 0
}, conditions);
let results = response.results;
return {
data: results.map(r => ({
state: r.state,
ndc: r.ndc,
product_name: (r.product_name || '').trim(), // Trim whitespace from product names
labeler_code: r.labeler_code,
year: parseInt(r.year) || 0,
quarter: parseInt(r.quarter) || 0,
units_reimbursed: parseFloat(r.units_reimbursed) || 0,
number_of_prescriptions: parseInt(r.number_of_prescriptions) || 0,
total_amount_reimbursed: parseFloat(r.total_amount_reimbursed) || 0,
medicaid_amount_reimbursed: parseFloat(r.medicaid_amount_reimbursed) || 0,
utilization_type: r.utilization_type
})),
meta: {
total_count: response.count,
returned_count: results.length,
query_type: 'drug_utilization',
source: 'DKAN API'
}
};
}
/**
* Query drug rebate program data via DKAN API with server-side filtering
*/
async function queryDrugRebate(params) {
const datasetId = '0ad65fe5-3ad3-5d79-a3f9-7893ded7963a'; // Drug rebate
const userLimit = params.limit || 100;
// Build server-side filter conditions
const conditions = [];
if (params.ndc) {
const normalizedNdc = params.ndc.replace(/-/g, '');
conditions.push({
property: 'ndc',
value: normalizedNdc,
operator: '='
});
}
if (params.drug_name) {
conditions.push({
property: 'fda_product_name',
value: `%${params.drug_name.toUpperCase()}%`,
operator: 'LIKE'
});
}
if (params.labeler_name) {
conditions.push({
property: 'labeler_name',
value: `%${params.labeler_name.toUpperCase()}%`,
operator: 'LIKE'
});
}
const response = await queryDKAN(datasetId, {
limit: userLimit,
offset: params.offset || 0
}, conditions);
let results = response.results;
return {
data: results.map(r => ({
ndc: r.ndc,
fda_product_name: r.fda_product_name,
labeler_name: r.labeler_name,
labeler_code: r.labeler_code,
drug_category: r.drug_category,
drug_type_indicator: r.drug_type_indicator,
fda_approval_date: r.fda_approval_date,
market_date: r.market_date,
termination_date: r.termination_date,
unit_type: r.unit_type,
units_per_pkg_size: r.units_per_pkg_size,
fda_therapeutic_equivalence_code: r.fda_therapeutic_equivalence_code,
clotting_factor_indicator: r.clotting_factor_indicator,
pediatric_indicator: r.pediatric_indicator,
year: r.year,
quarter: r.quarter
})),
meta: {
total_count: response.count,
returned_count: results.length,
query_type: 'drug_rebate',
source: 'DKAN API'
}
};
}
/**
* Query Federal Upper Limits via DKAN API with server-side filtering
*/
async function queryFederalUpperLimits(params) {
const datasetId = 'ce4cf49b-a21b-5a53-bbc3-509414940847'; // Federal Upper Limits
const userLimit = params.limit || 100;
// Build server-side filter conditions
const conditions = [];
if (params.ingredient) {
conditions.push({
property: 'Ingredient',
value: `%${params.ingredient.toUpperCase()}%`,
operator: 'LIKE'
});
}
if (params.ndc) {
conditions.push({
property: 'NDC',
value: params.ndc,
operator: '='
});
}
if (params.strength) {
conditions.push({
property: 'Strength',
value: `%${params.strength.toUpperCase()}%`,
operator: 'LIKE'
});
}
if (params.dosage) {
conditions.push({
property: 'Dosage',
value: `%${params.dosage.toUpperCase()}%`,
operator: 'LIKE'
});
}
if (params.year) {
conditions.push({
property: 'Year',
value: String(params.year),
operator: '='
});
}
if (params.month) {
conditions.push({
property: 'Month',
value: String(params.month),
operator: '='
});
}
const response = await queryDKAN(datasetId, {
limit: userLimit,
offset: params.offset || 0
}, conditions);
let results = response.results;
return {
data: results.map(r => ({
product_group: r['Product Group'] || r.product_group,
ingredient: r.Ingredient || r.ingredient,
strength: r.Strength || r.strength,
dosage: r.Dosage || r.dosage,
route: r.Route || r.route,
mdr_unit_type: r['MDR Unit Type'] || r.mdr_unit_type,
weighted_avg_amps: parseFloat(r['Weighted Average of AMPs'] || r.weighted_avg_amps) || 0,
aca_ful: parseFloat(r['ACA FUL'] || r.aca_ful) || 0,
package_size: r['Package Size'] || r.package_size,
ndc: r.NDC || r.ndc,
a_rated: r['A-Rated'] || r.a_rated,
multiplier: r['Multiplier Greater Than 175 Percent of Weighted Avg of AMPs'] || r.multiplier,
year: parseInt(r.Year || r.year),
month: parseInt(r.Month || r.month)
})),
meta: {
total_count: response.count,
returned_count: results.length,
query_type: 'federal_upper_limits',
source: 'DKAN API'
}
};
}
module.exports = {
queryDKAN,
queryDrugUtilization,
queryDrugRebate,
queryFederalUpperLimits
};