feat(skatteverket): expose filed VAT declarations and decisions via the v1 API (#1773)

* feat(skatteverket): expose filed VAT declarations and decisions via the v1 API

Add GET /api/v1/companies/:companyId/skatteverket/vat-declarations, returning
a period's momsdeklaration as Skatteverket has it on file: the submitted
declaration (SKV /inlamnat) and Skatteverket's beslut (SKV /beslutat), either
individually via ?state= or both.

- Auth: compliance:read scope; member-visibility read model per #1673
  (resolveReadAuth: caller's token, any member's active token, or system
  credentials with a verified ombud grant).
- Architecture: core reaches the Skatteverket extension through the
  registry-resolved services channel (contract in
  lib/skatteverket/declaration-status.ts), so core never imports from
  @/extensions/.
- New structured error SKATTEVERKET_API_ERROR (502) for upstream SKV
  failures; 404 from SKV maps to submitted/decided = null with HTTP 200.
- 19 new tests (route: auth, validation, extension-disabled, happy path;
  extension service: auth resolution, state filtering, SKV error mapping).

Fixes #1663

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* fix(skatteverket): address review findings on the vat-declarations read API

Consolidated fixes for PR #1773 review round:

- apiskill sync (core-build Checks): map the new skatteverket endpoint
  group into the periods.md reference and regenerate skills/accounted-api
  (124 -> 125 operations).
- CodeRabbit: parse the SKV 2xx body before writing the audit row, so an
  unreadable body is audited as skv_error and returns the structured
  SKATTEVERKET_API_ERROR 502 instead of escaping as an internal 500;
  regression test added.
- Compliance swarm (ISO A.8.12 / SOC2 CC6.1): stop forwarding the raw
  upstream SKV response body to API consumers; the caller now gets the
  status code and a generic Swedish message, the body is logged
  server-side only.
- Compliance swarm (GDPR Art.30): add the moms.declaration_status_read
  processing activity to .compliance/ropa.yaml (live read, no payload
  persisted, audit-log metadata only).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Mattsson
2026-08-21 12:12:18 +02:00
committed by GitHub
co-authored by Claude Fable 5
parent 0de766c6a4
commit 60920ec794
15 changed files with 949 additions and 7 deletions
+41
View File
@@ -228,6 +228,47 @@ processing_activities:
- bankid_signing_required_for_filing
- immutable_audit_log
- id: moms.declaration_status_read
name: Avläsning av inlämnad momsdeklaration och beslut från Skatteverket
purpose: >-
Läsa tillbaka en redan inlämnad momsdeklaration (inlamnat) och
Skatteverkets beslut (beslutat) för en period, på begäran av en
medlem i företaget via v1 REST-API:t eller MCP, så att bokföringen
kan stämmas av mot faktiskt inlämnade uppgifter. Läsning sker live
mot Skatteverket; deklarationsinnehållet lagras inte hos oss, endast
en audit-rad om att anropet gjordes.
lawful_basis: art_6_1_b # service provision: read-back requested by the customer
special_category_basis: null
controller: gnubok-tenant
processor: anthropic-na
data_subjects:
- business_owner
data_categories:
- user.government_id # orgnummer (juridiska personer) eller pnr
- user.financial.tax # rutor 05-62 i det inlämnade underlaget/beslutet
recipients:
- name: Skatteverket
country: SE
role: legal_recipient
international_transfers:
applicable: false
mechanism: null
note: Sweden-to-Sweden flow; no third-country transfer.
retention:
# Response bodies are returned to the caller and never persisted.
# Only the outbound call metadata lands in the audit log.
duration: 7y
basis: bfl_7_kap
stored_in:
- skatteverket_api_audit_log
security_measures:
- rls_company_scoped
- rbac_company_member_role_check
- tls_1_3_to_skatteverket
- immutable_audit_log
- no_payload_body_persisted
- upstream_error_bodies_logged_server_side_only
- id: psd2.cash_account_mirror
name: PSD2-konton speglas till cash_accounts
purpose: >-