Sprint Mission
- Add support for party and related entities.
Stories
Active
| Tags | Headline | Time | % | ||
|---|---|---|---|---|---|
| Total time | 3:30 | 100.0 | |||
| Stories | 3:30 | 100.0 | |||
| Active | 3:30 | 100.0 | |||
| agile | Sprint and product backlog refinement | 0:24 | 11.4 | ||
| code | Add FSM support to postgres | 1:01 | 29.0 | ||
| code | Add trade support | 2:05 | 59.5 |
| Tags | Headline | Time | % | ||
|---|---|---|---|---|---|
| Total time | 70:51 | 100.0 | |||
| Stories | 70:51 | 100.0 | |||
| Active | 70:51 | 100.0 | |||
| agile | Sprint and product backlog refinement | 3:37 | 5.1 | ||
| code | Add bound parameters to sqlgen | 0:51 | 1.2 | ||
| code | Add roles to account via codes | 0:34 | 0.8 | ||
| code | Implement party related entities at database level | 4:23 | 6.2 | ||
| code | Add party related support at the domain level | 0:23 | 0.5 | ||
| code | Add party related support to Qt | 6:41 | 9.4 | ||
| code | Add GLEIF data to datasets | 6:41 | 9.4 | ||
| code | Brainstorm on multi-party support | 4:00 | 5.6 | ||
| code | Improve code coverage | 0:14 | 0.3 | ||
| code | Improve generators with FK-aware test data | 1:44 | 2.4 | ||
| code | Enable all skipped tests | 0:29 | 0.7 | ||
| code | Add central bank related LEIs | 0:35 | 0.8 | ||
| code | Expand unit test coverage for ORE codegened types | 0:49 | 1.2 | ||
| code | Add system party support | 3:58 | 5.6 | ||
| code | Add customer party support | 1:33 | 2.2 | ||
| code | Fix OSX build | 0:19 | 0.4 | ||
| code | Add pagination to counterparty | 0:58 | 1.4 | ||
| code | Add support for business centres | 3:47 | 5.3 | ||
| code | Add LEI to BIC dataset | 0:27 | 0.6 | ||
| code | Add proper party short-codes | 2:18 | 3.2 | ||
| code | Polish party and counterparty list UI | 1:25 | 2.0 | ||
| code | Implement party-level RLS isolation | 2:33 | 3.6 | ||
| code | Add a setup new tenant wizard | 1:27 | 2.0 | ||
| code | Advanced counterparty dialog | 10:46 | 15.2 | ||
| code | Improve column handling in list widgets in Qt | 4:00 | 5.6 | ||
| code | Analyse caching at dialog level | 1:13 | 1.7 | ||
| code | Add FSM support to postgres | 1:01 | 1.4 | ||
| code | Add trade support | 4:05 | 5.8 |
COMPLETED Sprint and product backlog refinement agile
Updates to sprint and product backlog.
BLOCKED Add bound parameters to sqlgen code
At present we are using libpq for assorted queries to avoid issues with SQL injection. We should extend sqlgen to support this.
Links:
BLOCKED Remove uses of raw libpq code
We have added support for the missing features in sqlgen so that we can replace uses of raw libpq. The PRs have been merged in main sqlgen, we just need a release. Do a search for all uses of raw libpq and replace it with appropriate sqlgen calls.
We need to monitor sqlgen releases and then vcpkg updates.
Merged PRs:
COMPLETED Add shell widget to ores.qt code
It would be nice if we could login as super admin and add all the tenants, accounts etc in one go instead of having to go through different tools.
Merged stories:
Add REPL to Qt
Users should be able to interact with the system directly via the REPL. Add a simple widget for this.
COMPLETED Add roles to account via codes code
At present you can only add roles to an account via UUIDs. These keep changing so we can't just have a "setup system" script. However, if you could specify the account by name and the role by name it would be stable across DB refreshes.
This pull request significantly enhances the usability of role management within the IAM system by introducing a more intuitive, name-based approach for assigning and revoking roles. Instead of requiring users to work with internal UUIDs, administrators can now use human-readable principals and role names, streamlining operations and reducing potential for error. The changes are implemented across the protocol, server-side logic, and client-side shell commands, ensuring a consistent and user-friendly experience.
Highlights:
- Name-Based Role Management: Introduced new protocol messages (assign_role_by_name_request, revoke_role_by_name_request) that allow assigning and revoking roles using a principal (e.g., username@hostname) and role name, instead of requiring UUIDs.
- Server-Side Resolution: Implemented server-side handlers that automatically resolve the provided principal to an account ID and the role name to a role ID, then delegate to the existing UUID-based role assignment/revocation logic.
- Enhanced Shell Commands: The assign-role and revoke-role commands in the ores-shell now intelligently detect whether the arguments are UUIDs or names, supporting both existing UUID-based and new name-based workflows.
- Protocol Version Update: The communication protocol minor version has been bumped to 26.2 to reflect the addition of these new name-based role management messages.
- Documentation and Utilities: Updated shell recipes to include examples for name-based role assignment/revocation and added a find_account_by_username utility function to the account service for principal resolution.
COMPLETED Implement party related entities at database level code
The first step of this work is to get the entities to work at the database schema level.
This pull request lays the groundwork for robust party and counterparty management within the system. It introduces a comprehensive SQL schema to define internal legal entities and external trading partners, along with their associated identifiers and contact details. Key codegen templates have been enhanced to support advanced validation and indexing, streamlining future schema development. The changes also integrate new reference data with existing data quality frameworks and update the ER diagram for clarity.
Highlights:
- New SQL Schema for Parties and Counterparties: Introduced core tables, identifiers, contact information, and account-party associations for internal legal entities and external trading partners.
- Reference Data Tables: Added four new lookup tables (party_types, party_statuses, party_id_schemes, contact_types) with validation functions and seed data.
- Codegen Enhancements: Updated the domain entity template to support validations[] and indexes[], and fixed the notify trigger template to use product prefixes.
- Data Governance Integration: Established a cross-reference between party ID schemes and existing DQ coding schemes, ensuring strict FK validation through correct population ordering.
- ER Diagram Update: The Entity-Relationship diagram has been updated to reflect the new entities and their relationships.
- Table Structure: party
Field Name Data Type Constraints Commentary party_idInteger PK, Auto-Inc Internal surrogate key for database performance and foreign key stability. tenant_idInteger FK (tenant) The "Owner" of this record. Ensures GigaBank's client list isn't visible to AlphaHedge. party_nameString(255) Not Null The full legal name of the entity (e.g., "Barclays Bank PLC"). short_nameString(50) Unique A mnemonic or "Ticker" style name used for quick UI displays (e.g., "BARC-LDN"). leiString(20) Unique/Null The ISO 17442 Legal Entity Identifier. Critical for regulatory reporting and GLEIF integration. is_internalBoolean Default: False Flag: If TRUE, this party represents a branch or entity belonging to the Tenant (The Bank). party_type_idInteger FK (scheme) Categorizes the entity: Bank, Hedge Fund, Corporate, Central Bank, or Exchange. postal_addressText Used for generating legal confirmations and settlement instructions. business_center_idInteger FK (scheme) Links to an FpML Business Center (e.g., GBLO, USNY). Determines holiday calendars for settlement. statusEnum Active/Inactive Controls whether trades can be booked against this entity. created_atTimestamp Audit trail for when the entity was onboarded.
COMPLETED Add party entity code
Party analysis.
| Field | Type | Description | Foreign Key Reference |
|---|---|---|---|
| party_id | UUID | Primary key (globally unique identifier) | — |
| full_name | TEXT | Legal or registered name | — |
| short code | TEXT | Short code for the party. | |
| organization_type | INT | Type of organization | → organization_type_scheme |
| parent_party_id | INT | References parent party (self-referencing) | → party_id (nullable) |
COMPLETED Add party identifier entity code
Allows a party to have multiple external identifiers (e.g., LEI, BIC).
| Field | Type | Description | Foreign Key Reference |
|---|---|---|---|
| party_id | UUID | References party.party_id | → party |
| id_value | TEXT | Identifier value, e.g., "549300…" | — |
| id_scheme | TEXT | Scheme defining identifier type, e.g. LEI | → party_id_scheme |
| Description | TEXT | Additional information about the party |
Primary key: composite (party_id, id_scheme)
COMPLETED Contact information entity code
Contact Information is a container that groups various ways to reach an entity.
Contact Information can be associated with either a Party (at the legal entity level) or a BusinessUnit (at the desk/operational level). To build a robust trading system, your database should support a polymorphic or flexible link to handle this.
The Logic of the Link:
- Link to Party: Used for Legal and Regulatory contact details. This is the "Head Office" address, the legal service of process address, or the general firm-wide contact for the LEI.
- Link to Business Unit: Used for Execution and Operational contact details. This is where your "Machine" or "Human" actually lives. It links the trader or algo to a specific desk's phone number, email, and—most importantly—its Business Center (Holiday Calendar).
- Type: Contact Information
This is the main container for how to reach a party or person.
- address (Complex): The physical location.
- phone (String): Multiple entries allowed (Work, Mobile, Fax).
- email (String): Electronic mail addresses.
- webPage (String): The entity's URL.
- Type: Address
The physical street address structure.
- streetAddress (Complex): Usually a list of strings (Line 1, Line 2, etc.).
- city (String): The city or municipality.
- state (String): The state, province, or region.
- country (Scheme): An ISO 3166 2-letter country code (e.g., US, GB).
- postalCode (String): The ZIP or Postcode.
COMPLETED Add party related support at the domain level code
This pull request significantly expands the system's data model by introducing a robust set of domain entities and their associated infrastructure for managing party and counterparty information. The changes provide a foundational layer for classifying, identifying, and storing contact details for both internal and external entities, complete with mechanisms for data persistence, generation, and communication. This enhancement is crucial for building out comprehensive reference data and identity and access management capabilities.
Highlights:
- New Domain Entities: Introduced 11 new C++ domain types for party-related entities, spanning both ores.refdata and ores.iam components. These include core entities like party and counterparty, along with supporting lookup tables (party_type, party_status, party_id_scheme, contact_type), identifiers (party_identifier, counterparty_identifier), and contact information (party_contact_information, counterparty_contact_information).
- Junction Table for Account-Party Linking: Added an account_party junction table in ores.iam to establish relationships between IAM accounts and refdata parties, enabling granular control over user-party associations.
- Comprehensive Infrastructure Generation: For each new entity, a full stack of supporting code has been generated, including domain classes, JSON and table I/O, data generators, repository components (entity, mapper, repository), service layers, and binary messaging protocols.
- Expanded Messaging Protocol: Incorporated 40 new message types into message_type.hpp to support CRUD (Create, Read, Update, Delete) operations across all the newly introduced party-related entities, facilitating inter-service communication.
COMPLETED Add party related support to Qt code
This pull request significantly expands the Qt GUI capabilities by adding full support for the 'party' entity, encompassing list views, detailed editing, and historical tracking. A core improvement is the enhanced code generation framework, which now dynamically adapts to entity field configurations, streamlining UI development and maintenance. This update also ensures that existing entity screens benefit from these new, more robust templates.
Highlights:
- New Party Entity Qt Screens: Introduced comprehensive Qt screens for the 'party' entity, including detail dialogs, history dialogs, MDI windows, controllers, and client models, accessible via a new 'Parties' submenu in the main window.
- Configurable Codegen for Detail Fields: Enhanced the Qt code generation process by adding a configurable 'detail_fields' array. This allows templates to generate correct fields for all entity types without requiring manual post-codegen adjustments, improving flexibility and reducing boilerplate.
- Improved Key Field Handling in Templates: Fixed Qt templates to correctly handle non-standard key fields (e.g., 'short_code') in MdiWindow and Controller templates, ensuring proper entity identification and operations.
- Regeneration of Existing Entity Screens: Regenerated existing 'party', 'counterparty', and 'tenant' entity screens using the updated and more flexible templates, ensuring consistency and leveraging the new codegen capabilities.
COMPLETED Add GLEIF data to datasets code
We exported the external data but did not create the datasets for it.
This pull request significantly enhances the system's data quality capabilities by integrating comprehensive GLEIF LEI reference data. It establishes a robust pipeline for ingesting legal entity and relationship information, from defining data models and automating SQL script generation to registering new datasets and their dependencies within the existing data quality framework. This foundational work enables the system to manage and utilize critical legal entity data, with future plans to provision this data to operational tables.
Highlights:
- GLEIF LEI Data Integration: Introduced comprehensive support for GLEIF Legal Entity Identifier (LEI) data, encompassing both entity master data and corporate hierarchy relationships, by adding new artefact tables via codegen.
- Automated SQL Generation Pipeline: Developed a Python script (lei_generate_metadata_sql.py) and a shell wrapper (generate_lei_metadata.sh) to automate the creation of SQL populate scripts from GLEIF LEI CSV subsets, ensuring idempotent bulk insertion using PL/pgSQL.
- Metadata and Dataset Registration: Registered new artefact types (lei_entities, lei_relationships), a dedicated GLEIF catalog, its associated methodology, and four distinct datasets (small/large for entities/relationships) along with their dependencies within the system.
- Data Quality Framework Integration: Integrated the newly defined LEI artefact tables and their population into the existing Data Quality (DQ) framework's schema creation and catalogue population processes.
- Documentation Update: Updated methodology.txt to clearly document the new SQL generation pipeline for LEI data, providing detailed instructions and a list of generated output files.
COMPLETED Brainstorm on multi-party support code
We added parties but there are many open questions on the design. Use the brainstorm skill to come up with a design that solves most common use cases.
This pull request introduces party pagination, a design for party-level RLS isolation within tenants, and updates the product backlog with related features. The changes enhance data isolation and access control, providing a more granular security model for the application.
Highlights:
- Party Pagination: Implemented full-stack pagination for the party entity, including protocol, repository, service, handler validation, Qt client model, and MdiWindow integration.
- Party-Level RLS Isolation Design: Introduced a design document for party-level Row-Level Security (RLS) isolation within tenants, covering tenant and party types, visible party set computation, and login flow extension with party selection.
- Multi-Party Architecture Modeling: Created a multi-party architecture modeling document as a companion to the multi_tenancy.org document.
- Product Backlog Updates: Updated the product backlog with deferred stories for features like four-eyes authorisation, KYC workflow, librarian lockdown, and GLEIF evaluation wizard.
COMPLETED Improve code coverage code
It has dipped below 50% again.
This pull request significantly enhances the robustness and reliability of the ORE Studio codebase by introducing a substantial suite of new unit tests. The added tests target modules with previously lower coverage, ensuring that critical functionalities such as CLI parsing, data quality entity generation, identity and access management authorization, reference data generation, synthetic data creation, and logging configurations behave as expected. This effort aims to catch potential regressions early and provide a more stable development environment.
Highlights:
- Expanded Unit Test Coverage: Added 12 new unit test files, introducing approximately 110 new test cases and 1900 lines of test code across 7 core modules to significantly improve test coverage.
- CLI Parser Helpers Tested: Implemented comprehensive tests for ores.cli's parser helpers, covering operation validation, format reading, and help output generation.
- Data Quality (DQ) Generators and Enums Validated: Introduced extensive tests for 12 different entity generators within ores.dq and validated the publication_mode enum's string conversions and round-trip functionality.
- Reference Data (RefData) Generators Covered: Provided new tests for 10 entity generators in ores.refdata, ensuring the correct generation of parties, counterparties, contacts, and identifiers.
- IAM Authorization and Session Conversion Tested: Added tests for ores.iam's authorization logic, including wildcard permissions, and verified the session_converter's data mapping and updates.
- Synthetic Data Generation Logic Verified: Enhanced test coverage for ores.synthetic, focusing on the generation_context's random distributions, UUID generation, and the catalog_generator_service's orchestration and reproducibility.
- Logging Utilities Tested: Added tests for ores.logging's boost_severity conversions, logging_options JSON streaming, and the logging_options_validator's configuration checks.
COMPLETED Improve generators with FK-aware test data code
Generators for entities with foreign key UUID columns (e.g. party_id,
counterparty_id, account_id) currently produce random UUIDs via
uuid_gen(). This means generated test data contains dangling references that
won't satisfy FK constraints in the database.
Affected generators:
party_identifier_generator:party_idFK topartycounterparty_identifier_generator:counterparty_idFK tocounterpartyparty_contact_information_generator:party_idFK topartycounterparty_contact_information_generator:counterparty_idFK tocounterpartyaccount_party_generator:account_idFK toaccount,party_idFK toparty
Proposed approach:
- Generators should accept optional parent entity references or generate parent entities first, then use their IDs.
- Alternatively, generators could accept a list of valid FK values to sample from.
- Update codegen templates so
generator_exprfor FK columns can reference other generators.
Actually we should create a generation context with a KVP where generations can leave data for other generators to pick up from.
Acceptance criteria:
- Generated test data has valid FK references.
- Existing generator API is preserved or extended in a backwards-compatible way.
COMPLETED Fix issues with accounts dialog code
This pull request addresses a specific display issue in the accounts list view and significantly enhances the robustness and maintainability of Qt delegates. It rectifies an off-by-one error that emerged after a new column was added to the account model. More broadly, it refactors delegates to use type-safe Column enums from their respective models instead of hardcoded integer indices, preventing future display bugs and simplifying column reordering or additions. The change also includes updated documentation to guide developers on this improved pattern.
Highlights:
- Accounts List View Fix: Fixed an off-by-one display error in the accounts list view that occurred after the AccountType column was introduced, ensuring correct field alignment.
- Public Column Enum for ClientAccountModel: Made the ClientAccountModel::Column enum public, allowing delegates and other consumers to reference column indices directly and safely, improving type safety and refactorability.
- Delegate Refactoring - AccountItemDelegate: Updated AccountItemDelegate to utilize the ClientAccountModel::Column enum, replacing previously hardcoded integer indices for column checks and formatting.
- Delegate Refactoring - ConnectionItemDelegate: Updated ConnectionItemDelegate to utilize the ConnectionTreeModel::Column enum, replacing hardcoded integer indices for column checks.
- Documentation Update: Added new documentation to the qt-entity-creator skill guide, detailing the best practice for delegates to reference their model's public Column enums instead of hardcoding indices.
COMPLETED Merge all databases into one code
This pull request significantly refactors the database lifecycle management by eliminating redundant infrastructure databases and introducing a more secure, two-phase creation process. The changes aim to simplify deployment, enhance security through least-privilege access for schema operations, and improve testing efficiency by moving away from template cloning to RLS-based tenant isolation. Utility functions are now universally accessible, reducing complexity and improving maintainability across different database instances.
Highlights:
- Database Simplification: Removed the dedicated ores_admin and ores_template databases, streamlining the database infrastructure. Environment databases now use direct creation, and testing leverages Row-Level Security (RLS) instead of template cloning for tenant isolation.
- Least-Privilege Database Creation: Implemented a two-phase database creation process. The create_database.sql script, run by a PostgreSQL superuser, handles infrastructure setup, while setup_schema.sql, executed by the ores_ddl_user, manages schema and data population, enforcing the principle of least privilege.
- Centralized Utility Functions: Relocated administrative utility functions (e.g., whimsical name generation, cleanup views) from the removed ores_admin database into a new create/utility/ directory. These functions are now prefixed with ores_utility_ and are available in every ORES database.
COMPLETED Enable all skipped tests code
Gemini's comment does not reflect the entire PR, all previously skipped tests are now running.
This pull request significantly enhances the robustness of our testing infrastructure by rectifying issues with synthetic data generation. By ensuring that generated test data adheres to foreign key constraints and uses valid reference values, a substantial number of previously skipped tests are now active. This change improves the reliability of our test suite and provides more comprehensive coverage for critical data integrity aspects.
Highlights:
- DQ Generator Fixes: Fixed DQ generators (coding_scheme, dataset, dataset_bundle_member) to produce valid pre-populated reference data instead of random faker words that previously caused database validation failures.
- IAM Test Updates: Updated account_party tests to utilize real party_ids obtained from tenant provisioning, resolving issues with soft foreign key validation that arose from using random UUIDs.
- Test Unskipping: Enabled 19 previously skipped tests across the DQ (14 tests) and IAM (5 tests) modules by addressing the underlying foreign key-aware generator requirements.
- Skip Count: Reduced the total test skip count from 25 to 6, with only tenant RLS tests remaining skipped.
COMPLETED Add central bank related LEIs code
This pull request significantly expands the coverage of Legal Entity Identifier (LEI) anchors by integrating key sovereign, central bank, and supranational entities. The update also refines the sector classification mechanism to more accurately identify central banks, preventing misclassification and ensuring appropriate data sampling. These changes enhance the robustness and accuracy of the LEI data processing and documentation.
Highlights:
- New LEI Anchors Added: Incorporated approximately 93 new GLEIF-verified LEIs covering sovereign bond issuers (33), central banks (51), and supranational financial institutions (9) into the anchor extraction pipeline.
- Enhanced Sector Classification: Introduced a new CENTRAL_BANK sector keyword detection with multilingual support (20 keywords) to accurately classify central banks, prioritizing it over the generic BANK classification and applying a 3x financial priority sampling.
- Data Refresh and Cleanup: Regenerated all subset files and SQL populate scripts using the January 23rd golden copy, and removed stale February 8th subset files to ensure data currency.
- Methodology Documentation Updated: Updated the methodology.txt file to reflect the newly added anchor sources and the refined sector classification logic.
COMPLETED Expand unit test coverage for ORE codegened types code
This pull request significantly enhances the robustness and reliability of the ORE system by introducing a comprehensive suite of unit and XML roundtrip tests across various domain components. It ensures that critical data structures can be correctly serialized to and deserialized from XML, maintaining data integrity throughout the process. Additionally, the PR updates the underlying domain type generation for better XML schema compatibility and provides a new, dedicated mechanism for retrieving system party information from the reference data repository.
Highlights:
- Comprehensive Testing for ORE Components: Added extensive unit tests for the ores.ore currency mapper, ensuring correct bidirectional mapping between domain objects and XML definitions. This includes tests for various field combinations and rounding types.
- XML Roundtrip Tests for Domain Types: Introduced XML serialization and deserialization roundtrip tests for 9 previously untested ORE domain types: simulation, crossAssetModel, creditsimulation, sensitivityanalysis, stresstesting, ore, calendaradjustment, counterpartyInformation, nettingsetdefinitions, and collateralBalances. This verifies data integrity through XML I/O.
- File I/O Roundtrip Tests: Implemented load_file and save_file roundtrip tests for key ORE domain types like currencyConfig, simulation, and todaysmarket, confirming reliable file-based persistence.
- Domain Type Regeneration and Enhancements: Regenerated ORE domain types using an updated xsdcpp tool, which now includes substitution group support. This resulted in the addition of numerous new structs and group types (nettingSetGroup_group_t, DerivedScheduleGroup_group_t, legDataType_group_t, underlyingTypes_group_t, exerciseDatesGroup_group_t, strikeGroup_group_t, creditCurveIdType_group_t) to domain.hpp for improved XML schema representation.
- Refdata Party Repository Update: Added a new read_system_party method to the party_repository in ores.refdata, allowing for direct retrieval of the system party for a given tenant. This is backed by a new PostgreSQL function ores_refdata_read_system_party_fn.
- Removal of Unused Code: Removed the parsing_error class, which was identified as unused, streamlining the codebase.
COMPLETED Add system party support code
As per design document.
- Improvements to tenant and party dialog
This pull request significantly improves the user experience for managing core entities like parties and tenants by upgrading input fields to dynamic combo boxes that fetch valid options from the server. It also refines the underlying system architecture by centralizing data lookup mechanisms and clarifying the distinction and handling of system-level parties versus operational parties, ensuring better data integrity and system behavior.
Highlights:
- Enhanced UI for Detail Dialogs: Replaced QLineEdit with QComboBox for 'Type' and 'Status' fields in Party, Counterparty, and Tenant detail dialogs, enabling asynchronous server-fetched lookup values for improved data entry and consistency.
- Centralized Lookup Fetching Logic: Extracted common server-side lookup fetching logic into a new LookupFetcher utility class, reducing code duplication across various detail dialogs.
- Refined System Party Management: Introduced an 'Internal' party type and 'WRLD' (World) business center for system/platform entities, renamed the system tenant to 'Root Tenant' and system party to 'System Party', and updated the tenant provisioner accordingly. System parties are now explicitly excluded from operational root party uniqueness checks.
- Improvements to bootstrapping
This pull request significantly enhances the user experience for managing parties and counterparties by introducing dynamic dropdowns for key attributes, replacing manual text entry with controlled selections. It also streamlines the system's initial setup by enabling pre-population of admin credentials during provisioning. Furthermore, the database's foundational data seeding for system entities has been refined, and extensive documentation on the database lifecycle has been added to improve developer understanding and maintainability.
Highlights:
- UI Enhancements for Party and Counterparty Details: Replaced free-text input fields (QLineEdit) with dynamically populated dropdowns (QComboBox) for 'partyType', 'status', and 'partyCategory' in the CounterpartyDetailDialog and PartyDetailDialog. These comboboxes fetch their options from backend lookup services, ensuring data consistency and improving user experience.
- Dynamic Lookup Population: Introduced populateLookups() methods in both CounterpartyDetailDialog and PartyDetailDialog. These methods asynchronously fetch available party types and statuses from the backend using ClientManager and QtConcurrent::run, populating the new comboboxes upon dialog initialization.
- System Provisioning Pre-fill Capability: Modified the showSystemProvisionerWizard function in MainWindow to accept optional username and password parameters. This allows the System Provisioner Wizard to pre-fill the admin account creation form with credentials provided during the login process, streamlining the bootstrap setup.
- Refined Database Seeding for System Party: Updated the tenant provisioning SQL script (iam_tenant_provisioner_create.sql) to automatically seed a 'WRLD' (World) business center and assign it to the system party. The system party's type is now explicitly set to 'Internal', ensuring proper categorization and validation from the outset.
- Comprehensive Database Lifecycle Documentation: Added a new, detailed documentation file (database_lifecycle.org) that outlines the database creation, population, and teardown processes. It covers multi-environment architecture, database roles, user management, and testing infrastructure, providing a central reference for developers.
COMPLETED Add customer party support code
This pull request significantly enhances the data librarian's publication capabilities by introducing optional dataset members and a new wizard page for their selection. This change addresses previous issues with LEI data publication dependencies and provides greater flexibility for users to choose which datasets to include. It also includes a protocol version bump and a utility script improvement for database environment management, laying the groundwork for future party-scoped counterparty features.
Highlights:
- Optional Dataset Bundle Members: Introduced an 'optional' flag for dataset bundle members, allowing certain datasets (like LEI) to be selectively published based on user choice.
- Enhanced Publish Bundle Wizard: Implemented a new 'OptionalDatasetsPage' in the publish bundle wizard, providing a user interface to opt-in or opt-out of optional datasets. Counterparty datasets are initially disabled with a tooltip, pending a future migration.
- Improved LEI Publication Dependencies: Added crucial missing dataset dependencies for LEI parties and counterparties to ensure correct publication ordering and data integrity, resolving a previous tenant provisioning failure.
- Dynamic Dataset Publication Logic: Modified the SQL publish function to automatically skip optional datasets that are not explicitly selected by the user in the wizard, streamlining the publication process.
- Protocol Version Update: Bumped the communication protocol version from 28.0 to 29.0 to accommodate the new 'optional' field serialization for dataset bundle members.
- Database Environment Management: Added a '–kill' flag to the 'recreate_env.sh' script, enabling termination of active database connections before environment recreation, improving developer workflow.
- Product Backlog Refinement: Cleaned up the product backlog by removing several outdated or completed items, and moved some items to a sprint backlog.
- Librarian Publication Design Document: Added a new design document detailing the strategy for moving LEI party and counterparty publication to the data librarian, outlining a two-phase approach for future development.
COMPLETED Add party types lookup table code
Rationale: implemented.
Create ores_refdata_party_types_tbl (or similar) with two types: system and
operational. The system party is auto-created during tenant provisioning. The
operational type is for business entities created by users.
COMPLETED Add RLS-aware tenant provisioning for tests code
Rationale: implemented.
Repository tests for the tenant entity cannot use the standard
database_helper because the database has Row-Level Security (RLS) policies on
the tenant table. The test session runs under an existing test tenant context,
and RLS prevents that session from inserting new tenants via the normal
repository path.
This is a separate problem from FK-aware generators (which solve dangling foreign key references). The tenant issue is that the security policy itself blocks the operation entirely.
Possible approaches:
- A privileged
tenant_provisioning_helperthat uses direct SQL withSET LOCAL role = 'admin'or similar role escalation. - A superuser/admin database context that bypasses RLS for tenant provisioning.
- Pre-seeding test tenants outside the RLS-scoped transaction.
Affected tests:
repository_tenant_repository_tests.cpp: all 6 TEST_CASEs are currently SKIP'd with "Requires RLS-aware tenant provisioning".
Acceptance criteria:
- Tenant repository tests can create, read, and query tenants in a test context.
- The solution does not weaken RLS policies in production.
- All 6 SKIP'd tenant tests are re-enabled and passing.
COMPLETED Rename tenant types code
Rationale: implemented.
Rename existing tenant types: platform to system, organisation to
production, test to automation. Add new evaluation type. Update
population scripts, validation functions, and any code referencing old type
names.
See doc/plans/2026-02-09-party-isolation-and-tenant-types-design.org for the
rationale and full type descriptions.
COMPLETED Add tenant CRUD commands to CLI code
Rationale: implemented.
We need to be able to add new tenants, list tenants, etc.
COMPLETED Add roles for Super Admin code
Rationale: implemented.
We need to distinguish between the tenant admin and the "super" admin. These should have different roles.
CANCELLED Split create schemas from main populate script code
Rationale: not using schemas any longer.
We should probably add a create schemas script.
COMPLETED Clicking save on connections causes exit code
Rationale: implemented.
Asks if we want to exit. Also clicking save several times creates folders with the same name.
COMPLETED Make the icon theme "configurable" code
Rationale: implemented.
While we are trying to find a good icon theme, it should be possible to change the icons without having to rebuild. Ideally without having to restart, but if we have to restart that's not too bad.
COMPLETED Tests are logging to stdout in github code
Rationale: Seem to log correctly now. Maybe it's because logging is disabled.
There is a lot of stdout output in CDash. We need to understand why that is.
Test output
[2025-12-16 20:31:44.600851] [0x00000001f1d1a200] [info] Test run starting, creating test database
[2025-12-16 20:31:44.601397] [0x00000001f1d1a200] [info] Generated test database name: oresdb_test_4816_1242
[2025-12-16 20:31:44.601401] [0x00000001f1d1a200] [info] Creating test database: oresdb_test_4816_1242
[2025-12-16 20:31:44.601434] [0x00000001f1d1a200] [info] Creating context. Configuration: {"database_options":{"user":"ores","host":"localhost","database":"postgres","port":5432},"pool_size":1,"num_attempts":10,"wait_time_in_seconds":1}
[2025-12-16 20:31:44.630284] [0x00000001f1d1a200] [info] Finished creating context.
[2025-12-16 20:31:44.771670] [0x00000001f1d1a200] [info] Successfully created test database: oresdb_test_4816_1242
[2025-12-16 20:31:44.771733] [0x00000001f1d1a200] [info] Setting ORES_TEST_DB_DATABASE environment variable to: oresdb_test_4816_1242
[2025-12-16 20:31:44.771738] [0x00000001f1d1a200] [info] Environment variable set successfully
[2025-12-16 20:31:44.771740] [0x00000001f1d1a200] [info] Test database ready: oresdb_test_4816_1242
[2025-12-16 20:31:44.772151] [0x00000001f1d1a200] [info] Test case starting: delete_account_response_failure
[2025-12-16 20:31:44.772158] [0x00000001f1d1a200] [info] Tags: messaging #messaging_protocol_tests
COMPLETED Unsubscribe before logout code
Rationale: implemented.
On logout we see the following:
2025-12-11 22:45:54.559906 [INFO] [ores.accounts.messaging.accounts_message_handler] Successfully logged out account: 019a5e49-476c-70ce-9909-3887cae700e9 2025-12-11 22:45:54.559940 [DEBUG] [ores.comms.messaging.message_dispatcher] Successfully dispatched message, response type logout_response (0x200e) correlation_id=763 2025-12-11 22:45:54.559978 [DEBUG] [ores.comms.messaging.frame] Serialised frame logout_response (0x200e), size: 58 2025-12-11 22:45:54.560005 [DEBUG] [ores.comms.net.connection] Writing frame of size 58 type: logout_response (0x200e) sequence: 767 2025-12-11 22:45:54.560083 [DEBUG] [ores.comms.net.connection] Successfully wrote frame 2025-12-11 22:45:54.560113 [DEBUG] [ores.comms.net.session] Sent response for message type logout_request (0x200d) 2025-12-11 22:45:54.560137 [INFO] [ores.comms.net.session] Logout completed, closing connection 2025-12-11 22:45:54.560200 [ERROR] [ores.comms.net.session] Exception in notification writer: co_await: Operation canceled [system:125] 2025-12-11 22:45:54.560233 [DEBUG] [ores.comms.net.session] Notification writer coroutine ended 2025-12-11 22:45:54.560281 [INFO] [ores.comms.net.session] Unregistering session '127.0.0.1:38366' from subscription manager
We should probably unsubscribe before we logout.
COMPLETED Use events in comms and accounts code
Rationale: implemented.
Now we have an event bus, we should create events for:
- connect, disconnect, retry
- login, logout
COMPLETED Fix OSX build code
Build is broken at present in Setup Database step:
0s
Run ./projects/ores.sql/recreate_database.sh -y \
Error: Missing required passwords:
- postgres (-p or PGPASSWORD)
- ddl (-d or ORES_DB_DDL_PASSWORD)
- cli (-c or ORES_DB_CLI_PASSWORD)
- wt (-w or ORES_DB_WT_PASSWORD)
- comms (-m or ORES_DB_COMMS_PASSWORD)
- http (-h or ORES_DB_HTTP_PASSWORD)
- test_ddl (-t or ORES_TEST_DB_DDL_PASSWORD)
- test_dml (-T or ORES_TEST_DB_PASSWORD)
- ro (-r or ORES_DB_READONLY_PASSWORD)
Set via command line flags or environment variables.
This pull request primarily addresses a critical compatibility issue affecting the macOS CI pipeline by implementing a more portable argument parsing solution in key database and environment setup scripts. This change ensures that the scripts execute correctly on macOS systems, which do not support GNU-specific getopt long options, thereby stabilizing the CI process. Additionally, the pull request includes a substantial update to the project's product backlog, reflecting ongoing planning and prioritization of future development tasks.
Highlights:
- macOS CI Fix: Replaced GNU getopt with a portable while/case argument parsing mechanism in recreate_database.sh and recreate_env.sh to resolve CI failures on macOS, which uses BSD getopt.
- Argument Parsing Portability: Ensured all existing command-line options (-p, -d, -c, -w, -m, -h, -t, -T, -r, -D, -y, –no-sql-validation, -H) are preserved and function correctly across different getopt implementations.
- Product Backlog Update: Significantly updated the product backlog document, adding numerous new stories and removing several completed or cancelled items across various categories like UI, database features, and infrastructure.
COMPLETED Add pagination to counterparty code
This pull request significantly enhances the counterparty dialog by introducing comprehensive pagination support across the application stack. It modifies the communication protocol to include offset and limit parameters for requests and a total count for responses, enabling efficient retrieval of large datasets. The UI has been updated with a dedicated pagination widget, providing users with intuitive controls for navigating through counterparty lists and dynamically adjusting page sizes.
Highlights:
- Protocol Updates for Pagination: Introduced pagination parameters (offset, limit) to the get_counterparties_request protocol message and added total_available_count to the get_counterparties_response to inform the client about the total number of available records. The major protocol version was bumped to 31.0 due to these wire format changes.
- Client-Side Pagination Logic: Implemented comprehensive pagination logic within the ClientCounterpartyModel, including new methods for loading specific pages (load_page), fetching more data (fetchMore), and dynamically adjusting page sizes (set_page_size). This also includes handling duplicate entries during incremental loads.
- User Interface Integration: Integrated a new PaginationWidget into the CounterpartyMdiWindow to provide users with intuitive UI controls for page navigation, dynamic page size adjustment, and a 'Load All' functionality for smaller datasets.
- Backend Pagination Support: Extended the counterparty_repository and counterparty_service layers with new methods to support paginated data retrieval (read_latest(offset, limit)) and efficient total count calculation (get_total_count()) directly from the database.
COMPLETED Add support for business centres code
At present we do not have full support for CRUD on business centres.
This pull request introduces a new business_centre reference data type, providing a complete end-to-end solution for its management. It encompasses the full C++ backend, including data persistence, business logic, and communication protocols, alongside a rich Qt user interface for interactive data handling. The changes also include crucial database schema updates and a UI stability fix, significantly expanding the application's capabilities in managing financial reference data.
Highlights:
- New Business Centre Domain Type: Introduced a comprehensive C++ backend for the business_centre domain type, including its domain class, database entity, data mapper, repository, service, protocol messages (0x1061-0x1068), data generator, eventing, and JSON/table I/O capabilities. This establishes a full data management lifecycle for business centre reference data.
- Full Qt User Interface: Developed a complete Qt-based user interface for managing business centres. This UI features a paginated list window, a detail dialog for creating, editing, and viewing individual business centre records, and a version history dialog that includes field-by-field diffs. A dedicated controller manages the window lifecycle and interactions.
- Database Schema and Population Enhancements: Added a country_alpha2_code column to the business_centres SQL schema. Corresponding population functions were updated to derive and validate this country code from the business centre's code, ensuring data integrity and consistency.
- UI Bug Fix: Resolved an issue where combo boxes in detail dialogs would appear blank due to incorrect cross-thread QPointer access, improving the stability and usability of the Qt application.
- Documentation Updates: Expanded documentation to include details on LEI-to-BIC mapping data and a new domain documentation file for Standing Settlement Instructions (SSI), enhancing the knowledge base for financial reference data.
COMPLETED Add LEI to BIC dataset code
In order to simulate settlements it seems we also need the BIC. We have added the CSV to external, but we need to create dataset, population scripts and the associated publisher.
Links:
COMPLETED Add proper party short-codes code
At present we have fairly random short-codes. Seems like we are incorrectly using the LEI.
This pull request significantly enhances the system's ability to manage and display entity information by introducing robust short code generation and comprehensive support for transliterated names. These changes improve data quality and user experience, particularly for global entities. Additionally, it refactors the Qt UI's data fetching mechanisms to standardize pagination and network requests, leading to a more consistent and maintainable codebase.
Highlights:
- Short Code Generation: Introduced new SQL utility functions, ores_utility_strip_corporate_suffix_fn and ores_utility_generate_short_code_fn, to create 4-8 character mnemonic short codes from entity names, including collision resolution. This enhances entity identification, especially for internal entities without LEIs.
- Transliterated Name Support: Added a transliterated_name column across the entire stack (SQL, C++ domain/entity/mapper/protocol, Qt UI) for party and counterparty entities. This supports non-Latin entity names from sources like GLEIF data, improving global data handling.
- LEI Data Integration: Updated the LEI entities artefact staging table to include entity_transliterated_name_1 and its type, and registered gleif.lei_parties and gleif.lei_counterparties datasets to enable their publication via the bundle publisher.
- Qt Pagination Standardization: Removed infinite-scroll (canFetchMore/fetchMore) from all six Qt entity models, standardizing data loading on the PaginationWidget for explicit page controls, improving UI consistency and control.
- Network Request Refactoring: Standardized all Qt entity models to use process_authenticated_request for network communication, replacing manual sendRequest and frame construction, which streamlines and secures network interactions.
- Protocol Version Bump: Incremented PROTOCOL_VERSION_MAJOR from 31 to 32 to reflect the breaking change introduced by the new optional transliterated_name wire field.
- Analysis by Gemini
In the trading world, these are often referred to as Mnemonic Codes or Ticker Aliases. While large institutions rely on LEIs or SWIFT BICs for settlement, traders and middle-office users prefer "Short Codes" (usually 4–8 characters) for quick data entry and terminal commands.
There isn't a single universal standard, but there are several industry-standard heuristics used to generate them automatically while ensuring they remain human-readable.1.
The "Consonant-Heavy" Heuristic
This is the most common algorithm for generating readable abbreviations. It mimics how humans naturally "speed-read" words.
- Rule: Keep the first letter, then strip all vowels (A, E, I, O, U) and spaces/symbols, keeping only the subsequent consonants until a length limit is reached.
- Example: GOLDMAN SACHS -> GLDMN
- Example: BARCLAYS -> BRCLYS2.
The "3-3" or "4-2" Chunking Heuristic
Used frequently in older European banking systems (like the early days of SWIFT or Reuters).Rule: Take the first 3 characters of the first word and the first 3 characters of the second word.
- Example: MORGAN STANLEY -> MORSTA
- Example: DEUTSCHE BANK -> DEUBAN
- Refinement: If it's a single word, take the first 6 characters (APPLE -> APPLE_)
The Acronym + Location Heuristic
Professional systems often need to distinguish between branches of the same legal entity.
- Rule: [Acronym of Name] + [ISO Country/City Code]
- Example: JP Morgan London -> JPMLON
- Example: Société Générale Paris -> SOCGENPAR4.
Algorithmic Handling of Collisions
No matter how good your heuristic is, you will eventually hit a collision (e.g., CITI for Citibank and Citigroup). In a trading system, a short code must be unique.
The Collision Workflow:
- Generate the base mnemonic (e.g., MS).
- Check the database (Master + Staging).
- Iterate: If MS exists, append a digit or take the next consonant.
- MS -> MS2
- GLDMN -> GLDMS
COMPLETED Polish party and counterparty list UI code
Several UI polish items for the party and counterparty list windows.
- Capitalise party category values properly (Operational, System, Internal).
- Add country flag icon to parties and counterparties based on business centre.
- Business centre field should be a combo box (not free text).
This pull request significantly enhances the user interface for managing parties and counterparties by improving data consistency and usability. It standardizes party category values to a capitalized format across the backend and frontend, introduces visual cues with country flag icons in list views for better identification, and upgrades the business center input to a server-populated, editable combo box, streamlining data entry and reducing errors.
Highlights:
- Party Category Standardization: Standardized party category values (System, Operational, Internal) to use capitalization across database schemas, C++ constants, and related scripts for consistency.
- Country Flag Icons in List Views: Introduced country flag icons in the party and counterparty list views, reordering columns to display the flag and business center code prominently for improved visual identification.
- Enhanced Business Center Input: Converted the free-text business center input field in party and counterparty detail dialogs into an editable combo box, populated dynamically from the server, streamlining data entry and reducing errors.
COMPLETED Separate party identifiers into dedicated table code
LEI is currently used as the party/counterparty code, which prevents internal
entities that don't have an LEI. Identifiers like LEI, BIC, and other schemes
need to live in a separate junction table (party_identifiers).
- LEI should not be the primary code for parties or counterparties.
- Internal counterparties have no LEI; need a generated short code instead.
- LEI, BIC, and other identifier schemes belong in a dedicated table.
- Party and counterparty detail dialogs need tabs to display identifiers.
Related story: "Add proper party short-codes".
COMPLETED Improvements to counterparty and party UI code
This pull request significantly polishes the user experience for entity list windows and strengthens the underlying data model for party and counterparty identifiers. It addresses issues with duplicate identifier entries by introducing cardinality constraints in the database and improves UI consistency and usability through standardized column resizing, intelligent name display for multi-script data, and robust, centralized window settings persistence.
Highlights:
- Enhanced Identifier Handling: Modified database schemas and triggers to support multi-valued identifiers for parties and counterparties, introducing max_cardinality for identifier schemes to prevent duplicate key violations, particularly for BIC mappings.
- Improved UI for Entity Lists: Refined the display of entity lists by renaming "Business Center" to "Centre", merging transliterated names into the main "Name" column with non-Latin text detection, and standardizing column sizing to ResizeToContents.
- Centralized Settings Management: Consolidated window settings persistence logic into the EntityListMdiWindow base class, ensuring consistent saving and restoration of window sizes and header states across all MDI sub-windows, including versioning for header layouts.
- New Text Utility: Introduced a TextUtils utility class to facilitate detection of non-Latin characters and intelligent formatting of names with transliterations.
COMPLETED Implement party-level RLS isolation code
Add a second layer of Row-Level Security that isolates party-scoped data within
a tenant. At login, compute the user's visible party set via a recursive CTE on
the party hierarchy and store it as PostgreSQL session variables
(app.current_party_id, app.visible_party_ids). Extend the C++ database
layer to propagate party context. Introduce party_counterparties as the first
party-scoped junction table with an RLS policy to prove the pattern end-to-end.
See projects/ores.refdata/modeling/multi_party.org and
doc/plans/2026-02-09-party-isolation-and-tenant-types-design.org for the full
architecture.
This pull request significantly enhances data isolation capabilities by introducing party-level Row-Level Security (RLS). This new layer of security works in conjunction with existing tenant isolation to provide granular control over data visibility based on party hierarchies. The changes span across the database, C++ application layers, and code generation, ensuring that data access is appropriately scoped for different user types, from system administrators to individual operational parties.
Highlights:
- Party-Level Row-Level Security (RLS): Implemented a new layer of RLS to isolate party-scoped data, ensuring operational parties only see data assigned to them, while system parties retain full subtree visibility.
- New Junction Table: party_counterparties: Introduced the party_counterparties junction table as the first party-scoped table with dual RLS policies (tenant + party) to demonstrate the new isolation pattern.
- Database Context Extension: Extended the C++ database layer (tenant_aware_pool, context) to propagate party_id and visible_party_ids, setting corresponding PostgreSQL session variables upon connection acquisition.
- Session and Comms Layer Integration: Propagated party context through the session/comms layer (session_data, session_info, tenant_aware_handler) to ensure all downstream handlers receive party-scoped database contexts.
- Login Flow Party Resolution: Enhanced the login flow to resolve party assignments via account_parties and compute the visible party set using a recursive CTE SQL function.
- Codegen Template Improvements: Fixed C++ junction codegen templates for tenant_id, UUID handling, schema, field naming, and removed inapplicable service/protocol mappings for junction tables.
- Sub-task 1: SQL — visible party set computation
Create a PostgreSQL function
ores_refdata_visible_party_ids_fn(p_tenant_id uuid, p_party_id uuid)that returnsuuid[]using the recursive CTE from the design document. The function traverses the party hierarchy starting from the given party, collecting the party itself and all descendants. For the system party, this returns all parties in the tenant.Also create a helper function
ores_iam_current_party_id_fn()(analogous toores_iam_current_tenant_id_fn()) that readsapp.current_party_idfrom the session, andores_iam_visible_party_ids_fn()that reads and castsapp.visible_party_idstouuid[]. - Sub-task 2: C++ — extend
tenant_aware_poolwith party context
Add optional
party_idandvisible_party_idsfields totenant_aware_pool. When set,acquire()also executesSET app.current_party_idandSET app.visible_party_idsafter the existing tenant variable. When not set (party-unaware context), only tenant variables are set as before. - Sub-task 3: C++ — extend
contextwithwith_party()
Add
context::with_party(tenant_id, party_id, visible_party_ids)method that creates a new context sharing the underlying connection pool but with party awareness. The returned context's pool sets all three session variables on acquire. - Sub-task 4: C++ — extend
session_datawith party fields
Add
party_id(boost::uuids::uuid) andvisible_party_ids(std::vector<boost::uuids::uuid>) to thesession_datastruct inores.comms. Updatesession_converterto populate these fields. - Sub-task 5: Login flow — party resolution
After authentication in the login handler, query
account_partiesto find the user's parties. For single-party users, auto-select. For multi-party users, select the first party (party picker protocol is a future story). Compute the visible party set by calling the SQL function from sub-task 1. Populatesession_datawith party context.On
make_request_context()(or equivalent), usectx.with_party()to create a party-aware database context from the session's party fields. - Sub-task 6:
party_counterpartiesjunction table
Create
ores_refdata_party_counterparties_tblas the first party-scoped table. This is a bitemporal junction table mapping counterparties to the parties that can see them. Columns:tenant_id,party_id,counterparty_id, plus the standard audit trail (version,modified_by,performed_by,change_reason_code,change_commentary,valid_from,valid_to).Add tenant RLS policy (as per existing pattern) plus a party RLS policy:
party_id = ANY(ores_iam_visible_party_ids_fn()).Create domain type, repository, and generator following codegen patterns.
- Sub-task 7: Integration tests
Write tests that exercise party-level isolation end-to-end:
- Create a tenant with system party + two operational parties (A, B).
- Assign counterparties: some to party A only, some to party B only, some to both.
- Log in as party A user: verify only party A's counterparty assignments visible.
- Log in as system party user: verify all assignments visible.
- Create a nested hierarchy (parent → child): log in as parent, verify subtree visible; log in as child, verify only child visible.
COMPLETED Fix audit trail metadata for recorded_by and modified_by code
Audit trail fields are inconsistent across entities. The user who performed the action is often not correctly recorded, and the UI does not clearly surface this information.
- Counterparties and other librarian data are recorded by DDL user, not the user running the import.
modified_byandperformed_bymust have a soft FK against accounts table.- Super admin is "modified by" bootstrap; should have been a valid account.
- Tenant admin is "recorded by" onboarding; should have been super admin.
- No "performed by" in UI. Confusing: we use
modified_byandrecorded_bysomewhat randomly — need to standardise terminology.
Related stories: "Add entity messages should not set modified by", "Investigate how performed by is being set", "Add system account".
COMPLETED Investigate how performed by is being set code
It should just be the database account.
COMPLETED Add "system" account code
Modified by must always map to an existing account. We need to create an account that cannot login and which is used for all of the initial population.
Publication should be done using the new admin account, not the system account.
COMPLETED Add entity messages should not set modified by code
At present you can supply any modified by you want in the protocol messages. It makes more sense to say the message must have the modified by as the user logged in from the session.
COMPLETED Add generation context with KVP for audit trail fields code
Generators for test data currently hardcode faker::internet::username() for
modified_by. After the trigger-based validation of modified_by against the
accounts table (PR #447), this causes test failures whenever the accounts table
is non-empty: the faker username is not the DB session user and does not exist in
the accounts table.
The earlier story "Improve generators with FK-aware test data" proposed a generation context with a KVP where generators can leave data for other generators to pick up. This story extends that idea to audit trail fields.
Proposed approach:
- Create a
generation_contextstruct (or extend the existing one inores.synthetic) that holds astd::unordered_map<std::string, std::string>for well-known keys. - Define well-known key constants:
modified_by,tenant_id,parent_party_idetc. - All generators accept an optional
const generation_context¶meter. - Test helpers (
database_helper,scoped_database_helper) provide a pre-populated context viamake_generation_context()that setsmodified_bytodb_user(),tenant_idto the test tenant, etc. - Update codegen templates (
cpp_domain_type_generator.cpp.mustache) to generate context-aware signatures. - Re-enable strict username validation in
ores_iam_validate_account_username_fn(currently relaxed to allow any non-empty value).
Acceptance criteria:
- All generators accept a generation context for
modified_by. - Test helpers provide a pre-populated context.
- Trigger validation function strictly validates
modified_byagainst accounts table. - All tests pass with strict validation enabled.
This pull request significantly overhauls the synthetic data generation infrastructure to provide a more robust and flexible system. By introducing a decomposed generation_context with separate concerns for randomness and contextual data, it enables generators to produce data that consistently satisfies complex database constraints, such as audit trail validation and foreign key references. This change streamlines the generation process, making it more adaptable for various use cases, including testing, CLI tools, and UI interactions.
Highlights
- Synthetic Data Generation Refactor: The core generation_context has been decomposed into three distinct, composable types: generation_engine (handling randomness and UUIDs), generation_environment (providing a scoped key-value store with parent-chain lookup), and a new generation_context that composes both. This enhances modularity and control over synthetic data generation.
- Widespread Generator Migration: Approximately 36 generators across 6 components (iam, refdata, dq, assets, connections, synthetic) have been migrated to accept the new generation_context& parameter. This allows generators to dynamically look up contextual data like modified_by and tenant_id from the environment, replacing hardcoded values or ad-hoc parameters.
- Test Helper Integration: A new make_generation_context() factory has been added to ores.testing. This factory populates the modified_by field from db_user() and tenant_id from the test helper, ensuring generated entities pass trigger-based audit trail validation in test environments.
- Strict Audit Trail Validation Re-enabled: The strict modified_by validation in the iam_tenant_functions_create.sql script has been re-enabled. This was previously relaxed but can now be enforced due to the improved generation_context providing proper modified_by values.
- Codegen Template Updates: Codegen templates have been updated to reflect the new generator signatures and the pattern of looking up modified_by and tenant_id from the generation_context environment.
COMPLETED Enforce root party uniqueness constraints code
Each tenant must have exactly two root parties: one system party (auto-created during provisioning) and one operational root party (the "house"). Validate this constraint at the service layer and prevent additional root parties from being created.
COMPLETED Add a setup new tenant wizard code
Just like we did a new system provisioner, we need a new tenant provisioner that takes into account:
- GLEIF based party setup
- GLEIF based counterparty setup
We should make it clear it's evaluation.
COMPLETED Gate party and counterparty wizard steps by tenant type code
Party and counterparty setup steps in the tenant provisioning wizard should only be available for evaluation tenants. For production tenants, show these steps as disabled with an explanation that production party setup requires a different workflow.
COMPLETED Improve tenant provisioning wizard UX code
Multiple UX issues with the current tenant provisioning wizard.
- Rename wizard to evoke "evaluation tenant provisioning" (not generic).
- Move wizard off main menu; access via icon on tenants dialog only.
- State clearly that only evaluation tenants can be provisioned from there.
- Capitalise tenant type display values (Production, Evaluation).
- Tenant code column is too wide in the tenant list.
- Default tenant type to evaluation (production support added later).
- System party name should evoke "tenant system party" (not use tenant name).
- Root party should default to tenant name.
- Add password match indicator (tick/cross) for new tenant account creation.
This pull request significantly enhances the tenant provisioning wizard by introducing the ability to generate synthetic organizational data. This feature allows users to rapidly set up new tenants with realistic, yet artificial, financial entities and structures, bypassing the need for real-world data imports. It provides a flexible and efficient way to create test or demonstration environments, improving development and testing workflows.
Highlights:
- Synthetic Organisation Generation: Introduced a new 'Synthetic' subsystem that allows for the generation of realistic, interconnected organisational data, including parties, counterparties, business units, portfolios, and trading books, complete with addresses and identifiers.
- Tenant Provisioning Wizard Integration: Integrated the synthetic data generation capability directly into the tenant provisioning wizard, adding a new 'Data Source Selection' page where users can choose between GLEIF registry data or synthetic generation.
- Configurable Generation Options: Provided configurable options for synthetic data generation within the wizard, allowing users to specify country, counts for parties, counterparties, portfolios, and business units, and whether to generate addresses and identifiers.
- Streamlined Synthetic Workflow: Implemented logic to skip the LEI/counterparty setup pages in the wizard when synthetic data generation is selected, streamlining the provisioning process for test environments.
- New Messaging Protocol: Defined new message types (generate_organisation_request and generate_organisation_response) and a dedicated message range (0x7000-0x7FFF) for the synthetic subsystem to handle generation requests.
- Modular Service Architecture: Developed organisation_generator_service for creating the synthetic data structures and organisation_publisher_service for persisting them to the database, ensuring a clean separation of concerns.
- Tree Generation Utility: Added a generic tree_builder utility to ores.utility for generating hierarchical data structures, which is leveraged by the synthetic organisation generator.
COMPLETED Add evaluation tenant onboarding wizard on first login code
When logging in to a new evaluation tenant for the first time, show a provisioning wizard that offers to install a catalogue and set up the tenant. Users should be able to cancel without making any changes. The wizard should stop appearing once a root party exists (i.e. a party other than the tenant system party).
Related story: "Add GLEIF-based evaluation tenant onboarding wizard".
COMPLETED Business unit entity code
Represents internal organizational units (e.g., desks, departments, branches). Supports hierarchical structure.
| Field | Type | Description | Foreign Key Reference |
|---|---|---|---|
| unit_id | INT | Primary key | — |
| party_id | UUID | Top-level legal entity this unit belongs to | → party |
| parent_business_unit_id | INT | References parent unit (self-referencing) | → business_unit.unit_id (nullable) |
| unit_name | TEXT | Human-readable name (e.g., "FX Options Desk") | — |
| unit_id_code | TEXT | Optional internal code or alias | — |
| business_centre | TEXT | Business centre for the unit | → business centre scheme |
business_centre may be null (for example, we may want to have global desk and then London desk.
COMPLETED Book and Portfolio entities code
Support a single, unified hierarchical tree for risk aggregation and reporting (Portfolios) while maintaining operational accountability and legal/bookkeeping boundaries at the leaf level (Books).
- Portfolio
Logical Aggregation Nodes. Represents organizational, risk, or reporting groupings. Never holds trades directly.
Field Type Description portfolio_id (PK) UUID Globally unique identifier. parent_portfolio_id UUID (FK) Self-referencing FK. NULL = root node. name TEXT Human-readable name (e.g., "Global Rates", "APAC Credit"). owner_unit_id INT (FK) Business unit (desk/branch) responsible for management. purpose_type ENUM 'Risk', 'Regulatory', 'ClientReporting', 'Internal'. aggregation_ccy CHAR(3) Currency for P&L/risk aggregation at this node (ISO 4217). is_virtual BOOLEAN If true, node is purely for on-demand reporting (not persisted in trade attribution). created_at TIMESTAMP Audit trail. Note: Portfolios do not have a legal_entity_id. Legal context is derived from descendant Books.
- Book
Operational Ledger Leaves. The only entity that holds trades. Serves as the basis for accounting, ownership, and regulatory capital treatment.
Field Type Description book_id (PK) UUID Globally unique identifier. parent_portfolio_id UUID (FK) Mandatory: Links to exactly one portfolio. name TEXT Must be unique within legal entity (e.g., "FXO_EUR_VOL_01"). legal_entity_id UUID (FK) Mandatory: References party.party_id (must be an LEI-mapped legal entity). ledger_ccy CHAR(3) Functional/accounting currency (ISO 4217). gl_account_ref TEXT Reference to external GL (e.g., "GL-10150-FXO"). May be nullable if not integrated. cost_center TEXT Internal finance code for P&L attribution. book_status ENUM 'Active', 'Closed', 'Frozen'. is_trading_book BOOLEAN Critical for Basel III/IV: distinguishes Trading vs. Banking Book. created_at TIMESTAMP For audit. closed_at TIMESTAMP When book_status = 'Closed'. Objectives:
- Strict separation: Portfolios = logical; Books = operational
- Legal ownership at Book level → critical for regulatory capital, legal netting, tax
- Hierarchy via parent_portfolio_id
- Trading vs. Banking book flag → Basel requirement
Hierarchy Integrity Constraints:
- Rule: A Portfolio must not directly contain another Portfolio and a Book at
the same level if that violates business policy.
- Enforce via application logic or DB constraint (e.g., CHECK that a Portfolio is either "container-only" or "leaf-container", but typically Portfolios can contain both sub-Portfolios and Books—this is normal).
- Cycle Prevention: Ensure no circular references (parent → child → parent). Use triggers or application validation.
- Multi-Legal Entity Support: Your model allows Books under the same Portfolio
to belong to different legal entities. Is this intentional?
- Allowed in some firms (for consolidated risk views).
- Forbidden in others (e.g., regulatory ring-fencing).
- Recommendation: Add a validation rule (application-level): If a Portfolio contains any Books, all descendant Books must belong to the same legal_entity_id.” Or, if mixed entities are allowed, flag the Portfolio as 'MultiEntity' in purpose_type.
- Trade Ownership: Explicitly state: Every trade must have a book_id (FK). No trade exists outside a Book. This is implied but should be documented as a core invariant.
- Lifecycle & Governance: Add version or valid_from/valid_to if Books/Portfolios
evolve over time (e.g., name changes, reorgs).
- Especially important for audit and historical P&L.
- Consider owner_person_id (trader or book manager) for Books.
- Naming & Uniqueness:
Enforce: (legal_entity_id, name) must be unique for Books.
- Prevents ambiguous book names like "RatesDesk" used by two entities.
- Book Closure Policy: When a Book is Closed, should existing trades remain?
- Yes (typical). But no new trades allowed.
- Your book_status covers this
Combined Hierarchy Rules (Refined):
Rule Description Leaf Invariant Only Books may hold trades. Portfolios are purely aggregators. Single Parent Every Book and non-root Portfolio has exactly one parent. Legal Entity Scope A Book declares its legal owner. A Portfolio’s legal scope is the union of its Books’ entities. Permissioning Trade permission → granted on book_id. View/Analyze permission → granted on portfolio_id (includes subtree) Accounting Boundary P&L, capital, and ledger entries are computed per Book, then rolled up through Portfolios in aggregation_ccy.
COMPLETED Add business centre scheme entity code
The following is the analysis for adding support to party schemes.
Note: add a foreign key to the country table, which may be null in some cases.
The coding-scheme accepts a 4 character code of the real geographical business calendar location or FpML format of the rate publication calendar. While the 4 character codes of the business calendar location are implicitly locatable and used for identifying a bad business day for the purpose of payment and rate calculation day adjustments, the rate publication calendar codes are used in the context of the fixing day offsets. The 4 character codes are based on the business calendar location some of which based on the ISO country code or exchange code, or some other codes. Additional business day calendar location codes could be built according to the following rules: the first two characters represent the ISO 3166 country code [https://www.iso.org/obp/ui/#search/code/], the next two characters represent either a) the first two letters of the location, if the location name is one word, b) the first letter of the first word followed by the first letter of the second word, if the location name consists of at least two words. Note: for creating new city codes for US and Canada: the two-letter combinations used in postal US states (http://pe.usps.gov/text/pub28/28apb.htm ) and Canadian provinces (http://www.canadapost.ca/tools/pg/manual/PGaddress-e.asp) abbreviations cannot be utilized (e.g. the code for Denver, United States is USDN and not USDE, because of the DE is the abbreviation for Delaware state ). Exchange codes could be added based on the ISO 10383 MIC code [https://www.iso20022.org/sites/default/files/ISO10383_MIC/ISO10383_MIC.xls] according to the following rules: 1. it would be the acronym of the MIC. If acronym is not available, 2. it would be the MIC code. If the MIC code starts with an 'X', 3. the FpML AWG will compose the code. 'Publication Calendar Day', per 2021 ISDA Interest Rate Derivatives Definitions, means, in respect of a benchmark, any day on which the Administrator is due to publish the rate for such benchmark pursuant to its publication calendar, as updated from time to time. FpML format of the rate publication calendar. The construct: CCY-[short codes to identify the publisher], e.g. GBP-ICESWAP. The FpML XAPWG will compose the code.
- Obtained on 2025-04-25
- Version 9-4
- URL: http://www.fpml.org/coding-scheme/business-center-9-4.xml
- Code: The unique string/code identifying the business center, usually a 4-character code based on a 2-character ISO country code and a 2 character code for the city, but with exceptions for special cases such as index publication calendars, as described above.
- Code: AEAB
- Description: Abu Dhabi, Business Day (as defined in 2021 ISDA Definitions Section 2.1.10 (ii))
- Code: AEAD
- Description: Abu Dhabi, Settlement Day (as defined in 2021 ISDA Definitions Section 2.1.10 (i))
- Code: AEDU
- Description: Dubai, United Arab Emirates
- Code: AMYE
- Description: Yerevan, Armenia
- Code: AOLU
- Description: Luanda, Angola
- Code: ARBA
- Description: Buenos Aires, Argentina
- Code: ATVI
- Description: Vienna, Austria
- Code: AUAD
- Description: Adelaide, Australia
- Code: AUBR
- Description: Brisbane, Australia
- Code: AUCA
- Description: Canberra, Australia
- Code: AUDA
- Description: Darwin, Australia
- Code: AUME
- Description: Melbourne, Australia
- Code: AUPE
- Description: Perth, Australia
- Code: AUSY
- Description: Sydney, Australia
- Code: AZBA
- Description: Baku, Azerbaijan
- Code: BBBR
- Description: Bridgetown, Barbados
- Code: BDDH
- Description: Dhaka, Bangladesh
- Code: BEBR
- Description: Brussels, Belgium
- Code: BGSO
- Description: Sofia, Bulgaria
- Code: BHMA
- Description: Manama, Bahrain
- Code: BMHA
- Description: Hamilton, Bermuda
- Code: BNBS
- Description: Bandar Seri Begawan, Brunei
- Code: BOLP
- Description: La Paz, Bolivia
- Code: BRBD
- Description: Brazil Business Day. This means a business day in all of Sao Paulo, Rio de Janeiro or Brasilia not otherwise declared as a financial market holiday by the Bolsa de Mercadorias & Futuros (BM&F). BRBD should not be used for setting fixing time, instead the city centers (e.g. BRBR, BRRJ, BRSP) should be used, because they are locatable places.
- Code: BSNA
- Description: Nassau, Bahamas
- Code: BWGA
- Description: Gaborone, Botswana
- Code: BYMI
- Description: Minsk, Belarus
- Code: CACL
- Description: Calgary, Canada
- Code: Covers
- Description: all New Brunswick province.
- Code: CAFR
- Description: Fredericton, Canada.
- Code: CAMO
- Description: Montreal, Canada
- Code: CAOT
- Description: Ottawa, Canada
- Code: CATO
- Description: Toronto, Canada
- Code: CAVA
- Description: Vancouver, Canada
- Code: CAWI
- Description: Winnipeg, Canada
- Code: CHBA
- Description: Basel, Switzerland
- Code: CHGE
- Description: Geneva, Switzerland
- Code: CHZU
- Description: Zurich, Switzerland
- Code: CIAB
- Description: Abidjan, Cote d'Ivoire
- Code: CLSA
- Description: Santiago, Chile
- Code: CMYA
- Description: Yaounde, Cameroon
- Code: CNBE
- Description: Beijing, China
- Code: CNSH
- Description: Shanghai, China
- Code: COBO
- Description: Bogota, Colombia
- Code: CRSJ
- Description: San Jose, Costa Rica
- Code: CWWI
- Description: Willemstad, Curacao
- Code: CYNI
- Description: Nicosia, Cyprus
- Code: CZPR
- Description: Prague, Czech Republic
- Code: DECO
- Description: Cologne, Germany
- Code: DEDU
- Description: Dusseldorf, Germany
- Code: DEFR
- Description: Frankfurt, Germany
- Code: DEHA
- Description: Hannover, Germany
- Code: DEHH
- Description: Hamburg, Germany
- Code: DELE
- Description: Leipzig, Germany
- Code: DEMA
- Description: Mainz, Germany
- Code: DEMU
- Description: Munich, Germany
- Code: DEST
- Description: Stuttgart, Germany
- Code: DKCO
- Description: Copenhagen, Denmark
- Code: DOSD
- Description: Santo Domingo, Dominican Republic
- Code: DZAL
- Description: Algiers, Algeria
- Code: ECGU
- Description: Guayaquil, Ecuador
- Code: EETA
- Description: Tallinn, Estonia
- Code: EGCA
- Description: Cairo, Egypt
- Code: ESAS
- Description: ESAS Settlement Day (as defined in 2006 ISDA Definitions Section 7.1 and Supplement Number 15 to the 2000 ISDA Definitions)
- Code: ESBA
- Description: Barcelona, Spain
- Code: ESMA
- Description: Madrid, Spain
- Code: ESSS
- Description: San Sebastian, Spain
- Code: ETAA
- Description: Addis Ababa, Ethiopia
- Code: EUR
- Description: -ICESWAP Publication dates for ICE Swap rates based on EUR-EURIBOR rates
- Code: EUTA
- Description: TARGET Settlement Day
- Code: FIHE
- Description: Helsinki, Finland
- Code: FRPA
- Description: Paris, France
- Code: GBED
- Description: Edinburgh, Scotland
- Code: GBLO
- Description: London, United Kingdom
- Code: GBP
- Description: -ICESWAP Publication dates for GBP ICE Swap rates
- Code: GETB
- Description: Tbilisi, Georgia
- Code: GGSP
- Description: Saint Peter Port, Guernsey
- Code: GHAC
- Description: Accra, Ghana
- Code: GIGI
- Description: Gibraltar, Gibraltar
- Code: GMBA
- Description: Banjul, Gambia
- Code: GNCO
- Description: Conakry, Guinea
- Code: GRAT
- Description: Athens, Greece
- Code: GTGC
- Description: Guatemala City, Guatemala
- Code: HKHK
- Description: Hong Kong, Hong Kong
- Code: HNTE
- Description: Tegucigalpa, Honduras
- Code: HRZA
- Description: Zagreb, Republic of Croatia
- Code: HUBU
- Description: Budapest, Hungary
- Code: IDJA
- Description: Jakarta, Indonesia
- Code: IEDU
- Description: Dublin, Ireland
- Code: ILJE
- Description: Jerusalem, Israel
- Code: ILS
- Description: -SHIR Publication dates of the ILS-SHIR index.
- Code: ILS
- Description: -TELBOR Publication dates of the ILS-TELBOR index.
- Code: ILTA
- Description: Tel Aviv, Israel
- Code: INAH
- Description: Ahmedabad, India
- Code: INBA
- Description: Bangalore, India
- Code: INCH
- Description: Chennai, India
- Code: INHY
- Description: Hyderabad, India
- Code: INKO
- Description: Kolkata, India
- Code: INMU
- Description: Mumbai, India
- Code: INND
- Description: New Delhi, India
- Code: IQBA
- Description: Baghdad, Iraq
- Code: IRTE
- Description: Teheran, Iran
- Code: ISRE
- Description: Reykjavik, Iceland
- Code: ITMI
- Description: Milan, Italy
- Code: ITRO
- Description: Rome, Italy
- Code: ITTU
- Description: Turin, Italy
- Code: JESH
- Description: St. Helier, Channel Islands, Jersey
- Code: JMKI
- Description: Kingston, Jamaica
- Code: JOAM
- Description: Amman, Jordan
- Code: JPTO
- Description: Tokyo, Japan
- Code: KENA
- Description: Nairobi, Kenya
- Code: KHPP
- Description: Phnom Penh, Cambodia
- Code: KRSE
- Description: Seoul, Republic of Korea
- Code: KWKC
- Description: Kuwait City, Kuwait
- Code: KYGE
- Description: George Town, Cayman Islands
- Code: KZAL
- Description: Almaty, Kazakhstan
- Code: LAVI
- Description: Vientiane, Laos
- Code: LBBE
- Description: Beirut, Lebanon
- Code: LKCO
- Description: Colombo, Sri Lanka
- Code: LULU
- Description: Luxembourg, Luxembourg
- Code: LVRI
- Description: Riga, Latvia
- Code: MACA
- Description: Casablanca, Morocco
- Code: MARA
- Description: Rabat, Morocco
- Code: MCMO
- Description: Monaco, Monaco
- Code: MNUB
- Description: Ulan Bator, Mongolia
- Code: MOMA
- Description: Macau, Macao
- Code: MTVA
- Description: Valletta, Malta
- Code: MUPL
- Description: Port Louis, Mauritius
- Code: MVMA
- Description: Male, Maldives
- Code: MWLI
- Description: Lilongwe, Malawi
- Code: MXMC
- Description: Mexico City, Mexico
- Code: MYKL
- Description: Kuala Lumpur, Malaysia
- Code: MYLA
- Description: Labuan, Malaysia
- Code: MZMA
- Description: Maputo, Mozambique
- Code: NAWI
- Description: Windhoek, Namibia
- Code: NGAB
- Description: Abuja, Nigeria
- Code: NGLA
- Description: Lagos, Nigeria
- Code: NLAM
- Description: Amsterdam, Netherlands
- Code: NLRO
- Description: Rotterdam, Netherlands
- Code: NOOS
- Description: Oslo, Norway
- Code: NPKA
- Description: Kathmandu, Nepal
- Code: NYFD
- Description: New York Fed Business Day (as defined in 2006 ISDA Definitions Section 1.9, 2000 ISDA Definitions Section 1.9, and 2021 ISDA Definitions Section 2.1.7)
- Code: NYSE
- Description: New York Stock Exchange Business Day (as defined in 2006 ISDA Definitions Section 1.10, 2000 ISDA Definitions Section 1.10, and 2021 ISDA Definitions Section 2.1.8)
- Code: NZAU
- Description: Auckland, New Zealand
- Code: New
- Description: Zealand Business Day (proposed effective date: 2025-10-06)
- Code: NZBD
- Description: New Zealand Business Day (proposed effective date: 2025-10-06)
- Code: NZWE
- Description: Wellington, New Zealand
- Code: OMMU
- Description: Muscat, Oman
- Code: PAPC
- Description: Panama City, Panama
- Code: PELI
- Description: Lima, Peru
- Code: PHMA
- Description: Manila, Philippines
- Code: PHMK
- Description: Makati, Philippines
- Code: PKKA
- Description: Karachi, Pakistan
- Code: PLWA
- Description: Warsaw, Poland
- Code: PRSJ
- Description: San Juan, Puerto Rico
- Code: PTLI
- Description: Lisbon, Portugal
- Code: QADO
- Description: Doha, Qatar
- Code: ROBU
- Description: Bucharest, Romania
- Code: RSBE
- Description: Belgrade, Serbia
- Code: RUMO
- Description: Moscow, Russian Federation
- Code: SAAB
- Description: Abha, Saudi Arabia
- Code: SAJE
- Description: Jeddah, Saudi Arabia
- Code: SARI
- Description: Riyadh, Saudi Arabia
- Code: SEST
- Description: Stockholm, Sweden
- Code: SGSI
- Description: Singapore, Singapore
- Code: SILJ
- Description: Ljubljana, Slovenia
- Code: SKBR
- Description: Bratislava, Slovakia
- Code: SLFR
- Description: Freetown, Sierra Leone
- Code: SNDA
- Description: Dakar, Senegal
- Code: SVSS
- Description: San Salvador, El Salvador
- Code: THBA
- Description: Bangkok, Thailand
- Code: TNTU
- Description: Tunis, Tunisia
- Code: TRAN
- Description: Ankara, Turkey
- Code: TRIS
- Description: Istanbul, Turkey
- Code: TTPS
- Description: Port of Spain, Trinidad and Tobago
- Code: TWTA
- Description: Taipei, Taiwan
- Code: TZDA
- Description: Dar es Salaam, Tanzania
- Code: TZDO
- Description: Dodoma, Tanzania
- Code: UAKI
- Description: Kiev, Ukraine
- Code: UGKA
- Description: Kampala, Uganda
- Code: USBO
- Description: Boston, Massachusetts, United States
- Code: USCH
- Description: Chicago, United States
- Code: USCR
- Description: Charlotte, North Carolina, United States
- Code: USDC
- Description: Washington, District of Columbia, United States
- Code: USD
- Description: -ICESWAP Publication dates for ICE Swap rates based on USD-LIBOR rates
- Code: USD
- Description: -MUNI Publication dates for the USD-Municipal Swap Index
- Code: USDN
- Description: Denver, United States
- Code: USDT
- Description: Detroit, Michigan, United States
- Code: USGS
- Description: U.S. Government Securities Business Day (as defined in 2006 ISDA Definitions Section 1.11 and 2000 ISDA Definitions Section 1.11)
- Code: USHL
- Description: Honolulu, Hawaii, United States
- Code: USHO
- Description: Houston, United States
- Code: USLA
- Description: Los Angeles, United States
- Code: USMB
- Description: Mobile, Alabama, United States
- Code: USMN
- Description: Minneapolis, United States
- Code: USNY
- Description: New York, United States
- Code: USPO
- Description: Portland, Oregon, United States
- Code: USSA
- Description: Sacramento, California, United States
- Code: USSE
- Description: Seattle, United States
- Code: USSF
- Description: San Francisco, United States
- Code: USWT
- Description: Wichita, United States
- Code: UYMO
- Description: Montevideo, Uruguay
- Code: UZTA
- Description: Tashkent, Uzbekistan
- Code: VECA
- Description: Caracas, Venezuela
- Code: VGRT
- Description: Road Town, Virgin Islands (British)
- Code: VNHA
- Description: Hanoi, Vietnam
- Code: VNHC
- Description: Ho Chi Minh (formerly Saigon), Vietnam
- Code: YEAD
- Description: Aden, Yemen
- Code: ZAJO
- Description: Johannesburg, South Africa
- Code: ZMLU
- Description: Lusaka, Zambia
- Code: ZWHA
- Description: Harare, Zimbabwe
COMPLETED Add portfolio support code
COMPLETED Add GLEIF-based evaluation tenant onboarding wizard code
For evaluation tenants, provide a wizard that creates operational parties from
GLEIF/LEI data. The wizard is a separate action (not part of tenant
provisioning) gated by the evaluation tenant type. It imports a root LEI
entity and its corporate descendants as operational parties.
COMPLETED Add country support code
We will probably need country support at some point. We should link the country to the currencies, where applicable.
We now have country support, check that there is a link to currencies.
COMPLETED Add party hierarchy graph visualisation code
Add a visual graph or tree view showing the party hierarchy for a tenant. This should display parent-child relationships, party types, and potentially business centres.
COMPLETED Advanced counterparty dialog code
We've implemented a basic CRUD based counterparty dialog. However, real counterparty dialogs are much more complex. We've asked Gemini to sketch one out.
- 1. The "Four-Eyes" Status. In trading systems, you shouldn't be able to change
a BIC code or a Credit Limit without a second person "approving" it.
- UI Idea: Place a yellow banner at the top saying: "Pending Approval: Changes to Credit Limit (Requested by User A)".
- 2. Hierarchy Visualization: Since you are dealing with a System Tenant and a System Party, your users need to see the "Parent-Child" relationship clearly. If a trade happens with a subsidiary, the system should automatically "roll up" the risk to the parent.
- 3. Asset Class Matrix: Not every counterparty is allowed to trade every product. A simple grid with checkboxes or toggle switches for "Product Permissions" is the industry standard for this.
- 4. The "System Party" Identifier: For your internal System Party, I recommend
adding a "System-Owned" flag.
- UI treatment: Use a specific icon (like a gear or a building) next to the name to signify that this record is used for internal accounting and is not an external client.
UI Wireframe Specifications
Tab 1: General Info
_____________________________________________________________________________________ [ GENERAL INFO ] [ Hierarchy ] [ Trading Limits ] [ Settlement (SSI) ] _____________________________________________________________________________________ IDENTIFIERS CONTACTS ------------------------------------------ ---------------------------------- Internal ID: ENT-99201 Primary: Sarah Jenkins LEI: 7H6GLXDR0MBN8G7RUT71 Role: Head of Desk BIC/SWIFT: CHASUS33 Email: s.jenkins@jpm.com Country: US (United States) Phone: +1 212 555 0198 -------------------------------------------------------------------------------
Tab 2: Hierarchy
_____________________________________________________________________________________ [ General Info ] [[ HIERARCHY ]] [ Trading Limits ] [ Settlement (SSI) ] _____________________________________________________________________________________ RELATIONSHIP STRUCTURE ------------------------------------------------------------------------------- [Root] JP Morgan Chase & Co (Global Parent) |-- [Sub] J.P. Morgan Securities LLC | `-- [THIS] J.P. Morgan Prime Brokerage [Direct Subsidiary] `-- [Sub] J.P. Morgan Bank NA (Europe) -------------------------------------------------------------------------------
Tab 3: Trading Limits
_____________________________________________________________________________________ [ General Info ] [ Hierarchy ] [[ TRADING LIMITS ]] [ Settlement (SSI) ] _____________________________________________________________________________________ PRODUCT | ALLOWED | MAX TENOR | NET LIMIT (USD) | UTILIZATION --------------|---------|-----------|-----------------|-------------------------- FX Spot | [YES] | N/A | 50,000,000 | [|||||-----] 50% FX Forwards | [YES] | 2 Years | 20,000,000 | [||--------] 20% Equities | [YES] | N/A | 100,000,000 | [||||||||--] 80% -------------------------------------------------------------------------------
Tab 4: Settlement (SSI)
_____________________________________________________________________________________ [ General Info ] [ Hierarchy ] [ Trading Limits ] [[ SETTLEMENT (SSI) ]] _____________________________________________________________________________________ CCY | METHOD | NOSTRO BANK | ACCOUNT NO. | BIC/SWIFT | STATUS ----|--------|-------------------|------------------|-------------|-------------- USD | SWIFT | BNY MELLON NY | 9900881234 | IRVTUS3N | [VERIFIED] EUR | SWIFT | DEUTSCHE BANK AG | DE9100223344... | DEUTDEFF | [VERIFIED] -------------------------------------------------------------------------------
- Counterparty dialog
This pull request significantly enhances the user experience for managing counterparty data by introducing a tabbed detail dialog that allows for inline management of related entities like identifiers and contacts, and visualizes counterparty hierarchies. It also integrates a robust eventing system for real-time data updates and ensures data integrity through mandatory change reasons for amendments. Furthermore, critical backend fixes address UUID-related errors and a client-side crash during network re-authentication, improving overall system stability and reliability.
Highlights:
- Enhanced Counterparty Detail Dialog: The counterparty detail dialog has been completely restructured into a 5-tab layout: General Info, Identifiers, Contacts, Hierarchy, and Metadata. This provides a more organized and comprehensive view of counterparty data.
- Inline Sub-Entity Management: Users can now manage counterparty identifiers and contact information directly within the detail dialog using dedicated sub-tables and toolbars, streamlining data entry and modification workflows.
- Counterparty Hierarchy Visualization: A new 'Hierarchy' tab displays the parent-child relationships between counterparties in a tree structure, offering better insights into organizational structures.
- Change Reason Dialog Integration: The change reason dialog has been integrated for counterparty amendments, ensuring that all modifications are accompanied by a documented reason, consistent with existing country and currency amendment processes.
- New Eventing System for Counterparty Data: Server-side PostgreSQL change event definitions and client-side subscriptions have been added for counterparties, counterparty identifiers, and counterparty contact information, enabling real-time updates and improved data consistency.
- Critical Crash Fix during Re-authentication: A crash that occurred when a user clicked 'Disconnect' while auto-reconnect re-authentication was in progress has been resolved by preventing concurrent send_request_sync calls.
- Tenant ID Fix for Save Handlers: The tenant_id is now correctly set on save handlers for party, counterparty, counterparty_identifier, and counterparty_contact_information, resolving 'invalid input syntax for type uuid' errors.
- Refactor party and counterparty dialogs
This pull request significantly refactors the application's detail dialogs for managing Party and Counterparty entities. By adopting a strategy pattern, the previously duplicated logic for handling these similar but distinct entity types has been centralized into a single, generic EntityDetailDialog. This change streamlines the codebase, making it more maintainable and extensible for future entity types, while ensuring consistent UI behavior across different entity management screens.
Highlights:
- Strategy Pattern Implementation: Implemented a strategy pattern for entity operations, abstracting party and counterparty specific logic into distinct strategy classes.
- Unified Dialog Class: Consolidated PartyDetailDialog and CounterpartyDetailDialog into a single generic EntityDetailDialog class, reducing code duplication.
- New Interfaces and Data Structures: Introduced the entity_detail_operations abstract interface and common data structures like entity_data, identifier_entry, and contact_entry to provide a uniform view for different entity types.
- Code Duplication Reduction: Removed the PartyDetailDialog class and its associated UI file, as its functionality is now handled by the generic EntityDetailDialog.
- Controller Updates: Modified PartyController and CounterpartyController to instantiate the new generic EntityDetailDialog with the appropriate entity_detail_operations strategy.
COMPLETED Improve column handling in list widgets in Qt code
This pull request refactors the column configuration logic across numerous Qt list windows by centralizing metadata definitions. It introduces a ColumnMetadata struct and moves column styles, default window sizes, and settings group names into model headers. This change eliminates scattered inline literals, making the application's UI configuration more consistent, maintainable, and easier to update by establishing a single source of truth for these properties.
Highlights:
- Centralized Column Metadata: Introduced a new ColumnMetadata struct and associated helpers to serve as a single source of truth for column configuration across all Qt list windows.
- Model Header Refactoring: Updated 24 Client*Model headers to define column styles, default window sizes, and settings group names using static constexpr arrays and constants based on the new ColumnMetadata struct.
- MDI Window Integration: Modified 24 *MdiWindow.cpp files to consume column configuration directly from their respective model headers, replacing previously hardcoded string and QSize literals.
- Enum Relocation: Moved the column_style enum from EntityItemDelegate.hpp to the new ColumnMetadata.hpp to consolidate column-related definitions.
- API Signature Update: Changed the initializeTableSettings function signature in EntityListMdiWindow to accept std::string_view for the settings group parameter, with internal conversion to QString.
- UI File Adjustments: Adjusted the field ordering for 'Change Reason' and 'Recorded At' in several detail dialog .ui files.
POSTPONED Analyse caching at dialog level code
We seem to have a lot of caches lying around at the dialog level. It makes more sense to have a common core (i.e. non-Qt specific) data-structure that caches different types of data which is shared by the different dialogs. This would also be reused by different clients such as Wt, shell, etc.
Instead of locking we should use immutable data structures. We should also take into account notifications coming in for data changes. It should enable you to notify all clients, load the data in the background in a way that does not affect dialogs.
We could create workspace component which has all of the data needed, stored using immer containers:
- it can have a comms aspect, so that the UI does not need to worry about any of that. You just request say currencies page N, workspace then deals with that. It can just give you the current version. If none, it will load via comms. It also knows about subscriptions so it will tell you about pending subscriptions for a collection you are interested in. As you load more pages, we load these into immer containers ordered by page.
- once we implement workspaces, we should then make all references to foreign keys "clickable". For example, if you are in a business centre and it has a country we should be able to click on it and open the country. At present we can't do this because the data is kept at the main dialog level.
- ideally we want a way to cache data in Qt format. We don't need to save this data to the local database. However, we don't want to make the ores.workspace library depend on Qt. Maybe we just need some kind of "extensions" on each frontend (e.g. Wt etc), sort of a qt.workspace which contains the original workspace plus any Qt specific representations. Or maybe use composition.
- we should add a UI to visualise the workspace, or at least be able to see size usage etc. Baobab style map.
Notes:
- actually this is not "workspace", its ores.caching.
Links:
- GH: immer: "immer is a library of persistent and immutable data structures written in C++. These enable whole new kinds of architectures for interactive and concurrent programs of striking simplicity, correctness, and performance."
- Cache in-memory in ASP.NET Core: get ideas for the caching interfaces and requirements.
Merged stories:
Add workspace as a container
Core needs to have a container for all of the data stored within a context.
Actually, according to Data Priented Principles, we may not need it. This may be a UI concept but not a code concept.
COMPLETED Add FSM support to postgres code
In order to manage aspects such as trade life-cycles, authorisation, etc. We will need to support finite state machines. We should probably implement this directly in postgres.
Links:
COMPLETED Add trade support code
At the basic infrastructure needed to support trade envelopes.
This pull request significantly enhances the database schema by introducing a robust, generic Finite State Machine (FSM) framework and a detailed trade envelope. The FSM enables sophisticated lifecycle management for various domains, with trade lifecycle being its initial client. The trade envelope schema provides normalized structures for trade identity, temporal versioning, identifiers, and party roles, facilitating efficient querying and integration with systems like ORE. Accompanying these new features are extensive convention fixes across existing SQL files and updates to code generation templates, ensuring consistency and maintainability across the codebase.
Highlights:
- Unified Trade Envelope and FSM Schema: Implemented a comprehensive trade envelope and Finite State Machine (FSM) schema, as detailed in the design document, to support trade identity, temporal versioning, and lifecycle management.
- Generic FSM Framework: Introduced a reusable FSM framework in PostgreSQL, including tables for machines, states, and transitions, with notification triggers and Row-Level Security (RLS) policies.
- Trade Reference Data and Core Tables: Added four new trade reference data tables (trade types, lifecycle events, party role types, trade ID types) and core trade envelope tables (ores_trading_trades_tbl, ores_trading_identifiers_tbl, ores_trading_party_roles_tbl), complete with soft-FK validation and RLS.
- ORE Envelope View and Sample Data: Created ores_trade_ore_envelope_vw to flatten the latest trade state into the ORE structure, alongside a sample data script demonstrating a booking and novation lifecycle.
- SQL Convention Alignment: Fixed convention drifts across 40 existing SQL files by removing set schema 'public', schema-qualified table names, for update; idioms, stale check ("change_reason_code" <> '') constraints, and updating modified_by patterns.
- Code Generation Enhancements: Updated codegen templates (sql_schema_domain_entity_create.mustache, sql_schema_junction_create.mustache, sql_schema_table_create.mustache) to align with new hand-crafted conventions and added a new script (generate_trade_schema.sh) for trade schema generation.
- Rename trade to trading
This pull request implements a significant refactoring by renaming the ores.trade component to ores.trading. This change aims to enhance clarity and consistency throughout the system by adopting more precise terminology. The rename has been meticulously applied across all layers, including C++ source code, build configurations, database schemas, code generation definitions, and documentation, ensuring a unified and updated component identity.
Highlights:
- Component Rename: The ores.trade component has been comprehensively renamed to ores.trading across the entire codebase.
- Codebase-Wide Impact: This rename includes updates to C++ directories, headers, namespaces, CMake targets, SQL tables/objects, codegen models, and documentation.
- SQL Schema Migration: All SQL table prefixes and associated database objects (indexes, functions, triggers, rules, RLS policies, notification channels) have been migrated from ores_trade_*_tbl to ores_trading_*_tbl.
- Terminology Update: The 'trade envelope' wording has been removed from most comments and descriptions, with specific exceptions for FpML-related usage and a formal SQL view name.
- Documentation Removal: A comprehensive design document, doc/plans/2026-02-16-trade-envelope-and-fsm-design.org, was removed as part of this refactoring.
Footer
| Previous: Version Zero |