---
title: "Database and migrations"
description: "Drizzle push for local dev, migrate for UAT/prod, generate, and the better-auth schema output path."
canonical_url: "https://vinicunca.dev/taman/guides/database-and-migrations"
---
# Database and migrations

> Drizzle push for local dev, migrate for UAT/prod, generate, and the better-auth schema output path.

Package: `@taman/db-pg` (`packages/server/db-pg`). Config: `drizzle.config.ts`.

```ts
export default defineConfig({
  dialect: 'postgresql',
  schema: './src/schemas/index.ts',
  out: './migrations',
  dbCredentials: { url: DATABASE_URL },
});
```

`DATABASE_URL` is required (nx injects it from `.env` / `.env.uat` / `.env.prod`).

## Local development

```bash
docker compose up -d
pnpm db-pg:migrate:dev   # drizzle-kit push
```

**Push** applies the TypeScript schema directly. There is **no** `packages/server/db-pg/migrations` directory in the repository yet. Do not assume SQL files exist until you run generate.

## UAT / production

```bash
pnpm db-pg:migrate:uat    # drizzle-kit migrate + .env.uat
pnpm db-pg:migrate:prod
```

These need a migrations folder from `pnpm db:generate`.

## Generate SQL

```bash
pnpm db:generate          # drizzle-kit generate → ./migrations
```

Commit the SQL. Then migrate in environments that must not push.

## better-auth schema

```bash
pnpm db:generate:auth
```

nx runs:

```bash
pnpx @better-auth/cli generate --config ./gen-auth-schema.ts --output ./src/schema/auth.schema.ts -y
```

> [!WARNING]
> 
> The CLI writes **src/schema/auth.schema.ts** (singular). The package actually exports **src/schemas/auth.schema.ts** (plural), which is what `drizzle.config.ts` and `src/index.ts` import. After generating, move or merge the file into `src/schemas/` or the new file will be unused.

Auth tables (user, session, account, verification, organization, team, members, invitation) already live in `src/schemas/auth.schema.ts`. Re-generate when you change better-auth plugins or additional user fields.

## Studio

```bash
pnpm dev:db-pg:studio     # configurations: dev | uat | prod
```

## Client

`getDrizzleClient(databaseUrl)` in `@taman/db-pg`. The API uses `NITRO_DATABASE_URL`. Seed scripts accept `NITRO_DATABASE_URL` or `DATABASE_URL`.

IDs: `uuidv7()` SQL default on todos; better-auth uses JS `uuidv7()` in `generateId`.

## Pattern

New tables go in `src/schemas/<feature>.schema.ts`, re-exported from `src/schemas/index.ts`. Org-scoped resources should `references(() => organizationTable.id, { onDelete: 'cascade' })`.


## Sitemap

See the full [sitemap](https://vinicunca.dev/sitemap.md) for all pages.
