PrimebrickPrimebrick
  • Primebrick.dev
  • GitHub
  • Documentation
  • Services
  • Libraries
  • API Catalog
Resources
  • Landing Page
  • API Catalog
  • GitHub
PrimebrickPrimebrick

© 2026 Primebrick. MIT License.

github
DAL Library
    AI Agent Rules and SkillsAudit and Soft-Delete SubsystemsAudit Port and Delta TrackingAuditable Joins and Display NamesBulk OperationsCI/CD and Release ProcessConnection Pool and Session ConfigurationCore ArchitectureDal GatewayEntity Metadata SystemError HandlingGetting StartedGitFlow and Branching RulesGlossaryKey Design DecisionsOverviewQuery DSL and SQL BuilderRead OperationsRepository: CRUD and FindersStreaming Large Result SetsTest Infrastructure and EntitiesTest Suite CoverageTestingTimeout Management and withClientType Coercion: JS ↔ PostgreSQLWrite OperationsREADME
SDK Library
powered by Zudoku
DAL Library

Getting Started

Getting Started

Relevant source files

The following files were used as context for generating this wiki page:

  • .devin/skills/dal-usage/SKILL.md
  • .github/workflows/ci.yml
  • README.md
  • package.json
  • src/dal/dal.ts

This page provides a step-by-step guide for integrating @primebrick/dal-pg into a TypeScript project. It covers installation, environment configuration, entity definition, and basic database operations using the Dal gateway.

Installation

The package is managed via pnpm and requires reflect-metadata to support decorator-based entity definitions.

TerminalCode
pnpm install @primebrick/dal-pg reflect-metadata

TypeScript Configuration

Ensure your tsconfig.json includes the following settings to support the metadata system used by the DAL:

Code
{ "compilerOptions": { "experimentalDecorators": true, "emitDecoratorMetadata": true, "module": "NodeNext", "target": "ES2022" } }

Sources:

  • package.json:44-49
  • README.md:20-20

Environment Configuration

The DAL requires a valid PostgreSQL connection string. By convention, this is stored in a .env file or provided via the DATABASE_URL environment variable.

Code
DATABASE_URL=postgresql://user:password@localhost:5432/dbname?sslmode=disable

The Dal gateway uses this string to initialize the internal pg.Pool src/dal/dal.ts:131-137.

Sources:

  • src/dal/dal.ts:55-56
  • .devin/skills/dal-usage/SKILL.md:41-41

Initializing the Dal Gateway

The Dal class serves as the process-wide entry point. It manages the connection pool, registers type parsers (such as INT8 to bigint conversion), and enforces best-practice defaults like statement_timeout to prevent pool starvation src/dal/dal.ts:4-22.

Setup Example

Code
import "reflect-metadata"; // Must be imported at the entry point import { getDal } from "@primebrick/dal-pg"; const dal = getDal({ connectionString: process.env.DATABASE_URL!, schema: "public", max: 10, // Max pool size statementTimeoutMs: 30000, // 30s timeout per query applicationName: "my-service" }); // Graceful shutdown process.on("SIGTERM", async () => { await dal.close(); process.exit(0); });

Gateway Lifecycle and Data Flow

The following diagram illustrates how the Dal gateway initializes the system and bridges the application to the PostgreSQL database.

Diagram: Dal Initialization and Connection Flow

Code
graph TD subgraph "Application Space" App["App Entry"] -- "calls" --> getDal["getDal(config)"] getDal -- "creates" --> DalInstance["class Dal"] end subgraph "Dal Gateway (Internal)" DalInstance -- "1. register" --> TypeParsers["ensureTypeParsers()"] DalInstance -- "2. create" --> Pool["pg.Pool"] DalInstance -- "3. instantiate" --> Repo["class Repository"] Pool -- "onConnect hook" --> SessionConfig["SET statement_timeout<br/>SET search_path"] end subgraph "Database Space" SessionConfig -- "executes on" --> PG["PostgreSQL Instance"] end TypeParsers -- "modifies" --> PG_Types["pg.types.setTypeParser"]

Sources:

  • src/dal/dal.ts:101-170
  • src/dal/dal.ts:128-128
  • src/dal/dal.ts:147-163
  • .devin/skills/dal-usage/SKILL.md:36-52

Defining an Entity

Entities are plain TypeScript classes decorated with metadata. The DAL uses these decorators to map class properties to database columns and handle specialized logic like auditing and soft-deletion.

Code
import { Entity, Column, Key, Unique, AuditableField, DeletableField, AuditableFieldType, DeletableFieldType } from "@primebrick/dal-pg"; @Entity("user_account") export class UserAccount { @Key() id!: number; @Unique() uuid!: string; @Column({ length: 255, nullable: false }) email!: string; @AuditableField(AuditableFieldType.VERSION) version!: number; @DeletableField(DeletableFieldType.DELETED_AT) deleted_at?: Date; }

Sources:

  • README.md:7-7
  • .devin/skills/dal-usage/SKILL.md:59-78

Running the First Query

The Dal instance provides high-level methods for CRUD operations. All write operations utilize RETURNING * to ensure the returned object reflects the database state README.md:43-43.

Basic CRUD Operations

Code
// 1. Create (Add) const newUser = await dal.add(UserAccount, { email: "hello@primebrick.io" }, { actor: "system-init" }); // 2. Read (Find) const user = await dal.findByUUID(UserAccount, newUser.uuid); // 3. Filtered Search import { Filter, field } from "@primebrick/dal-pg"; const results = await dal.findAll(UserAccount, null, { filters: [ Filter.fieldValue(field(UserAccount, "email"), "=", "hello@primebrick.io") ] });

Entity to SQL Mapping

The following diagram bridges the "Natural Language Space" (Entity definitions) to the "Code Entity Space" (SQL Generation).

Diagram: Entity Metadata to SQL Execution

Code
graph LR subgraph "Code Entity Space" UserClass["@Entity('user_account')<br/>class UserAccount"] DalAdd["dal.add(UserAccount, data)"] end subgraph "Metadata Engine" Meta["getEntityPersistenceMeta"] SQLBuilder["buildInsertQuery"] end subgraph "Execution Space" Pool["pg.Pool.query()"] SQL["INSERT INTO user_account (...)<br/>RETURNING *"] end UserClass -- "scanned by" --> Meta DalAdd -- "triggers" --> SQLBuilder Meta -- "provides table/columns to" --> SQLBuilder SQLBuilder -- "generates" --> SQL SQL -- "sent via" --> Pool

Sources:

  • README.md:7-9
  • src/dal/dal.ts:172-180
  • .devin/skills/dal-usage/SKILL.md:83-106

Error Handling

The DAL throws specific error classes defined in @primebrick/dal-pg/errors. By default, finder methods like findById or findByUUID throw a NotFoundError if the record does not exist README.md:44-44.

Code
import { NotFoundError } from "@primebrick/dal-pg"; try { await dal.findByUUID(UserAccount, "some-uuid"); } catch (err) { if (err instanceof NotFoundError) { console.error("User not found in database."); } }

Sources:

  • package.json:23-27
  • .devin/skills/dal-usage/SKILL.md:168-176

Last modified on July 13, 2026
Error HandlingGitFlow and Branching Rules
On this page
  • Installation
    • TypeScript Configuration
  • Environment Configuration
  • Initializing the Dal Gateway
    • Setup Example
    • Gateway Lifecycle and Data Flow
  • Defining an Entity
  • Running the First Query
    • Basic CRUD Operations
    • Entity to SQL Mapping
  • Error Handling
JSON
TypeScript
TypeScript
TypeScript
TypeScript