feat(parties): phase 1 substrate, one party per counterpart (#2162)
* feat(parties): phase 1 substrate, one party per counterpart Adds the identity layer above customers and suppliers, which keep their tables and every foreign key and gain a nullable party_id. - parties: company-scoped identity with status (suggested | confirmed), kind, alias keys, origin and merged_into. One live party per org number and company, enforced by a partial unique index; merged losers leave the index so a merge can be undone. This is the unique key the duplicate-invoice guard has lacked, since suppliers never had one. - party_facts: statements with a source, a rank (preferred | normal | deprecated) and two time axes, never overwritten. - party_identities: bankgiro, plusgiro, IBAN and friends per party, with seen and paid counts and a known | unverified status. - party_decisions: every human action on a party as a labelled example. - normalize_org_number(text): SQL mirror of lib/invariants/org-number.ts (strip separators, drop the century on 12 digits, Luhn check, 10 digits). - ensure_party(): find by org number inside the company, else create. Name-only rows never merge at insert time; a name merge is a recorded human decision. - Backfill: one party per existing supplier and customer, merged on org number, suppliers first so both roles land on one party. - Archive contract: the four tables are master data in the full archive. Observed parties (keys derived from voucher and bank text) are not stored; they stay computed by the ledger-context RPC. No posted entry is touched. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * fix(parties): tenant-safe composite foreign keys on every party link Facts, identities, decisions, customers.party_id, suppliers.party_id and parties.merged_into now reference parties(id, company_id), so a row can only point at a party in its own company. ON DELETE SET NULL names party_id so role rows keep their company_id. Adds a pg-real test that rejects every cross-company link and checks company_id survives a party delete. 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>
This commit is contained in:
co-authored by
Claude Fable 5.1
Jakob Wennberg
parent
69d3bba587
commit
daeab67dca
@@ -967,6 +967,12 @@ export const MASTER_DATA_DUMP_TABLES: MasterDataTableSpec[] = [
|
||||
// Counterparties and articles
|
||||
{ name: 'customers', file: 'customers.json', orderBy: 'created_at' },
|
||||
{ name: 'suppliers', file: 'suppliers.json', orderBy: 'created_at' },
|
||||
// The party layer above customers and suppliers: identities, facts with
|
||||
// provenance, payment identities and the human decisions that shaped them.
|
||||
{ name: 'parties', file: 'parties.json', orderBy: 'created_at' },
|
||||
{ name: 'party_facts', file: 'party_facts.json', orderBy: 'recorded_at' },
|
||||
{ name: 'party_identities', file: 'party_identities.json', orderBy: 'created_at' },
|
||||
{ name: 'party_decisions', file: 'party_decisions.json', orderBy: 'created_at' },
|
||||
{ name: 'articles', file: 'articles.json', orderBy: 'created_at' },
|
||||
// Customer invoicing
|
||||
{ name: 'invoices', file: 'invoices.json', orderBy: 'invoice_date' },
|
||||
|
||||
Reference in New Issue
Block a user