Release v1.15.4 — re-ship v1.15.3 analytics changes with fixed SQL + defensive Promise.allSettled#118
Merged
Merged
Conversation
…defensive Promise.allSettled Re-ships the three v1.15.3 changes (blocked filter on empty-results, new Blocked Queries panel, Pacific timestamps) with two defects fixed that took v1.15.3 down within minutes of deploy (reverted via PR #117). Fix 1 — getBlockedQueries SQL: rewrote as a CTE-backed correlated subquery. v1.15.3 grouped the outer query on COALESCE(block_reason, '<unknown>') but the correlated subquery referenced raw query_log.block_reason, which Postgres rejects as an ungrouped column reference. The CTE pre-projects the COALESCEd expression to a single column (block_reason_key) that both the outer GROUP BY and the inner correlated reference use. Verified against real prod Postgres schema locally — endpoint returns 200 + valid grouped JSON when test rows exist, empty array when none. Fix 2 — Promise.all → Promise.allSettled in docs/analytics.html: a single panel's fetch failure used to throw out of Promise.all and blank the entire /analytics page (which is what made v1.15.3's SQL bug catastrophic instead of merely cosmetic). Each panel now renders independently; auth (401) still bubbles to the outer catch since a bad token fails every endpoint identically, and a failed summary still surfaces via the top-level banner. Per-panel failures (empty/blocked/tool-counts) degrade to an empty state with a console.error. Local verification (the missing discipline from v1.15.3): - Booted Pathfinder locally against the real prod DATABASE_URL - /api/analytics/blocked-queries returned HTTP 200 + valid JSON with grouped block_reason + NULL→'<unknown>' buckets when test rows were inserted; empty array when none (current prod state) - /api/analytics/empty-queries returned 200, no abuse strings - /analytics page returned 200 with no error banner
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Re-ships the three reverted v1.15.3 changes (blocked filter on empty-results, new Blocked Queries panel, Pacific timestamps) with the two defects fixed that took v1.15.3 down within minutes of deploy (reverted via PR #117):
getBlockedQueriesSQL — rewrote as a CTE-backed correlated subquery. v1.15.3 grouped the outer query onCOALESCE(block_reason, '<unknown>')but the correlated subquery referenced rawquery_log.block_reason, which Postgres rejects as an ungrouped column reference (subquery uses ungrouped column "query_log.block_reason" from outer query). The CTE (blocked_rows.block_reason_key) pre-projects the COALESCEd expression so the outerGROUP BYand the inner correlated reference operate on the same column.Promise.all→Promise.allSettledindocs/analytics.html. A single panel's fetch failure used to throw out ofPromise.alland blank the entire/analyticspage (which is what made v1.15.3's SQL bug catastrophic instead of merely cosmetic). Each panel now renders independently. Auth (401) still bubbles to the outer catch since a bad token fails every endpoint identically; a failed summary still surfaces via the top-level banner. Per-panel failures degrade to an empty state withconsole.error.Local verification (the discipline that was missing on v1.15.3)
Booted Pathfinder locally against the real prod
DATABASE_URL:/api/analytics/blocked-queries?days=7returned HTTP 200 + valid JSON. Verified with three test rows inserted into prod: response correctly grouped one bucket byblock_reason='hotfix-test'(2 hits, 2 sample_queries) and one<unknown>bucket for the NULL row (1 hit, 1 sample_query). Test rows then deleted; prod has zero blocked rows in the 7-day window (current state)./api/analytics/empty-queries?days=7returned HTTP 200, no abuse strings (toy story / box office / kalshi / scotus) leaked into results./analyticspage returned HTTP 200 with no rendered error banner.Pre-fix SQL was directly verified to fail against prod psql with the exact error above. Post-fix SQL was directly verified to return real grouped rows when run against prod psql with a wider window (
days=30returns ~13k legacy<unknown>rows). Both pre-fix and post-fix were observed end-to-end against the actual production schema before push.Test plan
/analyticsrenders all sections, no error banner/api/analytics/blocked-queries?days=7returns 200 + grouped JSON