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.

The Chef (Cocinero) dashboard is the kitchen-side counterpart to the waiter interface. It subscribes to Firebase in real time and surfaces every order that waiters have dispatched, grouped by status. Chefs advance orders through a defined lifecycle — accepting, preparing, and marking them ready — and the status changes propagate back to the waiter’s OrdersScreen instantly. The inventory tab gives chefs a read-only view of ingredient stock levels with search and category filtering. ChefMainScreen is reached from AppNavigation once userRole == UserRole.COCINERO is confirmed.

Workflow

1

Receive New Orders

ChefViewModel.setupFirebaseRealtimeUpdates() subscribes to firebaseOrderRepository.listenToNewOrders(). Every incoming ENVIADO order is saved to Room and surfaced in the Nuevas Órdenes section of the kitchen queue. A ChefNotification of type NEW_ORDER is added to the notification queue.
2

Accept the Order

The chef taps Aceptar on the OrderCard, which calls viewModel.acceptOrder(orderId). This sets status = ACEPTADO in both Room and Firebase. At the same time, updateInventoryForOrder() is triggered: for each OrderItem where trackInventory == true, the product’s stock is decremented in Firebase and synced to the InventoryViewModel.
3

Start Preparation

Tapping Comenzar calls viewModel.startOrderPreparation(orderId), setting status = EN_PREPARACION. The order moves from the Aceptadas section to En Preparación.
4

Mark as Ready

Tapping Listo calls viewModel.markOrderAsReady(orderId), setting status = LISTO. The waiter’s OrdersScreen now shows the order in the Listas para servir section, and the waiter receives a ORDER_READY notification.
5

Monitor Inventory

Switching to the INVENTARIO tab renders the InventoryScreen (chef variant) powered by InventoryViewModel. Chefs can search products by name, apply quick filters (All / Out of Stock / Low Stock / Enough Stock), and filter by category to monitor what ingredients are running low before accepting the next order.

Screens

The root screen for the Cocinero role. Contains a Scaffold with a custom Surface top bar showing the app name, a notification bell badge, and a logout button. A ConnectionStatusBannerChefMain card indicates Firebase connectivity state. The body hosts a two-tab TabRowORDENES (index 0) and INVENTARIO (index 1) — and an optional ChefNotificationPanel that slides in when the bell is tapped.

ChefViewModel

ChefViewModel is a @HiltViewModel that manages the kitchen order queue with an offline-first Room cache and Firebase Realtime listeners.

StateFlows

StateFlowTypeDescription
ordersStateFlow<List<Order>>Active kitchen orders (excludes COMPLETED and CANCELLED), deduped by ID
isLoadingStateFlow<Boolean>True while initial Room load or manual sync is in progress
selectedOrderStateFlow<Order?>Currently highlighted order, updated on selectOrder()
isFirebaseConnectedStateFlow<Boolean>Reflects Firebase reachability
isInternetAvailableStateFlow<Boolean>Set by ConnectivityManager.NetworkCallback
errorMessageStateFlow<String?>Ephemeral error banner
successMessageStateFlow<String?>Ephemeral success banner
connectionMessageStateFlow<String?>Ephemeral connectivity banner
notificationsStateFlow<List<ChefNotification>>In-app notification queue, capped at 5 entries

Computed Properties

val newOrdersCount: Int
    get() = _orders.value.count { it.status == OrderStatus.ENVIADO }

val acceptedOrdersCount: Int
    get() = _orders.value.count { it.status == OrderStatus.ACEPTADO }

val inProgressOrdersCount: Int
    get() = _orders.value.count { it.status == OrderStatus.EN_PREPARACION }

val readyOrdersCount: Int
    get() = _orders.value.count { it.status == OrderStatus.LISTO }

val deliveredOrdersCount: Int
    get() = _orders.value.count { it.status == OrderStatus.ENTREGADO }

val totalActiveOrders: Int
    get() = _orders.value.size

Convenience Methods

fun acceptOrder(orderId: String)          { updateOrderStatus(orderId, OrderStatus.ACEPTADO) }
fun startOrderPreparation(orderId: String) { updateOrderStatus(orderId, OrderStatus.EN_PREPARACION) }
fun markOrderAsReady(orderId: String)      { updateOrderStatus(orderId, OrderStatus.LISTO) }
fun completeOrder(orderId: String)         { updateOrderStatus(orderId, OrderStatus.COMPLETED) }
All four delegate to the single updateOrderStatus() method, which validates that the target status is in [ACEPTADO, EN_PREPARACION, LISTO, COMPLETED, CANCELLED] before writing.

Status Update Flow

fun updateOrderStatus(orderId: String, status: OrderStatus) {
    viewModelScope.launch {
        // 1. Write to Room immediately (PENDING) for offline-first
        val entity = db.orderDao().getAll().find { it.id == orderId }
        entity?.let {
            db.orderDao().insert(it.copy(
                status     = status.name,
                updatedAt  = System.currentTimeMillis(),
                syncStatus = "PENDING"
            ))
        }

        // 2. Push to Firebase if online
        if (_isInternetAvailable.value) {
            firebaseOrderRepository.updateOrderStatus(orderId, status.name)
            db.orderDao().updateStatus(orderId, "SYNCED")
        }

        // 3. Decrement inventory when order is ACCEPTED
        if (status == OrderStatus.ACEPTADO && _isInternetAvailable.value) {
            updateInventoryForOrder(orderId)
        }

        // 4. Refresh UI from Room
        refreshOrdersFromRoom()
    }
}
When status == ACEPTADO, updateInventoryForOrder() iterates the order’s items. For each item where trackInventory == true, it fetches the current stock from firebaseProductRepository.getProductStock(), subtracts the ordered quantity, and writes the new value back to both firebaseProductRepository.updateProductStock() and firebaseInventoryRepository.updateStock().

OrderCard and StatusChip

OrderCard (from presentation/screens/chef/components/) renders a single order with:
  • Table number and creation timestamp
  • A StatusChip composable displaying the current OrderStatus as a colour-coded label
  • A collapsible list of OrderItem rows showing quantity, product name, and subtotal
  • A QuickAction button row that is configured per-section
StatusChip maps each OrderStatus to a background colour and display text: ENVIADO → orange / “Enviado”, ACEPTADO → error colour / “Aceptado”, EN_PREPARACION → orange / “En Prep.”, LISTO → green / “Listo”. All other statuses display a neutral “Desconocido” label. QuickAction is a simple data class that bundles the label, target OrderStatus, and button colour:
data class QuickAction(
    val label:  String,
    val status: OrderStatus,
    val color:  Color
)
Example usage in the En Preparación section:
OrderCard(
    order = order,
    onUpdateStatus = { status ->
        when (status) {
            OrderStatus.LISTO -> viewModel.markOrderAsReady(order.id)
            else              -> viewModel.updateOrderStatus(order.id, status)
        }
    },
    quickActions = listOf(
        QuickAction(
            label  = "Listo",
            status = OrderStatus.LISTO,
            color  = SuccessGreen
        )
    )
)

ChefNotificationPanel

ChefNotificationPanel (from presentation/screens/chef/components/) is rendered inline inside ChefMainScreen directly below the top bar when showNotifications == true and notifications.isNotEmpty(). Unlike the waiter’s overlay, it fills the full horizontal width of the screen.
ChefNotificationPanel(
    notifications = notifications,
    onDismissNotification = { notification ->
        chefViewModel.removeNotification(notification)
    },
    onClearAll = {
        chefViewModel.clearAllNotifications()
        showNotifications = false
    },
    modifier = Modifier
        .fillMaxWidth()
        .padding(horizontal = 16.dp, vertical = 8.dp)
)

Notification Types

ChefNotificationTypeTrigger
NEW_ORDERA waiter sends an order with status = ENVIADO
ORDER_ACCEPTEDStatus advances to ACEPTADO
ORDER_IN_PREPARATIONStatus advances to EN_PREPARACION
ORDER_READYStatus advances to LISTO
ORDER_DELIVEREDWaiter marks delivery (ENTREGADO)
ORDER_CANCELLEDA waiter or chef cancels the order
INVENTORY_UPDATEDStock is decremented after order acceptance
Cancellation notifications have an additional guard: _lastProcessedCancellation tracks the last timestamp for each "${orderId}_CANCELLED" key. If fewer than 10 seconds have elapsed since the same cancellation was processed, the notification and Room write are skipped to prevent duplicates from Firebase emitting multiple events.

Build docs developers (and LLMs) love