Documentation Index
Fetch the complete documentation index at: https://mintlify.com/JAQA20/LaComanda/llms.txt
Use this file to discover all available pages before exploring further.
La Comanda persists all restaurant data — users, tables, orders, and products — in a MySQL 8 database whose full schema is defined in db/la_comanda.sql. When Docker Compose starts for the first time, the official MySQL image automatically imports that file, creates the schema, seeds reference data, and applies the utf8mb4 character set throughout. No manual migration step is required.
The schema uses the utf8mb4 charset and utf8mb4_unicode_ci collation on
every table, providing full Unicode support including emoji and accented
characters common in Spanish-language menus.
Schema Overview
The database is composed of ten tables and one view. The diagram below lists
each object and its purpose.
roles
Defines the four access levels recognised by the application.
| Column | Type | Notes |
|---|
id | INT PK | Auto-increment surrogate key |
nombre | VARCHAR(50) | admin, mesero, cocina, barista |
usuarios
Stores every staff account that can log in to La Comanda.
| Column | Type | Notes |
|---|
id | INT PK | Auto-increment surrogate key |
nombre | VARCHAR(100) | First name |
apellido | VARCHAR(100) | Last name |
email | VARCHAR(150) | Unique login identifier |
activo | TINYINT(1) | 1 = active, 0 = deactivated |
password | VARCHAR(255) | bcrypt hash — never stored in plain text |
rol_id | INT FK | References roles.id |
creado_en | DATETIME | Account creation timestamp |
password_resets
Tracks one-time tokens used by the forgot-password flow.
| Column | Type | Notes |
|---|
id | INT PK | Auto-increment surrogate key |
usuario_id | INT FK | References usuarios.id |
token | VARCHAR(64) | SHA-256 hash of the raw token sent via email |
expira_en | DATETIME | Token expires 60 minutes after creation |
usado | TINYINT(1) | 1 once the token has been redeemed |
mesas
Represents the physical dining tables in the restaurant.
| Column | Type | Notes |
|---|
id | INT PK | Auto-increment surrogate key |
numero | INT | Human-readable table number shown in the UI |
estado | ENUM | disponible (free) or ocupada (occupied) |
Twelve tables are seeded by default (numbers 1–12).
layout_configs
Persists the drag-and-drop floor-plan layout configured by the administrator.
| Column | Type | Notes |
|---|
id | INT PK | Auto-increment surrogate key |
layout_key | VARCHAR(100) | Identifies the layout context (e.g. default) |
payload_json | LONGTEXT | Full JSON snapshot of table positions |
actualizado_por | INT FK | usuarios.id of the last editor |
created_at | TIMESTAMP | Row creation time |
updated_at | TIMESTAMP | Last modification time |
categorias
Groups products and drives automatic kitchen/barista routing.
| Column | Type | Notes |
|---|
id | INT PK | Auto-increment surrogate key |
nombre | VARCHAR(100) | Display name shown in the POS UI |
slug | VARCHAR(100) | URL-safe identifier — controls preparation routing |
icono | VARCHAR(100) | FontAwesome class name (e.g. fa-coffee) |
orden | INT | Sort order in category lists |
activo | TINYINT(1) | 1 = visible, 0 = hidden |
productos
The menu items that waitstaff can add to an order.
| Column | Type | Notes |
|---|
id | INT PK | Auto-increment surrogate key |
categoria_id | INT FK | References categorias.id |
nombre | VARCHAR(150) | Product display name |
precio | DECIMAL(10, 2) | Unit price in local currency |
icono | VARCHAR(100) | FontAwesome class name |
activo | TINYINT(1) | 1 = available for ordering |
ordenes
One row per open or completed order, linked to a table and the waiter who created it.
| Column | Type | Notes |
|---|
id_orden | INT PK | Auto-increment surrogate key |
numero_orden | INT | Sequential display number for the shift |
mesa_id | INT FK | References mesas.id |
id_usuario | INT FK | Waiter who opened the order |
notas | TEXT | Optional free-text notes for the kitchen |
total | DECIMAL(10, 2) | Calculated order total |
fecha_creacion | DATETIME | When the order was placed |
fecha_lista | DATETIME | When all items were marked ready |
fecha_entrega | DATETIME | When the order was delivered to the table |
detalle_orden
Line-item detail for every product within an order. Each row tracks its own
preparation lifecycle independently.
| Column | Type | Notes |
|---|
id_detalle | INT PK | Auto-increment surrogate key |
id_orden | INT FK | References ordenes.id_orden |
id_producto | INT FK | References productos.id |
cantidad | INT | Number of units ordered |
precio_unitario | DECIMAL(10,2) | Price at time of order (snapshot, not a live FK) |
estado_item | ENUM | pendiente → en_preparacion → listo → entregado |
fecha_inicio_preparacion | DATETIME | Set when kitchen/barista starts the item |
fecha_lista | DATETIME | Set when the item is ready for collection |
fecha_entrega | DATETIME | Set when the waiter delivers the item |
observaciones | TEXT | Per-item special instructions from the customer |
vw_detalle_preparacion (view)
A read-only view that joins ordenes, detalle_orden, productos,
categorias, and mesas into a single flat result set. It adds the computed
column area_preparacion, which categorises every line item as barista,
cocina, or ignorar. Kitchen and barista screens query this view directly to
filter their own queues without duplicating the routing logic in PHP.
Category Routing Rules
The area_preparacion column in vw_detalle_preparacion is derived at query
time from each product’s category slug. The rules are:
categorias.slug | area_preparacion | Visible to |
|---|
cafes, bebidas | barista | Barista screen |
Anything else except mesas | cocina | Kitchen screen |
mesas | ignorar | Neither screen |
To add a new preparation area in a future version, introduce a new slug
value and extend the CASE expression inside vw_detalle_preparacion. No
PHP code changes are needed for the routing itself.
The mesas category represents table-service charges or cover items that
require no preparation. Assigning a product to this category removes it from
both the kitchen and barista queues entirely.
Seed Data
db/la_comanda.sql includes the following reference data, which is loaded
automatically by the MySQL Docker container on first start:
| Object | Count | Details |
|---|
| Roles | 4 | admin, mesero, cocina, barista |
| Users | 22 | Sample staff accounts covering all four roles, passwords are bcrypt-hashed |
| Tables | 12 | Numbered 1–12, all initially disponible |
| Categories | 6 | Mesas, Cafés, Comidas, Especialidades, Postres, Bebidas Frías |
| Products | 60 | Distributed across all six categories with realistic prices |
The seeded user passwords are for demonstration only. Replace them
immediately in any environment that is accessible from a network, using the
admin panel’s user management screen or a direct UPDATE statement with a
freshly generated bcrypt hash.
Resetting the Database
To wipe all data and reimport the schema and seed data from scratch, stop the
stack, remove the named volume, and rebuild:
docker compose down -v && docker compose up --build
The -v flag deletes the persistent MySQL volume. On the next up, Docker
re-imports db/la_comanda.sql as if the container had never run before.
This operation is irreversible. All orders, custom layouts, and user
accounts created since the last seed will be permanently deleted.
Accessing MySQL Directly
For ad-hoc queries, schema inspection, or manual data fixes, open an
interactive MySQL session inside the running container:
# Open a root shell inside the MySQL container
docker exec -it la-comanda-db mysql -u root -p
You will be prompted for the MYSQL_ROOT_PASSWORD defined in your .env.
Once connected, switch to the application database:
USE la_comanda;
-- List all tables
SHOW TABLES;
-- Inspect a table's structure
DESCRIBE detalle_orden;
Prefer connecting as lacomanda_user (DB_USER) for read queries so you
exercise the same privilege boundary as the application. Use the root
account only when schema-level changes are required.