Sistema multi-tenant de gestão de estoque com times, localizações, itens, movimentações e relatórios.
- Next.js 16 (App Router)
- React 18 + TypeScript
- Tailwind CSS + shadcn/ui
- SQLite/libSQL (
@libsql/client, Turso em produção) + Drizzle ORM - Jest para testes
O projeto segue separação explícita de camadas:
src/app/*: páginas e API Routes (adapters HTTP/UI).src/lib/services/*: regras de negócio, autorização e contratos de saída.src/lib/db/*: acesso a dados (queries Drizzle/SQLite).src/db/*: schema, cliente e migrações.
Fluxo padrão de API:
- Route handler valida params e body bruto.
- Route delega para um serviço em
src/lib/services/*. - Serviço valida payload, autoriza e chama
src/lib/db/*. - Route responde usando helpers de
src/lib/api-route.ts.
Guardrails automáticos (CI e hook) impedem violações arquiteturais.
- Autenticação por cookie assinado (
ps_session). - Role global
super_adminpara visão administrativa cross-tenant. - Multi-tenancy por time e membership ativo.
- CRUD de times, usuários do time, itens e localizações.
- Movimentações de estoque (
stock_in,stock_out,adjust,move,count) com atomicidade. - Relatórios consolidados por time.
- PWA com
manifest.jsone service worker. - i18n local (
pt-BR,en,fr).
src/
app/
(main)/, (auth)/ # páginas
teams/[id]/* # features por time
api/* # rotas HTTP
components/
ui/* # base UI
shared/* # blocos reutilizáveis
lib/
services/* # casos de uso
db/* # consultas por domínio
contracts/schemas.ts # parse/validação de payload
permissions.ts # autorização
db/
schema.ts # tabelas e relações
migrations/*.sql # migrações SQL- Node.js 20+ (alinhado com CI).
- npm.
DATABASE_URL: URL libSQL (libsql://...) para Turso. Em local, usefile:./src/db.sqlite.TURSO_AUTH_TOKEN(obrigatório para Turso remoto): token do banco Turso.SESSION_SECRET(obrigatório em produção): segredo para assinatura da sessão.STRIPE_SECRET_KEY(obrigatório para billing): chave secreta da Stripe.STRIPE_PRICE_ID(obrigatório para billing):price_iddo plano mensal por time.STRIPE_WEBHOOK_SECRET(obrigatório para webhook): segredo do endpoint de webhook.APP_URLouNEXT_PUBLIC_APP_URL(recomendado): URL base usada em retornos do Checkout/Portal.
npm install
npm run db:migrate
npm run devAplicação em http://localhost:3000.
Para Turso (remoto), configure:
DATABASE_URL=libsql://<seu-db>-<org>.turso.io
TURSO_AUTH_TOKEN=<seu_token_turso>npm run dev: ambiente de desenvolvimento.npm run build: build de produção.npm run start: sobe build de produção.npm run test: suíte completa.npm run test:watch: watch mode.npm run test:coverage: cobertura.npm run db:migrate: aplica SQLs desrc/db/migrations.npm run db:rollback -- --steps=1: faz rollback das últimas migrações aplicadas (requer arquivos*.down.sqlcorrespondentes).npm run db:new -- <nome>: cria par de migrationup/downcom próximo prefixo numérico.npm run verify:architecture: checks arquiteturais + política de testes + lint de arquitetura + testes de arquitetura.npm run prepush:required: validação obrigatória pré-push (verify:architecture+build).npm run prepush:full: validação completa pré-push (verify:architecture+test --runInBand+build).npm run hooks:install: ativa.githooks/pre-push.npm run hooks:uninstall: remove hook local.
Este repositório usa amplify.yml para gerar .env.production no build do Next.js.
Configure em Hosting > Environment variables (obrigatórias para o build SSR):
DATABASE_URLTURSO_AUTH_TOKENSESSION_SECRETSTRIPE_SECRET_KEYSTRIPE_WEBHOOK_SECRETAPP_URLSTRIPE_PRICE_IDSTRIPE_PUBLISHABLE_KEY
Observação: mesmo usando Hosting > Secrets, o build SSR do Next pode precisar das variáveis em Environment variables para coleta de page data.
- Atualizar variáveis no Amplify.
- Executar Clear cache and redeploy.
- Validar login (
/api/auth/login) e signup (/api/auth/signup).
- Erro
DATABASE_URL must be set in production:DATABASE_URLnão está chegando no build/runtime SSR.
- Erro
TURSO_AUTH_TOKEN must be set...:- token ausente no ambiente de produção.
- Erro
SERVER_ERROR: 401na conexão Turso:- token inválido/expirado; gere novo token e atualize o ambiente.
Para cada migration up, crie um arquivo down correspondente no mesmo diretório src/db/migrations.
NNN_nome_da_migration.sql: aplica mudança.NNN_nome_da_migration.down.sql: desfaz mudança.
Exemplo:
004_add_items_status.sql004_add_items_status.down.sql
Para gerar automaticamente o par de arquivos:
npm run db:new -- add_items_statusFluxo recomendado:
- Criar o
upcom alteração incremental. - Criar o
downrevertendo exatamente a alteração doup. - Executar
npm run db:migrate. - Testar reversão com
npm run db:rollback -- --steps=1.
Observação: existe script db:seed no package.json, mas o arquivo src/db/seed.ts não está presente no repositório atual.
POST /api/auth/signupPOST /api/auth/loginPOST /api/auth/logoutGET|POST /api/teamsGET|PUT|DELETE /api/teams/:idGET|POST /api/teams/:id/itemsGET|PUT|DELETE /api/teams/:id/items/:itemIdGET|POST /api/teams/:id/locationsGET|PUT|DELETE /api/teams/:id/locations/:locationIdGET|POST /api/teams/:id/stock-transactionsGET /api/teams/:id/reportsGET /api/teams/:id/transactionsDELETE /api/teams/:id/transactions/:transactionIdPOST /api/teams/:id/billing/checkoutPOST /api/teams/:id/billing/portalPOST /api/stripe/webhookGET /api/admin/teams(somentesuper_admin, com paginação e busca)
- Hook de pre-push executa
npm run prepush:required. - Quando o ambiente local estiver alinhado para testes nativos, rode também
npm run prepush:fullantes do push. - GitHub Actions:
- job
architecture:npm ci+npm run verify:architecture. - job
validate:npm ci+npm test -- --runInBand+npm run build.
- job
