oatpp-authkit/include/oatpp-authkit/repo/ITemporalEntity.hpp
Uwe Schuster a0c61b3d94 #7: Repository<T> interface set + ITemporalEntity + IHistoryRepository<T>
Header-only foundation for the structural refactor that moves fewo-webapp
from per-entity *Db clients to a shared Repository<TDto> abstraction. This
ships interfaces only — no concrete implementations, no callers updated.

Decisions baked in (all settled in the issue body):
- Mixed entity_id allocation: caller may supply, otherwise the concrete
  repo generates a UUID inside save().
- UnitOfWork / cross-repo transactions: explicitly out of scope.
- Repository<T> is a virtual-method interface, not a C++20 concept.
- History queries live on a separate IHistoryRepository<T> so non-temporal
  repos don't have to implement a stub.

Decorators (TemporalRepository<T>, ScopeGuardRepository<T>) follow in #8;
the optional IQueryable<T> capability for typed filtering follows in #9.
The fewo-webapp Person pilot (uwe.admin/fewo-webapp#457) and the wider
26-entity rollout (uwe.admin/fewo-webapp#458) build on this.

Closes #7

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

32 lines
1.2 KiB
C++

#ifndef OATPP_AUTHKIT_REPO_I_TEMPORAL_ENTITY_HPP
#define OATPP_AUTHKIT_REPO_I_TEMPORAL_ENTITY_HPP
namespace oatpp_authkit::repo {
/**
* @brief Marker for DTOs that carry temporal-versioning columns.
*
* A DTO opts in by inheriting this empty marker, signalling to the temporal
* decorator (oatpp-authkit#8) that the DTO has the three required oatpp
* `String` fields:
*
* @code
* DTO_FIELD(String, entity_id); // stable across versions
* DTO_FIELD(String, valid_from); // ISO-8601 UTC
* DTO_FIELD(String, valid_until); // ISO-8601 UTC; '9999-12-31T23:59:59Z' = live
* @endcode
*
* The marker is intentionally a plain empty struct rather than a C++20
* concept — the issue explicitly chose "pure abstract interface, not
* `requires` clause" for the wider Repository<T> shape, and this matches.
*
* Because oatpp DTOs use macros (`DTO_INIT` / `DTO_FIELD`), the field-shape
* contract above is documentation-enforced, not compiler-enforced. The
* temporal decorator dynamic-casts and accesses fields by name; a missing
* field surfaces as a clean runtime error at decorator construction.
*/
struct ITemporalEntity {};
} // namespace oatpp_authkit::repo
#endif