Skip to main content

Overview

Neuron Meet uses PostgreSQL as its database, managed through Prisma ORM. This guide covers setting up the database locally with Docker or using a managed service like Supabase.

Database Schema

The application uses the following data models:

Core Models

Stores user accounts and authentication data.Fields:
  • id - Unique identifier (CUID)
  • email - User email (unique, indexed)
  • name - Full name
  • displayName - Optional display name
  • password - Bcrypt hashed password
  • avatarUrl - Optional avatar image URL
  • createdAt - Account creation timestamp
  • updatedAt - Last update timestamp
Relations:
  • Hosts multiple rooms
  • Participates in multiple rooms
  • Sends multiple messages
Video conference rooms.Fields:
  • id - Unique identifier (CUID)
  • code - Unique room code (indexed)
  • name - Room name
  • hostId - User ID of the host (indexed)
  • isActive - Whether the room is currently active
  • isLocked - Whether new participants are blocked
  • startedAt - Room start time
  • endedAt - Room end time (nullable)
  • createdAt - Creation timestamp
  • updatedAt - Last update timestamp
Relations:
  • Belongs to one host (User)
  • Has one RoomSettings
  • Has multiple participants
  • Has multiple messages
Configuration for individual rooms.Fields:
  • id - Unique identifier (CUID)
  • roomId - Associated room ID (unique)
  • allowChat - Enable/disable chat (default: true)
  • allowScreenShare - Enable/disable screen sharing (default: true)
  • allowGuestAccess - Allow guest users (default: true)
  • waitingRoom - Enable waiting room (default: false)
  • muteParticipantsOnJoin - Auto-mute new participants (default: false)
  • isLocked - Lock room (default: false)
  • maxParticipants - Maximum participants (default: 100)
Relations:
  • Belongs to one room (cascade delete)
Tracks users and guests in rooms.Fields:
  • id - Unique identifier (CUID)
  • roomId - Room ID (indexed)
  • userId - User ID if authenticated (nullable, indexed)
  • guestName - Name if joining as guest (nullable)
  • isActive - Whether currently in the room
  • isHost - Whether this is the host participant
  • joinedAt - Join timestamp
  • leftAt - Leave timestamp (nullable)
Relations:
  • Belongs to one room (cascade delete)
  • Optionally belongs to one user
Chat messages in rooms.Fields:
  • id - Unique identifier (CUID)
  • roomId - Room ID (indexed)
  • userId - User ID if authenticated (nullable)
  • senderName - Sender name (nullable)
  • content - Message content
  • type - Message type: TEXT, SYSTEM, or FILE
  • createdAt - Timestamp (indexed)
Relations:
  • Belongs to one room (cascade delete)
  • Optionally belongs to one user

Option 1: Local PostgreSQL with Docker

The fastest way to set up PostgreSQL locally is using Docker.
1

Start PostgreSQL with Docker Compose

The project includes a Docker Compose configuration for PostgreSQL:
docker-compose up -d postgres
This starts:
  • PostgreSQL 15 Alpine
  • Container name: neuron-meet-db
  • User: neuronmeet
  • Password: neuronmeet
  • Database: neuronmeet
  • Port: 5432
  • Health check: runs every 5 seconds
2

Configure environment variables

Update your .env file with the local database URLs:
DATABASE_URL="postgresql://neuronmeet:neuronmeet@localhost:5432/neuronmeet"
DIRECT_URL="postgresql://neuronmeet:neuronmeet@localhost:5432/neuronmeet"
3

Generate Prisma client

npm run db:generate
This generates the Prisma client based on your schema.
4

Run migrations

npm run db:migrate
This creates all database tables and relationships.
5

Verify the setup

Check that the database is running:
docker ps | grep neuron-meet-db
You can also connect to the database:
docker exec -it neuron-meet-db psql -U neuronmeet
PostgreSQL data is persisted in a Docker volume named postgres_data, so it survives container restarts.

Option 2: Supabase (Managed PostgreSQL)

Supabase provides a managed PostgreSQL database with additional features.
1

Create a Supabase project

  1. Sign up at supabase.com
  2. Create a new project
  3. Choose a region close to your users
  4. Set a strong database password
2

Get connection strings

Navigate to Project SettingsDatabaseConnection string:For DATABASE_URL (Transaction pooler):
postgresql://postgres.[project-ref]:[password]@aws-0-[region].pooler.supabase.com:6543/postgres
For DIRECT_URL (Session pooler):
postgresql://postgres.[project-ref]:[password]@aws-0-[region].pooler.supabase.com:5432/postgres
3

Configure environment variables

Update your .env file with the Supabase connection strings:
DATABASE_URL="postgresql://postgres.xxxxx:[password]@aws-0-[region].pooler.supabase.com:6543/postgres"
DIRECT_URL="postgresql://postgres.xxxxx:[password]@aws-0-[region].pooler.supabase.com:5432/postgres"
Replace [password], [project-ref], and [region] with your actual values.
4

Generate Prisma client

npm run db:generate
5

Run migrations

npm run db:migrate
Supabase’s free tier includes:
  • 500 MB database space
  • Automatic backups
  • Direct access to PostgreSQL
  • No credit card required

Prisma Commands

Common database operations using Prisma:

Generate Client

Generate the Prisma Client after schema changes:
npm run db:generate
This runs prisma generate in the server directory.

Push Schema (Development)

Push schema changes directly to the database without creating migrations:
npm run db:push
This runs prisma db push - useful for rapid prototyping.
db:push is destructive and may result in data loss. Use migrations in production.

Run Migrations (Production)

Create and apply migrations:
npm run db:migrate
This runs prisma migrate dev which:
  1. Creates a new migration file
  2. Applies it to the database
  3. Regenerates the Prisma client

Prisma Studio (Database GUI)

Open a visual database editor:
cd server
npm run db:studio
This opens Prisma Studio at http://localhost:5555 where you can:
  • Browse all tables
  • View and edit data
  • Test queries

Connection Pooling

For production deployments, consider connection pooling:

With Supabase

Supabase provides built-in connection pooling:
  • Transaction pooler (port 6543): For serverless/edge functions
  • Session pooler (port 5432): For long-running servers
Use Transaction pooler for DATABASE_URL and Session pooler for DIRECT_URL.

With PgBouncer

For self-hosted PostgreSQL, use PgBouncer:
# Install PgBouncer
sudo apt install pgbouncer

# Configure /etc/pgbouncer/pgbouncer.ini
[databases]
neuronmeet = host=localhost port=5432 dbname=neuronmeet

[pgbouncer]
listen_addr = *
listen_port = 6432
auth_file = /etc/pgbouncer/userlist.txt
pool_mode = transaction
max_client_conn = 100
default_pool_size = 20
Then use port 6432 in your DATABASE_URL.

Backup and Restore

Backup Database

docker exec neuron-meet-db pg_dump -U neuronmeet neuronmeet > backup.sql

Restore Database

docker exec -i neuron-meet-db psql -U neuronmeet neuronmeet < backup.sql

Troubleshooting

Connection Refused

Check if PostgreSQL container is running:
docker ps | grep neuron-meet-db
View container logs:
docker logs neuron-meet-db
Restart the container:
docker-compose restart postgres
  • Verify your IP is allowed in Supabase dashboard
  • Check if you’re using the correct connection string
  • Ensure you’re using the pooler URL (not direct connection) for serverless

Migration Errors

Reset the database and migrations:
cd server
npx prisma migrate reset
This will delete all data! Only use in development.
Regenerate the Prisma client:
npm run db:generate

Next Steps

Environment Variables

Configure all database connection variables

Production Checklist

Optimize and secure your database for production

Build docs developers (and LLMs) love