Skip to content

Commit 3dd25de

Browse files
feat(@workflow/world-postgres): implemented a script for setting up the required tables (#57)
1 parent 55e2d0b commit 3dd25de

File tree

7 files changed

+146
-9
lines changed

7 files changed

+146
-9
lines changed

.changeset/soft-glasses-watch.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@workflow/world-postgres": minor
3+
---
4+
5+
Exported the database schema and added a script for initializing the database with all the required tables for the setup.

packages/world-postgres/README.md

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,39 @@ This package uses PostgreSQL with the following components:
7676
- **Drizzle ORM**: For database operations and schema management
7777
- **postgres**: For PostgreSQL client connections
7878

79+
### Quick Setup with CLI
80+
81+
The easiest way to set up your database is using the included CLI tool:
82+
83+
```bash
84+
pnpm exec workflow-postgres-setup
85+
# or
86+
npm exec workflow-postgres-setup
87+
```
88+
89+
The CLI automatically loads `.env` files and will use the connection string from:
90+
1. `WORKFLOW_POSTGRES_URL` environment variable
91+
2. `DATABASE_URL` environment variable
92+
3. Default: `postgres://world:world@localhost:5432/world`
93+
94+
### Database Schema
95+
96+
The setup creates the following tables:
97+
98+
- `workflow_runs` - Stores workflow execution runs
99+
- `workflow_events` - Stores workflow events
100+
- `workflow_steps` - Stores individual workflow steps
101+
- `workflow_hooks` - Stores webhook hooks
102+
- `workflow_stream_chunks` - Stores streaming data chunks
103+
104+
You can also access the schema programmatically:
105+
106+
```typescript
107+
import { runs, events, steps, hooks, streams } from '@workflow/world-postgres';
108+
// or
109+
import * as schema from '@workflow/world-postgres/schema';
110+
```
111+
79112
Make sure your PostgreSQL database is accessible and the user has sufficient permissions to create tables and manage jobs.
80113

81114
## Features
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
#!/usr/bin/env node
2+
3+
// Simple wrapper to run the CLI from the bin directory
4+
import('../dist/cli.js')
5+
.then((module) => {
6+
// Call the setupDatabase function
7+
return module.setupDatabase();
8+
})
9+
.catch((err) => {
10+
console.error('Failed to load CLI:', err);
11+
process.exit(1);
12+
});

packages/world-postgres/package.json

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,13 @@
44
"description": "A reference World implementation based on PostgreSQL",
55
"type": "module",
66
"main": "dist/index.js",
7+
"bin": {
8+
"workflow-postgres-setup": "./bin/setup.js"
9+
},
710
"files": [
8-
"dist"
11+
"dist",
12+
"bin",
13+
"src/drizzle/migrations"
914
],
1015
"publishConfig": {
1116
"access": "public"
@@ -20,7 +25,16 @@
2025
".": {
2126
"types": "./dist/index.d.ts",
2227
"default": "./dist/index.js"
23-
}
28+
},
29+
"./schema": {
30+
"types": "./dist/drizzle/schema.d.ts",
31+
"default": "./dist/drizzle/schema.js"
32+
},
33+
"./cli": {
34+
"types": "./dist/cli.d.ts",
35+
"default": "./dist/cli.js"
36+
},
37+
"./migrations/*.sql": "./src/drizzle/migrations/*.sql"
2438
},
2539
"scripts": {
2640
"build": "tsc",
@@ -35,6 +49,7 @@
3549
"@workflow/errors": "workspace:*",
3650
"@workflow/world": "workspace:*",
3751
"@workflow/world-local": "workspace:*",
52+
"dotenv": "^16.4.5",
3853
"drizzle-orm": "^0.31.2",
3954
"pg-boss": "^11.0.7",
4055
"postgres": "^3.4.7",

packages/world-postgres/src/cli.ts

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
#!/usr/bin/env node
2+
3+
import { config } from 'dotenv';
4+
import { readFile } from 'node:fs/promises';
5+
import { dirname, join } from 'node:path';
6+
import { fileURLToPath } from 'node:url';
7+
import postgres from 'postgres';
8+
9+
const __dirname = dirname(fileURLToPath(import.meta.url));
10+
11+
async function setupDatabase() {
12+
// Load .env file if it exists
13+
config();
14+
15+
const connectionString =
16+
process.env.WORKFLOW_POSTGRES_URL ||
17+
process.env.DATABASE_URL ||
18+
'postgres://world:world@localhost:5432/world';
19+
20+
console.log('🔧 Setting up database schema...');
21+
console.log(
22+
`📍 Connection: ${connectionString.replace(/^(\w+:\/\/)([^@]+)@/, '$1[redacted]@')}`
23+
);
24+
25+
try {
26+
const sql = postgres(connectionString);
27+
28+
// Read the migration SQL file
29+
// The migrations are in src/drizzle/migrations, and this CLI is in dist/
30+
// So we need to go up one level from dist/ to reach src/
31+
const migrationPath = join(
32+
__dirname,
33+
'..',
34+
'src',
35+
'drizzle',
36+
'migrations',
37+
'0000_redundant_smasher.sql'
38+
);
39+
const migrationSQL = await readFile(migrationPath, 'utf-8');
40+
41+
// Execute the migration
42+
await sql.unsafe(migrationSQL);
43+
44+
console.log('✅ Database schema created successfully!');
45+
console.log('\nCreated tables:');
46+
console.log(' - workflow_runs');
47+
console.log(' - workflow_events');
48+
console.log(' - workflow_steps');
49+
console.log(' - workflow_hooks');
50+
console.log(' - workflow_stream_chunks');
51+
52+
await sql.end();
53+
process.exit(0);
54+
} catch (error) {
55+
console.error('❌ Failed to setup database:', error);
56+
process.exit(1);
57+
}
58+
}
59+
60+
// Check if running as main module
61+
if (import.meta.url === `file://${process.argv[1]}`) {
62+
setupDatabase();
63+
}
64+
65+
export { setupDatabase };

packages/world-postgres/src/index.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,3 +50,7 @@ export function createWorld(
5050
},
5151
};
5252
}
53+
54+
// Re-export schema for users who want to extend or inspect the database schema
55+
export type { PostgresWorldConfig } from './config.js';
56+
export * from './drizzle/schema.js';

pnpm-lock.yaml

Lines changed: 10 additions & 7 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)