Saltar para o conteúdo
PMPaulo Mota
Voltar à demo

Como foi feito

A casa, por dentro

Como oito demonstrações passaram a ser uma casa sem se tornar um monólito.

01

O problema

Oito sistemas, cada um com a sua sala, cada um a contar a sua noite. O prato da ementa, o prato do take-away e a ficha técnica eram três linhas sem relação: uma venda não podia consumir stock porque não sabia que receita era. Um visitante via oito demonstrações bonitas e nenhuma casa.

02

Uma sala, uma ementa

Não há tabelas novas para a casa. As tabelas já pendiam todas de demo_rooms; a sala ganhou a lista de módulos ligados e passou a vir por contexto para todos os ecrãs, em vez de nascer oito vezes. E cada prato das duas ementas ganhou uma coluna, recipe_id, a apontar para a ficha técnica. Uma coluna, e a venda passou a saber o que consumir.

sql
-- Uma coluna em cada ementa, e a venda sabe o que consumir.
alter table demo_menu_items      add column recipe_id integer references demo_recipes(id);
alter table demo_takeaway_dishes add column recipe_id integer references demo_recipes(id);

-- A sala sabe que módulos tem ligados. Não há tabela nova para a casa.
alter table demo_rooms add column modules text[] not null default '{}';
TabelaPara que serve
demo_rooms.modulesQue módulos esta casa tem ligados. A única coluna nova na sala.
demo_menu_items.recipe_idA ficha técnica por trás de cada prato da sala. Nulo para o que não se cozinha (bebidas).
demo_takeaway_dishes.recipe_idO mesmo, para a ementa do take-away.
demo_order_items.consumed_atQuando a ficha consumiu, e stock_short se saiu sem stock que chegasse.
demo_eventsO registo do que atravessou módulos, por sala.
demo_haccp_deliveries.po_code, batch_idA entrada HACCP que veio de uma guia, ligada ao lote do stock.
03

Uma noite coerente

Abrir a casa semeia cada módulo ligado, uma vez: duas mesas a meio do serviço, duas reservas, uma encomenda de take-away em preparação, a abertura HACCP feita com o frigorífico da carne fora dos limites, a despensa com validades espalhadas, uma encomenda enviada ao talho, a escala da semana com quem já devia ter entrado a trabalhar. Todos os módulos contam a mesma noite porque são os mesmos ingredientes, a mesma equipa e a mesma ementa.

04

A venda consome no passe

Quando a cozinha marca um prato pronto, a ficha técnica consome os ingredientes por FEFO, com movimentos, dentro da mesma função que muda o estado. É no pronto e não no pedido, porque pedidos anulam-se e um prato que saiu do passe não volta. Sem stock a cozinha não pára: o prato sai marcado como saído sem stock e passa a esgotado nas duas ementas até entrar mercadoria. Só acontece em casas com stock ligado: um KDS sozinho não tem despensa e não finge que tem.

sql
-- No passe: marcar pronto consome, uma vez só, dentro da mesma função.
if p_done and not p_voided and v_row.consumed_at is null then
  select m.recipe_id into v_recipe from demo_menu_items m where m.id = v_row.menu_item_id;
  if v_recipe is not null then
    v_res := demo_consume_dish(p_room, v_recipe, v_row.qty, 'Mesa ' || v_order.table_id || ' · ' || v_row.name_snapshot);
    if v_res is not null then          -- null = casa sem stock ligado
      v_row.consumed_at := now();
      v_row.stock_short := (v_res->>'short')::boolean;
    end if;
  end if;
end if;

-- Quantas doses cada ficha ainda dá: o ingrediente mais curto manda.
select recipe_id, min(floor(disponivel / (qty_por_lote / doses))) from ...
05

O registo de acontecimentos

Cada coisa que atravessa um módulo para outro fica numa linha: a venda que consumiu, o lote que ficou abaixo do mínimo, a guia que chegou com dois quilos a menos, o incumprimento e a sua correcção, a mesa sentada, o ponto picado. O servidor guarda os dados; a frase faz-se no browser, na língua do visitante. A faixa no topo da casa é a ligação entre os sistemas a acontecer, em vez de afirmada num texto.

sql
-- Cada travessia fica numa linha. O texto faz-se no browser.
create table demo_events (
  id bigserial primary key,
  room_code text not null references demo_rooms(code) on delete cascade,
  at timestamptz not null default now(),
  module text not null, kind text not null,
  payload jsonb not null default '{}'
);
-- 'sale.consumed' {dish, ref, lines: [{ingredient, qty, allocation: [{batch, qty, left}]}]}
-- 'sale.short'    {dish, ingredient, needed, available}
-- 'po.received'   {code, status, batches, short}
-- 'haccp.fail'    {point, value, min, max}
06

Avançar o serviço não é fingir tempo

Uma casa aberta às cinco da manhã está parada. Avançar o serviço dá um passo na noite com as mesmas funções que os ecrãs usam: até três passos de módulos diferentes por carga, e devolve o que fez. Não há relógio falso, não há dados encenados: cada passo podia ter sido feito à mão e fica registado como tal. Um visitante vê uma noite inteira em dez cargas.

07

Uma só porta para a mercadoria

A recepção HACCP e a conferência da guia registavam o mesmo camião duas vezes, com dois lotes que nunca se encontravam. Agora conferir a guia cria os lotes no stock e, se a casa tem HACCP, escreve o registo de recepção com temperatura, lote e validade, ligado ao lote, na mesma transacção. Um prato servido leva ao lote, o lote leva à guia, a guia leva à temperatura a que a carne entrou. O formulário do HACCP fica para o que chega sem encomenda.

sql
-- Conferir a guia faz as duas coisas na mesma transacção.
v_batch := demo_stock_receive(p_room, ingrediente, v_good, preco_da_encomenda, validade, local, fornecedor, p_by);

if v_haccp then
  insert into demo_haccp_deliveries (room_code, supplier, product, kind, batch, expiry, qty, unit,
                                     temp_c, temp_ok, accepted, signed_by, po_code, batch_id)
  values (p_room, fornecedor, ingrediente, tipo, v_batch.code, validade, v_recv, unidade,
          p_temp, p_temp <= 4.0, v_good > 0, p_by, v_po.code, v_batch.id);
end if;
08

O que faria diferente num cliente real

Utilizadores com sessão e políticas por linha em vez de um código de sala: o empregado de sala não vê o custo-hora dos colegas. Perfis, em vez de um botão para trocar de lado. O painel com histórico, não só hoje. Sub-receitas e perdas de preparação, para o consumo ser exacto. E a caixa registadora ligada, para a venda ser a venda e não um pedido entregue.