Skip to content

Add stale + archived filters to the /repos dashboard page - #196

Merged
clickmatos merged 2 commits into
mainfrom
repos-page-stale-archived-filters
Aug 26, 2026
Merged

Add stale + archived filters to the /repos dashboard page#196
clickmatos merged 2 commits into
mainfrom
repos-page-stale-archived-filters

Conversation

@clickmatos

Copy link
Copy Markdown
Contributor

Summary

Follow-up to a bulk-analysis CLI script (scripts/list_active_repos.py, --stale/--include-archived) that never touched the real product — this adds the equivalent to the actual /[tenant]/repos dashboard page.

Stale filter (no push in 90d+) — pure client-side, zero new data or queries. RepoList already receives last_run_at per repo via the existing getOrgReposSummary load. A repo with no last_run_at at all counts as stale too. Note the same caveat the CLI script already documents: this is last iris push time, not literal last-commit time — no per-commit date survives into the stored payload (only week-level commit counts).

Archived filter (GitHub status) — the platform has no stored column for this and no durable GitHub credential to background-sync it (only a session-scoped OAuth token, no repo scope → public repos only). Per explicit direction, no database changes in this PR. Instead:

  • New checkArchivedStatus() in lib/github.ts, mirroring the existing listUserOrgs/listOrgMembers "one call per item, parallelized" pattern already used in that file.
  • New POST /api/repos/check-archived route, mirroring /api/auth/github-orgs exactly (same auth/error shape).
  • A "Hide archived" toggle in RepoList's toolbar triggers the check on first use (not automatically on page load — that would reintroduce the exact "dashboard does expensive work on every load" problem [BUG] Dashboard principal demora muito para carregar as informações #180/Eliminate N+1 query in getOrgChangeDetections #195 just fixed). Results live only in component state: nothing persisted, re-fetched fresh every time. Matched repos, remote_urlnormalizeRepoSlug (already exported + tested in lib/integrations/datadog/sync.ts) → GitHub API path.
  • Private repos (403/404) come back "unknown," not archived — never silently wrong.
  • Button disabled with a tooltip when the session has no GitHub-linked token.

Test plan

  • npx tsc --noEmit — clean
  • npx eslint on all touched/new files — 0 errors. One pre-existing-pattern warning (react-hooks/purity on a Date.now() call in the server component repos/page.tsx) — already present elsewhere in this codebase for the identical pattern (team/page.tsx:103), not a new regression.
  • npx vitest run — 269 passed. No new tests added: lib/github.ts has zero existing test coverage (external API wrapper, consistent with this codebase's convention of not unit-testing that layer), and normalizeRepoSlug reuse is already covered by platform/tests/datadog-sync.test.ts.
  • Not verified in a live browser — same limitation as the earlier OrgTimeline/N+1 PRs: needs a live Supabase + GitHub-OAuth session to exercise for real. Recommend a preview-deploy check before merge, especially for the archived-check flow (real GitHub API round-trip).

🤖 Generated with Claude Code

Two filters on /[tenant]/repos, requested as the dashboard equivalent
of scripts/list_active_repos.py's --stale/--include-archived (which
only ever touched that standalone CLI script, not the real product).

- Stale (no push in 90d+): pure client-side filter on RepoList using
  the last_run_at the page already loads via getOrgReposSummary — no
  new data, no new query. Same "never pushed also counts as stale"
  semantics as the CLI script, and the same documented caveat: this is
  last iris push time, not literal last-commit time (no per-commit
  date survives into the stored payload).

- Archived (GitHub status): the platform has no stored column for this
  and no durable GitHub credential to background-sync it — only a
  session-scoped OAuth token with no `repo` scope (public repos only).
  Per explicit direction, this ships with no database changes: a new
  "Check archived"/"Hide archived" toggle triggers an on-demand,
  ephemeral POST to /api/repos/check-archived, which calls GitHub's
  REST API in parallel per repo (mirroring the existing
  listUserOrgs/listOrgMembers pattern in lib/github.ts) using the
  logged-in user's own token, and returns results that live only in
  component state — nothing persisted, nothing runs automatically on
  page load. Private repos (403/404) come back "unknown", not
  archived. The button is disabled with an explanatory tooltip when
  the session has no GitHub-linked token.

Reuses normalizeRepoSlug (already exported from
lib/integrations/datadog/sync.ts, already tested) to match a repo's
remote_url back to the API response.

Co-Authored-By: claude-code_2-1-238_agent <claude-code_2-1-238_agent@iris.invalid>
@vercel

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

Request Review

Build failed: repo-list.tsx ("use client") imported normalizeRepoSlug
from lib/integrations/datadog/sync.ts, which transitively imports
lib/supabase.ts (server-only, uses next/headers) via decryptCredentials.
Importing anything from that file — even one dependency-free function —
drags its whole module graph into the client bundle, and Turbopack
correctly refuses to ship next/headers to the browser.

Moved normalizeRepoSlug to a new lib/repo-slug.ts with zero
dependencies. sync.ts now imports it from there and re-exports it
(so the existing datadog-sync.test.ts import path keeps working
unchanged); repo-list.tsx and github.ts import the new module
directly instead of going through sync.ts.

Verified with a local `npm run build` using the same placeholder env
vars CI uses — reproduced the original failure, confirmed this fixes it.

Co-Authored-By: claude-code_2-1-238_agent <claude-code_2-1-238_agent@iris.invalid>
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