Database Access Standard
Explain the converged PostgreSQL tier model, allowed Knex boundaries, and SQL-first review rules.
The repository uses one auditable PostgreSQL access standard across backend domain packages. Knex remains the shared transport and DDL engine, but day-to-day domain logic talks through neutral executor contracts and SQL-first stores.
Tier Model
Tier 1 uses a request-scoped
DbExecutorwith one pinned connection and RLS claims.Tier 2 uses a pool-level
DbExecutorfor admin, bootstrap, and public non-RLS work.Tier 3 keeps raw Knex only in infrastructure, migrations, and package-local DDL boundaries.
Core Rules
Domain routes and services accept
DbExecutororSqlQueryable.Domain code does not import
knexorKnexClientdirectly.Dynamic identifiers go through
qSchema,qTable,qSchemaTable, andqColumn.Mutating DML uses
RETURNINGso callers observe the committed row shape.Active-row reads must respect the owning domain soft-delete contract.
Zero-row writes fail closed instead of silently succeeding after stale lookups or races.
Advisory locks go through shared helpers instead of route-local or service-local raw helper forks.
Long-running work sets explicit
SET LOCAL lock_timeoutandstatement_timeoutbudgets.Schema-qualified names are required; domain SQL does not rely on
search_path.
Allowed Tier 3 Boundaries
@universo/schema-ddland migration packages own direct Knex DDL orchestration.@universo/databaseowns the shared Knex lifecycle and executor factories.@universo/applications-backendkeeps raw Knex behindsrc/ddl/index.tsfor runtime sync DDL orchestration.@universo/metahubs-backendkeeps raw Knex inside its DDL seams and schema-ddl integration paths.These boundaries may bridge back into executor-style contracts, but route and store code outside them stay SQL-first.
Request Flow
ensureAuthWithRlspins one connection and appliesrequest.jwt.claims.Route handlers choose request executor or pool executor at the boundary.
Services and stores run schema-qualified parameterized SQL through shared query and identifier helpers.
DDL or migration code stays in Tier 3 and may keep direct Knex access inside dedicated boundaries only.
Review Expectations
New persistence helpers should have direct unit tests, not only route-level mocks.
Route handlers should choose the correct tier once and pass neutral contracts downward.
Copy, delete, restore, and sync flows should prove their fail-closed behavior explicitly.
Package documentation and
AGENTS.mdguidance should match the same tier rules.
Enforcement
tools/lint-db-access.mjsblocks forbidden Knex usage in domain packages.CI runs the lint-db-access step before the workspace build.
Reviewers use the database code review checklist in the contributing docs.
Related References
Last updated