- Empresa: Brasaland (cadena de restaurantes, 14 locales)
- Reto: Seleccion de empresa mediante agente de IA
- Autor de la propuesta: Nicolas (enfoque desde experiencia previa en restaurantes)
Brasaland opera 14 locales sin visibilidad centralizada. Mariana (Direccion ejecutiva) toma decisiones reactivas, "apagando incendios", sin datos exactos de como funciona cada local.
En paralelo, Operaciones no tiene un control claro del stock ni de cuando se necesitara reposicion, lo que impacta directamente la atencion al cliente.
La propuesta ataca estos retos en dos frentes independientes pero conectados por los mismos datos base (locales, movimientos y fechas).
- Visibilidad de costos reales por local (no estimaciones).
- Identificar rapido que locales y decisiones son mas eficientes para la cadena.
- Un portal ejecutivo con totales claros por local.
- Filtrado temporal flexible: tiempo real, por dia, por mes o por rango libre.
- Trazabilidad de entradas, salidas y departamento que genero cada gasto.
- Informes semanales automaticos con puntos clave de mejora por local y a nivel de cadena.
| Necesidad de negocio | Pieza tecnica |
|---|---|
| Totales por local | generarReporteFinancieroPorLocal() (ya implementado): agrupa MovimientoFinanciero por localId y calcula entradas, salidas y balance. |
| Filtrado por rango de fechas | Filtro sobre movimientos usando filtrar() + comparacion de fechas antes de generar el reporte. |
| Gasto por departamento | El campo departamento en MovimientoFinanciero permite agrupar/filtrar por cocina, barra, administracion, marketing y mantenimiento. |
| Informe semanal automatico | Job programado (cron o similar) que ejecuta generarReporteFinancieroPorLocal() para la semana y lo almacena en el portal. |
| Portal ejecutivo | Dashboard frontend (Next.js) que consume una API con estos reportes. |
Mientras no haya integracion con POS/facturacion real, se simulara todo el flujo de datos, manteniendo el contexto real de 14 sedes.
- Generar datos simulados para las 14 sedes (no solo 2 o 3 de ejemplo).
- Incluir movimientos financieros de varios departamentos y rangos de fechas por sede.
- Simular el informe semanal automatico sobre las 14 sedes en conjunto.
- Entregar el informe semanal dentro del portal ejecutivo.
- Saber que hay en stock general: comida, bebida e insumos de empaque.
- Anticipar demanda segun temporada y fechas especiales (San Valentin, Navidad, Ano Nuevo, etc.).
- Alertas anticipadas de faltantes o excesos para optimizar compras y reducir desperdicio.
- Poder agregar productos nuevos cuando cambie la carta.
| Necesidad de negocio | Pieza tecnica |
|---|---|
| Stock general por categoria | Insumo ya incluye categoria; contarPorCategoria() y agruparPor() permiten ver stock agrupado. |
| Control de faltantes | tieneStockBajo(insumo) (ya implementado): compara stockActual vs stockMinimo. |
| Anticipar demanda por temporada | FechaEspecial + calcularImpactoEnDemanda() (ya implementado): devuelve factor vigente (ej. San Valentin x1.6, Navidad x2.0). |
| Alertas de faltantes/excesos | Pendiente: funcion que cruce tieneStockBajo() + calcularImpactoEnDemanda() para generar alertas priorizadas. |
| Perecederos vs no perecederos | Insumo.perecedero + diasVidaUtil ya modelado para logica de vencimiento cercano. |
| Agregar productos nuevos | Crear nuevo objeto Insumo; el modelo lo soporta sin cambios de esquema. |
- Perecederos refrigerados (carne, queso, pollo, verduras): rotacion semanal (7 dias).
- Licores y bebidas: rotacion quincenal (15 dias).
- Criterio de exceso: si el stock actual no se consume dentro del ciclo definido.
Implicacion tecnica:
Insumodebe incluirfrecuenciaRotacionDias(por ejemplo7 | 15) para evaluar exceso contra consumo esperado por ciclo, no con un umbral unico para todos los insumos.
Ambos modulos comparten entidades base (Local, fechas y movimientos), permitiendo que a futuro el agente de IA (Yayo, construido con OpenClaw) responda preguntas cruzadas entre finanzas y operaciones.
Ejemplo de consulta futura:
"Medellin es el local que mas gasta porque es el mas grande. Ese gasto esta justificado por su volumen de ventas o hay baja rotacion de stock que indique desperdicio?"
Esto no se construye en esta fase, pero el modelo de datos ya esta orientado para habilitarlo sin rehacer la base.
- Modelo de datos completo para ambos frentes (
types.ts). - Funciones de colecciones: filtrar, ordenar, buscar, agrupar (
collections.ts). - Reportes agregados: financiero por local e inventario por insumo (
aggregations.ts). - Validaciones de negocio por entidad (
validations.ts).
- Funcion de alertas de stock (cruce de
tieneStockBajo+calcularImpactoEnDemanda). - API (Flask o Next.js API routes) para exponer funciones como endpoints.
- Portal ejecutivo (frontend) con totales por local y filtro de fechas.
- Vista de Operaciones (frontend) con estado de stock y alertas.
- Job de informe semanal automatico.
- Mecanismo de entrega de alertas e informes (en esta fase, dentro del portal).
El departamento de atencion postventa de Brasaland gestiona incidencias de clientes (quejas, solicitudes y fallos operativos). Para validar el proceso de analisis sin exponer datos sensibles, se definio un dataset simulado interno de 100 registros en CSV.
El objetivo es validar la logica ahora con datos ficticios y, en una fase posterior, sustituir el origen por datos reales sin cambiar la arquitectura.
- Ruta del archivo: scripts/incidents-BRASALAND.csv
- Total de filas de datos: 100 (mas cabecera)
- Registros validos esperados: 92
- Registros invalidos esperados: 8
- incident_id
- fecha_reporte
- local_id
- cliente_id
- cliente_email
- cliente_telefono
- categoria
- estado
- prioridad
- satisfaccion
- descripcion
Los siguientes campos se consideran obligatorios para que una fila sea valida:
- incident_id
- fecha_reporte
- local_id
- cliente_id
- cliente_email
- cliente_telefono
- categoria
- estado
- prioridad
- descripcion
Nota: satisfaccion es opcional salvo cuando aplique logica de validacion de rango si viene informada.
- local_id: L01 a L14
- categoria: queja, solicitud, fallo_operativo
- estado: abierto, cerrado, descartado
- prioridad: baja, media, alta, critica
- satisfaccion: entero entre 1 y 5 cuando exista valor
Una fila es invalida si cumple al menos una de estas condiciones:
- Le falta un campo obligatorio.
- categoria fuera de rango.
- estado fuera de rango.
- local_id fuera de rango.
- prioridad fuera de rango.
- satisfaccion fuera de rango (menor a 1 o mayor a 5) o no numerica.
- Totales generales
- procesados: 100
- validos: 92
- invalidos: 8
- Invalidos por tipo
- campo_faltante: 2
- categoria_fuera_de_rango: 2
- estado_fuera_de_rango: 2
- satisfaccion_fuera_de_rango: 1
- local_id_fuera_de_rango: 1
- Totalizacion por categoria (solo validos)
- queja: 34
- solicitud: 30
- fallo_operativo: 28
- Totalizacion por estado (solo validos)
- abierto: 33
- cerrado: 45
- descartado: 14
- Satisfaccion media (solo cerrados con puntuacion)
- casos cerrados con satisfaccion: 40
- satisfaccion_media: 4.1
El CSV simulado contiene identificadores, correos y telefonos ficticios de prueba (dominio brasaland.test), por lo que no hay datos personales reales expuestos.