feat(bank): chequera register module (plan step 7)
Adds the office's own bank-register browser over the migrated SCOTHIA
data (22,354 bank_transactions), the last self-contained feature module.
API (apps/api/src/bank):
- GET /bank register browser: search over concepto/reference/notes/
amountInWords; direction (income|expense|void), cleared and
date-range filters; 5 sorts; income/expense/net totals for
the whole filtered set, not just the page
- GET /bank/stats headline income/expense/net + counts, date span, pending
- GET /bank/facets year list for the period filter
- GET /bank/summary year and month rollups with a running net-movement figure
Web (/banco): "Movimientos" register + "Resumen por periodo" with year->month
drill-down; added to the AppShell nav as "Chequera".
Deliberately kept OUT of /estado-cuenta: this is the office's own money, not
customer balances, and the two are never summed or shown together.
No category/ramo dimension, and the deferred concept->ramo classifier is
dropped as won't-build: concepto is a payee name (0 of 22,354 match a
category) and TABLA RAMODOS is an expense chart of accounts + owner names,
not the insurance/servicios/fideicomiso split it was assumed to be, so a
classifier would invent data. Single currency (MXN); the "acumulado" is net
movement since the register opened (no opening balance in the source), not a
bank balance. Verified end-to-end in the browser; totals reconcile.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -153,9 +153,12 @@ the reconciliation pass (done, then corrected) are all closed. See §3 and §8.
|
||||
3. **Old external-DB credential** — the old repo's `dbConnection.php` has a hardcoded
|
||||
plaintext MySQL password committed to git history. Not carried into the new platform,
|
||||
but rotate it regardless; it is already exposed.
|
||||
4. **`bank_transactions.categoryId` is null on all 22354 rows** — the concept→ramo
|
||||
classifier was deferred. Needed before any "insurance vs utilities vs trust" split of
|
||||
the office's own bank activity.
|
||||
4. **`bank_transactions.categoryId` is null on all 22354 rows — RESOLVED as won't-build**
|
||||
(plan step 7). The concept→ramo classifier was investigated and dropped: `concepto` is a
|
||||
payee name (0 of 22354 match a category), and TABLA RAMODOS is a property-management
|
||||
expense chart of accounts + owner names, not the insurance/servicios/fideicomiso split it
|
||||
was assumed to be — so a classifier would invent data rather than produce a business-line
|
||||
view. The `/banco` module intentionally has no category dimension. See §8 step 7(b).
|
||||
5. **`TRASPASOS PAYPAL` is a clearing account, not a customer** — carries -7.03M MXN over
|
||||
309 movements and therefore tops the adeudo worklist. Deliberately not special-cased in
|
||||
code; needs a business decision on how to model it.
|
||||
@@ -321,6 +324,40 @@ for what's actually next.
|
||||
(d) The biggest debtor by far is **"TRASPASOS PAYPAL"** (-7.03M MXN over 309 movements) —
|
||||
a house/clearing account, not a person. Left in rather than special-cased, but it will
|
||||
head the adeudo worklist until someone decides how to model it.
|
||||
- **Bank register module (plan step 7) — DONE**: `apps/api/src/bank/`
|
||||
(`GET /bank` register browser with search over concepto/beneficiario, cheque
|
||||
`reference`, `notes` and `amountInWords`; filters for direction
|
||||
(income|expense|void), cleared status and a from/to date range, 5 sorts, and
|
||||
**income/expense/net totals for the whole filtered set**; `/bank/stats`,
|
||||
`/bank/facets` (year list), `/bank/summary` year/month rollup with a running
|
||||
net figure) + web `/banco` (two tabs: "Movimientos" register and "Resumen por
|
||||
periodo" with clickable year→month drill-down). Added to the AppShell nav as
|
||||
"Chequera". Verified end-to-end in the browser: totals reconcile
|
||||
(6948 income + 14615 expense + 791 void = 22354; net +899,375.77 matches
|
||||
stats; 2013 months open at $0 and close at the year's net $794,295.78).
|
||||
**Design decisions / data findings:**
|
||||
(a) **Kept separate from `/estado-cuenta` on purpose** — this is the office's
|
||||
own chequera, not customer money; the two ledgers are never summed or shown
|
||||
together. Distinct nav entry, distinct page, distinct API module.
|
||||
(b) **No category/ramo dimension, and the concept→ramo classifier was NOT
|
||||
built** (closes open item §6.4): the data cannot support it. `DATOS E/I` have
|
||||
no ramo column to migrate; `concepto` is a *payee* name (PAYPAL, CFE, ~1,900
|
||||
individuals), and 0 of 22354 concepts match a `business_line_categories` name;
|
||||
and the 66 TABLA RAMODOS rows are a property-management expense chart of
|
||||
accounts (Payroll, Pool Labor, Gardening) + owner names, *not* the
|
||||
insurance/servicios/fideicomiso split the migration comment implied. A
|
||||
classifier would invent data, so `categoryId` stays null and the module does
|
||||
not filter on it. Register is browsable by date/payee/amount/cheque instead.
|
||||
(c) **Single currency (MXN).** `bank_transactions` has no currency column and
|
||||
every `amountInWords` is spelled out in PESOS — so, unlike the customer
|
||||
ledger, everything here is one currency and not split per-currency.
|
||||
(d) **The "acumulado" is net movement since the register opened, not a bank
|
||||
balance** — SCOTHIA carries no opening balance (its `ban` table holds only the
|
||||
bank's name), so the running total starts at 0 in 2013. Labelled as such in
|
||||
the UI so it is never read as a statement balance.
|
||||
(e) Sign convention (from `transform_bank.py`): positive = ingreso,
|
||||
negative = egreso, exactly zero = a cancelled/void cheque (787 of 791 say
|
||||
CANCELADO/VOID) — voids are excluded from both the income and expense sides.
|
||||
- Full pipeline reproducible in one command: `run_all.py --env <env>` runs customers →
|
||||
properties → policies → transactions → prune → bank → blobs in order (all idempotent);
|
||||
add `--stage` to re-extract from the Access files first. Verified end-to-end against dev.
|
||||
@@ -331,21 +368,18 @@ for what's actually next.
|
||||
`deploy/jorgecuadros-db.stack.yml` deploys prod from the same file as
|
||||
`jorgecuadros-prod-db` on :3306. MinIO for documents deployed as `jorgecuadros-dev-minio`.
|
||||
|
||||
6. **Staff web UI** — **DONE** for all four modules (§8 step 4: clientes, polizas, servicios,
|
||||
estado-cuenta). Spanish-first, session-cookie auth against the API, verified against real
|
||||
migrated data.
|
||||
6. **Staff web UI** — **DONE** for all five modules (§8 step 4 + step 7: clientes, polizas,
|
||||
servicios, estado-cuenta, banco). Spanish-first, session-cookie auth against the API,
|
||||
verified against real migrated data. **All app-layer feature work is complete.**
|
||||
|
||||
---
|
||||
|
||||
⏭ **NEXT — where to pick up:**
|
||||
|
||||
- **Plan step 7: bank register module.** SCOTHIA data is already migrated (22354
|
||||
`bank_transactions` + 66 `business_line_categories`) and has **no customer FK**, so it is
|
||||
self-contained and low-risk — API + `/banco` browser only. Blocked on nothing.
|
||||
Ties into open item §6.4 (`categoryId` is null on every row).
|
||||
- **Plan step 8–9: VPS + sync worker.** Blocked on VPS provisioning (§6.1) — the only real
|
||||
external dependency left.
|
||||
external dependency left. Pure ops: provider, size, Tailscale, MySQL replica.
|
||||
- **Plan step 10: reports / email campaigns / admin.**
|
||||
- **Uncommitted work:** the billing module and the ledger de-dup fix are written, built and
|
||||
verified but **not committed** — `git status` is dirty at the time of writing. The browser
|
||||
visual pass on `/estado-cuenta` was also never completed (it needs an interactive login).
|
||||
- **Small / open:** (a) `TRASPASOS PAYPAL` clearing account still tops the adeudo worklist
|
||||
(§6.4d) — a business modelling call, not code. (b) Credential rotation on the old repo's
|
||||
exposed MySQL password. (c) The `/estado-cuenta` browser visual pass — `/banco` was verified
|
||||
in-browser this session; `/estado-cuenta` still worth a look.
|
||||
|
||||
Reference in New Issue
Block a user