Cuchara para Pajaros API REST

Documentación pública

API Restaurante — Cuchara para Pajaros

API REST compartida por el panel de meseros, futuras apps web y móviles. JSON UTF-8.

Base URL https://panel.cucharaparapajaros.com/apis/api.php/

Autenticación

Tipo
Bearer JWT (HS256)
Header
Authorization: Bearer {token}
Login
POST /login con JSON { "usuario", "contrasena" } — devuelve token y datos del usuario.
Expiración
El token dura ~400 días. Renovar con POST /auth/refresh (Bearer). En el panel web: cookie de sesión en save_path propio + cookie HttpOnly sr_persist (JWT) que rehidrata si el archivo de sesión del SO se borra; solo se cierra con logout explícito o usuario inactivo.
Rutas públicas
Las rutas bajo /public/ no requieren token.
curl -X POST "https://panel.cucharaparapajaros.com/apis/api.php/login"
  -H "Content-Type: application/json"
  -d '{"usuario":"admin@correo.com","contrasena":"tu_clave"}'

Convenciones

  • Métodos: GET para consultas, POST para crear/actualizar/eliminar (no hay PUT/DELETE).
  • Cuerpo: Enviar JSON en POST salvo descarga de PDF/XML.
  • Respuesta: JSON con success, message y datos según endpoint. Errores: 400, 401, 403, 404, 409, 500.
  • CORS: Access-Control-Allow-Origin: * — usable desde web/app externa.
  • Estados: Muchos recursos usan estado A (activo), I (inactivo) o X (eliminado lógico). Inactivo oculta en pedidos pero conserva relaciones (ej. complementos vinculados a productos).
  • Menaje: Inventario de vajilla/utensilios (/menaje/*) es independiente de la lista de compras de insumos (/inventario/*). Permiso base: menaje.ver (+ menaje.crear|editar|conteo|movimientos|historial|eliminar). Conteos e ingresos/bajas generan historial; no mezclan stock con app_inventario_productos.
  • Recetas de inventario: Un insumo (app_inventario_productos) se liga a platos (app_productos) o opciones de complemento (app_complemento_opciones) vía /inventario/recetas*. Al cobrar ítems del pedido se aplica movimiento tipo consumo (cantidad_receta × cantidad_vendida, y lo mismo por cada complemento). Si no hay stock suficiente el cobro no falla (soft-fail). Flag idempotente app_pedido_items.stock_descontado; al revertir cobro se reponen las salidas.
  • Proteínas: Procesamiento de proteínas (/inventario/proteinas*): INGRESO registra lotes con fundas disponibles (estado D) y suma stock en ubicaciones ambito=proteinas; EGRESO retira fundas marcadas y/o unidades con spinner (POST /inventario/proteinas/egreso). Panel meseros: pestaña Egreso por defecto. Lectura: inventario.ver. Mutaciones: inventario.editar.
  • Totales de línea: total_linea = (precio_unitario + suma de complementos[].precio × (complementos[].cantidad||1)) × cantidad − descuento + tarrinas. Al crear/actualizar, si complementos traen opcion_id el API completa precio desde el catálogo (no confía en precio 0 del cliente). Al recalcular (crear, editar, cobrar) también repara precios de complemento en 0 cuando el catálogo tiene valor > 0. En grupos multi (max>1) el panel permite cantidad por opción; la suma de cantidades debe respetar min/max del grupo.
  • Nómina: La forma de pago de la empresa (app_empresas.frecuencia_pago: semanal | quincenal | mensual) define el período de roles, cuotas de anticipos y descuentos. Semanal = lunes a domingo. Quincenal = cortes de calendario 1–15 y 16–último día (no es una ventana rodante de 15 días). Mensual = día 1 al último del mes. El horario de turnos sigue siendo semanal. Roles ya generados conservan sus fecha_inicio/fecha_fin; no se recortan al cambiar la frecuencia. Zona horaria: America/Guayaquil.
  • Cuenta dividida (impresión): Precuenta y recibo térmico (nota) encolan un trabajo MAXINE por dueño (corte al terminar cada PDF). La cola no dispara el siguiente hasta el ACK, para no abrir dos Bluetooth a la vez. La comanda de cocina no se parte. El cobro y los totales por cuenta no cambian.
  • Scope de sucursal (pedidos): Listar/crear pedidos respeta X-Cod-Sucursal. Mutaciones y lecturas sensibles de un pedido validan cod_sucursal (ADMIN exento): detalle/cobrar/actualizar/finalizar/revertir-cobro/eliminar/programar_horario/actualizar_cliente/comprobante/items-asignar/documento-enlace/enviar_sri, más factura-enlace, documento cuentas/emitir/qr/correo, convertir_factura, anular_sri/reenviar_sri/enviar_correo, pickup whatsapp y datos_cliente_link. Pedidos legacy sin sucursal se permiten. create/update no aceptan estados terminales desde el cliente; cancelado no es editable. Crear/reasignar mesa bloquea la fila de app_mesas (FOR UPDATE) para evitar doble ocupación concurrente.
  • Factura por cuenta: POST /pedidos/documento/cuentas y /emitir: nota imprime recibo/precuenta por dueño; factura envía al SRI (una clave por dueño o una única del pedido, mutuamente excluyentes) e imprime. GET /pedidos/facturas lista una fila por comprobante SRI: primero por enviar/error, luego autorizadas por secuencial descendente; query estado_sri=por_enviar|autorizada|anulada|todas. Acciones PDF/SRI/anular aceptan owner. La impresión térmica/PDF de factura usa ese owner: si ya hay individuales no se genera una tira única ni un secuencial de vista previa de toda la mesa. Si ya está autorizada, el ticket no lleva “documento no autorizado”. El QR de datos acepta owner para cliente distinto por persona. No se revierte cobro si hay factura autorizada. Enviar al SRI bloquea la fila de app_facturas_sri del owner (FOR UPDATE) antes de reservar secuencial. Factura única (sin owner) exige mesa sin cuentas/saldo pendientes. Asignar dueños (POST /pedidos/items/asignar) usa TX; omite líneas ya cobradas y solo bloquea cuentas cobradas cuando el dueño de la línea realmente cambia (reenviar dueños ya pagados no falla).
  • Cocina / print WS: Mutaciones de kitchen (tickets/estado, preparar-todo, items/estado, cancelar) validan que el ticket/pedido pertenezca a la sucursal del tablero. POST /kitchen/tickets/estado usa FOR UPDATE + CAS (estado actual) y bloquea regresión delivered/completed sin privilegio OTP/ADMIN; expected_estado opcional → 409 si desfasado. Socket.IO kitchen exige JWT (query token) con cod_empresa coincidente. /kitchen-ws no admite soft auth (solo token). /print-ws legacy soft conserva job.print_token en el wake (Maxine imprime desde el evento); el claim atómico sigue en poll. Al autenticar /print-ws se reenvía wake del próximo pendiente. ImpresoraCola wake no se silencia por otros pendientes (solo en_proceso).
  • Roles / caja: Solo el rol ADMIN puede tener permiso *. roles.gestionar y equipo.gestionar son ADMIN_ONLY. equipo.gestionar no puede desactivar ADMIN. negocio.ver no otorga admin de caja (operar/borrar cualquier turno); eso requiere ADMIN/*. Abrir turno usa GET_LOCK por sucursal. GET caja_chica/estado y turnos_reporte exigen acceso de caja.