Commit graph

2 commits

Author SHA1 Message Date
792e509b67 #13: TemporalRepository save — stable-live + historical-copy semantics
The decorator's save() flow now preserves the live row's id PK across
updates and captures each prior version as a fresh row with a new id.
This unblocks fewo-webapp#459: the consumer's composite-FK schema needs
stable child references to the live row (UNIQUE(entity_id, valid_until)
with ON UPDATE CASCADE on every child FK), which the previous
close-then-insert flow couldn't provide.

New flow on update (when a live row exists for entity_id):
  1. Clone the live row in memory (cloneDto via oatpp reflection),
     assign a fresh id and set valid_until=now, save → INSERT historical.
  2. Set the new dto's id=live.id (preserve PK), valid_from=now,
     valid_until=SENTINEL, save → inner UPDATEs the live row in place by
     PK.

Inner adapter contract changes from "upsert keyed by (entity_id,
valid_from)" to "upsert keyed by id (per-row PK)". TemporalFieldTraits
gains an id() accessor; OATPP_AUTHKIT_REGISTER_TEMPORAL grows from 4 to
5 args (Dto + IdMember + EntityIdMember + FromMember + UntilMember).

Tests: test_repository_decorators asserts livePk stability across saves
and fresh historicalPk per version; remaining decorator tests updated to
the 5-arg macro form. README's TemporalRepository.hpp row rewritten to
describe the new write semantics.

Bumped CMake version 0.7.0 → 0.8.0 (semantic break — save() no longer
reallocates the live PK; consumers depending on the old contract need
audit).

Closes #13

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-30 00:10:03 +02:00
b5e1ea1894 #12: per-decorator migration kit (Prereq.hpp)
Each decorator now bundles its schema prereqs alongside its code via
DecoratorPrereq (additive CREATE-IF-NOT-EXISTS) and ReshapeStep
(non-idempotent reshape gated on a detectSql probe).

applyDecoratorMigrations<Decorators...>(table, probe, exec, recorder)
walks the listed decorators at startup, runs every PREREQ, runs every
reshape step whose probe returns false. Database-agnostic — consumer
wires probe/exec to their DbClient. SCHEMA_MIGRATIONS_TABLE_SQL is
provided for observability; the detect-probe is the source of truth.

TemporalRepository ships add_valid_from / add_valid_until /
drop_unique_entity_id / composite_unique (UNIQUE(entity_id, valid_until)
so close-then-insert can run in a deferred-FK transaction).
AuditLogRepository ships the audit_log CREATE TABLE.
ScopeGuardRepository ships nothing — exposes empty PREREQ + zero-length
RESHAPE_STEPS so it can be listed in applyDecoratorMigrations alongside
the schema-touching decorators without SFINAE.

Closes #12

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-29 21:47:03 +02:00