add arcodange-bank-reco — Qonto + Wise reconciliation against Dolibarr #6

Merged
arcodange merged 1 commits from claude/arcodange-bank-reco into main 2026-05-31 13:58:07 +02:00
Owner

Summary

V6 — first cross-system skill (arcodange-* namespace, not dolibarr-*). Closes the loop between what Dolibarr says happened and what the bank actually saw.

What ships

.claude/skills/arcodange-bank-reco/:

  • bank-curl.sh — unified read-only wrapper for Qonto + Wise. SCA-aware (Wise RSA challenge) even though we don't ultimately need it — see below.
  • bank-probe.sh — auth + discovery (org slug, profile id, balance ids).
  • qonto-transactions.sh — Qonto transaction lister with --since/--until/--month/--account/--side + pagination.
  • wise-transactions.sh — Wise activity lister via /v1/profiles/{pid}/activities with --enrich to pull wire references.
  • bank-match.sh — the headline: 3-bucket reconciliation (matched / bank-only / dolibarr-only) with internal Wise↔Qonto consolidation detection.
  • bank-balance.sh — live balances per account + Dolibarr cumulative-by-fk_account cross-check.

bin/arcodange bank {probe,qonto-transactions,wise-transactions,match,balance,curl} — full CLI integration.

dolibarr/README.md — env schema extended with QONTO_*, WISE_* vars.
dolibarr/SKILL.md — Pointers section gains the cross-link.

Two rabbit holes we explored so the next operator doesn't

  1. Wise SCA flow — implemented end-to-end (RSA keypair, public key upload, signature dance in bank-curl.sh). Still returns 403 on the EU statement endpoint regardless of signature. Wise docs explicitly state: "Funding transfers and retrieving balance statements via API are not supported except for accounts based in the US, Canada, Australia, New Zealand, Singapore, and Malaysia." The SCA code is kept in case Wise opens it later; not currently used.

  2. Qonto → Wise routing — the Qonto↔Wise UI integration does NOT expose Wise data via Qonto's API. We confirmed: no /v2/external_accounts, /v2/aggregated_accounts, /v2/connected_accounts. The two banks remain separately queried.

The unblock: GET /v1/profiles/{pid}/activities returns ALL movements (incoming + outgoing) in a unified HTML-tagged feed without SCA. wise-transactions.sh parses out the HTML and produces a clean table.

Live findings from the V1 baseline (cohort review action items)

Captured in examples/bank-match-2026-01-to-05.txt:

  • Wise +2147 EUR Kissmetrics on 2026-05-29 NOT YET in Dolibarr — payment received, needs to be entered.
  • Qonto bank-only expenses missing supplier invoices: MISTRAL.AI 172.68 €, CLAUDE.AI 180 €, URSSAF 493 €, +1000 € FOUREZ Quentin (income source to clarify).
  • 6 movements matched cleanly Jan-May 2026 (KM payments + Darnis + Wise plan fee).
  • Wise→Qonto 5000 EUR consolidation 2026-03-13 auto-detected as internal transfer, excluded from matching.
  • Live balances: Qonto 4 191.54 + Wise 5 308.25 = 9 499.79 EUR.
  • Date drift observed: FAC002 5100€ paid 2026-03-06 on Wise but Dolibarr says 2026-03-12 (Δ+6d) — saisie lag.

V7 candidates (out of scope here)

  • Reference-based matching using the --enrich wire refs (FOR INVOICE FAC*** → strong match)
  • Multi-row Dolibarr sub-payment aggregation before matching
  • Smarter avoir cycle handling (net AVC+FAC before matching)
  • CSV fallback if any API goes away

Test plan

  • bin/arcodange bank probe → both banks [OK] auth succeeded, prints discovered IDs
  • bin/arcodange bank qonto-transactions --since 2026-01-01 --until 2026-05-31 → 9 transactions, net +4191.54
  • bin/arcodange bank wise-transactions --since 2026-01-01 --until 2026-05-31 --enrich → 10 activities, net +5308.25, wire refs annotated
  • bin/arcodange bank match --since 2026-01-01 --until 2026-05-31 → exit 1 with 6 matched / 1 internal / 8 bank-only / 9 dolibarr-only
  • bin/arcodange bank balance → live + cross-check table
  • git diff --cached | grep -F <qonto-secret> empty
  • git diff --cached | grep -F <wise-token> empty
## Summary V6 — first **cross-system** skill (`arcodange-*` namespace, not `dolibarr-*`). Closes the loop between what Dolibarr says happened and what the bank actually saw. ### What ships `.claude/skills/arcodange-bank-reco/`: - **`bank-curl.sh`** — unified read-only wrapper for Qonto + Wise. SCA-aware (Wise RSA challenge) even though we don't ultimately need it — see below. - **`bank-probe.sh`** — auth + discovery (org slug, profile id, balance ids). - **`qonto-transactions.sh`** — Qonto transaction lister with `--since/--until/--month/--account/--side` + pagination. - **`wise-transactions.sh`** — Wise activity lister via `/v1/profiles/{pid}/activities` with `--enrich` to pull wire references. - **`bank-match.sh`** — the headline: 3-bucket reconciliation (matched / bank-only / dolibarr-only) with internal Wise↔Qonto consolidation detection. - **`bank-balance.sh`** — live balances per account + Dolibarr cumulative-by-`fk_account` cross-check. `bin/arcodange bank {probe,qonto-transactions,wise-transactions,match,balance,curl}` — full CLI integration. `dolibarr/README.md` — env schema extended with `QONTO_*`, `WISE_*` vars. `dolibarr/SKILL.md` — Pointers section gains the cross-link. ### Two rabbit holes we explored so the next operator doesn't 1. **Wise SCA flow** — implemented end-to-end (RSA keypair, public key upload, signature dance in `bank-curl.sh`). Still returns 403 on the EU statement endpoint regardless of signature. Wise docs explicitly state: *"Funding transfers and retrieving balance statements via API are not supported except for accounts based in the US, Canada, Australia, New Zealand, Singapore, and Malaysia."* The SCA code is kept in case Wise opens it later; not currently used. 2. **Qonto → Wise routing** — the Qonto↔Wise UI integration does NOT expose Wise data via Qonto's API. We confirmed: no `/v2/external_accounts`, `/v2/aggregated_accounts`, `/v2/connected_accounts`. The two banks remain separately queried. **The unblock:** `GET /v1/profiles/{pid}/activities` returns ALL movements (incoming + outgoing) in a unified HTML-tagged feed without SCA. `wise-transactions.sh` parses out the HTML and produces a clean table. ### Live findings from the V1 baseline (cohort review action items) Captured in `examples/bank-match-2026-01-to-05.txt`: - **Wise +2147 EUR Kissmetrics on 2026-05-29 NOT YET in Dolibarr** — payment received, needs to be entered. - **Qonto bank-only expenses missing supplier invoices**: MISTRAL.AI 172.68 €, CLAUDE.AI 180 €, URSSAF 493 €, +1000 € FOUREZ Quentin (income source to clarify). - **6 movements matched cleanly** Jan-May 2026 (KM payments + Darnis + Wise plan fee). - **Wise→Qonto 5000 EUR consolidation 2026-03-13** auto-detected as internal transfer, excluded from matching. - **Live balances**: Qonto 4 191.54 + Wise 5 308.25 = **9 499.79 EUR**. - Date drift observed: FAC002 5100€ paid 2026-03-06 on Wise but Dolibarr says 2026-03-12 (Δ+6d) — saisie lag. ### V7 candidates (out of scope here) - Reference-based matching using the `--enrich` wire refs (`FOR INVOICE FAC***` → strong match) - Multi-row Dolibarr sub-payment aggregation before matching - Smarter avoir cycle handling (net AVC+FAC before matching) - CSV fallback if any API goes away ## Test plan - [ ] `bin/arcodange bank probe` → both banks `[OK] auth succeeded`, prints discovered IDs - [ ] `bin/arcodange bank qonto-transactions --since 2026-01-01 --until 2026-05-31` → 9 transactions, net +4191.54 - [ ] `bin/arcodange bank wise-transactions --since 2026-01-01 --until 2026-05-31 --enrich` → 10 activities, net +5308.25, wire refs annotated - [ ] `bin/arcodange bank match --since 2026-01-01 --until 2026-05-31` → exit 1 with 6 matched / 1 internal / 8 bank-only / 9 dolibarr-only - [ ] `bin/arcodange bank balance` → live + cross-check table - [ ] `git diff --cached | grep -F <qonto-secret>` empty - [ ] `git diff --cached | grep -F <wise-token>` empty
arcodange added 1 commit 2026-05-31 13:57:59 +02:00
V6 — the first cross-system skill (under arcodange-* not dolibarr-*).
Closes the loop between what Dolibarr says (ERP-internal) and what the
bank actually saw.

What ships:
- arcodange-bank-reco/scripts/bank-curl.sh        unified read-only wrapper for Qonto + Wise
- arcodange-bank-reco/scripts/bank-probe.sh       auth + discovery (org slug, profile id, balances)
- arcodange-bank-reco/scripts/qonto-transactions  Qonto txn lister with pagination + filters
- arcodange-bank-reco/scripts/wise-transactions   Wise activity lister with --enrich for wire refs
- arcodange-bank-reco/scripts/bank-match.sh       3-bucket reconciliation (matched/bank-only/dol-only)
                                                  with internal Wise↔Qonto consolidation detection
- arcodange-bank-reco/scripts/bank-balance.sh     live balances + Dolibarr cumulative-by-fk_account

The headline bank-curl.sh is SCA-aware (Wise RSA dance) even though we
don't end up using it: the EU statement endpoint is region-blocked
("Funding transfers and retrieving balance statements via API are not
supported except for accounts based in the US, Canada, Australia, New
Zealand, Singapore, and Malaysia" per Wise docs). The wrapper supports
SCA so when/if Wise opens it, we're ready.

The pivot that unblocked Wise incoming: /v1/profiles/{pid}/activities
(documented at https://docs.wise.com/api-reference/activity/activitylist.md)
returns ALL movements in a unified HTML-tagged feed, no SCA required.
Parsing strips the HTML and recovers structured amount/sign/currency.

CLI integration:
- bin/arcodange bank {probe,qonto-transactions,wise-transactions,match,balance,curl}
- dolibarr/SKILL.md catalogue + Pointers updated
- dolibarr/README.md env schema extended with QONTO_*, WISE_*

Live baseline findings to raise with the cohort review (captured in
examples/bank-match-2026-01-to-05.txt):
- Wise 2026-05-29 +2147 EUR Kissmetrics NOT YET in Dolibarr
- Qonto bank-only: MISTRAL.AI 172.68, CLAUDE.AI 180, URSSAF 493, FOUREZ +1000
- 6 movements matched cleanly across Jan-May 2026
- Wise→Qonto 5000 EUR consolidation on 2026-03-13 auto-detected as internal
- Live balance: Qonto 4191.54 + Wise 5308.25 = 9499.79 EUR

V7 candidates noted in SKILL.md out-of-scope: reference-based matching
via the Wise --enrich wire refs (FOR INVOICE FAC***), multi-row Dolibarr
sub-payment aggregation, smarter avoir cycle handling.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
arcodange merged commit f398003eae into main 2026-05-31 13:58:07 +02:00
arcodange deleted branch claude/arcodange-bank-reco 2026-05-31 13:58:08 +02:00
Sign in to join this conversation.
No Reviewers
No Label
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: arcodange-org/erp#6