Skip to content

feat(admin): pagination, search debounce, reset-stuck UI, error boundaries#2386

Merged
andrew-bierman merged 8 commits into
mainfrom
fix/etl-memory-and-weight-validation-v2
May 7, 2026
Merged

feat(admin): pagination, search debounce, reset-stuck UI, error boundaries#2386
andrew-bierman merged 8 commits into
mainfrom
fix/etl-memory-and-weight-validation-v2

Conversation

@andrew-bierman
Copy link
Copy Markdown
Collaborator

@andrew-bierman andrew-bierman commented May 7, 2026

Summary

  • Pagination on catalog, packs, and users pages (50 items/page, URL-synced ?page=N)
  • Search debounce (300ms) — input feels instant, URL/API update is throttled; also resets page to 0 on new search
  • Reset Stuck Jobs button in the ETL Pipeline card — calls the new POST /api/admin/analytics/catalog/etl/reset-stuck endpoint, shows spinner + how many jobs were reset; removes the manual reset-stuck-etl-jobs.sql script
  • Error boundariesapp/error.tsx (root) and app/dashboard/error.tsx stop 500s from blanking the whole screen

API change

POST /api/admin/analytics/catalog/etl/reset-stuck — admin-only endpoint that marks jobs stuck in running for >3 hours as failed. Replaces the raw SQL script.

Post-Deploy Monitoring & Validation

  • Pagination: manually verify prev/next buttons on catalog page load 50 items each
  • Reset Stuck button: after deploy, use it to clear any remaining zombie ETL jobs — response will show { reset: N, ids: [...] }
  • Error boundaries: trigger a bad API URL to confirm the "Failed to load" UI renders instead of a blank page

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features

    • Prev/Next pagination with item-range displays across Catalog, Users, and Packs.
    • Reset-stuck ETL jobs action in catalog analytics.
    • Client-side error fallback UIs and an error boundary for dashboard pages.
    • Raw JSON preview dialog for row details.
  • Improvements

    • Search inputs now use unified query-state with paginated search (stable q + page handling).
    • Listings return richer catalog/pack/user metadata and improved price/currency display.
    • React Query key/cache patterns standardized for more consistent invalidation.

… boundaries

- Add 50-item pagination (URL ?page=N) to catalog, packs, users pages
- Debounce search input 300ms; resets page param on new search
- POST /api/admin/analytics/catalog/etl/reset-stuck endpoint replaces raw SQL script
- Reset Stuck Jobs button in ETL card with spinner + result feedback
- Root + dashboard error boundaries
- Delete packages/api/scripts/reset-stuck-etl-jobs.sql
- Fix queryKeys.admin.* to accept { q, page, limit } params
Copilot AI review requested due to automatic review settings May 7, 2026 18:26
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 7, 2026

Review Change Stack

Warning

Rate limit exceeded

@andrew-bierman has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 12 minutes and 24 seconds before requesting another review.

You’ve run out of usage credits. Purchase more in the billing tab.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: d58bfc51-e705-4f7f-8773-f12355505e67

📥 Commits

Reviewing files that changed from the base of the PR and between d25fca5 and 123e4ce.

📒 Files selected for processing (4)
  • apps/admin/app/dashboard/layout.tsx
  • apps/admin/app/global-error.tsx
  • apps/admin/components/error-fallback.tsx
  • apps/admin/components/raw-object-dialog.tsx

Warning

.coderabbit.yaml has a parsing error

The CodeRabbit configuration file in this repository has a parsing error and default settings were used instead. Please fix the error(s) in the configuration file. You can initialize chat with CodeRabbit to get help with the configuration file.

💥 Parsing errors (1)
Validation error: String must contain at most 250 character(s) at "tone_instructions"
⚙️ Configuration instructions
  • Please see the configuration documentation for more information.
  • You can also validate your configuration using the online YAML validator.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json
📝 Walkthrough

Walkthrough

This PR migrates the admin dashboard from URL search params to nuqs-based query state with paginated list keys, adds Prev/Next pagination to users/packs/catalog pages, refactors queryKeys to factory builders, implements a POST /catalog/etl/reset-stuck API plus frontend reset mutation, expands admin list response shapes, and adds client error fallback components.

Changes

Admin Pagination & ETL Reset

Layer / File(s) Summary
Query Key Architecture
apps/admin/lib/queryKeys.ts
queryKeys.admin and queryKeys.catalogAnalytics.etl refactored into factory objects with all() anchors and .list(params?) builders to include { q, page, limit } in keys.
API Response & Client Types
packages/api/src/routes/admin/index.ts, apps/admin/lib/api.ts
Admin list responses extended (users: avatarUrl, updatedAt; packs: isAIGenerated,tags,image,updatedAt; catalog items: many new attributes) and client types updated; resetStuckEtlJobs() client added.
ETL Reset API
packages/api/src/routes/admin/analytics/catalog.ts
Add POST /catalog/etl/reset-stuck route that updates running ETL jobs older than 3 hours to failed, sets completedAt, and returns reset count and IDs.
nuqs Integration & Providers
apps/admin/package.json, apps/admin/app/layout.tsx
Add nuqs dependency and wrap app with NuqsAdapter outside QueryProvider to enable nuqs query-state.
Paginated Search Hook
apps/admin/hooks/use-paginated-search.ts
New usePaginatedSearch() hook reading/writing q and page via nuqs, normalizing page and resetting page when search changes.
SearchInput
apps/admin/components/search-input.tsx
Refactor SearchInput to use useQueryState(parseAsString) with optional onSearch, removing Suspense/router transition logic.
Users Page Pagination
apps/admin/app/dashboard/users/page.tsx
Switch to usePaginatedSearch, compute offset = page * PAGE_SIZE, use queryKeys.admin.users.list({ q, page }) with getUsers({ q, limit, offset }), add Prev/Next controls and range footer, include RawObjectDialog in actions, invalidate queryKeys.admin.users.all() on delete.
Packs Page Pagination
apps/admin/app/dashboard/packs/page.tsx
Switch to usePaginatedSearch, PAGE_SIZE=50, use paginated query key and getPacks({ q, limit, offset }), add Prev/Next and range footer, include RawObjectDialog, invalidate queryKeys.admin.packs.all() on delete.
Catalog Page Pagination
apps/admin/app/dashboard/catalog/page.tsx
Switch to usePaginatedSearch, PAGE_SIZE=50, use queryKeys.admin.catalog.list({ q, page }), pass limit/offset to getCatalogItems, extend row UI (price/currency formatting, status/rating, productUrl), include RawObjectDialog, and add bottom range bar with Prev/Next; invalidate queryKeys.admin.catalog.all() on delete.
Catalog Analytics: ETL Reset (frontend)
apps/admin/lib/api.ts, apps/admin/hooks/use-catalog-analytics.ts, apps/admin/components/analytics/catalog-analytics.tsx
Add resetStuckEtlJobs() client, update catalog analytics query keys to callable forms, wire useMutation with "Reset Stuck" button and result/error feedback, and invalidate ETL analytics query on success; ETL table gains Invalid/started/completed columns and RawObjectDialog actions.
Row Actions & Utilities
apps/admin/components/raw-object-dialog.tsx, apps/admin/components/edit-catalog-dialog.tsx
Add RawObjectDialog for JSON inspection and update edit-catalog dialog to invalidate queryKeys.admin.catalog.all() on update.
Error Boundaries & Global Error UIs
apps/admin/app/dashboard/layout.tsx, apps/admin/components/error-fallback.tsx, apps/admin/app/error.tsx, apps/admin/app/global-error.tsx, apps/admin/app/dashboard/error.tsx
Add client-side error fallback components, wrap dashboard in ErrorBoundary using ErrorFallback, and add global/dashboard error pages that log errors and provide retry.
Cleanup / Misc
packages/api/scripts/reset-stuck-etl-jobs.sql, .gitignore, apps/admin/package.json
Remove obsolete SQL script (logic moved to API), add .worktrees ignore entry, and add nuqs dependency.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Suggested labels

web

Suggested reviewers

  • mikib0

Poem

🐰 I hop through queries, nuqs in paw,

Pages flip neatly without a flaw.
ETL wakes from its long, stuck night,
Error fences catch the fright—
The admin dashboard hums just right!

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 3.03% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title directly reflects the main changes: pagination support across multiple pages, search debouncing functionality, a reset-stuck UI feature, and error boundary implementations.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/etl-memory-and-weight-validation-v2

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions github-actions Bot added the api label May 7, 2026
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 7, 2026

Coverage Report for Expo Unit Tests Coverage (./apps/expo)

Status Category Percentage Covered / Total
🔵 Lines 81.65% 534 / 654
🔵 Statements 81.65% (🎯 75%) 534 / 654
🔵 Functions 92.98% 53 / 57
🔵 Branches 90.13% 201 / 223
File CoverageNo changed files found.
Generated in workflow #1103 for commit 123e4ce by the Vitest Coverage Report Action

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 7, 2026

Coverage Report for API Unit Tests Coverage (./packages/api)

Status Category Percentage Covered / Total
🔵 Lines 75.74% 609 / 804
🔵 Statements 75.74% (🎯 65%) 609 / 804
🔵 Functions 95.91% 47 / 49
🔵 Branches 88.23% 270 / 306
File CoverageNo changed files found.
Generated in workflow #1103 for commit 123e4ce by the Vitest Coverage Report Action

@cloudflare-workers-and-pages
Copy link
Copy Markdown
Contributor

cloudflare-workers-and-pages Bot commented May 7, 2026

Deploying with  Cloudflare Workers  Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

Status Name Latest Commit Preview URL Updated (UTC)
✅ Deployment successful!
View logs
packrat-admin 123e4ce Commit Preview URL

Branch Preview URL
May 07 2026, 08:47 PM

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds UX and operational improvements to the admin app by introducing URL-synced pagination, debounced search, a UI control + API endpoint to reset “stuck” ETL jobs, and Next.js error boundaries to avoid blank screens on runtime errors.

Changes:

  • Add pagination (50/page) to Users/Packs/Catalog pages and sync ?page= in the URL.
  • Debounce search input updates (300ms) and reset pagination when search changes.
  • Add admin-only POST /api/admin/analytics/catalog/etl/reset-stuck endpoint + “Reset Stuck” button in the ETL card; remove the legacy SQL script.
  • Add root and dashboard error boundary pages for the admin Next.js app.

Reviewed changes

Copilot reviewed 12 out of 12 changed files in this pull request and generated 7 comments.

Show a summary per file
File Description
packages/api/src/routes/admin/analytics/catalog.ts Adds the reset-stuck ETL admin endpoint.
packages/api/scripts/reset-stuck-etl-jobs.sql Removes manual SQL script (replaced by API endpoint).
apps/admin/lib/queryKeys.ts Updates query keys to support pagination/search params.
apps/admin/lib/api.ts Adds resetStuckEtlJobs() client wrapper.
apps/admin/components/search-input.tsx Implements debounced, URL-synced search input.
apps/admin/components/analytics/catalog-analytics.tsx Adds “Reset Stuck” ETL button + mutation wiring.
apps/admin/app/error.tsx Adds global error boundary UI.
apps/admin/app/dashboard/error.tsx Adds dashboard-segment error boundary UI.
apps/admin/app/dashboard/users/page.tsx Adds pagination controls + URL syncing for users list.
apps/admin/app/dashboard/page.tsx Updates dashboard queries to new query key shape.
apps/admin/app/dashboard/packs/page.tsx Adds pagination controls + URL syncing for packs list.
apps/admin/app/dashboard/catalog/page.tsx Adds pagination controls + URL syncing for catalog list.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread apps/admin/lib/queryKeys.ts Outdated
Comment on lines +16 to +20
['admin', 'users', params] as const,
packs: (params?: { q?: string; page?: number; limit?: number }) =>
['admin', 'packs', params] as const,
catalog: (params?: { q?: string; page?: number; limit?: number }) =>
['admin', 'catalog', params] as const,
} = useMutation({
mutationFn: resetStuckEtlJobs,
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: queryKeys.catalogAnalytics.etl() });
Comment thread apps/admin/components/search-input.tsx Outdated
Comment on lines 18 to 46
const urlValue = searchParams?.get(paramKey) ?? '';
const [inputValue, setInputValue] = useState(urlValue);
const debounceRef = useRef<ReturnType<typeof setTimeout> | null>(null);

// Keep input in sync if URL changes externally (e.g. browser back)
useEffect(() => {
setInputValue(urlValue);
}, [urlValue]);

const handleChange = useCallback(
(e: React.ChangeEvent<HTMLInputElement>) => {
const next = new URLSearchParams(searchParams?.toString() ?? '');
if (e.target.value) {
next.set(paramKey, e.target.value);
} else {
next.delete(paramKey);
}
startTransition(() => {
router.replace(`?${next.toString()}`, { scroll: false });
});
const next = e.target.value;
setInputValue(next);

if (debounceRef.current) clearTimeout(debounceRef.current);
debounceRef.current = setTimeout(() => {
const params = new URLSearchParams(searchParams?.toString() ?? '');
if (next) {
params.set(paramKey, next);
} else {
params.delete(paramKey);
}
// Also reset pagination when search changes
params.delete('page');
startTransition(() => {
router.replace(`?${params.toString()}`, { scroll: false });
});
}, 300);
},
Comment thread apps/admin/app/dashboard/users/page.tsx Outdated
const [, startTransition] = useTransition();

const q = searchParams?.get('q') ?? undefined;
const page = Math.max(0, Number(searchParams?.get('page') ?? '0'));
Comment thread apps/admin/app/dashboard/packs/page.tsx Outdated
const [, startTransition] = useTransition();

const q = searchParams?.get('q') ?? undefined;
const page = Math.max(0, Number(searchParams?.get('page') ?? '0'));
const [, startTransition] = useTransition();

const q = searchParams?.get('q') ?? undefined;
const page = Math.max(0, Number(searchParams?.get('page') ?? '0'));
.update(etlJobs)
.set({ status: 'failed', completedAt: new Date() })
.where(and(eq(etlJobs.status, 'running'), lt(etlJobs.startedAt, threeHoursAgo)))
.returning();
…ey invalidation

- Add nuqs for type-safe URL query state (search, pagination)
- SearchInput simplified to ~10 lines: useQueryState handles debounce (300ms
  throttle), URL sync, and unmount cleanup automatically
- Pagination pages use parseAsInteger — invalid ?page=foo safely defaults to 0
- queryKeys.admin.{users,packs,catalog} restructured to .all (prefix, for
  invalidation) and .list(params) (for useQuery) — fixes post-delete not
  refreshing the list
- catalogAnalytics.etl same pattern: .all for invalidation, .list(limit) for
  queries — fixes ETL table not updating after reset-stuck
- Wire NuqsAdapter into app/layout.tsx
@github-actions github-actions Bot added the dependencies Pull requests that update a dependency file label May 7, 2026
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@apps/admin/app/dashboard/users/page.tsx`:
- Around line 100-114: The page state isn't reset when the search query changes
and negative pages are allowed; replace the separate useQueryState('q'...) and
useQueryState('page'...) usage with a small shared hook (e.g.
usePaginatedSearch) that exposes { q, setSearch, page, setPage } where
setSearch(next) sets q and also sets page to 0, and ensure page is clamped via
page = Math.max(0, rawPage) (to avoid negative offsets); update the users page
to use that hook and call setSearch from the SearchInput on change (and apply
the same change in dashboard/packs/page.tsx and dashboard/catalog/page.tsx) so
queryKeys.admin.users.list and getUsers receive a non-negative page and new
searches reset to page 0.

In `@apps/admin/app/error.tsx`:
- Around line 6-27: The current app/error.tsx defines a component named
GlobalError but lives inside the root layout and therefore cannot catch errors
thrown by app/layout.tsx (so the root providers NuqsAdapter, QueryProvider,
ThemeProvider remain unguarded); rename the component GlobalError to RootError
to reflect its actual scope and update any imports/usages, then add a new
top-level app/global-error.tsx that provides a true global boundary (it must
render <html> and <body>) with a minimal inline fallback UI (avoid importing
components that depend on the crashed providers like Button/@packrat/web-ui) and
expose the reset handler to allow retry; ensure the signature uses the same
props (error, reset) so Next can call reset to recover.

In `@apps/admin/components/analytics/catalog-analytics.tsx`:
- Around line 64-73: The resetStuck mutation (`useMutation` using
`resetStuckEtlJobs`) only handles onSuccess and only shows inline UI when
`resetResult.reset > 0`, so failures and zero-result successes are invisible;
add an `onError` handler to `useMutation` to surface network/500/401 errors (via
a toast or inline error state) and add explicit success feedback when
`resetResult.reset === 0` (e.g., show a “no stuck jobs found” message or toast)
while still keeping `isResetting` to control the spinner; update UI rendering
logic that checks `isResetting`/`resetResult` to display success, zero-result,
and error states and keep `queryClient.invalidateQueries({ queryKey:
queryKeys.catalogAnalytics.etl.all })` on success as-is.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 1925b99d-3851-46b4-b1d2-9d89c4a391f7

📥 Commits

Reviewing files that changed from the base of the PR and between c1f2b9a and 2996849.

⛔ Files ignored due to path filters (1)
  • bun.lock is excluded by !**/*.lock
📒 Files selected for processing (16)
  • apps/admin/app/dashboard/catalog/page.tsx
  • apps/admin/app/dashboard/error.tsx
  • apps/admin/app/dashboard/packs/page.tsx
  • apps/admin/app/dashboard/page.tsx
  • apps/admin/app/dashboard/users/page.tsx
  • apps/admin/app/error.tsx
  • apps/admin/app/layout.tsx
  • apps/admin/components/analytics/catalog-analytics.tsx
  • apps/admin/components/edit-catalog-dialog.tsx
  • apps/admin/components/search-input.tsx
  • apps/admin/hooks/use-catalog-analytics.ts
  • apps/admin/lib/api.ts
  • apps/admin/lib/queryKeys.ts
  • apps/admin/package.json
  • packages/api/scripts/reset-stuck-etl-jobs.sql
  • packages/api/src/routes/admin/analytics/catalog.ts
💤 Files with no reviewable changes (1)
  • packages/api/scripts/reset-stuck-etl-jobs.sql

Comment thread apps/admin/app/dashboard/users/page.tsx Outdated
Comment thread apps/admin/app/error.tsx Outdated
Comment thread apps/admin/components/analytics/catalog-analytics.tsx
- Add global-error.tsx as true root error boundary (with inline html/body)
- Rename RootError in error.tsx (was incorrectly named GlobalError)
- Add usePaginatedSearch hook so search atomically resets page via nuqs
- Wire onSearch={setSearch} on catalog/packs/users pages
- Show "no stuck jobs found" and error state on Reset Stuck ETL button
API: expand all three list endpoints to return full field sets
- users: +avatarUrl, +updatedAt
- packs: +isAIGenerated, +tags, +image, +updatedAt
- catalog: +description, +productUrl, +sku, +model, +ratingValue,
  +reviewCount, +availability, +color, +size, +material, +seller,
  +currency, +images, +variants, +techs, +links

UI:
- Replace hand-rolled error.tsx files with react-error-boundary
  ErrorBoundary in layouts; add shared ErrorFallback component
- Add RawObjectDialog (Braces icon) on every row: users, packs,
  catalog items, ETL jobs — shows full JSON in a scrollable dialog
- Users: avatar thumbnail / initial fallback in User column
- Packs: AI badge, inline tags (up to 3)
- Catalog: Status column with availability + star rating, product
  URL link icon, description/model sub-lines
- ETL table: +Invalid column (red when >0), +Completed column
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@apps/admin/app/dashboard/layout.tsx`:
- Line 19: The ErrorBoundary around ErrorFallback is missing resetKeys so its
fallback can get stuck across route changes; retrieve the current pathname (e.g.
via usePathname from next/navigation) in the layout component and pass it as
resetKeys={[pathname]} to the <ErrorBoundary> (keep ErrorFallback and children
unchanged), and add the import for usePathname if not already present so the
boundary resets on navigation.

In `@apps/admin/app/global-error.tsx`:
- Around line 31-34: Replace the user-visible use of error.message in the
fallback UI: stop rendering {error.message} inside the <p> and always show a
generic message like "An unexpected error occurred." instead; move the detailed
information to logs/telemetry by calling console.error(error) or your
telemetry/reporting function from the error boundary where the error object is
available (i.e., the code that supplies the error used in the <p>), ensuring
only the generic string is rendered to users while error.message and stack are
recorded internally.

In `@apps/admin/components/error-fallback.tsx`:
- Around line 10-12: In the ErrorFallback component (error-fallback.tsx) do not
render raw error.message into the UI; replace the conditional JSX expression
that outputs error.message ({error instanceof Error ? error.message : ...}) with
a generic user-safe string like "Something went wrong" for the paragraph text,
and move the detailed diagnostic (error object or error.message/stack) to a
non-UI channel such as console.error or your telemetry/error-reporting hook
(e.g., call a logError/reportError helper) so internals are not exposed in the
shared fallback UI.

In `@apps/admin/components/raw-object-dialog.tsx`:
- Around line 31-40: Add a Radix DialogDescription inside the DialogContent
(e.g., directly under DialogTitle) to satisfy the aria-describedby requirement:
use the DialogDescription component (alongside existing DialogTitle in
raw-object-dialog.tsx) with a visually hidden text string such as "Raw object
content" or include the dynamic label to describe the dialog, so the warning
goes away while the visible UI remains unchanged.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 84d54899-40d4-44ca-ab77-08760ad94bfc

📥 Commits

Reviewing files that changed from the base of the PR and between 2996849 and d25fca5.

⛔ Files ignored due to path filters (1)
  • bun.lock is excluded by !**/*.lock
📒 Files selected for processing (21)
  • .gitignore
  • apps/admin/app/dashboard/catalog/page.tsx
  • apps/admin/app/dashboard/layout.tsx
  • apps/admin/app/dashboard/packs/page.tsx
  • apps/admin/app/dashboard/page.tsx
  • apps/admin/app/dashboard/users/page.tsx
  • apps/admin/app/error.tsx
  • apps/admin/app/global-error.tsx
  • apps/admin/components/analytics/catalog-analytics.tsx
  • apps/admin/components/edit-catalog-dialog.tsx
  • apps/admin/components/error-fallback.tsx
  • apps/admin/components/raw-object-dialog.tsx
  • apps/admin/components/search-input.tsx
  • apps/admin/hooks/use-catalog-analytics.ts
  • apps/admin/hooks/use-paginated-search.ts
  • apps/admin/hooks/use-platform-analytics.ts
  • apps/admin/lib/api.ts
  • apps/admin/lib/cfAccess.ts
  • apps/admin/lib/queryKeys.ts
  • apps/admin/package.json
  • packages/api/src/routes/admin/index.ts
✅ Files skipped from review due to trivial changes (3)
  • .gitignore
  • apps/admin/package.json
  • apps/admin/app/error.tsx
🚧 Files skipped from review as they are similar to previous changes (9)
  • apps/admin/components/edit-catalog-dialog.tsx
  • apps/admin/components/search-input.tsx
  • apps/admin/app/dashboard/page.tsx
  • apps/admin/app/dashboard/packs/page.tsx
  • apps/admin/components/analytics/catalog-analytics.tsx
  • apps/admin/lib/api.ts
  • apps/admin/app/dashboard/catalog/page.tsx
  • apps/admin/app/dashboard/users/page.tsx
  • apps/admin/lib/queryKeys.ts

Comment thread apps/admin/app/dashboard/layout.tsx Outdated
Comment thread apps/admin/app/global-error.tsx
Comment thread apps/admin/components/error-fallback.tsx Outdated
Comment thread apps/admin/components/raw-object-dialog.tsx
- ErrorBoundary: add resetKeys={[pathname]} so boundary auto-resets
  on route changes instead of keeping fallback across navigation
- error-fallback.tsx + global-error.tsx: stop surfacing raw error.message
  to users; log to console instead
- RawObjectDialog: add visually-hidden DialogDescription to silence
  Radix UI aria-describedby warning
- Note: .returning({ id }) on reset-stuck blocked by Drizzle TS types
  in this version; full .returning() retained
@andrew-bierman andrew-bierman merged commit 585bfdd into main May 7, 2026
11 checks passed
@andrew-bierman andrew-bierman deleted the fix/etl-memory-and-weight-validation-v2 branch May 7, 2026 23:26
andrew-bierman added a commit that referenced this pull request May 14, 2026
- Add global-error.tsx as true root error boundary (with inline html/body)
- Rename RootError in error.tsx (was incorrectly named GlobalError)
- Add usePaginatedSearch hook so search atomically resets page via nuqs
- Wire onSearch={setSearch} on catalog/packs/users pages
- Show "no stuck jobs found" and error state on Reset Stuck ETL button
andrew-bierman added a commit that referenced this pull request May 14, 2026
…lidation-v2

feat(admin): pagination, search debounce, reset-stuck UI, error boundaries
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

api dependencies Pull requests that update a dependency file

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants