This page takes you from zero to a working query in about 10 minutes: install,
bootstrap the Dal gateway, define an entity, and run insert + read + update +
delete. It assumes you already have a PostgreSQL database reachable via a
connection string.
@primebrick/dal-pg is a leaf dependency — it only depends on pg,
pg-query-stream, and reflect-metadata. It must not import from
primebrick-be-v3 or primebrick-us-v3.
reflect-metadata must be imported once, at the entry point of your
process, before any entity class is loaded. The decorators rely on the
Reflect.getMetadata("design:type", ...) reflection that
reflect-metadata polyfills.
Code
// src/index.ts — your process entry pointimport "reflect-metadata";// ... rest of your bootstrap
2. Bootstrap the Dal gateway
The Dal gateway (getDal()) is a singleton that owns the pg.Pool, registers
type parsers (INT8→bigint, NUMERIC→number), and sets search_path,
statement_timeout, and application_name on every connection. Create it once
at process startup and reuse it for every request — zero per-request allocation.
Code
// src/db.tsimport "reflect-metadata";import { getDal, type Dal } from "@primebrick/dal-pg";let _dal: Dal | undefined;export function getDb(): Dal { if (!_dal) { _dal = getDal({ connectionString: process.env.DATABASE_URL!, schema: "myapp", max: 10, statementTimeoutMs: 30_000, connectionTimeoutMillis: 5_000, applicationName: "my-service", }); } return _dal;}export async function closeDb(): Promise<void> { if (_dal) { await _dal.close(); _dal = undefined; }}
Wire graceful shutdown so the pool drains on SIGTERM:
Code
// src/index.tsimport { getDb, closeDb } from "./db.js";process.on("SIGTERM", async () => { await closeDb(); process.exit(0);});// ... start your HTTP server / NATS subscriber here
3. Define your first entity
Entities are plain TypeScript classes decorated with @Entity, @Key,
@Column, and @AuditableField. The class maps to a table; each decorated
property maps to a column. snake_case is used everywhere — DB column, TS
property, JSON response.
getDal(config) — creates the singleton pool, registers type parsers,
and stores the onConnect hook that sets session defaults.
dal.add(Entity, values, opts) — the Dal delegates to an internal
Repository(pool). The Repository reads entity metadata, builds a
parameterized INSERT ... RETURNING *, and hydrates the result row into an
entity instance (with bigint for INT8, Date for timestamptz, etc.).
Connection release — the pool reclaims the connection for the next
request. No per-request allocation.
6. Common pitfalls
Pitfall
Symptom
Fix
Forgot import "reflect-metadata" at the entry point