We use tracking cookies to understand how you use the product and help us improve it. For more information on how we store cookies, read our  privacy policy.

Database Setup

Configure your PostgreSQL database connection for Plainform.

Plainform uses PostgreSQL as its database, accessed through Prisma ORM for type-safe queries. Your database can be hosted on Supabase, Vercel Postgres, Railway, Neon, or any PostgreSQL provider.

Database Architecture

Plainform's database layer consists of:

  • PostgreSQL Database: Hosted on your chosen provider (Supabase, Vercel, etc.)
  • Prisma ORM: Type-safe database client with schema management
  • Connection Pooling: Efficient connection management for serverless environments
  • Environment Validation: @t3-oss/env-nextjs ensures required variables are set

Connection Strings

Plainform requires two connection strings:

DATABASE_URL (Pooled Connection)

Used for all database queries in your application. Includes connection pooling for serverless environments.

.env
DATABASE_URL="postgresql://user:password@host:6543/postgres?pgbouncer=true"
  • Port: 6543 (PgBouncer pooler)
  • Used by: Prisma Client for queries
  • Why: Prevents connection exhaustion in serverless functions

DIRECT_URL (Direct Connection)

Used for database migrations and schema changes. Bypasses connection pooling.

.env
DIRECT_URL="postgresql://user:password@host:5432/postgres"
  • Port: 5432 (standard PostgreSQL)
  • Used by: Prisma Migrate for schema changes
  • Why: Migrations require direct database access

For Supabase-specific setup instructions, see the Supabase Setup page.

Initial Setup

Get Connection Strings

Obtain your DATABASE_URL and DIRECT_URL from your database provider:

  • Supabase: Settings → Database → Connection String
  • Vercel Postgres: Storage → Database → Connection String
  • Railway: Database → Connect → Connection String
  • Neon: Dashboard → Connection Details

Add to Environment Variables

Create or update your .env file in the project root:

.env
# PostgreSQL Connection
DATABASE_URL="postgresql://user:password@host:6543/postgres?pgbouncer=true"
DIRECT_URL="postgresql://user:password@host:5432/postgres"

Never commit .env to version control. It's already in .gitignore.

Verify Environment Validation

The env.ts file validates these variables at startup:

env.ts
export const env = createEnv({
  server: {
    DATABASE_URL: z.string().min(5),
    DIRECT_URL: z.string().min(5),
    // ... other variables
  },
});

If either variable is missing, your app won't start and you'll see a validation error.

Test the Connection

Run Prisma's introspection to verify the connection works:

Terminal
npx prisma db pull

If successful, Prisma will read your database schema. If it fails, check your connection strings.

Generate Prisma Client

Generate the Prisma Client to start querying your database:

Terminal
npx prisma generate

This creates the type-safe Prisma Client in node_modules/@prisma/client.

Prisma Configuration

Your prisma/schema.prisma uses both connection strings:

prisma/schema.prisma
generator client {
  provider = "prisma-client-js"
}

datasource db {
  provider  = "postgresql"
  url       = env("DATABASE_URL")      // Pooled connection for queries
  directUrl = env("DIRECT_URL")        // Direct connection for migrations
}

Prisma automatically uses:

  • DATABASE_URL for queries (prisma.event.findMany())
  • DIRECT_URL for migrations (npx prisma migrate dev)

Database Models

Plainform includes these default models:

prisma/schema.prisma
model Event {
  id        String @id @default(cuid())
  type      String
  slug      String 
  text      String 
  timestamp BigInt 
}

model Comment {
  id        Int      @id @default(autoincrement())
  page      String   @default("default") @db.VarChar(256)
  thread    Int?     @map("threadId")
  author    String   @db.VarChar(256)
  content   Json     @db.Json
  timestamp DateTime @default(now()) @db.Timestamp()
  rates     Rate[]
  
  @@index([page])
}

model Rate {
  userId    String  @db.VarChar(256)
  commentId Int
  like      Boolean
  comment   Comment @relation(fields: [commentId], references: [id], onDelete: Cascade)
  
  @@id([userId, commentId])
  @@index([commentId])
}

These models support:

  • Event: Activity tracking (blog posts, updates)
  • Comment: Blog post comments via fuma-comment
  • Rate: Comment likes/dislikes

Next Steps

How is this guide ?

Last updated on