fix: emit the buyer legal registration identifier (BT-47)

DA
1mo ago
+30-1

Problem

BT-47 (Buyer legal registration identifier, ram:BuyerTradeParty/ram:SpecifiedLegalOrganization/ram:ID) is accepted as input, validated, and then silently dropped — it never reaches the generated XML, in any profile.

The cause is a mask ↔ schema mismatch:

  • profiles/minimum/schema.ts declares the buyer's organization node and its registrationIdentifier without a key, while the seller counterparts carry key: "BT-30-00" and key: "BT-30".
  • All five masks (minimum, basic-wl, basic, en16931, extended) do reference "BT-47-00" and "BT-47".
  • applyMask resolves schema nodes by key (findFieldByKey). A key referenced by the mask but never declared in the schema resolves to undefined, so the whole node is left out of the effective schema.

The repo's own MINIMUM fixture (src/test-utils/data/minimum.ts) already sets registrationIdentifier on both parties, which makes the asymmetry visible in the current output: SellerTradeParty gets its <ram:SpecifiedLegalOrganization>, BuyerTradeParty gets only <ram:Name>.

This matters in practice for French Factur-X: for public entities (ChorusPro) the buyer identifier is a SIRET and is mandatory — the schema's own description says so. Downstream we currently patch the profile object at runtime to get BT-47 emitted at all.

Fix

Two key entries in profiles/minimum/schema.ts, mirroring the seller side. Every other profile extends MINIMUM, so this one change covers them all. Nothing else is touched — no XML shape change beyond the previously missing element, which is optional in the XSD.

Test

formatter.test.ts gets a test that builds the MINIMUM fixture and asserts both parties emit their <ram:SpecifiedLegalOrganization> ID.

  • on main: fails with expected '\n <ram:Name>Kunden AG Frankre…' to contain '<ram:ID schemeID="0002">registrationI…'
  • with the fix: passes

Full suite is green (12 → 13 tests), tsc --noEmit clean, biome check clean on both files.