# Dossie de paridade PROFUNDO — camt.052 / camt.053 (saldo e extrato)

Auditor: revisao senior PIX. Modo READ-ONLY, zero inferencia (afirmacao so com prova arquivo:linha ou tabela.coluna). pt-br sem travessao.

Legenda de veredito por item: `coberto` (paridade ou melhoria provada), `divergencia` (comportamento difere), `parcial` (parte coberta), `ausente` (nao existe do nosso lado), `INCONCLUSIVO` (sem prova suficiente).

---

## 1. Escopo

No SPI/PIX do BACEN, camt.052 e camt.053 sao mensagens de retorno (o participante NAO as origina, so as consome):

- **camt.052 (BkToCstmrAcctRpt)**: aviso de que um ARQUIVO de extrato (RELACAO_LANCAMENTOS.csv, zipado) esta pronto para download. NAO carrega saldo. Carrega: `Rpt/Id` (eco do MsgId da camt.060 solicitante), `GrpHdr/MsgId`, `Rpt/Acct/Id/Othr/Id` (ISPB), `Rpt/TxsSummry/TtlNtries/NbOfNtries` (qtd lancamentos) e `Rpt/AddtlRptInf` (referencia/hash do arquivo).
- **camt.053 (BkToCstmrStmt)**: extrato/saldo. No SPI, dois usos: (a) SALDO da Conta PI com saldos proprietarios `SADP` (disponivel), `SABK` (bloqueado), `REMN` (remuneracao); (b) EOD regular com `OPBD`/`CLBD` e lancamentos `Ntry`.

Ambos os lados sao acionados pela camt.060 (consulta de saldo/extrato).

---

## 2. LEGADO — comportamento com prova

### 2.1 Tabelas de saldo (crk_spi, provado vivo)

| Tabela | Colunas-chave (tabela.coluna) | Rows | Papel |
|---|---|---|---|
| `SpiSaldoCAMT` | `IdInstFinanc`, `DtHrSaldoDisponivel`, `DtHrSaldoBloqueado`, `VlrSaldoDisponivel numeric(28,2)`, `VlrSaldoBloqueado numeric(28,2)` (PK = IdInstFinanc+DtHrSaldoBloqueado+DtHrSaldoDisponivel) | 9788 | Foto do saldo que o BACEN reporta via camt.053 (SADP/SABK). Provado vivo: registro mais novo `2026-07-23 10:09:54 disp=1000000.00 bloq=800000.00`, atualizado a cada ~15 min. |
| `SpiSaldo` | `IdInstFinanc`, `DtMovto`, `VlrPrevisto`, `VlrConfirmado`, `VlrSaldoAnterior`, `VlrSaldoPrevisto`, `VlrSaldoConfirmado` (todos numeric(28,2)) | 180 | Razao interno diario (abertura/previsto/confirmado). |
| `SpiReqSaldo` | `Ispb`, `IspbDestino`, `DtMovto`, `IdTipoMsg (enumMsgSaldo)`, `IdStatus`, `IdTipoRequisicao`, `Vlr`, `NumCtrlIF varchar(20)` | 4084 | Log de requisicoes de saldo (camt.060). Provado vivo: 1 req a cada ~15 min. |
| `SpiSaldoSpb` | `IdInstFinanc`, `DtMovto`, `VlrSaldo`, `DtAtualizacao` | 1016 | Saldo de RESERVA SPB (fora do escopo camt.052/053 PIX). |
| `SpiCadConciliacaoStatus` | `Ispb`, `DtReferencia`, `StatusAtual int`, `MessageId`, `UltimaInicio`, `UltimaFim`, `UltimoErro`, `AguardandoArquivo bit`, `ConciliacaoManual bit` | 0 | Maquina de estado da conciliacao (feature nova/nunca rodada nesse dump). |

Prova estrutural: `SPI.Core.Infrastructure.decompiled.cs:5332-5348` (SaldoCAMTConfiguration -> ToTable("SpiSaldoCAMT"); VlrSaldoDisponivel/VlrSaldoBloqueado numeric(28,2)); `:5350-5364` (SaldoSpb). Domain: `SPI.Core.Domain.decompiled.cs:1120-1130`.

### 2.2 Parse da camt.053 (saldo) — handler v12

`SPI.Core.Application.decompiled.cs:5669-5713` (`Handlers.CAMT053.v12.TraduzRetorno`), roteado em `:5406-5409` (`("camt.053", 2020-06-01) -> v12`, grava em `IRetornoLegadoWriteRepository<SaldoCAMT>`):

- Percorre `Document/BkToCstmrStmt/Stmt`.
- Se `Stmt/Id == "00000000000000000000000000000000"` (32 zeros): trata como REMUNERACAO, le `Bal[Prtry='REMN']/Amt` e cria um `Payment` (`:5688-5696`). O `SaldoCAMTRepository` marca essa mensagem `FlDebitoCredito = 2` (Credito) -> **o legado CREDITA a remuneracao**.
- Caso contrario: le `Bal[Prtry='SADP']` (disponivel) e `Bal[Prtry='SABK']` (bloqueado) (`:5698-5707`) e monta `SaldoCAMT` com:
  - `DtHrSaldoDisponivel = SADP/Dt/DtTm`, `DtHrSaldoBloqueado = SABK/Dt/DtTm`
  - `VlrSaldoDisponivel = SADP/Amt * (SADP/CdtDbtInd=="CRDT" ? +1 : -1)`
  - `VlrSaldoBloqueado = SABK/Amt * (SADP/CdtDbtInd=="CRDT" ? +1 : -1)` <- **DEFEITO LATENTE do legado**: usa o sinal do no SADP (`xmlNode3`) para o valor SABK, deveria usar o SABK (`xmlNode4`). Linha `:5707`.
- So parseia SADP/SABK/REMN. NAO parseia OPBD/CLBD/AVLB/PSSR/VSME.

### 2.3 Parse da camt.052 (aviso de arquivo) — handler v11

`SPI.Core.Application.decompiled.cs:5715-5795` (`Handlers.CAMT052.v11`), roteado em `:5403-5405` (grava em `IRetornoLegadoWriteRepository<LogDownloadArquivos>`):

- Le o parametro `URLDOWNLOADARQUIVOSEXTRATOS`; se ausente, **dispara excecao** `SPICoreBusinessException` (`:5737-5740`).
- Percorre `Document/BkToCstmrAcctRpt/Rpt`: `AddtlRptInf` -> `nmArquivo`; `TxsSummry/TtlNtries/NbOfNtries` -> `nrEntries` (`:5746-5747`).
- **Distingue tipo de relatorio pelo JsonInput**: se contem `"TipoRelatorio":"REL"` -> `SUBDIRETORIOEXTRATO` + `FlConciliacao="S"` (extrato de conciliacao); senao -> `SUBDIRETORIOTIR` + `FlConciliacao="N"` (`:5751-5760`).
- Baixa o zip (`serviceDownload.DownloadArquivo`) e grava `LogDownloadArquivos` (`BinArquivo`, `NrLinhas`, `NmArquivo`, `FlConciliacao`) (`:5763-5789`).

### 2.4 Colunas do RELACAO_LANCAMENTOS (CSV do extrato)

`SPI.Core.Angular.Application.decompiled.cs:4391-4411` (`RegistroCAMT052Map`, 17 colunas): AccountIdentification, Amount, CreditDebitIndicator, StatusCode, BookingDate, ValueDate, InstructionIdentification, EndToEndIdentification, ClearingSystemReference, InitiatingParty, DebtorAgent, CreditorAgent, ProprietaryAgentType, ProprietaryAgent, MessageNameIdentification, ServiceLevel, Purpose.

### 2.5 Calculo do saldo exibido — SPI_SPSELSALDO (proc, provado vivo)

`crk_spi.dbo.SPI_SPSELSALDO`:
- Ancora: pega o `SpiSaldoCAMT.VlrSaldoDisponivel` mais recente com `DtHrSaldoDisponivel <= @DtFim` (`@Vlr`, `@DtInicio`).
- Soma as operacoes liquidadas (`SpiStatusOperacao.Resultado = 2`, `FlDebitoCredito <> 3`) com `DtHrOperacao > @DtInicio` -> `@VlrOper`.
- `VlrSaldoConfirmado = @Vlr + @VlrOper` (saldo BACEN + movimentos liquidados apos a foto).
- `Parciais`: agrega por `(CdMsg, FlDebitoCredito)` os movimentos do dia em `VlrPrevisto` (Resultado IN 0,2) e `VlrConfirmado` (Resultado 2) -> devolve JSON array de parciais **por tipo de mensagem**.
- `VlrSaldoAnterior = VlrSaldoConfirmado - VlrConfirmado`; `VlrSaldoPrevisto = VlrSaldoAnterior + VlrPrevisto`.

Conclusao: o saldo do legado e calculado NA LEITURA = ultima foto SADP do BACEN + liquidados locais posteriores, com desdobramento previsto/confirmado por CdMsg.

### 2.6 Razao interno — SPI_SPUPDSLDSPI (proc, provado vivo)

`crk_spi.dbo.SPI_SPUPDSLDSPI(@IdInstFinanc,@DtMovto,@DtContabil,@Vlr,@FlDc,@FlConf)`: mantem `SpiSaldo` (previsto/confirmado, abertura, fechamento). `@FlConf`: 0=previsto, 1=confirmado, -1=rejeitado; `@FlDc`= sinal; trata `DtContabil != DtMovto` (agendado) e propaga confirmado para dias futuros (`DTMOVTO > @DTCONTABIL`).

### 2.7 Traducao para exibicao (central de mensagens)

`SPI.Core.Angular.Application.decompiled.cs:665-694` (dispatch por MsgDefIdr), `:797-815` (TraduzCAMT052: MSG ID, PARTICIPANTE DIRETO, QTD LANCAMENTOS `TxsSummry/TtlNtries/NbOfNtries`, HASH `AddtlRptInf`), `:817-842` (TraduzCAMT053: por `Stmt/Bal` mostra TIPO SALDO `Tp/CdOrPrtry/Prtry`, VALOR `Amt`, SINAL `CdtDbtInd`, DATA `Dt/DtTm`).

### 2.8 Auto-refresh de saldo na leitura — SaldoUseCase.Find

`SPI.Core.Angular.Application.decompiled.cs:2229-2265`: le parametro `ATUALIZACAOSALDOHORAS` (default 24). Se `_saldoCAMTRepo.FindAfter(now - N horas) == null` (nao ha foto CAMT recente), **gera automaticamente uma camt.060** (`CAMT060ApiSaldoAtualDTO{IdSystem=3}`) e so entao devolve o `_saldoRepo.Find` (SpiSaldo interno). Auto-solicitacao de saldo sob demanda quando a foto esta velha.

### 2.9 Worker de conciliacao (repair, com prova)

`SPI.Core.Worker.Conciliacao.decompiled.cs:119-189` (WorkerConciliacao): laco continuo, pausa `MILISSEGUNDOS_PAUSA_THREAD` default 60000ms (`:127`), lida de `SpiWorker.TempoPausa` (`:180-181`); a cada ciclo chama `ExecutaVerificacaoArquivo` com `EsEjecucionManual=false`, `DtMovtoDe=hoje`, `DtMovtoAte=23:59:59` (`:146-160`).

`SPI.Core.Angular.Application.decompiled.cs:2549-2641` (`ExecutaVerificacaoArquivoInternal`):
- Modo automatico redefine periodo para D-1 (`:2572-2576`).
- `ValidarHorarioEjecucion` (`:3900-3945`): le parametro `CONCILIACAO` (`AtivaConciliacaoAuto`, `AtivaConciliacaoManual`, `HoraIniSincAuto/Manual`, `HoraFimSincAuto/Manual`); fora da janela/desativado, encerra `Finalizado` "Fora de horario".
- Maquina de estado em `SpiCadConciliacaoStatus` via `SetStatus`: `Iniciando -> Processando -> AguardandoDownload -> ProcessandoDiferencas -> Finalizado`/`Error`; recusa disparo concorrente se ja em execucao (`:2588-2602`, retorna 98).
- Se nao ha arquivo, faz polling 2 min (`AguardaArquivosPeriodoAsync`, `:2643-2669`); esgotado, encerra pedindo "gerar novo CAMT.060 para o periodo" (`:2617-2622`).

`PagedConciliacaoList` (`:2756-2803`) + `ExecutarConciliacaoGenerica` (`:3166-3243`): carrega SPI grid (PACS.008/PACS.004), carrega entradas do CSV camt.052 (`ListarArquivosCAMT052`, `:2979-3078`, so `FlConciliacao='S'`, so BookingDate na janela, so StatusCode != INFO, so PACS.008/PACS.004), casa por `EndToEndIdentification` (008) / `RtrId` (004), e:
- **CAMT=BOOK e SPI != Efetivada -> ATUALIZA o status do SPI para Efetivada** (`AnalisarPrecedenciaStatus` `:4010-4028`, `AtualizarStatusSPI` `:4065-4102`).
- **Entrada no CAMT sem operacao local -> CRIA nova operacao SPI** a partir do CAMT (`CriarOperacaoNoSPI` `:4138-4185` + `CriarNovaOperacaoSPI` `:3791`).
- Conflito nao previsto -> `ManterAmbiguidade` (analise manual, `:3999-4006`).

Ou seja: a conciliacao do legado e um processo de CORRECAO/REPARO ativo (muta status e fabrica operacoes faltantes para casar com o extrato autoritativo do BACEN).

### 2.10 API/UI de conciliacao e saldo

- `ConciliacaoController` (`SPI.Web.Angular.Mensagens.Api.decompiled.cs:447-481,677-679`): `POST ExecutarConciliacao` (disparo MANUAL), `POST StatusConciliacao` (status), `POST listPaginaConciliacao` (grid de resultados).
- `DashboardController.montaDashboard` + `filtroOvernight` (`SPI.Web.Angular.Saldos.Api.decompiled.cs:414-513`); `SaldoCAMTController.Find/List/ListRange` (`:855-903`); `ReqSaldoController` add/list/totalPorMsg (`:750-855`); `padraoReqSaldos`/`padraoSaldos` (valores padrao de requisicao de saldo, `:532-748`).
- Angular: `LegadoPIX/Pix/SPI/angular/src/app/pages/spi/saldos/*`, `spi-dashboard/*`.

---

## 3. NOSSO — comportamento com prova (Elixir/Vue)

### 3.1 Parse da camt.053 (saldo) — Camt053Parser

`apps/spi_service/lib/spi_service/statements/camt053_parser.ex:49-93`: parseia XML (feed em BYTES, comentario `:51-55`) e extrai:
- `opening_balance` (OPBD), `closing_balance` (CLBD, default nil `:67`), `available_balance` (AVLB), `available_balance_sadp` (SADP `:71`), `blocked_balance_sabk` (SABK `:72`), `remuneration_balance` (REMN `:81`), `previous_balance_subject_remuneration` (PSSR `:82`), `settlement_balance` (VSME `:83`).
- `position_at` = `Bal/Dt/DtTm` do SADP/SABK/CLBD (`:78-80`) -> DATA DA FOTO, nao da chegada.
- `entries` (Ntry: e2e, amount, direction CRDT/DBIT, status, booking_date, counterpart_ispb) (`:204-228`).
- Sinal: DBIT negativa (`:170-174`) por balance-code, CORRIGINDO o defeito latente do legado (`:5707`).

Nosso parser e MAIS COMPLETO que o v12 do legado (SADP/SABK/REMN + OPBD/CLBD/AVLB/PSSR/VSME + position_date).

### 3.2 Aplicacao da posicao (saldo) — Balances

`apps/spi_service/lib/spi_service/balances.ex`:
- `upsert_position/5` (`:838-863`): materializa/atualiza `monetarie_spi.balances` (available/blocked/as_of/source) do retorno BACEN. Marca `source` honesto ("camt.053"/"camt.052"/"manual_homolog"/"seed"), nunca "bacen" cru (`:841-844`).
- `apply_bacen_position/5` (`:883-930`): **PROTECAO DE STALENESS** — se a foto do BACEN e MAIS VELHA que o ultimo movimento local (`stale_position?`, `:932-935`; `last_local_movement_at` via BalanceHistory `:939-955`), NAO sobrescreve o saldo vivo, so registra confirmado + conciliacao (`:900-918`); mais nova, sobrescreve (`:919-928`); sem linha, materializa (`:887-895`). Comentario cita incidente 13/07/2026 (foto de sexta apagava credito de segunda).
- `update_confirmed_balance/3` (`:972-1019`): grava `confirmed`/`confirmed_at` (checkpoint CLBD/SADP+SABK) com gate de monotonicidade por data da posicao (`:989-1008`).
- `get_projected_balance/1` (`:551-573`): `projected = available + pending_credits - pending_debits` (conceito "previsto").
- `list_all_positions/1` (`:616+`): expoe available, blocked, total, projected, confirmed, confirmed_at, as_of, source, materialized, status.

Schema `Shared.Schemas.Spi.Balance`: `available_amount`, `blocked_amount`, `projected_amount`, `total_balance`/`usable_balance` (virtual) (`apps/shared/lib/shared/schemas/spi/balance.ex:14-21`).

### 3.3 Processamento inbound da camt.053/052 — InboundProcessor

`apps/spi_service/lib/spi_service/workers/inbound_processor.ex`:
- `maybe_upsert_conta_pi_position/1` (`:2653-2673`): quando ha SADP/SABK, chama `Balances.apply_bacen_position(..., "camt.053")` usando `position_at` (Bal/Dt/DtTm) e nao o created_at.
- `maybe_credit_remuneration/2` (`:2690-2744`): quando `Stmt/Id == 32 zeros` e REMN > 0, CREDITA remuneracao (`update_balance direction :credit`, reference_type "spi_remuneration") com **idempotencia por `REMN-<message_id>`** (`:2706-2738`). Comentario cita explicitamente o handler legado `CAMT053/v12.cs:30-39` e `SaldoCAMTRepository.cs:67-71`.
- `process_account_report/2` (camt.052, `:2775-2911`): `record_audit_inbound`, `correlate_camt060_response(report_id,...)` (`:2786`), extrai report via `extract_camt052_report/1` (`:2919-2938`: report_id `//Rpt/Id`, msg_id `//GrpHdr/MsgId`, account_ispb `//Rpt/Acct/Id/Othr/Id`, entry_count `//Rpt/TxsSummry/TtlNtries/NbOfNtries`, report_ref `//Rpt/AddtlRptInf` = 1:1 com o v11 legado). **FAIL-LOUD** se `BACEN_STATEMENT_DOWNLOAD_URL` ausente (`:2796-2818`, comentario cita `Handlers.CAMT052/v11.cs:40-43`). Baixa e parseia (`StatementReportDownloader.download_and_parse`, `:2833`), persiste via `store_camt052_report` (`:2846`), publica `statement.report_available`.

### 3.4 Download + parse do extrato — StatementFile / StatementReportDownloader

- `apps/spi_service/lib/spi_service/statements/statement_file.ex:129-135`: `@relacao_lancamentos_columns` = as MESMAS 17 colunas do `RegistroCAMT052Map` legado; comentario `:124` diz "bate 1:1 com o DTO MensagemCamt052 do LegadoPIX". `parse_relacao_lancamentos/1` (`:149-161`), split que respeita aspas (`:168`).
- `apps/spi_service/lib/spi_service/statements/statement_report_downloader.ex:42`: `download_and_parse` (GET mTLS + verify SHA-256 + unzip).
- `apps/spi_service/lib/spi_service/statements.ex:513-568` (`store_camt052_report`): persiste Statement `source: "bacen_file"` (`:539`) + StatementEntries (17 colunas mapeadas: DBIT->:debit/CRDT->:credit; BOOK->:booked/INFO->:info); idempotente por statement_id=report_id (`:519-520`).

### 3.5 Conciliacao 3 vias + snapshot EOD — DailyReconciliation / EodSnapshotWorker

`apps/spi_service/lib/spi_service/daily_reconciliation.ex`:
- `reconcile_date/2` (`:147-229`): compara (a) nossos liquidados (`CanonicalTransactions.list_statement_movements`, filtrado settled `:286-293`), (b) entradas do extrato BACEN (camt.053 inbound `:306-342`, fallback arquivo baixado source="bacen_file" `:383-400`), (c) CLBD vs fechamento esperado (abertura + liquido). Detecta `divergente`/`conciliado`/`sem_extrato` (`:172-179`), grava 1 linha por (ispb, data) em `monetarie_spi.daily_reconciliations`, e **so DETECTA/ALERTA** (Logger.warning + telemetry `[:pix,:recon,:divergence]`, `:203-215`). NAO muta status nem cria operacoes.
- `snapshot_eod/2` (`:111-138`): grava `daily_balance_snapshots` (opening = fechamento anterior; closing = CLBD BACEN ou agregado). Campos do schema: `opening_balance`, `closing_balance`, `opening_source`, `closing_source` (`daily_reconciliation/balance_snapshot.ex:26-31`).
- `record_position_check/5` (`:241-271`): persiste divergencia confirmado-vs-local (kind "position").
- Agendamento: `config/config.exs:89` `{"30 3 * * *", SpiService.Workers.EodSnapshotWorker}` = 00:30 BRT, dia anterior. `apps/spi_service/lib/spi_service/workers/eod_snapshot_worker.ex:24-52` chama `run_eod`. **Cron diario unico, sem polling, sem janela configuravel, sem maquina de estado.**

### 3.6 camt.060 (consulta de saldo)

`apps/spi_service/lib/spi_service/camt060_requests.ex`: `record_sent` (`:60`), `correlate_response` por MsgId ecoado (`:99-153`), `correlate_not_found`, `sweep_timeouts` (`:243`). Disparo: `apps/spi_service/lib/spi_service_web/controllers/camt060_controller.ex:57` (`Camt060.query(action, ispb, params)`, ON-DEMAND por operador) e `med/infraction_enricher.ex:79`. **NAO ha cron de poll de saldo nem auto-refresh na leitura quando a foto esta velha.**

### 3.7 Geracao de camt.052/053 (extra nosso, nao no legado)

`apps/spi_service/lib/spi_service/statements.ex:45-107` (`generate_camt052`) e `:131-` (`generate_camt053`): GERAM statements a partir dos NOSSOS dados (statement_type "intraday"/"end_of_day", XML BkToCstmrAcctRpt/BkToCstmrStmt em `:748-844`). Isto e um artefato de relatorio local (issuer role), inexistente no legado, que so consome do BACEN.

### 3.8 Frontend (Vue admin)

`pix/frontend/admin/src/views/balance/*` (BalanceDashboardView, BalanceRequestsListView, BalanceRequestDetailView, BalanceHistoryView, BalanceParametersView, Credit/DebitRequestView, LiquidityInjectionView), `views/camt060/Camt060ToolView.vue`, `views/statements/{StatementListView,StatementGenerateView}.vue`, `views/reports/BalanceReportView.vue`, `views/accounting/ReconciliationView.vue`. Servicos: `services/{balance,statement,camt060}.ts`. Statement endpoints: `/api/v1/statements`, `/statements/generate`, `/statements/:id/download` (statement.ts:59-84).
NOTA: `ReconciliationView.vue` consome a conciliacao de SESSAO do settlement (`reconciliationRuns` PENDING/RUNNING/COMPLETED/FAILED, `settlement_service/reconciliation.ex:48-506`), que e OUTRA coisa; a `DailyReconciliation` (3 vias, camt.053) NAO tem rota de API nem tela.

---

## 4. GAPS (legado x nosso)

### G1 [divergencia, medio] Conciliacao do legado REPARA (muta status + cria operacao); a nossa so DETECTA/ALERTA
- Legado: `ExecutarConciliacaoGenerica`/`AnalisarPrecedenciaStatus`/`AtualizarStatusSPI`/`CriarOperacaoNoSPI` (`SPI.Core.Angular.Application.decompiled.cs:3166-3243,4010-4028,4065-4102,4138-4185`): CAMT=BOOK forca SPI->Efetivada; entrada CAMT sem SPI cria operacao nova.
- Nosso: `DailyReconciliation.reconcile_date` (`daily_reconciliation.ex:147-229`) grava linha divergente + Logger.warning + telemetry; nao muta status nem cria operacao.
- Risco: o legado curava drift de status automaticamente; o nosso deixa para intervencao humana (mais seguro contra fabricacao de operacao, porem drift persiste ate alguem agir). A correcao de status em tempo real, no nosso, ocorre por pacs.002/pacs.004/camt.054 (mensagens reais), nao pela via extrato.

### G2 [divergencia, medio] Gatilho da conciliacao: continuo+janela+maquina-de-estado x cron diario unico
- Legado: `WorkerConciliacao` (`SPI.Core.Worker.Conciliacao.decompiled.cs:127-160`) roda a cada 60s; `ValidarHorarioEjecucion` (`:3900-3945`) usa parametro `CONCILIACAO` (AtivaAuto/Manual + HoraIni/Fim); `SetStatus` em `SpiCadConciliacaoStatus` (Iniciando/Processando/AguardandoDownload/ProcessandoDiferencas/Finalizado/Error); polling 2 min por arquivo e "gerar novo CAMT.060" se faltar (`:2617-2622`).
- Nosso: `config/config.exs:89` cron unico `30 3 * * *`; sem polling, sem janela configuravel, sem maquina de estado persistida, sem prompt de gerar camt.060.

### G3 [ausente, medio] Sem API/UI/disparo-manual/status para a conciliacao camt.052/053
- Legado: `ConciliacaoController.ExecutarConciliacao` (manual), `StatusConciliacao`, `listPaginaConciliacao` (grid) (`SPI.Web.Angular.Mensagens.Api.decompiled.cs:447-481,677-679`).
- Nosso: `DailyReconciliation` nao tem rota nem tela; `ReconciliationView.vue` e a conciliacao de SESSAO do settlement (`settlement_service/reconciliation.ex`), fonte diferente. Grep por rota de daily_reconciliation/run_eod = 0.

### G4 [divergencia/parcial, medio] Auto-refresh de saldo (camt.060 sob demanda quando a foto esta velha)
- Legado: `SaldoUseCase.Find` (`SPI.Core.Angular.Application.decompiled.cs:2229-2265`): sem `SaldoCAMT` nas ultimas `ATUALIZACAOSALDOHORAS` (24h), gera camt.060 automaticamente e so entao devolve o saldo.
- Nosso: refresh e ON-DEMAND por operador (`camt060_controller.ex:57`); sem cron de poll de saldo e sem auto-refresh na leitura. `balances.ex` protege staleness ao ESCREVER, mas nao solicita foto nova ao LER.

### G5 [parcial, baixo] Desdobramento do saldo por tipo de mensagem (Parciais)
- Legado: `SPI_SPSELSALDO` devolve `Parciais` = JSON por `(CdMsg, FlDebitoCredito)` com VlrPrevisto/VlrConfirmado, alem de VlrSaldoAnterior/Previsto/Confirmado.
- Nosso: `get_projected_balance`/`get_balance_summary`/`list_all_positions` (`balances.ex:551-660`) expoem available/blocked/projected/confirmed/pending_credits/pending_debits e snapshots opening/closing, porem NAO ha desdobramento previsto/confirmado por CdMsg. Grep por parciais/by_msg/breakdown em balances/statements = 0.

### G6 [parcial, baixo] Distincao de tipo de relatorio camt.052 REL x TIR
- Legado: v11 gateia pelo JsonInput `"TipoRelatorio":"REL"` (`Handlers.CAMT052/v11.cs`, `:5751-5760`): so REL vira extrato de conciliacao (`FlConciliacao="S"`); TIR vai para outro subdiretorio.
- Nosso: `process_account_report` baixa e persiste TODO camt.052 como `source: "bacen_file"` (`statements.ex:539`), sem gatilho por tipo de relatorio; a `DailyReconciliation` usa todos como via (b).

### G7 [info] Saldo de reserva SPB (SaldoSpb) fora do escopo camt.052/053 PIX
- Legado: `SpiSaldoSpb` + `SaldoSPBController` (`SPI.Web.Angular.Saldos.Api.decompiled.cs:909-964`). Dominio SPB, nao PIX camt.052/053. Registrado so para completude; nao e gap desta auditoria.

---

## 5. COBERTOS relevantes (confianca)

- C1 [coberto] Parse camt.053 SADP/SABK: `camt053_parser.ex:71-72` + `inbound_processor.ex:2653-2673` (apply_bacen_position). Mais completo que o legado (v12 so SADP/SABK) e sem o bug de sinal do legado (`:5707`).
- C2 [coberto] Credito de remuneracao REMN (Stmt/Id 32 zeros): `inbound_processor.ex:2690-2744` com idempotencia `REMN-<msg_id>`, referenciando explicitamente `CAMT053/v12.cs:30-39` e `SaldoCAMTRepository.cs:67-71`. Legado credita via `FlDebitoCredito=2`; nos com dedup.
- C3 [coberto] Parse camt.052 (aviso de arquivo): `inbound_processor.ex:2919-2938` (report_id/msg_id/account_ispb/entry_count NbOfNtries/report_ref AddtlRptInf) = 1:1 com v11.
- C4 [coberto] Download + parse do extrato + persistencia: `statement_report_downloader.ex:42` (mTLS+SHA-256+unzip), `statement_file.ex:129-135` (17 colunas identicas ao RegistroCAMT052Map), `statements.ex:513-568` (persist idempotente source="bacen_file"). FAIL-LOUD sem URL (paridade com a excecao do v11).
- C5 [coberto] Correlacao camt.060 -> camt.052/053 por MsgId ecoado: `inbound_processor.ex:2786` + `camt060_requests.ex:99-153`.
- C6 [coberto/melhoria] Protecao de staleness da posicao (foto velha nao apaga movimento vivo): `balances.ex:883-935`; sem equivalente no legado (SPI_SPSELSALDO simplesmente ancora na foto mais recente).
- C7 [coberto] Conciliacao 3 vias com deteccao de divergencia por E2E + deltas + persistencia diaria: `daily_reconciliation.ex:147-229`.
- C8 [coberto] Snapshot EOD opening/closing por data: `daily_reconciliation.ex:111-138` + schema `balance_snapshot.ex:26-31`; paridade conceitual com SpiSaldo (abertura/fechamento).
- C9 [coberto] Traducao de camt.052/053 para exibicao: catalogo de mensagens (message_builder/message_parser em shared/bacen/iso20022) espelha `TraduzCAMT052/053` (`:797-842`).
- C10 [coberto] Telas de saldo/extrato/parametros de requisicao: `views/balance/*`, `views/statements/*`, `views/camt060/*`, `views/reports/BalanceReportView.vue` cobrem Dashboard/ReqSaldo/padraoSaldos/CAMT do legado.
- C11 [extra] Geracao local de camt.052/053 (issuer): `statements.ex:45-107,131-`; recurso a mais, inexistente no legado.

---

## 6. Resumo executivo

O nucleo de PARSE e USO de camt.052 (aviso+download+extrato) e camt.053 (saldo SADP/SABK/REMN + EOD OPBD/CLBD) esta COBERTO e em varios pontos MAIS correto/completo que o legado (parser de saldo mais rico, sinal SABK correto, idempotencia da remuneracao, protecao de staleness, 17 colunas identicas do RELACAO_LANCAMENTOS, fail-loud sem URL). As divergencias de peso sao operacionais/de fluxo, nao de mensageria:

1. G1: a conciliacao do legado REPARA (muta status, cria operacao faltante); a nossa so DETECTA/ALERTA.
2. G2/G3: o legado tem conciliacao continua com janela, maquina de estado e UI/disparo manual/grid; a nossa e um cron diario sem tela nem disparo manual.
3. G4: o legado auto-solicita saldo (camt.060) quando a foto esta velha na leitura; nos so por acao de operador.

Nenhuma dessas divergencias e defeito de parse/valores; sao lacunas de automacao de conciliacao/atualizacao de saldo. G5/G6 sao detalhes de apresentacao/gating de baixo risco. G7 (SaldoSpb) e SPB, fora do escopo.
