ores.cpp.shell-command

Table of Contents

This page is the literate source for the ores.cpp.shell-command facet of the codegen template library. Each archetype below is documented, and holds its mustache source, in its own linked page — this page is the facet-level summary and the routing table to them.

1. Summary

Three templates that project one entity onto one shell REPL command unit: a header declaring the unit class, a source holding its handler bodies, and the test file that pins the unit's guards. The unit owns one submenu and one command per verb the entity derives – a put becomes two, because a create and a replace are one verb stating two different claims – and registers that submenu on the root menu. The templates are opt-in and disabled by default.

2. The ores.cpp.shell-command facet

The facet consumes a domain_entity model or a junction and writes the shell's view of it. A junction is an entity whose key spans the two sides it links, so it derives the same verb set and reaches the same unit; the shape the templates read is the one the protocol was derived from, which is why a verb the model gains reaches the protocol and the shell in the same commit rather than the shell being written out by hand beside it.

The model already carries everything the templates need: the entity names and title, the component, the API sub-component, the primary key and the columns.

The facet writes into the entity's own adapter part under projects/ores.shell/, not into the entity's domain component. A trading entity lands in projects/ores.shell/trading/, at src/app/commands/trading/ and include/ores.shell/app/commands/trading/. That part declares #+component_kind: adapter, so codegen writes only its file lists beside the hand-authored CMakeLists, as Component architecture describes.

One variable places that output. {component} resolves to the short component name without the product prefix, so a trading entity yields trading and not ores.trading. The template body reads the same value under {{component}}, and uses it for the ores.<component>::domain namespace and the <component>.v1.<entity_plural>.list subject. Output paths and template bodies therefore share one spelling of the component.

The per-product split is the point of the shape. Each entity owns a file, so a component's units can be added and removed one at a time. A generated aggregator then calls each unit's register_commands in turn, which is what the hand-written trading_commands.cpp does today for its 39 units. That aggregator needs a component-scoped archetype and a render-time list of the component's opted-in entities, the same pattern the generator already uses for _COMPONENT_FILES_TEMPLATES.

Opt-in, disabled by default — enabling the facet is a per-entity decision, expressed as an :ores.cpp.shell-command.enabled: true entry in the entity model's properties drawer, exactly as ores.cpp.eventing-integration-test does it.

The add verb takes free-form tokens rather than one typed parameter per column. The cli library expands a typed handler into one template instantiation per argument, and the Windows clang toolchain abandons the mangler on the deeper chains. A token vector holds the argument list at a fixed shape, so the argument count no longer shapes the generated types.

The supply annotation. The add verb fills one domain member per positional argument. The :supplied_by: annotation on a column says who supplies the value, and the generator turns it into the {{positional_count}} arity and the {{#is_*}} sections the template reads. The four values are:

Value Meaning
user The default. The verb reads the value from the next positional.
minted The verb mints a fresh uuid. The default for a uuid primary key.
session_party The verb reads the acting party from the session, and fails when the account has no default party.
unset The verb leaves the member at its default and asks for nothing.

The tenant_id member takes no annotation. It is not a declared column, so the template names it directly and fills it from the session.

3. Archetypes

Archetype Description
ores.cpp.shell-command.command_header Shell REPL command unit header: submenu and process_* declarations for one entity.
ores.cpp.shell-command.command_implementation Shell REPL command unit implementation: the registration lambdas and the process_* bodies for one entity.
ores.cpp.shell-command.command_tests Shell REPL command unit tests: one case per handler guard, the arity check, a malformed token, and a valid token vector that reaches the transport.
ores.cpp.shell-command.operation_header Shell REPL command unit header for an operation model: the submenu and one process_* per declared message.
ores.cpp.shell-command.operation_implementation Shell REPL command unit implementation for an operation model: the registration lambdas and one process_* body per declared message.
ores.cpp.shell-command.operation_tests Shell REPL command unit tests for an operation model: a signed-out guard, the argument count, and a token vector that reaches the transport.

4. See also

Emacs 29.3 (Org mode 9.6.15)