morph 0.1.0
Asynchronous bridge between GUI thread and business models
Loading...
Searching...
No Matches
morph::journal::LogEntry Struct Reference

One recorded execution of an action against a model instance. More...

#include <action_log.hpp>

Public Attributes

uint64_t seq = 0
 Monotonic order assigned by the sink on append(). Callers pass 0.
std::string modelType
 String type-id of the model the action ran against (ModelTraits<M>::typeId()).
std::string entityKey
 Stable identity of the model instance (e.g. an account id), stamped from the value passed to attachActionLog(). Empty if none was set.
std::string actionType
 String type-id of the executed action (ActionTraits<A>::typeId()).
std::string payload
 JSON-encoded request (ActionTraits<A>::toJson).
std::string schema
 Structural fingerprint of the action payload's shape at the moment payload was encoded (morph::model::payloadFingerprint).
std::string result
 JSON-encoded result (ActionTraits<A>::resultToJson), captured after successful execution. Empty when outcome == Outcome::Failed.
Outcome outcome = Outcome::Succeeded
 Whether this execution succeeded or was rejected/threw. Defaults to Succeeded so a pre-existing on-disk entry (written before this field existed) decodes unchanged under the lenient reader — an absent key is indistinguishable from an explicit Succeeded.
std::string error
 std::exception::what() from the exception that rejected the action. Empty unless outcome == Outcome::Failed.
std::string principal
 Auth principal from morph::session::current(), if any. Empty if unset.
int64_t timestampMs = 0
 Wall-clock time of execution, milliseconds since the Unix epoch.
std::string idempotencyKey
 Optional dedup token for outbox-relayed entries. Empty by default; ordinary auto-appended entries (from ActionDispatcher's runner or Bridge::executeVia's local op) never set it. Mirrors morph::offline::QueueItem::idempotencyKey's exact contract: opaque, stored verbatim, stable across restarts for one logical outbox row. See journal::OutboxRelay (outbox.hpp) for how it's used.
std::uint32_t v = kLogFormatVersion
 Line-format version this entry was written at.
std::string causalParentId
 Identity of the "trigger" entry that caused this entry to be recorded, or empty (the sentinel) if this entry was not caused by another one.

Detailed Description

One recorded execution of an action against a model instance.

Normally produced automatically by morph::model::detail::IModelHolder::recordIfAttached. Application code may also construct and append one directly — that is what an outbox row is, and what causalParentId is set by; see morph::journal::OutboxRelay.

Definition at line 46 of file action_log.hpp.

Member Data Documentation

◆ seq

uint64_t morph::journal::LogEntry::seq = 0

Monotonic order assigned by the sink on append(). Callers pass 0.

Definition at line 48 of file action_log.hpp.

◆ modelType

std::string morph::journal::LogEntry::modelType

String type-id of the model the action ran against (ModelTraits<M>::typeId()).

Definition at line 51 of file action_log.hpp.

◆ entityKey

std::string morph::journal::LogEntry::entityKey

Stable identity of the model instance (e.g. an account id), stamped from the value passed to attachActionLog(). Empty if none was set.

Definition at line 55 of file action_log.hpp.

◆ actionType

std::string morph::journal::LogEntry::actionType

String type-id of the executed action (ActionTraits<A>::typeId()).

Definition at line 58 of file action_log.hpp.

◆ payload

std::string morph::journal::LogEntry::payload

JSON-encoded request (ActionTraits<A>::toJson).

Definition at line 61 of file action_log.hpp.

◆ schema

std::string morph::journal::LogEntry::schema

Structural fingerprint of the action payload's shape at the moment payload was encoded (morph::model::payloadFingerprint).

v above versions the line format; this versions the payload. Without it, replaying an entry written by an older build against a renamed field is indistinguishable from replaying an entry that genuinely omitted the field: the lenient decode drops the unknown key, default-constructs the new one, and reconstruction reports a state that was never recorded. With it, replay() compares this against the fingerprint the current build computes for the same action and refuses rather than guessing — see journal::replay() and docs/spec/journal/journal.md, "Payload schema fingerprint".

Stamped automatically by the two sites that execute an action (ActionDispatcher::registerAction's runner and Bridge::executeVia's local op). Empty is a meaningful value: it marks an unstamped entry — one written before this field existed, or appended directly by application code — whose payload shape is unknown and therefore unverifiable. See UnstampedPayloadPolicy for what replay does with one.

Definition at line 82 of file action_log.hpp.

◆ result

std::string morph::journal::LogEntry::result

JSON-encoded result (ActionTraits<A>::resultToJson), captured after successful execution. Empty when outcome == Outcome::Failed.

Definition at line 86 of file action_log.hpp.

◆ outcome

Outcome morph::journal::LogEntry::outcome = Outcome::Succeeded

Whether this execution succeeded or was rejected/threw. Defaults to Succeeded so a pre-existing on-disk entry (written before this field existed) decodes unchanged under the lenient reader — an absent key is indistinguishable from an explicit Succeeded.

Definition at line 92 of file action_log.hpp.

◆ error

std::string morph::journal::LogEntry::error

std::exception::what() from the exception that rejected the action. Empty unless outcome == Outcome::Failed.

Definition at line 96 of file action_log.hpp.

◆ principal

std::string morph::journal::LogEntry::principal

Auth principal from morph::session::current(), if any. Empty if unset.

Definition at line 99 of file action_log.hpp.

◆ timestampMs

int64_t morph::journal::LogEntry::timestampMs = 0

Wall-clock time of execution, milliseconds since the Unix epoch.

Definition at line 102 of file action_log.hpp.

◆ idempotencyKey

std::string morph::journal::LogEntry::idempotencyKey

Optional dedup token for outbox-relayed entries. Empty by default; ordinary auto-appended entries (from ActionDispatcher's runner or Bridge::executeVia's local op) never set it. Mirrors morph::offline::QueueItem::idempotencyKey's exact contract: opaque, stored verbatim, stable across restarts for one logical outbox row. See journal::OutboxRelay (outbox.hpp) for how it's used.

Definition at line 110 of file action_log.hpp.

◆ v

std::uint32_t morph::journal::LogEntry::v = kLogFormatVersion

Line-format version this entry was written at.

Defaults to kLogFormatVersion, so every freshly-constructed entry already carries the current version with no separate stamping step. A legacy line (written before this field existed) has no v key; under fromJson's lenient decode that is just an absent key, so it decodes with this same default — i.e. legacy data reads as v == 1, which is correct: v1 is today's shape, kLogFormatVersion merely names it.

Definition at line 120 of file action_log.hpp.

◆ causalParentId

std::string morph::journal::LogEntry::causalParentId

Identity of the "trigger" entry that caused this entry to be recorded, or empty (the sentinel) if this entry was not caused by another one.

Set by application code that journals a cascaded mutation — e.g. an automation rule that reacts to one recorded action by executing a further one — to the triggering entry's own stable identity, so replay() and an activity view can both recover "what caused this." Empty by default: an ordinary, non-cascaded entry never sets it.

Warning
Must not be a LogEntry::seq value. seq is sink-local and re-stamped by every sink's append() (and again by SessionLog::checkpoint() when forwarding) — it is not a stable, cross-sink or cross-restart identifier (see the Invariants section of docs/spec/journal/journal.md). A causalParentId wired to a raw seq would stop matching anything the moment the trigger entry is forwarded to another sink or the process restarts. Application code must instead mint its own opaque/UUID-style identity for the trigger entry at the point it is created, independent of whatever seq any sink later assigns it, and reuse that same identity as every cascaded entry's causalParentId.

Definition at line 143 of file action_log.hpp.


The documentation for this struct was generated from the following file: