Commit Graph

7 Commits

Author SHA1 Message Date
a524f23be2 downloads: track every door and surface them on /analytics
The analytics page could not answer "how many downloads, of which
product". Three of the four download doors recorded nothing: the tRPC
click proxy only left the generic request row, whose path is the raw URL
with the asset buried in `?batch=1&input={"asset_name":...}`, and the S3
file route that serves Sparkle updates and the Nook app logged nothing
at all. The one door that did log (the Nook redirect) kept a private copy
of the logVisit/enrich/flush sequence, under its own path.

All doors now go through trackDownload, which writes one row per event
under /api/downloads/<asset> and flushes it inside the request — a click
is low-volume and serverless is not guaranteed to run the 30s batch
timer after the response. The file route maps its prefix allowlist to
asset keys, so a version bump stays one asset rather than one per
release. getAnalyticsSummary groups those rows into a downloads block and
the freno.me panel renders it under the overview cards.

History is recovered to the degree it exists: the Nook door's rows and
the tRPC clicks still carry enough to derive from (asset name in the URL).
scripts/backfill-downloads.ts inserts those derived rows with a
`backfill-<source id>` primary key and INSERT OR IGNORE, leaving the
originals untouched, so re-running is a no-op. Run against the live table
it added 66 rows: gaze 42, thenook 19, inputhalo 4, lineage 1.

Tests: new backfill suite (derivation, visitor detail carried over,
idempotency, empty history) and summariseDownloads cases; the Nook route
test now pins the canonical path, and the NOOK-337 allowlist audit reads
the map keys instead of quoted strings. Red-checked by stubbing the
downloads block back to zeros — the summary case fails, then passes.
Full suite matches master.

Co-Authored-By: nw-flash <noreply@nw-flash.local>
MISC-48
2026-10-22 12:59:48 -04:00
1a182e53fe downloads: serve Nook delta files the Sparkle updater fetches
The v0.10.0 publish stopped at the enclosure check: the appcast names
Nook17-9.delta / Nook17-10.delta, and the proxy 400'd both with
'Invalid file format' while the TheNook DMG passed. Sparkle names delta
files after the app bundle, not the DMG, so the prefix allowlist needs
'Nook' alongside 'TheNook'. Both deltas sat in S3 the whole time; the
appcast was never published and the live one still serves 0.9.0.

Adds a static source-audit regression test in the repo's downloads.test
pattern; proven red against the unfixed allowlist.

Tests: bun test src/routes/api/downloads/filename.test.ts

NOOK-337

Co-Authored-By: glm-5.3-flash <noreply@neuralwatt.com>
2026-10-13 22:17:27 -04:00
e4a9be4899 prep for the nook 2026-08-26 17:41:57 -04:00
898c891bd5 chore: remediate pygienium audit findings
Dead code: 77 verified-unused exports, files (BackArrow, MenuBars,
cookies.ts, db/create.ts, schemas/comment.ts, security-headers.ts) and
12 unused dependencies removed
Comments: ~370 RESTATE comments stripped across 53 files; 2 verbose
blocks tightened; dead commented-out config removed
Complexity: bulkUpsert extracted into 11 per-entity helpers (CCN 156->~10);
login formHandler split into 3 submitters (CCN 63->~5); account page render
split into 8 section components (CCN 40); updatePost SQL builder rebuilt;
assert*Owned consolidated behind generic assertOwnedBy
Defensive guards: 4 redundant rethrow/nullish guards removed
2026-08-11 13:36:18 -04:00
8b6551330f input halo sections, sparkle handling 2026-04-30 06:38:54 -04:00
80daaa29dc quick fix 2026-02-02 15:24:28 -05:00
b81a3a69d2 fix: needed for sparkle 2026-01-11 20:37:50 -05:00