Task: Synthetic config entities across all layers (currency pattern)
This page documents a task in the Synthetic generation configuration and config-driven feeds story. It captures the goal, current status, acceptance, and any notes or results.
Goal
Establish the persisted synthetic generation config data model in ores.synthetic, party/tenant-scoped, with every file matching the currency/book codegen output patterns so a future codegen pass regenerates them with zero/minimal diff.
Status
| Field | Value |
|---|---|
| State | DONE |
| Parent story | Synthetic generation configuration and config-driven feeds |
| Now | Nothing. |
| Waiting on | Nothing. |
| Next | Nothing. |
| Last touched | 2026-06-28 |
Acceptance
- synthetic_config, synthetic_fx_spot_config and synthetic_gmm_component exist across all layers following the currency pattern exactly
- Real foreign keys link sub-config -> container and component -> sub-config
- DB recreate provisions the tables; CRUD round-trips over NATS; build is green
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
PRs
| PR | Title |
|---|---|
| #1362 | [synthetic] Add market data generation config domain entities |
Review
| # | Comment summary | File | Decision | Notes |
|---|---|---|---|---|
| R1 | Canary: synthetic not a registered component prefix + missing RLS policies | parser + rls | Fixed | 8d0043038 — prefix registered, 6 RLS policies added |
| R1 | ticks_per_hour / gmm_initial_price need positive constraints | fx_spot create.sql + service | Fixed | a5547f668 — SQL CHECK + service guard |
| R1 | ore_key needs non-empty constraint | fx_spot create.sql + service | Fixed | a5547f668 — SQL CHECK + service guard |
| R1 | weight needs DB-level CHECK | gmm create.sql | Fixed | a5547f668 — check (weight >= 0) |
| R1 | batch remove() missing valid_to filter (all 3 repos) | repositories | Fixed | ceb571f04 |
| R1 | truncated GPL header in fx_spot/gmm handlers | handlers | Fixed | be461c059 |
| R1 | no cascade soft-delete on parent removal | SQL triggers | Declined | acknowledged soft-FK limitation; separate cascade story |
| R1 | list handler swallows errors silently | handlers | Declined | inherited from currency template; cross-cutting, fix globally |
| R1 | informational notes (read perm, weight-sum, optional description, party-scoped source uniq) | — | Declined | intentional / matches established pattern |
Result
Delivered via PR #1362 (merged). Three party/tenant-scoped bitemporal entities added to ores.synthetic across every layer (domain, json_io, protocol, entity, mapper, repository, service, handler, registrar, SQL create/notify/drop, RLS, IAM permissions), each hand-written to match the currency/book codegen output:
- market_data_generation_config (container)
- fx_spot_generation_config (child; soft-FK config_id -> container)
- gmm_component (grandchild; soft-FK fx_spot_config_id -> fx_spot config)
Parent/child links use the established soft-FK pattern (UUID column validated in the insert trigger against the active parent row), since a real DB FK cannot target a bitemporal table's partial-unique key — captured in Acceptance as "real foreign keys" but realised as soft FKs per codebase convention.
ores.synthetic.api was converted from an INTERFACE to a compiled library to match ores.refdata.api. No new NATS service was created — handlers were wired into the existing ores.synthetic service.
Verified: validate_schemas.sh 0 warnings; db recreate provisions all 3 tables + 6 RLS policies; api/core/service build and link clean. Review round 1 handled (6 fixes, 3 declined with reasons).