From c3d4cae7a6013a0677fa9af309a3d92caef125a6 Mon Sep 17 00:00:00 2001 From: Dreamstore2046 <199616733+Dreamstore2046@users.noreply.github.com> Date: Sat, 27 Jun 2026 07:47:11 +0800 Subject: [PATCH] Stop tracking runtime data files --- .github/workflows/ci.yml | 2 +- .github/workflows/pr-meta.yml | 21 ++ .gitignore | 4 +- README.md | 6 +- data/.gitkeep | 1 + data/README.md | 2 +- data/orders.json | 112 ---------- data/spending.json | 315 ----------------------------- docs/adr/002-pii-in-persistence.md | 49 +++++ 9 files changed, 80 insertions(+), 432 deletions(-) create mode 100644 .github/workflows/pr-meta.yml create mode 100644 data/.gitkeep delete mode 100644 data/orders.json delete mode 100644 data/spending.json create mode 100644 docs/adr/002-pii-in-persistence.md diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 34d7c01..ec985c1 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -40,7 +40,7 @@ jobs: - name: Check for committed sensitive data files run: | - if git diff --name-only origin/main...HEAD 2>/dev/null | grep -qE '^data/(spending|orders)\.json$'; then + if git diff --name-only --diff-filter=ACMR origin/main...HEAD 2>/dev/null | grep -qE '^data/(spending|orders)\.json$'; then echo "::error::Sensitive data file detected in PR diff (data/spending.json or data/orders.json). Remove it before merging." exit 1 fi diff --git a/.github/workflows/pr-meta.yml b/.github/workflows/pr-meta.yml new file mode 100644 index 0000000..a5fc107 --- /dev/null +++ b/.github/workflows/pr-meta.yml @@ -0,0 +1,21 @@ +name: PR Metadata Guard + +on: + pull_request: + +jobs: + block-runtime-data: + name: Block committed runtime data + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Block data JSON files + run: | + base_ref="${{ github.base_ref }}" + if git diff --name-only --diff-filter=ACMR "origin/${base_ref}...HEAD" | grep -qE '^data/.*\.json$'; then + echo "::error::Runtime data files under data/*.json must not be committed. Keep them local or migrate to a managed database." + exit 1 + fi diff --git a/.gitignore b/.gitignore index fcf0d17..f82b6fa 100644 --- a/.gitignore +++ b/.gitignore @@ -5,9 +5,9 @@ dist/ .env.local .dev-seed *.log +data/*.json +!data/.gitkeep data/audit.log.jsonl -data/spending.json -data/orders.json data/pharmacy-pricing.sqlite data/pharmacy-pricing.sqlite-* data/pharmacy-pricing.sqlite-shm diff --git a/README.md b/README.md index 6b53af7..e0e93ba 100644 --- a/README.md +++ b/README.md @@ -112,6 +112,10 @@ cd dashboard && npm run dev # 6. Open http://localhost:3000 ``` +### Local runtime data + +CareGuard writes development runtime state under `data/`, including local order history and spending ledgers. Treat this directory as machine-local working data: JSON files under `data/` are ignored by git, and only placeholder/documentation files should be committed. + ### Docker dev (one command) For a single-command boot of the full stack — server, dashboard, redis, prometheus, grafana — use Docker Compose. See [issue #111](https://github.com/harystyleseze/careguard/issues/111). @@ -217,7 +221,7 @@ careguard/ │ └── types.ts # Shared TypeScript types ├── scripts/ │ └── setup-wallets.ts # Testnet wallet creation + USDC trustlines -├── data/ # Persisted spending data + orders +├── data/ # Local runtime data (JSON ignored by git) ├── .env.example # Environment variable template ├── QUICKSTART.md # Setup guide ``` diff --git a/data/.gitkeep b/data/.gitkeep new file mode 100644 index 0000000..94a42a9 --- /dev/null +++ b/data/.gitkeep @@ -0,0 +1 @@ +# Keep the data directory in git; runtime data files are ignored. diff --git a/data/README.md b/data/README.md index 1352472..a37885e 100644 --- a/data/README.md +++ b/data/README.md @@ -17,4 +17,4 @@ These files contain **sensitive financial data**. They must never appear in a co All paths are listed in `.gitignore`. If you see them untracked in `git status`, do not stage them. -CI will fail any PR where these files appear in the diff (see `.github/workflows/ci.yml`). +CI will fail any PR where these files appear in the diff (see `.github/workflows/pr-meta.yml`). diff --git a/data/orders.json b/data/orders.json deleted file mode 100644 index a6f95a1..0000000 --- a/data/orders.json +++ /dev/null @@ -1,112 +0,0 @@ -[ - { - "id": "order-1775189473690", - "drug": "lisinopril", - "pharmacy": "CVS Pharmacy", - "amount": 10, - "status": "confirmed", - "timestamp": "2026-04-03T04:11:13.690Z", - "network": "stellar:testnet", - "protocol": "MPP Charge" - }, - { - "id": "order-1775194929490", - "drug": "lisinopril", - "pharmacy": "Costco Pharmacy", - "amount": 3.5, - "status": "confirmed", - "timestamp": "2026-04-03T05:42:09.490Z", - "network": "stellar:testnet", - "protocol": "MPP Charge" - }, - { - "id": "order-1775194935166", - "drug": "metformin", - "pharmacy": "Walmart Pharmacy", - "amount": 4, - "status": "confirmed", - "timestamp": "2026-04-03T05:42:15.166Z", - "network": "stellar:testnet", - "protocol": "MPP Charge" - }, - { - "id": "order-1775720261932", - "drug": "Lisinopril", - "pharmacy": "Costco Pharmacy", - "amount": 3.5, - "status": "confirmed", - "timestamp": "2026-04-09T07:37:41.932Z", - "network": "stellar:testnet", - "protocol": "MPP Charge" - }, - { - "id": "order-1775720267414", - "drug": "Metformin", - "pharmacy": "Costco Pharmacy", - "amount": 4, - "status": "confirmed", - "timestamp": "2026-04-09T07:37:47.414Z", - "network": "stellar:testnet", - "protocol": "MPP Charge" - }, - { - "id": "order-1775720279451", - "drug": "Atorvastatin", - "pharmacy": "Costco Pharmacy", - "amount": 6.5, - "status": "confirmed", - "timestamp": "2026-04-09T07:37:59.451Z", - "network": "stellar:testnet", - "protocol": "MPP Charge" - }, - { - "id": "order-1775720282247", - "drug": "Amlodipine", - "pharmacy": "Walmart Pharmacy", - "amount": 4, - "status": "confirmed", - "timestamp": "2026-04-09T07:38:02.247Z", - "network": "stellar:testnet", - "protocol": "MPP Charge" - }, - { - "id": "order-1775855591245", - "drug": "Lisinopril", - "pharmacy": "Costco Pharmacy", - "amount": 3.5, - "status": "confirmed", - "timestamp": "2026-04-10T21:13:11.245Z", - "network": "stellar:testnet", - "protocol": "MPP Charge" - }, - { - "id": "order-1775855596274", - "drug": "Metformin", - "pharmacy": "Costco Pharmacy", - "amount": 4, - "status": "confirmed", - "timestamp": "2026-04-10T21:13:16.274Z", - "network": "stellar:testnet", - "protocol": "MPP Charge" - }, - { - "id": "order-1775855601817", - "drug": "Atorvastatin", - "pharmacy": "Costco Pharmacy", - "amount": 6.5, - "status": "confirmed", - "timestamp": "2026-04-10T21:13:21.817Z", - "network": "stellar:testnet", - "protocol": "MPP Charge" - }, - { - "id": "order-1775855606851", - "drug": "Amlodipine", - "pharmacy": "Walmart Pharmacy", - "amount": 4, - "status": "confirmed", - "timestamp": "2026-04-10T21:13:26.851Z", - "network": "stellar:testnet", - "protocol": "MPP Charge" - } -] \ No newline at end of file diff --git a/data/spending.json b/data/spending.json deleted file mode 100644 index 534b150..0000000 --- a/data/spending.json +++ /dev/null @@ -1,315 +0,0 @@ -{ - "medications": 36, - "bills": 0, - "serviceFees": 0.08600000000000002, - "transactions": [ - { - "id": "tx-1775719466950", - "timestamp": "2026-04-09T07:24:26.950Z", - "type": "service_fee", - "description": "x402 query: medical bill audit", - "amount": 0.01, - "recipient": "GBDRAD7IVVEQFM2PA6QW3R6SDHOO2VHGVA5S7BKZTDF4S75V3KJ2FKFE", - "stellarTxHash": "1865f9d4fb99632e5e64e6fb2ae228c401db61f10488c8afecec176b10cf2921", - "status": "completed", - "category": "service_fees" - }, - { - "id": "tx-1775720023144", - "timestamp": "2026-04-09T07:33:43.144Z", - "type": "service_fee", - "description": "x402 query: pharmacy prices for lisinopril", - "amount": 0.002, - "recipient": "GCS3Y2TMD6NRXN4GA3YYEUIFAITK3EYBBBMP2VB3EXHRXW4IBDZE3R2U", - "stellarTxHash": "0797da99fc5deac0fe39f256de5a3caf09a5e4293b3a4cf456714daaaf0b4693", - "status": "completed", - "category": "service_fees" - }, - { - "id": "tx-1775720034846", - "timestamp": "2026-04-09T07:33:54.846Z", - "type": "service_fee", - "description": "x402 query: pharmacy prices for metformin", - "amount": 0.002, - "recipient": "GCS3Y2TMD6NRXN4GA3YYEUIFAITK3EYBBBMP2VB3EXHRXW4IBDZE3R2U", - "stellarTxHash": "5dfd7383227124acbeb0ea4be362158b6049c7bcce7b09cb62f7da4656cdd539", - "status": "completed", - "category": "service_fees" - }, - { - "id": "tx-1775720042998", - "timestamp": "2026-04-09T07:34:02.998Z", - "type": "service_fee", - "description": "x402 query: pharmacy prices for atorvastatin", - "amount": 0.002, - "recipient": "GCS3Y2TMD6NRXN4GA3YYEUIFAITK3EYBBBMP2VB3EXHRXW4IBDZE3R2U", - "stellarTxHash": "d48f962e8692eddf55a1c0c569e2351f33557ba3dce6928561339c774aa5445a", - "status": "completed", - "category": "service_fees" - }, - { - "id": "tx-1775720054486", - "timestamp": "2026-04-09T07:34:14.486Z", - "type": "service_fee", - "description": "x402 query: pharmacy prices for amlodipine", - "amount": 0.002, - "recipient": "GCS3Y2TMD6NRXN4GA3YYEUIFAITK3EYBBBMP2VB3EXHRXW4IBDZE3R2U", - "stellarTxHash": "5e9d41f6e2a88443fb63708cf0b38d77d382bf5cf48574851142fdd61e6b37ba", - "status": "completed", - "category": "service_fees" - }, - { - "id": "tx-1775720083417", - "timestamp": "2026-04-09T07:34:43.417Z", - "type": "service_fee", - "description": "x402 query: medical bill audit", - "amount": 0.01, - "recipient": "GBDRAD7IVVEQFM2PA6QW3R6SDHOO2VHGVA5S7BKZTDF4S75V3KJ2FKFE", - "stellarTxHash": "6eea0f261bda02f742a3a4fc350683d73d0ea4542742218eef33b9d9e5c8bf51", - "status": "completed", - "category": "service_fees" - }, - { - "id": "tx-1775720202015", - "timestamp": "2026-04-09T07:36:42.015Z", - "type": "service_fee", - "description": "x402 query: pharmacy prices for lisinopril", - "amount": 0.002, - "recipient": "GCS3Y2TMD6NRXN4GA3YYEUIFAITK3EYBBBMP2VB3EXHRXW4IBDZE3R2U", - "stellarTxHash": "f28e49a33254d361c3ef37d3a04360b81e0d9c86445a7454fe1580355d0e4b7e", - "status": "completed", - "category": "service_fees" - }, - { - "id": "tx-1775720206487", - "timestamp": "2026-04-09T07:36:46.487Z", - "type": "service_fee", - "description": "x402 query: medical bill audit", - "amount": 0.01, - "recipient": "GBDRAD7IVVEQFM2PA6QW3R6SDHOO2VHGVA5S7BKZTDF4S75V3KJ2FKFE", - "stellarTxHash": "d926bdf6f4d772cca834baa4763994c220b1b472991cabbb71ba97d95f784f9f", - "status": "completed", - "category": "service_fees" - }, - { - "id": "tx-1775720220569", - "timestamp": "2026-04-09T07:37:00.569Z", - "type": "service_fee", - "description": "x402 query: pharmacy prices for metformin", - "amount": 0.002, - "recipient": "GCS3Y2TMD6NRXN4GA3YYEUIFAITK3EYBBBMP2VB3EXHRXW4IBDZE3R2U", - "stellarTxHash": "feff5da72d83e69da5bad17a4344dfb92e30b266d0b6ee3e02c0705ef1554786", - "status": "completed", - "category": "service_fees" - }, - { - "id": "tx-1775720232016", - "timestamp": "2026-04-09T07:37:12.016Z", - "type": "service_fee", - "description": "x402 query: pharmacy prices for atorvastatin", - "amount": 0.002, - "recipient": "GCS3Y2TMD6NRXN4GA3YYEUIFAITK3EYBBBMP2VB3EXHRXW4IBDZE3R2U", - "stellarTxHash": "20667b7a1308108186fdfb96d5d624bbaa93e49ec16d8107f01b7ab4aa82c21a", - "status": "completed", - "category": "service_fees" - }, - { - "id": "tx-1775720238049", - "timestamp": "2026-04-09T07:37:18.049Z", - "type": "service_fee", - "description": "x402 query: pharmacy prices for amlodipine", - "amount": 0.002, - "recipient": "GCS3Y2TMD6NRXN4GA3YYEUIFAITK3EYBBBMP2VB3EXHRXW4IBDZE3R2U", - "stellarTxHash": "547fad337dcda2e0ed3d40d8f570047f62c3d4a27be852faa60ea2ade18c70c8", - "status": "completed", - "category": "service_fees" - }, - { - "id": "tx-1775720248643", - "timestamp": "2026-04-09T07:37:28.643Z", - "type": "service_fee", - "description": "x402 query: drug interactions for lisinopril, metformin, atorvastatin, amlodipine", - "amount": 0.001, - "recipient": "GDDJOVCGIGMWKDH2N7QVJDMJF6CHROI7CUAQT442NA77NIXGH6RTM3D2", - "stellarTxHash": "b5603052977848771ccb8a128dc9f514df21eb0e82f9f75316f4ff799b237d1d", - "status": "completed", - "category": "service_fees" - }, - { - "id": "tx-1775720261938", - "timestamp": "2026-04-09T07:37:41.938Z", - "type": "medication", - "description": "Lisinopril from Costco Pharmacy [MPP Charge]", - "amount": 3.5, - "recipient": "costco-001", - "stellarTxHash": "efb72f663561f59c85829b93bebe07fe0cf420a7d031607b7db10babd9a2b4be", - "status": "completed", - "category": "medications" - }, - { - "id": "tx-1775720267417", - "timestamp": "2026-04-09T07:37:47.417Z", - "type": "medication", - "description": "Metformin from Costco Pharmacy [MPP Charge]", - "amount": 4, - "recipient": "costco-001", - "stellarTxHash": "d856cfb227b9ecdb133bb0ab9f982ea3444fb401a33bc97ca87092eb534b1112", - "status": "completed", - "category": "medications" - }, - { - "id": "tx-1775720279454", - "timestamp": "2026-04-09T07:37:59.454Z", - "type": "medication", - "description": "Atorvastatin from Costco Pharmacy [MPP Charge]", - "amount": 6.5, - "recipient": "costco-001", - "stellarTxHash": "6d5c942f4f00ce6550378702525199cd9047c2bf1db954ae0b953c0478dce5bb", - "status": "completed", - "category": "medications" - }, - { - "id": "tx-1775720282250", - "timestamp": "2026-04-09T07:38:02.250Z", - "type": "medication", - "description": "Amlodipine from Walmart Pharmacy [MPP Charge]", - "amount": 4, - "recipient": "walmart-001", - "stellarTxHash": "ccf32a01a7b615a4307508d5734e823bf611c33ce72174b9f96da8f0401b8941", - "status": "completed", - "category": "medications" - }, - { - "id": "tx-1775721737333", - "timestamp": "2026-04-09T08:02:17.333Z", - "type": "service_fee", - "description": "x402 query: medical bill audit", - "amount": 0.01, - "recipient": "GBDRAD7IVVEQFM2PA6QW3R6SDHOO2VHGVA5S7BKZTDF4S75V3KJ2FKFE", - "stellarTxHash": "795082d35c4185211f53ff0f42161548f2cccc4ae2541d62a788e10243447156", - "status": "completed", - "category": "service_fees" - }, - { - "id": "tx-1775855491832", - "timestamp": "2026-04-10T21:11:31.832Z", - "type": "service_fee", - "description": "x402 query: medical bill audit", - "amount": 0.01, - "recipient": "GBDRAD7IVVEQFM2PA6QW3R6SDHOO2VHGVA5S7BKZTDF4S75V3KJ2FKFE", - "stellarTxHash": "53a668593d0f357e6f3f510195d6f8b8bc1543e113243b6aa4f849710574e284", - "status": "completed", - "category": "service_fees" - }, - { - "id": "tx-1775855544049", - "timestamp": "2026-04-10T21:12:24.049Z", - "type": "service_fee", - "description": "x402 query: drug interactions for lisinopril, metformin, atorvastatin, amlodipine", - "amount": 0.001, - "recipient": "drug-interaction-api", - "stellarTxHash": "e15a36847ef10cd2537408774bf093510c5d651c47c447f0b31cc31f3be698b8", - "status": "completed", - "category": "service_fees" - }, - { - "id": "tx-1775855552613", - "timestamp": "2026-04-10T21:12:32.613Z", - "type": "service_fee", - "description": "x402 query: pharmacy prices for lisinopril", - "amount": 0.002, - "recipient": "GCS3Y2TMD6NRXN4GA3YYEUIFAITK3EYBBBMP2VB3EXHRXW4IBDZE3R2U", - "stellarTxHash": "8283fe14bd7727950f647ca61f9445211a339ff2dc82e84f59892c5647d0513d", - "status": "completed", - "category": "service_fees" - }, - { - "id": "tx-1775855561227", - "timestamp": "2026-04-10T21:12:41.227Z", - "type": "service_fee", - "description": "x402 query: pharmacy prices for metformin", - "amount": 0.002, - "recipient": "GCS3Y2TMD6NRXN4GA3YYEUIFAITK3EYBBBMP2VB3EXHRXW4IBDZE3R2U", - "stellarTxHash": "1678b7b6d1b312616186143260c1e1fb376b5f642ecb14f1bf9a4eabef3cccc4", - "status": "completed", - "category": "service_fees" - }, - { - "id": "tx-1775855573144", - "timestamp": "2026-04-10T21:12:53.144Z", - "type": "service_fee", - "description": "x402 query: pharmacy prices for atorvastatin", - "amount": 0.002, - "recipient": "GCS3Y2TMD6NRXN4GA3YYEUIFAITK3EYBBBMP2VB3EXHRXW4IBDZE3R2U", - "stellarTxHash": "4a685efccf6083b5a92551216da23d982fa40f04822a027c5a9eedb5195ad4f9", - "status": "completed", - "category": "service_fees" - }, - { - "id": "tx-1775855581738", - "timestamp": "2026-04-10T21:13:01.738Z", - "type": "service_fee", - "description": "x402 query: pharmacy prices for amlodipine", - "amount": 0.002, - "recipient": "GCS3Y2TMD6NRXN4GA3YYEUIFAITK3EYBBBMP2VB3EXHRXW4IBDZE3R2U", - "stellarTxHash": "04eba047a25a78a13a79dcd4a77293db4fe5ad3660ca539e7cb4835d4fe45380", - "status": "completed", - "category": "service_fees" - }, - { - "id": "tx-1775855591250", - "timestamp": "2026-04-10T21:13:11.250Z", - "type": "medication", - "description": "Lisinopril from Costco Pharmacy [MPP Charge]", - "amount": 3.5, - "recipient": "costco-001", - "stellarTxHash": "95c4150c1c2a9ebf64b9c0edeb6f10ac56b03cb17d367dc79dcdef774b1bc9cd", - "status": "completed", - "category": "medications" - }, - { - "id": "tx-1775855596276", - "timestamp": "2026-04-10T21:13:16.276Z", - "type": "medication", - "description": "Metformin from Costco Pharmacy [MPP Charge]", - "amount": 4, - "recipient": "costco-001", - "stellarTxHash": "dc43c68cb73935b337bf6259209ecb00302064fcc260871a3dfabbfbdf44f5b6", - "status": "completed", - "category": "medications" - }, - { - "id": "tx-1775855601820", - "timestamp": "2026-04-10T21:13:21.820Z", - "type": "medication", - "description": "Atorvastatin from Costco Pharmacy [MPP Charge]", - "amount": 6.5, - "recipient": "costco-001", - "stellarTxHash": "8cb1b9847c0e19a37522c02e21287d940c8d6efc92a9df5321272bb1d7abd0d9", - "status": "completed", - "category": "medications" - }, - { - "id": "tx-1775855606854", - "timestamp": "2026-04-10T21:13:26.854Z", - "type": "medication", - "description": "Amlodipine from Walmart Pharmacy [MPP Charge]", - "amount": 4, - "recipient": "walmart-001", - "stellarTxHash": "c05715b8c5e7024c80f0c604074cc25d0fc577dce35f3b13ad4ada22164263d6", - "status": "completed", - "category": "medications" - }, - { - "id": "tx-1775855706431", - "timestamp": "2026-04-10T21:15:06.431Z", - "type": "service_fee", - "description": "x402 query: medical bill audit", - "amount": 0.01, - "recipient": "GBDRAD7IVVEQFM2PA6QW3R6SDHOO2VHGVA5S7BKZTDF4S75V3KJ2FKFE", - "stellarTxHash": "1627780894a0b9052f37c000e855215cad98052d59760c6e9d2945afcc73d05a", - "status": "completed", - "category": "service_fees" - } - ] -} \ No newline at end of file diff --git a/docs/adr/002-pii-in-persistence.md b/docs/adr/002-pii-in-persistence.md new file mode 100644 index 0000000..f3ae6ed --- /dev/null +++ b/docs/adr/002-pii-in-persistence.md @@ -0,0 +1,49 @@ +# ADR 002: Local Runtime Data Must Stay Out of Git + +## Status + +Accepted + +## Context + +CareGuard writes local runtime state under `data/` during development, including spending ledgers, order history, wallet addresses, transaction hashes, and policy state. Even on testnet, this data can reveal caregiver workflows and payment behavior. On mainnet, equivalent records would be sensitive financial and health-adjacent operational data. + +The repository previously tracked `data/orders.json` and `data/spending.json`. Ignoring those paths after the fact is not enough while the files remain in the git index, because future edits continue to appear in pull requests. + +## Decision + +Runtime JSON files under `data/` are local working data and must not be committed. + +- `data/*.json` and recipient-scoped JSON files are ignored by git. +- `data/.gitkeep` keeps the root data directory available in fresh clones. +- `data/orders.json` and `data/spending.json` are removed from the git index with `git rm --cached` while remaining available locally for developers who already have them. +- Pull requests must fail if runtime JSON files are added back to the diff. + +## Migration Path + +Issue #111 tracks the move from local file persistence to a managed database-backed model. + +The migration should: + +1. Introduce database tables for orders, spending transactions, recipient policy state, and audit events. +2. Provide a one-time import path for local `data/*.json` files used by development and demos. +3. Move production deployments to the database-backed store before any mainnet usage. +4. Apply database backups, access controls, retention limits, and audit logging appropriate for financial and care-related records. +5. Remove any dependency on checked-in runtime data fixtures after the database path is in place. + +## Consequences + +### Positive + +- Prevents accidental disclosure of local order and spending history in PRs. +- Keeps clones usable by preserving the `data/` directory. +- Makes the persistence boundary explicit while the database migration is pending. + +### Negative + +- Developers must seed or generate local runtime files themselves. +- Existing local files no longer appear in git status once ignored. + +### Neutral + +- This does not remove sensitive data from repository history. If real secrets or production records were ever committed, the project would still need a history rewrite and credential rotation.