Skip to content

Commit eb2850b

Browse files
committed
feat(dashboard-agent-db): run migrations over a direct (non-pooler) connection
A transaction-mode pooler can't run the migrator (no advisory locks, no multi-statement DDL), so the agent datastore now resolves its migration connection from a dedicated DASHBOARD_AGENT_DIRECT_URL, falling back to the pooled DASHBOARD_AGENT_DATABASE_URL, then the main DIRECT_URL / DATABASE_URL for the single-database fallback. The application keeps using the pooled DASHBOARD_AGENT_DATABASE_URL. Only the migration entry points (drizzle.config.ts, migrate.mjs, migrate-status.mjs) changed; the runtime client is untouched.
1 parent f163c89 commit eb2850b

4 files changed

Lines changed: 31 additions & 13 deletions

File tree

internal-packages/dashboard-agent-db/README.md

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,13 @@ The conversation datastore for the in-dashboard agent, isolated from the main
44
Prisma database. Drizzle (postgres-js) over a dedicated `trigger_dashboard_agent`
55
Postgres schema.
66

7-
- **Cloud:** a separate PlanetScale Postgres database (`DASHBOARD_AGENT_DATABASE_URL`),
8-
reached over a standard pooled connection.
9-
- **OSS / self-host:** falls back to the main `DATABASE_URL`; the tables live in
10-
the dedicated `trigger_dashboard_agent` schema, isolated from Prisma's `public`.
7+
- **Cloud:** a separate PlanetScale Postgres database. The app connects over a
8+
pooled connection (`DASHBOARD_AGENT_DATABASE_URL`); migrations run over a direct
9+
(non-pooler) connection (`DASHBOARD_AGENT_DIRECT_URL`), since a transaction-mode
10+
pooler can't run the migrator.
11+
- **OSS / self-host:** falls back to the main `DATABASE_URL` (and `DIRECT_URL` for
12+
migrations); the tables live in the dedicated `trigger_dashboard_agent` schema,
13+
isolated from Prisma's `public`.
1114

1215
The schema is **foreign-key-free** — it references main entities (`organizationId`,
1316
`userId`) by id only, because in cloud it lives in a different database.
@@ -36,7 +39,7 @@ of truth.
3639

3740
```bash
3841
pnpm run db:generate # generate SQL migration from src/schema.ts (offline)
39-
pnpm run db:migrate # apply migrations (needs DASHBOARD_AGENT_DATABASE_URL or DATABASE_URL)
42+
pnpm run db:migrate # apply migrations (direct url: DASHBOARD_AGENT_DIRECT_URL, falling back to DASHBOARD_AGENT_DATABASE_URL / DIRECT_URL / DATABASE_URL)
4043
```
4144

4245
drizzle-kit is scoped to the `trigger_dashboard_agent` schema (`schemaFilter`), so

internal-packages/dashboard-agent-db/drizzle.config.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,13 @@
11
import { defineConfig } from "drizzle-kit";
22

3-
// Cloud points at the dedicated PlanetScale database; OSS falls back to the main
4-
// DATABASE_URL (tables still land in the trigger_dashboard_agent schema).
3+
// Migrations need a direct (non-pooler) connection; a transaction-mode pooler
4+
// can't run the migrator. Prefer the agent's direct url, then its pooled url,
5+
// then the main DIRECT_URL/DATABASE_URL (OSS single-database fallback; tables
6+
// still land in the trigger_dashboard_agent schema).
57
const url =
8+
process.env.DASHBOARD_AGENT_DIRECT_URL ??
69
process.env.DASHBOARD_AGENT_DATABASE_URL ??
10+
process.env.DIRECT_URL ??
711
process.env.DATABASE_URL ??
812
"postgres://placeholder"; // generate is offline; a real url is only needed for migrate/studio
913

internal-packages/dashboard-agent-db/migrate-status.mjs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,16 @@ import postgres from "postgres";
88
const MIGRATIONS_SCHEMA = "drizzle";
99
const MIGRATIONS_TABLE = "__dashboard_agent_migrations";
1010

11-
const connectionString = process.env.DASHBOARD_AGENT_DATABASE_URL ?? process.env.DATABASE_URL;
11+
// Match migrate.mjs: a direct (non-pooler) connection, same precedence.
12+
const connectionString =
13+
process.env.DASHBOARD_AGENT_DIRECT_URL ??
14+
process.env.DASHBOARD_AGENT_DATABASE_URL ??
15+
process.env.DIRECT_URL ??
16+
process.env.DATABASE_URL;
1217

1318
if (!connectionString) {
1419
console.error(
15-
"[dashboard-agent-db] DASHBOARD_AGENT_DATABASE_URL / DATABASE_URL not set; cannot check status."
20+
"[dashboard-agent-db] No database url set (DASHBOARD_AGENT_DIRECT_URL / DASHBOARD_AGENT_DATABASE_URL / DIRECT_URL / DATABASE_URL); cannot check status."
1621
);
1722
process.exit(2);
1823
}

internal-packages/dashboard-agent-db/migrate.mjs

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,19 @@ import { drizzle } from "drizzle-orm/postgres-js";
1010
import { migrate } from "drizzle-orm/postgres-js/migrator";
1111
import postgres from "postgres";
1212

13-
// Cloud points at the dedicated dashboard-agent database; OSS falls back to the
14-
// main DATABASE_URL (tables still land in the `trigger_dashboard_agent` schema).
15-
const connectionString = process.env.DASHBOARD_AGENT_DATABASE_URL ?? process.env.DATABASE_URL;
13+
// Migrations need a direct (non-pooler) connection; a transaction-mode pooler
14+
// can't run the migrator. Prefer the agent's direct url, then its pooled url,
15+
// then the main DIRECT_URL/DATABASE_URL (OSS single-database fallback; tables
16+
// still land in the `trigger_dashboard_agent` schema).
17+
const connectionString =
18+
process.env.DASHBOARD_AGENT_DIRECT_URL ??
19+
process.env.DASHBOARD_AGENT_DATABASE_URL ??
20+
process.env.DIRECT_URL ??
21+
process.env.DATABASE_URL;
1622

1723
if (!connectionString) {
1824
console.error(
19-
"[dashboard-agent-db] DASHBOARD_AGENT_DATABASE_URL / DATABASE_URL not set; cannot migrate."
25+
"[dashboard-agent-db] No database url set (DASHBOARD_AGENT_DIRECT_URL / DASHBOARD_AGENT_DATABASE_URL / DIRECT_URL / DATABASE_URL); cannot migrate."
2026
);
2127
process.exit(1);
2228
}

0 commit comments

Comments
 (0)