Postgres mit Drizzle: gemeinsamer Client, Schemas pro Modul, Transaktionen und ULID-IDs
Code8 DateienKontext~547 TokensPrüfung bestanden
Installieren
$
genpm add @core/dbWas du bekommst
- Quellcode in src/lib/db/, 8 Dateien. (7,6 kB)
- KI-Regeln in src/lib/db/AGENTS.md, dazu Regeldateien für die IDE.
- Umgebungsvariablen in .env.example ergänzt: DATABASE_URL.
README
Dieses Paket hat keine README.
~547 Tokens→ src/lib/db/AGENTS.md→ .cursor/rules/genpm-core-db.mdc
Genau das liest deine KI, wenn sie in src/lib/db arbeitet. Sonst wird ihrem Kontext nichts hinzugefügt.
@core/db — rules for AI agents
Purpose
Shared Postgres access for every module: one Drizzle client, per-module schemas, transactions, ULID ids and standard timestamps. It owns no tables itself. Not an ORM wrapper: use Drizzle's query builder directly.
Map
index.ts— public API:getDb,createDb,setDb,withTransaction,primaryId,timestamps,newId,ulid; typesDb,Tx,Executor.client.ts— lazy client fromDATABASE_URL(postgres-js).columns.ts—primaryId(prefix)andtimestampscolumn helpers.drizzle.config.ts— drizzle-kit config that collectssrc/lib/*/schema.ts.
Integration
- Set
DATABASE_URL(any Postgres: local, Neon, Supabase, RDS). - Install the npm deps if GenPM did not:
drizzle-orm,postgres, anddrizzle-kitas a dev dependency. - Add scripts to
package.json:"db:generate": "drizzle-kit generate --config src/lib/db/drizzle.config.ts","db:migrate": "drizzle-kit migrate --config src/lib/db/drizzle.config.ts". - Run
db:generatethendb:migrateafter installing any module that has aschema.ts. - Query from app code:
import { getDb } from './lib/db/index.js'; const rows = await getDb().select().from(users); - Another driver (Neon serverless, PGlite in tests): build it with Drizzle and call
setDb(db)once at startup.
Conventions
- Each module defines its tables in its own
src/lib/<module>/schema.ts. Never put tables insrc/lib/db. - Table names are prefixed with the module when ambiguous (
auth_sessions, notsessions). - Primary keys:
id: primaryId('<3-4 letter prefix>'); spread...timestampsin every table. - Functions that write accept an optional
Executor(dbortx) so callers can compose them inwithTransaction. - Money as integer minor units; times as
timestamp with time zone.
Don't
- Don't edit or reference another module's tables except through that module's exported functions.
- Don't create a second client or connection pool; use
getDb(). - Don't log
DATABASE_URLor query parameters that may hold secrets. - Don't use
drizzle-kit pushagainst production; generate and review migrations.
# @core/db — rules for AI agents
## Purpose
Shared Postgres access for every module: one Drizzle client, per-module schemas, transactions, ULID ids and standard
timestamps. It owns no tables itself. Not an ORM wrapper: use Drizzle's query builder directly.
## Map
- `index.ts` — public API: `getDb`, `createDb`, `setDb`, `withTransaction`, `primaryId`, `timestamps`, `newId`, `ulid`; types `Db`, `Tx`, `Executor`.
- `client.ts` — lazy client from `DATABASE_URL` (postgres-js).
- `columns.ts` — `primaryId(prefix)` and `timestamps` column helpers.
- `drizzle.config.ts` — drizzle-kit config that collects `src/lib/*/schema.ts`.
## Integration
1. Set `DATABASE_URL` (any Postgres: local, Neon, Supabase, RDS).
2. Install the npm deps if GenPM did not: `drizzle-orm`, `postgres`, and `drizzle-kit` as a dev dependency.
3. Add scripts to `package.json`:
`"db:generate": "drizzle-kit generate --config src/lib/db/drizzle.config.ts"`,
`"db:migrate": "drizzle-kit migrate --config src/lib/db/drizzle.config.ts"`.
4. Run `db:generate` then `db:migrate` after installing any module that has a `schema.ts`.
5. Query from app code:
```ts
import { getDb } from './lib/db/index.js';
const rows = await getDb().select().from(users);
```
6. Another driver (Neon serverless, PGlite in tests): build it with Drizzle and call `setDb(db)` once at startup.
## Conventions
- Each module defines its tables in its own `src/lib/<module>/schema.ts`. Never put tables in `src/lib/db`.
- Table names are prefixed with the module when ambiguous (`auth_sessions`, not `sessions`).
- Primary keys: `id: primaryId('<3-4 letter prefix>')`; spread `...timestamps` in every table.
- Functions that write accept an optional `Executor` (`db` or `tx`) so callers can compose them in `withTransaction`.
- Money as integer minor units; times as `timestamp with time zone`.
## Don't
- Don't edit or reference another module's tables except through that module's exported functions.
- Don't create a second client or connection pool; use `getDb()`.
- Don't log `DATABASE_URL` or query parameters that may hold secrets.
- Don't use `drizzle-kit push` against production; generate and review migrations.
Der genaue Baum, der nach .genpmignore eingebunden wird. Gepinnt an
// Cliente de base de datos. Un único `Db` para toda la app, creado perezosamente desde DATABASE_URL.
// El tipo es el `PgDatabase` genérico de Drizzle: cualquier driver Postgres (postgres-js, Neon, PGlite…) sirve.
import type { ExtractTablesWithRelations } from 'drizzle-orm';
import type { PgDatabase, PgQueryResultHKT, PgTransaction } from 'drizzle-orm/pg-core';
import { drizzle } from 'drizzle-orm/postgres-js';
import postgres from 'postgres';
export type Db = PgDatabase<PgQueryResultHKT, Record<string, never>>;
export type Tx = PgTransaction<PgQueryResultHKT, Record<string, never>, ExtractTablesWithRelations<Record<string, never>>>;
/** Cualquier cosa sobre la que se pueden lanzar consultas: la BD o una transacción en curso. */
export type Executor = Db | Tx;
let current: Db | null = null;
/** Crea un cliente Postgres. `max` bajo por defecto: pensado para serverless y desarrollo. */
export function createDb(url: string | undefined = process.env.DATABASE_URL, opts: { max?: number } = {}): Db {
if (!url) throw new Error('DATABASE_URL is not set (see .env.example)');
const sql = postgres(url, { max: opts.max ?? 5, prepare: false });
return drizzle(sql) as unknown as Db;
}
/** El cliente compartido de la app. */
export function getDb(): Db {
current ??= createDb();
return current;
}
/** Sustituye el cliente compartido (tests, o un driver distinto como PGlite o Neon). */
export function setDb(db: Db): void {
current = db;
}
Dieses Paket deklariert keine MCP-Server.
| Version | Commit | Veröffentlicht | Prüfung |
|---|---|---|---|
| 1.0.0 | 28d4b9f | vor 4 Stunden | ✔ Prüfung bestanden |
- genpm
- keine
- vorgeschlagen
- GenPM schlägt den npm-Befehl vor und führt ihn nur aus, wenn du zustimmst.
- Prüfung
- Prüfung bestanden · 0 Befunde
- Commit
- v1.0.0 → 28d4b9feecb83c7a3efc1ec8fd975ee003b0e3f3 · nach dem Abruf verifiziert
- Skripte
- Keine. GenPM führt niemals Paketcode aus.
- Lizenz
- MIT
- Meldung
- Stimmt etwas nicht?