← back to AbramsOS
scripts/ndc-recall-check.js
87 lines
#!/usr/bin/env node
// NDC-PRECISE FDA recall match. The by-name pass is advisory ("this drug has had recalls");
// this pass matches each fill's ACTUAL dispensed NDC against openFDA enforcement records, so a
// flag means "your specific product/manufacturer is on a recall list" — the actionable signal.
//
// Our fills store 11-digit package NDCs ("00032-3016-13"); openFDA stores 10-digit product NDCs
// with leading zeros stripped ("0032-3016"). We query a couple of candidate formats, then CONFIRM
// each hit by comparing leading-zero-stripped labeler|product pairs — exact, conservative.
//
// openFDA = free ($0). Idempotent. Usage: node scripts/ndc-recall-check.js
const db = require('../lib/db');
const audit = require('../lib/audit');
const sleep = (ms) => new Promise((r) => setTimeout(r, ms));
const USER = 'user_steve', SOURCE = 'shangoo-pharmacy-tax-2023-2026';
const BASE = 'https://api.fda.gov/drug/enforcement.json';
const KEY = process.env.OPENFDA_API_KEY ? `&api_key=${process.env.OPENFDA_API_KEY}` : '';
// leading-zero-stripped "labeler|product" from any NDC (ignores the package segment)
function segPair(ndc) {
const p = String(ndc || '').split('-');
if (p.length < 2 || !/^\d+$/.test(p[0]) || !/^\d+$/.test(p[1])) return null;
return `${parseInt(p[0], 10)}|${parseInt(p[1], 10)}`;
}
// candidate product_ndc query strings for a stored 5-4-2 package NDC
function candidates(ndc) {
const p = String(ndc).split('-'); if (p.length < 2) return [];
const c = new Set([`${p[0]}-${p[1]}`]); // as-stored labeler (e.g. 00032-3016)
if (p[0][0] === '0') c.add(`${p[0].replace(/^0/, '')}-${p[1]}`); // one leading zero off (0032-3016)
return [...c];
}
const sev = (c) => (c === 'Class I' ? 3 : c === 'Class II' ? 2 : c === 'Class III' ? 1 : 0);
async function main() {
await db.query(`ALTER TABLE prescription_fill
ADD COLUMN IF NOT EXISTS ndc_recalled boolean NOT NULL DEFAULT false,
ADD COLUMN IF NOT EXISTS ndc_recall_number text,
ADD COLUMN IF NOT EXISTS ndc_recall_class text,
ADD COLUMN IF NOT EXISTS ndc_recall_reason text`);
await db.query(`UPDATE prescription_fill SET ndc_recalled=false, ndc_recall_number=NULL, ndc_recall_class=NULL, ndc_recall_reason=NULL
WHERE user_id=$1 AND source=$2`, [USER, SOURCE]);
const ndcs = (await db.query(
`SELECT DISTINCT ndc FROM prescription_fill WHERE user_id=$1 AND source=$2
AND ndc IS NOT NULL AND ndc<>'' AND ndc NOT LIKE '00000%'`, [USER, SOURCE])).rows.map((r) => r.ndc);
console.log(`checking ${ndcs.length} distinct NDCs against openFDA (NDC-precise)…`);
let flagged = 0, fillsFlagged = 0;
for (const ndc of ndcs) {
const want = segPair(ndc); if (!want) continue;
let best = null;
for (const cand of candidates(ndc)) {
let results = [];
try {
const r = await fetch(`${BASE}?search=openfda.product_ndc:%22${encodeURIComponent(cand)}%22&limit=20${KEY}`,
{ headers: { 'User-Agent': 'AbramsOS/1.0 (personal household admin)' } });
if (r.status === 404) { await sleep(180); continue; }
if (r.ok) results = (await r.json()).results || [];
} catch { /* transient */ }
for (const rec of results) {
const pn = (rec.openfda && rec.openfda.product_ndc) || [];
if (!pn.some((x) => segPair(x) === want)) continue; // CONFIRM exact labeler|product
const cls = rec.classification || null;
if (!best || sev(cls) > sev(best.classification)) best = rec;
}
await sleep(180);
}
if (best) {
const up = await db.query(
`UPDATE prescription_fill SET ndc_recalled=true, ndc_recall_number=$3, ndc_recall_class=$4, ndc_recall_reason=$5
WHERE user_id=$1 AND source=$2 AND ndc=$6`,
[USER, SOURCE, best.recall_number || null, best.classification || null,
(best.reason_for_recall || '').slice(0, 300), ndc]);
flagged++; fillsFlagged += up.rowCount;
console.log(` ⚠ NDC ${ndc} → ${best.classification} ${best.recall_number} (${up.rowCount} fills)`);
}
}
await audit.log({ actorType: 'user', actorId: USER, objectType: 'prescription_fill', objectId: SOURCE,
eventType: 'fda_ndc_recall_crossref', metadata: { medical: true, source: 'openFDA', ndcs: ndcs.length, ndcs_recalled: flagged, fills_flagged: fillsFlagged } });
console.log(`\nNDC-precise DONE: ${flagged} of ${ndcs.length} NDCs on a recall list · ${fillsFlagged} fills flagged`);
if (!flagged) console.log(' ✓ None of your actual dispensed products appear in an FDA recall.');
process.exit(0);
}
main().catch((e) => { console.error('FAILED:', e.message); process.exit(1); });