Skip to content

feat: admin console (document verification, users, audit log) + query cache tuning and Lighthouse CI (#685, #714, #715, #716) - #820

Merged
amina69 merged 3 commits into
amina69:mainfrom
lockoabosede8-byte:feat/admin-console-and-query-perf
Oct 26, 2026
Merged

amina69 merged 3 commits into
amina69:mainfrom
lockoabosede8-byte:feat/admin-console-and-query-perf

Conversation

@lockoabosede8-byte

Copy link
Copy Markdown
Contributor

Summary

Delivers four Phase 3 backlog items in one PR: the query-cache/Lighthouse performance work and the three admin console pages.

Closes #685
Closes #714
Closes #715
Closes #716


#685 — Query cache tuning and Lighthouse budget

  • src/lib/staleTime.ts: one documented STALE_TIME policy per domain: pets 5 min, approvals 1 min, notifications live (0), documents refetch on focus, timelines 30 s, disputes 15 s.
  • Every query hook now takes its staleTime from that table and carries a one-line comment justifying it (useApprovalList/Detail, useNotifications, useUnreadNotificationCount, useDisputes/Detail, usePendingApprovalsCount, useEscrowStatus, useAdoptionTimeline, useEscrowTimeline, useCustody*, useSettlementSummary, useNotificationPreferences, usePolling, document and approval-history queries, the notification dropdown).
  • Prefetch on hover: PetCard calls prefetchPetDetail(id) on mouse-enter and focus (src/lib/prefetchPet.ts, petService.getPet), so detail opens from cache. Prefetch is best-effort and never throws.
  • Lighthouse CI: lighthouserc.js plus .github/workflows/lighthouse.yml run on every PR against the production build and fail if mobile performance < 85 or LCP >= 2.5 s on /listings.

#714 — Document verification queue (/admin/documents)

  • DocumentVerificationPage shows the queue of pending documents in DocumentPreviewModal with Verify and Reject. Reject reuses RejectionReasonModal, so a reason is required and is stored as the document's rejectionReason for the uploader.
  • useVerifyDocument fetches the queue and exposes decide. On success the decided document is removed from the cache immediately, so the next document loads automatically.
  • Shortcuts: J/K prev/next, V verify, documented in a help popover. isTypingTarget and the open reject dialog both suppress them, so they never fire while a text field is focused.

#715 — User management (/admin/users)

  • Searchable user table; the search term is debounced (useDebouncedValue, 300 ms).
  • UserDetailDrawer shows profile, role, activity counts and recent disputes. Actions:
    • Suspend requires a reason and shows a success toast; Reinstate.
    • Change role goes through a confirmation that names the target role.
  • An admin cannot change their own role: the control is disabled with a tooltip and visible explanatory text.

#716 — Audit log viewer (/admin/audit-log)

  • Read-only table filtered by actor, action and date range (new DateRangePicker); each row expands to the formatted metadata JSON.
  • Metadata is rendered as a React text node, so <script> is inert text.
  • CSV export of the current filtered view (client-side, for the loaded page). src/utils/csv.ts neutralises cells starting with =, +, -, @ (and tab/CR) with a leading ', and quotes per RFC 4180.

Supporting additions

Admin pages are wrapped in AdminOnly (access-denied for non-admins). The issues depend on components that don't exist in this repo yet (DateRangePicker, DocumentPreviewModal, debounce), so minimal versions are included. ConfirmationModal serves as the confirm dialog. New API surface lives in src/api/adminService.ts and documentService.getPendingDocuments.

Backend contract assumed

GET /documents?status=pending, GET /admin/users?search=, GET /admin/users/:id, POST /admin/users/:id/suspend {reason}, POST /admin/users/:id/reinstate, PATCH /admin/users/:id/role {role}, GET /admin/audit-log?actor&action&from&to. Please confirm these against the backend; they're isolated in two service files. The current user's id is read from localStorage["petad_user_id"] for the self-role check.

Testing

  • New: 11 tests in src/pages/admin/__tests__ and src/utils/__tests__ covering each acceptance criterion (inert <script>, CSV neutralisation, shortcuts not firing while typing, auto-advance, self-role disabled with tooltip, suspension requires a reason, role confirmation names the target).
  • tsc -b and eslint src are clean.
  • Full suite: all pass except mockNotificationStream.test.ts ("emits a well-formed envelope…"), which also fails on unmodified main and is unrelated.
  • Not verified locally: the Lighthouse workflow (runs on this PR) and the MSW dev handlers for the new admin endpoints (not added).

@vercel

vercel Bot commented Oct 22, 2026

Copy link
Copy Markdown

@Hollujay is attempting to deploy a commit to the sheriffamina1-9497's projects Team on Vercel.

A member of the Team first needs to authorize it.

@drips-wave

drips-wave Bot commented Oct 22, 2026

Copy link
Copy Markdown

@lockoabosede8-byte Great news! 🎉 Based on an automated assessment of this PR, the linked Wave issue(s) no longer count against your application limits.

You can now already apply to more issues while waiting for a review of this PR. Keep up the great work! 🚀

Learn more about application limits

@amina69

amina69 commented Oct 22, 2026

Copy link
Copy Markdown
Owner

@lockoabosede8-byte kindly fix the conflict

Resolve import conflicts in App.tsx and ApprovalHistoryTab.tsx by keeping both
the admin console / STALE_TIME imports and upstream's new imports.
@amina69
amina69 merged commit 05343fe into amina69:main Oct 26, 2026
3 of 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.

[109] Audit log viewer [108] User management list and detail [107] Document verification queue [090] Query cache tuning and Lighthouse budget

3 participants