Skip to main content
Tambo360 supports multi-establishment management, allowing users to operate and track multiple dairy farm locations from a single account.

Overview

Establishments represent individual dairy farm locations. Each user can manage multiple establishments, with all production data, costs, and analytics segregated by location.

Multi-Location Benefits

  • Centralized management across multiple farms
  • Location-specific production tracking
  • Independent analytics per establishment
  • Scalable architecture for farm expansion

Data Structure

Establishments are defined in the Prisma schema:
// schema.prisma:56-65
model Establecimiento {
  idEstablecimiento String           @id @default(uuid())
  nombre            String
  localidad         String
  provincia         String
  fechaCreacion     DateTime         @default(now())
  idUsuario         String
  usuario           Usuario          @relation(fields: [idUsuario], references: [idUsuario])
  loteProducciones  LoteProduccion[]
}

Key Fields

  • idEstablecimiento: Unique UUID identifier
  • nombre: Farm or establishment name
  • localidad: City/locality
  • provincia: Province/state
  • idUsuario: Owner reference
  • loteProducciones: All production batches for this location

Creating an Establishment

Users must create at least one establishment before tracking production:
// Create establishment (establishmentController.ts:7-35)
POST /api/establishments
Authorization: Bearer <jwt-token>

{
  "nombre": "Tambo La Esperanza",
  "localidad": "Rafaela",
  "provincia": "Santa Fe"
}

// Response
{
  "success": true,
  "statusCode": 201,
  "message": "Establecimiento creado correctamente",
  "data": {
    "idEstablecimiento": "550e8400-e29b-41d4-a716-446655440000",
    "nombre": "Tambo La Esperanza",
    "localidad": "Rafaela",
    "provincia": "Santa Fe",
    "fechaCreacion": "2026-03-08T10:30:00.000Z",
    "idUsuario": "user-uuid"
  }
}
1

Authenticate

User must be logged in with a valid JWT token.
2

Provide Details

Submit establishment name and location information.
3

Automatic Association

The establishment is automatically linked to the authenticated user.

Listing Establishments

Retrieve all establishments for the authenticated user:
// List user establishments (establishmentController.ts:37-53)
GET /api/establishments
Authorization: Bearer <jwt-token>

// Response
{
  "success": true,
  "statusCode": 200,
  "message": "Establecimientos obtenidos correctamente",
  "data": [
    {
      "idEstablecimiento": "550e8400-e29b-41d4-a716-446655440000",
      "nombre": "Tambo La Esperanza",
      "localidad": "Rafaela",
      "provincia": "Santa Fe",
      "fechaCreacion": "2026-03-08T10:30:00.000Z"
    },
    {
      "idEstablecimiento": "660e8400-e29b-41d4-a716-446655440001",
      "nombre": "Tambo San Martín",
      "localidad": "Sunchales",
      "provincia": "Santa Fe",
      "fechaCreacion": "2026-02-15T14:20:00.000Z"
    }
  ]
}
The list is automatically filtered by the authenticated user’s idUsuario. Users can only see their own establishments.

Establishment Selection

In the frontend, establishments are accessed through the user context:
// Dashboard.tsx:28-29
const { user } = useAuth()
const establishmentName = user.establecimientos[0].nombre
For users with one establishment, the system automatically uses that location for all operations.

Establishment Context in Production

All production data is tied to an establishment:

Production Batches

Each batch (LoteProduccion) links to idEstablecimiento

Dashboard Analytics

Metrics are calculated per establishment

Alerts

AI-powered alerts are generated per location

Cost Tracking

Costs are segregated by establishment

Validation Rules

The createEstablishmentSchema validates:
// Schema validation (establishmentController.ts:10-14)
{
  nombre: string (required),
  localidad: string (required),
  provincia: string (required)
}
All fields are mandatory. Invalid submissions return a 400 error.
// User authentication check (establishmentController.ts:16-20)
const user = (req as any).user;
if (!user) {
  throw new AppError("Usuario no autenticado", 401);
}
Only authenticated users can create or list establishments.

Use Cases

Single Farm Operation

// Typical flow for one location
1. User registers and verifies email
2. Creates first establishment
3. System stores establishment ID in user context
4. All production tracked under that establishment

Multi-Farm Enterprise

// Managing multiple locations
1. User creates multiple establishments
2. Each establishment has unique ID
3. Production batches tagged with establishment ID
4. Dashboard filters by selected establishment
5. Analytics compare across locations

Integration with Other Features

1

Production Batches

Every batch requires an idEstablecimiento. The system validates the establishment exists and belongs to the user.
2

Dashboard

The dashboard service filters production data by establishment:
// dashboardService.ts:26-30
where: {
  establecimiento: { idUsuario: userId },
  fechaProduccion: { gte: fechaInicio, lte: fechaFin }
}
3

AI Alerts

The TamboEngine analyzes production patterns per establishment:
// tamboEngineService.ts:47-61
const lotes = await prisma.loteProduccion.findMany({
  where: {
    idEstablecimiento,
    estado: true,
    fechaProduccion: { gte: fechaLimite }
  }
});

Best Practices

Naming Convention

Use clear, descriptive names that identify the physical location (e.g., “Tambo Las Rosas - Planta Norte”)

Location Accuracy

Provide accurate province and locality for potential future features like regional analytics

Establishment Selector

For multi-establishment users, implement a dropdown or selector in the navigation

Context Persistence

Store the selected establishment in local storage or context to maintain user preference

Future Enhancements

Consider implementing:
  • Establishment editing (update name, location)
  • Establishment archiving (soft delete)
  • Role-based access for multi-user establishments
  • Establishment-level settings and preferences

API Reference

EndpointMethodAuthPurpose
/api/establishmentsPOSTRequiredCreate new establishment
/api/establishmentsGETRequiredList user’s establishments

Build docs developers (and LLMs) love