Skip to main content
Un plano es una vista aproximada desde arriba de un local: sus pisos, la estructura fija de cada piso (paredes, mostrador, kioscos, puertas, columnas, zonas) y las mesas con sus asientos. Los planos son opcionales y se activan por local. En el dashboard dibujas el plano. La ocupación de las mesas no se marca aquí: llega desde el POS cuando un grupo se sienta y se abren sus órdenes.

Activa un plano

  1. En el dashboard, entra a Stores → Floor plans.
  2. Abre un local y activa Mostrar plano.
  3. Agrega un piso. Arrastra mesas y estructura desde la paleta al lienzo, dibuja paredes esquina por esquina y zonas como rectángulos, o pega el JSON del piso con Editar JSON. Selecciona elementos para moverlos, cambiar su tamaño o rotarlos. Todas las acciones funcionan también con el teclado, y Deshacer (Ctrl/Cmd+Z) revierte cualquier cambio.
  4. Selecciona Guardar. Cada piso con cambios se valida y se guarda.
Un local puede tener varios pisos. Cada piso tiene un level (0 para la planta baja y negativo para subsuelos) que se usa para ordenarlos.

Unidades y coordenadas

Las medidas usan unidades abstractas: 1 unidad equivale más o menos a 1 metro. El origen es la esquina superior izquierda del piso. x crece hacia la derecha y y hacia abajo. Cada elemento es una caja ubicada en x, y con un width y un depth, más una rotation opcional en grados alrededor de su centro.

JSON del piso

El editor, el API y las vistas del plano usan el mismo esquema. Vive en @repo/validations (vStoreFloors.floor()), así que todas las superficies lo validan igual. Cada elemento y cada mesa tiene id, x, y, width, depth y rotation (desde 0 y menor que 360). Todo debe caber dentro del piso y los ids no se pueden repetir en el piso.
  • Los elementos suman kind (wall, counter, kiosk, door, column o zone) y un label opcional.
  • Las paredes con trazo son paredes que además tienen points (de 2 a 200 esquinas sobre el eje de la pared, en unidades del piso) y un thickness opcional (de 0.1 a 2, por defecto 0.2). Su caja es el rectángulo que envuelve la pared dibujada y su rotation es 0. Solo las paredes pueden tener points o thickness, y cada esquina debe quedar dentro del piso. Las paredes sin points siguen siendo cajas simples, así que los pisos anteriores siguen siendo válidos.
  • Las mesas suman label (único por piso, sin distinguir mayúsculas), seats (de 1 a 50) y shape (square, round o rect). Los ids de mesa son únicos en todos los pisos del local, porque el POS y las reservas se refieren a ellos.

Ejemplo

Cómo se guarda

Un piso se guarda como dos tipos de datos, a propósito:
  • La estructura como JSON. Paredes, mostradores, kioscos, puertas, columnas y zonas se guardan en un solo documento jsonb por piso (store_floors.layout). Nada más se refiere a ellos, siempre se leen y editan juntos, y guardarlos como un documento hace que cada edición sea atómica.
  • Las mesas como filas. Cada mesa es una fila en store_tables. Las mesas tienen vida propia: el POS las marca como ocupadas, las agrupa y las vincula a órdenes, y las reservas apuntarán a ellas. Las filas le dan a cada mesa una identidad estable, llaves foráneas, seguridad por fila y actualizaciones en tiempo real por fila cuando cambia su estado, sin reescribir todo el piso.
Al guardar, el API toma el JSON del piso, guarda la estructura en el documento del piso y crea, actualiza o elimina las filas de mesas en una sola transacción.

Conceptos relacionados

Locales

Ubicaciones que tienen planos

Órdenes

Órdenes abiertas para grupos sentados