@concourse/db owns the Concourse application schema and its SQLite lifecycle. It uses Drizzle and
@libsql/client for local SQLite files and remote Turso databases.
The future @concourse/rsdb package is a separate Rackspace MySQL boundary. Do not add Rackspace
tables or connections to this package.
import { connectDb } from "@concourse/db";
const database = await connectDb({
url: process.env.TURSO_DATABASE_URL!,
authToken: process.env.TURSO_AUTH_TOKEN,
});Remote libsql:, https:, and wss: URLs require a token. Local file: URLs do not. Runtime code
reuses one server-side client. Scripts and tests call closeDb when their process-level work ends.
Every client enables and verifies foreign-key enforcement before Drizzle can use it. Authorization
writes use the shared retryable transaction helper. It retries the complete transaction no more than
three times after SQLITE_BUSY.
Development uses data/sqlite/concourse.db. Acceptance uses the fixed
data/sqlite/concourse-test.db file. Playwright removes stale files, applies migrations before it
starts Next, and removes the database and all SQLite sidecars after Next stops.
pnpm db:reset accepts only the exact development file. Test cleanup accepts only files named
concourse-test.db or concourse-test-*.db in the same directory. Both commands reject remote URLs
and unknown paths.
Edit packages/db/src/schema.ts for application tables or packages/auth/src/schema.ts for Better
Auth tables. Then run:
pnpm db:generate
pnpm db:diff
pnpm verifyThe repository has one SQLite baseline because no earlier production migration ledger needed to be retained. After the first production administrator exists, use expand-contract migrations for later releases.
| Command | Purpose |
|---|---|
pnpm db:generate | Generate a migration from both owned schemas |
pnpm db:migrate | Apply committed migrations |
pnpm db:seed | Add fixtures to an empty database |
pnpm db:reset | Recreate the known development file |
pnpm db:diff | Fail when schema and migration history differ |
pnpm db:clear | Remove rows managed by the seed command |
Production migrations run in .github/workflows/production-migration.yml. The workflow validates
the exact Vercel project and commit, pulls the integration-managed database values into an isolated
temporary directory, serializes the migration, and runs readiness and database smoke checks before
alias assignment.
@concourse/db owns the Concourse application schema and its SQLite lifecycle. It uses Drizzle and
@libsql/client for local SQLite files and remote Turso databases.
The future @concourse/rsdb package is a separate Rackspace MySQL boundary. Do not add Rackspace
tables or connections to this package.
import { connectDb } from "@concourse/db";
const database = await connectDb({
url: process.env.TURSO_DATABASE_URL!,
authToken: process.env.TURSO_AUTH_TOKEN,
});Remote libsql:, https:, and wss: URLs require a token. Local file: URLs do not. Runtime code
reuses one server-side client. Scripts and tests call closeDb when their process-level work ends.
Every client enables and verifies foreign-key enforcement before Drizzle can use it. Authorization
writes use the shared retryable transaction helper. It retries the complete transaction no more than
three times after SQLITE_BUSY.
Development uses data/sqlite/concourse.db. Acceptance uses the fixed
data/sqlite/concourse-test.db file. Playwright removes stale files, applies migrations before it
starts Next, and removes the database and all SQLite sidecars after Next stops.
pnpm db:reset accepts only the exact development file. Test cleanup accepts only files named
concourse-test.db or concourse-test-*.db in the same directory. Both commands reject remote URLs
and unknown paths.
Edit packages/db/src/schema.ts for application tables or packages/auth/src/schema.ts for Better
Auth tables. Then run:
pnpm db:generate
pnpm db:diff
pnpm verifyThe repository has one SQLite baseline because no earlier production migration ledger needed to be retained. After the first production administrator exists, use expand-contract migrations for later releases.
| Command | Purpose |
|---|---|
pnpm db:generate | Generate a migration from both owned schemas |
pnpm db:migrate | Apply committed migrations |
pnpm db:seed | Add fixtures to an empty database |
pnpm db:reset | Recreate the known development file |
pnpm db:diff | Fail when schema and migration history differ |
pnpm db:clear | Remove rows managed by the seed command |
Production migrations run in .github/workflows/production-migration.yml. The workflow validates
the exact Vercel project and commit, pulls the integration-managed database values into an isolated
temporary directory, serializes the migration, and runs readiness and database smoke checks before
alias assignment.