Postgresql sql engineering
Skill nledford/engineering-review-board/skills/postgresql-sql-engineering
A collection of AI agent skills I have written
npx -y skills add nledford/engineering-review-board --skill postgresql-sql-engineeringAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
One thing to look at
- 0 stars0 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
What its author says it does
Copied from the file, not written here
PostgreSQL and SQL engineering guidance. Use with sql-engineering when adding, changing, reviewing, testing, or optimizing PostgreSQL schemas, SQL queries, migrations, transactions, constraints, indexes, views, functions, row-level security, privileges, data behavior, or database performance in any language stack. Do not use for unchanged-SQL ORM or adapter mechanics. Use api-design when migrations or query outputs affect published contracts and observability-engineering for PostgreSQL telemetry signals.
SKILL.md
10.7 KB, ~2.2k tokens by cl100k_base, as published. Nobody here has run it
PostgreSQL And SQL Engineering
Use this skill with sql-engineering for
database-native PostgreSQL work independent of the application language. Let the
database-neutral skill establish shared SQL behavior and use this skill for
PostgreSQL semantics. Keep database invariants explicit, changes deployable, and
query behavior proven with the target database.
Use When
- Designing or reviewing tables, constraints, indexes, views, functions, triggers, migrations, transactions, privileges, RLS, or PostgreSQL extensions.
- Writing or reviewing SQL queries, query plans, pagination, bulk operations, reporting queries, or data repair scripts.
- A change needs database correctness, performance, security, observability, or rollback evidence.
- Rust code uses SQLx or SeaQuery against PostgreSQL: use this skill for
database design and
rust-persistence-sqlfor Rust adapter, execution, and query-builder details.
Do not use this skill for generic in-memory domain logic, ORM-only API usage with no SQL/schema behavior, or SQLite-specific behavior except when comparing it to PostgreSQL.
Security Review Routing
Load security-review when PostgreSQL work
touches roles, privileges, RLS/policies, SECURITY DEFINER, extensions,
dynamic SQL or injection risk, tenant isolation, audit logs, sensitive
migrations/backfills, data repair scripts, secrets, or production-data access.
Pair it with security-review-evidence
when evidence includes redacted SQL, EXPLAIN output, schema diffs,
audit/log samples, dumps, or migration artifacts.
API and Observability Routing
- Load
api-designwhen PostgreSQL migrations, views, functions, outbox/event rows, generated schemas, reporting outputs, or constraint-error mapping affect an external contract or compatibility promise. - Load
observability-engineeringwhen PostgreSQL work changes slow-query, migration, pool, lock wait, deadlock, replication, maintenance, dashboard, alert, or runbook signals.
Workflow
- Inspect the real database surface: migrations, schema dumps, SQL files, query builders, ORM mappings, seed data, test fixtures, migration tool, target PostgreSQL major version, extensions, and CI database setup. Verify version-sensitive behavior in the official documentation for that target version, not only the current documentation.
- State the data behavior before implementation. Use BDD-style examples for observable rules such as uniqueness, authorization, lifecycle transitions, conflict handling, and partial-write prevention.
- Model the boundary. Use DDD language for entities, value objects, aggregate-like consistency boundaries, repositories, and invariants. Do not let table shape leak into core domain APIs without a deliberate adapter.
- Design schema and migration order: new objects, backfill, constraints, indexes, locks, deploy compatibility, rollback, and validation queries.
- Implement SQL with bound parameters, explicit columns, deliberate transaction scope, and safe error mapping at the application edge.
- Verify with the target engine: migration from empty database, migration from a representative previous schema, focused query tests, and plan inspection for performance-sensitive paths.
Schema And Migration Checklist
- Tables have stable primary keys when identity matters, meaningful foreign
keys,
NOT NULLfor required facts, andCHECK,UNIQUE, exclusion, or domain constraints for invariants the database must enforce. - Normalize first. Denormalize, materialize, or duplicate only for measured read needs with an ownership and refresh story.
- Choose types by semantics:
TEXTfor ordinary strings,NUMERICfor exact decimal money-like values,TIMESTAMPTZfor instants,DATEfor dates,BOOLEANfor two-state facts, JSONB only for semi-structured data, and enums/domains/lookup tables when they fit the change cadence. - Index foreign key columns manually when joins or parent updates/deletes need them; PostgreSQL does not create those indexes automatically.
- Indexes have a query rationale. Match predicates, join keys, sort order, uniqueness, and partial or expression predicates to real access paths.
- Migration files are ordered for safe rollout. Call out lock-heavy DDL,
backfills, table rewrites,
CREATE INDEX CONCURRENTLY, data loss, and app/schema compatibility windows. - Views and materialized views declare security, staleness, refresh, ownership, and indexing assumptions.
Query And Transaction Checklist
- Select explicit columns. Avoid
SELECT *unless the whole row is the contract. - Bind user-controlled values. Never concatenate untrusted input into SQL.
- Predicates are sargable where possible and line up with available indexes.
- Joins preserve intended cardinality and do not accidentally multiply rows.
- Pagination is stable under inserts and deletes; prefer keyset pagination for large ordered result sets.
NULL, collation, case sensitivity, timezone, numeric precision, and enum evolution are explicit where they affect behavior.- Transactions cover exactly one consistency boundary. Name isolation, lock-ordering, retry, idempotency, and deadlock assumptions when concurrent writes matter.
- Bulk writes use set-based SQL,
COPY, or batched statements when appropriate instead of row-at-a-time loops.
PostgreSQL Features
- Use B-tree indexes for normal equality/range/order queries; GIN for JSONB, arrays, and full-text search; GiST/SP-GiST for ranges, geometry, and exclusion constraints; BRIN for very large naturally ordered data.
- JSONB works best for optional or variable attributes. Promote frequently filtered or constrained fields to columns, generated columns, expression indexes, or constraints when they become core behavior.
- Arrays are useful for ordered scalar lists, not many-to-many relationships that need referential integrity.
- Range types plus exclusion constraints are strong tools for non-overlap rules such as bookings and schedules.
- Row-level security and privileges are security boundaries. Review actor, role, policy predicate, bypass paths, and test coverage before relying on them.
- Extensions such as
pg_trgm,pgcrypto,citext, PostGIS, TimescaleDB, or pgvector must have a clear product need, migration story, and operational ownership.
RLS, Privileges, And Privileged Functions
- Model the actual application role, migration role, and object-owner role;
test the policy with representative connections or
SET ROLE, not just a privileged development connection. Superusers and roles withBYPASSRLSalways bypass RLS; table owners usually do too unless the table usesFORCE ROW LEVEL SECURITY. - Scope each policy deliberately by command and
TOrole.USINGcontrols which existing rows are visible or targetable bySELECT,UPDATE, andDELETE;WITH CHECKcontrols proposed rows forINSERTandUPDATE. Ordinary table grants still authorize commands: RLS filters authorized access, it does not replace grants. - Test allowed and denied reads, inserts, updates, and deletes for the app role, migration/owner behavior where relevant, and expected bypass behavior. Include cross-tenant and policy-absent cases.
- Use
SECURITY DEFINERonly for a narrow, reviewed privilege boundary. Give the function a trusted owner, fully qualify referenced objects, and set a trustedsearch_pathwithpg_templast (for example,SET search_path = app_private, pg_temp); do not search schemas writable by callers. - Create privileged functions transactionally, revoke default
PUBLICexecute immediately, then grant execute only to intended roles. Keep the function owner and its table privileges least-privileged and explicit.
Commands
Prefer repository recipes when they exist, especially for SQL scripts. When direct commands are needed:
psql -X -v ON_ERROR_STOP=1 -f path/to/query.sql
psql -c "\\d+ table_name"
psql -c "EXPLAIN (ANALYZE, BUFFERS) SELECT ..."
sqlx migrate run
sqlx migrate revert
By default, psql continues after SQL errors. ON_ERROR_STOP stops processing
and makes a noninteractive script invocation fail when an error occurs.
Use SQLx migration commands only when the repository uses SQLx. Otherwise use
the repository's migration tool or SQL deployment recipe. Use a repository-owned
recipe, libpq defaults, or a named PGSERVICE configured outside the command;
never put credentialed DSNs in argv, shell history, logs, examples, or reports.
For mutating EXPLAIN ANALYZE, use a transaction and rollback on disposable or
safe data:
BEGIN;
EXPLAIN (ANALYZE, BUFFERS) UPDATE ...;
ROLLBACK;
Testing And Review
- Use TDD for query bugs when practical: write a failing fixture or integration test that proves the old behavior is wrong.
- Use BDD examples for data behavior users can observe: duplicate prevention, authorization, lifecycle state, conflict responses, and atomicity.
- Test constraints and transactions against PostgreSQL, not only mocks or SQLite.
- Review plans for expensive queries with representative data and current statistics. Do not claim performance improvement without comparable evidence.
- Review security for injection, least privilege, RLS policy coverage, secret handling, audit logs, and safe error messages.
- Review observability for slow queries, migration failures, pool saturation, deadlocks, lock waits, and maintenance signals.
Anti-Patterns
- Treating application validation as a substitute for database constraints on critical invariants.
- Adding indexes speculatively without query, cardinality, and write-cost rationale.
- Assuming
EXPLAIN ANALYZEis read-only. - Hiding long or multi-domain transactions behind generic repository helpers.
- Storing relational facts in JSONB because it is convenient.
- Claiming PostgreSQL behavior from tests that only ran on SQLite or mocks.
Successful Use
The final handoff names the data behavior protected, migrations or SQL changed, database-specific checks run, query-plan or performance evidence when relevant, and any deploy or rollback risk that remains.