Skip to content

fix: correct sample data, keep CSVs out of the JS bundle, and pick a valid groupBy - #106

Merged
austenstone merged 4 commits into
mainfrom
fix/sample-data
Aug 20, 2026
Merged

fix: correct sample data, keep CSVs out of the JS bundle, and pick a valid groupBy#106
austenstone merged 4 commits into
mainfrom
fix/sample-data

Conversation

@austenstone

Copy link
Copy Markdown
Owner

Three first-run bugs, found by actually running the app against real exports.

The demo's Enterprise Members page was empty

sample-data.ts mapped enterprise-members.csv to the dormant users export. The real members file was never loaded, so the Enterprise Members page had nothing to render. Fixed, and the dormant-users sample is now loaded under its own (correct) name — 7 samples instead of 6.

Enterprise Members now shows 164 licenses in the demo, where it was previously blank.

15 MB of CSV was being shipped as JavaScript

Samples were imported with ?raw, which inlines the file contents into a JS chunk. The build emitted a 15.4 MB JS chunk that the engine has to parse as source before anything renders.

Switching to ?url + fetch() makes Vite emit the files as static assets. Same bytes over the wire, but they're now a plain .csv the browser streams instead of a script it has to parse. Tests are unaffected — they read examples/ through readFileSync.

The first chart rendered empty for summarized reports

addReport hardcoded groupByColumn to 'username'. GitHub's summarized metered usage export has no username column (see #105), so uploading one landed you on a chart grouped by a column that doesn't exist — empty chart, no error, nothing to tell you why.

resolveGroupByColumn() samples the parsed rows for a populated value and falls back to the schema default. It samples with a stride rather than from the head, because username is legitimately blank on leading storage rows.

While in there: activeReportIndex was set from prev.reports.length instead of the post-filter count. When samples are auto-removed on a real import, that pointed past the end of the array. Currently masked, but wrong.

Verified

Uploaded a 20,000-row summarized export over the demo:

  • 7 samples correctly auto-removed, leaving 1 report
  • lands on groupBy=sku instead of the empty username
  • renders $9,154.02 gross / 46.8K minutes across a populated SKU breakdown

260 tests pass, 0 lint errors, 0 type errors.

Stacked on #105. Review that one first.

…valid groupBy

Three fixes to first-run behaviour:

- enterprise-members.csv was actually loading the dormant-users export, so
  the Enterprise Members page rendered empty in the demo. Load the real
  members file and add the dormant-users sample alongside it.

- Samples were imported with ?raw, which inlines 15 MB of CSV into a JS
  chunk the engine has to parse as source. Switch to ?url + fetch so Vite
  emits them as static assets.

- addReport hardcoded groupByColumn to 'username'. Summarized metered usage
  reports have no username column, so the first chart rendered empty.
  resolveGroupByColumn samples the parsed rows and falls back to the
  schema default. Also fixes activeReportIndex, which used the unfiltered
  report count and pointed past the end of the array once samples were
  auto-removed on a real import.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
@austenstone-datadog

This comment has been minimized.

austenstone and others added 2 commits August 20, 2026 09:15
tsconfig.json is a solution-style config — "files": [] with only project
references — so `tsc --noEmit` resolved zero files and always exited 0.
CI has been running a typecheck gate that could never fail.

`tsc -b --noEmit` walks the referenced projects instead. Verified by
planting a deliberate type error: the old script reported nothing, the
new one reports it.

This immediately caught a real error in resolveGroupByColumn, which only
surfaced in the build step: the row union has no index signature, so it
can't be cast straight to Record<string, unknown>. Read the column
through an unknown-typed accessor instead.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
The README pointed everyone at "Settings > Billing > Usage report", which
isn't where any of these reports live anymore. Replace it with a per-report
table matching the in-app instructions in FileDropzone, and note that
metered usage exports come in detailed and summarized shapes now that both
parse.

The privacy section claimed "100% client-side, no uploads, no telemetry".
Accurate for CSV data, but formatters.ts does look up avatars from
api.github.com for bot accounts. Narrow the claim to what the code does.

Also drops the last /tbb/ scaffold paths from share-state.test.ts. The
test mocks its own location so it passed either way, but the fixture
should match the real base path.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
@austenstone
austenstone changed the base branch from fix/billing-format-drift to main August 20, 2026 17:24
@austenstone
austenstone merged commit 71872fd into main Aug 20, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant