Plataforma de Eventos e Ingressos — Verzel
Visão geral
RepositórioFunçãoURLverzel-backendAPI REST — regras de negócio, autenticação, banco de dados e integrações externashttps://github.com/paulodm145/verzel-backendverzel-frontendAplicação web — interface para organizador, cliente e portariahttps://github.com/paulodm145/verzel-frontend Informações úteis
ItemDetalheRepositório backendhttps://github.com/paulodm145/verzel-backendRepositório frontendhttps://github.com/paulodm145/verzel-frontendAplicação publicadahttps://verzel-frontend.vercel.appLicençaMIT (backend)Volume de testesMais de 300 testes automatizados no backend; suíte própria de testes de integração e concorrência no frontendDocumentação da APISwagger UI em /docs e especificação OpenAPI em /docs.json, gerados a partir dos mesmos schemas Zod que validam a entradaColeção de testes manuaisColeção Postman com 28 requisições, auto-configurável (login preenche tokens automaticamente), compatível também com Insomnia e BrunoCredenciais de demonstraçãoOrganizador, dois clientes e portaria, criados via seed — usados apenas para avaliação, nunca em produçãoRegistro de decisõesADRs no backend (docs/adr/) e documento de decisões no frontend (docs/DECISIONS.md), incluindo alternativas descartadas e reversões de rumo Este projeto é uma plataforma de eventos e ingressos desenvolvida como desafio técnico Elite Dev 2026 da Verzel, composta por dois repositórios independentes que juntos formam a mesma aplicação: um backend (API) e um frontend (interface web). O sistema atende três papéis de usuário distintos — organizador, cliente e portaria — cobrindo toda a jornada, desde a criação de um evento a partir de um catálogo externo até a validação do ingresso na entrada por QR Code.
O organizador cria eventos a partir de um catálogo externo de filmes e shows, definindo data, local, capacidade e preço. O cliente navega pelos eventos publicados, escolhe um assento em um mapa de lugares, simula o pagamento e recebe um ingresso com QR Code assinado digitalmente. A portaria valida esse ingresso na entrada, distinguindo entre válido, inválido, já utilizado e evento errado, tanto pelo leitor embutido na tela quanto pela câmera nativa do celular.
O backend segue um desenvolvimento orientado por especificação (spec-driven): cada funcionalidade do backlog nasce como uma especificação escrita, evolui para um plano técnico, depois um checklist de tarefas e só então vira código. Decisões arquiteturais relevantes ficam registradas como ADRs (Architecture Decision Records), com as alternativas descartadas e o motivo da escolha.
Stack tecnológica
- Node.js 20.19+ com TypeScript
- Express 5 como framework HTTP
- Prisma ORM 7 com adapter para PostgreSQL
- PostgreSQL 16 como banco relacional
- Redis 7 para locks distribuídos e cache
- Zod para validação de schemas e geração de documentação OpenAPI
- Swagger UI para documentação interativa da API
- JWT (biblioteca jose) para autenticação
- Vitest e Supertest para testes automatizados
- Docker Compose para orquestração local de Postgres e Redis
Funcionalidades principais
- Autenticação com três papéis (organizador, cliente, portaria) e sessão revogável via refresh token opaco e rotativo
- Integração com catálogo externo (TMDb para filmes e Ticketmaster para shows) através de um padrão Adapter, com cache e tolerância a falha de provedor
- Gestão completa de eventos: criação, edição, publicação e cancelamento pelo organizador
- Reserva de assentos com proteção contra venda duplicada, combinando lock no Redis e constraint única no PostgreSQL
- Simulação de pagamento e emissão de ingresso com QR Code assinado por HMAC-SHA256, garantindo que não seja falsificável
- Validação de ingressos na portaria, distinguindo válido, inválido, já utilizado e evento errado
- Documentação OpenAPI gerada automaticamente a partir dos schemas Zod, além de coleção Postman com 28 requisições prontas
Endpoints principais
RotaDescriçãoGET /healthEstado de saúde de Postgres e RedisGET /docs · GET /docs.jsonDocumentação Swagger UI e especificação OpenAPIPOST /auth/register · /auth/loginCadastro e autenticação de clientesPOST /auth/refresh · /auth/logoutRenovação e encerramento de sessãoGET /catalog/searchBusca no catálogo externo (organizador)POST /events · PATCH /events/:idCriação e edição de eventosPOST /events/:id/publish · /cancelTransições de estado do eventoGET /events/:id/seatsMapa de assentos do eventoPOST /events/:id/reservationsReserva de assento pelo clientePOST /reservations/:id/paymentPagamento simuladoGET /tickets/mine · GET /tickets/:codeConsulta de ingressosPOST /gate/validateValidação do ingresso na portaria Testes
Mais de 300 testes automatizados. Os testes de integração usam instâncias reais de PostgreSQL e Redis, sem mocks, para validar de fato a constraint anti-overselling e o comportamento sob falha de dependências.
Frontend — verzel-frontend
O frontend cobre a jornada completa da plataforma: o cliente escolhe o assento e simula o pagamento, o organizador cria e publica eventos, e a portaria valida ingressos por QR Code ou código manual. A arquitetura segue o padrão BFF (Backend for Frontend): o navegador conversa apenas com o Next.js, que mantém login e refresh de sessão em cookies httpOnly, enquanto chamadas de domínio passam por um proxy interno.
Stack tecnológica
- Next.js 16.3 com App Router e camada BFF
- React 19 e TypeScript
- Tailwind CSS 4
- TanStack Query para dados remotos e TanStack Table para tabelas server-side
- React Hook Form com Zod para formulários e validação
- Zustand para estado efêmero de fluxo e preferências de interface
- Vitest, Testing Library e MSW para testes automatizados
Funcionalidades principais
- Fluxo completo de compra: seleção de evento, escolha de assento e pagamento simulado
- Área do organizador para criação e publicação de eventos
- Tela dedicada de check-in para a portaria, sem menu lateral, com leitor de QR Code embutido e entrada manual de código
- Resultado da validação exibido em tela cheia por dois segundos, com cor e ícone próprios para cada situação (liberado, já utilizado, evento errado, inválido)
- Leitura do ingresso também pela câmera nativa do celular, abrindo a URL pública do ingresso e oferecendo atalho direto para validação na portaria
Qualidade e verificação
O projeto prioriza testes para a lógica com custo real de defeito: concorrência no refresh de sessão, idempotência, expiração de reserva, conflitos de assento, estados da portaria, trava do leitor de QR, formulários e tabelas server-side. Markup trivial não é testado isoladamente. O pipeline de qualidade inclui checagem de formatação, lint, checagem de tipos, testes automatizados e build de produção.
Desafios técnicos
Resumo dos pontos do projeto que concentraram maior risco técnico e exigiram uma decisão deliberada, não trivial — os que costumam render melhor conversa em entrevista.
1. Evitar vender o mesmo assento duas vezes
Concorrência real: duas requisições simultâneas para o mesmo assento não podem gerar duas reservas. A solução combina duas camadas com papéis diferentes — um lock no Redis evita a corrida no caminho feliz, e um índice único parcial no PostgreSQL (restrito a reservas com status pendente ou confirmada) é a garantia final. Um teste com vinte requisições simultâneas, inclusive com o Redis derrubado propositalmente, comprova que apenas uma reserva é criada em qualquer cenário. O lock é otimização de performance; o banco é a fonte da verdade.
2. QR Code não falsificável e validável offline
O ingresso precisa ser verificável na portaria mesmo com rede instável, sem permitir forjar um código válido. A solução foi um payload legível concatenado a uma assinatura HMAC-SHA256: o conteúdo não é escondido, e sim protegido por uma assinatura que não pode ser reproduzida sem o segredo do servidor. Isso permite recusar um ingresso inventado sem sequer consultar o banco.
3. Integração com catálogo externo tolerante a falha
Duas fontes externas (TMDb e Ticketmaster) precisavam conviver atrás de uma única interface, sem que a ausência de uma chave de API quebrasse o sistema. A solução foi um padrão Adapter com uma fábrica que instancia apenas o provedor configurado; a busca responde lista vazia (não erro) quando nenhuma chave está presente, e um provedor lento ou com falha sai do resultado sem derrubar os demais.
4. Sessão segura com detecção de roubo de token
O token de acesso é curto (15 minutos) e sem revogação; o de renovação dura 7 dias, é opaco e válido uma única vez. Reapresentar um refresh token já usado derruba todas as sessões daquele usuário — indício de que o token vazou e foi reaproveitado por outra parte. A decisão aceita um efeito colateral (um cliente que repete a chamada por falha de rede também é deslogado) em troca de segurança contra roubo de sessão.
5. QR Code que funciona com a câmera nativa do celular, não só com o leitor da tela
A primeira versão do QR carregava o token assinado da API — correto do ponto de vista técnico, mas inútil na prática: a câmera nativa do iPhone e do Android não sabe o que fazer com um token, só com uma URL. A decisão foi reverter o desenho para o QR carregar a URL pública do ingresso, que abre uma página com um botão de atalho para a validação. Esse ajuste só apareceu ao testar com um aparelho real, não por leitura de código.
6. Defeitos que só apareceram testando de verdade
Dois exemplos concretos documentados no projeto: um endpoint de saúde (/health) que travava quando o Redis ficava fora do ar, enquanto o teste correspondente passava porque usava um dublê (mock) que nunca exercitava esse caminho; e um leitor de QR no frontend que baixava um arquivo .wasm de uma CDN pública em tempo de execução, quebrando justamente no cenário sem internet pública em que a portaria opera. Ambos só foram encontrados derrubando containers e dirigindo um navegador real, não por revisão estática de código.
Uso de IA no desenvolvimento
Ambos os repositórios foram construídos com apoio de ferramentas de IA — principalmente Claude Code, com uso complementar de OpenAI Codex no frontend — de forma documentada e com decisão humana explícita sobre escopo, arquitetura e autorização de merges.
AspectoBackendFrontendFerramentaClaude Code (Opus 5)Claude Code e OpenAI CodexDecisões humanasStack, convenções, fluxo spec-driven e cada decisão arquitetural registrada em ADREscopo de cada epic, autorização de merge, validação visual e reversões de rumoDefeitos encontrados na revisãoNove problemas no primeiro épico, incluindo endpoint de saúde que travava com Redis fora do arLeitor de QR que dependia de CDN pública em runtime, falhando silenciosamente sem internet