Plano de Desenvolvimento

dbcheckout

Aplicativo de PDV e Self-Checkout. Ponta de escrita do banco MySQL legado — originando os dados que o dbdash posteriormente lê e analisa.

FastAPI + PydanticNext.js + ReactMySQL (Legado)Celery + Redisaiomysql asyncTDD + pytestService WorkersWeb HID API

Posição no Ecossistema DB

dbcheckout

PDV · Self-Checkout

Escreve no MySQL legado

VOCÊ ESTÁ AQUI

MySQL Legado

ETL Noturno

dbdash

Dashboard Analítico

Lê do PostgreSQL analítico

Fluxo: dbcheckout grava pedidos no MySQL → ETL consolida em KPIs → dbdash exibe análises. MySQL legado é a única fonte de verdade transacional.

Smith Laws Aplicadas

Princípios arquiteturais obrigatórios que governam todas as decisões do dbcheckout

LEI 01

Isolamento Frontend/Backend

O Next.js do dbcheckout jamais faz INSERT diretamente em pedidos ou pedidos_itens.

Toda criação de carrinho e finalização passa pela API (/api/v1/checkout/...) com validação forte de token (Session/JWT via iron-session).

LEI 02

Alta Simultaneidade Async

Nenhuma operação de I/O bloqueia o event loop do FastAPI.

FastAPI com aiomysql em modo async. Celery + Redis para emissão fiscal escalonada e atualizações financeiras fora do ciclo HTTP.

LEI 03

Multi-tenant Shield

O principal risco é injetar uma venda na loja errada. Zero tolerância.

Todas as queries usam Depends(get_current_user). O loja_id vem implicitamente do token — jamais do body JSON do request.

LEI 06

Clean Architecture

Routers não contêm lógica de negócio. Apenas validação de schema Pydantic.

Regras de desconto, cálculo de valor líquido e apuração de ICMS ficam exclusivamente em CartService e TaxService.

LEI 08

Erros Ricos

Todo endpoint de checkout falha de forma descritiva e controlada.

Logs com ID de Correlação em caso de recusa de TEF ou crédito, permitindo auditorias completas em conciliacao_recebiveis.

LEI 10

Testes Primeiros (TDD)

Motor financeiro e fiscal só vai para main após TDD verde.

Cobertura obrigatória com pytest em CartService, TaxService e CheckoutService antes de qualquer deploy em produção.

Stack Tecnológica Prescrita

Backend (API)

FastAPI + Pydantic

Alta simultaneidade async. Pydantic para validação dos schemas PedidoCreate, ItemCarrinhoCreate e PagamentoCreate. Lei 02.

Frontend (Client)

Next.js + React

Interface de PDV e self-checkout. Nunca acessa o banco diretamente. Comunicação exclusiva via API com iron-session. Lei 01.

Banco de Dados

MySQL (Legado)

O mesmo banco mapeado no dbdash. O dbcheckout é a ponta de escrita: INSERT em Pedido, PedidoItem, pedidos_pgtos.

I/O Async

aiomysql / SQLAlchemy async

Motor async para acesso ao MySQL. Conexões via pool assíncrono, evitando bloqueio durante picos de emissão fiscal.

Background Jobs

Celery + Redis

Emissão de NFCe em fila escalonada. Atualizações de conciliacao_recebiveis. Retry automático com backoff. Lei 02.

Testes

pytest + TDD

CartService, TaxService e CheckoutService cobertos por TDD antes do deploy. Testes de isolamento multi-tenant obrigatórios. Lei 10.

Cache Offline (Fase 5)

Service Workers + IndexedDB

Catálogo pré-cacheado via Workbox/next-pwa. Pedidos em andamento em IndexedDB durante quedas de rede.

Leitores Físicos (Fase 5)

Web HID API + KeyboardEvent

Integração com leitores USB/Bluetooth. Busca por EAN/Code128 em menos de 200ms. Fallback para input capture global.

Models de Dados — ORM e Pydantic

Mapeamento completo dos models com foco em clareza tributária e interface do PDV

Legenda:PKFKTENANTTRIBUTÁRIOVIRTUALBACKENDCALCULADOADICIONAL

Todos os models de catálogo são lidos via Redis/DB e nunca modificados pelo dbcheckout. A hierarquia Grupo → Tipo → Tamanho → Produto mapeia diretamente para os Painéis Táteis de Categorias da interface do PDV.

Nível mais alto da hierarquia. Renderiza as "Abas" de navegação no App de Venda (Ex: "Bebidas", "Lanches").

CampoTipoBadgesDescrição
codigoInteger
PK
Código único do grupo
lojaInteger
TENANT
Filtro multi-tenant obrigatório em todas as buscas
grupoString(30)
Descrição da aba de navegação (Ex: "Bebidas Frias")
classeString(30)
Agrupamento gerencial

Subcategoria que organiza os botões na tela dentro de um Grupo (Ex: "Refrigerantes", "Sucos").

CampoTipoBadgesDescrição
codigoInteger
PK
Código único do tipo
lojaInteger
TENANT
Filtro multi-tenant
tipoString(30)
Descrição do tipo de produto
grupo_idInteger
FK
FK → produto_grupos.codigo

Modificadores visuais do produto na interface. Permite exibir variações como "300ml", "Lata", "Familiar".

CampoTipoBadgesDescrição
codigoInteger
PK
Código único do tamanho
lojaInteger
TENANT
Filtro multi-tenant
tamanhoString(30)
Descrição do tamanho (Ex: "300ml", "Lata")
tipo_idInteger
FK
FK → produto_Tipos.codigo

Item transacionado. Aglutina Grupo+Tipo+Tamanho para desenhar o botão no POS. Carrega compliance tributário obrigatório.

CampoTipoBadgesDescrição
codigoInteger
PK
Código principal do produto
descricaoString(50)
Nome no botão do POS (Ex: "Coca-Cola Lata Zero")
lojaInteger
TENANT
Filtro multi-tenant contínuo em todas as buscas
status_produtoString
Apenas produtos ativos são lidos pelo Checkout
prc_unitarioNumeric
VIRTUAL
Fornecido pela inteligência de preços (não custo_real)
icms_aliquotaFloat
TRIBUTÁRIO
Alíquota ICMS — obrigatório para emissão NFCeCaixa trava se ausente em produção
ncmString(10)
TRIBUTÁRIO
Nomenclatura Comum do Mercosul — obrigatórioCaixa trava se ausente em produção
cfop_saida_estString(10)
TRIBUTÁRIO
CFOP de saída para o estado — obrigatórioCaixa trava se ausente em produção

O backend trava a venda de qualquer produto sem NCM e CFOP preenchidos em produção. Essa validação ocorre no TaxService antes do INSERT.

Extensão modular para Adicionais/Retiradas. Habilita botões "Sem Cebola" e "Com Bacon Extra" no carrinho visual.

CampoTipoBadgesDescrição
produto_idInteger
FK
FK → produtos.codigo (Combo/Prato principal)
ingrediente_idInteger
FK
FK → produtos.codigo (Insumo/ingrediente)
qtdNumeric(10,4)
Quantidade do ingrediente na composição
unidadeString(10)
Unidade de medida (kg, un, ml…)
custoNumeric(10,4)
Custo do insumo nesta composição
retiradoBoolean
ADICIONAL
Se True → exibe botão "Remover / Sem {ingrediente}"
adicionadoBoolean
ADICIONAL
Se True → sugere como "Adicional Extra Pago" no carrinho

Escopo Funcional — 5 Fases

Cada fase entrega valor incremental e independente. Fase 1 é pré-requisito para as demais.

Fase 1 — Fundação do Checkout

Identity, Security & Abertura de Turno

Auth Service — Operadores de Caixa

Criação do serviço de autenticação específico para operadores físicos de PDV. Diferente dos usuários gerenciais do dbdash.

TABELAS MySQL

lojasmovimento

ENDPOINTS API

POST/api/v1/auth/operador/login
POST/api/v1/auth/operador/refresh
POST/api/v1/auth/operador/logout

Middleware Anti-Intrusão

Camada de proteção no frontend (Next.js) e gerenciador de segredos. Encryption Service para tokens de integradores TEF.

ENDPOINTS API

GET/api/v1/health
GET/api/v1/auth/me

Abertura de Reforço/Turno

Inicia o registro na tabela movimento com saldo inicial, criando o token da sessão ligada ao operador físico (autenticador_abertura).

TABELAS MySQL

movimentoapuracao_caixa

ENDPOINTS API

POST/api/v1/caixa/abertura
POST/api/v1/caixa/reforco
POST/api/v1/caixa/sangria

Tabelas MySQL — Responsabilidade de Escrita

O dbcheckout é o único sistema autorizado a gravar nestas tabelas

pedidosINSERTFase 4

Capa do pedido: ORM Pedido — loja via JWT, valores via CartService/TaxService

pedidos_itensINSERTFase 4

ORM PedidoItem — snapshot tributário (NCM, CFOP, icms_base) no momento da venda

pedidos_pgtosINSERTFase 4

Split de PagamentoCreate — pode ter múltiplas linhas por pedido

movimentoINSERTFase 1

Abertura de turno, sangria, reforço e fechamento de caixa físico

apuracao_caixaINSERT / UPDATEFase 1

Conferência cega de valores recebidos vs esperados por turno

conciliacao_recebiveisINSERTFase 4

NSU, taxa e valor_liquido TEF — com correlation_id para auditoria

combo / descontosREADFase 3

Leitura das campanhas ativas pelo CampanhasService (somente leitura)

Regra absoluta (Lei 03): Em todas as operações de escrita, o campo loja é extraído do JWT do operador autenticado — nunca aceito do body da requisição.

Princípios de Segurança Operacional

iron-session (Next.js)

Sessão HTTP-only server-side para operadores. Token nunca exposto no client-side JavaScript.

Depends(get_current_user)

Cada endpoint FastAPI injeta o usuário autenticado. loja_id obrigatório no token — query filter automático.

ID de Correlação

Todo request gera correlation_id único. Em falhas TEF, disponível em conciliacao_recebiveis para auditoria.

Transação ACID

Pedido + PedidoItems + pedidos_pgtos em uma única transação atômica. Falha = rollback total.

RBAC de Operadores

Operador (venda), Supervisor (sangria), Gerente (fechamento). Nenhum acessa o dbdash.

Trava Tributária

TaxService bloqueia venda de produto sem NCM e CFOP preenchidos. Zero NFCe com campos fiscais vazios em produção.