Overview
The Tables API manages restaurant tables with real-time status tracking, manual occupancy control, and integration with orders and reservations. It provides enriched table data that combines base table info with current status.
Table Management
getTablesFromCache
Retrieves tables from in-memory cache synchronously.
export const getTablesFromCache = () : Table []
Array of tables sorted alphabetically by name
fetchAndCacheTables
Fetches tables from Firebase and updates caches.
export const fetchAndCacheTables = async () : Promise < Table []>
addTable
Creates a new table.
export const addTable = async ( tableData : Omit < Table , 'id' >) : Promise < Table >
Table name/number (e.g., “Mesa 1”, “Barra 3”)
Whether table can be reserved (default: true)
Created table with:
Generated ID (format: TBL-{timestamp}-{random})
overrideStatus set to null
import { addTable } from './services/tableService' ;
const table = await addTable ({
name: "Mesa 10" ,
capacity: 6 ,
allowsReservations: true
});
console . log ( 'Table created:' , table . id );
updateTable
Updates an existing table.
export const updateTable = async ( updatedTable : Table ) : Promise < Table >
Complete table object with all fields
deleteTable
Deletes a table by ID.
export const deleteTable = async ( tableId : string ) : Promise < void >
Manual Status Control
setTableOverrideStatus
Manually sets table status, overriding automatic status detection.
export const setTableOverrideStatus = async (
tableId : string ,
status : 'Bloqueada' | 'Ocupada' | null
): Promise < Table >
status
'Bloqueada' | 'Ocupada' | null
required
'Bloqueada' - Table is blocked/unavailable
'Ocupada' - Table is manually marked as occupied
null - Remove manual override (use automatic status)
Updated table with:
New overrideStatus
occupiedSince timestamp if status is ‘Ocupada’
Cleared session data if status is null
import { setTableOverrideStatus } from './services/tableService' ;
// Block a table
await setTableOverrideStatus ( "T1" , "Bloqueada" );
// Manually mark as occupied
await setTableOverrideStatus ( "T2" , "Ocupada" );
// Clear manual status
await setTableOverrideStatus ( "T1" , null );
Use Cases:
Block table for maintenance or special events
Manually mark walk-in customers before creating order
Clear status when customers leave
occupyTableAndGenerateCode
Marks table as occupied and generates a 4-digit access code.
export const occupyTableAndGenerateCode = async ( tableId : string ) : Promise < string >
4-digit access code (e.g., “3947”)
Behavior:
Sets overrideStatus to ‘Ocupada’
Sets occupiedSince timestamp
Generates random 4-digit code
Stores code in accessCode field
import { occupyTableAndGenerateCode } from './services/tableService' ;
const code = await occupyTableAndGenerateCode ( "T3" );
console . log ( 'Table access code:' , code );
// "7142"
Access codes can be used for customer self-service ordering or payment verification.
verifyTableAccessCode
Verifies an access code for a table.
export const verifyTableAccessCode = ( tableId : string , code : string ) : boolean
The access code to verify
true if code matches, false otherwise
import { verifyTableAccessCode } from './services/tableService' ;
const isValid = verifyTableAccessCode ( "T3" , "7142" );
if ( isValid ) {
console . log ( 'Access granted' );
}
updateTableSession
Updates session information for an occupied table.
export const updateTableSession = async (
tableId : string ,
customerName : string ,
guests : number
): Promise < void >
Customer name for the session
import { updateTableSession } from './services/tableService' ;
await updateTableSession ( "T3" , "Pedro Martínez" , 3 );
Enriched Table Data
enrichTables
Enriches tables with real-time status based on orders and reservations.
export const enrichTables = (
tables : Table [],
orders : Order [],
reservations : Reservation []
): EnrichedTable []
Array of orders to check for table occupancy
Array of reservations to check for upcoming bookings
Tables with computed status and details
Status Priority (highest to lowest):
Manual Override - overrideStatus takes precedence
Active Orders - Tables with active dine-in orders
Upcoming Reservations - Tables reserved within next 2 hours
Free - No conflicts
Status Types:
'Libre' - Available
'Ocupada' - Has active order or manual override
'Reservada' - Reserved 1-2 hours from now
'Bloqueada' - Blocked (manual or reserved within 1 hour)
import { enrichTables , getTablesFromCache } from './services/tableService' ;
import { getOrdersFromCache } from './services/orderService' ;
import { getReservationsFromCache } from './services/reservationService' ;
const tables = getTablesFromCache ();
const orders = getOrdersFromCache ();
const reservations = getReservationsFromCache ();
const enrichedTables = enrichTables ( tables , orders , reservations );
enrichedTables . forEach ( table => {
console . log ( ` ${ table . name } : ${ table . status } ` );
if ( table . details ) {
console . log ( ` Customer: ${ table . details . customerName } ` );
}
if ( table . accumulatedTotal ) {
console . log ( ` Total: $ ${ table . accumulatedTotal } ` );
}
});
Accumulated Totals:
For occupied tables, includes all orders placed since occupiedSince
Useful for showing running tab to customers and staff
getEnrichedTableById
Gets enriched data for a single table.
export const getEnrichedTableById = ( tableId : string ) : EnrichedTable | null
Enriched table data or null if not found
Availability Checking
getAvailableTablesForDineIn
Gets tables available for immediate dine-in orders.
export const getAvailableTablesForDineIn = (
reservationToIgnoreId ?: string
): Table []
Reservation ID to exclude from conflict check (useful when converting reservation to order)
Tables that are:
Not manually blocked or occupied
Not in use by active dine-in orders
Not reserved within the next hour
import { getAvailableTablesForDineIn } from './services/tableService' ;
const availableTables = getAvailableTablesForDineIn ();
if ( availableTables . length > 0 ) {
console . log ( 'Available tables:' , availableTables . map ( t => t . name ));
} else {
console . log ( 'No tables available' );
}
TypeScript Types
Table Interface
interface Table {
id : string ;
name : string ;
capacity : number ;
allowsReservations : boolean ;
overrideStatus : 'Bloqueada' | 'Ocupada' | null ;
occupiedSince ?: string | null ; // ISO timestamp
accessCode ?: string ; // 4-digit code
currentSession ?: {
customerName : string ;
guests : number ;
};
}
EnrichedTable Interface
interface EnrichedTable extends Table {
status : TableStatus ; // 'Libre' | 'Ocupada' | 'Reservada' | 'Bloqueada'
details ?: {
type : 'order' | 'reservation' ;
id : string ;
customerName : string ;
time ?: string ; // For reservations
startTime ?: string ; // For orders
orderStatus ?: OrderStatus ; // For orders
};
activeOrdersOnTable ?: Order []; // All orders at this table
accumulatedTotal ?: number ; // Sum of all order totals
}
TableStatus Type
type TableStatus = 'Libre' | 'Ocupada' | 'Reservada' | 'Bloqueada' ;
Complete Example
Managing Table Lifecycle
import {
occupyTableAndGenerateCode ,
updateTableSession ,
getEnrichedTableById ,
setTableOverrideStatus
} from './services/tableService' ;
import { saveOrder , OrderType , PaymentMethod , CreatedBy } from './services/orderService' ;
// 1. Customer arrives, occupy table and get code
const tableId = "T3" ;
const accessCode = await occupyTableAndGenerateCode ( tableId );
console . log ( 'Show customer this code:' , accessCode );
// 2. Update session info
await updateTableSession ( tableId , "Ana Torres" , 2 );
// 3. Customer places order
const order = await saveOrder ({
customer: { name: "Ana Torres" , phone: "+5491167890123" },
items: [
{ name: "Pizza Muzzarella" , quantity: 1 , price: 9200 , isPromotion: false , itemId: "PROD-1" }
],
total: 9200 ,
type: OrderType . DINE_IN ,
tableIds: [ tableId ],
guests: 2 ,
paymentMethod: PaymentMethod . CASH ,
createdBy: CreatedBy . ADMIN
});
// 4. Check table status
const enrichedTable = getEnrichedTableById ( tableId );
console . log ( 'Table status:' , enrichedTable ?. status );
console . log ( 'Running total:' , enrichedTable ?. accumulatedTotal );
// 5. Customer leaves, clear table
await setTableOverrideStatus ( tableId , null );
console . log ( 'Table cleared and ready for next customer' );