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]Acurrency_countryjunction table linkscurrencytocountry, generated viaores.codegen.junction, mirroringparty_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.