diff --git a/chronicle/source_package.py b/chronicle/source_package.py index 993b4d9f..707c4938 100644 --- a/chronicle/source_package.py +++ b/chronicle/source_package.py @@ -124,7 +124,22 @@ "jrc/euromod_be_baseline_statistics_2025" ), "sfpd-legal-pension-caseload-2025": Path("sfpd/legal_pension_caseload_2025"), + "sfpd-grapa-monthly-statistics-2025-02": Path( + "sfpd/grapa_monthly_statistics_2025_02" + ), "opgroeien-groeipakket-caseload-2025": Path("opgroeien/groeipakket_caseload_2025"), + "opgroeien-groeipakket-basic-caseload-2025-12": Path( + "opgroeien/groeipakket_basic_caseload_2025_12" + ), + "iriscare-child-benefit-caseload-2025-12": Path( + "iriscare/child_benefit_caseload_2025_12" + ), + "ostbelgien-child-benefit-caseload-2025-12": Path( + "ostbelgien/child_benefit_caseload_2025_12" + ), + "parlement-wallonie-child-benefit-partitions-2023-12": Path( + "parlement_wallonie/child_benefit_partitions_2023_12" + ), "bfp-economic-outlook-2026-06": Path("bfp/economic_outlook_2026_06"), "fpb-economic-outlook-2026-2031-june-2026": Path( "fpb/economic_outlook_2026_2031_june_2026" diff --git a/db/data/iriscare/child_benefit_caseload_2025_12/iriscare-child-benefit-2025-12-dashboard-capture.zip b/db/data/iriscare/child_benefit_caseload_2025_12/iriscare-child-benefit-2025-12-dashboard-capture.zip new file mode 100644 index 00000000..c25fc4ac Binary files /dev/null and b/db/data/iriscare/child_benefit_caseload_2025_12/iriscare-child-benefit-2025-12-dashboard-capture.zip differ diff --git a/db/data/iriscare/child_benefit_caseload_2025_12/iriscare_child_benefit_caseload_2025_12.csv b/db/data/iriscare/child_benefit_caseload_2025_12/iriscare_child_benefit_caseload_2025_12.csv new file mode 100644 index 00000000..8c161430 --- /dev/null +++ b/db/data/iriscare/child_benefit_caseload_2025_12/iriscare_child_benefit_caseload_2025_12.csv @@ -0,0 +1,3 @@ +value_id,period,iriscare.statistic,publication_status,entity_view,legal_period,publisher_entity_label,retrieved_at,count,source_url +entitled_children,2025-12,entitled_children,provisional,Children,LegalPeriod=202512,children,2026-08-30,304966,https://stat.iriscare.brussels/home/enfants-et-familles/allocations-familiales/statistiques-generales-allocations-familiales/ +payment_recipients,2025-12,payment_recipients,provisional,Beneficiaries,LegalPeriod=202512,allocataires,2026-08-30,162745,https://stat.iriscare.brussels/home/enfants-et-familles/allocations-familiales/statistiques-generales-allocations-familiales/ diff --git a/db/data/iriscare/child_benefit_caseload_2025_12/manifest.yaml b/db/data/iriscare/child_benefit_caseload_2025_12/manifest.yaml new file mode 100644 index 00000000..447aba8c --- /dev/null +++ b/db/data/iriscare/child_benefit_caseload_2025_12/manifest.yaml @@ -0,0 +1,50 @@ +source_id: iriscare +package_id: iriscare-child-benefit-caseload-2025-12 +dataset: iriscare_child_benefit_caseload_2025_12 +publisher: Iriscare, Common Community Commission of Brussels-Capital +source_page: https://stat.iriscare.brussels/home/enfants-et-familles/allocations-familiales/statistiques-generales-allocations-familiales/ +table: General child-benefit statistics, rights period December 2025 +files: + 2025: + filename: iriscare_child_benefit_caseload_2025_12.csv + source_url: https://stat.iriscare.brussels/home/enfants-et-familles/allocations-familiales/statistiques-generales-allocations-familiales/ + sha256: 7666027bdc5d793a05184bf766148966b717049d8e07044ef645ed049fe11e20 + size_bytes: 617 + fetched_at: '2026-08-30T12:26:22+00:00' + source_table: Official Iriscare dashboard query for LegalPeriod 202512 + source_urls: + - https://stat.iriscare.brussels/home/enfants-et-familles/allocations-familiales/statistiques-generales-allocations-familiales/ + - https://www.iriscare.brussels/nl/2026/07/22/kinderbijslag-128-222-brusselse-kinderen-kregen-in-2025-een-sociale-toeslag-bovenop-hun-kinderbijslag/ + notes: Curated two-row capture of the official embedded dashboard result for LegalPeriod=202512, + retrieved on 2026-08-30. The observed Children and Beneficiaries views and the + publisher labels children and allocataires are guarded separately. Iriscare + defines allocataires as associated payment recipients, not households. The municipality + table includes Flemish Region, Walloon Region, outside Belgium, and unknown + rows, so the totals retain an Iriscare scheme scope rather than resident NUTS1 + BE1. No stable static query identifier was exposed. + storage: + r2: + provider: r2 + bucket: ledger-raw + key: raw/belgium/iriscare/iriscare-child-benefit-caseload-2025-12/2025/7666027bdc5d793a05184bf766148966b717049d8e07044ef645ed049fe11e20/iriscare_child_benefit_caseload_2025_12.csv + uri: r2://ledger-raw/raw/belgium/iriscare/iriscare-child-benefit-caseload-2025-12/2025/7666027bdc5d793a05184bf766148966b717049d8e07044ef645ed049fe11e20/iriscare_child_benefit_caseload_2025_12.csv + source_capture: + filename: iriscare-child-benefit-2025-12-dashboard-capture.zip + source_url: https://stat.iriscare.brussels/home/enfants-et-familles/allocations-familiales/statistiques-generales-allocations-familiales/ + source_urls: + - https://stat.iriscare.brussels/home/enfants-et-familles/allocations-familiales/statistiques-generales-allocations-familiales/ + - https://app.fabric.microsoft.com/view?r=eyJrIjoiZTQ2OWQzMDItNTNkYy00Y2IyLWFmYjAtZDhlNWMxODhlYTJhIiwidCI6Ijk0YzA3MjAwLWU5MjEtNDBjNS04MzE5LTZkMjE2ZDkyZGZmMSIsImMiOjl9 + sha256: a254455cd9bc0e872a5f47a5c3f0fa07dff2fbfe7c1b5a1e0c22b4c65036a934 + size_bytes: 174132 + fetched_at: '2026-08-30T13:08:00+00:00' + notes: Browser capture of both official embedded Power BI views with period 202512, + all communes, all acquired-right statuses, and provisional data selected. The + archive contains screenshots plus accessibility-tree text preserving the exact + 304,966 entitled-child total, the exact 162,745 allocataire total, and the non-Brussels + and outside-Belgium rows that define the scheme-wide scope. + storage: + r2: + provider: r2 + bucket: ledger-raw + key: raw/belgium/iriscare/iriscare-child-benefit-caseload-2025-12/source_capture/a254455cd9bc0e872a5f47a5c3f0fa07dff2fbfe7c1b5a1e0c22b4c65036a934/iriscare-child-benefit-2025-12-dashboard-capture.zip + uri: r2://ledger-raw/raw/belgium/iriscare/iriscare-child-benefit-caseload-2025-12/source_capture/a254455cd9bc0e872a5f47a5c3f0fa07dff2fbfe7c1b5a1e0c22b4c65036a934/iriscare-child-benefit-2025-12-dashboard-capture.zip diff --git a/db/data/opgroeien/groeipakket_basic_caseload_2025_12/manifest.yaml b/db/data/opgroeien/groeipakket_basic_caseload_2025_12/manifest.yaml new file mode 100644 index 00000000..cee6ce89 --- /dev/null +++ b/db/data/opgroeien/groeipakket_basic_caseload_2025_12/manifest.yaml @@ -0,0 +1,48 @@ +source_id: opgroeien +package_id: opgroeien-groeipakket-basic-caseload-2025-12 +dataset: opgroeien_groeipakket_basic_caseload_2025_12 +publisher: Opgroeien (Agentschap Opgroeien regie), Flemish Community +source_page: https://www.opgroeien.be/kennis/cijfers-en-onderzoek/groeipakket/cijfers-op-maat +table: Groeipakket basic-amount child caseload, rights period 2025/12 +files: + 2025: + filename: opgroeien_groeipakket_basic_caseload_2025_12.csv + source_url: https://www.opgroeien.be/kennis/cijfers-en-onderzoek/groeipakket/cijfers-op-maat + sha256: 508c49236221b0bd246f46cab25f36cdc6f61222dbbe9a64a88c67fe37f3de20 + size_bytes: 442 + fetched_at: '2026-08-30T12:26:22+00:00' + source_table: Official Groeipakket dashboard query result for basic-amount children + source_urls: + - https://www.opgroeien.be/kennis/cijfers-en-onderzoek/groeipakket/cijfers-op-maat + - https://www.opgroeien.be/kennis/cijfers-en-onderzoek/vlaams-groeipakket + notes: Curated one-row capture of the official interactive dashboard result retrieved + on 2026-08-30. Separate guarded columns preserve the authored entity, period, + provisional-figure, Groeipakket, and basic-amount views. Opgroeien does not + expose this exact child count in a static download. The table includes bilateral + agreement and difference-payment categories, so the result is retained as a + scheme-wide statistical scope rather than resident NUTS1 BE2. + storage: + r2: + provider: r2 + bucket: ledger-raw + key: raw/belgium/opgroeien/opgroeien-groeipakket-basic-caseload-2025-12/2025/508c49236221b0bd246f46cab25f36cdc6f61222dbbe9a64a88c67fe37f3de20/opgroeien_groeipakket_basic_caseload_2025_12.csv + uri: r2://ledger-raw/raw/belgium/opgroeien/opgroeien-groeipakket-basic-caseload-2025-12/2025/508c49236221b0bd246f46cab25f36cdc6f61222dbbe9a64a88c67fe37f3de20/opgroeien_groeipakket_basic_caseload_2025_12.csv + source_capture: + filename: opgroeien-groeipakket-2025-12-dashboard-capture.zip + source_url: https://www.opgroeien.be/kennis/cijfers-en-onderzoek/groeipakket/cijfers-op-maat + source_urls: + - https://www.opgroeien.be/kennis/cijfers-en-onderzoek/groeipakket/cijfers-op-maat + - https://app.powerbi.com/view?r=eyJrIjoiZTFiMzllMTUtNmUxNy00MWVkLWJiOGEtNGE3ZmVlZTY3NjZhIiwidCI6IjEzY2ZlMTgyLTY0MmEtNDgwZS1iYzhhLTVlY2Y2NWRiMGFhMCIsImMiOjh9 + sha256: aa3a6158006e05db0d326ed1e00836d623607a4d5108a9aa96a5323c1c124bd0 + size_bytes: 12089 + fetched_at: '2026-08-30T13:06:00+00:00' + notes: Browser capture of the official embedded Power BI Data view. The archive + contains a screenshot and its accessibility-tree text. The text preserves the + selected 2025/12 column, every published basic-amount category, the bilateral-agreement + and difference-payment rows, and the exact Total 1,629,980 value. + storage: + r2: + provider: r2 + bucket: ledger-raw + key: raw/belgium/opgroeien/opgroeien-groeipakket-basic-caseload-2025-12/source_capture/aa3a6158006e05db0d326ed1e00836d623607a4d5108a9aa96a5323c1c124bd0/opgroeien-groeipakket-2025-12-dashboard-capture.zip + uri: r2://ledger-raw/raw/belgium/opgroeien/opgroeien-groeipakket-basic-caseload-2025-12/source_capture/aa3a6158006e05db0d326ed1e00836d623607a4d5108a9aa96a5323c1c124bd0/opgroeien-groeipakket-2025-12-dashboard-capture.zip diff --git a/db/data/opgroeien/groeipakket_basic_caseload_2025_12/opgroeien-groeipakket-2025-12-dashboard-capture.zip b/db/data/opgroeien/groeipakket_basic_caseload_2025_12/opgroeien-groeipakket-2025-12-dashboard-capture.zip new file mode 100644 index 00000000..9078cdad Binary files /dev/null and b/db/data/opgroeien/groeipakket_basic_caseload_2025_12/opgroeien-groeipakket-2025-12-dashboard-capture.zip differ diff --git a/db/data/opgroeien/groeipakket_basic_caseload_2025_12/opgroeien_groeipakket_basic_caseload_2025_12.csv b/db/data/opgroeien/groeipakket_basic_caseload_2025_12/opgroeien_groeipakket_basic_caseload_2025_12.csv new file mode 100644 index 00000000..b6f3480b --- /dev/null +++ b/db/data/opgroeien/groeipakket_basic_caseload_2025_12/opgroeien_groeipakket_basic_caseload_2025_12.csv @@ -0,0 +1,2 @@ +value_id,period,groeipakket.component,publication_status,entity_view,period_view,publication_view,groeipakket_view,basic_amount_view,retrieved_at,count,source_url +basic_amount_children,2025-12,basic_amount,provisional,Kinderen/Gezinnen=Kinderen,JJJJ/MM=2025/12,Voorlopige cijfers,Groeipakket=Groeipakket,"non-null; excludes Geen Groeipakket",2026-08-30,1629980,https://www.opgroeien.be/kennis/cijfers-en-onderzoek/groeipakket/cijfers-op-maat diff --git a/db/data/opgroeien/groeipakket_caseload_2025/manifest.yaml b/db/data/opgroeien/groeipakket_caseload_2025/manifest.yaml index 1295166b..ab3721c7 100644 --- a/db/data/opgroeien/groeipakket_caseload_2025/manifest.yaml +++ b/db/data/opgroeien/groeipakket_caseload_2025/manifest.yaml @@ -19,10 +19,11 @@ files: source_urls: - https://www.opgroeien.be/kennis/cijfers-en-onderzoek/groeipakket - https://www.opgroeien.be/kennis/cijfers-en-onderzoek/groeipakket/cijfers-op-maat - notes: Curated per-component Groeipakket caseload counts published by Opgroeien - (the Flemish government agency administering the Groeipakket) on its statistics - page. Each component carries its own published reference basis (end 2025, December - 2025, or school year 2025-2026). The basisbedrag child count is published only - as "more than 1.6 million" (a rounded lower bound), so it is omitted from the - child record set and recorded as a gap; the exact basisbedrag family count (930,010) + notes: Curated per-component Groeipakket administrative scheme caseload counts + published by Opgroeien (the Flemish government agency administering the + Groeipakket) on its statistics page. These are not resident BE2 counts. Each + component carries its own published reference basis (end 2025, December 2025, + or school year 2025-2026). The basisbedrag child count is published only as + "more than 1.6 million" (a rounded lower bound), so it is omitted from the child + record set and recorded as a gap; the exact basisbedrag family count (930,010) is published and retained. diff --git a/db/data/ostbelgien/child_benefit_caseload_2025_12/manifest.yaml b/db/data/ostbelgien/child_benefit_caseload_2025_12/manifest.yaml new file mode 100644 index 00000000..dd506e4a --- /dev/null +++ b/db/data/ostbelgien/child_benefit_caseload_2025_12/manifest.yaml @@ -0,0 +1,26 @@ +source_id: ostbelgien +package_id: ostbelgien-child-benefit-caseload-2025-12 +dataset: ostbelgien_child_benefit_caseload_2025_12 +publisher: Ministerium der Deutschsprachigen Gemeinschaft Belgiens +source_page: https://ostbelgienstatistik.be/desktopdefault.aspx/tabid-3748/6766_read-39090/ +table: Kindergeld in der Deutschsprachigen Gemeinschaft, Dezember 2025 +files: + 2025: + filename: ostbelgien_child_benefit_caseload_2025_12.csv + source_url: https://ostbelgienstatistik.be/desktopdefault.aspx/tabid-3748/6766_read-39090/ + sha256: 1fb13534cb93b039a1eeb380180a446d3343146289718b266ba751354a7d5a98 + size_bytes: 475 + fetched_at: '2026-08-30T12:26:22+00:00' + source_table: Official Ostbelgien Statistik December 2025 snapshot + source_urls: + - https://ostbelgienstatistik.be/desktopdefault.aspx/tabid-3748/6766_read-39090/ + notes: "Curated two-row transcription of the exact children and Empf\xE4nger counts\ + \ printed on the official HTML statistics page, audited on 2026-08-30. Automated\ + \ artifact capture was refused by the publisher with HTTP 403, so no claim is\ + \ made that this CSV is a verbatim page download." + storage: + r2: + provider: r2 + bucket: ledger-raw + key: raw/belgium/ostbelgien/ostbelgien-child-benefit-caseload-2025-12/2025/1fb13534cb93b039a1eeb380180a446d3343146289718b266ba751354a7d5a98/ostbelgien_child_benefit_caseload_2025_12.csv + uri: r2://ledger-raw/raw/belgium/ostbelgien/ostbelgien-child-benefit-caseload-2025-12/2025/1fb13534cb93b039a1eeb380180a446d3343146289718b266ba751354a7d5a98/ostbelgien_child_benefit_caseload_2025_12.csv diff --git a/db/data/ostbelgien/child_benefit_caseload_2025_12/ostbelgien_child_benefit_caseload_2025_12.csv b/db/data/ostbelgien/child_benefit_caseload_2025_12/ostbelgien_child_benefit_caseload_2025_12.csv new file mode 100644 index 00000000..93869e5e --- /dev/null +++ b/db/data/ostbelgien/child_benefit_caseload_2025_12/ostbelgien_child_benefit_caseload_2025_12.csv @@ -0,0 +1,3 @@ +value_id,period,ostbelgien.statistic,entity_view,source_label,retrieved_at,count,source_url +paid_children,2025-12,paid_children,Kinder,Kinder die Kindergeld im Dezember 2025 erhielten,2026-08-30,15533,https://ostbelgienstatistik.be/desktopdefault.aspx/tabid-3748/6766_read-39090/ +payment_recipients,2025-12,payment_recipients,Empfänger,Empfänger von Kindergeld im Dezember 2025,2026-08-30,8302,https://ostbelgienstatistik.be/desktopdefault.aspx/tabid-3748/6766_read-39090/ diff --git a/db/data/parlement_wallonie/child_benefit_partitions_2023_12/manifest.yaml b/db/data/parlement_wallonie/child_benefit_partitions_2023_12/manifest.yaml new file mode 100644 index 00000000..1024ba85 --- /dev/null +++ b/db/data/parlement_wallonie/child_benefit_partitions_2023_12/manifest.yaml @@ -0,0 +1,41 @@ +source_id: parlement_wallonie +package_id: parlement-wallonie-child-benefit-partitions-2023-12 +dataset: parlement_wallonie_child_benefit_partitions_2023_12 +publisher: Parlement de Wallonie, answer supplied by the Walloon Minister of Health + and Social Action +source_page: https://www.parlement-wallonie.be/pwpages?iddoc=138138&p=interp-questions-voir&type=28 +table: Walloon child-benefit households and children, December 2023 +files: + 2023: + filename: parlement_wallonie_child_benefit_partitions_2023_12.csv + source_url: https://nautilus.parlement-wallon.be/Archives_ARQE/3423.pdf + sha256: 1ffeab402feb4a597facdc749aabb85199dc9649f124ce49477320d7c4cd6d1e + size_bytes: 1357 + fetched_at: '2026-08-30T12:26:22+00:00' + source_table: Four mutually exclusive household-group tables in the official answer + notes: Curated transcription of all four publisher-authored table-total rows, + retaining households, children aged 0-17, children aged 18-24, total children, + page number, official URL, and the verbatim PDF digest for each household-type + and social-supplement category. Chronicle emits only these source rows; it does + not construct an all-scope total. + storage: + r2: + provider: r2 + bucket: ledger-raw + key: raw/belgium/parlement_wallonie/parlement-wallonie-child-benefit-partitions-2023-12/2023/1ffeab402feb4a597facdc749aabb85199dc9649f124ce49477320d7c4cd6d1e/parlement_wallonie_child_benefit_partitions_2023_12.csv + uri: r2://ledger-raw/raw/belgium/parlement_wallonie/parlement-wallonie-child-benefit-partitions-2023-12/2023/1ffeab402feb4a597facdc749aabb85199dc9649f124ce49477320d7c4cd6d1e/parlement_wallonie_child_benefit_partitions_2023_12.csv + source_capture: + filename: parlement-wallonie-child-benefit-partitions-2023-12.pdf + source_url: https://nautilus.parlement-wallon.be/Archives_ARQE/3423.pdf + sha256: 92b8dee4e25b91f891f78f60179abe881c5ad9d7d9b5436c767cf69f9dc55651 + size_bytes: 70032 + fetched_at: '2026-08-30T12:21:36+00:00' + notes: Verbatim official two-page PDF answer. Its four December 2023 tables distinguish + single-parent versus other households and presence versus absence of a social + supplement. + storage: + r2: + provider: r2 + bucket: ledger-raw + key: raw/belgium/parlement_wallonie/parlement-wallonie-child-benefit-partitions-2023-12/source_capture/92b8dee4e25b91f891f78f60179abe881c5ad9d7d9b5436c767cf69f9dc55651/parlement-wallonie-child-benefit-partitions-2023-12.pdf + uri: r2://ledger-raw/raw/belgium/parlement_wallonie/parlement-wallonie-child-benefit-partitions-2023-12/source_capture/92b8dee4e25b91f891f78f60179abe881c5ad9d7d9b5436c767cf69f9dc55651/parlement-wallonie-child-benefit-partitions-2023-12.pdf diff --git a/db/data/parlement_wallonie/child_benefit_partitions_2023_12/parlement-wallonie-child-benefit-partitions-2023-12.pdf b/db/data/parlement_wallonie/child_benefit_partitions_2023_12/parlement-wallonie-child-benefit-partitions-2023-12.pdf new file mode 100644 index 00000000..e19c42b2 Binary files /dev/null and b/db/data/parlement_wallonie/child_benefit_partitions_2023_12/parlement-wallonie-child-benefit-partitions-2023-12.pdf differ diff --git a/db/data/parlement_wallonie/child_benefit_partitions_2023_12/parlement_wallonie_child_benefit_partitions_2023_12.csv b/db/data/parlement_wallonie/child_benefit_partitions_2023_12/parlement_wallonie_child_benefit_partitions_2023_12.csv new file mode 100644 index 00000000..89f9523d --- /dev/null +++ b/db/data/parlement_wallonie/child_benefit_partitions_2023_12/parlement_wallonie_child_benefit_partitions_2023_12.csv @@ -0,0 +1,5 @@ +value_id,period,parlement_wallonie.household_type,parlement_wallonie.social_supplement_status,households,children_0_17,children_18_24,children_total,source_row_label,source_pdf_page,source_capture_sha256,source_url +single_parent_with_social_supplement,2023-12,single_parent,with_social_supplement,89575,118421,30748,149169,Ménages monoparentaux avec suppléments sociaux,1,92b8dee4e25b91f891f78f60179abe881c5ad9d7d9b5436c767cf69f9dc55651,https://nautilus.parlement-wallon.be/Archives_ARQE/3423.pdf +single_parent_without_social_supplement,2023-12,single_parent,without_social_supplement,24535,25316,13069,38385,Ménages monoparentaux sans suppléments sociaux,1,92b8dee4e25b91f891f78f60179abe881c5ad9d7d9b5436c767cf69f9dc55651,https://nautilus.parlement-wallon.be/Archives_ARQE/3423.pdf +other_household_with_social_supplement,2023-12,other_household,with_social_supplement,90308,148409,28820,177229,Autres ménages avec suppléments sociaux,1,92b8dee4e25b91f891f78f60179abe881c5ad9d7d9b5436c767cf69f9dc55651,https://nautilus.parlement-wallon.be/Archives_ARQE/3423.pdf +other_household_without_social_supplement,2023-12,other_household,without_social_supplement,308949,430670,114772,545442,Autres ménages sans suppléments sociaux,1,92b8dee4e25b91f891f78f60179abe881c5ad9d7d9b5436c767cf69f9dc55651,https://nautilus.parlement-wallon.be/Archives_ARQE/3423.pdf diff --git a/db/data/sfpd/grapa_monthly_statistics_2025_02/fr_stat_2502.pdf b/db/data/sfpd/grapa_monthly_statistics_2025_02/fr_stat_2502.pdf new file mode 100644 index 00000000..3c76ba75 Binary files /dev/null and b/db/data/sfpd/grapa_monthly_statistics_2025_02/fr_stat_2502.pdf differ diff --git a/db/data/sfpd/grapa_monthly_statistics_2025_02/manifest.yaml b/db/data/sfpd/grapa_monthly_statistics_2025_02/manifest.yaml new file mode 100644 index 00000000..92a5a4bb --- /dev/null +++ b/db/data/sfpd/grapa_monthly_statistics_2025_02/manifest.yaml @@ -0,0 +1,39 @@ +source_id: sfpd +package_id: sfpd-grapa-monthly-statistics-2025-02 +dataset: sfpd_grapa_monthly_statistics_2025_02 +source_page: https://www.sfpd.fgov.be/fr/centre-de-connaissances/statistiques +table: "Statistique mensuelle des prestations sociales - F\xE9vrier 2025, table 2.4.1" +files: + 2025: + filename: sfpd_grapa_monthly_2025_01.csv + source_url: https://www.sfpd.fgov.be/files/3432/fr_stat_2502.pdf + sha256: 6ff9d5d99881b48be68343cb259fb86d29761e020b39afed5df217bb6fc5ce01 + size_bytes: 400 + fetched_at: '2026-08-30T12:08:46+00:00' + source_table: "Statistique mensuelle des prestations sociales - F\xE9vrier 2025,\ + \ table 2.4.1" + notes: Long-form transcription of the January 2025 total, men, and women rows + from SFPD table 2.4.1. Counts and euro amounts reconcile exactly across the + two published sex partitions. The exact publisher PDF is retained as source_capture + below. + storage: + r2: + provider: r2 + bucket: ledger-raw + key: raw/belgium/sfpd/sfpd-grapa-monthly-statistics-2025-02/2025/6ff9d5d99881b48be68343cb259fb86d29761e020b39afed5df217bb6fc5ce01/sfpd_grapa_monthly_2025_01.csv + uri: r2://ledger-raw/raw/belgium/sfpd/sfpd-grapa-monthly-statistics-2025-02/2025/6ff9d5d99881b48be68343cb259fb86d29761e020b39afed5df217bb6fc5ce01/sfpd_grapa_monthly_2025_01.csv + source_capture: + filename: fr_stat_2502.pdf + source_url: https://www.sfpd.fgov.be/files/3432/fr_stat_2502.pdf + sha256: 0d6173e71a0e9c2cd220cd024a5b5fecbb6ca79f8b791cbd2b3368e7f8412106 + size_bytes: 2319705 + fetched_at: '2026-08-30T12:08:46+00:00' + notes: Verbatim SFPD monthly-statistics PDF. Printed page 36, table 2.4.1, reports + January 2025 GRAPA beneficiaries and monthly payments for the total population + and mutually exclusive men and women partitions. + storage: + r2: + provider: r2 + bucket: ledger-raw + key: raw/belgium/sfpd/sfpd-grapa-monthly-statistics-2025-02/source_capture/0d6173e71a0e9c2cd220cd024a5b5fecbb6ca79f8b791cbd2b3368e7f8412106/fr_stat_2502.pdf + uri: r2://ledger-raw/raw/belgium/sfpd/sfpd-grapa-monthly-statistics-2025-02/source_capture/0d6173e71a0e9c2cd220cd024a5b5fecbb6ca79f8b791cbd2b3368e7f8412106/fr_stat_2502.pdf diff --git a/db/data/sfpd/grapa_monthly_statistics_2025_02/sfpd_grapa_monthly_2025_01.csv b/db/data/sfpd/grapa_monthly_statistics_2025_02/sfpd_grapa_monthly_2025_01.csv new file mode 100644 index 00000000..b57c9db0 --- /dev/null +++ b/db/data/sfpd/grapa_monthly_statistics_2025_02/sfpd_grapa_monthly_2025_01.csv @@ -0,0 +1,4 @@ +sex,period,reference_basis,beneficiaries,monthly_amount_eur,source_url +all,2025-01,regular_payment_snapshot,118262,85039735.46,https://www.sfpd.fgov.be/files/3432/fr_stat_2502.pdf +male,2025-01,regular_payment_snapshot,42346,28338945.37,https://www.sfpd.fgov.be/files/3432/fr_stat_2502.pdf +female,2025-01,regular_payment_snapshot,75916,56700790.09,https://www.sfpd.fgov.be/files/3432/fr_stat_2502.pdf diff --git a/packages/iriscare/child_benefit_caseload_2025_12/source_package.yaml b/packages/iriscare/child_benefit_caseload_2025_12/source_package.yaml new file mode 100644 index 00000000..b7332e25 --- /dev/null +++ b/packages/iriscare/child_benefit_caseload_2025_12/source_package.yaml @@ -0,0 +1,216 @@ +schema_version: ledger.source_package.v1 +package_id: iriscare-child-benefit-caseload-2025-12 +label: Iriscare December 2025 child-benefit caseload +artifact: + source_name: iriscare_child_benefit_dashboard + source_table: Official Iriscare dashboard query for LegalPeriod 202512 + resource_package: db + resource_directory: data/iriscare/child_benefit_caseload_2025_12 + manifest: manifest.yaml + vintage: child_benefit_caseload_2025_12 + extracted_at: '2026-08-30' + extraction_method: >- + curated capture of the official embedded-dashboard result with its legal + period filter retained in each source row + parser: delimited_text_full_rows + artifact_year: 2025 + sheet_name: iriscare_child_benefit_caseload_2025_12 +record_sets: +- record_set_id: iriscare.child_benefit.month2025_12.entitled_children + provenance_class: administrative + record_set_spec_id: iriscare.child_benefit.entitled_children.v1 + source_record_id_prefix: iriscare.child_benefit.month2025_12.entitled_children + sheet_name: iriscare_child_benefit_caseload_2025_12 + period_type: month + period: '2025-12' + period_coverage: &period_coverage + basis: calendar + source_period_label: LegalPeriod=202512 + start_date: '2025-12-01' + end_date: '2025-12-31' + notes: >- + Iriscare identifies this as the rights month. Payments associated with + allocataires occur in the following month. + geography_id: BE-IRISCARE-CHILD-BENEFIT-SCHEME + geography_level: statistical_scope + geography_name: Iriscare child-benefit administrative scheme caseload + geography_vintage: IRISCARE_CHILD_BENEFIT_ADMIN_SCOPE_2025 + entity: person + entity_role: child_benefit_entitled_child + domain: child_benefit + groupby_dimension: iriscare.statistic + shared_filters: &shared_filters + publication_status: provisional + shared_constraints: &shared_constraints + - variable: publication_status + operator: == + value: provisional + label: Iriscare publication status + rows: + - value_id: entitled_children + label: Children entitled to child benefit + ordinal: 0 + row_number: 2 + expected_row_header_column: A + expected_row_header: entitled_children + table_record_kind: total + filters: + iriscare.statistic: entitled_children + constraints: + - variable: iriscare.statistic + operator: == + value: entitled_children + label: Iriscare statistic + guard_cells: + - column: A + row: 2 + expected_value: entitled_children + label: Source result identifier + - column: B + row: 2 + expected_value: 2025-12 + label: Rights period + - column: C + row: 2 + expected_value: entitled_children + label: Normalized statistic + - column: D + row: 2 + expected_value: provisional + label: Publication status + - column: E + row: 2 + expected_value: Children + label: Dashboard measure view + - column: F + row: 2 + expected_value: LegalPeriod=202512 + label: Dashboard legal-period filter + - column: G + row: 2 + expected_value: children + label: Publisher entity label + - column: H + row: 2 + expected_value: '2026-08-30' + label: Retrieval date + - column: J + row: 2 + expected_value: https://stat.iriscare.brussels/home/enfants-et-familles/allocations-familiales/statistiques-generales-allocations-familiales/ + label: Official dashboard URL + measures: + - measure_id: children + label: Children entitled to child benefit + ordinal: 0 + column: I + source_column_id: count + expected_column_header_row: 1 + expected_column_header: count + concept: iriscare.child_benefit_entitled_children + source_concept: iriscare.child_benefit.dashboard.entitled_children + concept_relation: source_label + concept_authority: iriscare + concept_evidence_url: https://stat.iriscare.brussels/home/enfants-et-familles/allocations-familiales/statistiques-generales-allocations-familiales/ + concept_evidence_notes: >- + The dashboard reports children for LegalPeriod 202512. The official 2025 + release independently prints the same December child count. Its captured + municipality table includes Flemish Region, Walloon Region, outside + Belgium, and unknown rows, so this is an Iriscare-system caseload rather + than a count of BE1 residents. This publisher-specific source label makes + no simulator or legal-rule mapping. + unit: count + aggregation: sum + expected_cell_type: number +- record_set_id: iriscare.child_benefit.month2025_12.payment_recipients + provenance_class: administrative + record_set_spec_id: iriscare.child_benefit.payment_recipients.v1 + source_record_id_prefix: iriscare.child_benefit.month2025_12.payment_recipients + sheet_name: iriscare_child_benefit_caseload_2025_12 + period_type: month + period: '2025-12' + period_coverage: *period_coverage + geography_id: BE-IRISCARE-CHILD-BENEFIT-SCHEME + geography_level: statistical_scope + geography_name: Iriscare child-benefit administrative scheme caseload + geography_vintage: IRISCARE_CHILD_BENEFIT_ADMIN_SCOPE_2025 + entity: person + entity_role: child_benefit_payment_recipient + domain: child_benefit + groupby_dimension: iriscare.statistic + shared_filters: *shared_filters + shared_constraints: *shared_constraints + rows: + - value_id: payment_recipients + label: Associated child-benefit payment recipients + ordinal: 0 + row_number: 3 + expected_row_header_column: A + expected_row_header: payment_recipients + table_record_kind: total + filters: + iriscare.statistic: payment_recipients + constraints: + - variable: iriscare.statistic + operator: == + value: payment_recipients + label: Iriscare statistic + guard_cells: + - column: A + row: 3 + expected_value: payment_recipients + label: Source result identifier + - column: B + row: 3 + expected_value: 2025-12 + label: Rights period + - column: C + row: 3 + expected_value: payment_recipients + label: Normalized statistic + - column: D + row: 3 + expected_value: provisional + label: Publication status + - column: E + row: 3 + expected_value: Beneficiaries + label: Dashboard measure view + - column: F + row: 3 + expected_value: LegalPeriod=202512 + label: Dashboard legal-period filter + - column: G + row: 3 + expected_value: allocataires + label: Publisher entity label + - column: H + row: 3 + expected_value: '2026-08-30' + label: Retrieval date + - column: J + row: 3 + expected_value: https://stat.iriscare.brussels/home/enfants-et-familles/allocations-familiales/statistiques-generales-allocations-familiales/ + label: Official dashboard URL + measures: + - measure_id: payment_recipients + label: Associated child-benefit payment recipients + ordinal: 0 + column: I + source_column_id: count + expected_column_header_row: 1 + expected_column_header: count + concept: iriscare.child_benefit_payment_recipients + source_concept: iriscare.child_benefit.dashboard.allocataires + concept_relation: source_label + concept_authority: iriscare + concept_evidence_url: https://stat.iriscare.brussels/home/enfants-et-familles/allocations-familiales/statistiques-generales-allocations-familiales/ + concept_evidence_notes: >- + Iriscare defines allocataires as associated people to whom benefit was + paid in the following month. The captured municipality table includes + Flemish Region, Walloon Region, outside Belgium, and unknown rows, so this + is an Iriscare-system caseload rather than a count of BE1 residents. This + is a person count, not a family or household count, and carries no + cross-system concept mapping. + unit: count + aggregation: sum + expected_cell_type: number diff --git a/packages/opgroeien/groeipakket_basic_caseload_2025_12/source_package.yaml b/packages/opgroeien/groeipakket_basic_caseload_2025_12/source_package.yaml new file mode 100644 index 00000000..c500e0a6 --- /dev/null +++ b/packages/opgroeien/groeipakket_basic_caseload_2025_12/source_package.yaml @@ -0,0 +1,130 @@ +schema_version: ledger.source_package.v1 +package_id: opgroeien-groeipakket-basic-caseload-2025-12 +label: Opgroeien December 2025 Groeipakket basic-amount child caseload +artifact: + source_name: opgroeien_groeipakket_dashboard + source_table: Official Groeipakket dashboard query for basic-amount children + resource_package: db + resource_directory: data/opgroeien/groeipakket_basic_caseload_2025_12 + manifest: manifest.yaml + vintage: groeipakket_administrative_scheme_scope_2025 + extracted_at: '2026-08-30' + extraction_method: >- + curated capture of the official interactive-dashboard result with exact + query filters retained in the source row + parser: delimited_text_full_rows + artifact_year: 2025 + sheet_name: opgroeien_groeipakket_basic_caseload_2025_12 +record_sets: +- record_set_id: opgroeien.groeipakket.month2025_12.basic_amount.children + provenance_class: administrative + record_set_spec_id: opgroeien.groeipakket.basic_amount.children.v1 + source_record_id_prefix: opgroeien.groeipakket.month2025_12.basic_amount.children + sheet_name: opgroeien_groeipakket_basic_caseload_2025_12 + period_type: month + period: '2025-12' + period_coverage: + basis: calendar + source_period_label: 2025/12 + start_date: '2025-12-01' + end_date: '2025-12-31' + notes: Opgroeien identifies the selected month as the rights period. + geography_id: BE-GROEIPAKKET-SCHEME + geography_level: statistical_scope + geography_name: Groeipakket administrative scheme caseload + geography_vintage: GROEIPAKKET_ADMINISTRATIVE_SCOPE_2025 + entity: person + entity_role: child_benefit_recipient + domain: child_benefit + groupby_dimension: groeipakket.component + shared_filters: + publication_status: provisional + shared_constraints: + - variable: publication_status + operator: == + value: provisional + label: Opgroeien publication status + rows: + - value_id: basic_amount_children + label: Children receiving a Groeipakket basic amount + ordinal: 0 + row_number: 2 + expected_row_header_column: A + expected_row_header: basic_amount_children + table_record_kind: total + filters: + groeipakket.component: basic_amount + constraints: + - variable: groeipakket.component + operator: == + value: basic_amount + label: Groeipakket component + guard_cells: + - column: A + row: 2 + expected_value: basic_amount_children + label: Source result identifier + - column: B + row: 2 + expected_value: 2025-12 + label: Rights period + - column: C + row: 2 + expected_value: basic_amount + label: Normalized component + - column: D + row: 2 + expected_value: provisional + label: Publication status + - column: E + row: 2 + expected_value: Kinderen/Gezinnen=Kinderen + label: Dashboard entity view + - column: F + row: 2 + expected_value: JJJJ/MM=2025/12 + label: Dashboard period view + - column: G + row: 2 + expected_value: Voorlopige cijfers + label: Dashboard provisional-figures view + - column: H + row: 2 + expected_value: Groeipakket=Groeipakket + label: Dashboard Groeipakket filter + - column: I + row: 2 + expected_value: non-null; excludes Geen Groeipakket + label: Dashboard basic-amount filter + - column: J + row: 2 + expected_value: '2026-08-30' + label: Retrieval date + - column: L + row: 2 + expected_value: https://www.opgroeien.be/kennis/cijfers-en-onderzoek/groeipakket/cijfers-op-maat + label: Official dashboard URL + measures: + - measure_id: children + label: Children receiving a Groeipakket basic amount + ordinal: 0 + column: K + source_column_id: count + expected_column_header_row: 1 + expected_column_header: count + concept: opgroeien.groeipakket_basic_amount_children + source_concept: opgroeien.groeipakket.dashboard.basic_amount.children + concept_relation: source_label + concept_authority: opgroeien + concept_evidence_url: https://www.opgroeien.be/kennis/cijfers-en-onderzoek/groeipakket/cijfers-op-maat + concept_evidence_notes: >- + The official dashboard result is scoped to children, rights period + 2025/12, provisional figures, Groeipakket, and a non-null basic amount + other than "Geen Groeipakket". The captured table also includes bilateral + agreements and difference-payment categories, so this is a scheme-wide + administrative caseload, not a count of BE2 residents. This + publisher-specific source label does not assert equivalence to any + simulator or legal-rule concept. + unit: count + aggregation: sum + expected_cell_type: number diff --git a/packages/opgroeien/groeipakket_caseload_2025/source_package.yaml b/packages/opgroeien/groeipakket_caseload_2025/source_package.yaml index 6ede7b81..fb22751e 100644 --- a/packages/opgroeien/groeipakket_caseload_2025/source_package.yaml +++ b/packages/opgroeien/groeipakket_caseload_2025/source_package.yaml @@ -1,6 +1,6 @@ schema_version: ledger.source_package.v1 package_id: opgroeien-groeipakket-caseload-2025 -label: Opgroeien Groeipakket 2025 Flemish child benefit caseload by component +label: Opgroeien Groeipakket 2025 administrative scheme caseload by component artifact: source_name: opgroeien_groeipakket source_table: Groeipakket caseload by benefit component, 2025 @@ -21,10 +21,10 @@ record_sets: sheet_name: opgroeien_groeipakket_caseload_2025 period_type: calendar_year period: 2025 - geography_id: BE2 - geography_level: nuts1 - geography_name: Flemish Region - geography_vintage: NUTS_2024 + geography_id: BE-GROEIPAKKET-SCHEME + geography_level: statistical_scope + geography_name: Groeipakket administrative scheme caseload + geography_vintage: GROEIPAKKET_ADMINISTRATIVE_SCOPE_2025 entity: person entity_role: benefit_recipient domain: child_benefit @@ -132,7 +132,8 @@ record_sets: component. Reference basis differs by component (December 2025 for social and orphan supplements, end 2025 for care, foster-care and support supplements, school year 2025-2026 for the school allowance); the exact - basis for each row is preserved in the reference_basis column. + basis for each row is preserved in the reference_basis column. These are + Groeipakket administrative scheme caseloads, not counts of BE2 residents. unit: count aggregation: sum expected_cell_type: number @@ -143,10 +144,10 @@ record_sets: sheet_name: opgroeien_groeipakket_caseload_2025 period_type: calendar_year period: 2025 - geography_id: BE2 - geography_level: nuts1 - geography_name: Flemish Region - geography_vintage: NUTS_2024 + geography_id: BE-GROEIPAKKET-SCHEME + geography_level: statistical_scope + geography_name: Groeipakket administrative scheme caseload + geography_vintage: GROEIPAKKET_ADMINISTRATIVE_SCOPE_2025 entity: household entity_role: benefit_recipient domain: child_benefit @@ -239,7 +240,8 @@ record_sets: Opgroeien publishes the number of families receiving each Groeipakket component. The basisbedrag family count (930,010, end 2025) is published exactly and included here; other rows carry the same reference basis as the - corresponding child caseload row. + corresponding child caseload row. These are Groeipakket administrative + scheme caseloads, not counts of BE2 resident families. unit: count aggregation: sum expected_cell_type: number diff --git a/packages/ostbelgien/child_benefit_caseload_2025_12/source_package.yaml b/packages/ostbelgien/child_benefit_caseload_2025_12/source_package.yaml new file mode 100644 index 00000000..c8eaf32d --- /dev/null +++ b/packages/ostbelgien/child_benefit_caseload_2025_12/source_package.yaml @@ -0,0 +1,184 @@ +schema_version: ledger.source_package.v1 +package_id: ostbelgien-child-benefit-caseload-2025-12 +label: Ostbelgien December 2025 child-benefit caseload +artifact: + source_name: ostbelgien_child_benefit_statistics + source_table: Official Ostbelgien Statistik December 2025 snapshot + resource_package: db + resource_directory: data/ostbelgien/child_benefit_caseload_2025_12 + manifest: manifest.yaml + vintage: child_benefit_caseload_2025_12 + extracted_at: '2026-08-30' + extraction_method: >- + curated transcription of the exact counts printed on the official HTML + page; automated byte capture was refused by the publisher with HTTP 403 + parser: delimited_text_full_rows + artifact_year: 2025 + sheet_name: ostbelgien_child_benefit_caseload_2025_12 +record_sets: +- record_set_id: ostbelgien.child_benefit.month2025_12.paid_children + provenance_class: administrative + record_set_spec_id: ostbelgien.child_benefit.paid_children.v1 + source_record_id_prefix: ostbelgien.child_benefit.month2025_12.paid_children + sheet_name: ostbelgien_child_benefit_caseload_2025_12 + period_type: month + period: '2025-12' + period_coverage: &period_coverage + basis: calendar + source_period_label: Dezember 2025 + start_date: '2025-12-01' + end_date: '2025-12-31' + notes: The official statistics page labels the figures as December 2025. + geography_id: BE-DG + geography_level: statistical_scope + geography_name: German-speaking Community child-benefit system + geography_vintage: child_benefit_scope_2025 + entity: person + entity_role: child_benefit_paid_child + domain: child_benefit + groupby_dimension: ostbelgien.statistic + rows: + - value_id: paid_children + label: Children paid child benefit + ordinal: 0 + row_number: 2 + expected_row_header_column: A + expected_row_header: paid_children + table_record_kind: total + filters: + ostbelgien.statistic: paid_children + constraints: + - variable: ostbelgien.statistic + operator: == + value: paid_children + label: Ostbelgien statistic + guard_cells: + - column: A + row: 2 + expected_value: paid_children + label: Source result identifier + - column: B + row: 2 + expected_value: 2025-12 + label: Reference month + - column: C + row: 2 + expected_value: paid_children + label: Normalized statistic + - column: D + row: 2 + expected_value: Kinder + label: Publisher entity label + - column: E + row: 2 + expected_value: Kinder die Kindergeld im Dezember 2025 erhielten + label: Source description + - column: F + row: 2 + expected_value: '2026-08-30' + label: Retrieval date + - column: H + row: 2 + expected_value: https://ostbelgienstatistik.be/desktopdefault.aspx/tabid-3748/6766_read-39090/ + label: Official statistics URL + measures: + - measure_id: children + label: Children paid child benefit + ordinal: 0 + column: G + source_column_id: count + expected_column_header_row: 1 + expected_column_header: count + concept: ostbelgien.child_benefit_paid_children + source_concept: ostbelgien.kindergeld.paid_children + concept_relation: source_label + concept_authority: ostbelgien + concept_evidence_url: https://ostbelgienstatistik.be/desktopdefault.aspx/tabid-3748/6766_read-39090/ + concept_evidence_notes: >- + The official page prints the number of children receiving Kindergeld in + December 2025. The publisher warns that supplement categories can + overlap, so this fact uses the unique child-benefit count only. It has no + simulator or legal-rule concept mapping. + unit: count + aggregation: sum + expected_cell_type: number +- record_set_id: ostbelgien.child_benefit.month2025_12.payment_recipients + provenance_class: administrative + record_set_spec_id: ostbelgien.child_benefit.payment_recipients.v1 + source_record_id_prefix: ostbelgien.child_benefit.month2025_12.payment_recipients + sheet_name: ostbelgien_child_benefit_caseload_2025_12 + period_type: month + period: '2025-12' + period_coverage: *period_coverage + geography_id: BE-DG + geography_level: statistical_scope + geography_name: German-speaking Community child-benefit system + geography_vintage: child_benefit_scope_2025 + entity: person + entity_role: child_benefit_payment_recipient + domain: child_benefit + groupby_dimension: ostbelgien.statistic + rows: + - value_id: payment_recipients + label: Child-benefit payment recipients + ordinal: 0 + row_number: 3 + expected_row_header_column: A + expected_row_header: payment_recipients + table_record_kind: total + filters: + ostbelgien.statistic: payment_recipients + constraints: + - variable: ostbelgien.statistic + operator: == + value: payment_recipients + label: Ostbelgien statistic + guard_cells: + - column: A + row: 3 + expected_value: payment_recipients + label: Source result identifier + - column: B + row: 3 + expected_value: 2025-12 + label: Reference month + - column: C + row: 3 + expected_value: payment_recipients + label: Normalized statistic + - column: D + row: 3 + expected_value: Empfänger + label: Publisher entity label + - column: E + row: 3 + expected_value: Empfänger von Kindergeld im Dezember 2025 + label: Source description + - column: F + row: 3 + expected_value: '2026-08-30' + label: Retrieval date + - column: H + row: 3 + expected_value: https://ostbelgienstatistik.be/desktopdefault.aspx/tabid-3748/6766_read-39090/ + label: Official statistics URL + measures: + - measure_id: payment_recipients + label: Child-benefit payment recipients + ordinal: 0 + column: G + source_column_id: count + expected_column_header_row: 1 + expected_column_header: count + concept: ostbelgien.child_benefit_payment_recipients + source_concept: ostbelgien.kindergeld.empfaenger + concept_relation: source_label + concept_authority: ostbelgien + concept_evidence_url: https://ostbelgienstatistik.be/desktopdefault.aspx/tabid-3748/6766_read-39090/ + concept_evidence_notes: >- + The official page separately prints Empfänger. This fact treats that as + a payment-recipient person count, not children, families, or households, + and makes no cross-system concept alignment claim. + unit: count + aggregation: sum + expected_cell_type: number diff --git a/packages/parlement_wallonie/child_benefit_partitions_2023_12/source_package.yaml b/packages/parlement_wallonie/child_benefit_partitions_2023_12/source_package.yaml new file mode 100644 index 00000000..434f96df --- /dev/null +++ b/packages/parlement_wallonie/child_benefit_partitions_2023_12/source_package.yaml @@ -0,0 +1,228 @@ +schema_version: ledger.source_package.v1 +package_id: parlement-wallonie-child-benefit-partitions-2023-12 +label: Walloon Parliament December 2023 child-benefit household partitions +artifact: + source_name: parlement_wallonie_child_benefit_response + source_table: Four household-group tables in the official ministerial answer + resource_package: db + resource_directory: data/parlement_wallonie/child_benefit_partitions_2023_12 + manifest: manifest.yaml + vintage: child_benefit_partitions_2023_12 + extracted_at: '2026-08-30' + extraction_method: >- + row-faithful transcription of the four publisher-authored table totals; + the verbatim official PDF is retained as a hash-pinned source capture + parser: delimited_text_full_rows + artifact_year: 2023 + sheet_name: parlement_wallonie_child_benefit_partitions_2023_12 +record_sets: +- record_set_id: parlement_wallonie.child_benefit.month2023_12.children_by_household_group + provenance_class: administrative + record_set_spec_id: parlement_wallonie.child_benefit.children_by_household_group.v1 + source_record_id_prefix: parlement_wallonie.child_benefit.month2023_12.children + sheet_name: parlement_wallonie_child_benefit_partitions_2023_12 + period_type: month + period: '2023-12' + period_coverage: &period_coverage + basis: calendar + source_period_label: décembre 2023 + start_date: '2023-12-01' + end_date: '2023-12-31' + notes: >- + The official answer says the tables carry family and child information + for December 2023. + geography_id: BE-WALLOON-FRENCH + geography_level: statistical_scope + geography_name: French-language Walloon child-benefit system + geography_vintage: child_benefit_scope_2023 + entity: person + entity_role: child_benefit_recipient_child + domain: child_benefit + groupby_dimension: parlement_wallonie.household_type + rows: &partition_rows + - value_id: single_parent_with_social_supplement + label: Single-parent households with social supplements + ordinal: 0 + row_number: 2 + expected_row_header_column: A + expected_row_header: single_parent_with_social_supplement + table_record_kind: detail + filters: + parlement_wallonie.household_type: single_parent + parlement_wallonie.social_supplement_status: with_social_supplement + constraints: + - variable: parlement_wallonie.household_type + operator: == + value: single_parent + label: Household type + - variable: parlement_wallonie.social_supplement_status + operator: == + value: with_social_supplement + label: Social-supplement status + guard_cells: + - {column: A, row: 2, expected_value: single_parent_with_social_supplement, label: Source row identifier} + - {column: B, row: 2, expected_value: 2023-12, label: Reference month} + - {column: C, row: 2, expected_value: single_parent, label: Household type} + - {column: D, row: 2, expected_value: with_social_supplement, label: Social-supplement status} + - {column: E, row: 2, expected_value: 89575, label: Published households} + - {column: F, row: 2, expected_value: 118421, label: Published children aged 0-17} + - {column: G, row: 2, expected_value: 30748, label: Published children aged 18-24} + - {column: H, row: 2, expected_value: 149169, label: Published total children} + - {column: I, row: 2, expected_value: Ménages monoparentaux avec suppléments sociaux, label: Publisher row heading} + - {column: J, row: 2, expected_value: 1, label: PDF page} + - {column: K, row: 2, expected_value: 92b8dee4e25b91f891f78f60179abe881c5ad9d7d9b5436c767cf69f9dc55651, label: Verbatim PDF SHA-256} + - {column: L, row: 2, expected_value: https://nautilus.parlement-wallon.be/Archives_ARQE/3423.pdf, label: Official PDF URL} + - value_id: single_parent_without_social_supplement + label: Single-parent households without social supplements + ordinal: 1 + row_number: 3 + expected_row_header_column: A + expected_row_header: single_parent_without_social_supplement + table_record_kind: detail + filters: + parlement_wallonie.household_type: single_parent + parlement_wallonie.social_supplement_status: without_social_supplement + constraints: + - variable: parlement_wallonie.household_type + operator: == + value: single_parent + label: Household type + - variable: parlement_wallonie.social_supplement_status + operator: == + value: without_social_supplement + label: Social-supplement status + guard_cells: + - {column: A, row: 3, expected_value: single_parent_without_social_supplement, label: Source row identifier} + - {column: B, row: 3, expected_value: 2023-12, label: Reference month} + - {column: C, row: 3, expected_value: single_parent, label: Household type} + - {column: D, row: 3, expected_value: without_social_supplement, label: Social-supplement status} + - {column: E, row: 3, expected_value: 24535, label: Published households} + - {column: F, row: 3, expected_value: 25316, label: Published children aged 0-17} + - {column: G, row: 3, expected_value: 13069, label: Published children aged 18-24} + - {column: H, row: 3, expected_value: 38385, label: Published total children} + - {column: I, row: 3, expected_value: Ménages monoparentaux sans suppléments sociaux, label: Publisher row heading} + - {column: J, row: 3, expected_value: 1, label: PDF page} + - {column: K, row: 3, expected_value: 92b8dee4e25b91f891f78f60179abe881c5ad9d7d9b5436c767cf69f9dc55651, label: Verbatim PDF SHA-256} + - {column: L, row: 3, expected_value: https://nautilus.parlement-wallon.be/Archives_ARQE/3423.pdf, label: Official PDF URL} + - value_id: other_household_with_social_supplement + label: Other households with social supplements + ordinal: 2 + row_number: 4 + expected_row_header_column: A + expected_row_header: other_household_with_social_supplement + table_record_kind: detail + filters: + parlement_wallonie.household_type: other_household + parlement_wallonie.social_supplement_status: with_social_supplement + constraints: + - variable: parlement_wallonie.household_type + operator: == + value: other_household + label: Household type + - variable: parlement_wallonie.social_supplement_status + operator: == + value: with_social_supplement + label: Social-supplement status + guard_cells: + - {column: A, row: 4, expected_value: other_household_with_social_supplement, label: Source row identifier} + - {column: B, row: 4, expected_value: 2023-12, label: Reference month} + - {column: C, row: 4, expected_value: other_household, label: Household type} + - {column: D, row: 4, expected_value: with_social_supplement, label: Social-supplement status} + - {column: E, row: 4, expected_value: 90308, label: Published households} + - {column: F, row: 4, expected_value: 148409, label: Published children aged 0-17} + - {column: G, row: 4, expected_value: 28820, label: Published children aged 18-24} + - {column: H, row: 4, expected_value: 177229, label: Published total children} + - {column: I, row: 4, expected_value: Autres ménages avec suppléments sociaux, label: Publisher row heading} + - {column: J, row: 4, expected_value: 1, label: PDF page} + - {column: K, row: 4, expected_value: 92b8dee4e25b91f891f78f60179abe881c5ad9d7d9b5436c767cf69f9dc55651, label: Verbatim PDF SHA-256} + - {column: L, row: 4, expected_value: https://nautilus.parlement-wallon.be/Archives_ARQE/3423.pdf, label: Official PDF URL} + - value_id: other_household_without_social_supplement + label: Other households without social supplements + ordinal: 3 + row_number: 5 + expected_row_header_column: A + expected_row_header: other_household_without_social_supplement + table_record_kind: detail + filters: + parlement_wallonie.household_type: other_household + parlement_wallonie.social_supplement_status: without_social_supplement + constraints: + - variable: parlement_wallonie.household_type + operator: == + value: other_household + label: Household type + - variable: parlement_wallonie.social_supplement_status + operator: == + value: without_social_supplement + label: Social-supplement status + guard_cells: + - {column: A, row: 5, expected_value: other_household_without_social_supplement, label: Source row identifier} + - {column: B, row: 5, expected_value: 2023-12, label: Reference month} + - {column: C, row: 5, expected_value: other_household, label: Household type} + - {column: D, row: 5, expected_value: without_social_supplement, label: Social-supplement status} + - {column: E, row: 5, expected_value: 308949, label: Published households} + - {column: F, row: 5, expected_value: 430670, label: Published children aged 0-17} + - {column: G, row: 5, expected_value: 114772, label: Published children aged 18-24} + - {column: H, row: 5, expected_value: 545442, label: Published total children} + - {column: I, row: 5, expected_value: Autres ménages sans suppléments sociaux, label: Publisher row heading} + - {column: J, row: 5, expected_value: 1, label: PDF page} + - {column: K, row: 5, expected_value: 92b8dee4e25b91f891f78f60179abe881c5ad9d7d9b5436c767cf69f9dc55651, label: Verbatim PDF SHA-256} + - {column: L, row: 5, expected_value: https://nautilus.parlement-wallon.be/Archives_ARQE/3423.pdf, label: Official PDF URL} + measures: + - measure_id: children + label: Recipient children in the publisher household group + ordinal: 0 + column: H + source_column_id: children_total + expected_column_header_row: 1 + expected_column_header: children_total + concept: parlement_wallonie.child_benefit_recipient_children_by_household_group + source_concept: parlement_wallonie.response.child_benefit.children_by_household_group + concept_relation: source_label + concept_authority: parlement_wallonie + concept_evidence_url: https://nautilus.parlement-wallon.be/Archives_ARQE/3423.pdf + concept_evidence_notes: >- + The ministerial answer publishes four separate December 2023 table-total + rows. The package retains each row and its 0-17 and 18-24 components; it + does not construct an all-scope value. AVIQ is identified in the answer + as the Walloon regulator, not as the publisher of this document. + unit: count + aggregation: sum + expected_cell_type: number +- record_set_id: parlement_wallonie.child_benefit.month2023_12.households_by_household_group + provenance_class: administrative + record_set_spec_id: parlement_wallonie.child_benefit.households_by_household_group.v1 + source_record_id_prefix: parlement_wallonie.child_benefit.month2023_12.households + sheet_name: parlement_wallonie_child_benefit_partitions_2023_12 + period_type: month + period: '2023-12' + period_coverage: *period_coverage + geography_id: BE-WALLOON-FRENCH + geography_level: statistical_scope + geography_name: French-language Walloon child-benefit system + geography_vintage: child_benefit_scope_2023 + entity: household + entity_role: child_benefit_recipient_household + domain: child_benefit + groupby_dimension: parlement_wallonie.household_type + rows: *partition_rows + measures: + - measure_id: households + label: Recipient households in the publisher household group + ordinal: 0 + column: E + source_column_id: households + expected_column_header_row: 1 + expected_column_header: households + concept: parlement_wallonie.child_benefit_recipient_households_by_household_group + source_concept: parlement_wallonie.response.child_benefit.households_by_household_group + concept_relation: source_label + concept_authority: parlement_wallonie + concept_evidence_url: https://nautilus.parlement-wallon.be/Archives_ARQE/3423.pdf + concept_evidence_notes: >- + The source labels these counts as ménages. Chronicle preserves the four + publisher rows separately and does not reinterpret them as families, + payment recipients, or a constructed all-scope total. + unit: count + aggregation: sum + expected_cell_type: number diff --git a/packages/sfpd/grapa_monthly_statistics_2025_02/source_package.yaml b/packages/sfpd/grapa_monthly_statistics_2025_02/source_package.yaml new file mode 100644 index 00000000..ca8578e6 --- /dev/null +++ b/packages/sfpd/grapa_monthly_statistics_2025_02/source_package.yaml @@ -0,0 +1,131 @@ +schema_version: ledger.source_package.v1 +package_id: sfpd-grapa-monthly-statistics-2025-02 +label: SFPD January 2025 GRAPA beneficiaries and monthly payments by sex +artifact: + source_name: sfpd_grapa + source_table: Statistique mensuelle des prestations sociales - Février 2025, table 2.4.1 + resource_package: db + resource_directory: data/sfpd/grapa_monthly_statistics_2025_02 + manifest: manifest.yaml + vintage: grapa_monthly_statistics_2025_02 + extracted_at: '2026-08-30' + extraction_method: >- + long-form transcription of the January 2025 row and its sex partitions + from the full SFPD monthly-statistics PDF, printed page 36, table 2.4.1 + parser: delimited_text_full_rows + artifact_year: 2025 + sheet_name: sfpd_grapa_monthly_2025_01 +record_sets: +- record_set_id: sfpd_grapa.month2025_01.regular_payment_beneficiaries.by_sex + provenance_class: administrative + record_set_spec_id: sfpd_grapa.regular_payment_beneficiaries.by_sex.v1 + source_record_id_prefix: sfpd_grapa.month2025_01.regular_payment_beneficiaries + sheet_name: sfpd_grapa_monthly_2025_01 + period_type: month + period: '2025-01' + geography_id: BE + geography_level: country + geography_name: Belgium + geography_vintage: current + entity: person + entity_role: grapa_beneficiary + domain: old_age_income_guarantee + groupby_dimension: sex + rows: + - value_id: all + label: All GRAPA beneficiaries in the regular-payment population + ordinal: 0 + row_number: 2 + expected_row_header_column: A + expected_row_header: all + table_record_kind: total + filters: {} + constraints: [] + guard_cells: + - column: B + row: 2 + expected_value: 2025-01 + label: Reference month + - column: C + row: 2 + expected_value: regular_payment_snapshot + label: Statistical population + - value_id: male + label: Men receiving GRAPA in the regular-payment population + ordinal: 1 + row_number: 3 + expected_row_header_column: A + expected_row_header: male + table_record_kind: detail + filters: + sex: male + constraints: + - variable: sex + operator: == + value: male + label: Sex + guard_cells: + - column: B + row: 3 + expected_value: 2025-01 + label: Reference month + - value_id: female + label: Women receiving GRAPA in the regular-payment population + ordinal: 2 + row_number: 4 + expected_row_header_column: A + expected_row_header: female + table_record_kind: detail + filters: + sex: female + constraints: + - variable: sex + operator: == + value: female + label: Sex + guard_cells: + - column: B + row: 4 + expected_value: 2025-01 + label: Reference month + measures: + - measure_id: beneficiaries + label: GRAPA beneficiaries in the regular-payment population + ordinal: 0 + column: D + source_column_id: beneficiaries + expected_column_header_row: 1 + expected_column_header: beneficiaries + concept: sfpd.grapa_regular_payment_beneficiary_count + source_concept: sfpd.monthly_statistics.table_2_4_1.grapa_beneficiaries + concept_relation: exact + concept_authority: sfpd + concept_evidence_url: https://www.sfpd.fgov.be/files/3432/fr_stat_2502.pdf + concept_evidence_notes: >- + SFPD table 2.4.1 reports 118,262 GRAPA beneficiaries for January 2025, + split into 42,346 men and 75,916 women. It is a monthly regular-payment + snapshot, not an annual-average, year-end, annual-any, eligibility, or + payment-transaction count. The publication uses both beneficiaries and + cases but does not publish its person-key deduplication method. + unit: count + aggregation: sum + expected_cell_type: number + - measure_id: monthly_amount_eur + label: Monthly GRAPA amount paid to the regular-payment population + ordinal: 1 + column: E + source_column_id: monthly_amount_eur + expected_column_header_row: 1 + expected_column_header: monthly_amount_eur + concept: sfpd.grapa_regular_payment_monthly_amount + source_concept: sfpd.monthly_statistics.table_2_4_1.grapa_monthly_amount + concept_relation: exact + concept_authority: sfpd + concept_evidence_url: https://www.sfpd.fgov.be/files/3432/fr_stat_2502.pdf + concept_evidence_notes: >- + SFPD table 2.4.1 pairs the January 2025 beneficiary population with + EUR 85,039,735.46 in monthly GRAPA payments. The men and women payment + rows sum exactly to the published total. + unit: eur + aggregation: sum + expected_cell_type: number diff --git a/tests/test_belgium_child_benefit_participation.py b/tests/test_belgium_child_benefit_participation.py new file mode 100644 index 00000000..3e59c8f6 --- /dev/null +++ b/tests/test_belgium_child_benefit_participation.py @@ -0,0 +1,284 @@ +"""Source-faithful Belgian child-benefit participation facts.""" + +from dataclasses import replace + +import pytest + +from chronicle.core import validate_facts +from chronicle.source_package import SOURCE_PACKAGE_ALIASES, load_source_package + + +OPGROEIEN_ALIAS = "opgroeien-groeipakket-basic-caseload-2025-12" +OPGROEIEN_COMPONENT_ALIAS = "opgroeien-groeipakket-caseload-2025" +IRISCARE_ALIAS = "iriscare-child-benefit-caseload-2025-12" +OSTBELGIEN_ALIAS = "ostbelgien-child-benefit-caseload-2025-12" +PARLEMENT_WALLONIE_ALIAS = "parlement-wallonie-child-benefit-partitions-2023-12" + + +def _facts(alias: str, year: int): + return tuple(load_source_package(alias).build_facts(year)) + + +def test_belgium_child_benefit_participation_aliases_are_registered(): + assert { + OPGROEIEN_ALIAS, + IRISCARE_ALIAS, + OSTBELGIEN_ALIAS, + PARLEMENT_WALLONIE_ALIAS, + } <= set(SOURCE_PACKAGE_ALIASES) + + +def test_all_opgroeien_packages_use_administrative_scheme_scope(): + opgroeien_aliases = { + alias + for alias, path in SOURCE_PACKAGE_ALIASES.items() + if path.parts[0] == "opgroeien" + } + + assert opgroeien_aliases == {OPGROEIEN_ALIAS, OPGROEIEN_COMPONENT_ALIAS} + for alias in opgroeien_aliases: + facts = _facts(alias, 2025) + assert { + (fact.geography.level, fact.geography.id, fact.geography.vintage) + for fact in facts + } == { + ( + "statistical_scope", + "BE-GROEIPAKKET-SCHEME", + "GROEIPAKKET_ADMINISTRATIVE_SCOPE_2025", + ) + } + + +def test_opgroeien_basic_child_caseload_preserves_dashboard_query_scope(): + facts = _facts(OPGROEIEN_ALIAS, 2025) + + assert len(facts) == 1 + fact = facts[0] + assert fact.value == 1_629_980 + assert (fact.period.type, fact.period.value) == ("month", "2025-12") + assert (fact.geography.level, fact.geography.id) == ( + "statistical_scope", + "BE-GROEIPAKKET-SCHEME", + ) + assert (fact.entity.name, fact.entity.role) == ( + "person", + "child_benefit_recipient", + ) + assert fact.measure.concept == "opgroeien.groeipakket_basic_amount_children" + assert fact.filters == { + "groeipakket.component": "basic_amount", + "publication_status": "provisional", + } + assert fact.period_coverage is not None + assert fact.period_coverage.source_period_label == "2025/12" + assert validate_facts(facts).valid + + +def test_iriscare_keeps_children_and_payment_recipients_distinct(): + facts = _facts(IRISCARE_ALIAS, 2025) + by_concept = {fact.measure.concept: fact for fact in facts} + + assert {concept: fact.value for concept, fact in by_concept.items()} == { + "iriscare.child_benefit_entitled_children": 304_966, + "iriscare.child_benefit_payment_recipients": 162_745, + } + assert {(fact.entity.name, fact.entity.role) for fact in facts} == { + ("person", "child_benefit_entitled_child"), + ("person", "child_benefit_payment_recipient"), + } + assert {(fact.period.type, fact.period.value) for fact in facts} == { + ("month", "2025-12") + } + assert {(fact.geography.level, fact.geography.id) for fact in facts} == { + ("statistical_scope", "BE-IRISCARE-CHILD-BENEFIT-SCHEME") + } + assert {fact.filters["publication_status"] for fact in facts} == {"provisional"} + assert validate_facts(facts).valid + + +def test_ostbelgien_keeps_children_and_payment_recipients_distinct(): + facts = _facts(OSTBELGIEN_ALIAS, 2025) + by_concept = {fact.measure.concept: fact for fact in facts} + + assert {concept: fact.value for concept, fact in by_concept.items()} == { + "ostbelgien.child_benefit_paid_children": 15_533, + "ostbelgien.child_benefit_payment_recipients": 8_302, + } + assert {(fact.entity.name, fact.entity.role) for fact in facts} == { + ("person", "child_benefit_paid_child"), + ("person", "child_benefit_payment_recipient"), + } + assert {(fact.period.type, fact.period.value) for fact in facts} == { + ("month", "2025-12") + } + assert {(fact.geography.level, fact.geography.id) for fact in facts} == { + ("statistical_scope", "BE-DG") + } + assert validate_facts(facts).valid + + +def test_walloon_response_preserves_published_partitions_without_total_fact(): + facts = _facts(PARLEMENT_WALLONIE_ALIAS, 2023) + by_measure_and_group = { + ( + fact.measure.concept, + fact.filters["parlement_wallonie.household_type"], + fact.filters["parlement_wallonie.social_supplement_status"], + ): fact.value + for fact in facts + } + + assert by_measure_and_group == { + ( + "parlement_wallonie.child_benefit_recipient_children_by_household_group", + "single_parent", + "with_social_supplement", + ): 149_169, + ( + "parlement_wallonie.child_benefit_recipient_children_by_household_group", + "single_parent", + "without_social_supplement", + ): 38_385, + ( + "parlement_wallonie.child_benefit_recipient_children_by_household_group", + "other_household", + "with_social_supplement", + ): 177_229, + ( + "parlement_wallonie.child_benefit_recipient_children_by_household_group", + "other_household", + "without_social_supplement", + ): 545_442, + ( + "parlement_wallonie.child_benefit_recipient_households_by_household_group", + "single_parent", + "with_social_supplement", + ): 89_575, + ( + "parlement_wallonie.child_benefit_recipient_households_by_household_group", + "single_parent", + "without_social_supplement", + ): 24_535, + ( + "parlement_wallonie.child_benefit_recipient_households_by_household_group", + "other_household", + "with_social_supplement", + ): 90_308, + ( + "parlement_wallonie.child_benefit_recipient_households_by_household_group", + "other_household", + "without_social_supplement", + ): 308_949, + } + + assert not any( + fact.measure.concept.endswith("_total") + or fact.filters.get("parlement_wallonie.household_type") == "all" + for fact in facts + ) + assert {(fact.period.type, fact.period.value) for fact in facts} == { + ("month", "2023-12") + } + assert {(fact.geography.level, fact.geography.id) for fact in facts} == { + ("statistical_scope", "BE-WALLOON-FRENCH") + } + assert validate_facts(facts).valid + + +@pytest.mark.parametrize( + ("alias", "year", "record_id", "required_addresses"), + [ + ( + OPGROEIEN_ALIAS, + 2025, + "opgroeien.groeipakket.month2025_12.basic_amount.children." + "basic_amount_children.children", + {"C2", "D2", "E2", "F2", "G2", "H2", "I2", "J2", "L2"}, + ), + ( + IRISCARE_ALIAS, + 2025, + "iriscare.child_benefit.month2025_12.payment_recipients." + "payment_recipients.payment_recipients", + {"C3", "D3", "E3", "F3", "G3", "H3", "J3"}, + ), + ( + OSTBELGIEN_ALIAS, + 2025, + "ostbelgien.child_benefit.month2025_12.payment_recipients." + "payment_recipients.payment_recipients", + {"C3", "D3", "E3", "F3", "H3"}, + ), + ( + PARLEMENT_WALLONIE_ALIAS, + 2023, + "parlement_wallonie.child_benefit.month2023_12.children." + "single_parent_with_social_supplement.children", + {"C2", "D2", "E2", "F2", "G2", "I2", "J2", "K2", "L2"}, + ), + ], +) +def test_participation_source_evidence_is_in_record_lineage( + alias, + year, + record_id, + required_addresses, +): + records = load_source_package(alias).build_source_records(year) + record = {item.source_record_id: item for item in records}[record_id] + + assert required_addresses <= set(record.source_cell_addresses) + + +@pytest.mark.parametrize( + ("alias", "year", "address", "replacement", "guard_label"), + [ + ( + OPGROEIEN_ALIAS, + 2025, + "H2", + "Groeipakket=changed", + "Dashboard Groeipakket filter", + ), + ( + IRISCARE_ALIAS, + 2025, + "E3", + "Households", + "Dashboard measure view", + ), + ( + OSTBELGIEN_ALIAS, + 2025, + "E3", + "changed source description", + "Source description", + ), + ( + PARLEMENT_WALLONIE_ALIAS, + 2023, + "K2", + "changed-pdf-digest", + "Verbatim PDF SHA-256", + ), + ], +) +def test_participation_source_guard_drift_refuses_resolution( + alias, + year, + address, + replacement, + guard_label, +): + package = load_source_package(alias) + cells = package.build_source_cells(year) + mutated = tuple( + replace(cell, raw_value=replacement, display_value=replacement) + if cell.address == address + else cell + for cell in cells + ) + + with pytest.raises(ValueError, match=guard_label): + package.build_source_records(year, cells=mutated) diff --git a/tests/test_belgium_targets.py b/tests/test_belgium_targets.py index afec1b2f..cb78ff4f 100644 --- a/tests/test_belgium_targets.py +++ b/tests/test_belgium_targets.py @@ -516,9 +516,7 @@ def test_belgium_euromod_comparator_pairs_c2_rows_with_model_outputs(): missing_ratios = { row["value_id"] for row in c2_rows - if row["value_id"] - .replace("_external_", "_ratio_") - .replace("_silc_", "_ratio_") + if row["value_id"].replace("_external_", "_ratio_").replace("_silc_", "_ratio_") not in ids } assert not missing_ratios @@ -541,6 +539,7 @@ def test_belgium_euromod_comparator_pairs_c2_rows_with_model_outputs(): SFPD_PENSION_ALIAS = "sfpd-legal-pension-caseload-2025" +SFPD_GRAPA_ALIAS = "sfpd-grapa-monthly-statistics-2025-02" GROEIPAKKET_ALIAS = "opgroeien-groeipakket-caseload-2025" BFP_OUTLOOK_ALIAS = "bfp-economic-outlook-2026-06" FPB_ANNEX_ALIAS = "fpb-economic-outlook-2026-2031-june-2026" @@ -549,6 +548,7 @@ def test_belgium_euromod_comparator_pairs_c2_rows_with_model_outputs(): def test_belgium_supplementary_publisher_aliases_are_registered(): assert { SFPD_PENSION_ALIAS, + SFPD_GRAPA_ALIAS, GROEIPAKKET_ALIAS, BFP_OUTLOOK_ALIAS, FPB_ANNEX_ALIAS, @@ -576,6 +576,32 @@ def test_sfpd_legal_pension_caseload_matches_published_cells(): assert validate_facts(facts).valid +def test_sfpd_grapa_snapshot_matches_payment_linked_published_cells(): + facts = _facts(SFPD_GRAPA_ALIAS, 2025) + by_measure_and_sex = { + (fact.measure.concept, fact.filters.get("sex", "all")): fact.value + for fact in facts + } + + assert by_measure_and_sex == { + ("sfpd.grapa_regular_payment_beneficiary_count", "all"): 118262, + ("sfpd.grapa_regular_payment_beneficiary_count", "male"): 42346, + ("sfpd.grapa_regular_payment_beneficiary_count", "female"): 75916, + ("sfpd.grapa_regular_payment_monthly_amount", "all"): 85039735.46, + ("sfpd.grapa_regular_payment_monthly_amount", "male"): 28338945.37, + ("sfpd.grapa_regular_payment_monthly_amount", "female"): 56700790.09, + } + assert 42346 + 75916 == 118262 + assert Decimal("28338945.37") + Decimal("56700790.09") == Decimal("85039735.46") + assert {fact.period.type for fact in facts} == {"month"} + assert {fact.period.value for fact in facts} == {"2025-01"} + assert {fact.geography.id for fact in facts} == {"BE"} + assert {fact.source.source_sha256 for fact in facts} == { + "6ff9d5d99881b48be68343cb259fb86d29761e020b39afed5df217bb6fc5ce01" + } + assert validate_facts(facts).valid + + def test_groeipakket_caseload_matches_published_component_cells(): facts = _facts(GROEIPAKKET_ALIAS, 2025) children = { @@ -589,7 +615,7 @@ def test_groeipakket_caseload_matches_published_component_cells(): if fact.measure.concept == "groeipakket_families_receiving_component" } - # Exact published caseload cells from Opgroeien (Flemish agency). + # Exact published administrative-scheme caseload cells from Opgroeien. assert children == { "social_supplement": 522148, "orphan_supplement": 21741, @@ -608,8 +634,16 @@ def test_groeipakket_caseload_matches_published_component_cells(): # basisbedrag child count is published only as a rounded ">1.6M" lower bound, # so it is intentionally omitted from the child record set (recorded as a gap). assert "basic_amount" not in children - assert {fact.geography.id for fact in facts} == {"BE2"} - assert {fact.geography.vintage for fact in facts} == {"NUTS_2024"} + assert { + (fact.geography.level, fact.geography.id, fact.geography.vintage) + for fact in facts + } == { + ( + "statistical_scope", + "BE-GROEIPAKKET-SCHEME", + "GROEIPAKKET_ADMINISTRATIVE_SCOPE_2025", + ) + } assert validate_facts(facts).valid diff --git a/tests/test_chronicle_bundle.py b/tests/test_chronicle_bundle.py index 6a00ef84..99467f45 100644 --- a/tests/test_chronicle_bundle.py +++ b/tests/test_chronicle_bundle.py @@ -73,16 +73,16 @@ def test_build_bundle_writes_merged_consumer_contract(tmp_path): "aggregate_duplicate_key_count": 0, "entity_count": 12, "error_count": 0, - "fact_count": 171855, - "geography_count": 12536, + "fact_count": 171874, + "geography_count": 12540, "period_count": 192, "semantic_duplicate_key_count": 121, "skipped_source_count": 10, - "source_count": 43, - "source_package_count": 151, + "source_count": 48, + "source_package_count": 156, "warning_count": 1, } - assert len(rows) == 171855 + assert len(rows) == 171874 assert {row["provenance_class"] for row in rows} <= { "administrative", "census", @@ -100,7 +100,7 @@ def test_build_bundle_writes_merged_consumer_contract(tmp_path): ) assert rows[0]["aggregate_fact_key"].startswith("ledger.aggregate_fact.v2:") assert rows[0]["semantic_fact_key"].startswith("ledger.semantic_fact.v2:") - assert source_packages["source_package_count"] == 151 + assert source_packages["source_package_count"] == 156 assert source_packages["skipped_source_count"] == 10 assert sorted(item["source"] for item in source_packages["skipped_sources"]) == [ "census-acs-s0101-congressional-district-age-2024", @@ -114,7 +114,7 @@ def test_build_bundle_writes_merged_consumer_contract(tmp_path): "jct-obbba-revenue-estimates-2025", "jct-tax-expenditures-2024", ] - assert coverage["fact_count"] == 171855 + assert coverage["fact_count"] == 171874 assert coverage["counts"]["by_source"] == { "bea": 445, "bfp_economic_outlook": 5, @@ -135,6 +135,7 @@ def test_build_bundle_writes_merged_consumer_contract(tmp_path): "hhs_acf_tanf": 110, "hmrc": 20551, "ici": 12, + "iriscare_child_benefit_dashboard": 2, "irs_soi": 40063, "isc": 2, "jrc_euromod_be": 90, @@ -148,8 +149,12 @@ def test_build_bundle_writes_merged_consumer_contract(tmp_path): "ons": 65647, "onss_contributions": 1, "opgroeien_groeipakket": 11, + "opgroeien_groeipakket_dashboard": 1, + "ostbelgien_child_benefit_statistics": 2, + "parlement_wallonie_child_benefit_response": 8, "scotgov": 2787, "sfpd_pensions": 4, + "sfpd_grapa": 6, "slc": 199, "spf_finances_pit": 1, "ssa": 426, @@ -161,7 +166,7 @@ def test_build_bundle_writes_merged_consumer_contract(tmp_path): "welshgov": 216, } table_counts = coverage["counts"]["by_source_table"] - assert len(table_counts) == 146 + assert len(table_counts) == 151 assert ( table_counts[ "dwp:Universal Credit childcare element statistics to August 2025, Table 1" @@ -608,7 +613,7 @@ def test_build_bundle_writes_merged_consumer_contract(tmp_path): "month:2023-09": 1, "month:2023-10": 1, "month:2023-11": 1, - "month:2023-12": 7, + "month:2023-12": 15, "month:2024-01": 2, "month:2024-02": 1, "month:2024-03": 1, @@ -621,7 +626,7 @@ def test_build_bundle_writes_merged_consumer_contract(tmp_path): "month:2024-10": 107, "month:2024-11": 107, "month:2024-12": 377, - "month:2025-01": 109, + "month:2025-01": 115, "month:2025-02": 107, "month:2025-03": 229, "month:2025-04": 112, @@ -632,7 +637,7 @@ def test_build_bundle_writes_merged_consumer_contract(tmp_path): "month:2025-09": 28, "month:2025-10": 19, "month:2025-11": 34, - "month:2025-12": 275, + "month:2025-12": 280, "month:2026-01": 3, "month:2026-02": 7, "month:2026-06": 348, @@ -675,11 +680,11 @@ def test_build_bundle_writes_merged_consumer_contract(tmp_path): "tax_year:2023": 63054, "tax_year:2024": 40, } - assert coverage["counts"]["by_geography"]["country:BE"] == 4888 + assert coverage["counts"]["by_geography"]["country:BE"] == 4894 assert coverage["counts"]["by_geography"]["country:DE"] == 36 assert coverage["counts"]["by_geography"]["country:FR"] == 36 assert coverage["counts"]["by_geography"]["nuts1:BE1"] == 3662 - assert coverage["counts"]["by_geography"]["nuts1:BE2"] == 3673 + assert coverage["counts"]["by_geography"]["nuts1:BE2"] == 3662 assert coverage["counts"]["by_geography"]["nuts1:BE3"] == 3662 assert coverage["counts"]["by_geography"]["commune:11002"] == 1 assert coverage["counts"]["by_geography"]["country:0100000US"] == 2109 @@ -689,17 +694,31 @@ def test_build_bundle_writes_merged_consumer_contract(tmp_path): ) assert coverage["counts"]["by_geography"]["country:K02000001"] == 4297 assert coverage["counts"]["by_geography"]["country:K03000001"] == 497 - assert len(coverage["counts"]["by_geography"]) == 12536 + assert ( + coverage["counts"]["by_geography"]["statistical_scope:BE-GROEIPAKKET-SCHEME"] + == 12 + ) + assert ( + coverage["counts"]["by_geography"][ + "statistical_scope:BE-IRISCARE-CHILD-BENEFIT-SCHEME" + ] + == 2 + ) + assert coverage["counts"]["by_geography"]["statistical_scope:BE-DG"] == 2 + assert ( + coverage["counts"]["by_geography"]["statistical_scope:BE-WALLOON-FRENCH"] == 8 + ) + assert len(coverage["counts"]["by_geography"]) == 12540 assert coverage["counts"]["by_entity"] == { "benefit_unit": 233, "dwelling": 12733, "family": 107, "firm": 1439, "government": 1313, - "household": 40724, + "household": 40728, "institutional_sector": 133, "pension_plan": 2, - "person": 60466, + "person": 60481, "return": 14600, "social_protection_scheme": 36, "tax_unit": 40069,