Skip to content

fix(platform): five high-severity bugs on /repos and repo-detail - #156

Merged
clickmatos merged 1 commit into
mainfrom
fix/repos-page-calc-bugs
Aug 13, 2026
Merged

fix(platform): five high-severity bugs on /repos and repo-detail#156
clickmatos merged 1 commit into
mainfrom
fix/repos-page-calc-bugs

Conversation

@clickmatos

Copy link
Copy Markdown
Contributor

Follow-up from a fresh audit of /repos (list + detail pages) — five confirmed 🔴 bugs, each traced end-to-end before fixing.

Fixes

  1. getRepoTimeSeries/getRepoAITimeSeries fetched the oldest N runs, not the newest N. .order("created_at", { ascending: true }).limit(52) sorts ascending then takes the first 52 — the oldest 52 once a repo/window has more than 52 runs. The repo-detail page's top MetricCards, ChangeAlert, and every chart fed by these two queries would freeze on a stale run and never advance, while the rest of the page (via getRepoLatestPayload, already DESC + limit(1)) kept showing the true latest state — two contradictory pictures of the same repo on one screen. Fixed by fetching DESC + limit then reversing in JS, mirroring the pattern getOrgReposSummary's sparkline already uses correctly.

  2. Investment Hotspots' fix-magnet cards rendered "0% of changes, 1% of fixes" instead of "35%, 70%". The engine's code_share_pct/fix_share_pct (iris/analysis/fix_targeting.py) are 0-1 fractions despite the "_pct" name; the platform copied them through unscaled while its two sibling hotspot types (stabilizationRatio, couplingRate) correctly multiply by 100. Scaled at the query layer and documented the misleading engine field name on both the raw type and the platform's own type.

  3. /repos and /ai-exposure ignored the org's actual analysis window, unlike /dashboard and /compare (which both call getAvailableWindowDays + resolveWindowDays). Both silently defaulted to the hardcoded 90-day window — any org ingesting under a different window saw every repo as unanalyzed on these two pages while the other two showed real data. Added the same window resolution plus a WindowSelector, for parity with the rest of the app.

  4. Repo-scoped DORA card never got the MTTR P90 hint added to the org dashboard and to RepoDORA's own type — a wiring gap, not a missing capability. Wired it in, reusing the existing translation key.

  5. Weekly Activity table's "AI%" column divided by HUMAN+AI_ASSISTED+BOT, while the canonical ai_detection_coverage_pct (used by the "AI Adoption" chart on the same page) excludes BOT. A week with a dependency-bump burst would show two different, both-labeled-"AI%" numbers on the same screen that don't reconcile. Excluded BOT from the table's denominator to match.

Verification

  • Added a regression test for the fix-magnet scaling bug (confirmed it fails against the pre-fix code: 0.35 instead of 35).
  • The other four fixes aren't covered by an automated test — three are UI/page-level code this codebase doesn't unit-test anywhere, and the time-series ordering fix is a direct Supabase query with no existing DB-mocking convention to build on (platform/CLAUDE.md: "integration tests use real DBs, unit tests for analysis modules"). Validated via tsc + review against the already-correct sibling patterns in the same files.
  • npx tsc --noEmit: clean.
  • npm run test: 254/254 passing (253 + 1 new).
  • npm run lint: 0 errors, same 72 pre-existing warnings.

Co-Authored-By: Claude Sonnet 5 noreply@anthropic.com

- getRepoTimeSeries / getRepoAITimeSeries fetched the OLDEST N runs
  instead of the newest N: `.order("created_at", { ascending: true
  }).limit(52)` sorts ascending then takes the first 52, i.e. the
  oldest 52 once a repo/window has more than 52 analysis runs. The
  repo-detail page's top MetricCards, ChangeAlert, and every chart fed
  by these two queries would freeze on a stale run and never advance,
  while the rest of the page (sourced from getRepoLatestPayload, which
  already did DESC + limit(1) correctly) kept showing the true latest
  state — two contradictory pictures of the same repo on one screen.
  Fixed by fetching DESC + limit then reversing in JS, mirroring the
  pattern getOrgReposSummary's sparkline already uses correctly.

- Investment Hotspots' fix-magnet cards rendered "0% of changes, 1% of
  fixes" instead of "35%, 70%". The engine's code_share_pct/
  fix_share_pct (iris/analysis/fix_targeting.py) are 0-1 fractions
  despite the "_pct" name; the platform copied them through unscaled
  while its two sibling hotspot types (stabilizationRatio,
  couplingRate) correctly multiply by 100. Scaled at the query layer
  and documented the misleading engine field name on both the raw
  FixTargetMetrics type and the platform's own FixMagnetHotspot type.

- /repos and /ai-exposure called getOrgReposSummary (and, for
  ai-exposure, getOrgLatestPayloads) without resolving the org's
  actual available analysis window first — unlike /dashboard and
  /compare, which both call getAvailableWindowDays + resolveWindowDays.
  Both pages silently defaulted to the hardcoded 90-day window; any org
  ingesting under a different window saw every repo as unanalyzed on
  these two pages while the other two showed real data. Added the same
  window resolution plus a WindowSelector, for parity with the rest of
  the app.

- The repo-scoped DORA card never got the MTTR P90 hint that was added
  to the org dashboard's DORAOverview and to RepoDORA's own type — a
  wiring gap, not a missing capability. Added it, reusing the same
  translation key.

- The Weekly Activity table's "AI%" column divided by HUMAN+AI_ASSISTED
  +BOT, while the canonical ai_detection_coverage_pct metric (used by
  the "AI Adoption" chart on the same page) explicitly excludes BOT
  from its denominator. A week with a dependency-bump burst would show
  two different, both-labeled-"AI%" numbers on the same screen that
  don't reconcile. Excluded BOT from the table's denominator to match.

Added a regression test for the fix-magnet scaling bug (confirmed it
fails against the pre-fix code: 0.35 instead of 35). The other four
fixes aren't covered by an automated test — three are UI/page-level
code this codebase doesn't unit-test anywhere, and the time-series
ordering fix is a direct Supabase query with no existing DB-mocking
convention to build on (platform/CLAUDE.md: "integration tests use
real DBs, unit tests for analysis modules"). Validated via tsc + careful
review against the already-correct sibling patterns in the same files.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@vercel

vercel Bot commented Aug 13, 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 Aug 13, 2026 8:15pm

Request Review

@clickmatos
clickmatos merged commit f1860e2 into main Aug 13, 2026
5 checks passed
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