Skip to content

Add PC processed reports admin page#440

Merged
Producdevity merged 5 commits into
stagingfrom
feat/pc-processed-listings
Jun 8, 2026
Merged

Add PC processed reports admin page#440
Producdevity merged 5 commits into
stagingfrom
feat/pc-processed-listings

Conversation

@Producdevity

@Producdevity Producdevity commented Jun 8, 2026

Copy link
Copy Markdown
Owner

Description

Adds the missing PC processed reports admin flow and keeps it aligned with the existing handheld processed reports page.

  • adds a PC processed reports admin route
  • adds pcListings.getProcessed with status filtering, search, sorting, and pagination
  • shares the processed reports admin UI between handheld and PC reports
  • keeps override, reset-to-pending, trust, notifications, and cache invalidation behavior aligned between handheld and PC reports
  • removes the old handheld-only override modal in favor of the shared admin component
  • includes the existing branch cleanups for the verify button, analytics dataLayer warning, RetroCatalog cache/error handling, and DB backup script

Fixes #379

Type of change

  • Bug fix
  • New feature
  • Breaking change
  • Documentation update
  • Refactor
  • Other (please describe):

How Has This Been Tested?

  • Local build
  • Lint
  • Typecheck
  • Unit tests
  • Manual testing

Ran:

pnpm lint
pnpm types
pnpm test
git diff --check origin/staging...HEAD

pnpm lint completed with 0 errors. The existing React Compiler warnings are still present.

Screenshots (if applicable)

N/A

Checklist

  • My code follows the style guidelines of this project
  • I have performed a self-review of my code
  • I have made corresponding changes to the documentation
  • I have checked that all checks (lint, typecheck, test) pass

Notes for reviewers

This keeps the shared processed reports UI under src/app/admin/components/processed-reports because it is admin-only UI shared by two admin routes. It does not move this into features.

Summary by CodeRabbit

  • New Features

    • Added admin interface for viewing and managing processed PC reports with filtering, sorting, and pagination capabilities.
    • Added status override functionality to change report approval decisions.
  • Bug Fixes

    • Improved API response caching behavior for RetroCatalog lookups.
    • Fixed analytics data layer initialization.
  • Chores

    • Refactored database backup script with improved validation and reliability.
    • Removed Supabase-specific backup script variant.
    • Updated admin notification event handling.

@vercel

vercel Bot commented Jun 8, 2026

Copy link
Copy Markdown

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

Project Deployment Actions Updated (UTC)
emuready Ready Ready Preview, Comment Jun 8, 2026 11:48am

Request Review

@coderabbitai

coderabbitai Bot commented Jun 8, 2026

Copy link
Copy Markdown

Review Change Stack

Walkthrough

This PR introduces a reusable processed-reports admin component suite and integrates it into both PC and handheld processed-listings pages. It adds PC listings router support for viewing and overriding processed reports, updates handheld admin router for trust actions and new notification patterns, and includes analytics, caching, and database script improvements.

Changes

Processed Reports Admin System

Layer / File(s) Summary
Processed Reports Types & PC Schema
src/app/admin/components/processed-reports/types.ts, src/schemas/pcListing.ts
Defines generic types for processed-reports admin UI (pagination, stats, user, hardware columns, accessors, override payloads) and extends PC listing schemas with nullable filters and expanded sort fields.
Reusable Processed Reports Components
src/app/admin/components/processed-reports/ApprovalStatusOverrideModal.tsx, ProcessedReportsAdminPage.tsx, ProcessedReportsTable.tsx, index.ts
Implements generic React components for approval-status overrides, search/filter/pagination, and sortable report tables. Modal conditionally renders notes textarea or informational message based on target status; page wires table state and override flow; table renders rows with permission-gated action buttons.
PC Processed Listings Page
src/app/admin/pc-processed-listings/page.tsx
Implements PC-specific page by configuring CPU/GPU hardware columns, mapping PC listing fields to generic accessors, wiring TRPC queries with pagination/sort/search/status filtering, and routing override mutations through resetToPending or overrideStatus.
Handheld Processed Listings Refactoring
src/app/admin/processed-listings/page.tsx, components/OverrideStatusModal.tsx (removed)
Refactors handheld page to replace handcrafted UI and modal with the generic ProcessedReportsAdminPage, consolidates query/mutation handling, and reroutes override logic through the same mutation pattern.
Admin Navigation & Routes
src/app/admin/config/routes.ts, src/app/admin/components/AdminNavIcon.tsx, src/app/admin/data.ts, src/app/admin/components/AdminQuickNavigation.tsx, src/app/admin/dashboard/AdminDashboard.tsx
Adds PC_PROCESSED_LISTINGS route, updates handheld nav label to "Processed Reports", adds FileText icon for PC route, renames QuickNavigation to AdminQuickNavigation.
PC Router: getProcessed Query
src/server/api/routers/pcListings.ts (lines 753–894), src/server/api/routers/pcListings.test.ts (lines 857–907)
Adds super-admin getProcessed procedure supporting pagination, status filtering, multi-field search, and processed-specific sorting; test verifies Prisma query shape and pagination behavior.
PC Router: overrideStatus Mutation
src/server/api/routers/pcListings.ts (lines 753–894), src/server/api/routers/pcListings.test.ts (lines 909–1009)
Introduces overrideStatus super-admin mutation to change approval status, manage processed metadata (cleared on PENDING, set for others), invalidate listing SEO, emit trust actions via getProcessedStatusTrustAction, and send approval/rejection notifications; bulkApprove now uses shared timestamp and includes bulk flag in notifications.
Handheld Admin Router Enhancements
src/server/api/routers/listings/admin.ts (lines 352–537)
Updates resetToPending to invalidate SEO and device cache when resetting from APPROVED; expands getProcessed search to include system/device/emulator relations; reworks overrideStatus to conditionally clear/set processor metadata, apply trust actions, and emit APPROVED/REJECTED notifications instead of generic override event.
Admin Router Test Coverage
src/server/api/routers/listings/admin.test.ts (lines 269–499)
Adds test suites for processed listings getProcessed (search/filter), overrideStatus (to rejected and to pending), and resetToPending, with assertions for metadata, trust actions, and notification emission.
Trust Action & Notification Updates
src/server/api/utils/processedStatusTrust.ts, src/server/notifications/eventEmitter.ts, src/server/notifications/service.ts
Introduces getProcessedStatusTrustAction utility deriving trust actions from approval-status transitions. Removes LISTING_STATUS_OVERRIDDEN event. Updates NotificationService to skip unmapped events.
PC Listing Helpers
src/server/api/utils/pcListingHelpers.ts
Adds ProcessedPcListingSortField type and buildProcessedPcListingOrderBy helper generating Prisma orderBy for processed PC listings with proper defaults and multi-field CPU/GPU ordering.
Google Analytics Data Layer
src/lib/analytics/utils/sendAnalyticsEvent.ts, src/lib/analytics/utils/sendAnalyticsEvent.test.ts
Introduces ensureGoogleAnalyticsDataLayer helper that initializes window.dataLayer when missing; adds test coverage for dataLayer state management.
Retrocatalog Caching
src/app/api/retrocatalog/[brandName]/[modelName]/route.ts, route.test.ts
Updates retrocatalog route to disable caching (no-store) for empty responses and upstream fetch; adds array validation; adds comprehensive cache-header test coverage.
Component & Feature Updates
src/components/verify/GenericVerifyButton.tsx, src/components/retrocatalog/RetroCatalogButton.tsx, src/data/storageKeys.ts, src/app/layout.tsx
Refactors GenericVerifyButton with early-return patterns for PC/handheld verification; reformats RetroCatalogButton; reorders GoogleAnalytics in layout; updates storage keys for admin column visibility.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

  • Producdevity/EmuReady#339: Intertwined trust-system overhaul affecting admin override/trust-action logic in both listings and PC listings routers.
  • Producdevity/EmuReady#362: Introduces SEO and cache invalidation helpers directly used by the new processed-status override flows in both router implementations.
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 6.90% 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
Title check ✅ Passed The title 'Add PC processed reports admin page' directly describes the main feature added: a new admin page for PC processed reports, which is the primary objective.
Description check ✅ Passed The description provides comprehensive coverage of changes including objectives, type of change, testing performed, and checklist completion, with detailed notes for reviewers.
Linked Issues check ✅ Passed All requirements from issue #379 are implemented: getProcessed router procedure added [pcListings.ts], PC processed-listings page created [pc-processed-listings/page.tsx], and GetProcessedPcSchema extended with sortField/sortDirection [pcListing.ts].
Out of Scope Changes check ✅ Passed The PR includes cleanup changes (verify button refactoring, analytics dataLayer, RetroCatalog caching, DB backup scripts) that are documented in the description as 'existing branch cleanups' aligned with the feature work.

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

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/pc-processed-listings
✨ Simplify code
  • Create PR with simplified code
  • Commit simplified code in branch feat/pc-processed-listings

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.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🧹 Nitpick comments (3)
src/data/storageKeys.ts (1)

40-41: 💤 Low value

Storage key rename will reset user preferences.

Renaming adminProcessedListings from admin_processed_listings_column_visibility to admin_processed_reports_column_visibility will cause existing users to lose their saved column visibility settings for the handheld processed listings admin page. This is acceptable as part of the refactoring but worth noting.

🤖 Prompt for 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.

In `@src/data/storageKeys.ts` around lines 40 - 41, The constant
adminProcessedListings was renamed to use key string
admin_processed_reports_column_visibility which will reset existing users' saved
preferences; to avoid data loss, update the storage key handling so that on
read/write the code first checks for the old key
admin_processed_listings_column_visibility (or migrates it) and copies its value
to the new key, or alternatively revert the value used in adminProcessedListings
back to the previous string; refer to the adminProcessedListings and
adminPcProcessedListings constants and the PREFIX symbol to locate the change
and implement the migration/read-fallback logic.
src/app/admin/components/processed-reports/ProcessedReportsTable.tsx (1)

166-166: 💤 Low value

Internal component props interface naming.

The guideline specifies that component props interfaces should be named Props. However, since ProcessedReportRow is an internal helper (not exported) and naming it Props would conflict with the outer component's interface, RowProps is acceptable here.

🤖 Prompt for 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.

In `@src/app/admin/components/processed-reports/ProcessedReportsTable.tsx` at line
166, The interface name RowProps for the internal helper component
ProcessedReportRow is acceptable to avoid clashing with the outer component's
Props; leave RowProps as-is and add a short inline comment above the interface
(mentioning ProcessedReportRow) indicating it's intentionally named differently
to avoid export/name conflicts so future maintainers understand the rationale.

Source: Learnings

src/server/api/utils/processedStatusTrust.ts (1)

14-27: 💤 Low value

Add explicit default case for future-proofing.

The switch statement lacks a default case. If ApprovalStatus is extended with a new value, the function would return undefined instead of null, which could cause subtle bugs in callers that check for truthiness.

🛡️ Suggested defensive addition
   switch (input.newStatus) {
     case ApprovalStatus.APPROVED:
       return { userId: input.authorId, action: TrustAction.LISTING_APPROVED }
     case ApprovalStatus.REJECTED:
       return { userId: input.authorId, action: TrustAction.LISTING_REJECTED }
     case ApprovalStatus.PENDING:
       return null
+    default:
+      return null
   }
 }
🤖 Prompt for 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.

In `@src/server/api/utils/processedStatusTrust.ts` around lines 14 - 27, The
switch in getProcessedStatusTrustAction can return undefined if ApprovalStatus
gains new values; update the switch over ApprovalStatus to include an explicit
default case that returns null (or add a final return null after the switch) so
the function always returns a ProcessedStatusTrustAction | null; reference
ApprovalStatus cases (APPROVED, REJECTED, PENDING) and ensure unknown enums fall
through to null to maintain the declared return type.
🤖 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.

Nitpick comments:
In `@src/app/admin/components/processed-reports/ProcessedReportsTable.tsx`:
- Line 166: The interface name RowProps for the internal helper component
ProcessedReportRow is acceptable to avoid clashing with the outer component's
Props; leave RowProps as-is and add a short inline comment above the interface
(mentioning ProcessedReportRow) indicating it's intentionally named differently
to avoid export/name conflicts so future maintainers understand the rationale.

In `@src/data/storageKeys.ts`:
- Around line 40-41: The constant adminProcessedListings was renamed to use key
string admin_processed_reports_column_visibility which will reset existing
users' saved preferences; to avoid data loss, update the storage key handling so
that on read/write the code first checks for the old key
admin_processed_listings_column_visibility (or migrates it) and copies its value
to the new key, or alternatively revert the value used in adminProcessedListings
back to the previous string; refer to the adminProcessedListings and
adminPcProcessedListings constants and the PREFIX symbol to locate the change
and implement the migration/read-fallback logic.

In `@src/server/api/utils/processedStatusTrust.ts`:
- Around line 14-27: The switch in getProcessedStatusTrustAction can return
undefined if ApprovalStatus gains new values; update the switch over
ApprovalStatus to include an explicit default case that returns null (or add a
final return null after the switch) so the function always returns a
ProcessedStatusTrustAction | null; reference ApprovalStatus cases (APPROVED,
REJECTED, PENDING) and ensure unknown enums fall through to null to maintain the
declared return type.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 4ee7f0b1-f5e1-461a-8156-b6139df64dd1

📥 Commits

Reviewing files that changed from the base of the PR and between 24639ef and 446bde7.

📒 Files selected for processing (33)
  • package.json
  • scripts/db-backup-supabase.sh
  • scripts/db-backup.sh
  • src/app/admin/components/AdminNavIcon.tsx
  • src/app/admin/components/AdminQuickNavigation.tsx
  • src/app/admin/components/processed-reports/ApprovalStatusOverrideModal.tsx
  • src/app/admin/components/processed-reports/ProcessedReportsAdminPage.tsx
  • src/app/admin/components/processed-reports/ProcessedReportsTable.tsx
  • src/app/admin/components/processed-reports/index.ts
  • src/app/admin/components/processed-reports/types.ts
  • src/app/admin/config/routes.ts
  • src/app/admin/dashboard/AdminDashboard.tsx
  • src/app/admin/data.ts
  • src/app/admin/pc-processed-listings/page.tsx
  • src/app/admin/processed-listings/components/OverrideStatusModal.tsx
  • src/app/admin/processed-listings/page.tsx
  • src/app/api/retrocatalog/[brandName]/[modelName]/route.test.ts
  • src/app/api/retrocatalog/[brandName]/[modelName]/route.ts
  • src/app/layout.tsx
  • src/components/retrocatalog/RetroCatalogButton.tsx
  • src/components/verify/GenericVerifyButton.tsx
  • src/data/storageKeys.ts
  • src/lib/analytics/utils/sendAnalyticsEvent.test.ts
  • src/lib/analytics/utils/sendAnalyticsEvent.ts
  • src/schemas/pcListing.ts
  • src/server/api/routers/listings/admin.test.ts
  • src/server/api/routers/listings/admin.ts
  • src/server/api/routers/pcListings.test.ts
  • src/server/api/routers/pcListings.ts
  • src/server/api/utils/pcListingHelpers.ts
  • src/server/api/utils/processedStatusTrust.ts
  • src/server/notifications/eventEmitter.ts
  • src/server/notifications/service.ts
💤 Files with no reviewable changes (4)
  • scripts/db-backup-supabase.sh
  • src/server/notifications/eventEmitter.ts
  • src/app/admin/processed-listings/components/OverrideStatusModal.tsx
  • package.json

@Producdevity Producdevity merged commit be26f58 into staging Jun 8, 2026
9 checks passed
@Producdevity Producdevity deleted the feat/pc-processed-listings branch June 8, 2026 12:11
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.

feat: implement PC admin processed-listings page for parity with handheld

1 participant