Skip to content

Release v1.15.4 — re-ship v1.15.3 analytics changes with fixed SQL + defensive Promise.allSettled#118

Merged
jpr5 merged 1 commit into
mainfrom
feat/v1.15.4-blocked-queries-hotfix
Jun 17, 2026
Merged

Release v1.15.4 — re-ship v1.15.3 analytics changes with fixed SQL + defensive Promise.allSettled#118
jpr5 merged 1 commit into
mainfrom
feat/v1.15.4-blocked-queries-hotfix

Conversation

@jpr5

@jpr5 jpr5 commented Jun 17, 2026

Copy link
Copy Markdown
Contributor

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):

  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 (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 outer GROUP BY and the inner correlated reference operate on the same column.
  2. Promise.allPromise.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; a failed summary still surfaces via the top-level banner. Per-panel failures degrade to an empty state with console.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=7 returned HTTP 200 + valid JSON. Verified with three test rows inserted into prod: response correctly grouped one bucket by block_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=7 returned HTTP 200, no abuse strings (toy story / box office / kalshi / scotus) leaked into results.
  • /analytics page 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=30 returns ~13k legacy <unknown> rows). Both pre-fix and post-fix were observed end-to-end against the actual production schema before push.

Test plan

  • CI green
  • Post-deploy: /analytics renders all sections, no error banner
  • /api/analytics/blocked-queries?days=7 returns 200 + grouped JSON

…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
@jpr5 jpr5 merged commit 6d23e83 into main Jun 17, 2026
8 checks passed
@jpr5 jpr5 deleted the feat/v1.15.4-blocked-queries-hotfix branch June 17, 2026 18:39
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