# MONETARIE CORE - AUDITORIA PROFUNDA DO SISTEMA
## Data: 2026-02-09
## Escopo: Backend, Banco de Dados, Ledger, Mensageria, Seguranca, Infraestrutura

---

# RESUMO EXECUTIVO

Auditoria completa de 6 camadas do sistema Monetarie Core, executada por 6 agentes especializados
analisando ~150 arquivos, ~40.000 linhas de codigo. O sistema demonstra **arquitetura solida**
com double-entry bookkeeping, outbox pattern, e idempotencia. Porem, **43 problemas CRITICOS**
e **42 problemas HIGH** devem ser resolvidos antes do deploy em producao.

## SCORECARD GERAL

| Camada               | CRITICAL | HIGH | MEDIUM | LOW | Score |
|----------------------|----------|------|--------|-----|-------|
| Backend Architecture | 2        | 4    | 12     | 5   | 6/10  |
| Database & Schema    | 12       | 8    | 15     | 7   | 4/10  |
| NATS Messaging       | 10       | 8    | 6      | 2   | 3/10  |
| TigerBeetle Ledger   | 3        | 4    | 5      | 2   | 6/10  |
| API Security         | 5        | 4    | 7      | 1   | 5/10  |
| K8s Infrastructure   | 11       | 14   | 36     | 9   | 4/10  |
| **TOTAL**            | **43**   | **42** | **81** | **26** | **4.7/10** |

## VEREDITO: SISTEMA NAO ESTA PRONTO PARA PRODUCAO

O sistema precisa de ~2-3 semanas de hardening antes de receber trafego real.
As fundacoes sao boas, mas faltam protecoes criticas.

---

# PARTE 1: BACKEND ARCHITECTURE (Score: 6/10)

## Pontos Fortes
- Supervision tree correta com `:one_for_one`
- Outbox pattern para NATS publishing (Oban)
- Idempotencia em operacoes TigerBeetle
- Task.async com timeouts e shutdown

## CRITICAL

### C-BE-1: Pool de DB sem timeout/queue config
**Arquivo**: `backend/config/runtime.exs:17-20`
**Problema**: Sem `timeout`, `queue_target`, `queue_interval` configurados
**Risco**: Sob carga alta, checkout de conexao pode bloquear indefinidamente
**Fix**:
```elixir
config :monetarie, Monetarie.Repo,
  pool_size: 30,
  timeout: 10_000,
  queue_target: 5_000,
  queue_interval: 1_000
```

### C-BE-2: NATS connection failure nao impede app start
**Arquivo**: `backend/lib/monetarie/nats/connection.ex:31-35`
**Problema**: GenServer retorna `{:ok, state}` mesmo quando NATS falha
**Risco**: App "healthy" mas todas operacoes NATS falham silenciosamente
**Fix**: Expor status da conexao no health check

## HIGH

### H-BE-1: AuditPlug usa Task.start (fire-and-forget)
**Arquivo**: `backend/lib/monetarie_web/plugs/audit_plug.ex:78`
**Problema**: Task nao supervisionada - se crashar, audit log perdido
**Risco**: Perda de audit logs (compliance financeira)
**Fix**: Usar Oban job

### H-BE-2: Sem request size limit
**Arquivo**: `backend/lib/monetarie_web/endpoint.ex:39-42`
**Problema**: Plug.Parsers sem `:length` - aceita payloads ilimitados
**Fix**: Adicionar `length: 10_000_000`

### H-BE-3: Sem rate limiting
**Problema**: Nenhum plug de rate limiting no router ou endpoint
**Risco**: Brute-force, credential stuffing, API abuse
**Fix**: Implementar PlugAttack ou Hammer

### H-BE-4: Sem back-pressure nos NATS consumers
**Problema**: Consumers puxam mensagens sem controle de fluxo
**Risco**: OOM em cenarios de alta volumetria

---

# PARTE 2: DATABASE & SCHEMA (Score: 4/10)

## Pontos Fortes
- Particionamento por mes nas tabelas de transacoes
- UUIDs como primary keys
- Amounts em centavos (integer)
- Oban worker para manutencao de particoes

## CRITICAL

### C-DB-1: Foreign Keys ausentes nas tabelas principais
**Arquivos**: Migrations de accounts, transactions, inflow/outflow_requests
**Problema**: Sem constraints de FK no banco - apenas definidos nos schemas Ecto
**Risco**: Registros orfaos, violacoes de integridade referencial
**Fix**: Migration adicionando FKs com ON DELETE RESTRICT

### C-DB-2: Tipo de ID inconsistente (Account)
**Arquivo**: Migration usa `:bigint`, Schema usa `:integer`
**Problema**: Insercao de IDs grandes pode falhar ou truncar
**Fix**: Alinhar schema com migration (usar `:bigint`)

### C-DB-3: Indexes ausentes em colunas de alta consulta
- `transactions.requestor_id` - sem index (filtro por merchant)
- `cosif_journal_entries.tigerbeetle_transfer_id` - sem index
- `webhook_deliveries` - sem index composto para retry queue
**Fix**: Criar indexes em nova migration

### C-DB-4: Unique constraint ausente em api_keys.client_secret_hash
**Risco**: Dois API keys com mesmo hash = autenticacao quebrada
**Fix**: `CREATE UNIQUE INDEX api_keys_secret_hash_idx ON api_keys(client_secret_hash)`

### C-DB-5: Indexes de particoes nao herdados automaticamente
**Arquivo**: `backend/lib/monetarie/partition_maintenance.ex:38-51`
**Problema**: PartitionMaintenance cria particoes sem indexes
**Risco**: Novas particoes sem indexes = performance degrada mensalmente
**Fix**: Verificar se PG 16 herda indexes ou adicionar criacao explicita

### C-DB-6: Query sem paginacao (Transactions.list/0)
**Arquivo**: `backend/lib/monetarie/crud/relational/transactions.ex:26-29`
**Problema**: Sem limit - com 10M+ transacoes, OOM no BEAM
**Fix**: Remover funcao ou adicionar paginacao obrigatoria

### C-DB-7: CHECK constraints ausentes
- `transactions.amount > 0` - sem constraint no DB
- `banks.code` - migration permite 10 chars, schema valida 3
**Fix**: ALTER TABLE ADD CONSTRAINT

### C-DB-8: on_delete ausente em associacoes criticas
- api_keys.merchant_id
- webhooks.merchant_id
- transfer_favorites.merchant_id
- bank_account_fees.bank_account_id
**Risco**: Registros orfaos ao deletar merchant/account

## HIGH

### H-DB-1: N+1 query em transaction detail
**Arquivo**: `controllers/admin/transactions_controller.ex:83-84`
**Problema**: 7 queries para 1 detalhe de transacao
**Fix**: Preload em uma unica query

### H-DB-2: Metrics module silencia erros do DB
**Arquivo**: `backend/lib/monetarie/metrics.ex:159-161`
**Problema**: `rescue _ -> 0` - dashboard mostra 0 se DB cair
**Fix**: Retornar `{:error, reason}` e logar

### H-DB-3: Seed de producao com senha placeholder
**Arquivo**: `backend/priv/repo/seeds/production.exs:32`
**Problema**: Admin password = "CHANGE_ME_ON_FIRST_LOGIN"
**Fix**: Gerar hash bcrypt ou forcar reset

---

# PARTE 3: NATS MESSAGING (Score: 3/10)

## Pontos Fortes
- Outbox pattern via Oban para publicacao
- Consumers com durable subscriptions
- Idempotencia via phash2 deterministico
- Exponential backoff no retry

## CRITICAL

### C-NATS-1: JetStream streams NUNCA criados
**Problema**: Consumers tentam criar consumers JetStream, mas os STREAMS nao existem
**Consequencia**: Fallback para plain NATS (sem durabilidade)
**Risco**: Se Core crashar, todas mensagens nao processadas sao PERDIDAS
**Fix**:
```bash
nats stream add MONETARIE_PIX --subjects "monetarie.spi.>" --retention limits --max-age 168h
nats stream add MONETARIE_SPB --subjects "monetarie.spb.>" --retention limits --max-age 168h
nats stream add MONETARIE_NPC --subjects "monetarie.npc.>" --retention limits --max-age 168h
nats stream add MONETARIE_STA --subjects "monetarie.sta.>" --retention limits --max-age 168h
```

### C-NATS-2: Sem Dead-Letter Queue
**Problema**: Mensagens que falham apos max retries sao apenas logadas - nao persistidas
**Risco**: Perda permanente de dados financeiros
**Fix**: Criar tabela `nats_dead_letters` no Postgres + inserir mensagens falhadas

### C-NATS-3: Cluster failover ausente (SPOF)
**Arquivo**: `backend/lib/monetarie/nats/connection.ex:18-19`
**Problema**: Apenas 1 IP do NATS configurado (10.10.40.5)
**Realidade**: Cluster tem 3 nodes (10.10.40.5, 10.10.40.7, 10.10.40.4)
**Risco**: Se node primario cair, NATS fica inacessivel
**Fix**: Usar config multi-server do Gnat

### C-NATS-4: Sem validacao de payload antes de publicar
**Problema**: Payloads invalidos enviados ao NATS, falham no consumer
**Fix**: Adicionar validacao JSON Schema ou Ecto changeset

### C-NATS-5: Mensagens fora de ordem nao tratadas
**Problema**: Sem checks defensivos nos handlers para mensagens fora de ordem
**Cenario**: `transaction.settled` chega antes de `transaction.created`
**Fix**: Implementar state machine nos handlers

## HIGH

### H-NATS-1: Reconexao sem exponential backoff
**Arquivo**: `backend/lib/monetarie/nats/connection.ex:44-54`
**Problema**: Sempre 5s de retry - sem backoff, sem max retries, sem rotacao de IPs
**Fix**: Backoff exponencial (5s → 10s → 20s → max 60s) com rotacao de cluster

### H-NATS-2: Dead letters apenas logados
**Problema**: Apos 3 retries, mensagem e logada e descartada
**Fix**: Persistir em tabela dedicada com admin UI para replay

### H-NATS-3: Oban jobs descartados silenciosamente
**Problema**: Apos 10 tentativas, mensagem marcada como discarded sem alerta
**Fix**: Telemetry handler para alertar em `[:oban, :job, :exception]`

---

# PARTE 4: TIGERBEETLE LEDGER (Score: 6/10)

## Pontos Fortes
- Double-entry correto em TODAS as operacoes
- Account flags (`debits_must_not_exceed_credits`) previnem saldo negativo
- Idempotencia com `:exists` tratado como sucesso
- IDs deterministicos via phash2
- COSIF mapping completo e correto

## CRITICAL

### C-TB-1: Indisponibilidade do TB causa perda de operacoes
**Arquivo**: `backend/lib/monetarie/wallet.ex:204-220`
**Problema**: Se TB esta temporariamente indisponivel, operacao falha sem retry
**Risco**: Operacoes financeiras perdidas durante blips de rede
**Fix**: Outbox pattern para operacoes TB (similar ao NATS publish_async)

### C-TB-2: Race condition entre balance check e hold
**Arquivo**: `backend/lib/monetarie_web/controllers/v2/pix_controller.ex:105-109`
**Problema**: Balance check e hold sao operacoes separadas - nao atomicas
**Mitigacao**: TB rejeita com `:exceeds_credits` (flag do account)
**Risco residual**: Transacoes desnecessariamente falhadas, UX ruim
**Fix**: Confiar na flag do TB e remover check pre-emptivo, ou usar PG lock

### C-TB-3: get_balance NAO e transacional
**Arquivo**: `backend/lib/monetarie/wallet.ex:83-92`
**Problema**: Balance e snapshot eventual - pode mudar antes de uso
**Fix**: Documentar modelo de consistencia eventual ou adicionar locking

## HIGH

### H-TB-1: Transaction ID collision risk (31-bit)
**Arquivo**: `backend/lib/monetarie/nats/handlers/pix_handler.ex:243`
**Problema**: `phash2` retorna 31 bits - apenas 2 bilhoes de IDs unicos
**Risco**: Birthday paradox - 50% chance de colisao apos ~50.000 transacoes
**Fix**: Usar SHA256 do reference ou `TigerBeetlex.ID.generate()`

### H-TB-2: Batch transfer partial failures nao inspecionados
**Arquivo**: `backend/lib/monetarie/transaction.ex:119-122`
**Problema**: `release_funds/2` envia 2 transfers em batch - se um falha, nao sabe qual
**Fix**: Inspecionar erros individuais no resultado do batch

### H-TB-3: Sem coordenacao de transacao distribuida PG/TB
**Problema**: TB operation acontece ANTES do Repo.transaction. Se PG falhar:
- TB tem o transfer postado
- PG nao tem registro
**Fix**: Usar pending_transactions como source of truth em TODOS os fluxos

### H-TB-4: COSIF reconciliation faltando client_liability (code 30)
**Arquivo**: `backend/lib/monetarie/cosif/reconciliation.ex:173-177`
**Problema**: Account code 30 nao mapeado - liabilities nao reconciliadas
**Fix**: Adicionar `defp tb_code_to_account_id(30), do: <id>`

---

# PARTE 5: API SECURITY (Score: 5/10)

## Pontos Fortes
- Bcrypt com timing-attack protection
- Guardian JWT corretamente implementado
- Audit logging automatico via plug
- Webhook signing com HMAC-SHA256
- WebSocket auth via JWT

## CRITICAL

### C-SEC-1: Credenciais default hardcoded
**Arquivo**: `backend/config/runtime.exs:69`
**Problema**: `password: System.get_env("ADMIN_PASSWORD") || "Monetarie#Adm@2026"`
**Risco**: Se env var nao definida em prod, senha publica conhecida
**Fix**: `raise "ADMIN_PASSWORD required"` se nao definida

### C-SEC-2: Sem rate limiting em login
**Problema**: Zero protecao contra brute-force
**Fix**: PlugAttack com 5 tentativas/minuto por IP

### C-SEC-3: Erros internos expostos ao cliente
**Arquivo**: `backend/lib/monetarie_web/controllers/fallback_controller.ex:65-70`
**Problema**: `inspect(reason)` retorna stack traces, nomes de modulos, erros de DB
**Fix**: Mensagem generica em producao com request_id para rastreamento

### C-SEC-4: Sem correlation ID distribuido
**Problema**: Request ID nao propagado para NATS, TB, webhooks
**Risco**: Impossivel rastrear transacao end-to-end
**Fix**: Propagar request_id em todas mensagens NATS e logs

### C-SEC-5: Health check incompleto
**Arquivo**: `backend/lib/monetarie_web/controllers/health_controller.ex:26-43`
**Problema**: Verifica apenas PG e TB - falta NATS, Redis, Oban
**Risco**: K8s roteia trafego para pods com NATS quebrado
**Fix**: Adicionar checks para NATS, Redis, Oban

## HIGH

### H-SEC-1: Admin API sem verificacao de role
**Arquivo**: `backend/lib/monetarie_web/router.ex:61-114`
**Problema**: Qualquer usuario autenticado acessa endpoints admin
**Risco**: Escalacao de privilegios
**Fix**: Criar plug `EnsureAdmin` no pipeline admin

### H-SEC-2: Dados sensiveis nos logs
**Problema**: CPF, transacoes detalhadas logados sem redacao
**Fix**: Redatar PII antes de logar

### H-SEC-3: Debug info em resposta V2
**Arquivo**: `backend/lib/monetarie_web/controllers/v2/account_controller.ex:268`
**Problema**: Campo `debug: inspect(e)` na resposta JSON
**Fix**: Remover campo debug em producao

### H-SEC-4: Security headers ausentes
**Problema**: Faltam X-Content-Type-Options, X-Frame-Options, HSTS
**Fix**: Criar plug SecurityHeaders

---

# PARTE 6: KUBERNETES & INFRA (Score: 4/10)

## Pontos Fortes
- Resource requests/limits definidos
- Liveness/readiness probes configurados
- HPA no core-api
- Network policies existentes
- AlertManager configurado

## CRITICAL

### C-K8S-1: Sem pod anti-affinity
**Problema**: Todos os pods podem rodar no mesmo node
**Risco**: Falha de node = outage total apesar de 3 replicas
**Fix**: Adicionar podAntiAffinity com topologyKey hostname

### C-K8S-2: Containers rodando como root
**Problema**: Sem securityContext em core-api e frontends
**Fix**: runAsNonRoot: true, drop ALL capabilities

### C-K8S-3: Tags :latest em todas as imagens
**Problema**: Deploys nao deterministicos, rollback impossivel
**Fix**: Usar git SHA ou semantic versioning

### C-K8S-4: Sem PodDisruptionBudget nos frontends
**Problema**: Node drain pode evictar todos os pods simultaneamente
**Fix**: Adicionar PDB com minAvailable: 1

### C-K8S-5: TigerBeetle single replica + Recreate strategy
**Problema**: Downtime garantido durante updates (30-60s)
**Fix**: Migrar para cluster 3-node com replicacao

### C-K8S-6: Secrets nao versionados/documentados
**Problema**: `core-secrets` referenciado mas sem manifesto
**Fix**: Documentar processo de criacao ou usar sealed-secrets

### C-K8S-7: Senhas em plaintext no AlertManager
**Arquivo**: `infrastructure/monitoring/dashboards/alert-policies.yaml:455`
**Fix**: Mover para Kubernetes Secret

### C-K8S-8: .dockerignore ausente
**Problema**: Build context inclui .git, node_modules, .env
**Fix**: Criar .dockerignore

## HIGH

### H-K8S-1: Redis master single replica (SPOF)
**Fix**: Deploy Redis Sentinel

### H-K8S-2: NATS_HOST com apenas 1 IP
**Fix**: Configurar os 3 IPs do cluster

### H-K8S-3: TigerBeetle egress bloqueado (inclui DNS)
**Fix**: Permitir egress para kube-dns

### H-K8S-4: Sem ServiceMonitors para Prometheus
**Fix**: Criar ServiceMonitor CRs

### H-K8S-5: Alert policies referenciam metricas inexistentes
**Fix**: Deploy exporter sidecar para TigerBeetle

### H-K8S-6: Sem backup para TigerBeetle PVC
**Fix**: VolumeSnapshot schedule diario

### H-K8S-7: Migration job usa `eval` (conflito de porta)
**Fix**: Mudar para `rpc`

### H-K8S-8: Sem Grafana dashboards para Core API, Oban, Redis

---

# TOP 15 FIXES PRIORITARIOS (ROADMAP)

## Semana 1: Security & Stability

| # | Fix | Esforco | Impacto |
|---|-----|---------|---------|
| 1 | Remover senha default hardcoded | 5min | CRITICAL |
| 2 | Adicionar rate limiting (PlugAttack) | 2h | CRITICAL |
| 3 | Criar plug EnsureAdmin | 1h | HIGH |
| 4 | Fix fallback_controller (nao expor erros) | 30min | CRITICAL |
| 5 | Adicionar security headers | 30min | HIGH |
| 6 | Fix health check (NATS + Redis + Oban) | 2h | CRITICAL |
| 7 | Adicionar DB timeout/queue config | 15min | CRITICAL |

## Semana 2: Data Integrity & Messaging

| # | Fix | Esforco | Impacto |
|---|-----|---------|---------|
| 8 | Criar JetStream streams no NATS | 1h | CRITICAL |
| 9 | Criar tabela nats_dead_letters | 3h | CRITICAL |
| 10 | Adicionar FKs e indexes no DB | 4h | CRITICAL |
| 11 | Fix NATS cluster failover (3 IPs) | 2h | CRITICAL |
| 12 | Fix TX ID generation (128-bit) | 1h | HIGH |

## Semana 3: Infrastructure & Operations

| # | Fix | Esforco | Impacto |
|---|-----|---------|---------|
| 13 | Pod anti-affinity + PDBs | 2h | CRITICAL |
| 14 | Security contexts (non-root) | 2h | CRITICAL |
| 15 | Versioned image tags + .dockerignore | 1h | CRITICAL |

---

# CONCLUSAO

## O que esta BOM:
1. **Double-entry bookkeeping** correto em todas as operacoes
2. **Outbox pattern** para NATS publishing via Oban
3. **Idempotencia** em operacoes TigerBeetle
4. **Particionamento** de tabelas por mes
5. **COSIF mapping** completo para regulacao BCB
6. **Audit logging** automatico em mutations
7. **Webhook signing** com HMAC-SHA256
8. **Supervision tree** bem estruturada

## O que PRECISA de trabalho:
1. **43 issues CRITICOS** - principalmente em DB constraints, NATS streams, e K8s security
2. **Sem rate limiting** - sistema vulneravel a brute-force
3. **Sem JetStream streams** - mensageria sem durabilidade
4. **Sem anti-affinity** - HA inexistente na pratica
5. **Credenciais hardcoded** - risco de seguranca
6. **TX ID collision** - 31-bit hash = colisao em ~50K transacoes

## Veredito Final:
O sistema tem **fundacoes arquiteturais solidas** mas precisa de **hardening significativo**
antes de producao. Estimativa: **2-3 semanas** de trabalho focado nos 15 fixes prioritarios
para atingir nivel de producao. A arquitetura esta correta - o que falta e robustecer.
