Skip to content

fix(platform): repos with metrics show "0 runs" (PostgREST max-rows cap) - #121

Merged
trentas merged 1 commit into
mainfrom
fix/repos-zero-runs-maxrows
Jul 14, 2026
Merged

fix(platform): repos with metrics show "0 runs" (PostgREST max-rows cap)#121
trentas merged 1 commit into
mainfrom
fix/repos-zero-runs-maxrows

Conversation

@trentas

@trentas trentas commented Jul 14, 2026

Copy link
Copy Markdown
Contributor

Problem

Repos with real analysis runs rendered "0 runs" in /repos (42 repos for the clickbus org).

Root cause: getOrgReposSummary fetched raw metrics org-wide with a global .limit(repos.length * 15) and grouped client-side. PostgREST silently caps every response at the project "Max rows" (default 1000), so once an org had > 1000 metric rows in a window only the newest 1000 came back. Repos whose latest run fell outside that slice received zero rows → "0 runs" despite having metrics.

Ruled out via SQL (not a data problem, not the #120 usage leak): all 192 repos have metrics@90d; the worst "newest-run rank" was 1546 < 1776 total metrics — pure read-side truncation.

Fix

  • New migration 022_repo_metric_summaries.sql: view returning one pre-aggregated row per (repository, window_days)runs_count, latest values, previous stabilization (delta), sparkline.
  • getOrgReposSummary reads the view instead of raw metrics. Result set ≈ repo count, well under any max-rows cap. Fixes /repos, /dashboard, /compare, /ai-exposure (all call this function).

Verification

  • tsc ✓ · eslint ✓ · 213 tests ✓
  • View behavior validated against real Postgres (PGlite): window isolation, latest/previous selection, sparkline order + null-drop all correct.
  • Migration already applied in prod; post-check repos_zero_runs = 0.

Follow-up (not in this PR)

getAvailableWindowDays (temporal.ts:47, .limit(2000)) shares the same org-wide cap pattern — low impact (window selector only).

🤖 Generated with Claude Code

getOrgReposSummary fetched raw `metrics` for the whole org with a global
`.limit(repos.length * 15)` and grouped client-side. PostgREST caps every
response at the project "Max rows" (default 1000), so once an org had
> 1000 metric rows in a window only the newest 1000 returned. Repos whose
latest run fell outside that slice received zero rows and rendered
"0 runs" despite having metrics — a read-side truncation, not missing data.

Add a `repo_metric_summaries` view (one pre-aggregated row per repo+window)
and read it instead of raw metrics. The result set is ~= repo count, well
under any max-rows cap, and the latest/previous/count/sparkline computation
moves into the DB. Fixes /repos, /dashboard, /compare and /ai-exposure,
which all call getOrgReposSummary.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@vercel

vercel Bot commented Jul 14, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
clickbus-iris Ready Ready Preview, Comment Jul 14, 2026 10:50pm

Request Review

@kody-ai

kody-ai Bot commented Jul 14, 2026

Copy link
Copy Markdown

Code Review Could Not Complete ⚠️

The review failed before suggestions could be generated.

Reason: The configured API key (google_gemini) is out of credits or has hit its billing limit. Top up the account or adjust the plan.

After fixing the issue, comment @kody review on this PR to re-run the review.

Kody Guide: Usage and Configuration
Interacting with Kody
  • Request a Review: Ask Kody to review your PR manually by adding a comment with the @kody start-review command at the root of your PR.

  • Validate Business Logic: Ask Kody to validate your code against business rules by adding a comment with the @kody -v business-logic command.

  • Provide Feedback: Help Kody learn and improve by reacting to its comments with a 👍 for helpful suggestions or a 👎 if improvements are needed.

Current Kody Configuration
Review Options

The following review options are enabled or disabled:

Options Enabled
Bug
Performance
Security
Business Logic

Access your configuration settings here.

@trentas
trentas merged commit 79f33c6 into main Jul 14, 2026
4 checks passed
@trentas
trentas deleted the fix/repos-zero-runs-maxrows branch July 14, 2026 22:50
renatoguimaraescb added a commit that referenced this pull request Aug 24, 2026
…ntry

The ingestion module had no way in. Adds the route, the read layer it
needed, and the nav entry.

Read layer (lib/queries/board-flow-data.ts) loads items and events and
hands them to the existing pure functions, so every calculation stays
unit-testable without a database. Reads paginate explicitly: PostgREST
caps responses at the project's max-rows, and a board above that would
come back silently truncated — the failure mode behind #121.

The route degrades instead of erroring. A missing schema (migration 023
not applied) and an org with no board both render an unconfigured state,
so the nav entry can ship before the migration lands rather than 500ing
on a deployment that hasn't migrated.

Section order is the spec's and it is deliberate: quality gates before
any number, so the reader knows what the figures can carry before
reading them. Then durations, time per column, WIP aging, throughput,
CFD, stalled items, Little's Law.

Two visualization decisions:

- The CFD groups by lifecycle bucket, not by column. The live board has
  17 columns; stacking that many bands is unreadable, while five buckets
  make accumulation obvious. Needed the resolved bucket per column, so
  summarizeBoard now returns `statusBuckets`.
- Ran the product's categorical ramp through a palette validator. It
  passes colour-vision separation (worst adjacent pair ΔE 18.6, target
  8) but four of five slots fall below 3:1 contrast against the page
  surface. That obligates relief, so every mark is paired with a visible
  label or rendered as a table — identity is never colour alone. Same
  reason the gates lead with an icon and the severity word, not a dot.

Nav entry lives in tenantNavItems, which the sidebar and the mobile
sheet share, so one entry covers both. Translations in en-US and pt-BR;
es-ES falls back to en-US per the existing convention.

Not verified: the page has not been rendered against real data. The
schema is not applied anywhere yet and this machine has no Supabase
credentials, so only the empty and unconfigured states are reachable
locally. Build and types pass; visual confirmation is still owed.

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
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