Authentication & Roles
Better Auth (Google OAuth) and the six-tier RBAC model.
Authentication & Roles
Better Auth + Google OAuth
Authentication uses Better Auth with Google OAuth as the only sign-in
method. Sessions are stored in Neon (HttpOnly, Secure, SameSite=Lax cookies).
The auth routes are mounted at /api/auth/[...all].
First sign-in routes a new user to /onboarding to collect phone, DOB, gender,
and consents; POST /api/onboarding/complete finalises the profile. UTM and
booking context survive the OAuth redirect via sessionStorage.
RBAC — six roles
Roles are hierarchical: a higher role satisfies any lower-role requirement.
| Role | Level | Typical access |
|---|---|---|
customer | 0 | Own bookings, profile, gems, membership |
staff | 1 | Own schedule + leave (admin.theroyalglow.in/me/*) |
receptionist | 2 | Bookings, customers, leads, billing |
manager | 3 | + services, offers, staff, schedule, reports |
owner | 4 | + users, branches |
developer | 5 | + integrations, logs |
Enforcing access in API routes
Two helpers guard server routes:
import { requireSession, requireRole } from '@/lib/api/session'
// Any signed-in user
const session = await requireSession()
// Minimum role (throws 403 FORBIDDEN if below)
const session = await requireRole('receptionist')requireSession()throws401 UNAUTHENTICATEDwhen there is no session.requireRole(minRole)throws403 FORBIDDENwhen the user's role level is below the required minimum.
Each API page in the reference notes the minimum role for every endpoint.
Route → role guidance
Customer endpoints live on theroyalglow.in; admin endpoints live on the
admin.theroyalglow.in subdomain at root paths (there is no /api/admin/
segment — the subdomain is the namespace).
| Route group | Minimum role |
|---|---|
theroyalglow.in/api/bookings, /api/membership, /api/gems, /api/notifications | customer |
admin.theroyalglow.in/api/me/* (own schedule + leave) | staff |
admin.theroyalglow.in/api/bookings, /api/customers, /api/leads, /api/billing, /api/memberships | receptionist |
admin.theroyalglow.in/api/services, /api/offers, /api/staff, /api/schedule, /api/reports | manager |
admin.theroyalglow.in/api/users, /api/branches | owner |
admin.theroyalglow.in/api/integrations, /api/logs | developer |
Public (no auth) customer endpoints: GET theroyalglow.in/api/services,
GET /api/services/[slug], GET /api/availability, POST /api/leads,
GET /api/health.
Was this page helpful?