Stack Tecnológica
Esta página descreve todas as tecnologias utilizadas no projeto, as justificativas para cada escolha e o que foi deliberadamente descartado.
1. Tabela geral
| Categoria | Tecnologia | Versão | Propósito |
|---|---|---|---|
| Framework | Next.js | 15.x | App Router, RSC, SSR/SSG, API Routes |
| Linguagem | TypeScript | 5.x | Tipagem estática em todo o codebase |
| UI Runtime | React | 19.x | Renderização de componentes |
| ORM | Prisma | 5.x | Acesso ao banco com type safety |
| Banco (prod) | MySQL | 8.x | Banco relacional gerenciado na Hostinger |
| Banco (testes) | SQLite | — | Banco em memória para CI sem infraestrutura |
| Estilos | Tailwind CSS | 3.x | Utility-first CSS; design tokens via config |
| Componentes | Radix UI Primitives | várias | Acessibilidade (WAI-ARIA) sem estilos impostos |
| Estado global | Zustand | 5.x | Carrinho, UI do admin, notificações |
| Animações | Framer Motion | 12.x | Transições de página, animações de produto |
| Autenticação | jose | 5.x | Geração e verificação de JWT HS256 |
| Hash de senhas | bcryptjs | 2.x | Hash bcrypt de senhas de usuários |
| Formulários | react-hook-form + zod | 7.x / 3.x | Validação de formulários no cliente e servidor |
| Editor visual | @puckeditor/core | 0.21.2 | Edição drag-and-drop de páginas de produto |
| Gráficos | Recharts | 2.x | Painel de analytics do admin |
| E-mails | nodemailer + resend | 8.x / 4.x | Envio de e-mails transacionais |
| Pagamentos | MercadoPago SDK | 2.x | PIX e cartão de crédito (mercado brasileiro) |
| Pagamentos | Stripe SDK | 17.x | Cartão de crédito internacional |
| Rich text | TipTap | 3.x | Descrições de produto editáveis |
| Drag & Drop | @dnd-kit | 6.x / 10.x | Reordenação de imagens e variações no admin |
| APM | @hyperdx/node-opentelemetry | 0.10.x | Rastreamento distribuído e métricas de performance |
| Heatmap | @microsoft/clarity | 1.x | Mapas de calor e gravação de sessões |
| Testes unit/int | Jest + MSW v2 | 30.x / 2.x | Testes isolados com mocking de APIs externas |
| Testes E2E | @playwright/test | 1.x | Testes de fluxo completo em browser real |
2. Justificativas das principais escolhas
Next.js 15 com App Router
O App Router representa a direç ão estratégica do ecossistema React. A adoção de React Server Components (RSC) permite buscar dados diretamente no servidor — sem useEffect, sem waterfall de requisições no cliente, sem estado de carregamento desnecessário. Para um e-commerce, isso se traduz em páginas de produto com First Contentful Paint mais rápido e melhor indexação por mecanismos de busca, já que o HTML com conteúdo chega completo na primeira resposta.
O suporte a Streaming com Suspense permite que partes lentas da página (ex.: recomendações personalizadas) sejam entregues incrementalmente, enquanto o esqueleto da página já está visível. Os Route Handlers (app/api/) substituem as Pages API Routes com tipagem melhorada e suporte nativo a Request/Response da Web API. A adoção foi registrada formalmente no ADR-001.
Prisma + MySQL
A Hostinger fornece MySQL 8 gerenciado como parte do plano de hospedagem compartilhada — não há custo adicional nem configuração de infraestrutura. O Prisma foi escolhido por oferecer queries totalmente type-safe geradas a partir do schema (schema.prisma), eliminando uma categoria inteira de bugs em tempo de compilação (campos inexistentes, tipos incompatíveis).
A decisão de usar SQLite em testes foi deliberada: o ambiente de CI (GitHub Actions) não precisa provisionar um servidor MySQL, tornando os testes mais rápidos e baratos. O trade-off é que algumas features específicas de MySQL (ex.: FULLTEXT INDEX) precisam ser testadas separadamente. Detalhes no ADR-002.
Zustand
O carrinho de compras é um estado global que precisa ser: (1) persistido entre recargas de página via localStorage, (2) acessível fora do React tree (ex.: limpar carrinho ao fazer logout no middleware), e (3) atualizado sem causar re-renders em componentes não relacionados. O Zustand atende aos três requisitos com um bundle de ~3 KB e zero boilerplate. O middleware persist com partialize garante que flags de UI voláteis (como isOpen de modais) não sejam serializadas, evitando hydration mismatch no SSR. Decisão formal no ADR-003.
MercadoPago + Stripe
O MercadoPago domina o mercado brasileiro de pagamentos online e é o único processador que oferece PIX nativo com geração de QR Code via API — fundamental para o público-alvo da loja. O Stripe complementa a oferta para pagamentos internacionais com cartão, aproveitando seu SDK de Elements para captura segura de dados de cartão (PCI DSS SAQ A).
Manter os dois SDKs no mesmo projeto aumenta ligeiramente a complexidade do checkout, mas garante a maior taxa de aprovação possível para diferentes perfis de cliente.
3. Diagrama de relacionamento entre tecnologias
┌─────────────────────────────────────────────────────────────────┐
│ BROWSER / CLIENTE │
│ │
│ React 19 ──── Zustand (estado) ──── Framer Motion (animações) │
│ │ │
│ Tailwind CSS ── Radix UI ── react-hook-form + zod │
│ │ │
│ Puck Editor (edição visual) ── TipTap (rich text) │
└────────────────────────┬────── ──────────────────────────────────┘
│ HTTP / RSC Streaming
┌────────────────────────▼────────────────────────────────────────┐
│ NEXT.JS 15 — APP ROUTER │
│ │
│ Server Components (RSC) ── Route Handlers (API Routes) │
│ │ │ │
│ middleware.ts (JWT, rate limit) Webhooks (MercadoPago/Stripe) │
└───────┬───────────────────────────┬─────────────────────────────┘
│ │
┌───────▼──────────┐ ┌───────────▼──────────────────────────────┐
│ PRISMA ORM │ │ SERVIÇOS EXTERNOS │
│ │ │ │
│ MySQL 8 (prod) │ │ MercadoPago SDK ── PIX + Cartão BR │
│ SQLite (testes) │ │ Stripe SDK ── Cartão Internacional│
└──────────────────┘ │ Nodemailer/Resend ── E-mails │
│ nfe-service ── NF-e │
│ HyperDX (OTel) ── APM/Traces │
│ MS Clarity ── Heatmaps │
└──────────────────────────────────────────┘
4. O que NÃO usamos e por quê
| Tecnologia descartada | Alternativa adotada | Motivo do descarte |
|---|---|---|
| Redux Toolkit | Zustand | Overhead de boilerplate (actions, reducers, selectors) para um estado de carrinho que cabe em ~60 linhas. Zustand é suficiente e muito mais simples de manter. |
| Pages Router | App Router (Next.js 15) | Pages Router não suporta React Server Components nem Streaming com Suspense. A migração para App Router foi realizada durante a fase de setup do projeto, evitando dívida técnica futura. |
| Redis (rate limiting) | globalThis.__rateLimitStore (in-memory) | A escala atual de um único processo não justifica o custo e a complexidade operacional de provisionar Redis. O rate limiting in-memory é suficiente para o volume de tráfego projetado. Existe uma ressalva documentada no ADR-005 para migração caso o deploy evolua para múltiplas instâncias. |
| next-auth | JWT manual com jose | next-auth adiciona complexidade de configuração (providers, callbacks, adapter de banco) para um cenário de autenticação simples com um único provider (email + senha). A implementação manual com jose oferece controle total com menos dependências. |
| MongoDB | MySQL 8 | A Hostinger não suporta MongoDB em seus planos de hospedagem compartilhada. Além disso, o modelo de dados do e-commerce (produtos, pedidos, clientes, variações) é inerentemente relacional. |
| Drizzle ORM | Prisma | Ecossistema e documentação menores à época da decisão. Prisma oferece melhor DX com o Prisma Studio e geração automática de tipos. |
| Sequelize | Prisma | Ausência de type safety gerada automaticamente; API mais verbosa; sem suporte nativo a migrações declarativas. |
| Context API (React) | Zustand | Causa re-renders em todos os consumidores do contexto mesmo quando apenas uma fatia do estado muda — inaceitável para o carrinho, que é referenciado em vários componentes do header e do checkout. |