Catálogo

Proveedores, productos y elaboraciones propias: las listas de referencia a las que apunta el resto del registro.

El catálogo es aquello de lo que un restaurante lleva una lista en lugar de medirlo: quién entrega, qué entra por la puerta y qué hace la propia cocina. Nada de esto es un control ni una lectura. Son las filas que nombra todo lo demás, así que suelen ser lo primero que carga y lo último que cambia.

ColecciónPermisoQué es un registro
supplierssuppliers:readUna empresa que entrega, y cómo contactar con ella.
productsproducts:readAlgo que el restaurante recibe y usa, por su nombre.
preparationspreparations:readAlgo que hace la cocina, con su vida útil y sus alérgenos.

Las tres comparten el sobre de instantánea: id, deleted, capturedAt, receivedAt, sequence y los demás campos acompañan al data que se describe más abajo.

suppliers

Un registro por proveedor que el restaurante haya dado de alta, haya llegado algo de él últimamente o no.

CampoTipoSignificado
namestring, obligatorioEl proveedor tal como lo nombra el restaurante. Texto libre, no un registro mercantil.
isDeletedboolean, obligatorioLa marca de retirada propia de la aplicación. No es el deleted del sobre: véase más abajo.
contactMethodsobject[]Cómo contactar con ellos. Cada entrada es { "type": string, "value": string }.
accountNumberstring | nullLa cuenta del restaurante con este proveedor, cuando se introdujo una.
{
  "id": "1f3c2a76-5b94-4b0e-9c1a-6d8f0a2e7b31",
  "collection": "suppliers",
  "deleted": false,
  "capturedAt": "1789431600214",
  "receivedAt": "1789431604771",
  "sequence": "412",
  "data": {
    "name": "Metro Nanterre",
    "isDeleted": false,
    "contactMethods": [
      { "type": "phone", "value": "+33 1 41 20 30 40" },
      { "type": "email", "value": "commandes@example.test" }
    ],
    "accountNumber": "FR-884213"
  }
}

contactMethods[].type no es un enum. El esquema dice string y ahí se acaba, y los valores de arriba son una ilustración, no una lista. Haga el switch con una rama por defecto, y muestre el value esté escrito como esté el type.

Una entrega incrusta su proveedor en línea como { id, name }: lo justo para ponerlo en pantalla, y nada más. Esta colección es donde viven el número de cuenta y el teléfono.

products

Lo que el restaurante recibe y usa. El registro es tan escueto como parece.

CampoTipoSignificado
namestring, obligatorioEl producto tal como lo nombró el restaurante.
isDeletedboolean, obligatorioLa marca de retirada de la aplicación. Véase más abajo.
{
  "id": "6b0d4ea2-91c7-4f3d-a0be-2c5f7d1e8a44",
  "collection": "products",
  "deleted": false,
  "capturedAt": "1789431980551",
  "receivedAt": "1789432001903",
  "sequence": "413",
  "data": {
    "name": "Beurre doux 250 g",
    "isDeleted": false
  }
}

Ese es el registro entero: ni referencia, ni categoría, ni unidad, ni proveedor. Si su modelo necesita algo de eso, le toca a usted guardarlo, indexado por el id del sobre.

Nada más apunta a un producto por su id. Una entrega registra lo que se midió como temperatureRecords[].product, texto libre tecleado durante el control: véase entregas. Cuadrar eso con esta lista es trabajo de cadenas por su parte, y «Beurre doux 250 g» no es «beurre doux». Hágalo si no le queda más remedio, pero no presente el resultado como un join.

preparations

Algo hecho en casa en lugar de recibido: una salsa, un fondo, una terrina.

CampoTipoSignificado
namestring, obligatorioLa elaboración tal como la nombra la cocina.
lifespannumber, obligatorioCuánto se conserva. Un número a secas.
allergensstring[]Qué contiene. Cadenas libres, no un conjunto cerrado.
isDeletedboolean, obligatorioLa marca de retirada de la aplicación. Véase más abajo.
{
  "id": "c47e8b13-0a52-4d96-8f1b-73ae2905cd6f",
  "collection": "preparations",
  "deleted": false,
  "capturedAt": "1789455120087",
  "receivedAt": "1789455133642",
  "sequence": "418",
  "data": {
    "name": "Sauce béarnaise",
    "lifespan": 3,
    "allergens": ["oeuf", "lait"],
    "isDeleted": false
  }
}

lifespan no lleva unidad. El esquema le da un número y nada con que interpretarlo. No escriba «3 días» porque tres parezca días: confirme qué significa para la aplicación en el restaurante que está leyendo, y etiquételo con franqueza si no puede.

allergens es una lista de cadenas, no una lista reglamentaria. Las entradas vienen de la aplicación en el idioma del restaurante. No las mapee a los catorce alérgenos de declaración obligatoria sin comprobar qué dicen realmente las cadenas, y no tome un array vacío por un control de alérgenos superado: también significa que nadie lo rellenó.

isDeleted no es deleted

Todas las colecciones de esta página llevan los dos, significan cosas distintas, y quien filtre por uno solo se queda con una lista equivocada.

  • deleted, en el sobre, es la lápida de la copia en sombra. true significa que el registro se borró en la aplicación y que data ya no está. Es la manera de enterarse de que algo ha desaparecido: la página del sobre tiene las reglas.
  • isDeleted, dentro de data, es la marca de borrado lógico que la aplicación pone en la fila. El registro sigue ahí, sigue teniendo su nombre y sigue llegando con deleted: false. El restaurante lo retiró: dejó de ofrecerlo en los selectores y lo conservó para que los registros antiguos se sigan resolviendo.

Así que filtre por los dos. Respete solo deleted y su lista de proveedores se llena de proveedores que el restaurante dejó hace dos años. Respete solo isDeleted y conservará filas que se borraron del todo, porque una lápida no tiene data de donde leer la marca.

Aun así, conserve las filas retiradas en lugar de descartarlas. Una entrega del pasado marzo sigue nombrando a un proveedor que hoy tiene isDeleted: true, y resolver ese nombre es toda la razón por la que guarda esta lista.

Estas tres son pequeñas, cambian despacio y las necesita casi todo lo demás, lo que las convierte en la parte barata de una sincronización y en la parte fácil de equivocar sin darse cuenta.

  • Recórralas primero, consérvelas, refrésquelas con una periodicidad fija. El catálogo entero de un restaurante son un puñado de páginas con limit=100. Guárdelo en su propio almacén indexado por el id del sobre, y resuelva los nombres desde ahí en lugar de pedirlos registro a registro.
  • Los nombres cambian, los id no. name es texto libre que el restaurante edita durante el servicio. Guarde el id como clave y trate el nombre como una etiqueta que refresca, nunca como algo por lo que cruzar.
  • Aquí la ausencia también es ambigua. Un proveedor que no aparece puede que nunca se diera de alta, o puede que todavía no haya llegado hasta nosotros. Consulte la advertencia antes de dar un recuento.

Última actualización: 2026-09-20.