Skip to main content
SYNTIfood usa un sistema de menú basado en JSON con categorías e ítems. Esta guía te muestra cómo estructurarlo.

Arquitectura del Menú

El menú se almacena en:
storage/app/tenants/{tenantId}/menu/menu.json
Estructura JSON:
{
  "categories": [
    {
      "id": "cat-XY12",
      "nombre": "Pizzas",
      "foto": "pizza-category.jpg",
      "activo": true,
      "items": [
        {
          "id": "item-AB34",
          "nombre": "Margarita",
          "precio": 12.00,
          "descripcion": "Salsa de tomate, mozzarella, albahaca",
          "image_path": null,
          "badge": "hot",
          "is_featured": true,
          "activo": true
        }
      ]
    }
  ]
}

Gestión de Categorías

Crear Categoría

1

Accede al dashboard

Ingresa a /tenant/{tenantId}/dashboard con tu PIN.En SYNTIfood verás la sección “Menú” en lugar de “Productos”.
2

Haz clic en 'Nueva Categoría'

Formulario:
  • Nombre (obligatorio) — Ej. “Entradas”, “Platos fuertes”, “Bebidas”
  • Foto (opcional) — Imagen destacada de la categoría
  • Activa — Checkbox de visibilidad
3

El sistema crea la categoría

Endpoint:
POST /tenant/{tenantId}/food/categories
Controlador: App\Http\Controllers\Food\CategoriesControllerEl servicio MenuService::createCategory() ejecuta:
$category = [
    'id'     => $this->generateId('cat'), // cat-XY12
    'nombre' => $data['nombre'],
    'foto'   => $data['foto'] ?? null,
    'items'  => [],
    'activo' => true,
];

$menu['categories'][] = $category;
$this->persist($tenantId, $menu);

Editar Categoría

1

Haz clic en 'Editar' en el card de categoría

Puedes cambiar:
  • Nombre
  • Foto (subir nueva o eliminar)
  • Estado activo/inactivo
2

Guardar cambios

Endpoint:
PUT /tenant/{tenantId}/food/categories/{categoryId}
El sistema actualiza el JSON y persiste:
foreach ($menu['categories'] as &$cat) {
    if ($cat['id'] === $catId) {
        $cat['nombre'] = $data['nombre'];
        $cat['foto'] = $data['foto'];
        $cat['activo'] = $data['activo'];
    }
}
$this->persist($tenantId, $menu);

Eliminar Categoría

Al eliminar una categoría se eliminan TODOS sus ítems asociados de forma permanente.
1

Haz clic en 'Eliminar'

Confirma la acción en el modal.
2

El sistema ejecuta

DELETE /tenant/{tenantId}/food/categories/{categoryId}
Lógica:
$menu['categories'] = array_values(
    array_filter($menu['categories'], fn($c) => $c['id'] !== $catId)
);
$this->persist($tenantId, $menu);

Gestión de Ítems

Crear Ítem

1

Desde una categoría, haz clic en 'Agregar Ítem'

Formulario:
  • Nombre (obligatorio) — Ej. “Pizza napolitana”
  • Precio (obligatorio) — Valor en REF
  • Descripción (opcional) — Ingredientes o detalles
  • Imagen (opcional) — Foto del plato
  • Badge — hot/new/promo
  • Destacado — Checkbox
  • Activo — Checkbox
2

El sistema crea el ítem

Endpoint:
POST /tenant/{tenantId}/food/categories/{categoryId}/items
Controlador: App\Http\Controllers\Food\ItemsControllerEl servicio ejecuta:
$item = [
    'id'          => $this->generateId('item'), // item-AB34
    'nombre'      => $data['nombre'],
    'precio'      => (float) $data['precio'],
    'descripcion' => $data['descripcion'] ?? null,
    'image_path'  => $data['image_path'] ?? null,
    'badge'       => $data['badge'] ?? null,
    'is_featured' => (bool) $data['is_featured'],
    'activo'      => true,
];

// Agrega a la categoría correspondiente
foreach ($menu['categories'] as &$cat) {
    if ($cat['id'] === $catId) {
        $cat['items'][] = $item;
    }
}

Editar Ítem

1

Haz clic en 'Editar' sobre el ítem

Puedes modificar cualquier campo.
2

Guardar cambios

Endpoint:
PUT /tenant/{tenantId}/food/categories/{categoryId}/items/{itemId}
El sistema busca el ítem dentro de la categoría y actualiza:
foreach ($menu['categories'] as &$cat) {
    if ($cat['id'] === $catId) {
        foreach ($cat['items'] as &$item) {
            if ($item['id'] === $itemId) {
                $item['nombre'] = $data['nombre'];
                $item['precio'] = $data['precio'];
                // ...
            }
        }
    }
}

Eliminar Ítem

1

Haz clic en 'Eliminar' sobre el ítem

Confirma en el modal.
2

El sistema ejecuta

DELETE /tenant/{tenantId}/food/categories/{categoryId}/items/{itemId}
Lógica:
foreach ($menu['categories'] as &$cat) {
    if ($cat['id'] === $catId) {
        $cat['items'] = array_values(
            array_filter($cat['items'], fn($i) => $i['id'] !== $itemId)
        );
    }
}

Límites por Plan

SYNTIfood Plan Limits (MenuService.php:16)
PlanÍtems totalesFotos de categorías
Básico ($9)506
Semestral ($39)10012
Anual ($69)15018
Los límites se aplican a ítems totales (suma de todas las categorías), no por categoría individual. Para verificar el conteo actual:
$totalItems = (new MenuService())->countItems($tenantId);

Subir Fotos de Categoría

1

Haz clic en 'Subir foto' en el card de categoría

Formatos: JPG, PNG, WebP Tamaño máx: 2 MB Dimensiones recomendadas: 1200×600 px (ratio 2:1)
2

El sistema procesa

Endpoint:
POST /tenant/{tenantId}/upload/category/{categoryId}
Guarda en storage/app/public/tenants/{tenantId}/menu/Nombre de archivo: cat-{categoryId}-{timestamp}.jpg
3

Actualiza el JSON

El campo foto de la categoría se actualiza con el nombre del archivo:
{
  "id": "cat-XY12",
  "nombre": "Pizzas",
  "foto": "cat-XY12-1709856432.jpg",
  "items": [...]
}

Ejemplo de Menú Completo

Restaurante de Comida Rápida

Categoría 1: Hamburguesas
  • Clásica (REF 8) — Carne, lechuga, tomate, queso
  • Doble carne (REF 12) — badge: hot
  • Vegetariana (REF 10) — badge: new
Categoría 2: Complementos
  • Papas fritas (REF 3)
  • Aros de cebolla (REF 4)
  • Nuggets x6 (REF 5)
Categoría 3: Bebidas
  • Refresco 500ml (REF 2)
  • Jugo natural (REF 3.5)
  • Batido (REF 5) — badge: promo

Fonda Venezolana

Categoría 1: Platos del día
  • Pabellón criollo (REF 10) — featured
  • Asado negro (REF 12) — badge: hot
  • Pollo guisado (REF 8)
Categoría 2: Arepas
  • Reina pepiada (REF 4)
  • Dominó (REF 3.5)
  • Pelúa (REF 4)

Menú Público

El menú se muestra en:
GET /menu/{subdomain}
Ejemplo: syntiweb.com/menu/pizzeriademo El controlador Food\MenuController::show() carga:
  1. Datos del tenant
  2. Categorías activas con ítems activos
  3. Tasa BCV actual (si el plan lo permite)
  4. Configuración de moneda

Pedido Rápido (Plan Anual)

Solo disponible en Plan Anual de SYNTIfood.
1

Cliente selecciona ítems

Hace clic en “Agregar” sobre cada ítem que desea.Se acumulan en un carrito temporal (localStorage del navegador).
2

Toca 'Enviar pedido'

El sistema construye un mensaje formateado:
🍕 *Pedido desde Pizzería Demo*

1x Pizza Margarita - REF 12.00
2x Refresco 500ml - REF 4.00
1x Tiramisú - REF 6.00

*Total: REF 22.00*

¡Espero tu confirmación!
3

Abre WhatsApp automáticamente

URL generada:
https://wa.me/584121234567?text={mensaje_codificado}
El cliente solo debe presionar “Enviar” en WhatsApp.

Rutas de la API

AcciónMétodoEndpoint
Listar categoríasGET/tenant/{tenantId}/food/categories
Crear categoríaPOST/tenant/{tenantId}/food/categories
Editar categoríaPUT/tenant/{tenantId}/food/categories/{categoryId}
Eliminar categoríaDELETE/tenant/{tenantId}/food/categories/{categoryId}
Crear ítemPOST/tenant/{tenantId}/food/categories/{categoryId}/items
Editar ítemPUT/tenant/{tenantId}/food/categories/{categoryId}/items/{itemId}
Eliminar ítemDELETE/tenant/{tenantId}/food/categories/{categoryId}/items/{itemId}
Ver menú públicoGET/menu/{subdomain}
Todas las operaciones de escritura requieren autenticación. El menú público es de acceso libre.

Build docs developers (and LLMs) love