Codegen entity meta-model — C++ service

Table of Contents

This page is a segment of the Codegen org-entity meta-model hub, covering the ores.cpp.service facet — the layer between C++ Repository and C++ NATS: authorization checks, business logic, and firing the changed-event on every mutation.

1. Physical model mapping

Facet Description
ores.cpp.service C++ service application classes.

2. What gets generated, unconditionally

Every entity gets a full service class with list, count, save, delete, get, get_history — no knobs control whether these exist, only paste blocks extend them:

class ORES_REFDATA_CORE_EXPORT book_service {
private:
    inline static std::string_view logger_name = "ores.refdata.service.book_service";
    // ...
public:
    using context = ores::database::context;
    // list/count/save/delete/get/get_history declarations
};

There are no service-level behavioural knobs today (unlike Presentation's has_change_reason_cache and friends) — everything entity-specific at this layer is expressed as one of the paste blocks below.

3. Paste blocks

The ores.cpp.service facet defines the following paste block kinds, one per sub-heading below — see Paste blocks for the general mechanism they assume.

3.1. Extra includes (header)

Extra #include directives injected into <entity>_service.hpp, immediately before the namespace opening brace, expecting a includes block. Use when the service needs headers for entity-specific types the generic template doesn't emit — a junction repository header, <boost/uuid/uuid.hpp>.

To use this paste block on an entity, declare it under ** Paste blocks > *** Extra includes (header). See the following example:

** Paste blocks
*** Extra includes (header)

#+begin_src cpp :name includes :implements C5F35C7E-6EED-48D8-99F8-793145586882
#include <boost/uuid/uuid.hpp>
#include "ores.refdata.core/repository/party_country_repository.hpp"
#+end_src

3.2. Custom public methods (header)

Additional public method declarations injected just before the private: label, expecting a declaration block. Use for entity-specific query methods beyond the standard CRUD surface — party-scoped list/count on a junction table, for example.

** Paste blocks
*** Custom public methods (header)

#+begin_src cpp :name declaration :implements 2D4EA0F9-6AF6-45A5-A959-F672BF866C6A
    std::vector<domain::country> list_countries_for_party(
        const boost::uuids::uuid& party_id,
        std::uint32_t offset, std::uint32_t limit);
#+end_src

3.3. Extra private members (header)

Additional private member declarations injected after the standard repo_ member, expecting a declaration block. Use when the service needs entity-specific members the generic template doesn't know about — most often a junction repository, paired with the custom method above.

** Paste blocks
*** Extra private members (header)

#+begin_src cpp :name declaration :implements 047A96EF-1CC4-4661-B80B-C6C4532076AB
    repository::party_country_repository junction_repo_;
#+end_src

3.4. Extra includes (.cpp)

Additional #include directives injected into <entity>_service.cpp after the standard includes, expecting a body block. Use for headers needed only by the custom implementations below — implementation details that shouldn't leak into the header (e.g. <algorithm>, <boost/uuid/uuid_io.hpp>).

3.5. Constructor extra init (.cpp)

Additional member-initialiser-list entries appended after ctx_(std::move(ctx)) in the generated constructor, expecting a ctor_init block that starts with , to extend the list correctly. Pairs with the extra private members block above — whatever member you add there, initialise it here.

** Paste blocks
*** Constructor extra init (.cpp)

#+begin_src cpp :name ctor_init :implements 4F8A2B1E-7C3D-4E9F-B6A0-1D5C8F2E7A4B
    , junction_repo_(ctx_)
#+end_src

3.6. Custom implementations (.cpp)

Out-of-class method definitions injected just before the closing namespace brace, expecting a body block — the implementations for the custom public methods declared above (the standard template only generates bodies for the built-in CRUD methods). Multiple blocks concatenate with a blank line between them.

3.7. File-local helpers (.cpp)

Free functions injected at the top of the file's anonymous namespace, before any service method, so the write hooks below can call them. The namespace exists when the service reads by key, which every protocol-derived service does.

3.8. After a single write (.cpp)

Statements run in each put method right after the repository writes the row, before the method reads the row back. The written value is value; the service's context is ctx_. A hook that writes another table runs inside the caller's unit of work when there is one.

3.9. After a batch write (.cpp)

The batch counterpart: statements run in each put-many method right after the repository writes the set, before the method reads it back. The written values are batch.

4. See also

Emacs 29.3 (Org mode 9.6.15)