El software de pedidos para restaurantes suele fallar en dos sitios: el momento en que un desconocido puede pedir a una mesa que no es suya, y el momento en que el total de la pantalla del cliente no coincide con el de la caja. El módulo de comida de Korat está diseñado hacia atrás desde ambos. La sesión de mesa la acuña el personal y lleva un token de un solo uso; la cuenta son las mismas filas que lee la caja; y place_dining_order pone el precio de cada línea en el servidor.
El QR de la mesa es un token de un solo uso, no un número de mesa
Deliberadamente no existe la vía de «teclea tu número de mesa». Es la función evidente que construir, y la razón por la que tantos sistemas de mesa se pueden abusar desde el aparcamiento: si la única credencial es un número impreso en la mesa, cualquiera que haya comido allí alguna vez puede pedir a cualquier mesa para siempre. En su lugar, el personal abre la mesa desde la consola, y abrirla acuña un token nuevo de un solo uso incrustado en el QR de esa mesa. Un QR fotografiado, una captura reenviada a un amigo o la impresión del martes pasado llevan un token que ya no es el vigente, y no funciona.
Quien se acerca a una mesa no es ni miembro del negocio ni anfitrión de una sesión que aún no existe, así que bajo seguridad a nivel de fila no puede leer la tabla dining_sessions en absoluto. RLS puede juzgar quién llama; no puede juzgar que una petición lleve un token válido. Por eso el escaneo pasa por join_session_by_token, una función SECURITY DEFINER que compara el token en el servidor, convierte en anfitrión a quien escanea primero y devuelve nulo cuando no coincide — sin decir por qué. Un error que distinga «token equivocado» de «token caducado» es un oráculo para adivinar.
Ya dentro, quien hace de anfitrión puede invitar al resto de la mesa con un enlace o una tarjeta en el chat, de modo que quien llega tarde entra en la misma sesión y su comida cae en la misma cuenta.
El QR de la mesa es un enlace https: se abre en la app o en la web
El QR de la mesa es una URL https, no un esquema propio de la app. Un teléfono con Korat instalado la abre en la app mediante un App Link con dominio verificado; uno sin ella —incluido cualquier iPhone— abre en su lugar la página web de pedidos. Esto arregla el momento más muerto de todo el producto: el cliente se sienta, levanta la cámara, escanea, y no pasa absolutamente nada. Esa página lee la carta, el reloj del bufé y las reglas del alcohol sin sesión iniciada, y solo pide identificarse al enviar el pedido, que es el único momento en que no puede evitarlo. Los QR ya impresos que llevan el antiguo korat://dine seguirán escaneándose siempre.
Pedir: modificadores, notas y una carta que sabe que va a cerrar
La carta se organiza por categorías y cada plato puede llevar grupos de opciones — el chorrito extra, el nivel de picante, el tipo de fideo — con diferencias de precio, marca de obligatorio y máximo de selecciones. La diferencia va pegada a la opción, no escrita en una nota, y por eso el tique de cocina y la línea de la cuenta dicen lo mismo. Los platos admiten además una nota libre y una cantidad, y el carrito se edita hasta que se envía.
Horario, margen de última comanda y control de alcohol
Los negocios fijan horario con un margen de última comanda. Al acercarse, la carta avisa de que la cocina va a cerrar; pasado ese punto, pedir queda bloqueado en vez de aceptarse y cancelarse en silencio después. Los platos no disponibles o sin stock lo dicen en la tarjeta, antes del toque. El alcohol lleva su propia marca: comprobación de edad contra la fecha de nacimiento, y el personal puede verificar la edad de toda una sesión de una vez.
La cola de confirmación: nada llega a la cocina hasta que una persona dice que sí
Los pedidos enviados no van directos al pase. Caen en una cola de espera de confirmación en la pantalla de cocina, y el personal confirma o rechaza cada uno antes de que se convierta en trabajo. Un sistema que deja a un teléfono meter tiques directamente en una cocina le ha dado a un desconocido la capacidad de costarle comida al negocio, y elimina el momento en que una persona nota que la mesa seis ha pedido cuatro menús idénticos por error.
Desde la pantalla de cocina el personal avanza los pedidos por sus estados, y la consola muestra avisos en vivo que se refrescan cada pocos segundos — pedidos activos, mesas que llaman, reservas pendientes, repartos nuevos — más una franja roja en cuanto una mesa pulsa llamar. Quien come tiene la otra mitad del bucle: llamar al personal, pedir la cuenta o dejar la mesa.
La cuenta detallada en vivo, y dividirla con un QR PromptPay
La cuenta en vivo muestra exactamente las filas que lee la caja, actualizadas conforme se confirma la comida: sin revelación final ni reconstrucción de memoria. Al cerrar la mesa, la app produce una hoja de resumen — incluidas sugerencias para agregar como amigos a quienes compartieron la sesión — y un recordatorio de reseña después. Los tiques quedan en un historial personal.
Dividir la cuenta: cuánto debe cada uno
La vista de división responde a lo que la gente discute de verdad: qué debo yo. Cada persona ve su subtotal a la carta más una parte igual de cualquier paquete de bufé de la mesa. Se puede generar un QR de PromptPay por el importe, en el formato estándar tailandés con su suma de control CRC-16.
La cuenta dividida es un desglose, no pagos separados. Calcula lo que debe cada persona; no cobra cuatro tarjetas por cuatro partes. Repartir el dinero se sigue haciendo entre las personas de la mesa y el negocio.
Y no hay una vía alternativa de «teclea tu número de mesa», a propósito. Si el QR de alguien no escanea, el personal reabre la mesa desde la consola. Añadir un camino manual devolvería exactamente el agujero que el token se acuñó para cerrar.
Bufé: paquetes por persona, temporizador y cargo por sobras
El bufé tiene su propio modelo en vez de fingirse con un plato con precio por persona. Un paquete tiene precio por cabeza, un temporizador con prórrogas que concede el personal, y recuentos separados de adultos y niños. Los platos llevan un papel dentro del bufé — incluido, solo a la carta, o incluido con suplemento — así que una sola carta sirve a los dos tipos de cliente. El cobro por comida sobrante está contemplado con etiquetas de unidad: la regla que casi todos los bufés tailandeses ya tienen impresa en la mesa y que casi todo el software finge que no existe.
Reparto, comida para llevar y reservas de mesa
La misma carta sostiene el reparto y la comida para llevar. Un pedido lleva coste de envío, proveedor, hora programada de recogida y dirección, y avanza por nuevo, cocinando, en camino y entregado, con aviso a ambas partes en cada transición. Las reservas de mesa toman fecha, hora, número de comensales y una nota, y esperan a que el negocio confirme; el recuento pendiente está en el panel como aviso en vivo. Un negocio que además vende producto envasado usa para eso el módulo tienda, construido sobre la misma regla de precios en el servidor.
Dos variantes frecuentes. Un local que atiende en mostrador y llama por número usa los turnos en vez de mesas. Y si primero quieres saber qué pide abrir un negocio, la página para negocios lo cuenta entero.
Cada precio se calcula en el servidor
La regla que hace seguro todo lo demás: el cliente nunca fija un precio. place_dining_order y place_shop_order leen los precios de los platos, las diferencias de las opciones y el coste de envío de la base de datos e ignoran lo que envió el teléfono. Un campo del cliente en el que se confía es un descuento que uno se concede solo. El mismo principio cubre las reseñas: solo puede escribir una quien la base de datos pueda demostrar que comió allí o pidió a domicilio, y la puntuación en estrellas la recalcula un disparador, nunca se teclea.