Nicchon.
Todos os projetos
SistemaEm produção· 2025

Zest

SaaS multi-tenant de food service: KDS, OMS, IMS, BI/Analytics, CRM, PWA. Beta fechado com billing PIX recorrente ativo.

Capa do projeto Zest

Sobre

Zest é meu produto SaaS multi-tenant pra food service, versão 0.9.9-beta com billing PIX recorrente ativo e cadastro self-service liberado. Substitui Excel + WhatsApp + iFood Tablet por plataforma única: KDS (Kitchen Display) pra cozinha, OMS pra pedidos online e mesas, IMS com custo médio ponderado de estoque, BI/Analytics com Recharts, CRM, billing Asaas, cardápio digital público, emissão NFC-e e integração iFood Merchant. Em produção em EC2 t3.small.

Stack

  • Next.js 16
  • React 19
  • TypeScript
  • Fastify 5
  • Prisma 6
  • PostgreSQL 17
  • Socket.IO 4
  • Tailwind CSS 4
  • Recharts
  • AWS S3
  • Caddy 2 (on-demand TLS)
  • Asaas
  • Mercado Pago
  • Pagar.me
  • OpenPix
  • Nuvem Fiscal (NFC-e)
  • iFood Merchant API
  • Evolution API
  • Meta WhatsApp Cloud
  • Sentry
  • Web Push (VAPID)

Decisões

  • Multi-tenancy híbrida: subdomínio por loja (slug.zestcozinha.com), painel path-based (zestcozinha.com/[slug]/) e domínios próprios via Caddy on-demand TLS — cliente escolhe nível de marca.
  • Caddy on-demand TLS com endpoint de validação dinâmico: GET /dominio-valido?domain=... é consultado antes de emitir Let's Encrypt. Raro de ver em portfolio, case forte de white-label SaaS.
  • Provider pattern multi-gateway PIX: 4 PSPs intercambiáveis (Mercado Pago, Pagar.me, Asaas, OpenPix) com validação de webhook diferente cada um. Factory makeProvider(empresa) retorna o configurado. Webhook rejeita sem secret (fail-closed).
  • Reaproveitamento de PIX já gerado e válido: reduz tarifa do PSP em pedidos refeitos.
  • Detecção de ataques real em produção: honeypots em 30+ paths com resposta HTML/JSON plausível por categoria, brute-force detection (5 falhas/IP/5min), alerta de IP novo em conta admin, dedup persistente com cooldown 6h.
  • JWT com tokenVersion no banco — invalidação server-side de sessões sem Redis nem blacklist. Bumpa o campo, middleware compara contra payload.
  • Audit log com flag 'modo suporte': diferencia ações do dono vs impersonate do superadmin.
  • Impersonate de suporte com token single-use de 5min (24 bytes hex), banner amarelo persistente em toda a nova aba.
  • Sem Redis / sem fila externa: 9 crons in-process via node-cron (cobrança, expiração, downgrade trial, onboarding). Trade-off consciente — EC2 t3.small dá conta no volume atual.
  • Custo médio ponderado em função pura testada com vitest (apps/api/src/lib/calculos.ts) — código de negócio crítico (impacto direto em CMV/contabilidade) merece disciplina de testes.

Desafios técnicos

  • TLS on-demand pra domínios próprios sem operação manual: endpoint valida o domínio em tempo real contra o banco antes do Caddy emitir cert.
  • KDS sincronizado entre cozinha e front com Socket.IO em salas loja:<id> + middleware de autorização no handshake que valida JWT antes de admitir o cliente na sala.
  • Custo médio ponderado de estoque com entradas e saídas concorrentes: lock por SKU + transação com retry, arredondamento explícito a 4 casas (Decimal(10,4)).
  • iFood Merchant API com OAuth client_credentials por loja, webhook HMAC-SHA256 validado com timingSafeEqual e confirmação automática do pedido de volta no iFood.
  • Emissão NFC-e via Nuvem Fiscal com OAuth2 e cache de token em memória, certificado A1 por empresa, ambiente homologação/produção.

Galeria

Dashboard de Analytics — faturamento últimos 30 dias, distribuição por hora, taxa de cancelamento, comparativo mensal por semana, ranking de operadores. Gráficos em Recharts, queries diretas no PostgreSQL.
Painel administrativo do lojista — visão consolidada da operação. Multi-tenancy por lojaId em todas as tabelas, isolamento total entre estabelecimentos.
Painel de pedidos com Socket.IO em sala loja:<id>. Pedidos novos aparecem em tempo real, status flui novo → recebido → fazendo → preparando → aguardando expedidor → pronto. Middleware de auth no handshake valida JWT antes de admitir cliente na sala.
Acompanhamento mobile do pedido pelo cliente final — acesso público por hash do pedido (sem login), atualização em tempo real do status. PWA-ready com Web Push VAPID pra notificar quando pronto.