# Relatório diário de movimentação e saldos diários: LegadoSPB vs nosso SPB

Data: 2026-07-14. Mandato do dono: o cliente precisa do relatório diário com
movimentação de entrada, de saída, detalhes completos das transações, e dos
saldos diários por data. O LegadoSPB atendia isso e o nosso não atende hoje.

A reclamação procede. O levantamento abaixo foi feito com evidência
(binários e definições do legado, manifests de ETL, arquivo:linha do nosso
código) e mostra exatamente onde está a lacuna: o backend nosso já tem a
maior parte dos dados e endpoints; a tela de Relatórios do operador é um
STUB que não chama backend nenhum. A paridade declarada anteriormente não
valia na ponta que o cliente usa, e fica aqui corrigida com o plano de
fechamento.

## 1. O que o legado tinha (evidência extraída dos artefatos)

O LegadoSPB usa Telerik Reporting e as DEFINIÇÕES dos relatórios estão em
disco como `.trdp` (zip com definition.xml), em
`EvolutionDotNet/www-webapi/wwwroot/Reports/`. Extraídos os campos de cada
um, os que correspondem ao pedido do cliente:

- `rpt_extrato_reserva_horario.trdp` e `rpt_extrato_reserva_grp.trdp`
  (e equivalentes CIP): extrato diário com `dt_movto`, `cd_msg`,
  `nr_ctrl_externo`, `vl_oper_cr` (entrada), `vl_oper_db` (saída),
  `vl_saldo` e `vl_saldo_anterior` (SALDO CORRIDO por dia).
- `rpt_diario_geral_anali.trdp` (+ dinamico/generico): diário geral por data
  (`pDataBase`), com conta débito/crédito, evento, histórico e valor.
- `rpt_movto_msgs.trdp`: movimento de mensagens por transação com
  `dt_movto`, `cd_msg`, `ds_status`, `nr_ctrl_if`, `hr_envio`,
  `hr_confirmacao`, `vl_oper_cr`, `vl_oper_db`.
- `rpt_transf_recursos.trdp`: transferências com remetente, favorecido,
  conta, valor.
- API do legado (`EVO.Web.API.dll`, strings): `ReportsController`,
  `api/reports`, `GetSaldos`, `ConsisteSaldoReserva`, `Fechamento`.

No banco legado (manifests de ETL em `docs/reports/2026-07-01-*`): tabelas
`BALANCO_SALDO_SPI`, `MOVIMENTOS_CONTA_PI`, `SALDO_CONTA_PI`,
`EXTRATO_MOVIMENTO_GI` (13.250 linhas, natureza C/D por conta/dia) e
`MOVIMENTOS_CONTABEIS_CLIENTE_{CREDITO,DEBITO}_EXTERNO`.

## 2. O que temos hoje (arquivo:linha)

Backend (bacen_gateway), JÁ EXISTE:

- `GET /exports/movement` (+ `/preview`) (`router.ex:748`,
  `exports/movement_controller.ex:29-33`): CSV `CEC-{ispb}-{de}-{ate}.csv`
  com `dt_movto, cd_msg, ent_ext, vl_operacao, nr_ctrl_IF, ds_status,
  finldd_if, cpf_cnpj_db, cpf_cnpj_cr, ag_db, ct_db, ag_cr, ct_cr,
  dt_hr_envio, dt_hr_retorno`. É o equivalente 1:1 do `rpt_movto_msgs` com
  entrada/saída e detalhe por transação. Filtros D/C, grupo, tipos, valor.
- `GET /reports/reserve-statement` (`router.ex:188`,
  `reports_controller.ex:156-216`): extrato de reserva por transação com
  indicador D/C derivado (`sender_ispb = nosso ISPB -> D`), valor, data de
  liquidação e sumário de débitos/créditos. NÃO está ligado a tela nenhuma.
- `GET /reports/message-movement` com `?format=csv` (`router.ex:187`,
  `reports_controller.ex:80-105`): agregado por dia/categoria/direção.
- Série de SALDO DIÁRIO por data: tabela `balance_positions`
  (`20260513224500_create_runtime_dependency_tables.exs:6-21`) com
  `position_date, opening_balance, closing_balance, debit/credit_*`
  (paridade exata de `vl_saldo_anterior`/`vl_saldo`), mantida pelo
  `Liquidante.BalanceManager`, exposta em
  `GET /balances/positions/:group_id/history` (`balance_controller.ex:127`)
  e `GET /reports/balance/history` (`balance_report_controller.ex:75`,
  atenção: este devolve fluxo líquido do dia, não saldo corrido).

Frontend, ONDE ESTÁ A LACUNA:

- Relatórios do OPERADOR (`operator/views/ReportsView.vue:264-277`): STUB.
  As categorias ("Extrato Reserva", "Movimento de Mensagens", "Lançamentos
  SLB") são listas hardcoded; `generateReport()` não chama API;
  `exportCSV()`/`exportPDF()` só mostram toast. O cliente clica e não sai
  relatório nenhum.
- `AccountingReportsView.vue:286`: STUB (colunas Saldo/Balancete sem fonte).
- Relatórios do ADMIN (`admin/views/ReportsView.vue:266-349`): funcional,
  mas só auditoria/estatística de mensagens.
- `BalanceDashboardView.vue:359`: snapshot do dia via `/balances`; não há
  tela de série histórica de saldo.

## 3. Plano de fechamento (sem modelagem nova; backend ~80% pronto)

Onda 1 (fecha o pedido do cliente):
1. Ligar a tela Relatórios do operador ao backend real:
   "Movimento diário" -> `GET /exports/movement/preview` (tabela) +
   `GET /exports/movement` (CSV); "Extrato de Reserva" ->
   `GET /reports/reserve-statement` com o sumário D/C.
2. Tela "Saldos diários" (série por data): consumir
   `GET /balances/positions/:group_id/history`
   (opening/closing/debit/credit por `position_date`), com export CSV.
3. Saldo corrido no extrato de reserva: juntar `reserve_statement` com
   `balance_positions` por `position_date` (paridade
   `vl_saldo`/`vl_saldo_anterior` do legado).

Onda 2 (paridade fina):
4. Diário geral (paridade `rpt_diario_geral_*`): já existe base em
   `GET /accounting/daily-summary` (`accounting_controller.ex:119-195`,
   partidas dobradas por conta/dia); ligar a `AccountingReportsView`.
5. Validar os números contra o acervo importado (`EXTRATO_MOVIMENTO_GI`,
   `BALANCO_SALDO_SPI`) ao centavo antes de liberar ao cliente.

Nota de dados: `spb_operations` não tem coluna `direction`; o D/C do
relatório é derivado de `sender_ispb` (mesmo critério já usado em
`reports_controller.ex:169-171`). Pagador/recebedor por transação já estão
materializados (`payer_*`/`beneficiary_*`), expostos na lista de Transações
nesta data (P6).
