From 129c1a043db9c3750bf4b600914c139125d77062 Mon Sep 17 00:00:00 2001 From: Hein Date: Wed, 30 Sep 2026 23:03:50 +0200 Subject: [PATCH] docs(readme): document single transaction per request, OnTxBegin, test server --- README.md | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/README.md b/README.md index 4256c31..5d638a5 100644 --- a/README.md +++ b/README.md @@ -43,6 +43,7 @@ All share the same core architecture and provide dynamic data querying, relation * **Pagination**: Built-in limit/offset and cursor-based pagination (both ResolveSpec and RestHeadSpec) * **Computed Columns**: Define virtual columns for complex calculations * **Custom Operators**: Add custom SQL conditions when needed +* **🆕 One Transaction Per Request**: Every statement and DB-touching hook of a request runs on one transaction; `OnTxBegin` hook stamps transaction-local settings (RLS) first. See [pkg/common/TRANSACTIONS.md](pkg/common/TRANSACTIONS.md) * **🆕 Recursive CRUD Handler**: Automatically handle nested object graphs with foreign key resolution and per-record operation control via `_request` field ### Architecture (v2.0+) @@ -370,6 +371,14 @@ ResolveSpec is designed for testability with mockable interfaces. For testing ex - [RestHeadSpec Testing](pkg/restheadspec/README.md#testing) - [WebSocketSpec Testing](pkg/websocketspec/README.md) +### Test Server (dbtrace, real PostgreSQL) + +* `make testserver-up` / `make testserver-down`: testserver + PostgreSQL via compose (host networking) +* `make testserver-smoke`: create, read, update, delete, batch create/delete against the testserver +* Ports: testserver `8123`, PostgreSQL `8124` +* `dbtrace` logs per request `tx`, `tx_queries`, `pooled`, `raw`; `pooled=0` is the target +* Integration tests default to PostgreSQL on `localhost:8124` + ## Continuous Integration ResolveSpec uses GitHub Actions for automated testing and quality checks. The CI pipeline runs on every push and pull request. @@ -683,6 +692,24 @@ This project is licensed under the MIT License - see the [LICENSE](LICENSE) file ## What's New +### Unreleased + +**Single transaction per request**: + +* **One tx per request**: hooks get the transaction in `hookCtx.Tx`, never the pool (`BeforeHandle` runs before any tx and must not touch the DB) +* **`OnTxBegin` hook**: all specs (mqttspec re-exports websocketspec's); fires once, first, in every tx; error or abort rolls back with no detail to the client +* **Second short tx**: create/update re-fetch, `BeforeScan` and post-commit hooks (`AfterCreate`, `AfterUpdate`, restheadspec `AfterRead`, funcspec `BeforeResponse`) run on a new tx after the first commits +* **Delete**: single and batch delete, hooks included, in one tx +* **websocketspec / mqttspec**: one tx per message; begin/commit failures answer `transaction_error` +* **resolvemcp**: read, create, update, delete transactional +* **RLS stamping**: `SecurityList.SetTxSettings(fn)`; `RegisterSecurityHooks` of every spec stamps `set_config(name, value, true)` on `OnTxBegin`; fails closed +* **New**: `common.RunRequestTx`, `common.TxContext`, `common.TxHookName` +* **Behavior changes**: `AfterDelete` failure now rolls the delete back; funcspec begin/commit failure answers 500 `transaction_error` + +**Clients**: Go, Rust, C# and Dart clients for ResolveSpec and FunctionSpec under `clients/`. + +**Test server**: compose uses host networking; ports `8123` (testserver) and `8124` (PostgreSQL), previously `8080` and `5434`. + ### v3.2 (Latest - March 2026) **ResolveMCP - Model Context Protocol Server (🆕)**: