MuseMVP Docs
Database

Database Configuration

A practical overview of database setup: schema design, connection strategies, and query-layer extension practices.

MuseMVP uses Drizzle ORM with PostgreSQL for data persistence. The database layer supports both standard Node.js (Vercel, Docker) and Cloudflare Workers (through Hyperdrive connection pooling).

Download and Configure the Database

Download a database (local) or create a Neon instance (remote)

After installation and service startup, create a development database (example):

createdb musemvp

On Windows, you can use the official installer directly (with pgAdmin included); after installation, confirm the postgresql service is running.
On macOS / Linux, install via your package manager and start the service.

  1. Open the Neon Console and create a Project. Create Project
  2. In Connection Details, copy the Pooled connection string (recommended for application runtime). Copy connection string
postgresql://neondb_username:npg_password@ep-xxx-bush-xxxx-pooler.ap-xxx-1.xxx.neon.tech/demo-musemvp-com?sslmode=require&channel_binding=require

Configure the database

Create .env in the project root (you can copy from .env.local.example) with at least:

# Local development / Vercel / Docker
DATABASE_CONNECTION_STRATEGY="database_url_first"
DATABASE_URL="postgresql://<user>:<password>@<host>:5432/<database>"

Then run:

pnpm drizzle:generate
pnpm drizzle:push

Local development note

Do not use hyperdrive_first for local Node.js development; use database_url_first.

Cloudflare Worker deployment

When deploying to Cloudflare Worker, you can switch to DATABASE_CONNECTION_STRATEGY="hyperdrive_first" and configure Hyperdrive; DATABASE_URL can be used as a fallback connection.

Verify the connection:

pnpm drizzle:studio

Common Commands

pnpm drizzle:generate   # Generate migrations based on schema changes
pnpm drizzle:migrate    # Apply migrations to the database
pnpm drizzle:push       # Push schema directly (development only)
pnpm drizzle:studio     # Open Drizzle Studio GUI
npm run drizzle:generate
npm run drizzle:migrate
npm run drizzle:push
npm run drizzle:studio

Connection Strategy

The database client in src/backend/database/client.ts resolves connections based on runtime:

Cloudflare Worker: Prefer Hyperdrive binding (HYPERDRIVE.connectionString) for edge connection pooling.

Node.js (Vercel, Docker): Use the DATABASE_URL environment variable.

Fallback: If Hyperdrive is unavailable on Cloudflare, fall back to DATABASE_URL.

Environment Variables

DATABASE_URL is required for local development and non-Cloudflare deployments. Cloudflare Workers require Hyperdrive, with optional DATABASE_URL as fallback.


Incremental Extension Flow

Add or update tables in schema.ts.

Run pnpm drizzle:generate to generate migration files.

Run pnpm drizzle:migrate to apply migrations.

Add query functions in queries/*.

Expose behavior in src/backend/api/routes/*.

Consume via src/backend/api-client/*.


Operations Checklist

  • Commit migration history to version control
  • Avoid using raw SQL in route handlers - use the query layer
  • Keep authentication and ownership checks in API middleware
  • Use explicit indexes for growing tables (see schema.ts examples)