A current-state remove reports removed for a delete that matched nothing
Table of Contents
This page is a capture in the inbox bucket of the product backlog — a pre-sprint idea, not yet pulled into a sprint as a story.
1. What
A generated repository's remove() answers with a remove_status. For an
entity with audit columns the template reads the row back after the DELETE
and answers conflicting when it is still there. A current-state entity
has no audit columns, so the read-back is skipped and the function answers
removed whatever the DELETE did. execute_delete_query is the reason it
cannot know: it discards the affected-row count, so a DELETE that matched
nothing is indistinguishable from one that removed the row.
The hole is reachable whenever the DELETE's predicate and the caller's
belief about the row disagree — the compute workflow bridge did exactly
that by passing the wrong tenant, and the removed answer hid it. Make
execute_delete_query return the affected-row count, and have the
current-state template answer missing when the count is zero. The
audit-column path needs no change; it already reads the row back.
2. Why
removed is a claim about the database, and the caller acts on it: the
bridge treats removed as "the link is gone, do not fire again". A false
removed turns an idempotency guard into a loop. Reporting the count is
one line in a helper every generated repository already calls, so the fix
is cheaper than each caller guessing.
3. References
projects/ores.database/include/ores.database/repository/bitemporal_operations.hpp—execute_delete_query, which returns void today.projects/ores.codegen/library/templates/cpp_domain_type_repository.cpp.mustache— thehas_audit_columnsread-back and the current-state path beside it.projects/ores.compute/service/src/app/batch_workflow_bridge.cpp— the caller the wrong answer misled.
4. See also
- Paginate the compute list requests — another generated-read follow-up.