Human-readable summary of the change ("Description set to ...", "Status changed from X to Y", "Record Created", etc.).
JSON-serialized field-level diff. Empty string for Create and
Delete (those rows are fully described by fullRecordJSON).
EntityInfo.ID of the entity the change belongs to.
Complete snapshot of the record's post-change state (or pre-delete state for deletes), JSON-encoded with quotes pre-escaped.
Composite-key serialized RecordID. May be empty when the caller intends to resolve it lazily from a SQL expression (e.g., PG's inline CTE save path uses the post-INSERT primary key).
When source === 'Restore', points at the historical RecordChange
row whose state was restored. Persisted to
RecordChange.RestoredFromID. Null otherwise.
When source === 'Restore', the optional user-entered reason.
Persisted to RecordChange.RestoreReason. Null when the user did
not enter one.
Source discriminator. See RecordChangeSource.
Change type — Create, Update, or Delete.
Acting user's UserInfo.ID.
Dialect-agnostic payload for a RecordChange row.
Built by
DatabaseProviderBase.BuildRecordChangePayloadfrom an entity's old/new data plus an optional restore context. Concrete providers consume the payload to render their dialect-specific SQL — SQL Server emitsEXEC spCreateRecordChange_Internal @..., PostgreSQL emits a parameterizedINSERT INTO "RecordChange"statement.Hoisting this shape into the base class means the diff/JSON/description assembly happens in exactly one place across providers, and adding new RecordChange columns in the future requires updating one method instead of every provider's render path.