Skip to main content
Tambo360’s alert system uses artificial intelligence to analyze production patterns and proactively notify you of anomalies, inefficiencies, and optimization opportunities.

Overview

The TamboEngine AI service:
  • Analyzes completed production batches
  • Identifies unusual patterns in production, waste, and costs
  • Generates actionable alerts with severity levels
  • Learns from historical data to improve accuracy
  • Provides establishment-specific insights

AI Service

The TamboEngine is a separate AI service that communicates with the main backend via REST API. It runs independently at TAMBO_AI_URL.

How Alerts Work

Analysis Trigger

Alerts are generated when specific conditions are met:
// tamboEngineService.ts:47-64
static async analizarSiCorresponde(idEstablecimiento: string) {
  const fechaLimite = new Date();
  fechaLimite.setDate(fechaLimite.getDate() - 15);
  
  // Fetch completed batches from last 15 days
  const lotes = await prisma.loteProduccion.findMany({
    where: {
      idEstablecimiento,
      estado: true,  // Only completed batches
      fechaProduccion: { gte: fechaLimite }
    },
    include: { producto: true, mermas: true, costosDirectos: true, establecimiento: true }
  });
  
  // Minimum 15 batches required for analysis
  if (lotes.length < MINIMO_LOTES) return;
}
1

Batch Completion

When a production batch is marked as complete, the system checks if analysis should run.
2

Data Collection

If there are 15+ completed batches in the last 15 days, data is collected.
3

AI Analysis

Batch data is sent to the TamboEngine AI service for pattern analysis.
4

Alert Generation

The AI generates alerts based on detected anomalies and patterns.
The 15-batch minimum ensures the AI has sufficient data for meaningful pattern detection.

Analysis Payload

The data sent to the AI service includes:
// tamboEngineService.ts:67-89
const payload = {
  idEstablecimiento,
  nombreEstablecimiento: lotes[0].establecimiento?.nombre || idEstablecimiento,
  periodo: new Date().toLocaleString("es-AR", { month: "long", year: "numeric" }),
  lotes: lotes.map(l => ({
    idLote: l.idLote,
    fechaProduccion: l.fechaProduccion.toISOString().split("T")[0],
    producto: l.producto.nombre,
    categoria: l.producto.categoria,
    cantidad: Number(l.cantidad),
    unidad: l.unidad,
    mermas: l.mermas.map(m => ({
      descripcion: m.observacion || m.tipo,
      cantidad: Number(m.cantidad),
      unidad: l.unidad,
    })),
    costosDirectos: l.costosDirectos.map(c => ({
      concepto: c.concepto,
      monto: Number(c.monto),
      moneda: "ARS",
    })),
  }))
};
The AI analyzes:
  • Production volumes and trends
  • Waste patterns by type
  • Cost variations
  • Efficiency metrics
  • Cross-batch comparisons

Retrieving Alerts

Get All Alerts

Fetch alerts for an establishment:
// Get alerts (alertController.ts:7-21)
GET /api/alertas/:idEstablecimiento?rango=30
Authorization: Bearer <jwt-token>

// Query parameters:
// - rango (optional): number of days to look back (default varies by AI)

// Response
{
  "success": true,
  "message": "Alertas obtenidas correctamente",
  "data": [
    {
      "idAlerta": "alert-uuid",
      "tipo": "merma_elevada",
      "severidad": "alta",
      "titulo": "Mermas elevadas en producción de queso",
      "descripcion": "Se detectó un incremento del 15% en mermas naturales comparado con el promedio histórico",
      "idLote": "lote-uuid",
      "numeroLote": 1247,
      "visto": false,
      "fechaCreacion": "2026-03-08T10:30:00.000Z"
    }
  ]
}

Get Recent Alerts

Fetch the most recent alerts for quick overview:
// Get latest alerts (alertController.ts:23-33)
GET /api/alertas/:idEstablecimiento/ultimas
Authorization: Bearer <jwt-token>

// Returns a limited set of the most recent alerts

Get Unseen Alert Count

Check how many alerts haven’t been viewed:
// Get unseen count (alertController.ts:46-56)
GET /api/alertas/:idEstablecimiento/no-vistas
Authorization: Bearer <jwt-token>

// Response
{
  "success": true,
  "message": "Conteo de alertas no vistas obtenido correctamente",
  "data": {
    "cantidad": 3
  }
}
Use this to display notification badges in the UI.

Marking Alerts as Seen

Once a user reviews an alert, mark it as seen:
// Mark as seen (alertController.ts:35-45)
PUT /api/alertas/:idAlerta/visto
Authorization: Bearer <jwt-token>

// No body required

// Response
{
  "success": true,
  "message": "Alerta marcada como vista correctamente",
  "data": {
    "idAlerta": "alert-uuid",
    "visto": true,
    ...
  }
}
Marking alerts as seen helps track which issues have been acknowledged and addressed.

Alert Enrichment

Alerts are enriched with batch information for better context:
// tamboEngineService.ts:28-45
private static async _enriquecerAlertasConNumeroLote(alertas: any[]) {
  if (!alertas || alertas.length === 0) return [];
  
  const idsLotes = alertas.map(a => a.idLote).filter(Boolean);
  if (idsLotes.length === 0) return alertas;
  
  // Fetch batch numbers
  const lotesDb = await prisma.loteProduccion.findMany({
    where: { idLote: { in: idsLotes } },
    select: { idLote: true, numeroLote: true }
  });
  
  const lotesMap = new Map(lotesDb.map(l => [l.idLote, l.numeroLote]));
  
  // Add numeroLote to each alert
  return alertas.map(a => ({
    ...a,
    numeroLote: lotesMap.get(a.idLote) || null
  }));
}
This allows users to quickly identify which batch an alert relates to.

Alert Types

The AI can generate various types of alerts:

High Waste

Detects when waste exceeds historical averages or industry benchmarks

Cost Anomalies

Identifies unusual cost patterns or unexpected expense increases

Production Efficiency

Highlights opportunities to improve yield or reduce processing time

Pattern Deviations

Flags when production patterns deviate from established norms

Severity Levels

Alerts are typically categorized by severity:
Immediate attention required
  • Significant production issues
  • Major cost overruns
  • Critical waste levels
  • Urgent intervention needed

Dashboard Integration

Alerts are displayed in the dashboard sidebar:
// Dashboard.tsx:114
<aside className="w-full lg:w-80 shrink-0">
  <AlertsSection />
</aside>
The AlertsSection component:
  • Fetches alerts for the current establishment
  • Displays unseen alerts prominently
  • Allows marking alerts as seen
  • Links to related batches for investigation

Error Handling

The system gracefully handles AI service issues:
// tamboEngineService.ts:8-26
private static async fetchWithTimeout(url: string, options: RequestInit = {}, timeout = 15000) {
  const controller = new AbortController();
  const id = setTimeout(() => controller.abort(), timeout);
  
  try {
    const response = await fetch(url, {
      ...options,
      signal: controller.signal
    });
    clearTimeout(id);
    return response;
  } catch (error: any) {
    clearTimeout(id);
    if (error.name === 'AbortError') {
      throw new AppError("Timeout: La IA tardó demasiado en responder", 504);
    }
    throw new AppError("Error de red: No se pudo conectar con la IA", 503);
  }
}
If the AI service is unavailable, the main application continues to function. Alerts simply won’t be generated until the service recovers.

Fallback Behavior

// tamboEngineService.ts:109-130
static async getAlertas(idEstablecimiento: string, rangoDias?: number) {
  try {
    const response = await this.fetchWithTimeout(url, {}, 15000);
    
    if (!response.ok) {
      if (response.status === 404) return []; // No alerts yet
      throw new AppError(`Error interno en la IA (Status: ${response.status})`, response.status);
    }
    
    const alertas = await response.json();
    return await this._enriquecerAlertasConNumeroLote(alertas);
  } catch (error: any) {
    console.error("[TamboEngine] Error consultando alertas:", error);
    if (error instanceof AppError) throw error;
    throw new AppError("El servicio de Inteligencia Artificial devolvió una respuesta inesperada.", 502);
  }
}
Returns empty array instead of crashing when:
  • AI service hasn’t generated alerts yet (404)
  • Service is temporarily unavailable

Use Cases

Scenario: Alert for elevated waste
  1. Alert appears in dashboard: “Mermas elevadas - Lote #1247”
  2. User clicks alert to view details
  3. System shows batch information and waste breakdown
  4. User investigates:
    • Reviews waste type (Natural, Technical, etc.)
    • Checks observations for clues
    • Compares with similar batches
  5. User identifies root cause (e.g., equipment issue)
  6. User marks alert as seen after addressing
Scenario: Alert for cost anomaly
  1. Alert: “Costos 20% sobre promedio - Queso Cheddar”
  2. User reviews cost breakdown for flagged batch
  3. Identifies raw milk cost spike
  4. Investigates supplier pricing
  5. Negotiates better rates or switches supplier
  6. Marks alert as seen
Scenario: Alert for production inefficiency
  1. Alert: “Rendimiento bajo - considerar ajustes de proceso”
  2. User compares flagged batch with high-performing batches
  3. Identifies process variation
  4. Implements standardized procedures
  5. Monitors improvement in subsequent batches
  6. Marks alert as seen

Best Practices

Complete Batches Promptly

Mark batches complete as soon as production finishes to ensure timely AI analysis

Review Daily

Check the alerts section daily to stay on top of issues

Investigate Thoroughly

Don’t just dismiss alerts—investigate root causes

Track Resolution

Mark alerts as seen only after addressing the underlying issue

System Requirements

Minimum Data Requirements:
  • At least 15 completed batches
  • Batches must be from the last 15 days
  • Batches must include waste and cost data
  • All batches must have estado: true

Performance Considerations

Background Processing

AI analysis runs in background; doesn’t block batch completion

Timeout Protection

15-second timeout prevents indefinite waiting on AI service

Graceful Degradation

System remains functional even if AI service is down

Efficient Queries

Alert enrichment batches database queries for performance

API Reference

EndpointMethodPurpose
/api/alertas/:idEstablecimientoGETGet all alerts for establishment
/api/alertas/:idEstablecimiento/ultimasGETGet recent alerts
/api/alertas/:idEstablecimiento/no-vistasGETGet count of unseen alerts
/api/alertas/:idAlerta/vistoPUTMark alert as seen

AI Service Endpoints

The TamboEngine AI service exposes:
EndpointMethodPurpose
/api/v1/tambo/analyzePOSTTrigger production analysis
/api/v1/tambo/alertas/:idEstablecimientoGETFetch alerts
/api/v1/tambo/alertas/:idEstablecimiento/ultimasGETGet recent alerts
/api/v1/tambo/alertas/:idAlerta/vistoPUTMark as seen
/api/v1/tambo/alertas/:idEstablecimiento/no-vistasGETGet unseen count

Build docs developers (and LLMs) love