new-site/api/migrations/088_npi_compliance_data.sql

69 lines
2.8 KiB
SQL

-- ─────────────────────────────────────────────────────────────────────
-- NPI / Healthcare provider compliance lookup data.
--
-- Powers /tools/npi-compliance-check. The live identity/status comes from
-- the free public NPPES Registry API at query time; these tables hold the
-- *dateable hooks* and exclusion data that the public NPI API does NOT
-- expose, all keyed by NPI:
--
-- npi_revalidation_due — CMS Medicare revalidation due dates (the flagship
-- dateable hook; ~218k providers are PAST DUE).
-- npi_exclusions — OIG LEIE exclusion list (matched by NPI when present).
-- npi_optout — Medicare opt-out affidavits (end dates).
--
-- Source files (free, public):
-- data.cms.gov Revalidation Due List, Medicare Opt Out
-- oig.hhs.gov LEIE downloadable database
-- ─────────────────────────────────────────────────────────────────────
CREATE TABLE IF NOT EXISTS npi_revalidation_due (
id SERIAL PRIMARY KEY,
npi TEXT NOT NULL,
enrollment_id TEXT,
first_name TEXT,
last_name TEXT,
organization_name TEXT,
enrollment_state TEXT,
enrollment_type TEXT, -- CMS enrollment type code
provider_type TEXT,
specialty TEXT,
revalidation_due_date DATE, -- NULL = "TBD" in CMS data
adjusted_due_date DATE,
reassign_to TEXT,
receiving_reassignment TEXT,
loaded_at TIMESTAMPTZ DEFAULT now()
);
CREATE INDEX IF NOT EXISTS idx_npi_reval_npi ON npi_revalidation_due (npi);
CREATE TABLE IF NOT EXISTS npi_exclusions (
id SERIAL PRIMARY KEY,
npi TEXT, -- '0000000000' / blank when OIG has none
last_name TEXT,
first_name TEXT,
middle_name TEXT,
business_name TEXT,
general_category TEXT,
specialty TEXT,
state TEXT,
exclusion_type TEXT, -- e.g. 1128a1
exclusion_date DATE,
reinstatement_date DATE, -- NULL when still excluded
loaded_at TIMESTAMPTZ DEFAULT now()
);
CREATE INDEX IF NOT EXISTS idx_npi_excl_npi ON npi_exclusions (npi) WHERE npi IS NOT NULL AND npi <> '0000000000';
CREATE TABLE IF NOT EXISTS npi_optout (
id SERIAL PRIMARY KEY,
npi TEXT,
first_name TEXT,
last_name TEXT,
specialty TEXT,
optout_effective_date DATE,
optout_end_date DATE,
state TEXT,
loaded_at TIMESTAMPTZ DEFAULT now()
);
CREATE INDEX IF NOT EXISTS idx_npi_optout_npi ON npi_optout (npi);
-- Reuse the existing free-tool logging table (compliance_check_log) for NPI
-- checks; no schema change needed there.