Catálogo

Fornecedores, produtos e preparações da casa — as listas de referência para as quais o resto do registo aponta.

O catálogo é aquilo de que um restaurante mantém uma lista em vez de medir: quem entrega, o que entra pela porta, e o que a cozinha faz por si. Nada aqui é um controlo ou uma leitura. Estas são as linhas que tudo o resto nomeia, por isso costumam ser a primeira coisa que carrega e a última que muda.

ColeçãoÂmbitoO que é um registo
supplierssuppliers:readUma empresa que entrega, e como chegar até ela.
productsproducts:readAlgo que o restaurante recebe e utiliza, pelo nome.
preparationspreparations:readAlgo que a cozinha faz, com o seu prazo de validade e os seus alergénios.

As três partilham o envelope de instantâneo: id, deleted, capturedAt, receivedAt, sequence e os restantes ficam ao lado do data descrito abaixo.

suppliers

Um registo por fornecedor que o restaurante tenha introduzido, tenha ou não chegado alguma coisa deles ultimamente.

CampoTipoSignificado
namestring, obrigatórioO fornecedor tal como o restaurante lhe chama. Texto livre, não um registo comercial.
isDeletedboolean, obrigatórioA marca de retirada da própria aplicação. Não é o deleted do envelope — veja abaixo.
contactMethodsobject[]Como chegar até eles. Cada entrada é { "type": string, "value": string }.
accountNumberstring | nullA conta do restaurante junto deste fornecedor, quando foi introduzida.
{
  "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 não é uma enumeração. O esquema diz string e fica-se por aí, e os valores acima são uma ilustração e não uma lista. Ramifique sobre ele com um caso por omissão, e mostre o value seja qual for a grafia do type.

Uma entrega traz o seu fornecedor embutido como { id, name } — o suficiente para pôr no ecrã, e mais nada. É nesta coleção que vivem o número de conta e o número de telefone.

products

O que o restaurante recebe e utiliza. O registo é tão magro como parece.

CampoTipoSignificado
namestring, obrigatórioO produto tal como o restaurante lhe chamou.
isDeletedboolean, obrigatórioA marca de retirada da aplicação. Veja abaixo.
{
  "id": "6b0d4ea2-91c7-4f3d-a0be-2c5f7d1e8a44",
  "collection": "products",
  "deleted": false,
  "capturedAt": "1789431980551",
  "receivedAt": "1789432001903",
  "sequence": "413",
  "data": {
    "name": "Beurre doux 250 g",
    "isDeleted": false
  }
}

É este o registo todo: sem referência, sem categoria, sem unidade, sem fornecedor. Se o seu modelo precisar de alguma dessas coisas, é a si que cabe mantê-las, indexadas pelo id do envelope.

Mais nada aponta para um produto por identificador. Uma entrega regista o que foi medido em temperatureRecords[].product, texto livre escrito durante o controlo — veja entregas. Fazer corresponder isso a esta lista é trabalho de cadeias de caracteres do seu lado, e «Beurre doux 250 g» não é «beurre doux». Faça-o se for preciso, mas não apresente o resultado como uma junção.

preparations

Algo feito na casa em vez de recebido — um molho, um caldo, uma terrina.

CampoTipoSignificado
namestring, obrigatórioA preparação tal como a cozinha lhe chama.
lifespannumber, obrigatórioQuanto tempo se conserva. Um número e mais nada.
allergensstring[]O que contém. Cadeias livres, não um conjunto fechado.
isDeletedboolean, obrigatórioA marca de retirada da aplicação. Veja abaixo.
{
  "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 não traz unidade nenhuma. O esquema dá-lhe um número e nada com que o interpretar. Não escreva «3 dias» só porque três parece dias — confirme o que a aplicação quer dizer com isso para o restaurante que está a ler, e identifique-o com clareza se não conseguir.

allergens é uma lista de cadeias de caracteres, não uma lista regulamentar. As entradas vêm da aplicação na língua do restaurante. Não as mapeie para os catorze alergénios nomeados sem verificar o que as cadeias dizem de facto, e não trate uma lista vazia como um controlo de alergénios feito e limpo — também significa que ninguém a preencheu.

isDeleted não é deleted

Todas as coleções desta página trazem os dois, significam coisas diferentes, e quem filtre por um deles fica com uma lista errada.

  • deleted, no envelope, é a marca de eliminação da cópia sombra. true significa que o registo foi apagado na aplicação e que o data desapareceu. É assim que fica a saber que alguma coisa desapareceu — a página do envelope tem as regras.
  • isDeleted, dentro do data, é a marca de eliminação lógica da própria aplicação sobre a linha. O registo continua lá, continua a ter o seu nome, e continua a chegar com deleted: false. O restaurante retirou-o: deixou de o oferecer nos seletores, e guardou-o para que os registos antigos continuem a resolver-se.

Por isso, filtre pelos dois. Respeite só o deleted e a sua lista de fornecedores enche-se de fornecedores que o restaurante abandonou há dois anos. Respeite só o isDeleted e fica com linhas que foram apagadas de vez, porque uma marca de eliminação não tem data de onde ler a marca.

Ainda assim, guarde as linhas retiradas em vez de as deitar fora. Uma entrega de março passado ainda nomeia um fornecedor que hoje está a isDeleted: true, e resolver esse nome é a razão inteira por que tem esta lista.

Estas três são pequenas, mudam devagar e são precisas para quase tudo o resto, o que faz delas a parte barata de uma sincronização e a parte fácil de errar sem dar por isso.

  • Percorra-as primeiro, guarde-as, atualize-as com regularidade. O catálogo inteiro de um restaurante são meia dúzia de páginas com limit=100. Guarde-o no seu próprio armazenamento, indexado pelo id do envelope, e resolva os nomes a partir daí em vez de ir buscar um por registo.
  • Os nomes mudam, os identificadores não. name é texto livre que o restaurante edita durante o serviço. Guarde o id como a sua chave e trate o nome como uma etiqueta que vai atualizando — nunca como algo pelo qual unir.
  • A ausência também é ambígua aqui. Um fornecedor que não apareça pode nunca ter sido introduzido, ou pode ainda não ter chegado até nós. Veja a nota de aviso antes de comunicar uma contagem.

Última atualização em 2026-09-20.