Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/luisumit/LaPreviaRestobar/llms.txt

Use this file to discover all available pages before exploring further.

La Previa Restobar uses a role-based access model enforced at authentication time. Once a user signs in through Firebase Authentication, their role is resolved from Firestore and stored in LoginViewModel. The root AppNavigation composable then reads the role from LoginViewModel.userRole and immediately routes the user to the correct top-level destination — waiter_main, chef_main, or admin_main — clearing the back stack so the login screen cannot be revisited. All routes are defined in a single NavHost inside AppNavigation; each destination is protected so that if the authenticated role does not match the route, the user is redirected back to login.

The UserRole Sealed Class

Roles are modelled as a Kotlin sealed class so that when expressions are exhaustive by default and no string comparison is needed at runtime outside of Firebase deserialization.
sealed class UserRole {
    object MESERO   : UserRole()
    object COCINERO : UserRole()
    object ADMIN    : UserRole()

    val name: String
        get() = when (this) {
            is MESERO   -> "MESERO"
            is COCINERO -> "COCINERO"
            is ADMIN    -> "ADMIN"
        }

    override fun toString(): String = name
}

fromString() — Deserializing from Firestore

When the user document is fetched from Firestore, the role field arrives as a plain string. fromString() converts it back to the sealed class, defaulting to MESERO if the value is unrecognised.
companion object {
    fun fromString(value: String): UserRole {
        return when (value.uppercase()) {
            "MESERO"   -> MESERO
            "COCINERO" -> COCINERO
            "ADMIN"    -> ADMIN
            else       -> MESERO // default fallback
        }
    }
}
The else -> MESERO fallback in fromString() means a missing or misspelled role field in Firestore will silently grant waiter-level access rather than blocking login. Ensure Firestore user documents always include a valid role field.

Login to Role Routing

After a successful Firebase sign-in, AppNavigation observes LoginViewModel.userRole via collectAsState() and calls navController.navigate() inside a LaunchedEffect. The popUpTo("login") { inclusive = true } block ensures the login screen is removed from the back stack.
LaunchedEffect(currentUser, userRole) {
    if (currentUser != null && userRole != null) {
        when (userRole) {
            UserRole.MESERO   -> navController.navigate("waiter_main") {
                                    popUpTo("login") { inclusive = true } }
            UserRole.COCINERO -> navController.navigate("chef_main") {
                                    popUpTo("login") { inclusive = true } }
            UserRole.ADMIN    -> navController.navigate("admin_main") {
                                    popUpTo("login") { inclusive = true } }
            else -> isAuthenticated = false
        }
    }
}
The login screen itself renders three animated role cards — one per UserRole variant. Tapping a card calls viewModel.selectRole(role), which transitions the LoginUiState to RoleSelected and displays an EmailLoginForm pre-labeled with the chosen role.

Role Comparison

PropertyMesero (Waiter)Cocinero (Chef)Admin
Routewaiter_mainchef_mainadmin_main
ViewModelWaiterViewModelChefViewModelAdminViewModel
Primary jobTable and order managementKitchen queue and status updatesProduct catalog and operations
ScreensTables, TableDetails, Products, Orders, InventoryOrders (kitchen queue), InventoryDashboard, Reports, Products, QR
NotificationsNotificationPanel — order status changes from chefChefNotificationPanel — new orders and cancellationsAdminStockWorker — low-stock and out-of-stock alerts
Offline supportRoom cache + pending sync via SyncManagerRoom cache + SyncManager.syncOrders()Room cache + SyncManager.syncProducts()

Individual Role Pages

Waiter

Tables grid, product catalog, order builder, and live order tracker driven by WaiterViewModel.

Chef

Kitchen order queue with status progression from ENVIADO to LISTO, plus ingredient inventory view.

Admin

Full product CRUD via ProductFormDialog, sales reports, QR menu, and scheduled low-stock notifications.

Build docs developers (and LLMs) love