# Mapeamento ib-front e merchant-front vs AVIV (money-path do usuário final) — 2026-07-17

Mandato do dono: mapear com discernimento o ib-front (core/apps/banking) e o
merchant-front (core/apps/merchant) confrontando com a referência de produção
AVIV (/Users/luizpenha/coreproviders), lembrando que PIX passa pela nossa
cabine SPI e TED pela nossa cabine SPB, com o objetivo de 100% funcional para
o usuário final. Levantamento por agente com evidência arquivo:linha,
read-only; itens de validação viva listados na seção 6.

Complemento vivo da mesma data: a superfície de QR da PARTNER API foi validada
empiricamente em HML nesta sessão (token OAuth do parceiro, QR estático
com/sem valor, cobrança dinâmica, payload URL pública com JWS) e os 4 defeitos
achados (CobV expirando em 1h, worker de expiração nunca agendado, expiration
ignorada, salt do PS256 dependente do ambiente) foram corrigidos com TDD —
ver handoff 2026-07-17 e commits da sessão.

---
**Convenção de caminhos:** salvo indicação, caminhos são relativos a `/Users/luizpenha/monetarie` (nosso) e a `/Users/luizpenha/coreproviders` (AVIV). Caminhos reais confirmados: ib-front = `core/apps/banking`, merchant-front = `core/apps/merchant`; AVIV = `frontends/{banking,merchant}` + `apps/mobile`.

## 1. Inventário ib-front (`core/apps/banking`, Vue 3, base `/api`, escopo V2 `router.ex:3006`)

### Trilhos VIVOS (rota + use case real + integração real)

| Funcionalidade | Trilho (evidência) |
|---|---|
| Login/2FA | `stores/auth.ts:48,67` → `router.ex:2221,2227` → `v2/auth_controller.ex`/`v2/mfa_controller.ex` (Guardian real) |
| Saldo | `useBalances.ts:15` → `router.ex:3307/3248` → TigerBeetle real |
| Extrato | `useStatements.ts:71` → `router.ex:3438/3071` |
| Comprovante | `ReceiptView.vue:464` → `router.ex:3079` → `V2.TransactionController.receipt` |
| PIX enviar | `usePix.ts:252` `POST /accounts/:id/pix/send` (Idempotency-Key) → `router.ex:3252` → `transfer_controller.ex:257` → `OutboundOrchestrator.execute` (kill switches, limites, hold TB) → NATS `monetarie.core.pix.payment_request` → cabine `core_event_processor.ex:72` → pacs.008. VIVO ponta a ponta |
| PIX agendado | `usePix.ts:276` → `scheduled_pix_controller.ex:94` → `scheduled_pix.ex:53` + executor Oban → mesmo funil outbound. VIVO |
| PIX devolução | `PixRefundView.vue:182` → `pix_controller.ex:547` (hold + pacs.004) → NATS `monetarie.core.pix.return` → cabine (CumulativeCap). VIVO |
| Chaves PIX + claims + DICT | `usePix.ts:332-401` → req/reply `dict.api.request`/`dict.lookup.request` → dict_service responders. VIVO |
| TED enviar | `useTransfer.ts:38` → `v2/transfer_controller.ex:45/446` (hold + tx na mesma Repo.transaction) → NATS `monetarie.core.spb.transfer_request` → cabine SPB `core_event_consumer.ex:203` → STR0008. VIVO |
| Favoritos | `useTransfer.ts:52-80` + `/pix/favorites`. VIVO |
| Boleto pagar | `useBoleto.ts:59,77` → `boleto_controller_v2.ex:50` (hold + NATS `monetarie.core.npc.boleto_request` em Repo.transaction). VIVO até o publish; consumer NPC não rastreado |
| Notificações, webhooks/API keys, MED defesa, disputas, in-transit, PIX-in (crédito) | trilhos reais |
| Cartão, crédito, investimentos, capital, assembleias | vivos como camada de dados; cartão sem processadora |

### PARCIAIS ou QUEBRADOS no ib-front

1. **QR receber (gerar) é STUB**: `core/backend/lib/monetarie_web/controllers/v2/pix_controller.ex:702-717` — `# TODO: Monetarie.Pix.BRCode module not yet implemented`, BR Code por interpolação de string SEM CRC16 (termina em `"6304"` sem os 4 hex), tag 54 malformada, `qrcode_base64 = nil`. EMV inválido: nenhum app paga. O motor real da cabine (`monetarie.pix.qrcode.static|dynamic`) está ligado só na Partner API.
2. **PIX copia-e-cola quebrado no front**: `core/apps/banking/src/views/pix/PixCopyPasteView.vue:59` chama `pix.payQrCode(...)` que NÃO existe em `usePix.ts` — a tela sempre cai no catch. Backend real pronto (`pix_controller.ex:753`).
3. **TED agendada sem trilho no IB**: motor do item A ligado só no v1 `ted_controller.ex:52`; o v2 que o IB usa segura hold e publica imediatamente, `scheduled_date` ignorado pela cabine SPB (zero refs). Sem UI de agendamento; `TransferScheduledView.vue:66` consulta fonte que nunca verá `scheduled_teds`.
4. **TEF entre contas = 501**: tela ativa → `merchant_portal_controller.ex:181-182` not_implemented; handler real existe só no partner (`partner_v1/transfers_controller.ex:516`).
5. **Limites: telas estáticas** (`LimitsView.vue`, `PixLimitsView.vue`, sem chamada de API): o enforcement é real (`limit_check.ex:22-84`, noturno Res. 142) mas o usuário não consegue ver nem alterar o limite que o bloqueia.
6. Menores: comprovante de boleto stub (`boleto_controller_v2.ex:146`), criação/edição de contas 501.

## 2. Inventário merchant-front (`core/apps/merchant`)

### VIVOS
Login/2FA; extrato/documentos/conciliação; PIX enviar; devolução; chaves/DICT/claims; favoritos; fee-splits; relatório de tarifas; webhooks/API keys; equipe/RBAC; MED defesa; infrações (leitura); TED; PIX agendados (leitura/cancel).

### PARCIAIS / QUEBRADOS
1. **QR da tela do lojista = mesmo stub do IB** (`v2/pix_controller.ex:702`). Motor real só na Partner API.
2. **Criação persistida de cobrança = 501** (`merchant_portal_controller.ex:171-176`).
3. **Saque: leitura viva, criação 501** (`:178-179`).
4. **Saldo: `pending: 0` e `blocked: 0` hardcoded** (`:87-88`) — bloqueio judicial/MED invisível.
5. **Boleto: backend vivo, front "em desenvolvimento"** (`PaymentsConfirmView.vue:91-92`).
6. **Chamadas para rotas inexistentes**: `GET /transactions/search`; `/transfers/favorites` e `/transfers/lookup-account` bare; `POST /kyc/submit`; webhooks bare; `POST /infractions/:id/defense` (rota é admin_only → 403); `GET /limits` bare; onboarding colide com admin.
7. **Telas 100% mock**: Fees, Limits, DashboardAnalytics, TransactionSearch, Meds (lista), OpenFinance, Cards.
8. **Agendados com duas fontes de verdade**: merchant usa `PixAutomatico.Instruction/Recurrence`; IB usa `ScheduledPix`.

## 3. Matriz NATS (prova dos trilhos)

**Vivos ponta a ponta**: PIX out/in, devolução out/in, PIX agendado, QR via Partner (`monetarie.pix.qrcode.*`), DICT, TED out/in, TED agendada (v1), devolução SPB, transferência interna (book-transfer + trck.002).

**Mortos/assimétricos**:
- `monetarie.spb.messages.*`, `monetarie.spi.payment.*`, `monetarie.settlement.session.credit`: consumers sem publisher.
- Rotas v1 `/pix/in|/pix/out` publicam envelope SEM campo `event` (`pix_controller.ex:108,192,197`; rotas montadas em `router.ex:289-290`) → catch-all → DLQ.
- `in_house/adapter.ex:88-137` publica `recurrence.*`/`mandate.*`/`camt0*` sem `event` → DLQ. O PIX Automático vivo usa `monetarie.spi.recurrence.execute`. As telas do IB têm rotas nos DOIS controllers — validar vivo qual é chamado.
- **`monetarie.settlement.qrcode.paid` NÃO tem consumer no Core** — a cabine avisa que a cobrança foi paga e ninguém escuta (única marcação alternativa vive no caminho TB-first PROIBIDO).
- `CoreEventConsumer` SPB é `Gnat.sub` plain (não durável), mitigado pelo item E.

## 4. Confronto com AVIV

AVIV: IB e merchant quase o mesmo SPA sobre `/api/merchant` único; PIX via provider externo OnZ CloudPIX; mobile Flutter (API v2 fora do repo). Nós somos PSP direto (cabine própria) — estruturalmente superior, com toda a responsabilidade do money-path.

**AVIV tem e nós não (ou quebrado)**: gerar QR real pela TELA; copia-e-cola funcional; consulta de limites real; export CSV de extrato (30d); comprovante PDF; transferência agendada operável pela tela; TEF pela tela; defesa de infração pelo lojista; senha de transação/device binding/biometria/push (mobile).

**Diferenças com risco**: dualidade de contrato no mesmo subject (`payment_request` plano vs envelope); dois frontends divergentes com rotas bare vs scoped; agendados PIX com duas fontes.

**Temos a mais**: boleto no IB, crédito/empréstimo, investimentos, capital, assembleias, CobV via Partner, notificações in-app, cabine própria SPI/SPB/DICT.

## 5. Gaps priorizados

### P0 (money-path do usuário final quebrado/enganoso)
1. **QR receber stub (IB + merchant)** — `v2/pix_controller.ex:702-717` | delegar ao gateway existente (`use_cases/pix/gateway/qr_code.ex:28,40`, como a Partner API) | usuário gera EMV inválido e acha que vai receber | S.
2. **Copia-e-cola quebrado no IB** — `PixCopyPasteView.vue:59` (`payQrCode` inexistente) | backend pronto (`pix_controller.ex:753`) | pagar QR não funciona na tela | S.
3. **Cobrança paga sem trilho de evento ao Core** — `qr_codes.ex:442` publica `qrcode.paid` sem consumer | lojista nunca vê "pago"/webhook de cobrança | M.

### P1
4. TED agendada só no v1 (v2 debita imediato e ignora `scheduledDate`; sem UI) | S.
5. Limites invisíveis ao usuário (telas estáticas; enforcement real) | M.
6. TEF entre contas 501 com tela ativa (handler real no partner) | S/M.
7. PIX Automático com trilho duplo, um vai a DLQ (`in_house/adapter.ex:88-137`) | S.
8. Legado v1 `/pix/in|/pix/out` → DLQ com rota montada | S.
9. Defesa de infração do lojista → 403 (rota admin_only) | S.
10. Pacote de chamadas mortas do merchant (seção 2 item 6) | S cada.

### P2
11. Saldo pending/blocked hardcoded 0 | M. 12. Export CSV | S. 13. Comprovante PDF | M. 14. Boleto no merchant-front | S. 15. Comprovante de boleto | S/M. 16. Telas mock: esconder até haver trilho | S. 17. Unificar fontes dos agendados PIX | S/M. 18. Higiene NATS (consumers órfãos + publishes sem event) | S. 19. Durabilizar CoreEventConsumer SPB | M.

## 6. Validação empírica viva necessária em HML

1. QR ponta a ponta: gerar pela Partner API e PAGAR com celular real; provar que o QR da tela é recusado.
2. Cobrança paga: observar se status/webhook "pago" chega ao lojista (código diz que não).
3. Copia-e-cola no IB: reproduzir o erro no browser.
4. PIX agendado IB: D+1 + caso saldo insuficiente.
5. TED agendada: v1 com settlement_date futuro vs v2 com scheduledDate (débito imediato divergente).
6. PIX Automático pelas telas: capturar endpoint chamado + monitorar DLQ.
7. Limite noturno: PIX acima do teto após 20h; mensagem ao usuário.
8. Boleto: pagar pelo IB e confirmar consumer NPC.
9. Devolução total/parcial pela tela do IB.
10. 501s com tela ativa: o que o usuário vê.
11. Webhooks do lojista com evento real.

## Não coberto (declarado)
App mobile Flutter; consumer NPC do boleto; internals de auth/webhook/api_key, EventsView/LogsView, onboarding PF completo, CapitalIntegrate, OpenFinance; AVIV admin e /api/external; API v2 do mobile AVIV (fora do repo).

**Síntese honesta**: o money-path núcleo (PIX out/in, devolução, agendado, TED, crédito TED-in, DICT/chaves/claims) está VIVO ponta a ponta pelas telas. O que NÃO está 100% concentra-se em: recebimento por QR pelas telas (stub perigoso), pagamento por QR no IB (front quebrado), e a camada de verdade visível (limites, saldo bloqueado, status de cobrança paga, telas mock e chamadas mortas). Majoritariamente S/M porque os motores reais já existem; falta ligar as telas neles.
