204 lines
8.1 KiB
Markdown
204 lines
8.1 KiB
Markdown
# PRD — Cardápio Joinville (o que a plataforma faz)
|
||
|
||
| Campo | Valor |
|
||
|-------|--------|
|
||
| **Produto** | Pizza Digital |
|
||
| **Módulo** | Cardápio / Menu (pesquisa regional → operação) |
|
||
| **Fonte Spec** | [`CARDAPIO-JOINVILLE.md`](CARDAPIO-JOINVILLE.md) · [`SPEC-CARDAPIO.md`](SPEC-CARDAPIO.md) |
|
||
| **Ambiente auditado** | https://pizza.itecnologys.com · VM125 · `v0.5.0` |
|
||
| **Loja piloto** | Pizza Digital Joinville (`pizza-digital-piloto`) |
|
||
| **Data auditoria** | 2026-11-09 |
|
||
| **Tipo** | PRD operacional (Spec × construído × passos de uso) |
|
||
|
||
---
|
||
|
||
## 1. Entendimento da demanda
|
||
|
||
Documentar **cada Spec** não só como intenção, mas como **PRD da plataforma real**:
|
||
|
||
1. Ler a Spec / pesquisa
|
||
2. Inspecionar o que está construído (UI + API + banco)
|
||
3. Descrever **passo a passo** o que o usuário faz
|
||
4. Marcar o que já funciona, o que é parcial e o que falta
|
||
|
||
Este arquivo é o **exemplo-piloto** usando `CARDAPIO-JOINVILLE.md`.
|
||
|
||
---
|
||
|
||
## 2. Problema e objetivo
|
||
|
||
### Problema
|
||
Pizzarias de Joinville vendem com nomenclatura inconsistente de tamanhos, sabores regionais e preços locais. Sem um cardápio único, PDV/KDS/canais divergem.
|
||
|
||
### Objetivo do módulo (construído)
|
||
Ser a **fonte da verdade do que a loja vende** no piloto Joinville: categorias, itens, preços base (Grande), tamanhos no pedido, split de sabores e acompanhamentos — alimentando o **PDV** e, depois, KDS/Central.
|
||
|
||
### Fora deste PRD
|
||
Saldo de estoque, NF, inventário → [`SPEC-ESTOQUE.md`](SPEC-ESTOQUE.md) / SmartStock.
|
||
|
||
---
|
||
|
||
## 3. O que a pesquisa Joinville definiu vs o que existe hoje
|
||
|
||
| Tema (CARDAPIO-JOINVILLE) | Spec / pesquisa | Construído na plataforma (2026-11-09) | Status |
|
||
|---------------------------|-----------------|----------------------------------------|--------|
|
||
| 6 tamanhos (Broto→Família) | cm, fatias, sabores máx., fator preço | Tabela `PizzaSizeBase` com 6 sizeCodes ativos | ✅ |
|
||
| Preço base = Grande 40 cm | Sim | `MenuItem.priceCents` = preço Grande; PDV multiplica por `priceFactor` | ✅ |
|
||
| Split = maior sabor × fator | Sim | Sheet do PDV: escolhe tamanho + N sabores até `maxFlavors` | ✅ |
|
||
| Tradicionais alta rotação | Lista ~20 sabores | Cat. **Tradicionais** · 20 ativos (Calabresa, Mussarela, Frango Catupiry…) | ✅ |
|
||
| Regionais SC | Joinville, Linguiça Blumenau, Aipim, Catarina | Cat. **Da casa** · 6 ativos (+ Aipim Blumenau, Coração) | ✅ |
|
||
| Doces | 6 tipos | Cat. **Doces** · 6 ativos (Broto legado inativo) | ✅ |
|
||
| Bebidas / sucos / energéticos / vitaminas | Tabelas de mercado | 4 categorias · 57 itens ativos | ✅ |
|
||
| Bordas | Catupiry/Cheddar ~R$12–20 | Cat. **Bordas especiais** · 3 itens | ✅ |
|
||
| SKU Broto separado | Evitar no piloto | Cat. legado **Pizzas Broto** · `active=false` · 5 itens inativos | ✅ (legado) |
|
||
| Cardápio público PWA `/c/:slug` | Track C1 | Ainda não é o foco deste PRD | ⏳ |
|
||
| CRUD gestor no Admin | RF-MEN-01 | API CRUD existe; UI Admin menu | ⚠️ parcial |
|
||
|
||
### Inventário real (banco piloto)
|
||
|
||
| Categoria | Ativos | Inativos |
|
||
|-----------|--------|----------|
|
||
| Tradicionais | 20 | 1 |
|
||
| Da casa | 6 | 0 |
|
||
| Doces | 6 | 1 |
|
||
| Refrigerantes | 23 | 0 |
|
||
| Sucos | 14 | 0 |
|
||
| Energéticos | 8 | 0 |
|
||
| Vitaminas · frutas c/ leite | 12 | 0 |
|
||
| Bordas especiais | 3 | 0 |
|
||
| Pizzas Broto (legado) | 0 | 5 |
|
||
| **Total** | **92** | **7** |
|
||
|
||
### Tamanhos reais (`PizzaSizeBase`)
|
||
|
||
| sizeCode | Nome | cm | Fatias | Sabores máx. | Fator |
|
||
|----------|------|----|--------|--------------|-------|
|
||
| broto | Broto | 25 | 4 | 1 | 0,55 |
|
||
| pequena | Pequena | 30 | 6 | 1 | 0,70 |
|
||
| media | Media | 35 | 8 | 2 | 0,85 |
|
||
| grande | Grande | 40 | 12 | 3 | 1,00 |
|
||
| gigante | Gigante | 45 | 16 | 4 | 1,20 |
|
||
| familia | Familia | 50 | 20 | 4 | 1,35 |
|
||
|
||
---
|
||
|
||
## 4. Personas e telas
|
||
|
||
| Persona | Onde usa o cardápio | Rota |
|
||
|---------|---------------------|------|
|
||
| Atendente PDV | Monta pedido a partir do cardápio | `/pdv` |
|
||
| Gestor | CRUD categorias/itens (API/Admin) | `/admin` · `/api/menu/*` |
|
||
| Cliente (futuro) | Cardápio digital | `/c/:slug` (Track C) |
|
||
| Cozinha | Não edita cardápio; recebe itens mapeados a estações | `/kds/*` |
|
||
|
||
---
|
||
|
||
## 5. Fluxo passo a passo — Atendente no PDV (construído)
|
||
|
||
> Caminho feliz: pizza com tamanho + split + bebida → enviar à cozinha.
|
||
|
||
### Passo 1 — Entrar
|
||
1. Abrir https://pizza.itecnologys.com/login
|
||
2. Usar demo: `pdv@pizza.local` / `805353` (loja `pizza-digital-piloto`)
|
||
3. Ir em **PDV**
|
||
|
||
### Passo 2 — Tipo de fulfillment
|
||
1. Escolher **Entrega**, **Balcão** ou **Mesa**
|
||
2. Se Entrega: preencher Cliente, Telefone, Bairro, Endereço
|
||
3. Opcional: observações e flag **Urgente**
|
||
|
||
### Passo 3 — Escolher item do cardápio
|
||
1. Navegar nas **categorias** (Tradicionais, Da casa, Doces, Refrigerantes…)
|
||
2. Tocar num item
|
||
3. Se o item é pizza (`halfHalf=true`): abre **sheet de montagem**
|
||
4. Se é bebida/extra: adiciona linha direta ao pedido
|
||
|
||
### Passo 4 — Montar pizza (regra Joinville)
|
||
1. Escolher **tamanho** (Broto…Família) na grade
|
||
2. Sistema limita sabores pelo `maxFlavors` do tamanho
|
||
3. Selecionar 1..N sabores (split)
|
||
4. Preço unitário = **maior `priceCents` entre sabores** × `priceFactor` do tamanho
|
||
5. Opcional: borda especial
|
||
6. Confirmar → linha no “Pedido atual” com nome tipo:
|
||
`Pizza Grande 40cm · Calabresa / Mussarela`
|
||
|
||
### Passo 5 — Enviar à cozinha
|
||
1. Revisar linhas e total
|
||
2. **Enviar pra cozinha**
|
||
3. Pedido entra na Central `/pedidos` e gera tickets KDS conforme estações do item
|
||
|
||
---
|
||
|
||
## 6. Fluxo passo a passo — Gestor (API / Admin)
|
||
|
||
### Listar cardápio
|
||
`GET /api/menu` (JWT) → `{ pizzaSizes, categories[] }` com itens ativos.
|
||
|
||
### Tamanhos
|
||
`GET /api/menu/sizes` → catálogo `PizzaSizeBase`.
|
||
|
||
### CRUD (RF-MEN-01 — parcial na UI)
|
||
- `POST/PATCH/DELETE /api/menu/categories`
|
||
- `POST/PATCH/DELETE /api/menu/items`
|
||
- Campos relevantes: `name`, `priceCents`, `halfHalf`, `active`, `stockMode`, estações, ficha (BOM)
|
||
|
||
### Regra de negócio congelada (piloto)
|
||
1. Preço catalogado = Grande
|
||
2. Broto/Pequena = 1 sabor (inteira)
|
||
3. Média ≤2 · Grande ≤3 · Gigante/Família ≤4
|
||
4. Split cobra o **maior** sabor
|
||
5. Cardápio **não** guarda saldo — ponte via `stockMode` + ficha
|
||
|
||
---
|
||
|
||
## 7. Arquitetura funcional (como a plataforma liga as peças)
|
||
|
||
```text
|
||
CARDAPIO-JOINVILLE.md (pesquisa)
|
||
│
|
||
▼
|
||
seed / MenuCategory + MenuItem + PizzaSizeBase
|
||
│
|
||
├─► PDV sheet (tamanho × sabores × fator)
|
||
├─► OrderItem (sizeCode, halfHalf, preço calculado)
|
||
├─► KDS (estações do MenuItem)
|
||
└─► Estoque (BOM / RecipeLine) — SPEC irmã
|
||
```
|
||
|
||
---
|
||
|
||
## 8. Critérios de aceite (PRD)
|
||
|
||
| # | Critério | Evidência | Status |
|
||
|---|----------|-----------|--------|
|
||
| CA-01 | Existem ≥6 tamanhos com fator e max sabores | `PizzaSizeBase` | ✅ |
|
||
| CA-02 | Catálogo Joinville com tradicionais + SC + doces + bebidas | 92 ativos | ✅ |
|
||
| CA-03 | PDV calcula preço por tamanho a partir da base Grande | `PdvPage` `priceForSize` | ✅ |
|
||
| CA-04 | PDV impede ultrapassar max sabores do tamanho | validação sheet | ✅ |
|
||
| CA-05 | API menu autenticada por loja | `/api/menu` | ✅ |
|
||
| CA-06 | Categoria Broto legado não aparece como catálogo ativo | `active=false` | ✅ |
|
||
| CA-07 | PDV mostra categorias/itens ao operador logado | UI `/pdv` | ⚠️ a validar (em 2026-11-09 UI mostrou “Nenhuma categoria…” apesar da API OK — possível bug de fetch/cache) |
|
||
| CA-08 | PWA cardápio público | Track C | ⏳ |
|
||
|
||
---
|
||
|
||
## 9. Gaps e próximos passos
|
||
|
||
1. **Investigar** PDV sem categorias na UI enquanto API retorna 8 cats / 92 itens
|
||
2. Completar **UI Admin** de CRUD alinhada ao RF-MEN-01
|
||
3. Expor cardápio no **canal digital** (SPEC-CANAIS)
|
||
4. Ligar indisponibilidade a **Estoque** (esgotado / pausado)
|
||
5. Repetir este formato de PRD para as demais Specs (KDS, Despacho, Matriz, etc.)
|
||
|
||
---
|
||
|
||
## 10. Referências
|
||
|
||
- Pesquisa: [`CARDAPIO-JOINVILLE.md`](CARDAPIO-JOINVILLE.md)
|
||
- Spec: [`SPEC-CARDAPIO.md`](SPEC-CARDAPIO.md)
|
||
- Estoque: [`SPEC-ESTOQUE.md`](SPEC-ESTOQUE.md)
|
||
- App: https://pizza.itecnologys.com
|
||
- Código: `apps/web/src/PdvPage.tsx` · `apps/api/src/menu/*` · `prisma/seed.ts`
|
||
|
||
—
|
||
*PRD gerado a partir de Spec + auditoria da plataforma · iTecnologys*
|