Add Statskontoret data integration support#1993
Conversation
Agent-Logs-Url: https://github.com/Hack23/riksdagsmonitor/sessions/dc62517a-f53c-423f-b327-3d2856b258f8 Co-authored-by: pethers <1726836+pethers@users.noreply.github.com>
Agent-Logs-Url: https://github.com/Hack23/riksdagsmonitor/sessions/dc62517a-f53c-423f-b327-3d2856b258f8 Co-authored-by: pethers <1726836+pethers@users.noreply.github.com>
Agent-Logs-Url: https://github.com/Hack23/riksdagsmonitor/sessions/dc62517a-f53c-423f-b327-3d2856b258f8 Co-authored-by: pethers <1726836+pethers@users.noreply.github.com>
Agent-Logs-Url: https://github.com/Hack23/riksdagsmonitor/sessions/dc62517a-f53c-423f-b327-3d2856b258f8 Co-authored-by: pethers <1726836+pethers@users.noreply.github.com>
🏷️ Automatic Labeling SummaryThis PR has been automatically labeled based on the files changed and PR metadata. Applied Labels: documentation,dependencies,testing,refactor,size-xl Label Categories
For more information, see |
🔍 Lighthouse Performance Audit
📥 Download full Lighthouse report Budget Compliance: Performance budgets enforced via |
Agent-Logs-Url: https://github.com/Hack23/riksdagsmonitor/sessions/6d0707ac-bee8-4c66-b550-cd699273652c Co-authored-by: pethers <1726836+pethers@users.noreply.github.com>
🔍 Lighthouse Performance Audit
📥 Download full Lighthouse report Budget Compliance: Performance budgets enforced via |
Agent-Logs-Url: https://github.com/Hack23/riksdagsmonitor/sessions/6d0707ac-bee8-4c66-b550-cd699273652c Co-authored-by: pethers <1726836+pethers@users.noreply.github.com>
🔍 Lighthouse Performance Audit
📥 Download full Lighthouse report Budget Compliance: Performance budgets enforced via |
Agent-Logs-Url: https://github.com/Hack23/riksdagsmonitor/sessions/f3c03785-61ec-4ef8-acf8-c12c952c7ded Co-authored-by: pethers <1726836+pethers@users.noreply.github.com>
🔍 Lighthouse Performance Audit
📥 Download full Lighthouse report Budget Compliance: Performance budgets enforced via |
Addressed in b064b08:
20/20 targeted tests pass, ESLint clean, build:lib green, parallel_validation green (Code Review: 0 comments, CodeQL: 0 alerts). |
Agent-Logs-Url: https://github.com/Hack23/riksdagsmonitor/sessions/e7e16b7d-265b-46d9-8628-73a43c059298 Co-authored-by: pethers <1726836+pethers@users.noreply.github.com>
🔍 Lighthouse Performance Audit
📥 Download full Lighthouse report Budget Compliance: Performance budgets enforced via |
Agent-Logs-Url: https://github.com/Hack23/riksdagsmonitor/sessions/e7e16b7d-265b-46d9-8628-73a43c059298 Co-authored-by: pethers <1726836+pethers@users.noreply.github.com>
🔍 Lighthouse Performance Audit
📥 Download full Lighthouse report Budget Compliance: Performance budgets enforced via |
…ation Agent-Logs-Url: https://github.com/Hack23/riksdagsmonitor/sessions/7f40b8bb-7e1e-4b19-9881-f1ad5386d8f0 Co-authored-by: pethers <1726836+pethers@users.noreply.github.com>
🔍 Lighthouse Performance Audit
📥 Download full Lighthouse report Budget Compliance: Performance budgets enforced via |
…, fix test comment Agent-Logs-Url: https://github.com/Hack23/riksdagsmonitor/sessions/7f40b8bb-7e1e-4b19-9881-f1ad5386d8f0 Co-authored-by: pethers <1726836+pethers@users.noreply.github.com>
🔍 Lighthouse Performance Audit
📥 Download full Lighthouse report Budget Compliance: Performance budgets enforced via |
🔍 Lighthouse Performance Audit
📥 Download full Lighthouse report Budget Compliance: Performance budgets enforced via |
There was a problem hiding this comment.
Pull request overview
Adds first-class Statskontoret open-data integration (client + CLI + persistence + docs/tests) to complement existing IMF/SCB/World Bank provider tiers.
Changes:
- Introduces
scripts/statskontoret-client.ts(discovery, XLSX/ZIP parsing, headcount + budget outturn helpers, typed errors) andscripts/statskontoret-fetch.tsCLI wrapper for workflows. - Extends persistence layer with
persistStatskontoretData()and addsjszipdependency for workbook/ZIP parsing. - Adds comprehensive Vitest coverage and a new
analysis/statskontoret/documentation hub (inventory, data dictionary, use cases) plus architecture/threat-model updates.
Reviewed changes
Copilot reviewed 19 out of 20 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
| tests/statskontoret-inventory.test.ts | Validates the new Statskontoret inventory JSON matches the in-code source catalogue and decision matrix. |
| tests/statskontoret-fetch.test.ts | Covers CLI argument parsing + guards (including allowlist enforcement and typed CLI errors). |
| tests/statskontoret-client.test.ts | Covers discovery parsing, XLSX/ZIP parsing, aggregation helpers, and typed error surfaces. |
| scripts/statskontoret-fetch.ts | Adds workflow-friendly CLI to discover/download/parse Statskontoret artifacts with optional persistence. |
| scripts/statskontoret-client.ts | Adds the core Statskontoret client, parsers, aggregators, allowlist guard, and typed error type. |
| scripts/parliamentary-data/data-persistence.ts | Adds statskontoret documentType + persistStatskontoretData() for cache/provenance sidecars. |
| package.json | Adds jszip for XLSX/ZIP parsing. |
| package-lock.json | Locks jszip and transitive dependencies. |
| analysis/statskontoret/use-cases.md | Documents canonical use cases (headcount, budget execution, outturn summaries). |
| analysis/statskontoret/indicators-inventory.json | Introduces a machine-readable Statskontoret dataset inventory + provider decision matrix. |
| analysis/statskontoret/data-dictionary.md | Documents field mappings, inference rules, freshness discipline, and persistence layout. |
| analysis/statskontoret/README.md | Adds the Statskontoret integration hub and CLI quick reference. |
| THREAT_MODEL.md | Adds STRIDE threat assessment section for Statskontoret ingestion. |
| TESTING.md | Documents Statskontoret test suites and expectations (no live network). |
| SECURITY_ARCHITECTURE.md | Adds security architecture notes/controls for the new integration. |
| README.md | Adds top-level documentation entry for Statskontoret integration and quick commands. |
| MINDMAP.md | Adds current-state mindmap branch for Statskontoret integration. |
| FLOWCHART.md | Adds current-state data-flow diagram for Statskontoret ingestion/persistence. |
| DATA_MODEL.md | Adds data-model extension notes for Statskontoret entities and persisted artifacts. |
| ARCHITECTURE.md | Adds current-architecture section describing how Statskontoret fits into the provider tiering and workflows. |
|
|
||
| private async fetchWithTimeout(url: string): Promise<Response> { | ||
| const resolved = resolveStatskontoretUrl(url, this.baseURL); | ||
| assertStatskontoretFetchTarget(resolved); |
| if (!response.ok) { | ||
| throw new StatskontoretError(`Statskontoret API error: ${response.status} ${response.statusText} for ${response.url}`, 'http'); | ||
| } | ||
| return response; |
| * typed rows sorted by year ascending, then month ascending (NaN last for | ||
| * annual rows), then documentType alphabetically. For single-type workbooks | ||
| * (e.g. a file explicitly downloaded as "Inkomst"), pass | ||
| * `options.documentType` to set the label uniformly. |
| "version": "1.1", | ||
| "description": "Machine-readable inventory of Statskontoret open datasets used by Riksdagsmonitor for Swedish government-body and central-government budget context. Complements IMF (primary economic projections), SCB (Swedish official statistics), World Bank (non-economic global context), and Riksdag/Regering data.", | ||
| "lastUpdated": "2026-04-25", | ||
| "effectiveDate": "2026-04-25", | ||
| "source": "Statskontoret open data (www.statskontoret.se)", | ||
| "classification": "Public", | ||
| "clients": { | ||
| "cli": "tsx scripts/statskontoret-fetch.ts (commands: list-sources, discover, headcount, budget-outturn)", | ||
| "library": "scripts/statskontoret-client.ts (StatskontoretClient class)", | ||
| "persistence": "scripts/parliamentary-data/data-persistence.ts (persistStatskontoretData)" | ||
| }, | ||
| "notes": { | ||
| "firewallAllowlist": "www.statskontoret.se", | ||
| "noMcp": "Statskontoret is not an MCP server. Agentic workflows invoke the TypeScript CLI via the bash tool, mirroring IMF's no-MCP client pattern.", | ||
| "formats": "Myndighetsförteckningen is published as Excel. Årsutfall and Månadsutfall expose both Excel and CSV ZIP downloads. Budget time-series pages link to annual official-statistics publications and related open-data tables.", | ||
| "privacy": "Public authority/agency data and aggregate budget data only; no private-person data. Authority names and agency-level budget lines are public administrative records." | ||
| }, | ||
| "datasets": { | ||
| "myndighetsforteckning": { | ||
| "title": "Myndighetsförteckning – öppna data", | ||
| "url": "https://www.statskontoret.se/analys-och-statistik/oppna-data/myndighetsforteckning/", | ||
| "cadence": "Annual snapshot; source page metadata observed as last-modified 2026-02-06 for the 2025 workbook.", | ||
| "coverage": "Summerande statistik 2025; tidsserier 2007–2025; förteckning 2025; förteckning 2007–2025.", | ||
| "format": [ | ||
| "xlsx" | ||
| ], | ||
| "primaryUse": "Headcount of government bodies, grouped by department, leadership form and special organs; department headcount over time from 2007 onward.", | ||
| "keyFields": [ | ||
| "År", | ||
| "Myndighet", | ||
| "Departement / departementstillhörighet", | ||
| "Årsarbetskrafter", | ||
| "Ledningsform", | ||
| "Särskilda organ" | ||
| ], | ||
| "derivedArtifacts": [ | ||
| { | ||
| "id": "headcount-by-department", | ||
| "description": "Sum årsarbetskrafter by year and department, with authority count per group.", | ||
| "script": "tsx scripts/statskontoret-fetch.ts headcount --url <xlsx-url> --persist", | ||
| "storage": "analysis/data/statskontoret/myndighetsforteckning/headcount-by-department.json" | ||
| } | ||
| ], | ||
| "committees": [ | ||
| "KU", | ||
| "FiU", | ||
| "AU" | ||
| ], | ||
| "admiralty": "A1" | ||
| }, | ||
| "budget-time-series": { | ||
| "title": "Tidsserier, statens budget m.m.", | ||
| "url": "https://www.statskontoret.se/analys-och-statistik/officiell-statistik/tidsserier-statens-budget-m.m", | ||
| "cadence": "Annual official statistics release.", | ||
| "coverage": "Final outcomes for central-government revenue, expenditure, balance and related public-finance tables, generally from 1995.", | ||
| "format": [ | ||
| "html-publication", | ||
| "linked-open-data" | ||
| ], | ||
| "primaryUse": "Long-run Swedish central-government budget context for finance, tax and public-administration analysis.", | ||
| "committees": [ | ||
| "FiU", | ||
| "SkU", | ||
| "KU" | ||
| ], | ||
| "admiralty": "A1", | ||
| "derivedArtifacts": [ | ||
| { | ||
| "id": "budget-outturn", | ||
| "description": "Long-run central-government budget time series (revenue and expenditure) from 1995 onward parsed into StatskontoretBudgetRow objects.", | ||
| "script": "tsx scripts/statskontoret-fetch.ts budget-outturn --source budget-time-series --url <xlsx-url> --persist", | ||
| "storage": "analysis/data/statskontoret/budget-time-series/budget-outturn.json" | ||
| } | ||
| ] | ||
| }, |
| ```ts | ||
| import { parseBudgetRows, summarizeBudgetOutturn } from '../scripts/statskontoret-client.js'; | ||
|
|
||
| const rows = parseBudgetRows(records, { documentType: 'Inkomst' }); | ||
| const summary = summarizeBudgetOutturn(rows); | ||
| // summary[0] → { year: 2024, documentType: 'Inkomst', totalOutturn: 700000, totalBudget: 670000, variance: 30000, rowCount: 2 } | ||
| ``` |
|
@copilot apply changes based on the comments in this thread |
… formatting Agent-Logs-Url: https://github.com/Hack23/riksdagsmonitor/sessions/29714f50-655f-4c5d-a8c0-9f65516d4ce2 Co-authored-by: pethers <1726836+pethers@users.noreply.github.com>
🔍 Lighthouse Performance Audit
📥 Download full Lighthouse report Budget Compliance: Performance budgets enforced via |
Addressed in 1068acb: configurable Statskontoret |
baseURLintoassertStatskontoretFetchTargetfromStatskontoretClient.fetchWithTimeoutStatskontoretErrorwithkind: 'http'and preservecausebuildBudgetTimeSeriesJSDoc with actual annual-row orderinganalysis/statskontoret/indicators-inventory.jsonto repository-standard 2-space indentationanalysis/statskontoret/use-cases.mdexample import pathbaseURLand network typed-error behaviornpm run build:lib: passed