Entity-table writes go through the repositories

Table of Contents

1. Summary

Application code writes an entity table only through the generated repository for that entity. The repository states the optimistic concurrency claim, stamps the audit columns, and applies the tenant and the party the row must carry; a hand-written write states all of that itself and drifts from the repository the moment either changes. Two classes are excepted: the sanctioned tenant purge and test fixtures. A check states the rule to a machine, and a ratchet baseline names the writers that predate it.

2. Detail

2.1. The rule

A table named ores_<component>_<entity>_tbl is an entity table. Only the generated repository for that entity writes it. Neither a SQL function nor a hand-written C++ file runs insert, update or delete against one.

The repository is where the shape of a write lives:

  • The claim. Who last read the row, which the store checks before it writes.
  • The audit. modified_by, performed_by, the change reason and the comment.
  • The tenant and the party. Row-level security holds the written row to both.

2.2. The exceptions

The sanctioned purge. ores_iam_purge_tenant_fn deletes across the component tables when a tenant is removed. It is the one function allowed to write entity tables directly, and ores_iam_purge_test_tenants_fn is its test counterpart.

Test fixtures. The SQL test tree, projects/ores.sql/test/, and every tests directory, write the rows a repository would, so that a test can set up the state it needs. They are not application code.

2.3. The check

projects/ores.codegen/scripts/check_entity_table_writes.py reads every SQL function under projects/ores.sql/create/ and every hand-written C++ file under projects/ores.*/. It fails on a writer of an entity table that is not a repository, the purge or a fixture. It runs in .github/workflows/codegen-drift.yml and locally:

python3 projects/ores.codegen/scripts/check_entity_table_writes.py

2.4. The ratchet baseline

projects/ores.codegen/scripts/entity_table_writes_baseline.json names the writers that predate the rule, each with a reason. The check fails on a writer that is not in it, and on an entry that no longer writes, so the list can only shrink. Remove an entry when its writer is fixed. Run --write-baseline only to accept a new writer, and state its reason.

3. See also

Emacs 29.3 (Org mode 9.6.15)