lenso-postgres-kit
lenso-postgres-kit gives a stateful Lenso Module an explicit lifecycle for
its own PostgreSQL schema. It is intentionally not a shared State Module, a
generic SQL Capability, or an ORM.
The owning Module still defines:
- its data model and immutable ordered migrations;
- its SQL queries and transaction boundaries;
- its backup, restore, retention, and data-governance policy;
- the dedicated PostgreSQL role used to enforce schema access in production.
The kit supplies:
- atomic, advisory-locked schema setup and upgrade;
- a private migration ledger with checksum drift detection;
- fail-closed runtime preparation that never migrates automatically;
- a verified SQLx pool with the Module schema selected as its
search_path.
Author one owned schema
Keep SQL in the owning Module's migrations/ directory and include it in the
binary at compile time. The Rust declaration remains the explicit ordered
schema plan; the SQL body stays reviewable as SQL:
orders-module/
├── migrations/
│ ├── 001_create_orders.sql
│ └── 002_add_order_status.sql
└── src/
└── lib.rs
use ;
const MIGRATIONS: & = sql_migrations!;
# async
Paths are relative to the owning crate's Cargo.toml. sql_migrations!
expands to include_str! for each file. There is no runtime directory scan, so
missing files fail compilation, file changes trigger a rebuild, and the
existing migration checksum still binds version, stable name, and exact SQL.
Never edit an applied SQL file; append the next numbered file.
When a new migration is linked, preparation returns UpgradeRequired. Stop
the owning Module, run SchemaOperator::upgrade, and then prepare the new
generation. setup never adopts an existing unmanaged schema, and checksum
drift or a newer database fails closed.
Isolation contract
search_path provides convenient unqualified queries; it is not a security
boundary. Give each Module a dedicated non-superuser PostgreSQL role, make that
role the owner of only its schema, and restrict grants at the database level.
The kit verifies that the current role owns the selected schema.
Sharing one physical PostgreSQL cluster does not grant one Module access to another Module's tables. Cross-Module workflows belong in explicit Capability calls and application-level coordination, not in shared SQL transactions.
Validation
LENSO_POSTGRES_TEST_URL=postgres://... \