ores.refdata.counterparty

Table of Contents

External trading partners and counterparties that participate in financial transactions with the organisation. Counterparties form a hierarchy through parent_counterparty_id for group structures.

1. Flags

2. Columns

2.1. id

UUID uniquely identifying this counterparty.

Surrogate key for the counterparty record.

2.2. short_code

Short code for quick reference.

A brief mnemonic code used in trading systems.

std::string(faker::string::alpha(6))

2.3. full_name

Full legal name of the counterparty.

The official registered name of the external entity. Not unique (e.g. the same legal name can recur across branches with distinct short codes) — see the non-unique search index declared under the SQL Indexes section below.

std::string(faker::company::companyName())

2.4. transliterated_name

Transliterated (e.g. Latin-script) rendering of the full legal name, for counterparties whose registered name uses a non-Latin script.

std::nullopt

2.5. party_type

Classification of this counterparty.

References the party_type lookup table.

std::string("Bank")

2.6. parent_counterparty_id

Parent counterparty for hierarchy.

References the parent counterparty record for group structures. Null for root counterparties.

std::nullopt

2.7. business_center_code

Business center location code.

FpML business center code indicating primary location.

std::string("WRLD")

2.8. status

Current lifecycle status.

References the party_status lookup table.

std::string("Active")

2.9. image_id

Optional reference to a logo/branding image in the images table.

std::nullopt

3. SQL

3.1. Flags

3.2. Indexes

name columns unique current_only where_extra
full_name tenant_id, full_name false true  

4. Foreign keys

4.1. parent_counterparty_id

4.2. image_id

5. Insert trigger

5.1. Validations

column validation_function
party_type ores_refdata_validate_party_type_fn
status ores_refdata_validate_party_status_fn
business_center_code ores_refdata_validate_business_centre_fn

6. Messages

The composite_as_of pair, declared here so both the header and its TypeScript twin render it.

6.1. get_counterparty_composite_as_of_request

/**
 * @brief Reads a counterparty as it stood at a specific version, together
 * with its identifiers and contact information as they stood during that
 * same version's [valid_from, valid_to) window. See the "Temporal composite
 * entity versioning" architecture doc.
 */

6.1.1. id

6.1.2. version

6.2. get_counterparty_composite_as_of_response

6.2.1. success

6.2.2. message

6.2.3. counterparty

6.2.4. identifiers

6.2.5. contacts

7. C++

7.1. Flags

7.2. Repository

7.3. Domain includes

#include <chrono>
#include <string>
#include <optional>
#include <boost/uuid/uuid.hpp>

7.4. Entity includes

#include <string>
#include <optional>
#include "sqlgen/Timestamp.hpp"
#include "sqlgen/PrimaryKey.hpp"

7.5. Conventions

7.6. Table display

column header
short_code Code
full_name Name
party_type Type
status Status
business_center_code Business Center
modified_by Modified By
version Version

7.7. Presentation

7.7.1. Detail fields

field label widget type is_key is_required placeholder flag_source combo_allow_blank combo_fetch combo_domain_type combo_display_field combo_fetch_include combo_fetch_fn combo_watcher_name combo_code_field combo_tooltip_field combo_sort_field combo_label combo_setter_pascal badge_key combo_blank_label
short_code Short Code codeEdit line_edit true true Enter short code                              
full_name Full Name nameEdit line_edit false true Enter full name                              
party_type Party Type partyTypeCombo dynamic_combo false           refdata::domain::party_type     fetch_party_types partyTypeWatcher code description display_order party types PartyTypeCombo party_type  
status Status statusCombo dynamic_combo false           refdata::domain::party_status     fetch_party_statuses partyStatusWatcher code description display_order party statuses PartyStatusCombo party_status  
business_center_code Business Center businessCenterCombo flagged_combo false     business_centre false fetch_business_centre_codes                        
parent_counterparty_id Parent Counterparty parentCounterpartyCombo dynamic_combo false true         refdata::domain::counterparty full_name   fetch_counterparties parentCounterpartyWatcher id short_code version counterparties ParentCounterpartyCombo   No Parent

7.7.2. Columns

enum_name field header type width is_badge badge_key formatter formatter_include
ShortCode short_code Code string 120        
FullName full_name Name string 250        
PartyType party_type Type string 120 true party_type    
Status status Status string 100 true party_status    
BusinessCenterCode business_center_code Business Center string 130        
Version version Version int 80        
ModifiedBy modified_by Modified By string 120        
RecordedAt recorded_at Recorded At timestamp 150        

7.7.3. Icon columns

Business center gets its own flag icon, same as any other single-business-centre cell (e.g. Book's rates centre code column).

column accessor field1 field2
BusinessCenterCode business_centre_flag_icon business_center_code  

7.8. Custom repository methods

7.9. Custom NATS protocol messages

counterparty declares its composite_as_of message pair in the top-level * Messages section: reads a counterparty as it stood at a specific version, together with its identifiers and contact information as they stood during that same version's window — see the "Temporal composite entity versioning" architecture doc. The header and its TypeScript twin both render it from there.

#include "ores.refdata.api/domain/counterparty_contact_information.hpp"
#include "ores.refdata.api/domain/counterparty_identifier.hpp"

7.10. Custom NATS handler methods

#include "ores.refdata.core/service/counterparty_contact_information_service.hpp"
#include "ores.refdata.core/service/counterparty_identifier_service.hpp"
#include <boost/uuid/string_generator.hpp>
#include <chrono>
void composite_as_of(ores::nats::message msg) {
    BOOST_LOG_SEV(counterparty_handler_lg(), debug) << "Handling " << msg.subject;
    auto req_ctx_expected = ores::service::service::make_request_context(ctx_, msg, verifier_);
    if (!req_ctx_expected) {
        error_reply(nats_, msg, req_ctx_expected.error());
        return;
    }
    const auto& req_ctx = *req_ctx_expected;
    auto req = decode<get_counterparty_composite_as_of_request>(msg);
    if (!req) {
        BOOST_LOG_SEV(counterparty_handler_lg(), warn) << "Failed to decode: " << msg.subject;
        error_reply(nats_, msg, ores::service::error_code::bad_request);
        return;
    }
    try {
        service::counterparty_service cpty_svc(req_ctx);
        const auto version = static_cast<std::uint32_t>(req->version);
        auto current = cpty_svc.get_counterparty_at_version(req->id, version);
        if (!current) {
            reply(nats_,
                  msg,
                  get_counterparty_composite_as_of_response{
                      .success = false,
                      .message = "No such counterparty version: " + req->id + " v" +
                                 std::to_string(version)});
            return;
        }

        // See party_handler::composite_as_of — windows are contiguous
        // by construction; the domain object doesn't surface valid_to.
        auto next = cpty_svc.get_counterparty_at_version(req->id, version + 1);
        const auto window_end =
            next ? next->recorded_at :
                   std::chrono::system_clock::now() + std::chrono::hours(24 * 365 * 100);

        service::counterparty_identifier_service identifier_svc(req_ctx);
        auto identifiers =
            identifier_svc.list_counterparty_identifiers_by_counterparty_id_as_of(
                req->id, current->recorded_at, window_end);

        service::counterparty_contact_information_service contact_svc(req_ctx);
        auto contacts =
            contact_svc.list_counterparty_contact_informations_by_counterparty_id_as_of(
                req->id, current->recorded_at, window_end);

        BOOST_LOG_SEV(counterparty_handler_lg(), debug) << "Completed " << msg.subject;
        reply(nats_,
              msg,
              get_counterparty_composite_as_of_response{.success = true,
                                                        .counterparty = std::move(*current),
                                                        .identifiers = std::move(identifiers),
                                                        .contacts = std::move(contacts)});
    } catch (const std::exception& e) {
        BOOST_LOG_SEV(counterparty_handler_lg(), error)
            << msg.subject << " failed: " << e.what();
        reply(nats_,
              msg,
              get_counterparty_composite_as_of_response{.success = false, .message = e.what()});
    }
}

7.11. Custom NATS subscriptions

Hand-crafted subject wired into the generated counterparty_registrar.cpp via the nats-sub-registrar facet's custom-subscription paste point.

subs.push_back(
    nats.queue_subscribe(get_counterparty_composite_as_of_request::nats_subject,
                         queue_group,
                         [h](ores::nats::message msg) { h->composite_as_of(std::move(msg)); }));

8. See also

Emacs 29.3 (Org mode 9.6.15)