> Atualização 0.2: o documento abaixo preserva o planejamento da etapa 1. O estado implementado agora está em LOCALHOST.md: multiplayer local, contas de teste, motor e persistência. Itens marcados como futuros neste registro histórico não substituem a descrição atual.

# Aurum Poker — arquitetura e regras propostas

Entrega: etapa 1. Data: 09/09/2026.

## Status real

Implementados: interface em português, lobby com busca e filtros combináveis, favoritas locais, detalhes de entrada, validação de entrada ilustrativa, roteiro visual de pré-flop até showdown, navegação por URLs, carteira e histórico sem operações, páginas de acesso bloqueadas, preferências locais de movimento/som, área administrativa indisponível e ajuda. Sem coleta de credenciais. O aviso offline reflete a conectividade do navegador, não a saúde de um servidor de jogo.

Não implementados: contas/sessões, multiplayer, bots, motor de regras, embaralhamento, avaliação de mãos, transações, PostgreSQL, Redis, NestJS, pagamentos, MFA, análise antifraude e limites aplicados no servidor. Não existe dinheiro real, moeda conversível ou resgate. O saldo 10.000 é um dado visual fixo. As cartas do roteiro são fixas, conhecidas e sem resultado financeiro. Não usar esta aplicação para aceitar depósitos.

## Decisão tecnológica

TypeScript, React 19.2.6, Next.js 16.2.6 (APIs de interface) e Tailwind 4.2.1 fazem parte do ambiente fornecido; versões resolvidas estão fixadas em package-lock.json. O build do Sites usa Vinext 1.0.0-beta.5 e Cloudflare Workers: **essa adaptação é beta**. Não declarar a pilha inteira como estável nem atribuir a ela homologação de Next.js. A interface não depende de recursos específicos do motor de jogo e pode ser migrada para build Next.js nativo.

A arquitetura futura mantém NestJS e WebSockets em processo Node separado, PostgreSQL como fonte persistente e Redis apenas se necessário. O Sites não hospeda Docker nem um daemon NestJS e não oferece conexão TCP bruta para PostgreSQL. Não substituir a contabilidade por armazenamento no navegador ou D1 silenciosamente. Para multiplayer, hospedar o backend em serviço Node/containers com TLS/WSS e PostgreSQL privado; a interface acessará HTTPS/WSS. Antes de escolher versões do backend, conferir as versões estáveis e compatíveis nesse momento, fixá-las e executar testes de integração. Nenhum backend foi instalado nesta etapa.

Fontes técnicas consultadas em 09/09/2026:
- Next.js — execução Node, Docker e limitações de exportação: https://nextjs.org/docs/app/getting-started/deploying
- NestJS — gateways, guards e adaptadores Socket.IO/ws: https://docs.nestjs.com/websockets/gateways
- Docker — implantação de Next.js: https://docs.docker.com/guides/nextjs/
- Referência de modalidade e nomenclatura (não fonte jurídica nem certificação): https://www.pokerstars.com/poker/games/texas-holdem/

## Fronteiras da aplicação futura

1. Interface: apresenta PlayerView e envia comandos de intenção. Não conhece baralho, cartas alheias, chaves, snapshots privados nem saldo calculado localmente.
2. Identidade: sessão de cookie HttpOnly, Secure e SameSite; proteção CSRF/origem; senha com Argon2id; recuperação com token único de curta duração; MFA obrigatório para administradores; revogação de sessões. Autenticar também upgrades WebSocket e revalidar expiração. Identidade é obtida da sessão, nunca de userId enviado pelo navegador.
3. Gateway NestJS: valida esquema, limita taxa/tamanho, autoriza usuário e mesa, deduplica commandId e despacha para o proprietário da mesa. Ack contém revisão/resultado; erro não altera estado.
4. Motor puro de Hold’em: recebe estado privado e comando validado, produz próximo estado e eventos. Sem banco, HTTP ou UI. RNG é injetado pelo servidor; RNG determinístico só em testes.
5. Coordenador de mesas: um escritor por mesa. SQL transacional com bloqueio por mesa, revisão compare-and-swap e fencing token monotônico. Redis não pode ser a única garantia de exclusão. Instância com token antigo não consegue gravar. Ao perder propriedade, parar ações imediatamente.
6. Contabilidade: ledger de partidas dobradas, transações ACID, saldos derivados/reconciliáveis, operações idempotentes e trilha imutável.
7. Pagamentos: adaptador externo separado, caixa de entrada de webhooks e reconciliação periódica.
8. Administração: guards server-side e RBAC; funções suporte, risco, financeiro e administrador com menor privilégio; trilha de consulta/exportação e alterações. Sem API para editar saldo.

Contratos iniciais estão em lib/poker/contracts.ts. Eles são interfaces de planejamento, não uma implementação. Montantes são strings de inteiros no transporte e bigint/NUMERIC exato no servidor. Rejeitar negativos indevidos, decimais, NaN, expoentes e valores fora dos limites de negócio. Na primeira etapa somente fichas inteiras pequenas de demonstração são formatadas no cliente.

## Regras da casa propostas para implementar na etapa 2

- Texas Hold’em No-Limit cash de 2 a 6 jogadores. Entry 20–100 BB nas mesas de exemplo. Nenhuma entrada, recarga ou saída financeira durante a resolução de uma mão: pedidos são efetivados entre mãos; jogador que pede saída continua elegível a potes já disputados.
- Botão móvel conforme assentos ativos; definir testes de transição 3→2 e 2→3 para não repetir blinds indevidamente. Regra inicial: próximo botão no próximo assento elegível em sentido horário, SB/BB nos seguintes; documentar dead button se adotado depois, sem misturar políticas.
- Heads-up: botão é SB, recebe carta por último entre os dois; SB age primeiro pré-flop, BB primeiro pós-flop. Com três ou mais, ação pré-flop começa à esquerda do BB; pós-flop, primeiro ativo à esquerda do botão.
- Distribuir duas cartas, uma por vez, começando à esquerda do botão. Queimar uma carta antes do flop, turn e river. Não expor cartas queimadas.
- Check somente se não houver diferença a pagar; call limitado ao stack; all-in não autoriza fold automático de oponentes. Fold remove elegibilidade, sem devolver contribuição já igualada.
- Aposta mínima: BB, salvo all-in menor. Raise total mínimo = maior aposta atual + último incremento completo de aposta/raise. BB forçado estabelece mínimo pré-flop mesmo se postado parcialmente por stack curto.
- All-in incompleto aumenta valor a pagar, mas não necessariamente reabre raise a quem já agiu. Manter, por jogador, valor enfrentado na última ação e incremento completo exigido. Múltiplos all-ins curtos podem cumulativamente reabrir se aumento enfrentado alcançar o incremento completo aplicável. Jogador que ainda não agiu mantém direito de raise. Cobrir também check seguido de abertura all-in menor que BB.
- Avançar rua apenas quando todos os jogadores capazes de agir tiverem respondido à aposta vigente e suas contribuições estiverem igualadas, desconsiderando all-ins. Se não há disputa de apostas possível, completar board e showdown sem exigir ações fictícias.
- Potes por faixas de contribuição: incluir fichas de quem desistiu no valor; elegibilidade somente de quem não desistiu e alcançou a faixa. Devolver excesso não igualado ao único contribuinte antes de cobrar rake. Side pot sem elegível indica erro/invariante violada e exige interrupção, nunca redistribuição arbitrária.
- Showdown: comparar melhor mão de cinco entre sete, incluindo sequências com A baixo, flush, full house, quads, kickers e empate exato. Jogar o board é permitido. Não usar a ordem de naipes para desempatar.
- Dividir cada pote entre vencedores elegíveis. Ficha indivisível começa pelo primeiro vencedor à esquerda do botão em sentido horário. Documentar e testar posição do botão, empates e vários potes.
- Vitória por desistência: resolver sem revelar cartas privadas do vencedor. Em showdown, revelar somente mãos necessárias à regra de apresentação adotada, com política explícita de muck e acesso histórico.
- Tempo: 20 segundos calculados pelo servidor. Timeout = check se legal, fold se não. Nunca call/raise automático nem gasto adicional. Desconectado permanece sujeito ao mesmo relógio. Após timeout, sit-out na próxima mão. Reconexão não reinicia prazo.
- Sit-out: não participar de novas mãos; retorno com política de blind documentada (inicialmente aguardar próximo BB). Recarga limitada ao máximo da mesa, entre mãos, com reserva contábil atômica.
- Rake de teste: 0. Futuro: percentual em basis points, teto e no-flop-no-drop explícitos antes do buy-in. Configuração copiada para a mão no início; alterações só em mãos futuras. Arredondamento para baixo na menor unidade, teto por mão; excluir apostas devolvidas e distribuir cobrança por pote com algoritmo exato documentado. Sem sorteios ou prêmios vinculados a perdas.

## Dealer automático e justiça — requisitos, ainda pendentes

Cada mesa mantém estado e ciclo independente. Não confundir mecanismo automático com botão posicional. Criar baralho de 52 cartas, aplicar Fisher–Yates usando crypto.randomInt(0, i+1), cuja seleção evita viés de módulo. Não usar Math.random. RNG não recebe jogador, saldo ou histórico. Nenhum override administrativo de cartas.

Antes de cada emissão, construir DTO com lista explícita de campos autorizados. Proibir broadcast de estado privado seguido de filtro no navegador. Nunca registrar baralho, seed ou hole cards em logs, exceções, métricas ou analytics. Persistência para recuperação deve ser criptografada com chave externa à base, acesso mínimo e auditado. Históricos públicos e privados são separados. Teste estatístico não é certificação de justiça; auditoria independente será requisito externo quando aplicável.

## Recuperação e processamento ordenado

Persistir comando aceito, revisão, eventos, estado privado criptografado e outbox na mesma transação. Idempotência por (jogador, commandId), vinculada também ao hash do payload; reutilizar chave com outro payload é erro. Não iniciar distribuição nova nem gerar baralho novo ao retomar uma mão existente.

Ao falhar uma instância: adquirir nova propriedade SQL com fencing token, carregar último snapshot e aplicar eventos posteriores, validar conservação e integridade, retomar prazo persistido (timeout determinístico se expirado), e emitir visão filtrada com revisão. Consumidores descartam revisões antigas. Liquidação usa chave única por handId/pot/version e é atômica com transição terminal; replay não paga novamente. Em corrupção, suspender mesa e congelar movimentos para revisão; compensação precisa ser auditada e não pode perder ou criar fichas. Backup e restauração são parte do teste, não apenas instrução de infraestrutura.

## Contabilidade futura

Plano de contas separa caixa/provedor, passivos de carteiras dos jogadores, reservas/stacks de mesa, saques pendentes, clearing e receita de rake. Cada transação contém journal e postings cuja soma assinada é zero por moeda. Não confiar apenas em restrição CHECK de uma linha para impor soma entre linhas: implementar função/trigger diferível e privilégio de escrita restrito.

Montantes BIGINT/NUMERIC(precision,0); bloqueios de contas em ordem canônica; impedir saldo disponível negativo; transação SERIALIZABLE ou locks explícitos com retry limitado. Idempotency key única e hash do pedido. Banir UPDATE/DELETE de journal/postings para role do aplicativo; correção = lançamento compensatório com referência ao original, justificativa, ator e aprovação conforme função. Atualização de cache de saldo ocorre na mesma transação e é reconciliada com ledger.

Exemplos (convenção débito/crédito documentada no futuro schema): depósito liquidado debita caixa/provedor e credita obrigação da carteira; entrada debita obrigação disponível e credita obrigação em mesa; retorno inverte reserva; rake debita obrigação da mesa e credita receita; saque reserva obrigação disponível em pendente e só baixa caixa quando confirmado. Ganhos/perdas transferem entre subcontas de jogadores, não criam ativo ou receita. Não misturar fixture 10.000 com dinheiro.

Conciliação: total por provedor, caixa, passivos, stacks, potes, pendências e receita, por moeda e intervalo. Um agregado em Redis nunca é prova de saldo. Relatório de divergência interrompe movimentos afetados e abre ocorrência.

Não há migração de banco nesta etapa porque nenhum banco foi conectado. Etapa 2 entrega migrations de usuários/mesas/eventos; etapa 3 entrega ledger com suas garantias e testes reais de concorrência PostgreSQL. Um schema sem essas garantias não será apresentado como carteira concluída.

## Pagamentos futuros

Adaptador retorna transação pendente; frontend nunca confirma liquidação. Webhook valida assinatura sobre corpo bruto, timestamp, conta/recebedor, moeda e valor; limites de replay, comparação constante e rotação de segredos conforme provedor. Deduplicar eventId e externalId. Eventos fora de ordem passam por máquina de estados monotônica e consulta autoritativa ao provedor em divergência. paid repetido não credita novamente; estorno exige compensação. Timeout de create exige consulta/idempotência, não criação cega de novo pagamento. Provedor sandbox não é contrato aprovado para poker. PIX depende de provedor compatível e validação explícita da atividade.

## Segurança e operação — não ativadas

Segredos fora do repositório; TLS/WSS, origem permitida, CSRF, cookies seguros, rate limiting distribuído, validação de mensagens e payloads; hash de senha forte, MFA e RBAC. Painel e API administrativos protegidos no servidor, sem confiar em flag no navegador. Backup criptografado, PITR PostgreSQL, testes de restore e logs com redaction. Definir RPO/RTO em conjunto com hospedagem antes de alegar SLA.

Investigações: sinais de chip dumping, vínculos de contas/dispositivos e padrões de ação; minimização de dados e acesso por função; nenhuma punição automática só por IP compartilhado. Revisão humana e histórico de decisões. Limites de depósito e exclusão devem bloquear servidor, webhooks e novas sessões conforme política; não apenas esconder botões. Prazos de retenção dependem da jurisdição.

## Dinheiro real: condição de bloqueio

País de operação e público ainda não foram informados. Não presumir Brasil somente porque a interface é pt-BR. Antes da etapa de ativação, pesquisar legislação, regulador e fontes oficiais atuais do país definido; obter análise jurídica da atividade concreta, licenças necessárias, requisitos de KYC/idade/AML, privacidade e tributação, e aprovação contratual do adquirente/provedor. Esta entrega não oferece parecer jurídico nem classificação regulatória de poker. Não foi iniciada integração real. Não há interruptor que permita ativar dinheiro real nesta versão: REAL_MONEY_ENABLED é false e não existem endpoints financeiros.

## Gates de entrega

1. Atual: navegação + documentação + build + testes dos filtros/entrada. Não prova motor ou segurança financeira.
2. Multiplayer: dois usuários reais em dispositivos distintos; jogo completo, heads-up, ordem/raises, RNG seguro, potes, showdown, DTO privado, retomada de socket e crash; testes unitários e de propriedades. Bots somente de teste identificados, usando mesma visão permitida ao jogador.
3. Ledger/admin: concorrência real no PostgreSQL, rollback, idempotência, soma zero, saldo não negativo, conciliação, MFA e RBAC testados.
4. Sandbox: provedor definido, assinatura inválida rejeitada, eventos duplicados/fora de ordem, recuperação e estorno verificados; limites e exclusão realmente aplicados.
5. Revisão: carga, acessibilidade, dispositivos reais, segurança independente, restore, documentação, runbooks e gate jurídico. Produção monetária exige aprovação específica posterior.

Matriz obrigatória de testes futuros: HU SB primeiro pré-flop/BB pós-flop; 3→2; raise mínimo; all-in insuficiente/reabertura cumulativa; all-ins múltiplos e side pots com folds; empate e fichas indivisíveis; uncalled bet; board jogado; A2345; desconexão/timeout; comando duplicado com payload igual/diferente; escritor antigo bloqueado; crash antes/depois de commit; replay de liquidação; cliente adversário sem hole cards; conservação stacks+potes+saídas+rake; duas reservas concorrentes contra mesma carteira; rollback, webhooks e restore.
