Skip to main content
Production batches (lotes) are the core of Tambo360’s tracking system. Each batch represents a specific production run of cheese or milk, with detailed tracking of quantities, costs, and waste.

Overview

The batch system provides:
  • Automatic lot number generation
  • Product categorization (cheese/milk)
  • Real-time production status
  • Complete lifecycle tracking from creation to completion
  • Integration with waste and cost modules

Data Model

Production batches are defined in the Prisma schema:
// schema.prisma:74-87
model LoteProduccion {
  idLote            String          @id @default(uuid())
  numeroLote        Int             @default(autoincrement())
  fechaProduccion   DateTime        @default(now())
  idProducto        String
  producto          Producto        @relation(fields: [idProducto], references: [idProducto])
  cantidad          Decimal
  unidad            Unidad          // kg or litros
  idEstablecimiento String
  estado            Boolean         @default(false)
  establecimiento   Establecimiento @relation(fields: [idEstablecimiento], references: [idEstablecimiento])
  mermas            Merma[]
  costosDirectos    CostosDirecto[]
}

Key Fields

numeroLote

Auto-incrementing sequential number for easy reference

estado

Boolean flag: false = in progress, true = completed

unidad

Enum: kg for cheese, litros for milk

producto

Relation to Producto model with category (quesos/leches)

Creating a Production Batch

1

Initiate Batch

Create a new production batch with product details:
// Create batch (batchController.ts:7-25)
POST /api/lotes
Authorization: Bearer <jwt-token>

{
  "idProducto": "producto-uuid",
  "cantidad": 150.5,
  "unidad": "kg",
  "idEstablecimiento": "establecimiento-uuid",
  "fechaProduccion": "2026-03-08T08:00:00.000Z"  // optional
}

// Response
{
  "success": true,
  "statusCode": 201,
  "message": "Lote creado correctamente",
  "data": {
    "idLote": "lote-uuid",
    "numeroLote": 1247,
    "fechaProduccion": "2026-03-08T08:00:00.000Z",
    "cantidad": 150.5,
    "unidad": "kg",
    "estado": false,
    "producto": { ... },
    "establecimiento": { ... }
  }
}
2

Track Progress

The batch remains in progress (estado: false) while production continues. During this time:
  • Waste can be registered
  • Costs can be added
  • Quantity can be updated
3

Complete Batch

Mark the batch as completed when production finishes:
POST /api/lotes/:idLote/completar
Authorization: Bearer <jwt-token>

// No body required

// Response updates estado to true
{
  "success": true,
  "message": "Lote completado correctamente",
  "data": {
    "idLote": "lote-uuid",
    "estado": true,
    ...
  }
}
Once a batch is marked as completed (estado: true), it’s locked for modifications. Plan accordingly.

Batch Operations

List Batches

Retrieve batches with optional filters:
// List batches (batchController.ts:62-82)
GET /api/lotes?idEstablecimiento=uuid&estado=false&fechaInicio=2026-03-01&fechaFin=2026-03-08
Authorization: Bearer <jwt-token>

// Query parameters (all optional):
// - idEstablecimiento: filter by establishment
// - estado: true (completed) or false (in progress)
// - fechaInicio: start date filter
// - fechaFin: end date filter

// Response
{
  "success": true,
  "message": "Lotes listados correctamente",
  "data": [
    {
      "idLote": "lote-uuid",
      "numeroLote": 1247,
      "fechaProduccion": "2026-03-08T08:00:00.000Z",
      "cantidad": 150.5,
      "unidad": "kg",
      "estado": false,
      "producto": {
        "idProducto": "producto-uuid",
        "nombre": "Queso Cheddar",
        "categoria": "quesos"
      },
      "mermas": [...],
      "costosDirectos": [...]
    }
  ]
}

Get Single Batch

// Get batch details (batchController.ts:84-104)
GET /api/lotes/:idLote
Authorization: Bearer <jwt-token>

// Returns complete batch with all relations
{
  "success": true,
  "message": "Lote obtenido correctamente",
  "data": {
    "idLote": "lote-uuid",
    "numeroLote": 1247,
    "producto": { ... },
    "mermas": [ ... ],
    "costosDirectos": [ ... ],
    "establecimiento": { ... }
  }
}

Edit Batch

Update batch information before completion:
// Edit batch (batchController.ts:27-43)
PUT /api/lotes/:idLote
Authorization: Bearer <jwt-token>

{
  "cantidad": 155.0,  // Updated quantity
  "fechaProduccion": "2026-03-08T09:00:00.000Z"
}

// Response with updated batch
{
  "success": true,
  "message": "Lote actualizado correctamente",
  "data": { ... }
}
Only incomplete batches (estado: false) can be edited.

Delete Batch

// Delete batch (batchController.ts:45-60)
DELETE /api/lotes/:idLote
Authorization: Bearer <jwt-token>

// Response
{
  "success": true,
  "message": "Lote eliminado correctamente",
  "data": null
}
Deleting a batch also removes all associated waste records and costs due to database cascade.

Today’s Production

Get batches created today for quick daily overview:
// Daily production (batchController.ts:106-115)
GET /api/lotes/produccion-del-dia
Authorization: Bearer <jwt-token>

// Returns batches with today's date
{
  "success": true,
  "message": "Producción del día",
  "data": [...]
}
This endpoint powers the “Daily Production Log” component in the dashboard.

Product Categories

Batches are categorized by product type:
// schema.prisma:21-24
enum Categoria {
  quesos  // Cheese products
  leches  // Milk products
}

model Producto {
  idProducto       String           @id @default(uuid())
  nombre           String
  categoria        Categoria
  loteProducciones LoteProduccion[]
}
{
  "producto": {
    "nombre": "Queso Mozzarella",
    "categoria": "quesos"
  },
  "cantidad": 120.5,
  "unidad": "kg"
}

Batch Lifecycle

Integration Points

Waste Management

Waste records link to batches:
// Waste is validated against batch quantity
const totalMermas = sumaMermas + nuevaMerma;
if (totalMermas > lote.cantidad) {
  throw new Error("La merma supera la cantidad disponible del lote");
}
See Waste Management for details.

Cost Tracking

Direct costs are assigned to specific batches:
// Each cost links to idLote
model CostosDirecto {
  idCostoDirecto String         @id @default(uuid())
  concepto       ConceptoCosto
  monto          Decimal        @db.Decimal(13, 2)
  idLote         String
  lote           LoteProduccion @relation(fields: [idLote], references: [idLote])
}
See Cost Tracking for details.

Dashboard Analytics

Completed batches feed into dashboard metrics:
// dashboardService.ts:26-30
const resultActual = await prisma.loteProduccion.findMany({
  where: {
    establecimiento: { idUsuario: userId },
    fechaProduccion: { gte: fechaInicio, lte: fechaFin }
  },
  include: { mermas: true, costosDirectos: true, producto: true }
});

AI Analysis

The TamboEngine analyzes completed batches:
// tamboEngineService.ts:47-61
const lotes = await prisma.loteProduccion.findMany({
  where: {
    idEstablecimiento,
    estado: true,  // Only completed batches
    fechaProduccion: { gte: fechaLimite }
  }
});
Requires minimum 15 completed batches for AI analysis.

Validation & Security

All batch operations verify:
const user = (req as any).user;
if (!user) throw new AppError("Usuario no autenticado", 401);

// Batch must belong to user's establishment
const lote = await LoteService.obtenerLote(idLote, user.id);
// crearLoteSchema validates:
{
  idProducto: string (UUID),
  cantidad: number (positive),
  unidad: enum (kg | litros),
  idEstablecimiento: string (UUID),
  fechaProduccion: date (optional, defaults to now)
}
  • Quantity must be positive
  • Unit must match product category
  • Establishment must belong to user
  • Only incomplete batches can be edited
  • Completed batches cannot be reopened

Best Practices

Complete Batches Promptly

Mark batches as complete as soon as production finishes for accurate analytics

Accurate Quantities

Record final quantities before completion to ensure waste calculations are correct

Use Filters

Leverage query parameters when listing batches to improve performance

Track Daily Production

Use the daily production endpoint for end-of-day summaries

API Reference

EndpointMethodPurpose
/api/lotesPOSTCreate new batch
/api/lotesGETList batches with filters
/api/lotes/:idLoteGETGet batch details
/api/lotes/:idLotePUTUpdate batch
/api/lotes/:idLoteDELETEDelete batch
/api/lotes/:idLote/completarPOSTMark batch as complete
/api/lotes/produccion-del-diaGETGet today’s batches

Build docs developers (and LLMs) love