# Limpieza

> El plan de limpieza, las tareas realmente hechas y las fotografías que lo demuestran: tres colecciones y qué no prueba un registro ausente.

Source: https://developers.backresto.com/es/docs/cleaning

La limpieza en la aplicación es un plan y su prueba. El restaurante anota qué
hay que limpiar, dónde y con qué frecuencia; el personal va marcando las tareas
a medida que las hace; algunas de esas tareas exigen una fotografía. Tres
colecciones, una por capa, y el cruce entre ellas es donde está casi todo el
trabajo.

| Colección | Scope | Qué es un registro |
| --- | --- | --- |
| `cleaning-tasks` | `cleaning-tasks:read` | Una línea del plan: qué hay que limpiar, dónde, con qué frecuencia, si necesita una fotografía. |
| `cleaning-task-records` | `cleaning-task-records:read` | Una tarea hecha de verdad: cuándo y por quién. |
| `cleaning-task-pictures` | `cleaning-task-pictures:read` | La fotografía que lo demuestra. Lleva un archivo. |

Las tres 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.

## `cleaning-tasks`

El plan en sí. Cambian poco (un restaurante escribe su plan una vez y lo edita
cuando cambia la cocina), así que esta es la colección que menos veces recorrerá
y la que más tiempo puede conservar en caché.

| Campo | Tipo | Significado |
| --- | --- | --- |
| `index` | integer, **obligatorio** | La posición de la tarea en el plan, según la ordena la aplicación. |
| `name` | string, **obligatorio** | Qué hay que limpiar, en las palabras del restaurante. |
| `description` | string \| null | Instrucciones más largas, cuando alguien las escribió. |
| `areaId` | string \| null | La [zona](https://developers.backresto.com/es/docs/facilities) a la que pertenece. `null` en un restaurante que no se divide en zonas. |
| `recurrence` | integer, **obligatorio** | Cada cuánto vuelve la tarea, como un entero a secas. |
| `requirePhotoProof` | boolean \| null | `true` cuando la tarea exige una fotografía. `null` significa que la aplicación nunca lo fijó. |
| `isDeleted` | boolean, **obligatorio** | El soft delete propio de la aplicación. Lea la nota de abajo. |

```json
{
  "id": "c9a4f7e2-1b83-4d05-a6f1-90e3b7c4d218",
  "collection": "cleaning-tasks",
  "deleted": false,
  "capturedAt": "1789601204773",
  "receivedAt": "1789601399042",
  "sequence": "1",
  "data": {
    "index": 3,
    "name": "Nettoyage de la trancheuse",
    "description": "Démonter la lame, dégraisser, désinfecter.",
    "areaId": "7d2c0b61-4e8a-49f3-9c27-5a1b8e60d3f4",
    "recurrence": 1,
    "requirePhotoProof": true,
    "isDeleted": false
  }
}
```

**`recurrence` no lleva unidad.** Es un entero y el registro no dice qué cuenta.
Muéstrelo como lo muestra la aplicación en lugar de escribir «cada 1 días» a
partir de una suposición.

**`isDeleted` no es el `deleted` del sobre.** Una tarea que el restaurante quitó
de su plan vuelve con `isDeleted: true` y `deleted: false`: sigue siendo un
registro vivo, que describe una línea que ya no se aplica. Filtre por los dos y
conserve las borradas: los registros antiguos siguen apuntando a ellas.

## `cleaning-task-records`

Una tarea hecha. Pequeño a propósito: qué tarea, cuándo, quién.

| Campo | Tipo | Significado |
| --- | --- | --- |
| `timestamp` | string, **obligatorio** | Cuándo se hizo la tarea, en milisegundos desde la época Unix como cadena. |
| `cleaningTaskId` | string, **obligatorio** | El registro de `cleaning-tasks` que satisface. |
| `userId` | string \| null | El [miembro del personal](https://developers.backresto.com/es/docs/facilities) que la hizo, cuando la aplicación registró uno. |

```json
{
  "id": "5f8b3d16-2c90-4a77-b4e8-31d0a9c65f7b",
  "collection": "cleaning-task-records",
  "deleted": false,
  "capturedAt": "1789775012558",
  "receivedAt": "1789775204910",
  "sequence": "2",
  "data": {
    "timestamp": "1789774800000",
    "cleaningTaskId": "c9a4f7e2-1b83-4d05-a6f1-90e3b7c4d218",
    "userId": "2774953d-8d9b-4a68-8ec4-1209edd90777"
  }
}
```

`cleaningTaskId` es obligatorio, así que todo registro tiene una tarea. Lo
contrario no se cumple: una tarea puede estar en el plan sin ningún registro
durante semanas, y ese es el estado normal de una tarea semanal un martes.

## `cleaning-task-pictures`

La fotografía. Lleva un archivo, lo que la convierte en la única colección de
esta página que no puede consumir solo desde el endpoint de registros.

| Campo | Tipo | Significado |
| --- | --- | --- |
| `timestamp` | string, **obligatorio** | Cuándo se tomó la fotografía, en milisegundos desde la época Unix como cadena. |
| `cleaningTaskRecordId` | string \| null | El registro de `cleaning-task-records` del que es prueba. Admite `null`: véase más abajo. |
| `part` | number \| null | Sin documentar, y un decimal en lugar de un contador. Páselo tal cual en lugar de interpretarlo: la misma advertencia que en las [etiquetas de trazabilidad](https://developers.backresto.com/es/docs/traceability-labels). |
| `groupId` | string \| null | Vincula esas fotografías entre sí. Los registros que comparten un `groupId` pertenecen a la misma prueba. |
| `asset` | object, **obligatorio** | Nombra el archivo: `objectKey` y `status` siempre, más `contentType`, `byteLength` y `sha256` una vez subido. |

```json
{
  "id": "2d71c8a9-6e34-4b0f-8517-ac93e25d0b46",
  "collection": "cleaning-task-pictures",
  "deleted": false,
  "capturedAt": "1789775118330",
  "receivedAt": "1789775301774",
  "sequence": "3",
  "data": {
    "timestamp": "1789774860000",
    "cleaningTaskRecordId": "5f8b3d16-2c90-4a77-b4e8-31d0a9c65f7b",
    "part": 1,
    "groupId": "a03e5c88-71bd-4f92-b6d4-2e8f10c73a5b",
    "asset": {
      "objectKey": "cleaning-task-pictures/2d71c8a9/1.jpg",
      "status": "uploaded",
      "contentType": "image/jpeg",
      "byteLength": 812043,
      "sha256": "9f2a…"
    }
  }
}
```

Los bytes son una segunda llamada, contra el propio id del registro:

```http
GET /v1/restaurants/{restaurantId}/collections/cleaning-task-pictures/records/{recordId}/assets
```

Responde con una lista de URL firmadas, cada una válida durante **quince
minutos** y con su propia autorización, de modo que la descarga no necesita
cabecera. Descargue los bytes ahora, guarde los bytes en lugar del enlace y
vuelva a llamar al endpoint cuando necesite una URL nueva. Las reglas (qué
aparece, para qué sirve `sha256`, por qué conviene leer `contentType`) están en
[la página de colecciones](https://developers.backresto.com/es/docs/collections), y aquí son las mismas.

**`asset.status` le dice si hay bytes que descargar.** Es `pending` o
`uploaded`. Un archivo `pending` es una fotografía que el dispositivo ha
anunciado y todavía no ha terminado de enviar: el registro es real, el archivo
no, y el endpoint de archivos adjuntos responde sin él. Lea el estado antes de
tomar una lista de archivos vacía por una fotografía que nunca se hizo.

**`cleaningTaskRecordId` admite `null`.** Una fotografía puede existir sin
apuntar a ningún registro, así que un cruce que dé por hecho que siempre está
ahí pierde fotografías por el camino. Cuéntelas aparte en lugar de descartarlas
en silencio.

## Cruzar las tres

La forma que casi seguro quiere es una fila por tarea hecha, con su línea del
plan y sus fotografías:

- `cleaning-task-records.cleaningTaskId` → `cleaning-tasks.id`
- `cleaning-task-pictures.cleaningTaskRecordId` → `cleaning-task-records.id`

Tres recorridos, unidos por su parte. No hay ningún endpoint que lo haga por
usted, y no hay filtro por tarea ni por fecha: recorre cada colección entera y
concilia, como describe [la página del sobre](https://developers.backresto.com/es/docs/collections).

Informe sobre `capturedAt` y sincronice por `receivedAt`: una tableta en una
cámara frigorífica sube los datos cuando encuentra cobertura, y una fotografía
tomada a las 09:00 puede llegar a las 14:00, después del registro al que
pertenece o antes que él.

## Qué no significa un registro ausente

**Una línea del plan sin registro que le corresponda no prueba que la tarea se
omitiera.** Puede haberse hecho en un dispositivo que todavía no ha subido nada,
o antes de que se activara la captura para ese restaurante. Lo mismo vale para
una tarea marcada con `requirePhotoProof: true` y sin ninguna fotografía: la
fotografía puede estar a mitad de subida, y un archivo cuya subida no ha
terminado está ausente, no roto.

Así que no saque de esta API una tasa de cumplimentación de la limpieza y la
llame cumplimiento. Lo que puede decir con honestidad es qué llegó y cuándo:
consulte [la nota sobre exhaustividad](https://developers.backresto.com/es/docs/support) antes de poner una cifra
delante de nadie.
