# Estado empírico do projeto e dos ambientes AWS

Data da verificação: 22/07/2026
Conta AWS: `990933657879`
Região: `sa-east-1`
Perfil usado: `vulcimonetarie`

## Critério deste relatório

Este documento separa fatos reproduzidos de riscos ainda abertos. Não declara o sistema inteiro como "fail-proof": a suíte mobile permanece vermelha e existem incidentes operacionais no caminho financeiro. PRD foi somente consultado; nenhum deploy, restart, teste sintético ou alteração foi executado nesse ambiente. PIX e SPB não foram implantados nem reiniciados.

## Resultado executivo

- O onboarding corrigido está publicado somente em HML e o fluxo PF real foi executado no domínio público, sem mocks.
- O caminho roteado do PF é e-mail OTP → `verify_otp` → criação da proposta PF → `journeyLink` HTTPS → Nextcode; SMS, captura manual, selfie e revisão local não são mais roteados.
- A nova sessão temporária PF impede acesso por UUID isolado, exige CSRF em mutações e grava cookies `Secure` em runtime de produção.
- O rollout final do Core em HML foi acompanhado continuamente: 75 de 75 respostas foram HTTP 401 esperado, sem HTTP 5xx.
- Core, Banking e Merchant estão estáveis em HML e PRD, com `desired=1`, `running=1`, `pending=0` e rollout `COMPLETED`.
- Os target groups consultados de Core API, Internet Banking e Merchant estão `healthy` em HML e PRD.
- PRD continua nas revisões anteriores e não recebeu os ajustes deste trabalho.
- O estado global ainda não é verde: mobile tem 417 apontamentos de análise e 43 testes falhos; HML tem 28 mensagens em DLQ, PIXRET em quarentena e 95 retries de webhook observados durante a auditoria.

## Publicação manual em HML

O deploy seguiu o mecanismo manual já existente em `scripts/deploy_hml_arm64.sh`; nenhuma CI foi criada ou modificada.

| Serviço | Revisão HML | Imagem/digest | Estado final |
| --- | --- | --- | --- |
| Core API | `monetarie-core-api-homolog:210` | `sha256:1e5c8f8d2d20574bfa79b5e60ae93646d3c9b91a996fe569ceb1cf0290e9f09e` | `1/1`, `COMPLETED` |
| Banking UI | `monetarie-core-banking-ui-homolog:52` | `sha256:2163f51c16572d7155bd00629d2c809ee068277d8642aa34ac7ca47bb91b7b7e` | `1/1`, `COMPLETED` |
| Merchant UI | `monetarie-core-merchant-ui-homolog:30` | não alterada neste fechamento | `1/1`, `COMPLETED` |

Configuração viva dos três serviços HML após o ajuste: `minimumHealthyPercent=100`, `maximumPercent=200`, deployment circuit breaker habilitado e rollback habilitado.

## PRD consultado passivamente

| Serviço | Revisão PRD | Estado observado |
| --- | --- | --- |
| Core API | `monetarie-core-api-prod:99` | `desired=1`, `running=1`, `pending=0`, `COMPLETED` |
| Banking UI | `monetarie-core-banking-ui-prod:14` | `desired=1`, `running=1`, `pending=0`, `COMPLETED` |
| Merchant UI | `monetarie-core-merchant-ui-prod:10` | `desired=1`, `running=1`, `pending=0`, `COMPLETED` |

## Prova funcional do onboarding PF em HML

Execução feita em `https://ib-h.monetarie.com` por navegador real:

- carregamento inicial HTTP 200;
- `POST /api/onboarding` retornou 201;
- `PUT /api/onboarding/:id/personal` retornou 200;
- navegação final chegou a `/onboarding/address`;
- data persistida e relida como `1990-01-01`;
- cookie de sessão: `Secure=true`, `HttpOnly=true`, `SameSite=Lax`;
- cookie CSRF: `Secure=true`, `HttpOnly=false`, `SameSite=Lax`;
- zero erro de console e zero falha de request nessa execução completa.

A aplicação sintética retida para rastreabilidade é `d4a621c2-6990-4bbe-8311-db687f899945`. Duplicatas criadas durante a captura foram removidas transacionalmente; somente essa evidência final foi mantida.

### Limite da prova externa

O task definition HML `monetarie-core-api-homolog:210` tem `NEXTCODE_ENABLED=true` e `NEXTCODE_API_URL=https://onboarding-api.nxcd.app`. Os testes de contrato comprovam que um OTP de e-mail bem-sucedido dispara payload PF com `products=["ocr","liveness"]`, persiste proposta/registration, expõe `journeyLink` e evita duplicidade. Entretanto, a captura pública final acima executou somente criação e dados pessoais; não consumiu OTP real nem fez egress para a Nextcode. A consulta dos logs Core HML nos sete dias anteriores não encontrou eventos `[OnboardingNextcode]` ou `[NextcodeWebhook]`. Portanto, a integração está implementada, configurada e coberta por teste, mas a chamada externa PF em HML ainda não está empiricamente observada nesta auditoria.

Foram também capturadas 34 combinações de tela/viewport: todas responderam HTTP 200, sem falha de navegação e sem divergência de rota. Houve 14 respostas HTTP 401 nas aberturas artificiais de telas protegidas sem sessão — dez em `/api/onboarding/business/status` e quatro em `/api/auth/me`; são bloqueios de autenticação esperados, não respostas 5xx.

## Controles corrigidos e comprovados

- Sessão PF assinada com `Phoenix.Token`, vinculada ao UUID da aplicação e com duração de 24 horas.
- Double-submit CSRF obrigatório em POST/PUT/PATCH/DELETE autenticados pela sessão temporária.
- Tentativa de ler outro UUID retorna 404; sessão ausente ou inválida retorna 401; CSRF ausente retorna 403.
- Consulta de bureau exige JWT e restringe usuário comum ao próprio documento; administradores mantêm acesso autorizado.
- WebSocket de onboarding atribui documento/papel a partir do Guardian e restringe o tópico ao dono ou administrador.
- Frontend deixou de consultar bureau antes da sessão e passou a enviar `X-CSRF-Token` nas mutações.
- Documentos usam S3/KMS; put/get/delete foi exercitado em HML.
- Códigos SMS usam Redis, HMAC, TTL, limite de tentativas e rate limit; os cenários foram cobertos por testes.
- A etapa legada de 2FA do onboarding PJ foi removida; MFA de primeiro acesso permanece.

## Evidência automatizada

| Componente | Resultado reproduzido nesta auditoria |
| --- | --- |
| Core backend | 25 doctests, 55 properties, 8.831 testes, 0 falhas, 47 pulados, 131 excluídos |
| Banking frontend | 36 arquivos, 261 testes, 0 falhas; build de produção verde |
| Merchant frontend | 28 testes, 0 falhas |
| SPB | 17.925 testes, 0 falhas |
| PIX SPI | 1.000 testes, 0 falhas |
| PIX Dict | 473 testes, 0 falhas |
| NPC | 216 testes, 0 falhas |
| STA frontend | typecheck e build verdes |
| Mobile | vermelho: 417 apontamentos no `flutter analyze` e 43 falhas no `flutter test` |

Durante a execução isolada dos 25 testes PF/PJ/segurança, todos passaram. O ambiente de teste também emitiu warning de infraestrutura PIX: `core-pix-remuneration-consumer` tentou criar consumidor em stream inexistente (`404`, `err_code=10059`); isso não falhou a suíte, mas é um achado real a tratar antes de depender desse consumidor.

O fechamento do Core ocorreu em 333,8 segundos. A prova específica posterior de sessão/configuração executou 27 testes sem falhas. `terraform validate` passou e os arquivos Terraform tocados foram formatados. Nenhum `terraform apply` foi executado.

## Resiliência de deploy

O primeiro rollout Core observado revelou indisponibilidade potencial: o serviço vivo estava com `minimumHealthyPercent=0`, `maximumPercent=100` e deregistration delay de 300 segundos; os eventos ECS registraram aproximadamente seis minutos com `runningCount=0` durante a substituição.

A causa foi corrigida em fonte e alinhada diretamente apenas nos três serviços HML do Core, sem reinício forçado. A capacidade HML observada era de duas instâncias ARM saudáveis, enquanto a fonte declarava uma; a fonte passou a declarar `core_ecs_capacity=2`. No rollout seguinte, ECS manteve tarefa antiga e nova simultaneamente (`running=2`) até a nova ficar saudável. A sonda pública registrou 75 respostas HTTP 401 esperadas e nenhuma 5xx.

## Riscos e pendências reais

1. **Mobile vermelho:** 417 apontamentos de análise e 43 testes falhos impedem classificar o repositório inteiro como aprovado.
2. **DLQ em HML:** monitor registrou 28 dead letters para threshold 10.
3. **PIXRET em quarentena:** logs anteriores ao deploy do onboarding mostram retorno PIX retido; o caminho financeiro não foi alterado por segurança operacional.
4. **Webhooks:** foram observados 95 retries pendentes.
5. **AtomicPayment:** logs registraram falhas repetidas de void; requer investigação coordenada fora da janela de uso financeiro.
6. **Terraform:** a fonte foi corrigida, mas não aplicada. O estado vivo HML dos serviços ECS foi alinhado via AWS CLI; PRD continua inalterado.
7. **Escopo de prova:** testes, builds, logs e fluxos acima comprovam o escopo executado, mas não demonstram matematicamente ausência de defeitos em todas as integrações externas ou cenários produtivos.
8. **Nextcode externo não observado:** a implementação e o contrato estão verdes, mas falta executar em HML uma jornada autorizada até o OTP real para provar egress, recebimento do convite e retorno pelo webhook.
9. **Consumer PIX de remuneração:** o teste emitiu `stream not found` para `core-pix-remuneration-consumer`; investigar criação/nomes dos streams e bootstrap do consumidor.

## Artefatos auditáveis

- Resultado PF real: `docs/reports/screenshots/2026-07-22-onboarding-pf-session-hml/results.json`
- Capturas PF reais: `docs/reports/screenshots/2026-07-22-onboarding-pf-session-hml/`
- Matriz visual de 34 telas: `docs/reports/screenshots/2026-07-22-onboarding-hml-after/results.json`
- Capturas antes da correção: `docs/reports/screenshots/2026-07-22-onboarding-hml-before/`
- Script PF sem mocks: `scripts/codex_capture_pf_session_hml.cjs`
- Script da matriz visual: `scripts/codex_capture_onboarding_hml.cjs`

## Restrições respeitadas

- sem CI nova ou alteração de CI;
- sem deploy, restart ou teste sintético em PRD;
- sem deploy ou restart de PIX/SPB;
- sem `terraform apply`;
- sem commit ou push;
- sem gravação de segredo no repositório.

## Auditoria de escala PIX e migrations — 23/07/2026

### Demanda informada

O volume informado equivale, na média aritmética diária, a aproximadamente 115,74 PIX in/s e 28,94 PIX out/s, totalizando 144,68 eventos/s. Isso não dimensiona picos: para um desenho resiliente é necessário testar pelo menos o pico de planejamento, rajadas, retries, duplicatas, retornos e reprocessamento simultâneo. O alvo de menos de 500 ms deve ser especificado por percentil (`p95`, `p99`) e por fase; não é possível comprová-lo apenas por índices ou pela média diária.

### Migrations verificadas diretamente no Aurora HML

As consultas foram executadas pelos tasks ECS ativos, sem expor credenciais e sem alteração de dados:

| Banco | Arquivos locais considerados | Aplicadas no banco | Versão mínima | Versão máxima | Resultado |
| --- | ---: | ---: | --- | --- | --- |
| `mon_core` | 321 | 321 | `20260101000000` | `20260722190000` | completo |
| `mon_pix` | 71 versões únicas nos conjuntos Shared/SPI/Settlement | 71 | `20260101000000` | `20260719140000` | completo |
| `mon_spb` | 55 | 55 | `20260101000000` | `20260720130000` | completo |
| `mon_sta` | 8 | 8 | `20260131000001` | `20260427153455` | completo |

Os três arquivos PIX com timestamps repetidos entre aplicações foram tratados por versão única, como exige `schema_migrations`; não há migration local ausente no conjunto efetivamente comparado ao banco HML.

### Particionamento observado

No Aurora HML, a consulta do catálogo PostgreSQL encontrou:

- Core: `transactions` por `started_at`, `inflow_requests` por `started_at`, `outflow_requests` por `started_at`, `cosif_journal_entries` por `entry_date`, `account_entries` por `entry_date`, `message_timeline` por `received_at`, `fee_transactions` por `created_at` e `fee_split_transactions` por `charged_at`.
- PIX: `monetarie_spi.messages` por `operation_time`, `monetarie_auth.activity_log` por `created_at` e `monetarie_auth.login_history` por `logged_in_at`.
- O `Shared.PartitionManager` mantém apenas `activity_log`, `login_history` e `messages`, com janela de 60 dias; ele não mantém as tabelas de transação do SPI nem as tabelas financeiras do Core.
- **Gap crítico:** `monetarie_spi.transactions` não é particionada. Ela possui índices por E2E, message ID, institution, status, operação e ISPB, mas crescerá indefinidamente com o volume PIX informado.
- As tabelas particionadas HML estão sem dados estimados relevantes no momento da consulta; portanto, não há benchmark real de plano, cache, bloat ou concorrência que valide 500 ms.

### Índices e capacidade

Os índices existentes cobrem várias chaves de idempotência e consultas operacionais, e o Core já recebeu índices compostos para `transactions` e `account_entries` por partição. Ainda assim, a meta de escala não está comprovada porque falta:

1. particionar `monetarie_spi.transactions` por tempo, com estratégia de retenção/arquivamento e índices locais por partição;
2. definir a chave de particionamento e o contrato de unicidade para E2E/message ID, pois índices únicos em PostgreSQL particionado precisam incluir a chave de partição;
3. auditar `EXPLAIN (ANALYZE, BUFFERS)` das consultas de ingestão, deduplicação, status, reconciliação, retorno e settlement em dados sintéticos na ordem de bilhões de linhas;
4. medir WAL, checkpoints, autovacuum, bloat, locks, pool de conexões, I/O, CPU, latência NATS e latência das cabines em carga sustentada e rajadas;
5. dimensionar retenção, arquivamento, réplicas de leitura e capacidade Aurora para o pico, incluindo retries e reprocessamento, não somente 144,68 eventos/s médios;
6. validar o caminho inteiro Core → NATS → cabine PIX → retorno/settlement → ledger: índice PostgreSQL não torna a liquidação externa sub-500 ms.

Conclusão desta etapa: migrations HML estão completas nos quatro bancos, mas a arquitetura de persistência ainda não está pronta para ser declarada suportada em 7,5M PIX in + 2,5M PIX out por dia. O particionamento de `monetarie_spi.transactions`, o plano de índices locais e o teste de carga controlado são pré-requisitos antes de qualquer aprovação de capacidade.

## Diagnóstico do e-mail OTP no onboarding PF — 23/07/2026

### Causa reproduzida

O task HML anterior estava em `MIX_ENV=prod`, com `EMAIL_TRANSPORT=ses` e remetente `nao-responda@monetarie.com`, porém `Application.get_env(:monetarie, :env)` não era configurado no `runtime.exs`. O código de `ContactVerification` usa esse valor para decidir entre envio real e modo de desenvolvimento. Os logs CloudWatch `/ecs/monetarie/homolog/core-api` registraram, em duas tentativas, `DEV MODE — Email OTP ...`; portanto o OTP era persistido e a API respondia sucesso, mas o `OtpEmail.deliver` não era chamado.

### Correção e validação

- `core/backend/config/runtime.exs` passou a definir `config :monetarie, :env, :prod` no bloco de produção.
- O teste de configuração e o teste de OTP passaram: `17 tests, 0 failures`.
- HML foi publicado manualmente pela revisão `monetarie-core-api-homolog:211`; ECS terminou com `desired=1`, `running=1`, `pending=0` e rollout `COMPLETED`. Os health checks posteriores responderam HTTP 200.

### Bloqueio operacional SES

A conta SES `sa-east-1` permanece em sandbox (`ProductionAccessEnabled=false`), com limite de 1 mensagem/s e 200/dia. A identidade `monetarie.com` está verificada, com DKIM e MAIL FROM em `SUCCESS`; `monetarie.com.br` não está cadastrada. Assim, o remetente configurado não é a causa, mas destinatários reais não verificados continuam bloqueados pelo sandbox. A prova final deve usar a identidade de teste verificada ou aguardar a aprovação do pedido de produção SES.

## Desenho de execução HML e preparação PRD

Ordem proposta, sem alteração em PRD nesta etapa:

1. **E-mail HML:** executar uma jornada controlada para destinatário SES verificado; capturar logs de `ContactVerification`, resultado SES e recebimento. Em seguida, decidir entre solicitar produção SES ou manter sandbox explicitamente restrito.
2. **Observabilidade:** transformar falha de entrega em evento/contador com alerta; o caminho não pode retornar “sucesso” sem distinguir aceitação pelo SES de entrega final.
3. **Integrações:** tratar `MONETARIE_DLQ` com 28 mensagens, o stream ausente de `core-pix-remuneration-consumer`, 95 retries de webhook e a devolução PIXRET em quarentena antes de carga financeira.
4. **Escala PIX:** desenhar `monetarie_spi.transactions` particionada por tempo, índices locais e contrato de unicidade compatível com PostgreSQL particionado; medir retenção, arquivamento, WAL, autovacuum, locks e pool antes de migrar.
5. **Carga HML:** testar ingestão, deduplicação, status, retorno, settlement e ledger com média de 144,68 eventos/s, picos, retries e duplicatas. Aprovar somente com `p95`/`p99` por fase e ponta a ponta abaixo de 500 ms.
6. **PRD readiness:** preparar diff de migrations, backup/restore, rollback, janela, canário, alarmes, critérios de abortar e evidência de HML. Só então submeter mudança para aprovação; PRD permanece passivo.

O desenho não declara capacidade ou entrega “fail-proof” antes dessas provas; cada gate precisa de evidência observável e plano de reversão.

### Incidente de publicação PRD — 23/07/2026

A primeira task definition PRD derivada para o ajuste de onboarding foi a `monetarie-core-api-prod:100`. O boot falhou repetidamente com `DOCUMENT_STORAGE_BUCKET is required in AWS runtimes`. A investigação comparativa confirmou que as task definitions anteriores não declaravam esse bucket, enquanto o `runtime.exs` passou a exigir também `DOCUMENT_STORAGE_KMS_KEY_ID`.

Correção operacional aplicada: criação do bucket privado `monetarie-onboarding-documents-prod-990933657879`, bloqueio de acesso público, versionamento, SSE-KMS com `alias/monetarie-core-prod` e política mínima no task role `monetarie-ecs-task-prod`. A task definition `:101`, derivada da `:100` e acrescida dessas duas variáveis, foi publicada. O serviço PRD está com `desired=1`, `running=1`, target group `healthy` e logs posteriores com HTTP 200 em `/health`. A `:100` é imutável e permanece registrada, mas não é a revisão ativa porque não contém a configuração necessária.

O incidente também revelou um gap de capacidade do ambiente: o ASG PRD estava limitado a uma instância `t4g.small`, com memória livre insuficiente para uma segunda tarefa durante rollout. O ASG foi ampliado para `max=2`/`desired=2`; a segunda instância foi registrada no ECS e permitiu a recuperação da publicação.
