feat: cog_balances(), a reader surface for cash and security holdings (#25) #28

Merged
jared merged 22 commits from feat/cog-balances-25 into main 2026-08-03 11:52:13 -04:00
2 changed files with 11 additions and 9 deletions
Showing only changes of commit a9e80858d4 - Show all commits
+10 -8
View File
@@ -60,19 +60,20 @@ USCOGDATA_URL (local path or https://)
Any value without `://` is treated as a local path by `.is_local_path()` and reads Any value without `://` is treated as a local path by `.is_local_path()` and reads
`manifest.json` directly from disk (no HTTP, no TTL cache). `manifest.json` directly from disk (no HTTP, no TTL cache).
## Current State (2026-04-27) ## Current State (2026-08-03)
**Version:** 0.1.0 (pre-release) **Version:** 0.1.0 (pre-release)
**Branch:** `main`, commit `d65e9fe` **Branch:** `feat/cog-balances-25`, commit `fde62eb`
**Tests:** 764 PASS / 0 FAIL / 0 SKIP (measured `testthat::test_local()`, 2026-08-03, on the tree including the balance_caveats schema test) **Tests:** 788 PASS / 0 FAIL / 0 SKIP / 0 WARN (measured `testthat::test_local()`, 2026-08-03, after the final-review fix wave)
**CI:** Gitea Actions green (`.gitea/workflows/ci.yml`) **CI:** Gitea Actions green (`.gitea/workflows/ci.yml`)
### Completed (Tasks 2.1–2.7) ### Completed (Tasks 2.1–2.7)
All 10 exported verbs implemented and tested: All **14** exports implemented and tested (measured from `NAMESPACE`):
`cog_spending`, `cog_revenue`, `cog_balances`, `cog_explain`, `cog_spending`, `cog_revenue`, `cog_balances`, `cog_explain`,
`cog_geographic_rollup`, `cog_find_peers`, `cog_peer_compare`, `cog_geographic_rollup`, `cog_find_peers`, `cog_peer_compare`,
`cog_gov_search`, `cog_mirror`, plus `cog_categories`. `cog_gov_search`, `cog_mirror`, `cog_categories`, `cog_recipes`,
`cog_manifest`, `cog_basket_resolution`, `cog_basket_unresolved`.
Bundled fixture corpus at `inst/extdata/fixture_corpus/` (years Bundled fixture corpus at `inst/extdata/fixture_corpus/` (years
2011, 2012, 2019, 2020 — measured via DuckDB `read_parquet(hive_partitioning=1)`, 2011, 2012, 2019, 2020 — measured via DuckDB `read_parquet(hive_partitioning=1)`,
@@ -80,9 +81,10 @@ Bundled fixture corpus at `inst/extdata/fixture_corpus/` (years
### Remaining to v0.1 release ### Remaining to v0.1 release
1. **Task 2.8 — Docs:** roxygen `@param`/`@return`/`@examples` on all exports; 1. **Task 2.8 — Docs:** mostly done — all 14 exports have a `man/*.Rd`,
full `README.md`; `_pkgdown.yml`; `devtools::document()` + `pkgdown::build_site()`. `README.md` and `_pkgdown.yml` exist, and `vignettes/` carries
Vignettes can be stubbed for v0.1. `total-spending.Rmd` + `population-denominators.Rmd`. Outstanding:
`pkgdown::build_site()` has never been run (no `docs/`).
2. **Phase 3 — cog_explorer bridge:** create 2. **Phase 3 — cog_explorer bridge:** create
`cog_explorer/examples/hello_world_uscogdata.Rmd` (installs from Gitea, runs `cog_explorer/examples/hello_world_uscogdata.Rmd` (installs from Gitea, runs
+1 -1
View File
@@ -55,7 +55,7 @@
}, },
"balance_caveats": { "balance_caveats": {
"type": ["object", "null"], "type": ["object", "null"],
"description": "Present only on cog_balances() results (null/absent for cog_spending()/cog_revenue()). `not_gaap` is always TRUE and `not_gaap_note` explains that Census holdings are gross -- no liabilities are netted -- so they are NOT comparable to a GAAP fund balance. `coverage_window` maps each observed balance_subtype to its measured [min year, max year] in the mounted corpus (never hardcoded). `truncated` lists the subtypes whose coverage_window does not fully span the requested years.", "description": "Present only on cog_balances() results (null/absent for cog_spending()/cog_revenue()). `not_gaap` is always TRUE and `not_gaap_note` explains that Census holdings are gross -- no liabilities are netted -- so they are NOT comparable to a GAAP fund balance. `coverage_window` maps EVERY balance_subtype present in the mounted corpus -- not only the ones this query observed -- to its measured [min year, max year] there (never hardcoded), so a caller can see which families exist and over what span before deciding they missed one. `truncated` is the query-scoped field: it lists only the subtypes this result actually observed whose coverage_window does not fully span the requested years.",
"properties": { "properties": {
"not_gaap": { "type": "boolean" }, "not_gaap": { "type": "boolean" },
"not_gaap_note": { "type": "string" }, "not_gaap_note": { "type": "string" },