Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/soft-glasses-watch.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@workflow/world-postgres": minor
---

Exported the database schema and added a script for initializing the database with all the required tables for the setup.
33 changes: 33 additions & 0 deletions packages/world-postgres/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,39 @@ This package uses PostgreSQL with the following components:
- **Drizzle ORM**: For database operations and schema management
- **postgres**: For PostgreSQL client connections

### Quick Setup with CLI

The easiest way to set up your database is using the included CLI tool:

```bash
pnpm exec workflow-postgres-setup
# or
npm exec workflow-postgres-setup
```

The CLI automatically loads `.env` files and will use the connection string from:
1. `WORKFLOW_POSTGRES_URL` environment variable
2. `DATABASE_URL` environment variable
3. Default: `postgres://world:world@localhost:5432/world`

### Database Schema

The setup creates the following tables:

- `workflow_runs` - Stores workflow execution runs
- `workflow_events` - Stores workflow events
- `workflow_steps` - Stores individual workflow steps
- `workflow_hooks` - Stores webhook hooks
- `workflow_stream_chunks` - Stores streaming data chunks

You can also access the schema programmatically:

```typescript
import { runs, events, steps, hooks, streams } from '@workflow/world-postgres';
// or
import * as schema from '@workflow/world-postgres/schema';
```

Make sure your PostgreSQL database is accessible and the user has sufficient permissions to create tables and manage jobs.

## Features
Expand Down
12 changes: 12 additions & 0 deletions packages/world-postgres/bin/setup.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#!/usr/bin/env node

// Simple wrapper to run the CLI from the bin directory
import('../dist/cli.js')
.then((module) => {
// Call the setupDatabase function
return module.setupDatabase();
})
.catch((err) => {
console.error('Failed to load CLI:', err);
process.exit(1);
});
19 changes: 17 additions & 2 deletions packages/world-postgres/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,13 @@
"description": "A reference World implementation based on PostgreSQL",
"type": "module",
"main": "dist/index.js",
"bin": {
"workflow-postgres-setup": "./bin/setup.js"
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

question for @Schniz - curious if we could just keep this as the main bin? that way npx @workflow/world-postgres

i'm indifferent

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not a strong opinion, but I think since it's a one-time setup script separate from regular intended execution, it makes sense for it to be named like it's in the PR

},
"files": [
"dist"
"dist",
"bin",
"src/drizzle/migrations"
],
"publishConfig": {
"access": "public"
Expand All @@ -20,7 +25,16 @@
".": {
"types": "./dist/index.d.ts",
"default": "./dist/index.js"
}
},
"./schema": {
"types": "./dist/drizzle/schema.d.ts",
"default": "./dist/drizzle/schema.js"
},
"./cli": {
"types": "./dist/cli.d.ts",
"default": "./dist/cli.js"
},
"./migrations/*.sql": "./src/drizzle/migrations/*.sql"
},
"scripts": {
"build": "tsc",
Expand All @@ -35,6 +49,7 @@
"@workflow/errors": "workspace:*",
"@workflow/world": "workspace:*",
"@workflow/world-local": "workspace:*",
"dotenv": "^16.4.5",
"drizzle-orm": "^0.31.2",
"pg-boss": "^11.0.7",
"postgres": "^3.4.7",
Expand Down
65 changes: 65 additions & 0 deletions packages/world-postgres/src/cli.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
#!/usr/bin/env node
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems like it's not needed given we except this to either be imported by the bin (and run), or imported in a module


import { config } from 'dotenv';
import { readFile } from 'node:fs/promises';
import { dirname, join } from 'node:path';
import { fileURLToPath } from 'node:url';
import postgres from 'postgres';

const __dirname = dirname(fileURLToPath(import.meta.url));

async function setupDatabase() {
// Load .env file if it exists
config();

const connectionString =
process.env.WORKFLOW_POSTGRES_URL ||
process.env.DATABASE_URL ||
'postgres://world:world@localhost:5432/world';

console.log('🔧 Setting up database schema...');
console.log(
`📍 Connection: ${connectionString.replace(/^(\w+:\/\/)([^@]+)@/, '$1[redacted]@')}`
);

try {
const sql = postgres(connectionString);

// Read the migration SQL file
// The migrations are in src/drizzle/migrations, and this CLI is in dist/
// So we need to go up one level from dist/ to reach src/
const migrationPath = join(
__dirname,
'..',
'src',
'drizzle',
'migrations',
'0000_redundant_smasher.sql'
);
const migrationSQL = await readFile(migrationPath, 'utf-8');

// Execute the migration
await sql.unsafe(migrationSQL);

console.log('✅ Database schema created successfully!');
console.log('\nCreated tables:');
console.log(' - workflow_runs');
console.log(' - workflow_events');
console.log(' - workflow_steps');
console.log(' - workflow_hooks');
console.log(' - workflow_stream_chunks');

await sql.end();
process.exit(0);
} catch (error) {
console.error('❌ Failed to setup database:', error);
process.exit(1);
}
}

// Check if running as main module
if (import.meta.url === `file://${process.argv[1]}`) {
setupDatabase();
}

export { setupDatabase };
4 changes: 4 additions & 0 deletions packages/world-postgres/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,3 +50,7 @@ export function createWorld(
},
};
}

// Re-export schema for users who want to extend or inspect the database schema
export type { PostgresWorldConfig } from './config.js';
export * from './drizzle/schema.js';
17 changes: 10 additions & 7 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading