# Enfriamiento y procesos alimentarios

> Enfriamiento, congelación, recalentamiento y transporte: cuatro colecciones que registran una transición de temperatura, y qué aspecto tiene una sin terminar.

Source: https://developers.backresto.com/es/docs/food-processes

Un plato caliente que se enfría despacio pasa horas en el rango en que las
bacterias se multiplican, así que la regla es bajarlo rápido y poder demostrar
que se hizo. Cuatro colecciones registran ese tipo de transición. Tres son una
transición en el tiempo (bajar, bajar más, volver a subir) y la cuarta es la
misma idea en el espacio.

| Colección | Scope | Qué es un registro |
| --- | --- | --- |
| `cooling` | `cooling:read` | Un producto caliente bajado a temperatura de conservación en frío. |
| `freezing` | `freezing:read` | Un producto bajado hasta la congelación. |
| `reheating` | `reheating:read` | Un producto frío subido de nuevo a temperatura de servicio. |
| `transport` | `transport:read` | Un producto trasladado de un sitio a otro, con la temperatura en cada extremo. |

Las cuatro comparten el [sobre de snapshot](https://developers.backresto.com/es/docs/collections): `id`,
`deleted`, `capturedAt`, `receivedAt`, `sequence` y los demás campos acompañan
al `data` que se describe más abajo.

## `cooling`

Un ciclo: un producto, cuándo empezó y a qué temperatura estaba, cuándo terminó
y a qué temperatura acabó.

| Campo | Tipo | Significado |
| --- | --- | --- |
| `timestamp` | string, **obligatorio** | La marca propia del registro, en milisegundos desde la época Unix como cadena. No es el reloj del ciclo: eso son las dos fechas de abajo. |
| `product` | string, **obligatorio** | Qué se enfrió, como texto. |
| `beginDate` | string, **obligatorio** | Cuándo empezó el ciclo, en milisegundos desde la época Unix como cadena. |
| `beginTemperature` | number, **obligatorio** | La temperatura a la que empezó. |
| `endDate` | string \| null | Cuándo terminó. `null` mientras no lo haya hecho. |
| `endTemperature` | number \| null | La temperatura a la que terminó. `null` junto con `endDate`. |
| `reminderId` | string \| null | El recordatorio que la aplicación asoció al ciclo, cuando hubo uno. |
| `userId` | string \| null | El [miembro del personal](https://developers.backresto.com/es/docs/facilities) que lo registró, cuando la aplicación registró uno. |

```json
{
  "id": "0e5d1a7c-9f24-4b13-8d60-c1a7f0b25e94",
  "collection": "cooling",
  "deleted": false,
  "capturedAt": "1789779612441",
  "receivedAt": "1789779910228",
  "sequence": "1",
  "data": {
    "timestamp": "1789772400000",
    "product": "Blanquette de veau",
    "beginDate": "1789772400000",
    "beginTemperature": 63.5,
    "endDate": "1789779600000",
    "endTemperature": 8.2,
    "userId": "2774953d-8d9b-4a68-8ec4-1209edd90777"
  }
}
```

**`product` es un nombre, no una referencia.** No hay ningún `productId` en
estos registros, así que no puede cruzarlos con `products` sin comparar cadenas,
y las cadenas se teclean durante el servicio, en el idioma del restaurante.

**`reminderId` es opaco.** Ninguna colección de esta API lo resuelve. Llévelo
consigo si le ayuda a agrupar registros; no espere poder consultarlo.

## `freezing`

La misma forma, para un producto bajado a congelación en lugar de a temperatura
de nevera. Campo a campo, es `cooling`.

| Campo | Tipo | Significado |
| --- | --- | --- |
| `timestamp` | string, **obligatorio** | La marca propia del registro. |
| `product` | string, **obligatorio** | Qué se congeló. |
| `beginDate` | string, **obligatorio** | Cuándo empezó la operación. |
| `beginTemperature` | number, **obligatorio** | La temperatura a la que empezó. |
| `endDate` | string \| null | Cuándo terminó, o `null`. |
| `endTemperature` | number \| null | La temperatura a la que terminó, o `null`. |
| `reminderId` | string \| null | Como arriba. |
| `userId` | string \| null | Quién lo registró. |

Nada en el registro dice cuál de las tres es: eso lo dice la colección de la que
viene, y el campo `collection` del sobre lo refleja. Un pipeline que fusione las
tres en una sola tabla tiene que conservar esa columna.

## `reheating`

Un producto frío que se vuelve a subir. De nuevo la misma forma, leída en el
otro sentido: `beginTemperature` es la baja y `endTemperature` la alta.

| Campo | Tipo | Significado |
| --- | --- | --- |
| `timestamp` | string, **obligatorio** | La marca propia del registro. |
| `product` | string, **obligatorio** | Qué se recalentó. |
| `beginDate` | string, **obligatorio** | Cuándo entró. |
| `beginTemperature` | number, **obligatorio** | La temperatura a la que empezó. |
| `endDate` | string \| null | Cuándo salió, o `null`. |
| `endTemperature` | number \| null | La temperatura que alcanzó, o `null`. |
| `reminderId` | string \| null | Como arriba. |
| `userId` | string \| null | Quién lo registró. |

Una operación sin final tiene este aspecto:

```json
{
  "id": "b4c8e21d-3a76-4f58-9c02-77ad5e1b8f30",
  "collection": "reheating",
  "deleted": false,
  "capturedAt": "1789783221907",
  "receivedAt": "1789783402115",
  "sequence": "2",
  "data": {
    "timestamp": "1789783200000",
    "product": "Gratin dauphinois",
    "beginDate": "1789783200000",
    "beginTemperature": 4.1,
    "endDate": null,
    "endTemperature": null,
    "userId": "2774953d-8d9b-4a68-8ec4-1209edd90777"
  }
}
```

## `transport`

La misma transición, en el espacio en lugar de en el tiempo: de dónde salió el
producto y adónde llegó, con una temperatura en cada extremo.

| Campo | Tipo | Significado |
| --- | --- | --- |
| `timestamp` | string, **obligatorio** | La marca propia del registro. |
| `product` | string, **obligatorio** | Qué se transportó, como texto. |
| `departureLocation` | string, **obligatorio** | De dónde salió, como texto. |
| `departureTime` | string, **obligatorio** | Cuándo salió, en milisegundos desde la época Unix como cadena. |
| `departureTemperature` | number, **obligatorio** | La temperatura a la salida. |
| `arrivalLocation` | string \| null | Adónde llegó. `null` mientras no lo haya hecho. |
| `arrivalTime` | string \| null | Cuándo llegó, o `null`. |
| `arrivalTemperature` | number \| null | La temperatura a la llegada, o `null`. |
| `reminderId` | string \| null | Como arriba. |
| `userId` | string \| null | Quién lo registró. |

```json
{
  "id": "f31b6a08-5c47-4de9-b1a5-6e0c9d247b82",
  "collection": "transport",
  "deleted": false,
  "capturedAt": "1789786944610",
  "receivedAt": "1789787101883",
  "sequence": "3",
  "data": {
    "timestamp": "1789785000000",
    "product": "Plats préparés, service traiteur",
    "departureLocation": "Cuisine centrale",
    "departureTime": "1789785000000",
    "departureTemperature": 3.4,
    "arrivalLocation": "Salle Montparnasse",
    "arrivalTime": "1789786800000",
    "arrivalTemperature": 5.9,
    "userId": "2774953d-8d9b-4a68-8ec4-1209edd90777"
  }
}
```

Los dos lugares son texto libre, no [zonas](https://developers.backresto.com/es/docs/facilities) ni direcciones.
Son lo que tecleó la persona, y el extremo de llegada es exactamente tan
opcional como la temperatura de llegada: un registro puede llevar una salida y
nada más.

## Trabajar con estas colecciones

**Un final nulo son dos cosas distintas.** `endDate` y `endTemperature` (y
`arrivalTime`, `arrivalTemperature` y `arrivalLocation` en `transport`) admiten
`null`, y el registro no le dice por qué. Puede ser una operación que sigue en
curso mientras la lee, o una que nadie cerró nunca. Las dos tienen exactamente
el mismo aspecto.

Eso importa en cuanto calcule una duración. Las fechas son cadenas, así que
`endDate - beginDate` resta sin problema en un registro cerrado y, en uno
abierto, convierte `null` en cero y le devuelve un número negativo enorme en
lugar de un error. No salta ninguna excepción; su media simplemente está mal.
Filtre primero los registros cerrados, cuente los abiertos aparte y decida usted
a partir de qué antigüedad un registro abierto deja de estar en curso y pasa a
estar abandonado: nada en esta API toma esa decisión por usted.

**Calcule sobre `beginDate` y `endDate`, no sobre `timestamp`.** Las fechas son
el reloj de la operación. `timestamp` es el del propio registro, y no es la
materia de la que se hace una duración.

**Informe sobre `capturedAt`, sincronice por `receivedAt`.** Una tableta en una
cámara frigorífica sube los datos cuando encuentra cobertura, así que un ciclo
empezado a las 09:00 puede llegar a las 14:00.
[La página del sobre](https://developers.backresto.com/es/docs/collections) cuenta la historia completa.

**La ausencia no prueba nada.** Un producto sin registro de enfriamiento puede
que nunca se enfriara, o puede estar en un dispositivo que todavía no ha subido
nada. No convierta un recuento de estos en una cifra de cumplimiento: consulte
[la nota sobre exhaustividad](https://developers.backresto.com/es/docs/support).
