Authentication
Staccato uses Supabase Auth with multiple sign-in methods and a role-based access system.
Sign-In Methods
| Method | Implementation | Notes |
|---|---|---|
| Email/Password | AuthService.signIn(email:password:) | Default, always available |
| Apple Sign In | Native ASAuthorizationController → Supabase | Required for App Store |
| Google OAuth | Supabase OAuth redirect | Opens in-app browser |
Auth Flows
Role System
Three roles defined in the profiles table:
| Role | Access | Tabs |
|---|---|---|
customer | Menu, orders, loyalty, rewards | Home, Order, Rewards, Account |
employee | All customer features + order queue + menu availability | + Orders tab |
admin | All employee features + analytics + menu management | + Analytics tab |
Roles are checked via computed properties on Profile:
struct Profile: Codable {
let role: UserRole
var isStaff: Bool {
role == .employee || role == .admin
}
var isAdmin: Bool {
role == .admin
}
}
enum UserRole: String, Codable {
case customer
case employee
case admin
}Session Management
- Sessions are managed by
SupabaseManagersingleton AuthViewModelobserves auth state changes viaAuthService.observeAuthStateChanges()- On session restore, profile and loyalty data are loaded automatically
- OAuth callback URL:
staccatocoffee://auth/callback(configured inInfo.plist)
Profile Auto-Creation
When a new user signs up, a database trigger automatically creates a profiles row:
CREATE TRIGGER on_auth_user_created
AFTER INSERT ON auth.users
FOR EACH ROW EXECUTE FUNCTION handle_new_user();The function copies the user’s email and full name from auth metadata into the profiles table with the default customer role.
Promoting Users
Staff and admin roles are assigned via SQL (there is no self-service promotion):
UPDATE profiles SET role = 'employee' WHERE id = 'user-uuid';
UPDATE profiles SET role = 'admin' WHERE id = 'user-uuid';