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ón | Permiso | Qué es un registro |
|---|---|---|
suppliers | suppliers:read | Una empresa que entrega, y cómo contactar con ella. |
products | products:read | Algo que el restaurante recibe y usa, por su nombre. |
preparations | preparations:read | Algo 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.
| Campo | Tipo | Significado |
|---|---|---|
name | string, obligatorio | El proveedor tal como lo nombra el restaurante. Texto libre, no un registro mercantil. |
isDeleted | boolean, obligatorio | La marca de retirada propia de la aplicación. No es el deleted del sobre: véase más abajo. |
contactMethods | object[] | Cómo contactar con ellos. Cada entrada es { "type": string, "value": string }. |
accountNumber | string | null | La 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.
| Campo | Tipo | Significado |
|---|---|---|
name | string, obligatorio | El producto tal como lo nombró el restaurante. |
isDeleted | boolean, obligatorio | La 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.
| Campo | Tipo | Significado |
|---|---|---|
name | string, obligatorio | La elaboración tal como la nombra la cocina. |
lifespan | number, obligatorio | Cuánto se conserva. Un número a secas. |
allergens | string[] | Qué contiene. Cadenas libres, no un conjunto cerrado. |
isDeleted | boolean, obligatorio | La 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.truesignifica que el registro se borró en la aplicación y quedataya no está. Es la manera de enterarse de que algo ha desaparecido: la página del sobre tiene las reglas.isDeleted, dentro dedata, 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 condeleted: 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.
Leer el catálogo
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 eliddel sobre, y resuelva los nombres desde ahí en lugar de pedirlos registro a registro. - Los nombres cambian, los id no.
namees texto libre que el restaurante edita durante el servicio. Guarde elidcomo 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.