Skip to main content
Tambo360’s waste management system (mermas) provides detailed tracking of product loss during production. The system categorizes waste into four distinct types to help identify inefficiencies and improve processes.

Overview

The waste management module:
  • Tracks waste by production batch
  • Categorizes waste into 4 predefined types
  • Validates waste against batch quantities
  • Provides optional observations for each record
  • Integrates with dashboard analytics

Waste Types

The system defines four categories of waste:
// schema.prisma:31-36
enum TipoMerma {
  Natural          // Natural loss during production
  Tecnica          // Technical/equipment failures
  Administrativa   // Administrative errors
  Danio            // Damage to product
}

Natural

Natural losses occur during normal production processes:
  • Evaporation during heating
  • Moisture loss during aging
  • Separation of whey in cheese production
  • Normal shrinkage

Tecnica

Technical waste results from equipment or process failures:
  • Machine malfunctions
  • Temperature control failures
  • Contamination issues
  • Process deviations

Administrativa

Administrative waste stems from human error:
  • Incorrect measurements
  • Documentation mistakes
  • Scheduling errors
  • Mislabeled batches

Danio

Damage waste includes physical product damage:
  • Broken packaging
  • Dropped containers
  • Transport damage
  • Handling errors

Data Model

// schema.prisma:89-97
model Merma {
  idMerma       String         @id @default(uuid())
  tipo          TipoMerma
  observacion   String?        // Optional notes
  cantidad      Decimal
  fechaCreacion DateTime       @default(now())
  idLote        String
  lote          LoteProduccion @relation(fields: [idLote], references: [idLote])
}
Each waste record is tied to a specific production batch. The total waste cannot exceed the batch quantity.

Recording Waste

1

Identify Waste

During production, identify and measure waste that occurs.
2

Create Waste Record

Submit waste information with the batch ID:
// Create waste (mermaController.ts:13-20)
POST /api/mermas
Authorization: Bearer <jwt-token>

{
  "idLote": "lote-uuid",
  "tipo": "Natural",
  "cantidad": 5.5,
  "observacion": "Pérdida de humedad durante curado"
}

// Response
{
  "idMerma": "merma-uuid",
  "tipo": "Natural",
  "cantidad": 5.5,
  "observacion": "Pérdida de humedad durante curado",
  "fechaCreacion": "2026-03-08T14:30:00.000Z",
  "idLote": "lote-uuid"
}
3

Automatic Validation

The system validates the waste record:
// mermaService.ts:42-61

// 1. Check if batch exists
const lote = await prisma.loteProduccion.findUnique({
  where: { idLote: data.idLote }
});

// 2. Calculate total existing waste
const totalMermas = await prisma.merma.aggregate({
  _sum: { cantidad: true },
  where: { idLote: data.idLote }
});

// 3. Validate new waste doesn't exceed batch quantity
if (sumaMermas + Number(data.cantidad) > Number(lote.cantidad)) {
  throw new Error("La merma supera la cantidad disponible del lote");
}
If total waste (existing + new) exceeds the batch quantity, the system rejects the record with an error.

Waste Operations

Get All Waste Types

Retrieve the list of available waste types:
// Get waste types (mermaController.ts:8-11)
GET /api/mermas/tipos

// Response
[
  "Natural",
  "Tecnica",
  "Administrativa",
  "Danio"
]
Use this endpoint to populate dropdown selectors in your UI.

List All Waste Records

// List all waste (mermaController.ts:22-25)
GET /api/mermas
Authorization: Bearer <jwt-token>

// Response includes batch information
[
  {
    "idMerma": "merma-uuid",
    "tipo": "Natural",
    "cantidad": 5.5,
    "observacion": "Pérdida de humedad durante curado",
    "fechaCreacion": "2026-03-08T14:30:00.000Z",
    "lote": {
      "idLote": "lote-uuid",
      "numeroLote": 1247,
      "cantidad": 150.5,
      "producto": { ... }
    }
  }
]

Get Specific Waste Record

// Get waste by ID (mermaController.ts:27-37)
GET /api/mermas/:id
Authorization: Bearer <jwt-token>

// Response
{
  "idMerma": "merma-uuid",
  "tipo": "Tecnica",
  "cantidad": 12.0,
  "observacion": "Falla en el sistema de refrigeración",
  "fechaCreacion": "2026-03-08T10:15:00.000Z",
  "lote": { ... }
}

Update Waste Record

Modify existing waste records:
// Update waste (mermaController.ts:39-46)
PUT /api/mermas/:id
Authorization: Bearer <jwt-token>

{
  "cantidad": 6.0,
  "observacion": "Pérdida de humedad durante curado - ajustado"
}

// Response with updated record
{
  "idMerma": "merma-uuid",
  "tipo": "Natural",
  "cantidad": 6.0,
  "observacion": "Pérdida de humedad durante curado - ajustado",
  ...
}
When updating waste quantity:
// mermaService.ts:142-161

// Calculate sum of OTHER waste records for the same batch
const totalMermas = await prisma.merma.aggregate({
  _sum: { cantidad: true },
  where: {
    idLote: merma.idLote,
    NOT: { idMerma }  // Exclude current record
  }
});

// Validate updated total doesn't exceed batch
if (sumaMermas + Number(data.cantidad) > Number(lote.cantidad)) {
  throw new Error("La merma supera la cantidad disponible del lote");
}

Delete Waste Record

// Delete waste (mermaController.ts:48-55)
DELETE /api/mermas/:id
Authorization: Bearer <jwt-token>

// Response
{
  "message": "Merma eliminada correctamente"
}

Validation Rules

Batch Required

Every waste record must link to a valid batch (idLote)

Type Validation

Waste type must be one of the four enum values

Positive Quantity

Quantity must be a positive number greater than 0

Quantity Limit

Total waste cannot exceed batch quantity

Dashboard Integration

Waste data is aggregated in the dashboard:
// dashboardService.ts:46-52
const buildSummary = (result: InfoMes) => {
  const summary = result.reduce<SummaryResult>((acc, lote) => {
    // ...
    acc[category].mermas += lote.mermas.reduce(
      (sum: number, merma: Merma) => sum + Number(merma.cantidad), 
      0
    );
    return acc;
  }, {});
};
The dashboard displays:
// Dashboard.tsx:11-20
const totalProduccion = 
  (data.actual.quesos || 0) + (data.actual.leches || 0);

const porcentajeMermas = totalProduccion > 0
  ? ((data.actual.mermas || 0) / totalProduccion) * 100
  : 0;
Shown as a percentage in the dashboard stat card.

Use Cases by Type

Scenario: Cheese aging process
// Day 1: Initial batch
POST /api/lotes
{ "cantidad": 100, "unidad": "kg", ... }

// Day 7: Natural moisture loss
POST /api/mermas
{
  "idLote": "...",
  "tipo": "Natural",
  "cantidad": 2.5,
  "observacion": "Pérdida de humedad semana 1"
}

// Day 14: Additional natural loss
POST /api/mermas
{
  "idLote": "...",
  "tipo": "Natural",
  "cantidad": 1.8,
  "observacion": "Pérdida de humedad semana 2"
}
Total natural waste: 4.3 kg (4.3%)
Scenario: Equipment malfunction
POST /api/mermas
{
  "idLote": "...",
  "tipo": "Tecnica",
  "cantidad": 25.0,
  "observacion": "Falla en tanque de refrigeración - temperatura elevada por 4 horas"
}
Track equipment failures to identify maintenance needs.
Scenario: Measurement error
POST /api/mermas
{
  "idLote": "...",
  "tipo": "Administrativa",
  "cantidad": 3.2,
  "observacion": "Error en pesaje inicial - sobreestimación de cantidad disponible"
}
Identify process improvement opportunities in documentation.
Scenario: Handling incident
POST /api/mermas
{
  "idLote": "...",
  "tipo": "Danio",
  "cantidad": 8.5,
  "observacion": "Caída de bandeja durante transporte a cámara de maduración"
}
Track physical damage to improve handling procedures.

Analytics & Reporting

Waste data is used in multiple analytics contexts:
// dashboardService.ts:136-140
if (metrica === "mermas") {
  valor = lote.mermas.reduce(
    (sum, m) => sum + Number(m.cantidad),
    0
  );
}
The 6-month historical chart shows waste trends over time.

AI Alert Analysis

// tamboEngineService.ts:78-82
mermas: l.mermas.map(m => ({
  descripcion: m.observacion || m.tipo,
  cantidad: Number(m.cantidad),
  unidad: l.unidad,
}))
The AI engine analyzes waste patterns to generate alerts about:
  • Abnormal waste levels
  • Recurring issues
  • Efficiency opportunities

Best Practices

Record Immediately

Log waste as soon as it occurs for accurate tracking

Detailed Observations

Include specific details in observations to aid analysis

Correct Categorization

Choose the most accurate waste type for better insights

Regular Review

Analyze waste trends monthly to identify patterns

Common Issues

Error: “La merma supera la cantidad disponible del lote”Solutions:
  • Verify the batch quantity is correct
  • Check if waste has been double-recorded
  • Update the batch quantity if initial measurement was incorrect
Error: “Tipo de merma inválido”Solution: Use only the four predefined types: Natural, Tecnica, Administrativa, Danio (case-sensitive)
Error: “El lote indicado no existe”Solution: Verify the idLote UUID is correct and the batch hasn’t been deleted

API Reference

EndpointMethodPurpose
/api/mermas/tiposGETGet available waste types
/api/mermasPOSTCreate waste record
/api/mermasGETList all waste records
/api/mermas/:idGETGet specific waste record
/api/mermas/:idPUTUpdate waste record
/api/mermas/:idDELETEDelete waste record

Build docs developers (and LLMs) love