Story: Synthetic generation configuration and config-driven feeds
Table of Contents
This page documents a story in Sprint 21. It captures the goal, current status, acceptance criteria, and the tasks that compose it.
The producer half of the Market Data Architecture: ores.synthetic owns how synthetic data is generated, as a persisted, party-scoped, named configuration, and generates from it autonomously.
Goal
Replace the PoC's transient, boot-time, system-tenant generation with a proper
producer: a persisted synthetic generation config in ores.synthetic that a
user authors, and a service that generates from it autonomously and publishes on
its own namespaced channel — stamping the config's tenant and source name so the
data is correctly owned and traceable.
Status
| Field | Value |
|---|---|
| State | DONE |
| Parent sprint | Sprint 21 |
| Now | Complete. Library data task deferred to sprint 22. |
| Waiting on | Nothing. |
| Next | Nothing. |
| Last touched | 2026-07-02 |
Acceptance
- A persisted synthetic config exists in
ores.synthetic: a container (synthetic_config: tenant, party, name/source, enabled) and a typed FX spot sub-config (GMM params, ore_key, tick mode/rate) linked by a real foreign key, party/tenant-scoped. (P1) - CRUD + NATS protocol (list/get/save/delete) for the config, authenticated. (P1)
- A Qt UI creates/edits/lists configs scoped to the logged-in tenant/party; a config cannot be created without it. (P2)
- The synthetic service loads enabled configs (replacing the boot-time system-tenant bootstrap) and generates autonomously, stamping every observation with the config's tenant and source name. (P3)
- Generation publishes ticks to a producer-namespaced channel
(
synthetic.v1.tick.<key>); the per-tickobservations.saveis removed (persistence moves to marketdata — see the feed-binding story). (P4) - A business-tenant/party login sees only its own configs and its own data.
Tasks
| Task | State | Start | End | Description |
|---|---|---|---|---|
| Synthetic config entities across all layers (currency pattern) | DONE | 2026-06-28 | 2026-06-28 | Hand-write the synthetic generation config domain model — synthetic_config (container), synthetic_fx_spot_config (sub-config, FK to container), synthetic_gmm_component (FK to sub-config) — across every layer, mirroring the currency reference entity (and book for FKs) so they convert to codegen types later: domain type + json_io + table_io + table, generator, repository (entity/mapper/repository), NATS protocol, SQL (create/triggers/notify), service, handler, eventing, CMake + registrar wiring. |
| Qt config UI for synthetic market data generation configs | DONE | 2026-06-28 | 2026-06-29 | Qt client UI to create/edit/list/delete the synthetic market data generation config entities (container + fx_spot sub-config + gmm components), mirroring the currency Qt setup exactly: table model, list window with pagination, create/edit dialogs, history view, controller, and plugin menu/toolbar wiring. |
| Synthetic FX spot library: 30 pairs with historically-consistent starting spots | BACKLOG | — | — | Pre-canned library data bundle covering the 30 benchmark FX spot pairs (G10 + key EM vs USD) that seeds the CRM. Each config carries a GMM starting spot consistent with a single reference date t (2024-01-02). Apply is idempotent. |
Decisions
- Modelled per Polymorphic types over NATS: a discriminated container with one typed sub-config struct + subject per concrete type; never a JSON blob.
- Provenance is via the source name; market data stays tenant-scoped (no party column) — see cross-rates matrix for the wider model.
Out of scope
- Marketdata feed binding, ingestion and the official stream (separate story).
- The source-agnostic control panel (separate story).
- CRM derivation and correlations (backlog).
Result
Config entities (synthetic_config container + synthetic_fx_spot_config sub-config + synthetic_gmm_component) delivered across all layers. Qt CRUD UI delivered. Config-driven autonomous generation running per-config. Library data task (30 benchmark pairs) deferred to sprint 22.