Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 32 additions & 0 deletions .changeset/security-businesses-backfill.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
---
'@accounter/server': patch
---

Add `yarn backfill:security-businesses`, the one-time backfill that gives already-ingested securities
their businesses.

Ingestion now creates a business per security as executions arrive, but the history that predates it
has none, and its trades still point at the general foreign-securities business. The script closes
that gap in two idempotent steps:

1. **A business per ISIN** out of `accounter_schema.poalim_securities_transactions`, with a
`POALIM_SECURITY_KEY` identifier for every Poalim key seen reporting that ISIN — so two keys for
one instrument collapse onto one business. Sort code, IRS code, country and tax category are
inherited from the tenant's general foreign-securities business, and the currency is normalized
through `formatCurrency`, matching what `ensureSecurityBusiness` does. The three inserts a
security takes run as one transaction: a failure part-way through would otherwise leave a
business that is not a security, which the ISIN lookup would never find again and a re-run would
duplicate.
2. **Re-point the trades** whose description names exactly one key that resolves. Only transactions
currently pointing at the general foreign-securities business are touched — anything else is a
human decision the script has no business overwriting — and only non-fee rows, since the fee side
stays with the bank.

**Dry-run by default**; `--apply` writes, `--owner=<uuid>` limits the run to one tenant. The report
counts what was (or would be) created, linked and re-pointed, and names the cases it deliberately
left alone: security keys reporting no ISIN (the ISIN is the identity and cannot be invented from the
key — those are assigned by hand from the charge UI), descriptions naming more than one security, and
keys with no business behind them.

It sets `app.current_business_id` per tenant, exactly as the server does per request, so it behaves
the same whether or not the connecting role bypasses RLS.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
"node": "26.7.0"
},
"scripts": {
"backfill:security-businesses": "tsx scripts/backfill-security-businesses.ts",
"build": "yarn generate && yarn build:tools && yarn build:main",
"build:main": "yarn workspaces foreach --all --parallel --include @accounter/client --include @accounter/server --include @accounter/scraper-app --include @accounter/mcp-server --include @accounter/email-ingestion-gateway run build",
"build:tools": "yarn workspaces foreach --all --parallel --include @accounter/etana-scraper --include @accounter/etherscan-scraper --include @accounter/green-invoice-graphql --include @accounter/hashavshevet-mesh --include @accounter/israeli-vat-scraper --include @accounter/kraken-scraper --include @accounter/payper-mesh --include @accounter/pcn874-generator --include @accounter/shaam-uniform-format-generator --include @accounter/shaam6111-generator run build",
Expand Down
Loading
Loading