* fix(parties): readable suggestions from assistant-written vouchers, auto-build queue, SCB fetch after promotion
Live feedback on a real company (2026-09-03): the queue showed 35 one-off
suggestions with sentence-long names, wide empty rows, a "Hämta förslag"
step nobody could predict, no SCB fetch after promotion, and an empty
supplier created from a Finansinspektionen fee line.
- ledger_key v2 (migration 20260904002000): keep the counterpart head of
"<counterpart> · <note>" descriptions, drop bank method tokens and long
references before normalising; JS mirror in lib/parties/ledger-key.ts
with shared LEDGER_KEY_CASES. Suggested parties nobody has touched are
rebuilt under the new keys (repair in the same migration).
- apply_party_suggestions attaches by VAT number too, so ledger keys with
a VAT number but no org number reach existing roles.
- Queue: fixed name/reason column widths, inline "Hitta i
företagsregistret" for rows without an org number.
- Page: builds the queue automatically on first visit when nothing has
been suggested yet; after promotion, fetches SCB facts for every
promoted legal person (spaced under the 10 calls/10 s limit) and fills
the role's VAT number; confirm dialog says how many rows lack an org
number.
- Classifier: more authorities (Finansinspektionen, Arbetsförmedlingen,
Pensionsmyndigheten, ...) and fee words (registreringsavgift,
tillsynsavgift, ...) so fee lines stop becoming suppliers.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
* fix(parties): scope the suggestion repair to keys the new ledger_key no longer produces
Superagent flagged the repair DELETE as global. It now only removes
untouched pipeline suggestions that no posted voucher of the company maps
to under the new function; suggestions whose key is unchanged stay.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
---------
Co-authored-by: Jakob Wennberg <311770904+jakobwennberg-oss@users.noreply.github.com>
Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
Migrants arrive with vouchers, not bank transactions, so the bank-keyed
ledger context is empty for them. This adds the description-keyed twin.
- public.ledger_key(text): legibility key on top of the frozen
normalize_counterparty_key mirror: strips AP-register prefixes (levfakt,
leverantörsfaktura från N, levbet, faktura, kvitto, utgift), the supplier
number that follows them, and trailing 1-3 digit runs, never "inköp".
Mirrored by lib/parties/ledger-key.ts; the pair is pinned by a shared
fixture list in the pg test.
- public.get_observed_parties(company, from_date, limit): posted vouchers
grouped by ledger_key(description) with occurrences, variants, expense
and revenue SEK from the lines, first/last seen, median cadence and the
Laplace-smoothed dominant result account. Excludes storno, opening
balance, year-end and VAT settlement, and vouchers that carry a bank
merchant name (those stay with get_ledger_deep_context). SECURITY
INVOKER, so RLS scopes it. Never stored.
- lib/parties/classify.ts: the deterministic pre-classifier moved out of
the evaluation script so product and evaluation share one implementation
(0.965 agreement with the founder labels, party recall 0.99).
- lib/parties/observed.ts: RPC wrapper that classifies each row and
derives a display rhythm from the cadence.
Co-authored-by: Jakob Wennberg <311770904+jakobwennberg-oss@users.noreply.github.com>
Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>