Repository navigation
Read-only bug tester role for QA - #465
Conversation
Add a "bug_tester" staff role so people can test the admin side without being able to change anything. - isStaffRole is now an allow-list (super_admin, admin, moderator) instead of "anything but volunteer", so a new role can never become full staff by default - isAdmin lets a bug tester through for queries only; any mutation behind it (and isSuperAdmin, built on it) is refused with a read-only message. isScanner does the same, so the scan desks are viewable but nothing can be checked in - callerIsAdmin stays staff-only: bug testers get no widened public responses and cannot act on other leaders' initiatives - resume and bootcamp file routes use isStaffRole, so bug testers cannot download resumes - portal: bug testers see the admin nav (minus the staff-only Staff & Roles and project-lead pages) with a read-only banner; super admins can grant the role from Staff & Roles Every admin query was checked for writes before allowing them; none write. Tests cover queries allowed, mutations refused (full staff, super admin and scanner) and the nav.
The API already refuses every write from a bug tester; the admin UI now says so instead of letting the click fail silently. useReadOnly() is true only for a bug tester, and every control whose purpose is a write (create, save, delete, toggles, check-in, scanning, sending, judging and results controls, membership grants, uploads) renders disabled with a "Read-only access" tooltip. Reads stay usable: tabs, filters, search, pagination, exports, QR viewing and opening detail views. Enter-to-submit on the manual check-in fields is guarded too. The banner copy now says buttons are greyed out.
Dependency Review✅ No vulnerabilities or license issues or OpenSSF Scorecard issues found.Scanned FilesNone |
|
Visit the preview URL for this PR (updated for commit 0f5579c): https://hacklytics2027--pr-465-3z6qj5gp.web.app (expires Mon, 12 Oct 2026 00:50:54 GMT) 🔥 via Firebase Hosting GitHub Action 🌎 Sign: c48ba34db61581e25fe2978355160b5eefe0e83f |
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes using default effort and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit 0f5579c. Configure here.
| // edition exists behind a door they cannot open is the whole leak, and the | ||
| // query is disabled for them anyway, so waiting on it spun forever. | ||
| if (!portalContext?.isAdmin) { | ||
| if (!canViewAdmin(portalContext)) { |
There was a problem hiding this comment.
Testers cannot load draft editions
Medium Severity
Bug testers are admitted to admin screens via canViewAdmin, but those screens still load data through public procedures that widen only when callerIsAdmin is true. Testers are not staff, so draft or hidden editions that appear on listAll 404 or drop out of the judging picker.
Additional Locations (1)
Reviewed by Cursor Bugbot for commit 0f5579c. Configure here.


Adds a
bug_testerrole: people who can open every admin page to test it, but can't change anything.How it's enforced (server side)
isAdminlets a bug tester through for queries only; every mutation behind it, and behindisSuperAdmin, is refused ("Bug testers have read-only access…").isScannerdoes the same.isStaffRoleis now an explicit allow-list (super_admin,admin,moderator). Before, it was "anything but volunteer", so any new role would have been full staff.callerIsAdminstays staff-only, so bug testers get no widened public responses and can't act on other leaders' initiatives.isStaffRole, so bug testers can't download resumes.Portal
No migration:
admin.roleis a text column; the enum is TypeScript-only.Checks:
tsc,eslint --max-warnings 0, vitest 744 passed. New tests cover queries allowed, mutations refused (full staff, super admin, scanner) and the nav; they fail without the middleware change. Verified locally: as a bug tester,/admin/hackathonsloads, and toggling visibility returns 403 with no change.Base: stacked on #462 (
feat/portal-ui-redesign), so the diff shows only the role. Merge #462 first; this PR then retargets to dev.Note
Medium Risk
Changes authorization middleware and portal gating for a new admin tier; enforcement is centralized in
isAdmin/isScanner, with new tests, but any gap in UI-only disables could still surface 403s rather than data loss.Overview
Introduces a
bug_testeradmin role so QA can browse the full admin portal without changing data.API: The role is added to the admin schema and super-admin create/update flows.
isStaffRolebecomes an explicit allow-list (super_admin,admin,moderator) so new roles are not full staff by default.isAdminandisScanneradmit bug testers for queries only and reject all mutations with a shared read-only message;isSuperAdminstill requiressuper_admin. Portal context exposesisBugTesterwhileisAdminstays false for testers;callerIsAdminremains staff-only so testers do not get widened public responses or project-leader powers.Portal:
canViewAdmin/useReadOnlygate page access and disable write controls (with tooltips) across admin pages and components. Bug testers see the admin nav and a read-only banner inAdminLayout, but Staff & Roles and /lead are hidden. The dashboard links them to the admin panel like staff.Tests: New edge tests cover staff queries allowed, mutations (including scan desk) refused, and super-admin queries still blocked.
Reviewed by Cursor Bugbot for commit 0f5579c. Bugbot is set up for automated code reviews on this repo. Configure here.