|
| 1 | +--- |
| 2 | +features: [Bulk API, $export, Plan-Net, Provider Directory, S3, MinIO, Presigned URLs] |
| 3 | +languages: [TypeScript] |
| 4 | +--- |
| 5 | +# Medicare Plan Finder (MPF) |
| 6 | + |
| 7 | +A minimal TypeScript provider-directory publishing pipeline on Aidbox. The flow: |
| 8 | + |
| 9 | +1. **Export**: kick off a system-level FHIR [`$export`](https://docs.aidbox.app/api/bulk-api/export) with `_typeFilter`, poll to completion, download the gzipped NDJSON. |
| 10 | +2. **Scope filter**: walk references from the kept parents and drop children nothing points at. |
| 11 | +3. **Bundle**: partition into FHIR collection `Bundle` files plus an `index.json` manifest. |
| 12 | +4. **Publish**: upload through Aidbox-presigned URLs to S3-compatible storage (local [MinIO](https://github.com/minio/minio) here). The script holds no bucket credentials. |
| 13 | + |
| 14 | +This is the shape behind CMS provider-directory feeds (Medicare Plan Finder): a crawler starts from `index.json` and downloads the bundles it lists. |
| 15 | + |
| 16 | +## Layout |
| 17 | + |
| 18 | +| File | Purpose | |
| 19 | +|---|---| |
| 20 | +| `docker-compose.yml` | Aidbox, PostgreSQL, MinIO (buckets auto-created), and an `export` service that runs the pipeline with [Bun](https://bun.sh). | |
| 21 | +| `init-bundle.json` | An `AwsAccount` for MinIO, the `provider-export` client with a least-privilege `AccessPolicy`, and a small Plan-Net dataset (one plan, two networks, practitioners in and out of network). | |
| 22 | +| `src/main.ts` | Scope config and orchestration of the four steps. | |
| 23 | +| `src/aidbox.ts` | Token mint, `$export` start and polling, presigned uploads. | |
| 24 | +| `src/filter.ts` | Two-pass scope filter. | |
| 25 | +| `src/bundle.ts` | Bundle partitioning and `index.json`. | |
| 26 | + |
| 27 | +## Run |
| 28 | + |
| 29 | +1. Add an Aidbox license to `.env` (obtain one at [aidbox.app](https://aidbox.app)): |
| 30 | + |
| 31 | + ```bash |
| 32 | + cp .env.example .env |
| 33 | + ``` |
| 34 | + |
| 35 | +2. Start the stack. `curl http://localhost:8888/health` returns `200` when ready. |
| 36 | + |
| 37 | + ```bash |
| 38 | + docker compose up -d |
| 39 | + ``` |
| 40 | + |
| 41 | +3. Run the pipeline: |
| 42 | + |
| 43 | + ```bash |
| 44 | + # "export" is the compose service that runs `bun src/main.ts`. --rm drops the container after |
| 45 | + docker compose run --rm export |
| 46 | + ``` |
| 47 | + |
| 48 | + It prints progress and the manifest URL `http://localhost:9000/provider-directory-publish/index.json`. Bundles are also written to `./output`. |
| 49 | + |
| 50 | +## Adapting |
| 51 | + |
| 52 | +Scope IDs live in `src/main.ts`, sample data and the storage account in `init-bundle.json`. To change the data before a rerun, edit `init-bundle.json` and re-seed with `docker compose down -v && docker compose up -d`, or edit it live in the Aidbox console at http://localhost:8888 (admin / secret). Swap MinIO for S3, GCP, or Azure through the `AwsAccount`. |
0 commit comments