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.

Tables are the physical anchor of every transaction in La Previa Restobar. Each table record carries its current status, its seating capacity, and a reference to the active order — making it possible for any role in the app to understand the full picture of the dining floor at a glance, without querying the orders collection separately.

The Table Data Class

data class Table(
    val id: Int,
    val number: Int,
    val status: TableStatus,
    val currentOrderId: String? = null,
    val capacity: Int = 4,
    val version: Long = 0,
    val syncStatus: String = "SYNCED"
)

id / number

id is the integer primary key used in Room and as the Firebase node key. number is the human-facing label displayed on table cards (e.g. “Mesa 3”).

currentOrderId

Populated by CreateOrderUseCase when an order is placed. Cleared when the order reaches COMPLETED or CANCELLED. A non-null value indicates the table has an active ticket.

capacity

Defaults to 4 seats. Displayed in the waiter’s table selection screen to help allocate appropriate tables for party sizes.

syncStatus

Defaults to "SYNCED" (unlike orders, which default to "PENDING"). Tables are typically written by the Firebase admin setup and only require local sync pushes when the status changes offline.

TableStatus Enum

enum class TableStatus {
    LIBRE,
    OCUPADA,
    RESERVADA
}
StatusMeaningWho sets it
LIBRETable is available for seatingSystem, when order is COMPLETED or CANCELLED
OCUPADATable has an active orderCreateOrderUseCase via assignOrderToTable
RESERVADATable is held for a future bookingAdmin manually

Table Status Transitions During an Order

The table status is tightly coupled to the order lifecycle. The transitions below describe the full journey from an empty table to a freed seat.
1

LIBRE → OCUPADA (order created)

When the waiter calls CreateOrderUseCase, the use case calls tableRepository.assignOrderToTable(order.tableId, order.id) immediately after creating the order. This sets the table status to OCUPADA and writes currentOrderId with the new order’s UUID.
2

OCUPADA — order in progress

The table remains OCUPADA through all intermediate order statuses: ENVIADO, ACEPTADO, EN_PREPARACION, LISTO, and ENTREGADO. This prevents another waiter from accidentally seating new guests at an occupied table.
3

OCUPADA → LIBRE (order completed or cancelled)

When the order transitions to COMPLETED (bill paid) or CANCELLED, the table repository clears currentOrderId (sets it to null) and reverts status to LIBRE. The table card on the waiter’s screen immediately reflects the change via the Firebase real-time listener.
A table set to RESERVADA by the admin will not be automatically changed to OCUPADA if an order is placed against it. Ensure a reserved table is manually freed before a waiter attempts to seat guests.

TableDao Queries

@Dao
interface TableDao {
    @Insert(onConflict = OnConflictStrategy.REPLACE)
    suspend fun insert(table: TableEntity)

    @Query("SELECT * FROM tables")
    suspend fun getAll(): List<TableEntity>

    @Query("SELECT * FROM tables WHERE syncStatus = 'PENDING'")
    suspend fun getPending(): List<TableEntity>

    @Query("UPDATE tables SET syncStatus = :status WHERE id = :id")
    suspend fun updateStatus(id: Int, status: String)

    @Query("UPDATE tables SET syncStatus = :status, version = :newVersion, lastModified = :lastModified WHERE id = :id AND version < :newVersion")
    suspend fun updateStatusIfNewer(id: Int, status: String, newVersion: Long, lastModified: Long)

    @Query("SELECT * FROM tables WHERE id = :id")
    suspend fun getById(id: Int): TableEntity?
}
getPending() is used by SyncManager.syncTables() to push locally modified table records back to Firebase when connectivity returns. updateStatusIfNewer adds a version guard so that a stale offline update cannot silently overwrite a more recent remote change.

GetTablesUseCase

class GetTablesUseCase @Inject constructor(
    private val tableRepository: TableRepository
) {
    operator fun invoke(): Flow<List<Table>> {
        return tableRepository.getTables()
    }
}
The use case returns a Flow<List<Table>> that the waiter’s ViewModel collects. Because the repository attaches a ValueEventListener on the Firebase tables/ node, every status change — regardless of which device made it — propagates to all connected clients in real time.

Waiter Table Screen

On the waiter’s home screen, tables are displayed as a grid of cards. Each card shows:
  • The table number (Table.number)
  • The current status rendered as a color-coded badge:
    • 🟢 LIBRE — available (green)
    • 🔴 OCUPADA — occupied (red)
    • 🟡 RESERVADA — reserved (amber)
  • The capacity as a seat count indicator
Tapping a LIBRE table navigates the waiter to the product selection screen where they build the order. Tapping an OCUPADA table opens the existing active order so the waiter can add items, view its status, or close the bill.
The currentOrderId field on the Table record allows the waiter screen to navigate directly to the active order without a separate Firebase query — just look up the order by that ID from the local Room cache.

Code Reference

data class Table(
    val id: Int,
    val number: Int,
    val status: TableStatus,
    val currentOrderId: String? = null,
    val capacity: Int = 4,
    val version: Long = 0,
    val syncStatus: String = "SYNCED"
)

enum class TableStatus {
    LIBRE,
    OCUPADA,
    RESERVADA
}

Build docs developers (and LLMs) love