# Handoff — Core/ETL deep fix + re-migração + padronização centavos (2026-06-26)

Fonte de verdade para CONTINUAR de onde paramos. Sessão profunda no Core (dono cético, mandato "ache nosso defeito, prove empírico, zero inferência"). Tudo abaixo está **vivo em AWS homolog** e/ou commitado na branch local.

---

## 0. Ambiente e acessos (copiar)

- AWS: conta **990933657879**, região **sa-east-1**, profile **vulcimonetarie**. Wrapper:
  ```bash
  awsmon() { env -u AWS_ACCESS_KEY_ID -u AWS_SECRET_ACCESS_KEY -u AWS_SESSION_TOKEN AWS_PROFILE=vulcimonetarie AWS_REGION=sa-east-1 aws "$@"; }
  ```
- Cluster ECS `monetarie-greenfield-homolog`. Aurora `monetarie-core-homolog-45` (DB `mon_core`). VPN ativa → `coreadmin-h.monetarie.internal` (admin SPA) responde.
- **Acesso ao DB vivo = ECS exec na task core-api** (a task alcança Aurora + TB). Dentro do container: `psql` em `/usr/bin/psql`, release em `/app/bin/monetarie`, env `DATABASE_URL`(=mon_core, scheme `ecto://` → trocar p/ `postgresql://`), `DICT_SOURCE_DATABASE_URL`(=mon_pix). Padrão que funciona (evita inferno de aspas): base64 do script + `sh`:
  ```bash
  TASK=$(awsmon ecs list-tasks --cluster monetarie-greenfield-homolog --service-name core-api --query "taskArns[0]" --output text | sed 's#.*/##')
  B64=$(base64 < script.sh | tr -d '\n')
  awsmon ecs execute-command --cluster monetarie-greenfield-homolog --task "$TASK" --container core-api --interactive --command "/bin/sh -c \"echo $B64 | base64 -d | sh\""
  ```
  - Dentro do script: `PGURL=$(printf '%s' "$DATABASE_URL" | sed 's#^ecto://#postgresql://#')`. Em `rpc`, NÃO use aspas simples no SQL (quebra) — todos os account_entries têm `status='confirmed'`, então pode dropar o filtro; ou use `<<39>>`.
- Login admin via API: `POST http://coreadmin-h.monetarie.internal/api/admin/auth/login` `{email:admin@monetarie.com.br, password:<secret>}`, senha em `monetarie/homolog/admin/core/initial_password`. JWT claim `entity_id=61d67833-4580-4d6e-a1ce-63fb851fb5cf` (a ÚNICA entidade; todos os dados são dela).
- Screenshots: Playwright em `core/node_modules/@playwright/test`. Login core: `#email` + `input[type="password"]` + `button[type="submit"]`. Senha via env `CORE_PASSWORD` (não logar).

## 1. Estado do git

- Branch de trabalho: **`fix/core-etl-visibility`** (off `9e98a0aa`, **NÃO pushada**). Commits: `c93a59f7` (dashboard+clientes), `ce29e56c` (account-detail+snapshot), `780b0a1d` (100x class), `41fa13e6` (account_controller centavos), + docs (`541cb2c6`, planos, relatórios).
- `origin/main` = `75ca3376` (tem o ETL `core/backend/lib/monetarie/etl/autbank/*` — a branch de trabalho NÃO tem).
- A working tree pode estar nessa branch; se a OUTRA sessão (PIX) precisar de `main`, dar `git checkout main` (a alteração de `pix/.../bacen/client.ex` é da outra sessão, preservar).

## 2. Deploy (mecanismo)

Manual, ARM64, sem GHA: `docker buildx build --platform linux/arm64 -f <Dockerfile> -t 990933657879.dkr.ecr.sa-east-1.amazonaws.com/monetarie/<repo>:homolog-<sha> --push <ctx>` → `awsmon ecs describe-task-definition` (strip campos) → `register-task-definition` (nova rev) → `update-service`. Contextos: core-api `core/backend`, admin-ui `core` (`-f core/apps/admin/Dockerfile`). ECR login: `awsmon ecr get-login-password | docker login --username AWS --password-stdin 990933657879.dkr.ecr.sa-east-1.amazonaws.com`.
- **Vivo agora:** core-api task-def **:35** (`homolog-780b0a1d`); core-admin-ui **:9** (`homolog-c93a59f7`).

## 3. O que JÁ foi aplicado no dado vivo (NÃO refazer)

- `account_entries`: 64 linhas de **abertura** `reference='etl_opening_backfill_20260626'` (R$271.709,65). Total = 7.411.589.800 subcent = **R$741.158,98** (== TB == origem).
- `cosif_journal_entries`: **245.048 linhas `reference_type='etl_replay'`** (replay completo por tipo de evento, 2024-07..2026-05). O `etl_opening` (77) foi **DELETADO**.
- `cosif_accounts`: criadas 3 contas IOF `4.9.1.10.02.10.001/002/003` (id é **bytea**, gerado por `decode(replace(gen_random_uuid()::text,'-',''),'hex')`).
- `cosif_account_balances`: snapshots mensais 2024-07..2026-06 (gerados por `SnapshotGenerator.generate_for_date/1`; o seed sintético R$2bi de 24/06 foi purgado).
- Unidades: `account_entries.amount`=subcentavos (×10000); `cosif_journal_entries.amount`=centavos (×100); TB=subcentavos. Conversão subcent→centavos = `div(_,100)`.
- **Reversibilidade:** apagar `etl_replay`, recriar `etl_opening`, regenerar snapshot de junho. A re-migração (Track A) vai resetar tudo isso de qualquer forma.

## 4. Veredito da contabilidade (provado)

Balancete fecha mês a mês; DRE real. Posições: Disponibilidades `1.1.2.10.01.10.001` R$1.035.735,86; Obrigações `4.9.8.10.01.10.002` R$741.158,98; IOF a recolher R$81,60; Receita tarifas `7.1.7.10.01.10.001/002` R$294.445,05; Juros `7.1.1.10.01.10.213` R$50,23. **Ativo = Passivo + Resultado ao centavo.**

## 5. Mapa COSIF (do `~/Desktop/Plano_de_Contas_Interno_SCD.md`, já validado e usado)

| Lançamento | Sinal | Débito | Crédito |
|---|---|---|---|
| Pix/TED recebimento | + | `1.1.2.10.01.10.001` | `4.9.8.10.01.10.002` |
| Pix/TED pagamento | − | `4.9.8.10.01.10.002` | `1.1.2.10.01.10.001` |
| Tarifa | − | `4.9.8.10.01.10.002` | `7.1.7.10.01.10.001` (cadastro→`...002`) |
| IOF Adicional | − | `4.9.8.10.01.10.002` | `4.9.1.10.02.10.002` |
| IOF op. crédito | − | `4.9.8.10.01.10.002` | `4.9.1.10.02.10.001` |
| Juros | − | `4.9.8.10.01.10.002` | `7.1.1.10.01.10.213` |

## 6. DUAS FRENTES EM EXECUÇÃO (planos)

### Track A — ETL re-migração completa (decisão do dono: re-migrar)
Plano: `docs/plans/2026-06-26-etl-autbank-full-remigration.md`.
- Backup novo: `~/Desktop/monbank_backup_2026-06-26.sql` (pg_dump **-Fc**, 166MB). 11 tabelas; 4 novas `autbank_*`. A que importa: **`autbank_legacy_transactions` = 258.959 lançamentos** (type debit/credit, amount numeric(15,2) em REAIS, posted_at, history_code, **balance_after** = saldo corrido → reconciliação exata, sem plug). accounts 1.606 / users 1.542. As outras 3 `autbank_*` são tooling de import do Autbank (ignorar).
- Inspeção offline (sem server): `pg_restore --schema-only -t <tab> -f - <backup>` e `pg_restore --data-only -t <tab> -f - <backup>`. (`/opt/homebrew/opt/libpq/bin/pg_restore`.)
- **BLOQUEIO:** o ETL roda DENTRO da VPC (origem precisa ser alcançável pela task). Docker/OrbStack local estava DESLIGADO. Caminho AWS-only: subir o backup no **S3** → task one-off do core-api faz `pg_restore` num **DB temporário no Aurora** → `AUTBANK_SOURCE_URL` aponta pra ele. (Precisa AUTORIZAÇÃO do dono p/ subir backup do concorrente no S3/Aurora.)
- Código: ETL em `origin/main`; estender `source.ex` p/ ler `autbank_legacy_transactions`, `event_map.ex` p/ classificar por history_code, novo `loader/ledger.ex`. Reset entidade + apply + reconcile por `balance_after`.

### Track B — padronização CENTAVOS
Plano: `docs/plans/2026-06-26-money-unit-centavos-standardization.md`. Relatório dos 94 bugs: `docs/reports/2026-06-26-core-money-bug-sweep.md`.
- **Iniciado:** `account_controller.fetch_tigerbeetle_balance` → centavos (commit `41fa13e6`, NÃO deployado ainda).
- Raiz: formatters do front inconsistentes (`moneyUnit.ts` vendado nos 3 apps + shared divide ÷10000; `MoneySerializer.to_base()` ×100 no v2 pareia com ÷10000 e acerta por acaso; controllers que devolvem TB cru = 100x).
- Regra: **atômico por app** (backend+front no MESMO deploy). Sequência: admin → banking → merchant → partner. Banking/merchant: remover `to_base` (v2/account, v2/transfer, v2/merchant_portal) JUNTO de `moneyUnit ÷100`.
- Já corrigidos (centavos) em sessões anteriores: bank_accounts (dashboard_stats/balance/statement), merchants/virtual_accounts (fetch_tigerbeetle_balance), account-entries controller.

## 7. Pendências / decisões abertas
1. Track A: autorizar backup no S3 + DB temp Aurora (ou subir Docker numa EC2 da VPC). 
2. Track B: cadência (app por app agora vs sessão dedicada).
3. Capital Social = R$0 (Autbank não traz; cadastrar integralização real se houver).
4. Dashboard PIX/Boletos/MEDs/Basileia = hardcoded 0 (não implementados; não é ETL).
5. Validação tela-a-tela final + relatório pt-br humano SEM travessão (regra do dono).

## 8. Validação rápida (sanity)
- API: `POST /api/admin/auth/login` → token; `GET /api/admin/bank-accounts/dashboard-stats` (saldo R$625.861,90); `GET /api/admin/merchants?perPage=3` (1.525); `GET /api/v1/cosif/trial-balance?start_date=2026-03-01&end_date=2026-03-31` (balanceado).
- Conta exemplo: `109071-2` KAY CASS GLOBAL LTDA, saldo R$373.446,51, movimento jan/2026 (465 lançamentos).
