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
- Codegen org-entity meta-model — the hub.
- C++ Repository — what this service wraps.
- C++ NATS — the pipeline that calls into this service and that this service publishes changed-events into.
- Variability — MASD's formal vocabulary; this facet currently has no standalone knobs, only paste blocks.