ArchitectureAuthentication

Authentication

Staccato uses Supabase Auth with multiple sign-in methods and a role-based access system.

Sign-In Methods

MethodImplementationNotes
Email/PasswordAuthService.signIn(email:password:)Default, always available
Apple Sign InNative ASAuthorizationController → SupabaseRequired for App Store
Google OAuthSupabase OAuth redirectOpens in-app browser

Auth Flows

Role System

Three roles defined in the profiles table:

RoleAccessTabs
customerMenu, orders, loyalty, rewardsHome, Order, Rewards, Account
employeeAll customer features + order queue + menu availability+ Orders tab
adminAll 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 SupabaseManager singleton
  • AuthViewModel observes auth state changes via AuthService.observeAuthStateChanges()
  • On session restore, profile and loyalty data are loaded automatically
  • OAuth callback URL: staccatocoffee://auth/callback (configured in Info.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';