Skip to content

Read-only bug tester role for QA - #465

Merged
aamoghS merged 2 commits into
feat/portal-ui-redesignfrom
feat/qa-role
Oct 5, 2026
Merged

aamoghS merged 2 commits into
feat/portal-ui-redesignfrom
feat/qa-role

Conversation

@github-actions

@github-actions github-actions Bot commented Oct 5, 2026 •

Copy link
Copy Markdown
Contributor

Adds a bug_tester role: people who can open every admin page to test it, but can't change anything.

How it's enforced (server side)

  • isAdmin lets a bug tester through for queries only; every mutation behind it, and behind isSuperAdmin, is refused ("Bug testers have read-only access…"). isScanner does the same.
  • isStaffRole is now an explicit allow-list (super_admin, admin, moderator). Before, it was "anything but volunteer", so any new role would have been full staff.
  • callerIsAdmin stays staff-only, so bug testers get no widened public responses and can't act on other leaders' initiatives.
  • Resume and bootcamp file routes use isStaffRole, so bug testers can't download resumes.
  • Every admin query was checked for writes first; none write.

Portal

  • Bug testers see the admin nav with a read-only banner. Staff & Roles and the project-lead pages are hidden, because their queries refuse non-staff.
  • Super admins grant the role from Staff & Roles ("Bug tester").
  • Every write control (create, save, delete, toggles, check-in, scanning, sending, judging/results, membership grants, uploads) is greyed out with a "Read-only access" tooltip. Reads stay usable: tabs, filters, search, pagination, exports, QR viewing, detail views.

No migration: admin.role is 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/hackathons loads, 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_tester admin 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. isStaffRole becomes an explicit allow-list (super_admin, admin, moderator) so new roles are not full staff by default. isAdmin and isScanner admit bug testers for queries only and reject all mutations with a shared read-only message; isSuperAdmin still requires super_admin. Portal context exposes isBugTester while isAdmin stays false for testers; callerIsAdmin remains staff-only so testers do not get widened public responses or project-leader powers.

Portal: canViewAdmin / useReadOnly gate page access and disable write controls (with tooltips) across admin pages and components. Bug testers see the admin nav and a read-only banner in AdminLayout, 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.

@github-actions
github-actions Bot requested a review from aamoghS as a code owner October 5, 2026 00:25
@aamoghS aamoghS changed the title Feature: feat/qa-role to dev Read-only bug tester role for QA Oct 5, 2026

@cursor cursor 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.

Stale Bugbot comment from a previous run.

Comment thread packages/api/src/middleware/procedures.ts
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.
@aamoghS
aamoghS changed the base branch from dev to feat/portal-ui-redesign October 5, 2026 00:48
@github-actions

github-actions Bot commented Oct 5, 2026

Copy link
Copy Markdown
Contributor Author

Dependency Review

✅ No vulnerabilities or license issues or OpenSSF Scorecard issues found.

Scanned Files

None

@github-actions

github-actions Bot commented Oct 5, 2026

Copy link
Copy Markdown
Contributor Author

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

@cursor cursor 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.

Cursor Bugbot has reviewed your changes using default effort and found 1 potential issue.

Fix All in Cursor

❌ 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)) {

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

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)
Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 0f5579c. Configure here.

@aamoghS
aamoghS merged commit 6f12ff8 into feat/portal-ui-redesign Oct 5, 2026
13 of 16 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant