Auth Helpers Implementation Plan
Context
P0 GAP-01 from AUDIT.md: staffMutation/adminMutation/authenticatedQuery/authenticatedMutation not in convex/auth.ts. These helpers are required by ~14 plans but were never implemented. All plans are marked "completed" but the auth infrastructure they depend on is missing.
Current State
File: packages/backend/convex/lib/auth.ts exists with authedQuery and authedMutation but lacks role-based variants.
Tasks
Task 1: Add role constants and types
Add Role type, STAFF_ROLE, ADMIN_ROLE constants, and AUTH_ERROR_CODE.
Task 2: Implement requireStaffOrAdmin helper
Extracted from existing inline code. Validates user is STAFF or ADMIN role.
Task 3: Implement requireAdmin helper
Validates user is ADMIN role only.
Task 4: Implement staffMutation wrapper
Uses requireStaffOrAdmin + customMutation pattern.
Task 5: Implement adminMutation wrapper
Uses requireAdmin + customMutation pattern.
Task 6: Implement authenticatedQuery wrapper
Renamed from existing authedQuery for clarity.
Task 7: Implement authenticatedMutation wrapper
Renamed from existing authedMutation for clarity.
Task 8: Export all helpers
Update exports in lib/auth.ts and create convex/auth.ts barrel.
Task 9: Update CLAUDE.md documentation
Document the auth helpers pattern for future reference.
Implementation Notes
- Use
customMutation/customQueryfromconvex-helpers/server/customFunctions - Follow existing
authedQuery/authedMutationpattern - Re-export from
convex/auth.tsfor consistency with project structure - All helpers throw
Error("UNAUTHORIZED")on auth failure
Files to Modify
packages/backend/convex/lib/auth.ts- Add new helperspackages/backend/convex/auth.ts- Re-export for conveniencepackages/backend/convex/CLAUDE.md- Document auth helpers
Verification
-
staffMutationthrows UNAUTHORIZED for non-authenticated users -
staffMutationthrows UNAUTHORIZED for non-STAFF/ADMIN users -
staffMutationallows STAFF role -
staffMutationallows ADMIN role -
adminMutationthrows UNAUTHORIZED for non-ADMIN users -
adminMutationallows ADMIN role only -
authenticatedQuerythrows UNAUTHORIZED for unauthenticated users -
authenticatedMutationthrows UNAUTHORIZED for unauthenticated users - All existing tests pass