Implemented SageClient interfacing with Sage v3.1 REST API endpoints.
Handled OAuth 2.0 with automatic token refresh, clock-skew protection (EXPIRY_SKEW_MS = 30s), and single-use refresh token rotation.
Configured attribute projections (?attributes=all) on all list calls (/ledger_accounts, /bank_accounts, /contacts, /sales_invoices, /other_payments) to ensure Sage returns full objects rather than bare stub summaries.
Built pagination handling supporting large datasets with a safety cap.
Unwrapped API envelopes ($items) cleanly with zero I/O.
Handled Sage's string-encoded numbers (e.g. "11400.0", "9500.0") by safely parsing them into finite numbers.
Preserved strict canonical purity: missing fields remain undefined—no synthetic defaults, fake zeroes, or invented placeholders.
Mapped all entities into Buki’s canonical finance shapes:
LedgerAccount: 144 chart of accounts + 8 bank accounts mapped as assets with deduplication.
Party: Contacts classified as customer, supplier, or both via contact_types.
Invoice & InvoiceLine: Sales invoices normalized with line-level ledger accounts and status mappings (unpaid, part_paid, paid, void, draft).
BankTransaction: Mapped with signed movements (+ for receipts/credits, - for payments/debits).
Stored canonical records in .data/store.json using collision-free canonical IDs (sage:<id>).
Implemented domain isolation: a failure in the finance domain is logged with error telemetry and never corrupts or deletes existing HR records.
Verified end-to-end functionality across tests, live modules, and the Brief Q&A engine.
