pizza-digital/SPEC.md
Admin d669f56398 Import Pizza Digital SPECs and docs from Obsidian vault sync
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-11-09 19:52:34 +00:00

724 lines
29 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# SPEC — Pizza Digital
| Campo | Valor |
|-------|--------|
| **Produto** | Pizza Digital |
| **Versão do SPEC** | **0.3.2** |
| **Status** | Fase 1 cozinha no ar · **Prioridade seguinte: entrada por canais digitais** |
| **Data** | 2026-07-23 · rev. matriz acesso 2026-10-19 |
| **Owner** | Roger / iTecnologys |
| **Host Dev** | Proxmox BIG · VMID **125** · `10.10.10.125` · user `mini` |
| **URL pública** | `https://pizza.itecnologys.com` (legado SPEC: pizza.myvexx.com) |
| **Detalhe Fase 1** | [`docs/SPEC-FASE1.md`](docs/SPEC-FASE1.md) |
| **Canais digitais** | [`docs/SPEC-CANAIS-DIGITAIS.md`](docs/SPEC-CANAIS-DIGITAIS.md) · §5.5 |
| **Cardápio** | [`docs/SPEC-CARDAPIO.md`](docs/SPEC-CARDAPIO.md) · RF-MEN · Joinville |
| **Estoque** | [`docs/SPEC-ESTOQUE.md`](docs/SPEC-ESTOQUE.md) · RF-EST · BOM ↔ menu |
| **Matriz de acesso** | [`docs/SPEC-MATRIZ-ACESSO.md`](docs/SPEC-MATRIZ-ACESSO.md) · `/acessos` · RF-ACS |
| **Sequência oficial** | §15 — S0…S9 · Track C · Track M/E · Matriz ACS |
| **Referência principal** | CityFoods — Cozinha Digital + Cardápio Digital (`@cityfoods_app`) |
| **KDS / estações** | kitchenOS + restaurant-pos + este SPEC |
| **Rotas / dispatch** | **rusterando** = referência oficial (ORS, driver tour) — AGPL: modelo operacional, não fork do core |
| **Repos open-source** | kitchenOS, rusterando, URY Mosaic, MaSoVa, Tasty-Station |
---
## 1. Visão
**Pizza Digital** é uma plataforma de operação de delivery para pizzarias, restaurantes e outras cozinhas, com foco em **Cozinha Digital (KDS)**: eliminar comanda de papel, organizar produção por estações, reduzir erros e acelerar despacho.
Não é um marketplace. É o **sistema operacional da cozinha + delivery próprio**, no mesmo espírito da CityFoods:
> Cozinha Digital não é sobre robôs — é inteligência e fluxo à prova de falhas, do pedido à entrega.
### 1.1 Problema
Operações de delivery perdem tempo e clientes por:
- Comandas de papel (perda, rasura, leitura ruim)
- Pedidos de vários canais em telas diferentes
- Falta de priorização (pedido novo não sai junto de outros prontos)
- Erros de observação / montagem
- Motoboys mal roteados (ida e volta na mesma região)
- Zero métrica de tempo por estação
### 1.2 Promessa
Uma plataforma única que:
1. Recebe pedidos (PDV, cardápio digital, marketplaces)
2. Distribui por **estações de cozinha** (KDS)
3. Identifica pedidos por **etiquetas**
4. Prioriza e agrupa saída
5. Despacha com **gestão de rotas**
6. Mede **tempo e produtividade** em tempo real
### 1.3 Posicionamento
| | CityFoods (referência) | Pizza Digital (nossa) |
|--|------------------------|------------------------|
| Foco | Delivery multi-tipo | **Pizzaria primeiro**, depois outras cozinhas |
| Diferencial citado | “Primeira Cozinha Digital” | Cozinha Digital + templates de estação por tipo de negócio |
| Mercado | SC / BR SaaS | Começar local / controlado, evoluir para SaaS multi-tenant |
---
## 2. Objetivos e métricas de sucesso
### 2.1 Objetivos de produto (MVP)
- Substituir comanda de papel por KDS touch
- Operar **1 pizzaria piloto** de ponta a ponta (pedido → pronto → despacho)
- Reduzir erros de montagem / observação
- Medir tempo médio por estação e por pedido
### 2.2 KPIs (piloto)
| KPI | Meta inicial (90 dias) |
|-----|------------------------|
| Erros de pedido (reclamação / refazer) | −50% vs baseline |
| Tempo médio pedido → pronto | −20% |
| Pedidos sem papel na cozinha | 100% no piloto |
| Atraso de despacho (> SLA) | −30% |
| Adoção diária do KDS | ≥ 95% dos pedidos passam pelo KDS |
### 2.3 Não-objetivos (MVP)
- App consumidor nativo (iOS/Android) completo
- Marketplace próprio
- Contabilidade / ERP completo
- Multi-país / multi-moeda
- IA generativa na cozinha
---
## 3. Personas e papéis
| Papel | Quem | Precisa |
|-------|------|---------|
| **Operador KDS** | Cozinheiro / pizzaiolo | Tela grande, bump rápido, ver observações |
| **Expedição** | Embalador / conferente | Pedido completo, etiqueta, agrupar saída |
| **Caixa / PDV** | Atendente | Lançar pedido balcão / telefone |
| **Despachante** | Quem libera motoboy | Agrupar por região, priorizar |
| **Entregador** | Motoboy | Lista de entregas, status, navegação básica |
| **Gestor** | Dono / gerente | Métricas, cardápio, usuários, relatórios |
| **Admin SaaS** (fase 2) | iTecnologys | Multi-loja, billing, suporte |
---
## 4. Escopo por fases
### Fase 0 — Fundação (esta SPEC + bootstrap)
- Repositório, monorepo, CI mínimo
- Modelo de domínio e eventos
- Ambiente local (Docker)
### Fase 1 — MVP Cozinha Digital (core) ✅ em andamento
> Detalhe completo: [`docs/SPEC-FASE1.md`](docs/SPEC-FASE1.md) · Host: VM **125** `10.10.10.125`
- Pedidos manuais (PDV web)
- KDS multi-estação (pizzaria)
- Status: `novo → em_preparo → pronto → despachado → entregue`
- Priorização / reordenação de fila
- Etiquetas (impressão ESC/POS ou PDF fallback)
- Painel gestor básico (tempos)
- Stack: NestJS + React + Postgres + Redis + Socket.io (Docker na VM 125)
### Fase 2 — Delivery operacional (após KDS estável)
> Prioridade de construção: **KDS multi-estação primeiro**; delivery/rotas só depois do piloto de cozinha (S5).
> Referência oficial de dispatch: **[rusterando](https://github.com/holg/rusterando)** (kitchen → driver tour → ORS). Detalhe: §15.1 e §15.2.
- Gate `order.ready` → fila de despacho
- Agrupar por bairro (manual + sugestão) + atribuir motoboy + reordenar saída (“2 cliques” CityFoods)
- OpenRouteService (padrão rusterando) para ordem da rota
- Mapa no despacho · PWA entregador · tracking
- Pagamento/comissão por entrega · fechamento de caixa básico
### Fase 3 — Canais digitais e SaaS (PRIORIDADE pós-S5)
> Track **C** (canais) começa em paralelo assim que o piloto de cozinha (S5) estiver estável — **não esperar o fim de S6–S8**.
> Ver §5.5 e [`docs/SPEC-CANAIS-DIGITAIS.md`](docs/SPEC-CANAIS-DIGITAIS.md).
- **C1** Cardápio digital público (PWA) + checkout (Pix / dinheiro na entrega)
- **C1** Pedidos digitais no quadro `/pedidos` com badge de origem
- **C2** Integração iFood (webhook → pedido normalizado)
- Multi-tenant / multi-loja
- Relatórios operacionais avançados
- Templates de cozinha: pizzaria, hamburgueria, sushi, dark kitchen
---
## 5. Conceito operacional — Cozinha Digital
### 5.1 Estações (template Pizzaria)
| Estação | Responsabilidade | Exemplos de itens |
|---------|------------------|-------------------|
| **Massa** | Abrir / preparar base | Massa, borda |
| **Montagem** | Molho, queijo, toppings | Sabores, adicionais |
| **Forno** | Assar | Pizza em forno |
| **Expedição** | Embalar, conferir, etiquetar | Pedido completo |
| **Bebidas** (opcional) | Separar frios | Refrigerante, água |
**Princípio KDS (CityFoods — claim exclusivo):**
1. A **fila chega para todas** as estações.
2. Uma estação **escolhe e puxa (PEGAR)** um ou mais pedidos para si.
3. Com o claim, **as outras estações ficam bloqueadas** de pegar aquele pedido.
4. Só a estação dona dá **BUMP** (pedido pronto).
Regras de mapeamento (histórico / tickets):
- Cada item do cardápio mapeia para **1+ estações** (referência de produção)
- Claim é ao nível do **pedido completo**, não por item
### 5.2 Template futuro — outras cozinhas
| Tipo | Estações padrão |
|------|-----------------|
| Hamburgueria | Grelha · Fritura · Montagem · Expedição |
| Sushi | Corte · Montagem · Expedição |
| Dark kitchen genérica | Prep · Quente · Frios · Expedição |
### 5.3 Etiquetas
Cada pedido (ou item, configurável) gera etiqueta com:
- Código curto do pedido (ex: `#A42`)
- Canal (PDV / iFood / Cardápio)
- Cliente (nome parcial)
- Itens resumidos + observações em destaque
- Horário / timer SLA
- QR opcional para conferência
Objetivo: eliminar grampear comanda ilegível na embalagem.
### 5.4 Priorização (inspirado CityFoods “2 cliques”)
O despachante/gestor pode:
- Reordenar fila de saída
- Agrupar pedidos da mesma região para sair juntos
- Marcar pedido como **urgente** (sobresai visualmente no KDS)
### 5.5 Entrada por canais digitais (PRIORIDADE)
> Detalhe de produto: [`docs/SPEC-CANAIS-DIGITAIS.md`](docs/SPEC-CANAIS-DIGITAIS.md) · RFs: RF-CAN, RF-PED-08/09, RF-MEN-04/06/07, RF-INT-01/03/05
**Problema:** pedidos chegam por telefone, WhatsApp e iFood em telas diferentes — a loja digita de novo no PDV e erra.
**Promessa:** o cliente pede no canal digital; a loja vê **o mesmo Order** no quadro `/pedidos` e a cozinha trata igual a pedido de balcão.
#### Dimensões (substituem `channel` misturado)
| Dimensão | Valores | Uso na UI |
|----------|---------|-----------|
| `origin` | `pdv` · `cardapio` · `ifood` · `whatsapp` · `telefone` | Badge no card (CARDÁPIO / IFOOD / …) |
| `fulfillment` | `entrega` · `retirada` · `mesa` | Faixa ENTREGA / RETIRADA (CityFoods) |
#### Canais de entrada → um quadro
```text
Cardápio PWA /c/:slug ─┐
WhatsApp (deep-link) ─┼─► Order Ingest (schema único)
iFood webhook ─┤ │
PDV / telefone (staff) ─┘ ▼
/pedidos (badge origem + fulfillment)
│
▼
KDS · Etiqueta · Despacho
```
#### Track C (após piloto S5; C1 pode prototipar em paralelo)
| Track | Entrega |
|-------|---------|
| **C1** | Cardápio público + checkout (Pix / pagar na entrega) → `/pedidos` ≤ 500 ms |
| **C2** | Webhook iFood → normalizador + idempotência |
**Regra de ouro:** nenhum canal tem UI de cozinha própria — tudo passa pelo Order bus e pelo `/pedidos`.
---
## 6. Fluxos principais
### 6.1 Fluxo feliz — delivery pizzaria (canal digital ou PDV)
```text
[Cliente] Cardápio /c/:slug | WhatsApp | iFood
[Staff] PDV /pedidos (+ Novo)
→ Order Ingest normaliza (origin + fulfillment + itens)
→ Aparece em /pedidos (badge origem · faixa ENTREGA/RETIRADA)
→ Roteia itens → estações KDS
→ Operadores dão claim/bump por estação
→ Expedição confere + imprime etiqueta (origem + fulfillment)
→ Pedido = PRONTO
→ Despacho atribui motoboy / agrupa rota
→ Entregador: saiu → entregue
→ Métricas gravadas (tempos por etapa)
```
### 6.2 Estados do pedido
```text
rascunho → confirmado → em_producao → pronto → em_rota → entregue
↓
cancelado
```
Estados de **item na estação**:
```text
na_fila → em_preparo → concluido | cancelado
```
### 6.3 Diagrama lógico
```text
Canais Core Operação
───── ──── ────────
PDV ──────┐
Cardápio ─┼─► Order Ingest ─► Router ─► KDS Stations
iFood ────┘ │ │ │
│ │ ▼
│ └──► Labels / Print
▼
Order Store ◄── WebSocket fan-out
│
▼
Dispatch / Routes ─► Driver PWA
│
▼
Analytics
```
---
## 7. Requisitos funcionais
### 7.1 Pedidos (RF-PED)
| ID | Requisito | MVP |
|----|-----------|-----|
| RF-PED-01 | Criar pedido no PDV (itens, adicionais, obs, tipo: delivery/balcão/mesa) | Sim |
| RF-PED-02 | Schema único de pedido independente do canal | Sim |
| RF-PED-03 | Editar pedido até entrar em produção (política configurável) | Sim |
| RF-PED-04 | Cancelar pedido com motivo | Sim |
| RF-PED-05 | Observações em destaque no KDS | Sim |
| RF-PED-06 | Número sequencial diário + código curto legível | Sim |
| RF-PED-07 | Ingestão via webhook (iFood etc.) | Track C2 |
| RF-PED-08 | Campos `origin` + `fulfillment` (em vez de channel misturado) | Track C1 |
| RF-PED-09 | Pedido digital aparece no `/pedidos` em tempo real (WS) | Track C1 |
### 7.2 KDS / Cozinha Digital (RF-KDS)
| ID | Requisito | MVP |
|----|-----------|-----|
| RF-KDS-01 | Tela KDS por estação (filtro de área) | Sim |
| RF-KDS-02 | Atualização em tempo real (WebSocket, sem polling) | Sim |
| RF-KDS-03 | Timer visual (verde / amarelo / vermelho por SLA) | Sim |
| RF-KDS-04 | Bump item / bump pedido na estação | Sim |
| RF-KDS-05 | Multi-estação no mesmo pedido | Sim |
| RF-KDS-06 | Som/alerta opcional de novo ticket | Sim |
| RF-KDS-07 | Modo tela cheia / tablet / TV | Sim |
| RF-KDS-08 | Offline degradado (fila local + sync) | Fase 2 |
### 7.3 Etiquetas (RF-ETQ)
| ID | Requisito | MVP |
|----|-----------|-----|
| RF-ETQ-01 | Gerar etiqueta ao concluir expedição (ou sob demanda) | Sim |
| RF-ETQ-02 | Impressão térmica ESC/POS | Sim (com fallback PDF) |
| RF-ETQ-03 | Layout configurável por loja | Fase 2 |
### 7.4 Despacho e rotas (RF-ROT)
| ID | Requisito | MVP |
|----|-----------|-----|
| RF-ROT-01 | Lista de pedidos prontos para despacho | Fase 1 (lista simples) |
| RF-ROT-02 | Atribuir entregador | Fase 2 |
| RF-ROT-03 | Agrupar por bairro / proximidade | Fase 2 |
| RF-ROT-04 | Reordenar saída (priorização) | Fase 1 |
| RF-ROT-05 | App/PWA entregador com status | Fase 2 |
| RF-ROT-06 | Cálculo de pagamento de entregadores | Fase 3 |
### 7.5 Cardápio e PDV (RF-MEN)
> Detalhe: [`docs/SPEC-CARDAPIO.md`](docs/SPEC-CARDAPIO.md) · pesquisa [`docs/CARDAPIO-JOINVILLE.md`](docs/CARDAPIO-JOINVILLE.md)
> Ponte estoque: [`docs/SPEC-ESTOQUE.md`](docs/SPEC-ESTOQUE.md)
| ID | Requisito | MVP |
|----|-----------|-----|
| RF-MEN-01 | CRUD categorias, itens, preços, adicionais | Sim |
| RF-MEN-02 | Mapear item → estações KDS | Sim |
| RF-MEN-03 | Tempo SLA por categoria/item | Sim |
| RF-MEN-04 | Cardápio digital público (PWA cliente) | **Track C1** |
| RF-MEN-05 | Combos / meia-a-meia (pizzaria) | Fase 1 (meia-a-meia) |
| RF-MEN-06 | Horário de funcionamento / loja aberta-fechada no cardápio | Track C1 |
| RF-MEN-07 | Áreas de entrega + taxa por bairro no cardápio | Track C1 |
| RF-MEN-08 | Tamanhos com preço (`broto`/`grande`/…) | Track M1 |
| RF-MEN-09 | Pausar item (manual ou estoque baixo) | Track M1 |
| RF-MEN-10 | Ficha técnica (BOM) ligada ao item | Track M1 ↔ EST |
| RF-MEN-11 | Bebida `stockMode=sku` 1:1 | Track M1 |
| RF-MEN-12 | Vitamina/suco natural via BOM | Track M1 |
### 7.6 Gestão e métricas (RF-GES)
| ID | Requisito | MVP |
|----|-----------|-----|
| RF-GES-01 | Dashboard: pedidos abertos, atrasados, tempo médio | Sim |
| RF-GES-02 | Tempo médio por estação | Sim |
| RF-GES-03 | Relatório de fluxo do pedido (timestamps) | Sim |
| RF-GES-04 | Usuários, papéis, permissões | Sim |
| RF-GES-05 | Multi-loja / tenant | Fase 3 |
### 7.7 Integrações (RF-INT)
| ID | Requisito | Fase |
|----|-----------|------|
| RF-INT-01 | Webhook genérico de pedido | Track C1 |
| RF-INT-02 | iFood (ou agregador BR) | Track C2 |
| RF-INT-03 | Pagamento online (Pix / dinheiro na entrega) | Track C1 |
| RF-INT-04 | Impressoras de rede | 1 |
| RF-INT-05 | Deep-link WhatsApp → cardápio da loja | Track C1 |
### 7.8 Canais digitais (RF-CAN)
| ID | Requisito | Track |
|----|-----------|-------|
| RF-CAN-01 | PWA cardápio público por loja (`/c/:slug`) | C1 |
| RF-CAN-02 | Carrinho cliente → Order com `origin=cardapio` | C1 |
| RF-CAN-03 | Escolha fulfillment entrega/retirada no cardápio | C1 |
| RF-CAN-04 | Taxa / área de entrega no checkout | C1 |
| RF-CAN-05 | Pedido digital no `/pedidos` ≤ 500 ms (WS) | C1 |
| RF-CAN-06 | Badge de origem no card (CARDÁPIO / IFOOD / …) | C1 |
| RF-CAN-07 | Webhook iFood → normalizador | C2 |
| RF-CAN-08 | Idempotência / dedupe de pedidos externos | C2 |
### 7.9 Estoque (RF-EST)
> Detalhe: [`docs/SPEC-ESTOQUE.md`](docs/SPEC-ESTOQUE.md) · dispara a partir do Order · pausa o Cardápio
| ID | Requisito | Track |
|----|-----------|-------|
| RF-EST-01 | CRUD insumos (unidade, min, custo) | E1 |
| RF-EST-02 | Ficha técnica por MenuItem | E1 |
| RF-EST-03 | Baixa automática no pedido (`em_producao`) | E1 |
| RF-EST-04 | Entrada compra / ajuste manual | E1 |
| RF-EST-05 | Alerta estoque mínimo (WS) | E1 |
| RF-EST-06 | Pausa automática do item no cardápio | E2 |
| RF-EST-07 | Estorno em cancelamento elegível | E1 |
| RF-EST-08 | CMV teórico por dia/item | E2 |
| RF-EST-13 | Ficha por pizza com qty em **gramas** (38 tipos) | E1 |
| RF-EST-14 | Catálogo `fichas-pizzas-peso.json` | E1 |
**Regra de ouro:** Cardápio declara `stockMode` (`bom`\|`sku`\|`none`); Estoque executa a baixa.
**Pizzas:** baixa por **peso (g)** por tipo — [`docs/FICHAS-TECNICAS-PESO.md`](docs/FICHAS-TECNICAS-PESO.md).
---
## 8. Requisitos não-funcionais
| ID | Tema | Requisito |
|----|------|-----------|
| RNF-01 | Latência KDS | Novo pedido visível na tela ≤ **500 ms** (LAN saudável) |
| RNF-02 | Disponibilidade | MVP single-node OK; alvo produção 99.5% |
| RNF-03 | Concorrência | Suportar pico de **60 pedidos/hora** no piloto |
| RNF-04 | UX cozinha | Touch-first, botões grandes, alto contraste, legível a 1–2 m |
| RNF-05 | Segurança | Auth JWT/session; senhas hashed; HTTPS; RBAC |
| RNF-06 | Auditoria | Log de mudanças de status com user + timestamp |
| RNF-07 | Observabilidade | Logs estruturados + healthcheck |
| RNF-08 | Idioma | PT-BR nativo |
| RNF-09 | Deploy | Docker Compose local; caminho claro para VPS/Proxmox |
| RNF-10 | LGPD | Dados de cliente mínimos; retenção configurável |
---
## 9. Arquitetura alvo
### 9.1 Princípios
1. **Order bus / schema único** — todo canal vira o mesmo `Order`
2. **Event-driven para cozinha** — WebSocket fan-out por loja/estação
3. **Station routing** — regras no servidor, não na UI
4. **PWA** — KDS e entregador rodam no browser/tablet
5. **Começar simples** — 1 processo API + Postgres + Redis; extrair microsserviços só se necessário
### 9.2 Stack sugerida (do zero)
| Camada | Tecnologia | Motivo |
|--------|------------|--------|
| Frontend | React + Vite + TypeScript (PWA) | KDS/PDV touch, ecossistema forte |
| Realtime | Socket.io ou native WS | Padrão dos KDS de referência |
| API | NestJS ou Fastify (Node/TS) | Tipagem compartilhada, rapidez |
| DB | PostgreSQL | Pedidos, auditoria, relatórios |
| Cache / pubsub | Redis | Tickets abertos + fan-out |
| Filas (fase 2+) | BullMQ | Webhooks, impressão, retries |
| Print | ESC/POS (node) + PDF fallback | Etiquetas térmicas |
| Infra local | Docker Compose | Postgres + Redis + API + Web |
Referências de forma (não copy-paste cego):
- **kitchenOS** → ingestão + KDS + Redis stream
- **Tasty-Station** → Socket.io POS↔KDS
- **rusterando** → **referência oficial** pizzaria + rotas / ORS / driver tour (modelo, não fork AGPL)
- **URY Mosaic** → multi-kitchen KDS
### 9.3 Apps da plataforma
| App | URL mental | Usuário |
|-----|------------|---------|
| `web-pdv` | `/pdv` | Caixa |
| `web-kds` | `/kds/:station` | Cozinha |
| `web-dispatch` | `/despacho` | Despachante |
| `web-admin` | `/admin` | Gestor |
| `web-driver` | `/entregador` | Motoboy (fase 2) |
| `web-menu` | `/m/:slug` | Cliente (fase 3) |
Monorepo sugerido:
```text
pizza-digital/
├── SPEC.md # este documento
├── docs/
│ ├── domain.md # glossário e regras
│ ├── api.md # contratos HTTP/WS
│ └── ui-kds.md # wireframes textuais
├── apps/
│ ├── web/ # PDV + KDS + Admin (rotas)
│ └── api/
├── packages/
│ ├── domain/ # types Order, Station, events
│ └── escpos/ # impressão
└── docker-compose.yml
```
---
## 10. Modelo de domínio (MVP)
### 10.1 Entidades
- **Store** — loja
- **User** — usuário + role
- **Station** — estação KDS
- **Category / Product / Modifier** — cardápio ([SPEC-CARDAPIO](docs/SPEC-CARDAPIO.md))
- **ProductStationRule** — produto → estações
- **Recipe / RecipeLine** — ficha técnica BOM ([SPEC-ESTOQUE](docs/SPEC-ESTOQUE.md))
- **Ingredient** — insumo com saldo
- **StockMovement** — entrada/saída/ajuste
- **Order** — pedido
- **OrderItem** — item do pedido (+ modifiers, notes)
- **StationTicket** — fatia do item/pedido na estação
- **LabelPrintJob** — job de etiqueta
- **Courier** (fase 2) — entregador
- **DispatchBatch** (fase 2) — lote de rota
### 10.2 Campos críticos de `Order`
```text
id, store_id, code, channel, type (delivery|pickup|dine_in),
status, customer_name, customer_phone, address,
notes, priority, promised_at,
accepted_at, production_started_at, ready_at,
dispatched_at, delivered_at, canceled_at,
created_at, updated_at
```
### 10.3 Eventos (WebSocket)
```text
order.created
order.updated
order.canceled
ticket.upserted
ticket.bumped
order.ready
order.dispatched
order.delivered
label.printed
```
Rooms: `store:{id}`, `store:{id}:station:{stationId}`
---
## 11. Regras de negócio — pizzaria
1. **Meia-a-meia**: 1 pizza = 2 sabores; preço = maior sabor (configurável); aparece no KDS como um item com 2 metades.
2. **Borda / adicionais**: modifiers ligados à montagem (ou massa, se borda recheada).
3. **Tempo SLA padrão** (editável): Massa 3 min · Montagem 5 · Forno 8 · Expedição 3 — total alvo ~20 min.
4. **Pedido delivery sem endereço** não confirma.
5. **Bump na expedição** só liberado se estações anteriores concluídas (ou override gestor).
6. **Prioridade urgente** não pula forno fisicamente — só sobe na fila visual e alerta.
---
## 12. UX — KDS (requisitos de interface)
- Cards grandes por pedido; código `#A42` enorme
- Observação do cliente em **cor de alerta**
- Timer no canto; vira amarelo/vermelho por threshold
- Botão único: **PRONTO** (item) / **TUDO PRONTO** (estação)
- Badge do canal (PDV / iFood / …)
- Sem cards decorativos desnecessários — densidade operacional
- Funciona em tablet paisagem e TV 32"+
---
## 13. Segurança e permissões (RBAC)
| Recurso | Operador KDS | Expedição | PDV | Despacho | Gestor |
|---------|--------------|-----------|-----|----------|--------|
| Ver KDS da sua estação | ✓ | ✓ | — | — | ✓ |
| Bump tickets | ✓ | ✓ | — | — | ✓ |
| Criar pedido | — | — | ✓ | — | ✓ |
| Cancelar pedido | — | — | ✓* | — | ✓ |
| Despachar | — | ✓ | — | ✓ | ✓ |
| Cardápio / users | — | — | — | — | ✓ |
| Métricas | — | — | — | leitura | ✓ |
\*cancelar só antes de produção, salvo permissão.
---
## 14. Critérios de aceite do MVP
O MVP está **aceito** quando, em ambiente piloto:
1. Atendente cria pedido no PDV com 2 pizzas (1 meia-a-meia) + bebida + observação
2. Tickets aparecem nas estações corretas em &lt; 1 s
3. Cada estação conclui seus itens; expedição só libera no fim
4. Etiqueta é gerada/impressa
5. Gestor reordena/prioritiza um pedido pronto
6. Dashboard mostra tempos por estação daquele pedido
7. Zero uso de papel na cozinha durante o teste supervisionado
---
## 15. Sequência oficial de implementação (S0–S9)
> **Congelado 2026-07-23 (SPEC 0.2.1).**
> Ordem: **KDS por estação antes de delivery/rotas.**
> Ciclo inspirado no rusterando: `cart/PDV → kitchen board → driver tour → ORS`.
> Não forkamos o binário Rust/AGPL; reutilizamos o **modelo operacional** no stack Nest/React.
### 15.1 Mapa de sprints
| Sprint | Bloco (rusterando) | Entrega Pizza Digital | Status |
|--------|--------------------|------------------------|--------|
| **S0** | Foundation | Repo + Docker Compose + domain types + SPEC | ✅ |
| **S1** | Auth + menu admin | Auth JWT + Store + Cardápio + mapa item→estações | ✅ (`pizza.myvexx.com`) |
| **S2** | Cart → order | **PDV** + criar pedido + state machine `confirmado→em_producao→pronto` | ✅ |
| **S3** | Kitchen board | **KDS multi-estação** realtime (bump, timers, rooms Socket.io) | ✅ |
| **S4** | Ready / expedição | Etiquetas + fila `pronto` + priorização + dashboard tempos | pendente |
| **S5** | Piloto cozinha | 1 pizzaria estável sem papel (aceite §14) | pendente |
| **S6** | Driver tour (manual) | Despacho: fila só `pronto` → agrupar bairro → motoboy → reordenar | pendente |
| **S7** | **ORS** | Gestor de Rotas: `DispatchBatch` + mapa permanente + heurística; ORS com `ORS_API_KEY` | ✅ parcial (ORS opcional) |
| **S8** | Driver + push | `/motoboy` + rota + GPS ping (+ push staff depois) | ✅ parcial (sem PIN/offline) |
| **S9 / Track C1** | Public menu / pay | **Cardápio digital** + checkout (Pix / dinheiro) → quadro `/pedidos` | **PRIORIDADE pós-S5** |
| **Track C2** | Agregadores | iFood webhook → Order normalizado | após C1 |
**Gate entre mundos (obrigatório):**
`order.ready` → fila despacho → batch → ORS *(só a partir de S6/S7)*.
### 15.2 Módulo Rotas (CityFoods → Pizza Digital)
**Referência oficial de dispatch:** [rusterando](https://github.com/holg/rusterando) (AGPL-3.0).
| Subfase | Capacidade | Sprint |
|---------|------------|--------|
| MVP rotas | Fila só pedidos `pronto` | S6 |
| MVP rotas | Agrupar por bairro (manual + sugestão) | S6 |
| MVP rotas | Atribuir motoboy | S6 |
| MVP rotas | Reordenar saída (“2 cliques” CityFoods) | S6 |
| Ampliação | OpenRouteService — ordem ótima da tour | S7 |
| Ampliação | Mapa no despacho | S7 |
| Ampliação | PWA entregador + tracking | S8 |
| Ampliação | Pagamento / comissão por entrega | S8–S9 |
Papéis rusterando → Pizza Digital: Admin≈gestor · Kitchen≈kds/estações · Driver≈entregador · Customer≈canal cardápio (S9).
### 15.3 Referências por domínio
| Domínio | Fonte |
|---------|--------|
| KDS / estações / bump | Este SPEC + kitchenOS / Tasty-Station |
| Despacho / ORS / driver tour | **rusterando** (oficial) + CityFoods Gestor de Rotas |
| UX “2 cliques” priorização | CityFoods |
### 15.4 Design UI
Status: **ainda não congelado.** S1 tem UI funcional (login + admin cardápio).
Antes de S3: wireframes PDV → KDS (touch) → Despacho. Design system em documento separado (`docs/DESIGN.md`) quando existir.
---
## 16. Riscos
| Risco | Mitigação |
|-------|-----------|
| Cozinha rejeita tela (hábito do papel) | UX bump mínima + treinamento 1 turno + impressão híbrida opcional |
| Impressora térmica incompatível | Driver ESC/POS + fallback PDF/A4 |
| Pico de pedidos derruba WS | Redis pubsub + rooms por loja; load test 60/h |
| Escopo inchando (virar iFood) | Freeze: MVP = cozinha digital, não marketplace |
| Integração iFood cedo demais | Só após piloto estável |
---
## 17. Glossário
| Termo | Significado |
|-------|-------------|
| **KDS** | Kitchen Display System — tela digital da cozinha |
| **Bump** | Marcar item/pedido como pronto na estação |
| **Estação** | Setor de produção (massa, forno, …) |
| **Ticket** | Representação do trabalho de um item/pedido numa estação |
| **SLA** | Tempo alvo até alerta de atraso |
| **Despacho** | Liberação do pedido pronto para entregador |
| **Canal** | Origem do pedido (PDV, cardápio, iFood, …) |
| **Cozinha Digital** | Operação completa sem comanda de papel + métricas |
| **BOM / Ficha técnica** | Lista de insumos por item do cardápio |
| **stockMode** | `bom` · `sku` · `none` — como o item consome estoque |
| **CMV** | Custo da mercadoria vendida (teórico via BOM) |
---
## 18. Decisões em aberto (para fechar com Roger)
1. Stack final: **NestJS** ✅ (congelado Fase 1)
2. Piloto: qual pizzaria / volume médio de pedidos/dia?
3. Impressora térmica já definida (marca/modelo)?
4. MVP inclui **mesa/comanda salão** ou só delivery + balcão?
5. Hospedagem inicial → **Proxmox BIG VM125** (`10.10.10.125`) ✅
6. Domínio → **`https://pizza.myvexx.com`** ✅
7. Sequência S0–S9 + rusterando = ref. rotas → **congelado §15** ✅
8. Design UI/UX (wireframes KDS/PDV/despacho) — em aberto
---
## 19. Referências
- CityFoods Cozinha Digital — https://abre.ai/cityfoods / https://cityfoods.com.br/
- CityFoods Instagram — https://www.instagram.com/cityfoods_app/
- kitchenOS — https://github.com/rajeshselvam02/kitchenOS
- rusterando (**ref. oficial dispatch/ORS**) — https://github.com/holg/rusterando
- URY / Mosaic — https://github.com/ury-erp/ury
- MaSoVa — https://github.com/SVamseekar/masova-platform
- Tasty-Station POS — https://github.com/hey-Zayn/Tasty-Station-POS
---
## 20. Próximo passo imediato
1. **S4** — Etiquetas + priorização + dashboard tempos (fechar cozinha)
2. **S5** — Piloto pizzaria (cozinha estável)
3. **Track C1 — entrada digital** — cardápio público → `/pedidos` (§5.5) ← **foco de produto**
4. **Track E1 / M1** — Estoque + ficha técnica ligados ao cardápio Joinville
5. Em paralelo ou depois: S6–S8 (rotas) · Track C2 (iFood)
---
*Documento vivo. Mudanças de escopo devem atualizar versão (ex.: 0.2.0 → 0.2.1) e registrar changelog em `docs/CHANGELOG-SPEC.md`.*