* feat(arcim-migration): Briox provider with SIE-over-API import - Briox auth via account ID + application token (no app-level credentials); both tokens rotate on refresh and are persisted - New sie-fetcher pulls the general ledger as SIE through the provider API for Fortnox, Briox and Bjorn Lunden - Wizard stops on a failed SIE import and surfaces the real errors instead of proceeding to the misleading migrate-guard message - PROVIDER_SIE_ONLY_FORTNOX renamed to PROVIDER_SIE_NOT_SUPPORTED; new PROVIDER_TOKEN_INVALID for rejected provider credentials Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * feat(bookkeeping): per-line accruals (periodisering) on invoices and supplier invoices Defer revenue/costs per invoice line to 29xx/17xx interim accounts with automatic monthly dissolution (nightly cron + catch-up at registration), schedule cancellation on credit, year-end auto-detect exclusion for already-scheduled invoices, invoice-inbox service-period extraction for prefill, and an MCP tool to list schedules. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * feat(bokslut): iXBRL arsredovisning generation and Bolagsverket digital filing Generate the annual report as iXBRL from a generated taxonomy registry (K2 element lists, taxonomy:generate/check scripts + CI guard), expose it via the fiscal-period API, and add the bolagsverket extension for digital submission to eget utrymme with webhook-driven status tracking (submissions table + pg tests, lifecycle events, year-end wizard UI). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * test(mcp): raise origin-guard test timeout to 20s The dynamic import pulls in the full server module; the parse alone flirts with the 5s default under full-suite parallel load. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * Add new scripts and documentation for K2 AB taxonomy generation and validation - Introduced `generate-taxonomy-registry.ts` to automate the generation of the iXBRL taxonomy concept registry from official element lists and tuple models. - Added `validate-ixbrl.mjs` for validating generated iXBRL reports against the official taxonomy package using Arelle. - Included new documentation files: - `k2-ab-arsredovisning-elementlista-2024-09-12_rev20250312_sv.xlsx` - `tuple-innehallsmodell-arsredovisning-k2-2024-09-12.xlsx` - `taxonomi-paket-2024-09-12_rev20250312.zip` * Add tests for bookkeeping accruals dissolution and supplier invoices - Implement tests for the POST /api/bookkeeping/accruals/[id]/dissolve route, covering success and error scenarios. - Add tests for the DELETE /api/supplier-invoices/[id] route, including authentication checks and validation of invoice deletion conditions. - Introduce tests for the Arcim migration provider client, ensuring token handling and error classification. - Create tests for the Bolagsverket extension, validating submission role enforcement and environment settings. - Add Zod schemas for Bolagsverket response payloads to ensure proper validation. - Implement tests for MCP server's list accrual schedules, confirming registration and scope mapping. - Add consistency tests for IXBRL document generation, ensuring duplicate facts and XML escaping are handled correctly. - Introduce typed domain errors for accrual schedules to improve error handling in the service. - Add tests for resolving consent with Briox token refresh concurrency, ensuring proper token management and error handling. * fix(tests): update payload size guard comments to reflect recent changes in tool descriptions and ceiling adjustments * fix(gitattributes): mark generated JSON files in bokslut taxonomy as linguist-generated * feat(migrations): add backfill for invoices.journal_entry_id and fallback for next_voucher_number user_id * feat(bokslut): enhance compliance and financial processing features with new submission details and security measures --------- Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
368 lines
14 KiB
YAML
368 lines
14 KiB
YAML
# Record of Processing Activities (GDPR Art. 30)
|
||
#
|
||
# Each entry documents one processing activity. Field shape follows EDPB
|
||
# Guidelines 9/2022 §3 (controller-side RoPA): purposes, lawful basis,
|
||
# data subject + data category, recipients, transfer mechanism, retention,
|
||
# security measures. Add an entry whenever a new flow ships that touches
|
||
# personal data — onboarding, integrations, support, or regulator filings.
|
||
|
||
processing_activities:
|
||
|
||
- id: agi.submit
|
||
name: AGI inlämning till Skatteverket
|
||
purpose: >-
|
||
Lämna in lagstadgad arbetsgivardeklaration på individnivå (AGI) till
|
||
Skatteverket varje månad (Skatteförfarandelagen 26 kap.). Innefattar
|
||
huvuduppgift (HU) och individuppgifter (IU) per anställd.
|
||
lawful_basis: art_6_1_c # legal obligation
|
||
special_category_basis: null
|
||
controller: gnubok-tenant
|
||
processor: anthropic-na # software supplier; Skatteverket is recipient, not processor
|
||
data_subjects:
|
||
- employee
|
||
data_categories:
|
||
- user.government_id # personnummer
|
||
- user.name
|
||
- user.financial.employment # gross salary, tax withheld, benefits
|
||
- user.financial.tax # avgifter, sjuklönekostnad
|
||
recipients:
|
||
- name: Skatteverket
|
||
country: SE
|
||
role: legal_recipient
|
||
international_transfers:
|
||
applicable: false
|
||
mechanism: null
|
||
note: >-
|
||
Sweden-to-Sweden processor-to-public-authority flow. Adequacy decision
|
||
not applicable; no third-country transfer.
|
||
retention:
|
||
duration: 7y
|
||
basis: bfl_7_kap # BFL 7 kap. — räkenskapsinformation
|
||
stored_in:
|
||
- agi_declarations.xml_content
|
||
- agi_declarations.individuppgifter
|
||
- skatteverket_api_audit_log
|
||
security_measures:
|
||
- encryption_at_rest_supabase
|
||
- rls_company_scoped
|
||
- tls_1_3_to_skatteverket
|
||
- bankid_signing_required_for_filing
|
||
- immutable_audit_log
|
||
- personnummer_at_rest_encryption
|
||
|
||
- id: agi.kontrollera.preflight
|
||
name: AGI pre-flight kontrollera (HU/IU)
|
||
purpose: >-
|
||
Skicka enskild HU eller IU som JSON till Skatteverkets kontrollera-
|
||
ändpunkt (v1.7 §7/§8) för dry-run-validering av felmeddelanden och
|
||
STOPP-/AVVISANDE-status innan ett fullständigt underlag laddas upp.
|
||
Skatteverket lagrar inget från denna kontroll; svaret driver vår UI
|
||
som låter användaren rätta felaktigheter i lönekörningen lokalt.
|
||
lawful_basis: art_6_1_c # legal obligation (ancillary to AGI filing)
|
||
special_category_basis: null
|
||
controller: gnubok-tenant
|
||
processor: anthropic-na
|
||
data_subjects:
|
||
- employee
|
||
data_categories:
|
||
- user.government_id # personnummer (BetalningsmottagarId)
|
||
- user.financial.employment # gross salary, tax withheld, benefits
|
||
recipients:
|
||
- name: Skatteverket
|
||
country: SE
|
||
role: legal_recipient
|
||
international_transfers:
|
||
applicable: false
|
||
mechanism: null
|
||
note: Sweden-to-Sweden flow; no third-country transfer.
|
||
retention:
|
||
# Skatteverket retains nothing for kontrollera calls. Our outbound
|
||
# audit row in skatteverket_api_audit_log records who-called-what-when
|
||
# but NOT the payload body, minimising at-rest footprint.
|
||
duration: 7y
|
||
basis: bfl_7_kap
|
||
stored_in:
|
||
- skatteverket_api_audit_log
|
||
security_measures:
|
||
- strict_zod_allow_list_input_validation
|
||
- request_size_cap_64kb
|
||
- rbac_company_member_role_check
|
||
- rls_company_scoped
|
||
- tls_1_3_to_skatteverket
|
||
- immutable_audit_log
|
||
- no_payload_body_persisted
|
||
|
||
- id: moms.declaration
|
||
name: Momsdeklaration till Skatteverket
|
||
purpose: >-
|
||
Lämna in lagstadgad momsdeklaration (utkast, lås och signering) till
|
||
Skatteverkets momsdeklaration-API (Mervärdesskattelagen 17 kap. 24 §).
|
||
lawful_basis: art_6_1_c
|
||
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
|
||
recipients:
|
||
- name: Skatteverket
|
||
country: SE
|
||
role: legal_recipient
|
||
international_transfers:
|
||
applicable: false
|
||
mechanism: null
|
||
note: Sweden-to-Sweden flow; no third-country transfer.
|
||
retention:
|
||
duration: 7y
|
||
basis: bfl_7_kap
|
||
stored_in:
|
||
- extension_data (utkast metadata)
|
||
- skatteverket_api_audit_log
|
||
security_measures:
|
||
- rls_company_scoped
|
||
- tls_1_3_to_skatteverket
|
||
- bankid_signing_required_for_filing
|
||
- immutable_audit_log
|
||
|
||
- id: psd2.cash_account_mirror
|
||
name: PSD2-konton speglas till cash_accounts
|
||
purpose: >-
|
||
När en bank-anslutning via Enable Banking returnerar kontolista efter
|
||
lyckad PSD2-consent kopieras kontometadata (IBAN, valuta, kontonamn,
|
||
external_uid) till cash_accounts så att avstämning, motkontoresolver
|
||
och __PRIMARY_SEK__-sentinel kan rutta verifikat utan att läsa JSONB
|
||
från bank_connections.accounts_data vid varje fråga.
|
||
lawful_basis: art_6_1_b # contract (PSD2 consent + bookkeeping service)
|
||
special_category_basis: null
|
||
controller: gnubok-tenant
|
||
processor: anthropic-na
|
||
data_subjects:
|
||
- business_owner
|
||
data_categories:
|
||
- user.financial.bank_account # IBAN
|
||
- user.contact # account name (kontotitel)
|
||
recipients:
|
||
- name: Supabase
|
||
country: EU
|
||
role: processor
|
||
international_transfers:
|
||
applicable: false
|
||
mechanism: null
|
||
note: EU-only processor; no third-country transfer.
|
||
retention:
|
||
duration: consent_lifetime
|
||
basis: psd2_consent
|
||
stored_in:
|
||
- cash_accounts
|
||
- bank_connections.accounts_data
|
||
security_measures:
|
||
- rls_company_scoped
|
||
- data_minimization_no_balance_on_callback
|
||
- failure_emitted_to_event_log
|
||
|
||
- id: transactions.counterparty_iban
|
||
name: Motpartens IBAN på transaktioner
|
||
purpose: >-
|
||
Spara motpartens IBAN på transaktionsraden så att own-account-detector
|
||
kan identifiera överföringar mellan företagets egna konton (1930 → 1932
|
||
etc.) och bokföra båda benen automatiskt istället för att felbokföra
|
||
utflödet som extern kostnad. Krävs även för payment-matchning mot
|
||
leverantörsfakturor.
|
||
lawful_basis: art_6_1_b # contract (bookkeeping service)
|
||
special_category_basis: null
|
||
controller: gnubok-tenant
|
||
processor: anthropic-na
|
||
data_subjects:
|
||
- business_owner
|
||
- counterparty
|
||
data_categories:
|
||
- user.financial.bank_account # counterparty IBAN
|
||
recipients:
|
||
- name: Supabase
|
||
country: EU
|
||
role: processor
|
||
international_transfers:
|
||
applicable: false
|
||
mechanism: null
|
||
note: EU-only processor.
|
||
retention:
|
||
duration: 7y
|
||
basis: bfl_7_kap
|
||
stored_in:
|
||
- transactions.counterparty_iban
|
||
security_measures:
|
||
- rls_company_scoped
|
||
- immutable_after_post
|
||
|
||
- id: skattekonto.drift_alert
|
||
name: Skattekonto-drift via e-post
|
||
purpose: >-
|
||
Underrätta företagets kontaktadress när det cachade Skatteverket-saldot
|
||
avviker från GL 1630 utöver konfigurerad tolerans (> 1 SEK), så
|
||
bokföraren kan granska skattekonto-raderna. E-postmeddelandet
|
||
innehåller ingen finansiell siffra utan en länk till autentiserad
|
||
dashboard; mottagaren valideras mot company_members innan utskick.
|
||
lawful_basis: art_6_1_f # legitimate interest (bookkeeping accuracy)
|
||
special_category_basis: null
|
||
controller: gnubok-tenant
|
||
processor: resend
|
||
data_subjects:
|
||
- business_owner
|
||
- company_member
|
||
data_categories:
|
||
- user.contact.email
|
||
recipients:
|
||
- name: Resend
|
||
country: US
|
||
role: processor
|
||
international_transfers:
|
||
applicable: true
|
||
mechanism: scc_2021_c2p
|
||
note: >-
|
||
Resend (US) — SCC Module 2 (controller-to-processor). Outbound
|
||
payload limited to ett notifieringsmail utan finansiella belopp;
|
||
TIA dokumenterad i .compliance/tia/resend.md.
|
||
retention:
|
||
duration: 30d
|
||
basis: event_log_ttl
|
||
stored_in:
|
||
- event_log
|
||
security_measures:
|
||
- recipient_membership_check_before_send
|
||
- no_financial_figures_in_body
|
||
- tls_to_resend
|
||
- rls_company_scoped
|
||
|
||
- id: ai.inference
|
||
name: AI-inferens (kategorisering + dokumenttolkning) via Amazon Bedrock
|
||
purpose: >-
|
||
Föreslå bokföringskategori för banktransaktioner och tolka/extrahera
|
||
uppladdade underlag (kvitton, leverantörsfakturor) med Anthropic
|
||
Claude-modeller körda i Amazon Bedrock. Endast aktiv när tenanten
|
||
uttryckligen aktiverat AI-funktioner — kärntjänsten (bokföring, fakturor,
|
||
moms, rapporter) fungerar fullt ut utan AI.
|
||
lawful_basis: art_6_1_a # consent — opt-in, AI features off by default
|
||
special_category_basis: null
|
||
controller: gnubok-tenant
|
||
processor: aws-bedrock
|
||
data_subjects:
|
||
- business_owner
|
||
- counterparty # namn/belopp på uppladdade underlag
|
||
data_categories:
|
||
- user.financial # transaktionsdata skickad för kategorisering
|
||
- user.document # uppladdade kvitton/fakturor för OCR/extraktion
|
||
recipients:
|
||
- name: Amazon Web Services (Amazon Bedrock)
|
||
country: EU
|
||
role: processor
|
||
international_transfers:
|
||
applicable: false
|
||
mechanism: null
|
||
note: >-
|
||
Inferens körs i AWS-regionen eu-north-1 (Stockholm) — ingen överföring
|
||
till tredje land. AWS DPA + SCC + DPF-certifiering finns som
|
||
skyddsmekanism. Prompter lagras ej hos Bedrock efter anropet och används
|
||
ej till modellträning.
|
||
retention:
|
||
duration: none_at_processor
|
||
basis: no_retention_bedrock # prompt not persisted by Bedrock post-inference
|
||
stored_in:
|
||
- ai_usage_tracking # usage metadata only (tokens/cost), no payload body
|
||
security_measures:
|
||
- opt_in_consent_required
|
||
- eu_region_inference_eu_north_1
|
||
- prompts_not_retained_after_inference
|
||
- not_used_for_model_training
|
||
- rls_company_scoped
|
||
- tls_to_bedrock
|
||
|
||
- id: mcp.telemetry
|
||
name: MCP/agent-telemetri i event_log
|
||
purpose: >-
|
||
Varje MCP-verktygsanrop loggar metadata (verktygsnamn, felkod,
|
||
felmeddelande max 500 tecken, latens, aktör, session, frivillig
|
||
distributionskanal-markör — t.ex. 'openclaw' via X-Gnubok-Client-header
|
||
eller ?client=-parameter, sanerad mot allow-list och aldrig använd för
|
||
auktorisation) och varje skill-laddning loggar slug/tier till event_log.
|
||
Syftet är tillförlitlighetsanalys av agentgränssnittet: felfrekvens per
|
||
verktyg, adoption per distributionskanal, korrelation mellan laddade
|
||
skills och efterföljande fel, samt agenters egenrapporterade feedback
|
||
(agent.feedback). Inga verktygsargument eller verktygsresultat
|
||
persisteras.
|
||
lawful_basis: art_6_1_f # legitimate interest (service reliability/improvement)
|
||
special_category_basis: null
|
||
controller: gnubok-tenant
|
||
processor: supabase
|
||
data_subjects:
|
||
- business_owner
|
||
data_categories:
|
||
- user.unique_id # userId, actorId (API-nyckel-id), sessionId
|
||
- user.contact # actorLabel (användarvald API-nyckeletikett)
|
||
recipients:
|
||
- name: Supabase
|
||
country: EU
|
||
role: processor
|
||
international_transfers:
|
||
applicable: false
|
||
mechanism: null
|
||
note: EU-only processor; no third-country transfer.
|
||
retention:
|
||
# Differentiated TTL via /api/events/cleanup/cron: mcp.*/agent.*-rader
|
||
# behålls 180 dagar (felfrekvens-trender kräver mer än leveransfönstret);
|
||
# övriga event_log-rader (leveranshändelser) 30 dagar.
|
||
duration: 180d
|
||
basis: legitimate_interest_reliability
|
||
stored_in:
|
||
- event_log
|
||
security_measures:
|
||
- rls_user_scoped_select # event_log SELECT: auth.uid() = user_id
|
||
- service_role_only_writes
|
||
- error_message_truncated_500_chars
|
||
- no_tool_args_or_results_persisted
|
||
|
||
- id: arsredovisning.bolagsverket.submit
|
||
name: Digital inlämning av årsredovisning till Bolagsverket
|
||
purpose: >-
|
||
Lämna in årsredovisningen (iXBRL) digitalt till Bolagsverkets eget
|
||
utrymme (ÅRL 8 kap.). Avsändarens och undertecknarens personnummer
|
||
krävs av Bolagsverkets API (skapa-inlamningtoken, lamna-in) och
|
||
används transient i anropen; i databasen sparas endast
|
||
företagssaltade SHA-256-hashar. Fastställelseintyget signeras med
|
||
e-legitimation hos Bolagsverket, aldrig i appen.
|
||
lawful_basis: art_6_1_c # legal obligation (ÅRL filing duty)
|
||
special_category_basis: null
|
||
controller: gnubok-tenant
|
||
processor: anthropic-na # software supplier; Bolagsverket is recipient, not processor
|
||
data_subjects:
|
||
- business_owner # avsändare/undertecknare (styrelseledamot, VD)
|
||
data_categories:
|
||
- user.government_id # personnummer (transient; at rest only salted SHA-256 hash)
|
||
- user.name # undertecknarens namn
|
||
- user.contact # undertecknarens/kvittens e-post
|
||
- user.financial # årsredovisningens finansiella innehåll
|
||
recipients:
|
||
- name: Bolagsverket
|
||
country: SE
|
||
role: legal_recipient
|
||
international_transfers:
|
||
applicable: false
|
||
mechanism: null
|
||
note: Sweden-to-Sweden flow to a public authority; no third-country transfer.
|
||
retention:
|
||
duration: 7y
|
||
basis: bfl_7_kap # filed .xhtml archived as räkenskapsinformation
|
||
stored_in:
|
||
- arsredovisning_submissions # status, idnummer, checksums, PNR hashes only
|
||
- document_attachments # the exact filed iXBRL bytes (WORM)
|
||
security_measures:
|
||
- mtls_client_certificate_to_bolagsverket
|
||
- mtls_key_env_only_injected_from_secret_manager # never in settings/DB; see .env.example custody note
|
||
- pinned_endpoint_allowlist_per_environment # HOSTS map in client.ts; not env-configurable
|
||
- personnummer_never_persisted_plaintext_salted_sha256_only
|
||
- personnummer_never_logged
|
||
- webhook_secret_constant_time_validation
|
||
- rls_company_scoped
|
||
- immutable_status_machine_trigger
|