Core Setup

Database

Set up MongoDB with Mongoose or PostgreSQL with Prisma and Supabase. Understand the schema, collections, and how to switch databases.

MoveFast supports two database options. Your variant comes pre-configured with one of them:

  • MongoDB variants use Mongoose for schema-less document storage
  • Supabase variants use Prisma 7 with PostgreSQL

You do not need to configure both. Your variant only includes the code for the database you selected.


MongoDB Setup

Environment Variable

env
MONGODB_URI=mongodb+srv://user:password@cluster.mongodb.net/your-db-name

Getting a MongoDB Database

Option A: MongoDB Atlas (recommended for production)

  1. Create a free account at mongodb.com/atlas
  2. Create a cluster
  3. Create a database user with read/write access
  4. Get the connection string and add it to your .env
  5. Whitelist your IP (or allow access from anywhere for Vercel)

Option B: Local MongoDB

  1. Install MongoDB locally
  2. Use mongodb://localhost:27017/movefast as your URI

Collections

MongoDB creates collections automatically when the first document is inserted. The app uses these collections:

CollectionPurpose
usersUser accounts with roles, status, plan info
magiclinktokensTemporary magic link verification tokens
waitinglistsEmail waitlist entries
invitesAdmin-created invite records
paymentsPayment transaction records
subscriptionsSubscription lifecycle records

How It Works

Mongoose models are defined in src/lib/schemas/. The connection is established lazily on first use via src/lib/mongodb.ts, which caches the connection across hot reloads in development.


Supabase / PostgreSQL Setup

Environment Variables

env
DATABASE_URL=postgresql://user:password@host:5432/dbname

If your provider requires a direct connection (some do for migrations):

env
DIRECT_URL=postgresql://user:password@host:5432/dbname

Getting a PostgreSQL Database

Option A: Supabase (recommended)

  1. Create a project at supabase.com
  2. Go to Project Settings > Database
  3. Copy the connection string (use the "Transaction" pooler for DATABASE_URL)
  4. For DIRECT_URL, use the "Session" pooler or direct connection

Option B: Any PostgreSQL provider

Any PostgreSQL database works. Neon, Railway, Render, or a self-hosted instance are all fine.

Generate Prisma Client

After installing dependencies, generate the Prisma client:

bash
npx prisma generate

This creates the client in generated/prisma/. You must run this:

  • After every fresh npm install
  • In CI before npm run build

Push Schema to Database

Apply the schema to your database:

bash
npx prisma db push

This creates all the tables defined in prisma/schema.prisma.

Schema Overview

The Prisma schema defines these tables:

TablePurpose
UserUser accounts (id, email, name, roles, isActive, planId)
VerificationTokenMagic link tokens (identifier, token, expires)
WaitingListWaitlist entries with email tracking
InviteInvite records with token, expiry, used/revoked status
PaymentPayment records linked to users
SubscriptionSubscription records with provider details

Importing the Prisma Client

The generated client lives at generated/prisma/, not in node_modules. Import it using the path alias:

typescript
import type { PrismaClient } from "@/prisma/client";

The client is constructed lazily in src/lib/prisma.ts with a PostgreSQL driver adapter. This means next build works even without live database credentials.

Prisma Studio

To browse your data visually:

bash
npx prisma studio

Data Models

Both database options store the same logical entities. Here is what each model contains:

User

  • id - Unique identifier
  • email - Unique email address
  • name - Display name
  • image - Profile image URL (from OAuth)
  • roles - Array of roles (USER, ADMIN)
  • isActive - Whether the account is enabled
  • planId - The product ID of their purchased plan (for one-time payments)
  • emailVerified - When their email was verified
  • createdAt / updatedAt - Timestamps

Payment

  • userId - Reference to the user
  • provider - Which payment provider (STRIPE, DODO, POLAR)
  • providerPaymentId - The provider's payment ID
  • status - Payment status (COMPLETED, etc.)
  • amount - Payment amount
  • currency - Currency code
  • planId - Which plan was purchased

Subscription

  • userId - Reference to the user
  • provider - Which payment provider
  • providerSubscriptionId - The provider's subscription ID
  • providerCustomerId - The provider's customer ID
  • planId - Which plan
  • status - ACTIVE, CANCELLED, PAST_DUE, etc.
  • currentPeriodStart / currentPeriodEnd - Billing period dates
  • cancelAt / cancelledAt - Cancellation dates

Tips

  • Use a separate database for development and production to avoid polluting real data with test signups
  • For MongoDB Atlas, make sure to whitelist 0.0.0.0/0 if deploying to Vercel (serverless IPs change)
  • For Supabase, use the pooled connection string for DATABASE_URL in serverless environments
  • Run npx prisma generate in your CI/CD build step before npm run build