bib: ingest Medicare Benefits Policy Manual (IOM Pub 100-02) into library #304
Reference in New Issue
Block a user
Delete Branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
The Medicare Benefits Policy Manual (CMS Pub 100-02) defines what Medicare Part A and Part B cover. It is the authoritative source for coverage determinations.
Chapters needed:
Source: https://www.cms.gov/regulations-and-guidance/guidance/manuals/internet-only-manuals-ioms-items/cms012673
Each chapter is a separate PDF. Create Manual items in bib.sqlite with pub_number=100-02, chapter=N, attach the PDFs.
Closed via #343-tracked sync pipeline. 100-02 (Benefit Policy Manual): 16 chapter PDFs ingested, attached, and synced to Zotero under
Healthcare Data Platform / Manuals.Architecture
Landed a full CMS IOM pipeline — not just this manual, every IOM CMS publishes (20 pubs, 177 chapters total).
Modules
src/bib/iom.py(new) — scraper + orchestrator.fetch_index(client)scrapes the CMS IOM index table.fetch_chapters(client, entry)scrapes each manual's landing page. Handles single-file manuals (100-17/18/19/20/21) via_WHOLE_PUBregex fallback; handles split chapters ("Chapter 1 Part 2") via_CHAPTER_PARTfold into composite IDs like1P2; skips supplementals (crosswalks, addenda).ingest_all(store, client, *, pubs=None, prune=True)— idempotent: re-upserts by URL and prunes Manual records whose URL is no longer in the live CMS list, cleaning up stale filename-rename dupes.download_attachments(store, client)— SHA-256-keyed; skips files whose on-disk checksum matches the stored copy.check_future_updates(store, client)— pollsfuturepdf.pdf(CMS upcoming-transmittal schedule); attaches only when checksum changes; designed as the trigger signal for out-of-band refresh cycles.src/bib/sync.py— extended with attachment sync + collection routing.push_to_zotero(items, store=..., ...)now walksstore.attachmentsand copies PDFs into Zotero'sdata/zotero/data/storage/<key>/+ createsitemAttachmentsrows withlinkMode=1(IMPORTED_URL)._zotero_collection_path(item)derives the target hierarchy; Manual items route toHealthcare Data Platform / Manuals / <manual_name>, ensured viaDb.ensure_collectionon the fly.replace_fields(item_id, fields)— wipes existing itemData before rewriting to clean stale garbage from prior buggy syncs.src/cli/bib.py— new commands, all idempotent:stack bib ingest-iom [--pub X]stack bib attach-iom [--pub X] [--force]stack bib watch-iomstack bib sync-zotero [--tag X] [--type manual](wrapsdocker stop/start zotero)stack bib refresh-iom— one-shot: ingest → watch → attach → sync. Safe to cron (follow-up #343).Schema parity fix
Root cause of earlier Zotero corruption was stale
TYPE_MAP/FIELD_MAP/CREATOR_TYPESconstants insrc/zot/db.pyauthored against an older Zotero schema. Modern Zotero 7 assigns different numeric IDs, somanual → 15landed as "email" instead of "report" and attachments as "document" instead of "attachment", tripping Zotero'sgetFilePath()consistency checks._verify_schema_parity()runs on everyDb.__init__and raises immediately if IDs drift — future Zotero upgrades can't silently corrupt data.src/zot/schema.sqlreplaced with a fresh dump (2,499 lines) — the old file had triggers likeitemTypeID != 14for attachments that were valid only in the pre-7 schema.src/zot/ops.pypackagesdump_schema,fix_dates,fix_keys,fix_fieldsas importable + CLI-exposed (stack zot {…}). Olddev/scripts/*.pybecame thin shims that call into the module.Data flow
Verified clean state
report, 177 attachment children typedattachment(linkMode=1)PRAGMA integrity_check= ok,PRAGMA foreign_key_check= ok(itemTypeID, fieldID)pairs valid peritemTypeFieldsCombinedGotchas recorded for future agents
.dockerignoreare required (!infra/marimo/theme/,!infra/gitea/) or the build context lacks theme files.docker stop zotero/start zoteroautomatically (--holddefault on).filenamecolumn inbib.attachmentsis a display label, not a filesystem name. UsePath(storage_path).namewhen copying into Zotero storage.