Money trace service — fund origin trees and bank mail ingestion
Go to file
Kavi dd8931c04c Side exercise: DTE factura <-> payment reconciliation view
- scripts/build_reconciliation.py: normalizes the existing SII-RCV cross-
  reference CSV (Muralla/Murallita, 519 DTEs) into web/reconciliation.json
  with per-status / per-company / per-payer summaries.
- web/reconciliation.html: standalone reconciliation view in the money-trace
  aesthetic — KPIs (facturado, asignado, pendiente, IVA), breakdown bars,
  and a searchable/sortable table of every factura with its linked payment,
  who paid, source of funds, and confidence. Reuses logos.js for providers.
- dashboard.html: header link to the reconciliation view.

State: $15.6M facturado · 168 asignado ($6.1M) · 315 pendiente ($9.2M).
2026-06-02 18:08:24 -04:00
config chore: restore kua-money-trace from Bruno (source was on Bruno, Gal copy was lost) 2026-05-01 03:00:31 -04:00
data chore: restore kua-money-trace from Bruno (source was on Bruno, Gal copy was lost) 2026-05-01 03:00:31 -04:00
docs chore: restore kua-money-trace from Bruno (source was on Bruno, Gal copy was lost) 2026-05-01 03:00:31 -04:00
parsers Fix BancoEstado parser for wrapped-header CuentaRUT layout 2026-06-02 14:23:44 -04:00
scripts Side exercise: DTE factura <-> payment reconciliation view 2026-06-02 18:08:24 -04:00
src Add dashboard.html and static file serving to server 2026-06-01 22:38:51 -04:00
test chore: restore kua-money-trace from Bruno (source was on Bruno, Gal copy was lost) 2026-05-01 03:00:31 -04:00
web Side exercise: DTE factura <-> payment reconciliation view 2026-06-02 18:08:24 -04:00
.gitignore Add 2019-2024 backfill ledger (separate) + ?ledger= dashboard param 2026-06-02 07:32:21 -04:00
.kua-vault.json chore: restore kua-money-trace from Bruno (source was on Bruno, Gal copy was lost) 2026-05-01 03:00:31 -04:00
README.md chore: restore kua-money-trace from Bruno (source was on Bruno, Gal copy was lost) 2026-05-01 03:00:31 -04:00
debug-labels.js chore: restore kua-money-trace from Bruno (source was on Bruno, Gal copy was lost) 2026-05-01 03:00:31 -04:00
kua.json chore: restore kua-money-trace from Bruno (source was on Bruno, Gal copy was lost) 2026-05-01 03:00:31 -04:00
list-labels.js chore: restore kua-money-trace from Bruno (source was on Bruno, Gal copy was lost) 2026-05-01 03:00:31 -04:00
package-lock.json chore: restore kua-money-trace from Bruno (source was on Bruno, Gal copy was lost) 2026-05-01 03:00:31 -04:00
package.json chore: restore kua-money-trace from Bruno (source was on Bruno, Gal copy was lost) 2026-05-01 03:00:31 -04:00
schema.sql chore: restore kua-money-trace from Bruno (source was on Bruno, Gal copy was lost) 2026-05-01 03:00:31 -04:00

README.md

kua-money-trace

Servicio separado para reconstruir el arbol de origen y destino del dinero.

No reemplaza contabilidad ni aprobacion humana. Guarda hechos, propone enlaces y permite ver de donde vino la plata que termino financiando cada gasto.

Primer MVP

  • Ledger en JSON local.
  • Motor de grafo con enlaces explicitos y enlaces FIFO por cuenta.
  • Trazabilidad hacia atras desde cualquier movimiento, documento o evento economico.
  • API HTTP minima sin dependencias externas.
  • CLI para resumen y pruebas rapidas.

Ejecutar

npm test
npm run summarize
npm run demo
npm run serve

Luego:

curl http://localhost:3910/health
curl http://localhost:3910/nodes/event:black-spa-10804/origin-tree

Descargar correos

Primera cuenta configurada:

vjoati-gmail -> vjoati@gmail.com
kdoi-email -> kdoi@email.com

La clave no se guarda en el repo. Para Gmail se debe usar una app password/OAuth y exponerla solo en el entorno:

export VJOATI_GMAIL_APP_PASSWORD='...'
npm run mail:dry-run
npm run mail:download -- --limit 25 --since 2025-01-01

Gmail API OAuth

El camino recomendado para Gmail es OAuth con permiso solo lectura. Necesita un OAuth Client de Google Cloud con redirect URI http://127.0.0.1:3912/oauth2callback y la Gmail API habilitada.

export GOOGLE_OAUTH_CLIENT_ID='...apps.googleusercontent.com'
export GOOGLE_OAUTH_CLIENT_SECRET='...'
npm run mail:gmail-oauth

El comando imprime una URL, espera el callback local y guarda el refresh token en:

data/mail-oauth/vjoati-gmail.token.json

Luego descarga desde Google, no desde Apple Mail:

npm run mail:gmail-download -- --limit 100 --since 2025-01-01

El archivo queda en:

data/mail-archive/vjoati-gmail/
  raw-eml/yyyy/mm/*.eml
  attachments/yyyy/mm/*
  manifests/emails.ndjson

Para probar sin tocar Gmail:

npm run mail:fixture

Si Gmail no permite app password, hay dos caminos ya soportados:

Apple Mail local

Lista cuentas/carpetas locales de Mail.app:

npm run mail:list-apple

Importa una carpeta .mbox local de Apple Mail:

node src/mailCli.js import-apple-mail \
  --account vjoati-gmail \
  --source '/Users/kavi/Library/Mail/V10/.../INBOX.mbox' \
  --limit 25

Para cuentas ya configuradas en macOS, es mejor usar el indice de Mail. Esto resuelve la cuenta desde ~/Library/Accounts/Accounts4.sqlite, lee Envelope Index, y archiva los .emlx locales por id de mensaje:

node src/mailCli.js import-apple-mail-index \
  --account vjoati-gmail \
  --mailbox all \
  --since 2025-01-01 \
  --limit 100

En Gmail, --mailbox all usa [Gmail]/Todos cuando existe y si no cae a INBOX. Para la cuenta kdoi-email, el importador detecta la IMAP directa con mensajes y usa INBOX.

Atajos:

npm run mail:import-apple-index -- --limit 100 --since 2025-01-01
npm run mail:import-kdoi -- --limit 100 --since 2025-01-01

Google Takeout / MBOX

Exporta Gmail desde Google Takeout como archivo .mbox, luego:

node src/mailCli.js import-mbox \
  --account vjoati-gmail \
  --file '/ruta/al/archivo.mbox' \
  --limit 1000

Idea central

Un pago con tarjeta no es el origen final. El arbol correcto puede ser:

DTE / gasto Muralla
└─ cargo Visa Darwin
   └─ pago Visa desde cuenta corriente Darwin
      └─ ingreso puro Darwin

Y para cuentas europeas:

Gasto con debito Revolut
└─ saldo Revolut EUR
   └─ carga Revolut con Visa Chile
      └─ pago Visa desde cuenta corriente Chile
         └─ ingreso puro

Proximos pasos

  • Importadores para cartolas Banco de Chile, Santander, Revolut, Mercado Pago y SII RCV.
  • Archivo de correos y adjuntos en Storagebox.
  • Extraccion IA de PDFs/correos con estado propuesto, nunca aprobado automaticamente.
  • Persistencia Postgres con auditoria de decisiones.