# Validação e dia do evento

**Para quem:** produtor, equipe de porta, operação no local  
**Última revisão:** 2026-07-13  
**Rotas relacionadas:** `/seller/validate-ticket/[password]`, `/seller/validate-ticket/bar/[barPassword]`, `/seller/validate-ticket/store/[id]`

---

## O que você consegue fazer

- Validar ingressos por QR code na entrada
- Buscar ingressos por nome ou e-mail (a partir de 3 caracteres) e validar manualmente
- Validar consumo no bar digital
- Validar compras na loja da organização

---

## Pré-requisitos

- Evento criado com ingressos vendidos
- Link ou senha de validação do evento (gerada automaticamente na criação)
- Dispositivo com câmera (para QR) ou teclado (para busca por nome ou e-mail)
- Conexão com internet no local (validação é em tempo real via Convex)

---

## Passo a passo — Validar ingressos do evento

### 1. Acessar a página de validação

No card expandido do evento em `/seller/events`, clique em **validar tickets**.

A rota é `/seller/validate-ticket/{password}` — a senha tem 12 caracteres e é única por evento.

**Atenção:** este link contém a senha do evento. Compartilhe apenas com pessoas de confiança na equipe de porta. A UI exibe aviso de segurança ao abrir o link.

### 2. Validar por QR code

1. Aponte a câmera para o QR do ingresso (no app do comprador ou e-mail)
2. O scanner lê o ID do ticket no Convex
3. Se válido: status muda para `used`, `checkinTime` é registrado, feedback de sucesso
4. Scanner reseta após ~1 segundo para o próximo ingresso

**QR inválido:** URLs, textos aleatórios ou IDs fora do formato são rejeitados.

### 3. Validar por nome ou e-mail

1. Digite pelo menos 3 letras do nome ou e-mail do comprador
2. A lista mostra quem tem ingresso neste evento e vai afinando conforme você digita mais
3. Selecione a pessoa para ver os ingressos e validar cada um

Útil quando o comprador não consegue exibir o QR (bateria, tela quebrada, etc.).

### 4. Resultados possíveis

| Resultado | Significado |
|-----------|-------------|
| Sucesso | Ingresso `valid` → marcado como `used` |
| Já usado | Ingresso já validado anteriormente (`checkinTime` exibido) |
| Reembolsado / cancelado | Ingresso não pode entrar |

---

## Validação no bar digital

Rota: `/seller/validate-ticket/bar/{barPassword}`

- Usa `events.getByBarPassword` para identificar o evento/bar
- Scanner específico: `QrScannerBar`
- Busca por nome ou e-mail: `BarTicketSearchByEmail`

Acesse pelo painel do bar em `/seller/bar/[id]` ou pelo card do evento.

---

## Validação na loja

Rota: `/seller/validate-ticket/store/[id]`

Para retirada/validação de produtos comprados na loja da organização.

---

## Certificado de participação

Com "emitir certificado" ativo no evento, quem fez check-in (`status: used`) recebe o certificado quando a sessão do ingresso termina:

- **E-mail automático**: até ~15 minutos depois do fim, o participante recebe um e-mail com o link do certificado. Só vale para sessões encerradas nos últimos 3 dias.
- **Download**: em `/tickets/[id]/certificate`, em PDF (A4 deitado) ou imagem PNG, nas versões clara e escura.
- **Verificação**: cada certificado tem um código (ex.: `K7QF-2M9X-HC4D`) e um QR que abrem `/certificado/[código]`, página pública que mostra participante, evento, data e carga horária. Se o ingresso for reembolsado ou cancelado depois, ou o certificado for desativado, a página mostra "certificado revogado".
- **Painel do produtor**: na aba **público**, o card "certificados" lista quem fez check-in, o código e se o e-mail saiu, com botão para enviar ou reenviar o e-mail.
- Quem tem ingresso mas não fez check-in vê no ingresso que o certificado depende do check-in.

---

## O que acontece nos bastidores

- Mutation `tickets.validateTicketStatus` só aceita tickets com `status: valid`
- O QR do ingresso é um código aleatório (`sbc1.…`), não o id do ingresso. Quando o ingresso é transferido, o QR muda: print, e-mail ou Wallet de quem enviou deixa de passar. QRs antigos (só o id) ainda são aceitos enquanto o ingresso não for transferido
- A busca por nome/e-mail valida mesmo ingresso transferido: confira o titular
- Check-in é irreversível pela validação padrão (não "desvalida" pelo scanner)
- A senha do evento (`events.password`) é diferente da senha do bar (`barPassword`)
- Eventos curados não exibem link de validação de ingressos no card do seller

---

## Problemas comuns

| Sintoma | Causa provável | O que fazer |
|---------|----------------|-------------|
| QR não lê | Luz ruim ou QR de outro evento | Use busca por nome ou e-mail |
| "Já usado" | Check-in duplicado | Verifique `checkinTime`; pode ser tentativa de reentrada |
| "Inválido" num ingresso que a pessoa diz ser dela | Ingresso foi transferido e mostraram o QR antigo (print, e-mail ou Wallet de quem enviou) | Peça o QR atual no app de quem recebeu, ou valide pela busca por e-mail conferindo o titular |
| Página não carrega evento | Senha errada na URL | Copie link de **validar tickets** do card do evento |
| Câmera não abre | Permissão negada no browser | Libere câmera nas configurações do navegador |
| Ingresso não aparece na busca | E-mail diferente do da compra | Confirme e-mail usado no checkout |

---

## Referências de código (time interno)

- `app/seller/validate-ticket/[password]/page.tsx` — validação de ingressos
- `app/seller/validate-ticket/bar/[barPassword]/page.tsx` — bar
- `app/seller/validate-ticket/store/[id]/page.tsx` — loja
- `components/seller/QrScanner.tsx` — scanner de ingressos
- `components/seller/TicketSearchByEmail.tsx` — busca por nome ou e-mail
- `convex/tickets.ts` — `validateTicketStatus`, `searchEventTicketsByEmail`, `suggestEventEmailsByPrefix`
- `convex/events.ts` — `getByPassword`, `getByBarPassword`
