feat(invoices): add Peppol delivery foundation (#1595)

* feat(invoices): add Peppol delivery foundation

* fix(invoices): harden Peppol compliance guards

* fix(api): narrow Peppol document loading

* test(pg): hash Peppol fixture payload

* fix(invoices): address Peppol review findings

* test(pg): isolate Peppol provider events

* test(pg): isolate Peppol submission fixtures
This commit is contained in:
Mattsson
2026-08-13 19:44:32 +02:00
committed by GitHub
parent 05380ddf54
commit 07e89d9b52
25 changed files with 2376 additions and 84 deletions
+1
View File
@@ -935,6 +935,7 @@ One line per decision: `[YYYY-MM-DD] <decision>: <why>`. Appended by agents and
[2026-08-13] Skeptic refutation fix on the renewal guard: the picker's gap-fill probe keys its state by connectionId and lists `accounts` in its deps, so the pre-existing reset effect (re-runs on every accounts identity change, e.g. the panel's visibility refetch after a BankID app switch) can never wipe the renewal default without a matching re-probe. Backfill sweep hardening from the same pass: accounts whose cash_accounts row did not resolve (found: false) are skipped instead of degrading to the pooled currency-only form, and the sweep window opens at the oldest returned booking date when the bank over-returns history. resolveGapFillStart clamps to the backend's 365-day floor so the shown date always matches the actual backfill start.
[2026-08-13] WhatsApp decline observability (#1552) reuses whatsapp_messages with content-free rows for unknown-sender declines instead of a new table or aggregate RPC: no migration (no orphan risk), the wamid unique index gives redelivery dedupe for free (a redelivered bad-code or greeted message no longer earns a second reply), and the existing 30-day unknown-sender retention pass already deletes the rows. Write amplification from an over-quota flood is bounded by a 20-rows-per-hash-per-day trace cap, not by dropping the trail entirely. The settings panel gets a closed event enum derived server-side (lib/last-event.ts), never raw error_message text, so internal errors cannot leak to the client.
[2026-08-13] Issue #546 ships a provider-agnostic Peppol BIS Billing 3 XML export with strict Swedish preflight, not a fake send path: certified access-point delivery, SMP lookup, receipts, inbound handling, credentials, and commercial terms depend on Emil selecting and contracting a multitenant provider, and the existing email delivery state cannot truthfully model those guarantees.
[2026-08-13] Issue #546 Peppol transport foundation uses separate immutable staging, event, and evidence records with a disabled send gate: Corner 3 transport is not buyer acceptance, raw out-of-order events must remain auditable, and Storecove or Qvalia credentials plus a verified webhook contract are still external product inputs.
[2026-08-13] Kontantmetoden year-end VAT supersedes the 2026-08-06 VAT-reporting premise: BAS 2618/2628/2638 and 2648 feed the final declaration, reverse-charge purchases include both VAT sides and their basis, and only the mechanical day-one reversal is excluded from later VAT periods. Skatteverket requires unpaid invoice VAT in the final period and warns against reporting it twice after year end.
[2026-08-13] Per-account VAT treatment is class-aware and explicit values override the static BAS mapping; SIE #SRU and #KTYP never supply it because they encode tax-return fields and account class, not momsdeklaration treatment.
[2026-08-13] Per-account VAT treatment is class-aware; explicit values extend custom accounts while canonical accounts keep their static BAS momsdeklaration mapping. SIE #SRU and #KTYP never supply it because they encode tax-return fields and account class, not momsdeklaration treatment. VMB carries no default account rate because its VAT base is the margin, not gross sales.