ores.cpp.repository.entity_header

Table of Contents

sqlgen-side struct mirroring the table shape. repository profile.

See the Template variable reference for the complete list of available variables and their semantics.

1. Template

The full template source. Edit here and re-tangle with compass build --direct tangle_codegen_templates to regenerate library/templates/cpp_domain_type_entity.hpp.mustache.

{{! GENERATED FILE — tangled from projects/ores.codegen/library/templates/cpp_repository.org. Edit the org source. }}
{{{cpp_license}}}
{{#domain_entity}}
#ifndef ORES_{{component_core_upper}}_REPOSITORY_{{entity_singular_upper}}_ENTITY_HPP
#define ORES_{{component_core_upper}}_REPOSITORY_{{entity_singular_upper}}_ENTITY_HPP

#include <string>
#include <optional>
#include <ostream>
#include "ores.database/repository/db_types.hpp"
#include "sqlgen/PrimaryKey.hpp"
{{#cpp.includes.entity}}
#include {{{.}}}
{{/cpp.includes.entity}}

namespace ores::{{component}}::repository {

using db_timestamp = ores::database::repository::db_timestamp;

/**
 * @brief Represents a {{entity_title_lower}} in the database.
 */
struct {{entity_singular}}_entity {
    constexpr static const char* schema = "public";
    constexpr static const char* tablename = "{{sql.tablename}}";

{{#primary_key.columns}}
    sqlgen::PrimaryKey<std::string> {{column}};
{{/primary_key.columns}}
{{#has_tenant_id}}
{{#nullable_tenant_id}}
    std::optional<std::string> tenant_id;
{{/nullable_tenant_id}}
{{^nullable_tenant_id}}
    std::string tenant_id;
{{/nullable_tenant_id}}
{{/has_tenant_id}}
{{#has_workspace_id}}
    std::string workspace_id;
{{/has_workspace_id}}
{{#has_audit_columns}}
    int version = 0;
{{/has_audit_columns}}
{{#natural_keys}}
{{#is_uuid}}
    std::string {{column}}{{#default_value}} = {{{default_value}}}{{/default_value}};
{{/is_uuid}}
{{#is_date}}
    std::string {{column}};
{{/is_date}}
{{#is_timestamp}}
    std::string {{column}};
{{/is_timestamp}}
{{^is_uuid}}{{^is_date}}{{^is_timestamp}}
    {{{cpp_type}}} {{column}}{{#default_value}} = {{{default_value}}}{{/default_value}};
{{/is_timestamp}}{{/is_date}}{{/is_uuid}}
{{/natural_keys}}
{{#columns}}
{{#is_optional_uuid}}
    std::optional<std::string> {{name}};
{{/is_optional_uuid}}
{{#is_uuid}}
    std::string {{name}};
{{/is_uuid}}
{{#is_optional_timestamp}}
    std::optional<sqlgen::Timestamp<"%Y-%m-%d %H:%M:%S">> {{name}};
{{/is_optional_timestamp}}
{{#is_required_timestamp}}
    std::string {{name}};
{{/is_required_timestamp}}
{{#is_required_inet}}
    std::string {{name}};
{{/is_required_inet}}
{{#is_base64}}
    std::string {{name}};
{{/is_base64}}
{{#is_nullable_string}}
    std::optional<std::string> {{name}};
{{/is_nullable_string}}
{{#is_nullable_numeric}}
    std::optional<{{{cpp_type}}}> {{name}};
{{/is_nullable_numeric}}
{{#is_already_optional}}
    {{{cpp_type}}} {{name}};
{{/is_already_optional}}
{{#is_enum}}
    std::string {{name}};
{{/is_enum}}
{{#is_value_type}}
    std::string {{name}};
{{/is_value_type}}
{{#render_is_enum}}
{{^is_enum}}
    std::optional<std::string> {{name}};
{{/is_enum}}
{{/render_is_enum}}
{{#is_simple}}
    {{{cpp_type}}} {{name}}{{#default_value}} = {{{default_value}}}{{/default_value}};
{{/is_simple}}
{{/columns}}
{{#has_audit_columns}}
    std::string modified_by;
    std::string performed_by;
    std::string change_reason_code;
    std::string change_commentary;
{{/has_audit_columns}}
{{^current_state}}
    db_timestamp valid_from = "9999-12-31 23:59:59";
    db_timestamp valid_to = "9999-12-31 23:59:59";
{{/current_state}}
};

std::ostream& operator<<(std::ostream& s, const {{entity_singular}}_entity& v);

}

#endif
{{/domain_entity}}
{{#junction}}
#ifndef ORES_{{component_core_upper}}_REPOSITORY_{{name_singular_upper}}_ENTITY_HPP
#define ORES_{{component_core_upper}}_REPOSITORY_{{name_singular_upper}}_ENTITY_HPP

#include <string>
#include <optional>
#include <ostream>
#include "ores.database/repository/db_types.hpp"
#include "sqlgen/PrimaryKey.hpp"
{{#cpp.includes.entity}}
#include {{{.}}}
{{/cpp.includes.entity}}

namespace ores::{{component}}::repository {

using db_timestamp = ores::database::repository::db_timestamp;

/**
 * @brief Represents a {{name_title_lower}} in the database.
 *
 * Junction table with composite primary key ({{left.column}}, {{right.column}}, valid_from).
 */
struct {{name_singular}}_entity {
    constexpr static const char* schema = "public";
    constexpr static const char* tablename = "{{sql.tablename}}";

    sqlgen::PrimaryKey<std::string> {{left.column}};
{{#has_tenant_id}}
    std::string tenant_id;
{{/has_tenant_id}}
    std::string {{right.column}};
    int version = 0;
{{#columns}}{{#is_uuid}}    std::string {{name}};
{{/is_uuid}}{{#is_optional_uuid}}    std::optional<std::string> {{name}};
{{/is_optional_uuid}}{{#is_optional_timestamp}}    std::optional<sqlgen::Timestamp<"%Y-%m-%d %H:%M:%S">> {{name}};
{{/is_optional_timestamp}}{{#is_required_timestamp}}    std::string {{name}};
{{/is_required_timestamp}}{{#is_date}}    std::string {{name}};
{{/is_date}}{{#is_base64}}    std::string {{name}};
{{/is_base64}}{{^is_uuid}}{{^is_optional_uuid}}{{^is_optional_timestamp}}{{^is_required_timestamp}}{{^is_date}}{{^is_base64}}    {{{cpp_type}}} {{name}}{{#default_value}} = {{{default_value}}}{{/default_value}};
{{/is_base64}}{{/is_date}}{{/is_required_timestamp}}{{/is_optional_timestamp}}{{/is_optional_uuid}}{{/is_uuid}}{{/columns}}    std::string modified_by;
    std::string performed_by;
    std::string change_reason_code;
    std::string change_commentary;
    db_timestamp valid_from = "9999-12-31 23:59:59";
    db_timestamp valid_to = "9999-12-31 23:59:59";
};

std::ostream& operator<<(std::ostream& s, const {{name_singular}}_entity& v);

}

#endif
{{/junction}}

2. Design notes

2.1. Org entity includes feed the header (2026-09-06)

The {{#cpp.includes.entity}} arm emits the org-declared "Entity includes" block after the template's standard include set. The org_loader filters out the standard tokens, so only includes the template cannot derive – e.g. the header of a domain-enum column type such as ores.trading.api/domain/product_type.hpp for trade_type's product_type column – reach the emitted header. Org blocks that merely repeat the standard set leave regeneration byte-identical.

The filter (org_loader's _ENTITY_HEADER_STANDARD_INCLUDES) also drops the tokens legacy blocks add that no emitted member can require, and applies to junction entity headers as well as domain ones:

  • sqlgen/Timestamp.hpp arrives via db_types.hpp's db_timestamp alias, which the template always emits and which includes Timestamp.hpp;
  • boost/uuid/uuid.hpp is never needed: the template renders every uuid-typed column and junction PK/FK side as std::string;
  • <cstdint> appears in drift-rollout-era blocks as a stale transcription of pre-org headers; the canonical entity headers compile without it and the drift registry pins them byte-for-byte.

Without these drops, the whole-estate drift check flags the four registered-component headers whose orgs declare them (compute app_version_platform, iam account_party, reporting report_definition and report_instance). A real future need for one of these headers in the entity header belongs in this template's fixed include set, not in an org block.

2.2. Domain entity vs junction: unified on db_timestamp (2026-07-15)

Both the {{#domain_entity}} and {{#junction}} sections now use the db_timestamp type alias (ores::database::repository::db_timestamp, imported via db_types.hpp) for valid_from=/=valid_to, and both use the component_core_upper-based include guard.

This was previously a documented, deliberate divergence (the junction section used raw sqlgen::Timestamp<"%Y-%m-%d %H:%M:%S"> and a component_upper-based guard instead), justified by "the composite-PK interaction with sqlgen's db_timestamp alias has not been validated" — but the existing hand-authored party_currency_entity.hpp=/ =party_country_entity.hpp (real, currently-compiling junction entities) already use db_timestamp and the CORE-prefixed guard in production, which is exactly the validation the old note said was missing. Unified the template to match what already ships, while adding a codegen junction facet for tenor_convention_resolution (see the Retire legacy codegen profile system; add junction support to physical-space codegen story).

Capture Unify junction entity timestamp type to db_timestamp alias can be closed as done.

3. See also

Emacs 29.3 (Org mode 9.6.15)