Task: Model a currency-country junction

Table of Contents

This page documents a task in the Model calendars as proper ORE Studio reference data story. It captures the goal, current status, acceptance, and any notes or results.

Goal

Model a currency_country many-to-many junction between currency and the existing country entity (ores.refdata.country), following the same pattern as party_country_junction. A currency can be issued by multiple countries (e.g. EUR spans DE, FR, IT, …). This is independent reference data in its own right — not a prerequisite for the calendar entity, which carries its own country_code (with the ZZ sentinel handled in that task) rather than deriving a currency's calendars transitively through currency_country, since supranational calendars like TARGET have no single owning country to derive through.

Status

Field Value
State DONE
Parent story Model calendars as proper ORE Studio reference data
Now Nothing.
Waiting on Nothing.
Next Nothing.
Last touched 2026-07-13

Acceptance

  • [X] A currency_country junction table links currency to country, generated via ores.codegen.junction, mirroring party_country_junction's shape.
  • [X] Existing currencies are seeded with their real issuing countries (EUR -> DE, FR, IT, ES, …; USD -> US; GBP -> GB; etc.) for the currencies already present in synthetic/seed data.

Plan

(Implementation strategy. Written when work starts; key decisions are distilled into the parent story's * Decisions at close, but the plan itself stays — it is the historical record of what we did.)

Notes

Test Scenarios

Manual QA scenarios (scaffolded via compass add test_scenario, run through the QA Validation Runner panel) that verify this task. Link new ones here as they're created; the scenario doc itself links back via its "Verifies task" field.

Scenario State Notes
     

PRs

PR Title
#1568 [refdata] Model currency_country junction

Review

# Comment summary File Decision Notes
1 Missing drop script for the new table (all 3 review passes) projects/ores.sql/drop/refdata/refdata_currency_country_drop.sql Accepted Added, mirroring refdata_party_countries_drop.sql; wired into refdata_drop.sql before currencies/countries drop
2 generate_synthetic_currency_country hardcodes both composite-key fields, so generate_synthetic_currency_countries(n) produces n identical rows projects/ores.refdata/api/src/generators/currency_country_generator.cpp Accepted Vary currency_iso_code per call via an atomic counter suffix, matching the "X" + counter convention currency's own synthetic generator uses
3 Missing repository-level tests vs. the cited party_country precedent projects/ores.refdata/core/tests/repository_currency_country_repository_tests.cpp Accepted Added, mirroring repository_party_country_repository_tests.cpp (write single/multiple, read by currency/country, remove, remove_by_currency, read nonexistent)
4 ES breaks alphabetical ordering in the countries seed projects/ores.sql/populate/refdata/refdata_countries_populate.sql Accepted Moved after DK

Result

Modelled currency_country as an ores.codegen.junction (SQL schema generated), and hand-authored the full C++ layer — domain struct, JSON I/O, table display/table I/O, custom generator, repository entity/mapper/repository — since junction codegen currently only supports the SQL address (confirmed by checking party_country and currency_currency_group, the two closest precedents: both are also SQL-only from codegen, with their C++ hand-authored). Mirrors party_country_junction's exact shape and conventions throughout.

Seeded 23 real currency-country mappings (EUR spans DE/FR/IT/ES/AT/FI; USD/GBP/JPY/CHF/CAD/AUD/SEK/NOK/DKK/CNY/HKD/SGD/ZAR/INR/KRW/MXN/BRL each map to one country) via both a generate_currency_countries() custom generator and a matching SQL populate script (refdata_currency_countries_populate.sql), following the same dual-path pattern established for calendar's QuantLib seed in the previous task. Discovered ES (Spain) wasn't yet in the countries seed (only calendar-referenced countries were there) and added it, since EUR -> ES is in this task's own acceptance criteria.

Wired the generated junction SQL into refdata_create.sql (was missing, same class of gap as calendar/calendar_type in the previous task) at the point after both currencies and countries exist.

Verified end-to-end: ores.refdata.api.lib=/=ores.refdata.core.lib build clean; full monorepo build and ctest (72/73 passed — the 1 failure is the same pre-existing, unrelated contact_type test seen in the previous task's PR, confirmed untouched by any commit here); compass db recreate runs clean with 23 junction rows present. Note: the real ISO currencies (EUR, USD, GBP, …) these rows reference are themselves populated via DQ-publish/tenant provisioning, not db recreate's foundation layer — a pre-existing characteristic of this codebase, not something this task changes.

Emacs 29.3 (Org mode 9.6.15)