Files
Daniel Thomas dc5f6d1703 feat: let entities defer write-once fields to $setOnInsert
Upsert and UpsertMany stamped createdAt whenever the entity carried a zero
value. That guard silently inverts its meaning depending on whether the caller
read the document first: a read-modify-write caller holds the stored value and
keeps it, while a blind writer - an import feed, say - has nothing to supply and
so overwrites the stored createdAt on every re-import.

Entities can now implement EntityWithInsertOnlyFields to declare which fields
must only ever be written on insert. Those elements are routed through
$setOnInsert, so an upsert resolving to an update leaves them at their stored
value while one that inserts writes them once.

keel learns no field names in the process - the entity supplies them. That
preserves the existing property that keel only names a field in order to query
by it (id, version), never in order to write it.

UpsertUpdate and ApplyTimestamps are exported so callers driving their own bulk
writes, such as an import feed filtering on a staleness predicate, can apply the
same policy rather than restating it per call site.

Entities that do not implement the interface are written exactly as before, so
existing consumers are unaffected; TestUpsertLegacyEntityBehaviourUnchanged pins
that behaviour deliberately.

Adds the first tests to persistence/mongo, backed by a mongo testcontainer.
2026-09-15 13:42:36 +02:00
..
2026-08-06 17:16:54 +02:00
2021-10-01 16:18:51 +02:00