From f2dc37a898cd21f4c80be904e9ddaff70458c053 Mon Sep 17 00:00:00 2001 From: Jordan Ritter Date: Wed, 17 Jun 2026 11:35:30 -0700 Subject: [PATCH] =?UTF-8?q?Release=20v1.15.4=20=E2=80=94=20re-ship=20v1.15?= =?UTF-8?q?.3=20analytics=20changes=20with=20fixed=20SQL=20+=20defensive?= =?UTF-8?q?=20Promise.allSettled?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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, '') 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→'' 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 --- CHANGELOG.md | 12 + docs/analytics.html | 373 +++++++++++++++--- package.json | 2 +- .../analytics-auth-length-check.test.ts | 2 + src/__tests__/analytics-error-log-ip.test.ts | 4 + .../analytics-sendfile-correlation.test.ts | 1 + src/__tests__/analytics-server.test.ts | 84 ++++ src/__tests__/analytics-ui.test.ts | 211 ++++++++++ src/__tests__/analytics.test.ts | 108 +++++ src/cli.ts | 2 +- src/db/analytics.ts | 110 ++++++ src/server.ts | 30 ++ 12 files changed, 875 insertions(+), 64 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 82b9d24..888f1b7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,17 @@ # @copilotkit/pathfinder +## 1.15.4 + +### Patch Changes + +- **Re-ship of v1.15.3 with the broken `getBlockedQueries` SQL fixed and defensive client-side panel isolation.** v1.15.3 was reverted via PR #117 within minutes of deploy because the `/api/analytics/blocked-queries` route 500'd against real Postgres and the page's `Promise.all` then nuked the entire `/analytics` dashboard. v1.15.4 re-ships all three v1.15.3 changes (blocked filter on empty-results, new Blocked Queries panel, Pacific timestamps) with the SQL and resilience defects fixed. +- **`getBlockedQueries` SQL — rewrote as a CTE-backed correlated subquery.** The original v1.15.3 SQL grouped the outer query on `COALESCE(block_reason, '')` 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 fix pre-projects the COALESCEd expression into a CTE (`blocked_rows.block_reason_key`) so the outer GROUP BY and the inner correlated reference operate on the same column. Verified against the actual prod Postgres schema before push. +- **Analytics page — `Promise.all` replaced with `Promise.allSettled`.** A single panel's fetch failure used to throw out of `Promise.all` and blank the entire `/analytics` page (this is what made the v1.15.3 SQL bug catastrophic instead of merely cosmetic). Each section now renders independently: the summary endpoint failing still surfaces via the top-level error banner (the page can't render statcards without it), but per-panel failures (empty queries / blocked queries / tool counts) degrade to an empty state with a `console.error` and leave the rest of the dashboard intact. Auth (401) errors still bubble to the outer catch since a bad token fails every endpoint identically. + +## 1.15.3 — REVERTED + +This release was reverted via PR #117 immediately after deploy. Its `getBlockedQueries` SQL was incompatible with real Postgres (ungrouped column reference inside a correlated subquery) and its client-side `Promise.all` rendering blanked the entire `/analytics` page on a single panel's failure. See v1.15.4 for the fixed re-ship. + ## 1.15.2 ### Patch Changes diff --git a/docs/analytics.html b/docs/analytics.html index ce460dc..a522f90 100644 --- a/docs/analytics.html +++ b/docs/analytics.html @@ -4,19 +4,41 @@ Pathfinder Analytics - - - - - - - - - - - - - + + + + + + + + + + + + +