Add Repository<T> interface + ITemporalEntity + IHistoryRepository<T> #8

Closed
opened 2026-04-27 21:05:23 +02:00 by uwe.admin · 5 comments
Owner

Part of a structural refactor: move from per-entity *Db clients to a shared Repository<T> abstraction. This issue lands the interfaces only in webapp-scaffold. No behavior change yet, no concrete implementations, no callers updated.

Scope

Add to webapp-scaffold:

  • Repository<TDto> — pure abstract interface, temporal-agnostic:
    • findByEntityId(entityId)
    • list(filter)
    • save(dto) — generates a random UUID if entity_id is null on the DTO; otherwise uses the caller-supplied id (mixed allocation policy)
    • softDelete(entityId)
  • ITemporalEntity — DTO mixin/marker requiring entity_id, valid_from, valid_until
  • IHistoryRepository<TDto>separate interface for history(entityId), only implemented by repositories that wrap temporal entities
  • TemporalAt — value type: "live" or a specific point in time
  • ActorContext — placeholder for who is performing the action (used by the scope-guard decorator in the next issue)

Out of scope

  • Any concrete repository implementations
  • Decorators (temporal, scope-guard) — separate issue
  • Transactions / unit-of-work — explicitly deferred
  • Any migration of controllers or *Db callers in fewo-webapp

Acceptance

  • Interfaces compile in webapp-scaffold
  • A trivial in-memory test fake of Repository<MockDto> exists, demonstrating the contract without touching SQL

Decisions (from planning discussion)

  1. entity_id allocation: mixed — client passes id OR repository allocates a random UUID if null
  2. UnitOfWork: deferred, not in scope
  3. Repository<T> shape: pure abstract interface (not C++20 concept)
  4. History queries: live on a separate IHistoryRepository<T>, not on Repository<T>
Part of a structural refactor: move from per-entity `*Db` clients to a shared `Repository<T>` abstraction. This issue lands the **interfaces only** in webapp-scaffold. No behavior change yet, no concrete implementations, no callers updated. ## Scope Add to webapp-scaffold: - `Repository<TDto>` — pure abstract interface, **temporal-agnostic**: - `findByEntityId(entityId)` - `list(filter)` - `save(dto)` — generates a random UUID if `entity_id` is null on the DTO; otherwise uses the caller-supplied id (mixed allocation policy) - `softDelete(entityId)` - `ITemporalEntity` — DTO mixin/marker requiring `entity_id`, `valid_from`, `valid_until` - `IHistoryRepository<TDto>` — **separate** interface for `history(entityId)`, only implemented by repositories that wrap temporal entities - `TemporalAt` — value type: "live" or a specific point in time - `ActorContext` — placeholder for who is performing the action (used by the scope-guard decorator in the next issue) ## Out of scope - Any concrete repository implementations - Decorators (temporal, scope-guard) — separate issue - Transactions / unit-of-work — explicitly deferred - Any migration of controllers or `*Db` callers in fewo-webapp ## Acceptance - Interfaces compile in webapp-scaffold - A trivial in-memory test fake of `Repository<MockDto>` exists, demonstrating the contract without touching SQL ## Decisions (from planning discussion) 1. `entity_id` allocation: **mixed** — client passes id OR repository allocates a random UUID if null 2. UnitOfWork: **deferred**, not in scope 3. `Repository<T>` shape: **pure abstract interface** (not C++20 concept) 4. History queries: live on a **separate** `IHistoryRepository<T>`, not on `Repository<T>`
Author
Owner

Agent Evaluation

This issue was drafted as part of the planning thread that produced the parent tracking issue (uwe.admin/fewo-webapp#458). The body above is itself the evaluation; this comment closes the workflow loop.

Feasibility: Trivial — pure header definitions plus an in-memory test fake. No SQL, no controller changes, no fewo-webapp impact.

Impact: Foundational. Phases 2–7 all depend on these interfaces.

Effort: Small.

Recommendation: Accept. No design questions remain (decisions 1–4 are baked into the body).

## Agent Evaluation This issue was drafted as part of the planning thread that produced the parent tracking issue (uwe.admin/fewo-webapp#458). The body above is itself the evaluation; this comment closes the workflow loop. **Feasibility:** Trivial — pure header definitions plus an in-memory test fake. No SQL, no controller changes, no fewo-webapp impact. **Impact:** Foundational. Phases 2–7 all depend on these interfaces. **Effort:** Small. **Recommendation:** Accept. No design questions remain (decisions 1–4 are baked into the body).
Author
Owner

Agent Evaluation

Feasibility: Medium — interfaces themselves are trivial (~150 LOC of headers + an in-memory test fake). The blocking question is target language: webapp-scaffold today is a TypeScript/npm package (frontend build glue: vite-config, core-fetch, i18n, openapi codegen). It contains no C++. The proposed Repository<TDto> is a C++ abstraction over oatpp::orm::DbClient. It belongs in a C++ shared library — naturally oatpp-authkit (the existing header-only C++ companion) or a new oatpp-repo package — not in the npm frontend scaffold.

Impact: High if placed correctly. A composable repository layer is the right shape for the temporal + property-scope cross-cutting concerns the lost-booking incident exposed, and unblocks the 26-entity rollout in fewo-webapp #458. But landing it in webapp-scaffold would put C++ headers next to TypeScript build scripts in a package consumed via npm — an awkward mix that would force fewo-webapp's CMake to depend on a node package, and confuses the repo's stated purpose ("shared frontend build glue").

Effort: Small (~150 LOC) once the host repo is decided.

Recommendation: Needs clarification — pick a host repo before implementation.

Implementation plan (once target is chosen)

  1. Add headers under the host's include tree:
    • Repository.hpp (pure abstract, generic on TDto)
    • ITemporalEntity.hpp (marker requiring entity_id/valid_from/valid_until)
    • IHistoryRepository.hpp (separate interface for history(entityId))
    • TemporalAt.hpp (live-or-point-in-time value type)
    • ActorContext.hpp (placeholder for the scope-guard decorator)
  2. Add a trivial in-memory Repository<MockDto> fake to demonstrate the contract without SQL, gated under the host's existing test-build option.
  3. Export via the host's existing CMake config package so fewo-webapp can find_package and link.

Decision needed

Check one (edit this comment):

  • Option A — Move to oatpp-authkit — Reuses an existing C++ header-only library already consumed by fewo-webapp via FetchContent; no new package; matches oatpp-authkit's "distilled from fewo-webapp's hardened stack" charter.
  • Option B — New repo oatpp-repo — Keeps oatpp-authkit narrowly auth/security-focused; introduces a third C++ package to track and version. More boilerplate now.
  • Option C — Expand webapp-scaffold to host C++ headers too — Single "scaffold" repo for both frontend and backend shared code; consumers pull C++ via FetchContent and TypeScript via npm from the same git URL. Stretches the repo's identity but avoids a new package.
## Agent Evaluation **Feasibility:** Medium — interfaces themselves are trivial (~150 LOC of headers + an in-memory test fake). The blocking question is **target language**: webapp-scaffold today is a **TypeScript/npm package** (frontend build glue: vite-config, core-fetch, i18n, openapi codegen). It contains no C++. The proposed `Repository<TDto>` is a C++ abstraction over `oatpp::orm::DbClient`. It belongs in a C++ shared library — naturally `oatpp-authkit` (the existing header-only C++ companion) or a new `oatpp-repo` package — not in the npm frontend scaffold. **Impact:** High *if* placed correctly. A composable repository layer is the right shape for the temporal + property-scope cross-cutting concerns the lost-booking incident exposed, and unblocks the 26-entity rollout in fewo-webapp #458. But landing it in webapp-scaffold would put C++ headers next to TypeScript build scripts in a package consumed via npm — an awkward mix that would force fewo-webapp's CMake to depend on a node package, and confuses the repo's stated purpose ("shared frontend build glue"). **Effort:** Small (~150 LOC) once the host repo is decided. **Recommendation:** Needs clarification — pick a host repo before implementation. ### Implementation plan (once target is chosen) 1. Add headers under the host's include tree: - `Repository.hpp` (pure abstract, generic on `TDto`) - `ITemporalEntity.hpp` (marker requiring `entity_id`/`valid_from`/`valid_until`) - `IHistoryRepository.hpp` (separate interface for `history(entityId)`) - `TemporalAt.hpp` (live-or-point-in-time value type) - `ActorContext.hpp` (placeholder for the scope-guard decorator) 2. Add a trivial in-memory `Repository<MockDto>` fake to demonstrate the contract without SQL, gated under the host's existing test-build option. 3. Export via the host's existing CMake config package so fewo-webapp can `find_package` and link. ### Decision needed Check one (edit this comment): - [ ] **Option A — Move to oatpp-authkit** — Reuses an existing C++ header-only library already consumed by fewo-webapp via FetchContent; no new package; matches oatpp-authkit's "distilled from fewo-webapp's hardened stack" charter. - [ ] **Option B — New repo `oatpp-repo`** — Keeps oatpp-authkit narrowly auth/security-focused; introduces a third C++ package to track and version. More boilerplate now. - [ ] **Option C — Expand webapp-scaffold to host C++ headers too** — Single "scaffold" repo for both frontend and backend shared code; consumers pull C++ via FetchContent and TypeScript via npm from the same git URL. Stretches the repo's identity but avoids a new package.
uwe.admin added the
effort:medium
evaluated
labels 2026-04-27 21:07:38 +02:00

Please go with Option A for now.

Please go with Option A for now.
Author
Owner

Re-evaluation

Responding to owner feedback:

Please go with Option A for now.

Acknowledged. The C++ Repository<T> layer will land in oatpp-authkit, not webapp-scaffold. This issue (and #9) are effectively redirected — the intent is accepted, but the implementation target moves repos.

Implication for tracking: webapp-scaffold #8 / #9 should probably be closed in favour of equivalent tickets in oatpp-authkit. I'll do that as a separate poll action only with explicit owner instruction; for now this issue stays open as the design-discussion record.

Revised implementation plan (against oatpp-authkit)

  1. In oatpp-authkit/include/oatpp-authkit/, add a new repo/ subdirectory alongside the existing auth/, db/, dto/, handler/, etc.:
    • repo/Repository.hpp — pure abstract template <class TDto> class Repository with findByEntityId, list, save (mixed UUID allocation), softDelete.
    • repo/ITemporalEntity.hpp — DTO marker requiring entity_id/valid_from/valid_until.
    • repo/IHistoryRepository.hpp — separate history(entityId) interface.
    • repo/TemporalAt.hpplive | at(timestamp) value type.
    • repo/ActorContext.hpp — placeholder DTO for the scope-guard decorator.
  2. Add a unit test under oatpp-authkit/test/ exercising a Repository<MockDto> in-memory fake (matches the existing test_negotiation.cpp / test_json_serialization.cpp style — plain executable, REQUIRE macro, no third-party framework).
  3. Wire into test/CMakeLists.txt and add_test(NAME repository_interface ...).
  4. README: append a row to the v0.1 table for the new repo/ headers.

Updated effort: Small (unchanged — still ~150 LOC).
Updated recommendation: Accept (target now resolved). Ready for implementation when the owner adds accepted. The pilot uwe.admin/fewo-webapp#457 unblocks once this lands.

Decision needed (carried over)

The implementation target above assumes the in-house option lands first. The owner separately raised uwe.admin/webapp-scaffold#10 (optional IQueryable<T> capability + in-house query AST) — that's a follow-on, not a blocker for this issue.

## Re-evaluation Responding to owner feedback: > Please go with Option A for now. **Acknowledged.** The C++ `Repository<T>` layer will land in **oatpp-authkit**, not webapp-scaffold. This issue (and #9) are effectively redirected — the *intent* is accepted, but the implementation target moves repos. **Implication for tracking:** webapp-scaffold #8 / #9 should probably be closed in favour of equivalent tickets in oatpp-authkit. I'll do that as a separate poll action only with explicit owner instruction; for now this issue stays open as the design-discussion record. ### Revised implementation plan (against oatpp-authkit) 1. In `oatpp-authkit/include/oatpp-authkit/`, add a new `repo/` subdirectory alongside the existing `auth/`, `db/`, `dto/`, `handler/`, etc.: - `repo/Repository.hpp` — pure abstract `template <class TDto> class Repository` with `findByEntityId`, `list`, `save` (mixed UUID allocation), `softDelete`. - `repo/ITemporalEntity.hpp` — DTO marker requiring `entity_id`/`valid_from`/`valid_until`. - `repo/IHistoryRepository.hpp` — separate `history(entityId)` interface. - `repo/TemporalAt.hpp` — `live` | `at(timestamp)` value type. - `repo/ActorContext.hpp` — placeholder DTO for the scope-guard decorator. 2. Add a unit test under `oatpp-authkit/test/` exercising a `Repository<MockDto>` in-memory fake (matches the existing `test_negotiation.cpp` / `test_json_serialization.cpp` style — plain executable, REQUIRE macro, no third-party framework). 3. Wire into `test/CMakeLists.txt` and `add_test(NAME repository_interface ...)`. 4. README: append a row to the v0.1 table for the new `repo/` headers. **Updated effort:** Small (unchanged — still ~150 LOC). **Updated recommendation:** Accept (target now resolved). Ready for implementation when the owner adds `accepted`. The pilot uwe.admin/fewo-webapp#457 unblocks once this lands. ### Decision needed (carried over) The implementation target above assumes the in-house option lands first. The owner separately raised uwe.admin/webapp-scaffold#10 (optional `IQueryable<T>` capability + in-house query AST) — that's a follow-on, not a blocker for this issue.
Author
Owner

Closed in favour of uwe.admin/oatpp-authkit#7 per the Option A decision (this issue's #8 thread). C++ work belongs in oatpp-authkit, not in this TypeScript scaffold package.

Closed in favour of uwe.admin/oatpp-authkit#7 per the Option A decision (this issue's #8 thread). C++ work belongs in oatpp-authkit, not in this TypeScript scaffold package.
Sign in to join this conversation.
No milestone
No project
No assignees
2 participants
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference: uwe.admin/webapp-scaffold#8
No description provided.