# Handoff: Fase 5 — API externa de cliente final (/api/external) + validação 100% do Postman

Data: 21/07/2026 (noite). Sessão de origem: exposição pública + onboarding Nextcode. Retomar com sessão DEDICADA. Plano mestre: `docs/plans/2026-07-21-exposicao-publica-onboarding-plan.md` (Tasks 19-26 = esta fase). Design validado: `docs/plans/2026-07-21-exposicao-publica-api-externa-onboarding-nextcode-design.md`.

## O que a Fase 5 entrega

A API pública de cliente final em `api.monetarie.com/api/external/*` (HML `api-h`), modelo AVIV: `Authorization: ApiKey client_id:client_secret` + whitelist de IP OBRIGATÓRIA por chave + HMAC-SHA512 por POST (header `hmac`, JSON canônico com chaves em ordem alfabética, compacto, comparação constant-time) + rate limit + idempotência. Superfície EXATA = o que os docs públicos JÁ DOCUMENTAM (ver abaixo).

## ATENÇÃO: os docs públicos estão À FRENTE da API (risco reputacional)

`docs.monetarie.com` (no ar, 2 ambientes) já documenta a API externa completa com 2 collections Postman baixáveis (porte fiel rebrandado da AVIV). O backend NÃO serve nada disso ainda: `GET /api/external/ping` = 404 do Phoenix (provado vivo 21/07). Cliente que baixar o Postman hoje recebe 404. Decisão do dono pendente sobre mitigação (banner "em ativação" vs segurar divulgação) — perguntar no início da sessão se ainda não resolvido.

## Contrato = docs. Fonte da verdade para implementar

- Portal: `docs/docs-site/` (33 páginas pt + en/es). Páginas-chave: `auth-token.md` (ApiKey), `hmac.md` (algoritmo com exemplos multi-linguagem — o plug DEVE bater byte a byte com isso), `guide/environments.md`, todas as `pix-cashout-*`/`pix-cashin*`/`bank-*`/`pix-keys`/`pix-refund`/`med-*`/`infractions`/`cpf-validation`/`account-controls`/`webhooks*`.
- Collections: `docs/docs-site/public/monetarie-postman-collection.json` + `public/downloads/monetarie-api-externa.postman_collection.json` (esta tem pre-request script de HMAC — validar contra o plug real).
- Referência de implementação AVIV (ler antes de codar): `/Users/luizpenha/coreproviders/backend/lib/fluxiq_web/plugs/{api_key_auth.ex,hmac_validation.ex}` e `routers/external_router.ex` (pipeline `[:api, :api_key_authenticated, :audit_context, :hmac_validated, :rate_limited_api, :idempotent]`; GET/DELETE sem hmac; /balance sem rate limit).

## Fundação JÁ PRONTA (não refazer)

- `api_keys` no shape certo (client_id/secret_hash/prefix/permissions/ip_whitelist, escopo merchant/partner) + `ApiKeyAuth` plug EXISTE (checa whitelist quando não-vazia; Task 20 = opção `require_ip_whitelist: true` fail-closed) + pipeline `api_key_authenticated` definido no router (não usado por rota nenhuma). NÃO existe HMAC de request no core (Task 19 porta o da AVIV).
- Borda: regra do ALB público (prio 20) já roteia `api(-h).monetarie.com` paths `/api/external/*` + `/api/webhooks/nextcode/*` para o core-api:4000. Whitelist de paths fail-closed provada (Partner/admin/v2 inalcançáveis pelo host público).
- WAF em COUNT nos 2 ambientes com scope-down excluindo `/api/external/*` das managed rules; IP sets `monetarie-extapi-clients-{h,p}` criados VAZIOS (Task 25 = port do `AwsWafSyncWorker` da AVIV que sincroniza os ip_whitelist das api_keys ativas). BLOCK só com OK do dono; piso do sistema 120k req/60s.
- Gestão de chaves já existe (v2 ApiKeyController com update de ip-whitelist + admin parity controller).
- Reuso obrigatório de use cases v2/partner (NUNCA reimplementar money-path; lookup-to-pay com E2E do DICT reusado é MANDATÓRIO — memória `monetarie-money-path-submissao-inferencia-0716`). Unidade da fronteira externa = CENTAVOS.

## Sequência sugerida (Tasks do plano, TDD + review 2 estágios por task)

19 HmacValidation plug (RED contra os exemplos do hmac.md) → 20 ApiKeyAuth require_ip_whitelist → 21 pipeline+scope+ping → 22 saldo/extrato/chaves (com teste IDOR) → 23 PIX cash-out (chave/EMV) + cash-in QR + consultas + devolução (adaptadores finos sobre o funil v2; cabine mockada no seam) → 24 MED/infrações+defesa, CPF, webhooks CRUD → 25 AwsWafSyncWorker (flag OFF default) → 26 deploy HML + api_key de teste com whitelist do IP de validação + campanha 100% viva rota a rota do Postman (padrão da campanha Partner 66/66; HMAC recalculado fora do app; provas vivas; gate de paridade doc==código com o harness do F4 apontado para docs/docs-site) → PRD com OK do dono.

## Pendências herdadas da sessão de 21/07 (fora da Fase 5, não perder)

1. **Nextcode HML**: key fornecida dá 401 Invalid api-key em todos os hosts nxcd (sondado). PRD 100% ativa e provada. Falta o cliente/Nextcode confirmarem a key de jornadas de homolog; a config (`kyc_provider_configs`) já está pronta em HML esperando só a troca da credential.
2. **Jornada Nextcode viva em HML** (bloqueada no item 1): disparar PF+PJ reais pelo coreadmin, webhook finish, review, approve = user+member+conta (Task 18 do plano; código todo deployado HML core-api:190/admin:36/banking:41).
3. **SES**: ativo nos 2 (envio provado). Sandbox ainda ON (pedido de produção em análise na AWS — acompanhar); `CCS_NOTIFICATION_EMAILS` sem definição do dono; e-mail do Gabriel (cardosobiel96@gmail.com) pendente de clique de verificação.
4. **WAF COUNT → BLOCK**: observar métricas CountedRequests alguns dias; flip só com OK (isentar IP set de clientes do rate).
5. **Validação visual regra #11 do lote IB B/C+B4-B9** em ib.monetarie.com (parcial: telas de transferência validadas com screenshot em 21/07; restante do lote pendente).
6. **Deploy PRD da Frente 2 Nextcode** (core-api PRD já tem o código via deploys do dia; telas admin/banking PRD já foram nos deploys bankbox — conferir paridade de revisões no início da sessão).
7. Solicitação de saída do sandbox SES + eventual verificação do domínio de MAIL FROM em produção de e-mail em volume.

## Credenciais/segredos (Secrets Manager, NUNCA em arquivo)

`monetarie/{homolog,prod}/kyc/nextcode/api_key` (PRD = key dedicada validada; HML = key INVÁLIDA, trocar quando o cliente mandar), `monetarie/{homolog,prod}/kyc/nextcode/webhook_secret`. Execution roles já têm `kyc/*` na whitelist de secrets; task roles já têm ses:Send*.

## Estado vivo no fecho de 21/07 (conferir drift no início da sessão)

`origin/main = 136901e9`. HML: core-api:190, banking-ui:41, merchant-ui:25, admin-ui:36, docs-portal:15. PRD: core-api:83, banking-ui:11, merchant-ui:7, docs-portal:10, admin-ui:28 (sem mudança), mais os 8 TGs públicos healthy nos ALBs qrcode-*. Memória da sessão: `monetarie-exposicao-publica-onboarding-0721`.

## ADENDO: fila da OUTRA sessão de 21/07 (handoff `2026-07-21-sessao-validacao-visual-prd-handoff.md`), com status pós-sessão da noite

Itens da fila dela conferidos contra o que ESTA sessão já entregou (não repetir trabalho):

- **Item 3 (terminar) — SisbajudView PRD**: PENDENTE. Login coreadmin PRD dava 401 com admin@monetarie.com.br; alternativa provada NESTA sessão: cunhar token Guardian direto por exec (tabela platform_admins; técnica no histórico — em HML foi `encode_and_sign(%{id: uuid, type: "platform_admin"})`). Depois capturar Ordens (filtro nascendo vazio), Requisições 5308, Arquivos 5302×5309.
- **Item 4 — deploy lote IB/merchant**: DEPLOY FEITO nesta sessão nos 2 AMBIENTES (banking:41/merchant:25 HML; banking:11/merchant:7 PRD, main atual com B/C+B4-B9+autocomplete). Resta SÓ a validação visual regra #11 do restante das telas — agora SEM VPN: usar os hosts públicos ib-h.monetarie.com / ib.monetarie.com (telas de transferência já validadas com screenshot).
- **Item 2 — TED viva pelo IB em HML**: FEITO nesta sessão (TRF202607218df305259 pelo funil público do IB: aceita, SPB ack, rejected do BACEN homolog = desfecho esperado, hold devolvido ao centavo). Sobra opcional: conferir nos logs do spb o STR0008 no gate :xsd_oficial para fechar 100% formal.
- **Item 1 — CQRC**: PENDENTE (cadastral BACEN via STA; PEMs no Desktop; re-validar certqrc.zip PRD + certqrc-h.zip HML por fingerprint).
- **Item 6 — Postgrex disconnects pix PRD + silent-failure hunt**: PENDENTE, incluir os 3 achados da sessão visual (tela Configuração do STA PRD mostrando endpoint de HOMOLOG; Join timeout do canal de notificações; Rotas=0).
- **Itens 5 e 8 — designs STA (a-d) e tarifa SLB**: designs COMMITADOS pela outra sessão (21822004, incl. docs/plans/2026-07-21-tarifa-slb-mapeamento-design.md); implementação PENDENTE.
- **Item 7**: só monitorar.
- **Artefatos não commitados da outra sessão** (working tree): screenshots validacao-visual-prd (8 pngs do STA), handoff dela, handoff+relatórios do incidente JF, runbook pritunl, sta-prd-01-dashboard.png — DECIDIR COMMIT no início da próxima sessão (cuidado: relatório forense pode conter PII; conferir antes de versionar).
