﻿@AGENTS.md

# Panorama para Claude

## Atualizacao 2026-05-10 - DAST e runbooks de seguranca

- `lib/security.ts` centraliza `shouldRevokeSessionsForUserSecurityChange()`; a rota de admin usuarios usa esse helper e `tests/security.test.ts` cobre que troca/reset de senha revoga sessoes.
- `.github/workflows/dast.yml` sobe banco SQLite efemero, roda migrations/build/start, valida `/api/health` e executa OWASP ZAP baseline.
- Runbooks operacionais novos: `docs/EDGE_SECURITY_RUNBOOK.md`, `docs/SECRET_ROTATION_RUNBOOK.md`, `docs/SERVER_HARDENING_RUNBOOK.md` e `docs/PENTEST_DAST_PLAN.md`.
- WAF/CDN, SSH/root, atualizacoes do SO e ativacoes no provedor seguem como tarefas operacionais pendentes, nao como codigo aplicado localmente.

## Atualizacao 2026-05-11 - Site modelo e landing do cliente

- Os refinamentos visuais do site modelo tambem precisam funcionar no site real do cliente (`/[tenant]`), porque a pagina publica renderiza `landingConfig` salvo em `/organizador/landing-page`.
- O dashboard da landing configura ordem, visibilidade, status de publicacao, textos e itens de hero, estatisticas, datas, lotes, sobre, programacao, palestrantes, submissao, local, hospedagem, patrocinadores, historia, instrucoes tecnicas, eventos anteriores, banners, noticias, diretoria/comissoes e normas.
- Componentes visuais novos da landing do evento devem herdar a paleta por props (`primary`, `secondary`, `accent`, `cardBg`, `cardBorder`, `sectionBg`, `darkBg`) derivadas de `getPalette(config.palette)` e respeitar `customPrimary/customSecondary/customAccent` quando ativos.
- Evite cores fixas em hover, sombras coloridas, atmosferas, gradientes e bordas de componentes do site do evento; a troca de paleta pelo cliente deve manter tudo harmonico. A excecao e a marca Tikáh no rodape, que usa o ambar oficial e linka `https://tikah.com.br`.

## Atualizacao 2026-05-10 - Modelos de certificados

- `CertificateConfig` guarda `templateKey`, `fontFamily` e `useEventBranding`.
- `/organizador/certificados` oferece modelos `CLASSICO`, `MODERNO` e `ACADEMICO`, seletor de fonte, cores editaveis, heranca da identidade do evento e previa visual.
- O download em `/api/congressista/certificados/[id]/download` tenta incorporar `Event.logoUrl` e `drawProfessionalCertificate()` renderiza o PDF conforme o modelo salvo.

## Atualizacao 2026-05-10 - Origem do nome Tikáh

- A landing institucional (`/`) possui a secao `#nome`, acessivel pelo primeiro item do menu (**O nome**), para contar a origem Maori de Tikáh.
- A copy em `lib/tikah-i18n.ts` existe em PT/EN/ES e relaciona `tika` a correto, verdadeiro, justo, apropriado e direto, com um toque curto de humor em PT sobre "tickar" tarefas importantes como feitas.
- Destaques textuais em ciano claro devem usar `#22D3EE` via `text-[#22D3EE]` em novos componentes.
- O destaque principal do hero deve permanecer como um gradiente unico de `#22D3EE` para `#F59E0B`, usando Tailwind arbitrary value para preservar as web colors oficiais.
- Nao reintroduzir seletor visual de idioma nos cabecalhos publicos da Tikáh, no site publico de evento nem no admin da landing; `?lang=` deve ficar apenas como compatibilidade tecnica.
- A landing institucional nao deve usar verde/emerald como acento; use `#22D3EE` para `Como funciona`, dominio, preco, checks, CTA `Solicitar implantacao` e estados de contato.
- A secao de implantacao assistida da landing esta oculta, mas preservada em `app/page.tsx`; nao apagar sem pedido explicito.
- O contato comercial publico e `contato@tikah.com.br` e WhatsApp `5516997986937`; botoes de e-mail da landing e do rodape devem copiar para a area de transferencia com aviso visual, nao abrir `mailto:`.
- `components/landing/landing-stats.tsx` anima os indicadores do hero somente apos scroll, quando o bloco esta perto do centro da viewport.
- A demo publica deve ser tratada como `site modelo`: menu `Ver site modelo`, CTA `Acessar site modelo` com icone de globo, e termo `site modelo` no hero em ciano sublinhado apontando para `/demo`.
- Nao usar `#contato` como destino publico; CTAs de implantacao e `/registro` devem abrir o WhatsApp publico. O logo do cabecalho aponta para `/` e rola ao topo se ja estiver na home.
- Ao mexer na landing, preserve **O nome** como primeira opcao do menu em `components/landing/tikah-header.tsx`.

## Atualizacao 2026-05-08 - Descricao contratual do escopo

- `descricao.md` foi reescrito como documento de escopo funcional para contrato/proposta, cobrindo a plataforma Tikáh por modulo: multi-tenant, site publico, idiomas, inscricoes, pagamentos, cientifico, avaliacao, anais, programacao, palestrantes, comunicacao, credenciamento, caixa, pesquisa, certificados, relatorios, LGPD, seguranca e pendencias de producao.
- Ao preparar contrato ou proposta comercial, use `descricao.md` como fonte principal e trate dominios, Asaas, SMTP, banco gerenciado, storage externo, backups, WAF/CDN, monitoramento e politicas juridicas finais como condicoes de implantacao/producao.

## Atualizacao 2026-05-08 - Landing institucional em idiomas

- A landing publica da Tikáh (`/`) suporta `?lang=pt|en|es`, com metadados e textos de venda em `lib/tikah-i18n.ts`.
- O seletor de idiomas da landing institucional usa os mesmos locales de `lib/event-i18n.ts`, mas nao depende de `landingConfig`.
- A copy publica em PT/ES deve permanecer com acentuacao real em UTF-8; nao trocar textos visiveis para ASCII.

Este projeto Ã© a plataforma **Tikáh** â€” um SaaS multi-tenant de eventos cientÃ­ficos construÃ­do em Next.js 16, com demo configurado para o ENEP 2027 (Encontro Nacional de Especialistas em Parkinson).

## Identidade do produto

- **Produto**: Tikáh (by Huryz) â€” `tikah.com.br`
- **Landing de venda**: `/` (app/page.tsx) â€” dark theme grafite/ciano com acento ambar
- **Demonstração**: `/demo` â€” evento ENEP com dados fictÃ­cios
- **Super Admin**: `daniel@huryz.com.br` / role `SUPER_ADMIN` â†’ `/tikah-admin`

## Modelo de negÃ³cio

- **Plano Ãºnico â€” sem mensalidade**
- **8% sobre cada inscriÃ§Ã£o paga**, repassado ao organizador em atÃ© 5 dias Ãºteis
- Nunca criar tabela de planos (Gratuito/Pro/Enterprise foi removida)
- A seÃ§Ã£o `#preco` na landing exibe o `8%` em destaque

## Arquitetura Multi-tenant

- Cada usuÃ¡rio que se cadastra vira ORGANIZADOR com um `Tenant` e um `Event` (RASCUNHO) criados automaticamente
- Slug gerado do e-mail: `carlaandrade@gmail.com` â†’ `carlaandrade`
- URL do evento: `tikah.com.br/carlaandrade`
- Modelo `Tenant` em `prisma/schema.prisma`: slug, plan (mantido para futura referÃªncia), status, customDomain, domainVerified, ownerId
- Slugs reservados centralizados em `lib/reserved-slugs.ts`
- Custom domain routing via `data/domain-map.json` (lido no `proxy.ts`)

## Rotas por papel

- `SUPER_ADMIN` â†’ `/tikah-admin` (painel da plataforma: tenants, SMTP, banco)
- `ORGANIZADOR` â†’ `/organizador` (dashboard com evento do prÃ³prio tenant)
- `ADMIN` â†’ `/admin` (administrador do evento demo)
- `AVALIADOR` â†’ `/avaliador`
- `CONGRESSISTA` â†’ `/congressista`
- `SECRETARIA` â†’ `/organizador/credenciamento`
- PÃºblico: `/[tenant]/*` (site do evento por slug), `/login`, `/registro`, `/demo`

## Ãreas do Sistema

### PÃºblico / Marketing
- `/` â€” Landing page de venda do Tikáh (preÃ§o Ãºnico 8%, seÃ§Ã£o `#preco`)
- `/demo` â€” Evento demo ENEP 2027 (com banner "vocÃª estÃ¡ vendo uma demonstraÃ§Ã£o")
- `/[tenant]` â€” Site pÃºblico do evento do tenant (mostra "site em construÃ§Ã£o" se nÃ£o publicado)
- `/[tenant]/login` â€” Login para participantes do evento
- `/[tenant]/registro` â€” Registro de congressistas para o evento

### Organizador (dashboard protegido)
- Meu Site, Landing Page, Participantes, SubmissÃµes, Avaliadores, ProgramaÃ§Ã£o
- Credenciamento, Etiquetas, Certificados, ComunicaÃ§Ã£o, RelatÃ³rios, ConfiguraÃ§Ãµes
- **Meu Site** (`/organizador/meu-site`): renomear slug + conectar domÃ­nio + instruÃ§Ãµes DNS

### Tikáh Admin (`/tikah-admin`)
- Dashboard com mÃ©tricas globais de tenants e eventos
- GestÃ£o de tenants: alterar plano, status, domÃ­nio customizado
- SMTP global (`SmtpConfig` no banco)
- Banco de dados (`PlatformConfig` singleton `id="singleton"`)

## Convencoes Tecnicas

- Next.js 16 App Router
- Usar `proxy.ts`, nao `middleware.ts`
- Ler documentacao local em `node_modules/next/dist/docs/` antes de mudar APIs do Next
- Em paginas server-side com rotas dinamicas, `params` e `Promise`
- Prisma Client gerado em `app/generated/prisma`
- Banco local SQLite/libSQL em `dev.db`
- Seed principal em `prisma/seed.ts`
- Evento publicado global: `lib/events.ts` â†’ `getPublishedEvent()`
- Evento do organizador (por tenant): `lib/events.ts` â†’ `getOrganizerEvent(session)`
- Consultas de congressista/avaliador devem filtrar por `eventId` do evento publicado
- A sidebar recebe sessao inicial pelo layout do dashboard; preserve isso para evitar menu renderizado com role errado no HTML inicial
- Lotes usam `endMode` (`DATE`, `CAPACITY`, `DATE_OR_CAPACITY`) e precos manuais por categoria em `lot_category_prices`; nao usar desconto percentual para novos precos
- `tenantId` e `tenantSlug` disponÃ­veis em `session.user` (via `types/next-auth.d.ts`)

## Multi-tenant: como funciona

1. UsuÃ¡rio cadastra em `/registro` â†’ `User(ORGANIZADOR)` + `Tenant(slug)` + `Event(RASCUNHO)` criados em transaÃ§Ã£o
2. DiretÃ³rios de upload criados em `public/uploads/tenants/{slug}/`
3. Organizer dashboard (`/organizador`) usa `getOrganizerEvent(session)` â€” retorna o evento do tenant
4. Site pÃºblico em `app/[tenant]/page.tsx` â€” busca o tenant pelo slug, renderiza evento PUBLICADO ou pÃ¡gina "em construÃ§Ã£o"
5. Renomear slug: `PATCH /api/organizador/tenant/slug` â€” atualiza DB, renomeia diretÃ³rios de upload best-effort, atualiza `data/domain-map.json` e grava redirecionamento 308 em `data/slug-redirect-map.json`
6. Custom domain: `PATCH /api/organizador/tenant/domain` â€” salva no DB + atualiza `data/domain-map.json`
7. Proxy rewrite/redirect: `proxy.ts` lÃª `data/domain-map.json` para rotear domÃ­nios customizados para `/{slug}` e `data/slug-redirect-map.json` para redirecionar slugs antigos

## Modelos novos (Tikáh)

- `Tenant`: slug, plan, status, customDomain, domainVerified, ownerId â†’ User
- `PlatformConfig`: singleton `id="singleton"`, config do banco e branding da plataforma
- `Event.tenantId`: FK opcional para Tenant

## Componentes da landing

- `components/landing/back-to-top.tsx` â€” botÃ£o flutuante back-to-top: chevron gordo branco (strokeWidth 5, strokeLinecap round) + logo Tikáh idÃªntico ao cabeÃ§alho. Aparece apÃ³s 400px de scroll. Hover anima a seta para cima.
- `components/landing/landing-stats.tsx` â€” indicadores comerciais do hero com contador crescente lento, acionado apos scroll quando o bloco esta perto do centro da viewport.
- `components/landing/feature-showcase.tsx` â€” carrossel mobile de funcionalidades usando native CSS scroll snap (`overflow-x-auto`, `snap-x`) e `IntersectionObserver` para atualizaÃ§Ã£o das dots em 60fps bypassando o estado do React.
- `components/landing/speaker-carousel.tsx` â€” carrossel de palestrantes

## Seguranca Ja Implementada

- Headers globais em `next.config.ts`
- Cookies NextAuth `HttpOnly`, `SameSite=Lax` e `Secure` em producao
- Rate limit local em fluxos sensiveis
- Validacao Zod em rotas principais
- Upload de palestrantes com bloqueio de SVG, validacao MIME, extensao, tamanho e assinatura
- SUPER_ADMIN protegido por role check no proxy + layout server-side
- Slugs reservados validados no registro e na API de rename
- Pendencias operacionais em `todo.md`

## Scripts uteis

- `npm run dev` â€” Sobe servidor de desenvolvimento
- `npm run build` â€” Build de produÃ§Ã£o (valida TypeScript)
- `npm run seed` â€” Popula banco com dados demo ENEP 2027 + SUPER_ADMIN
- `npm run db:reset` â€” Reset + seed (solicita consentimento explÃ­cito ao Claude)
- `setup-tenant.sh <slug>` â€” Provisiona diretÃ³rios de upload de um tenant
- `npx prisma generate` â€” Regenerar client apÃ³s mudancas no schema
- `npx prisma migrate dev --name <nome>` â€” Criar nova migration
- `npx prisma studio` â€” Interface visual do banco (localhost:5555)

## DocumentaÃ§Ã£o

- `GUIA.md` â€” Guia completo de desenvolvimento: logins demo, mapa de rotas, comandos, estrutura de arquivos, modelo de negÃ³cio, o que funciona localmente vs produÃ§Ã£o
- `CLAUDE.md` â€” Este arquivo (instruÃ§Ãµes para o Claude)
- `todo.md` â€” PendÃªncias de seguranÃ§a para produÃ§Ã£o
## Atualizacao 2026-05-08 - Multi-evento por tenant

- Organizadores/admins possuem `/organizador/eventos` para listar historico de edicoes, criar nova edicao, duplicar uma edicao existente e selecionar o evento ativo.
- O seletor lateral mostra as edicoes disponiveis e grava a escolha no cookie `tikah-active-event-id`.
- `getOrganizerEvent(session)` agora respeita o evento selecionado quando ele pertence ao tenant do usuario; se nao houver selecao valida, cai no evento mais recente do tenant ou no publicado global para ADMIN.
- A duplicacao reaproveita dados principais, landing, categorias, lotes/precos, areas tematicas, templates de e-mail, palestrantes e programacao base, mas cria a nova edicao como `RASCUNHO`.
## Atualizacao 2026-05-08 - Idiomas do evento

- `landingConfig.i18n` guarda `defaultLocale`, `enabledLocales` e traducoes parciais para `en`/`es`; PT continua sendo o conteudo base.
- `/organizador/landing-page`, aba `Idiomas`, habilita PT/EN/ES e edita traducoes das principais secoes da landing.
- O site publico do tenant usa `?lang=pt|en|es`, aplica `getLocalizedLandingConfig()` e exibe seletor de idioma quando mais de um idioma esta ativo.
- Textos fixos do sistema publico do evento ficam em `lib/event-i18n.ts`; templates de e-mail usam `EmailTemplate.locale` e possuem versoes iniciais em PT/EN/ES.

## Atualizacao 2026-05-08 - Gestao do site do evento

- `/organizador/landing-page`, aba `Gestao do site`, edita banners agendados, noticias, diretoria/comissoes e normas de inscricao com anexos.
- Banners ficam em `landingConfig.sections.banners.items`; o site publico usa o primeiro banner com `startsAt`/`endsAt` dentro da janela como imagem do hero.
- Noticias, diretoria/comissoes, normas cientificas e normas de inscricao sao renderizadas na landing publica quando o bloco esta visivel e publicado.
- `landingConfig.publishing.sections` guarda status por bloco: `PUBLISHED`, `REVIEW` ou `DRAFT`; a landing publica exibe somente `PUBLISHED`.

## Atualizacao 2026-05-08 - Etapa 2 inscricoes

- `/organizador/inscricoes` gerencia atividades opcionais vendidas com inscricao, cupons patrocinados, base de socios quites, analise de comprovantes, estornos e exportacoes CSV/XLS.
- Inscricoes registram aceite de termos (`termsVersion`, `termsAcceptedAt`, `termsAcceptedIp`), CNA, cupom, comprovantes, atividades/acompanhante e demonstrativo financeiro com taxa Tikáh de 8%.
- LGPD: `/privacidade` e `/[tenant]/privacidade` exibem politicas editaveis; `/organizador/configuracoes`, aba LGPD, salva politica/consentimentos por evento e processa solicitacoes de anonimizacao; `/congressista/perfil` permite solicitar exclusao/anonimizacao e consultar consentimentos.
- Pagamentos usam `PaymentTransaction` e Asaas como gateway principal (`ASAAS_ENV`, `ASAAS_API_KEY`, `ASAAS_WEBHOOK_TOKEN`); PIX exibe QR Code/copia e cola, boleto grava linha digitavel/URL e cartao e processado no formulario da Tikáh sem checkout externo.
- Etapa cientifica usa `AbstractType`, `EvaluationCriterion`, `AbstractFile` e campos de apresentacao/publicacao em `Abstract`; `/organizador/submissoes` configura tipos, limites, criterios, media/conceito, avaliadores min/max, desempate e conflitos.

## Atualizacao 2026-05-08 - Anais e programacao/palestrantes

- Anais consolidados ficam em `/api/organizador/anais` com capa, sumario por area/tipo, filtros por busca/area/tipo/apresentacao e ISBN/ISSN configuraveis no evento (`Event.proceedingsIsbn`, `Event.proceedingsIssn`).
- A programacao publica do evento fica em `/[tenant]/programacao` com busca e filtros por dia, sala e tipo; a agenda do participante em `/congressista/programacao` exporta PDF/iCal e mostra links de streaming quando cadastrados.
- `/organizador/programacao` cria/edita sessoes com convidados, sala, horarios, capacidade e `Session.streamingUrl`; o backend bloqueia choque de horario para o mesmo convidado via `SessionSpeaker`.
- A area do palestrante fica em `/palestrante` e `/palestrante/perfil`: o convidado confirma/recusa atividades, informa conflito, atualiza foto, mini-curriculo, dados de voo e hospedagem (`User.travelInfo`, `User.lodgingInfo`).
- Relatorios: `/api/organizador/programacao/export` gera PDF/Word/Excel/iCal; `/api/organizador/palestrantes/export` lista convites, confirmacoes, conflitos, streaming, voo e hospedagem.

## Atualizacao 2026-05-08 - Comunicacao e cartas

- `/organizador/comunicacao` virou central operacional de cartas: escolhe modelo por idioma, edita assunto/HTML, gera preview renderizado e envia por segmento.
- Segmentos suportados em `lib/communication.ts`: todos, inscritos pagos, pendentes, autores, aprovados, avaliadores, palestrantes/convidados e presentes no credenciamento.
- Novos modelos: `CommunicationCampaign` e `CommunicationRecipient`; `EmailLog` agora pode guardar `eventId`, `campaignId`, `cc`, `providerStatus`, `providerMessageId` e `error`.
- `Event.communicationCopyEmails` guarda copias para organizador/secretaria; `Event.communicationAutomationConfig` guarda toggles de automacoes de boas-vindas, inscricao, pagamento, submissao, resultado, prazos e certificados.
- APIs: `/api/organizador/comunicacao/preview`, `/api/organizador/comunicacao/enviar` e `/api/organizador/comunicacao/settings`.

## Atualizacao 2026-05-08 - Credenciamento e secretaria

- `/organizador/credenciamento` concentra leitura de cracha, busca de participantes, pendencias, socio/CNA validado, inscricao presencial e atalhos de documentos.
- APIs novas: `/api/organizador/credenciamento/participantes`, `/api/organizador/credenciamento/cracha/[id]`, `/api/organizador/credenciamento/recibo/[id]` e `/api/organizador/secretaria/inscricoes`.
- Crachas individuais usam `buildBadgePdf()` com QR code do `badgeCode`; congressista baixa pelo celular em `/api/congressista/inscricao/cracha`.
- Inscricao presencial respeita vagas de lote/atividade/categoria, aceita atividades e acompanhante, registra pagamento `SECRETARIA`, emite recibo imediato e incrementa `soldCount`.
- Check-in agora resolve o evento com `getOrganizerEvent(session)`, grava `CheckIn.location` e bloqueia pagamento/comprovante pendente diretamente para o operador.

## Atualizacao 2026-05-08 - Caixa, presenca e acesso

- Novos modelos: `CashShift`, `CashMovement`, `MaterialPickup`, `SessionAccess`; `CheckIn` ganhou `source` e `clientUid` para sincronizacao offline idempotente.
- `/organizador/credenciamento` tambem abre/fecha caixa por operador, registra ajustes/divergencias, vincula inscricoes presenciais ao caixa aberto e exibe painel de presenca com polling.
- Controle presencial registra retirada de material por cracha, acesso a sessoes/salas, capacidade por `Session.maxCapacity`, validacao de categoria opcional na API e negacao por pendencias.
- APIs novas: `/api/organizador/credenciamento/controle`, `/caixa`, `/material`, `/acesso` e `/offline-sync`.
- `app/manifest.ts` habilita experiencia instalavel/standalone apontando para `/organizador/credenciamento`; offline da recepcao usa `localStorage` e sincroniza depois.

## Atualizacao 2026-05-08 - Producao, deploy e seguranca inicial

- `DEPLOY_TIKAH.md` e o roteiro principal para subir `tikah.com.br` em AlmaLinux com root, runner self-hosted, PM2, reverse proxy, secrets, backup e checklist de validacao.
- `.github/workflows/deploy.yml` executa `npm ci`, `npx prisma generate`, `npm audit --audit-level=high --omit=dev`, `npm run build`, migracoes opcionais, `npm prune --omit=dev`, `rsync` e `pm2 startOrReload`.
- `ecosystem.config.cjs` define o app PM2 `tikah` rodando `next start` na porta configurada por `PORT`.
- `proxy.ts` ativa Basic Auth para o site publico quando `TIKAH_SITE_PASSWORD` existe. Usuario recomendado: `TIKAH_SITE_LOCK_USERNAME=tikah`; use uma senha longa e exclusiva em Secrets; `/api/*` fica liberado para healthcheck/webhooks.
- `/api/health` responde status simples para monitoramento externo.
- `lib/upload-security.ts` centraliza validacao de MIME, extensao e assinatura real; comprovantes, propostas e fotos usam esse helper.
- Hardening 2026-05-09: `lib/html.ts` sanitiza HTML rico e escapa interpolacoes de e-mail; `proxy.ts` restringe Origin em `/api/*`; cron/webhook falham fechados em producao sem secrets; workflow valida secrets fortes e cria `.htaccess` em `public/uploads`.
- Producao com PostgreSQL ainda exige migrar Prisma de SQLite/libSQL (`provider = "sqlite"` e `@prisma/adapter-libsql`) para Postgres antes de ativar migrations/deploy nesse banco.
- `next.config.ts` ganhou HSTS em producao, `X-Robots-Tag` durante trava por senha e headers adicionais de endurecimento.
- A landing institucional agora e vitrine comercial: CTAs apontam para contato por e-mail/WhatsApp, `/registro` redireciona para o WhatsApp publico e `/api/auth/register` fica bloqueada salvo `ALLOW_SELF_SERVICE_ORGANIZER_REGISTRATION=true`.
