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
MONGODB_URI=mongodb+srv://user:password@cluster.mongodb.net/your-db-nameGetting a MongoDB Database
Option A: MongoDB Atlas (recommended for production)
- Create a free account at mongodb.com/atlas
- Create a cluster
- Create a database user with read/write access
- Get the connection string and add it to your
.env - Whitelist your IP (or allow access from anywhere for Vercel)
Option B: Local MongoDB
- Install MongoDB locally
- Use
mongodb://localhost:27017/movefastas your URI
Collections
MongoDB creates collections automatically when the first document is inserted. The app uses these collections:
| Collection | Purpose |
|---|---|
users | User accounts with roles, status, plan info |
magiclinktokens | Temporary magic link verification tokens |
waitinglists | Email waitlist entries |
invites | Admin-created invite records |
payments | Payment transaction records |
subscriptions | Subscription 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
DATABASE_URL=postgresql://user:password@host:5432/dbnameIf your provider requires a direct connection (some do for migrations):
DIRECT_URL=postgresql://user:password@host:5432/dbnameGetting a PostgreSQL Database
Option A: Supabase (recommended)
- Create a project at supabase.com
- Go to Project Settings > Database
- Copy the connection string (use the "Transaction" pooler for
DATABASE_URL) - 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:
npx prisma generateThis 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:
npx prisma db pushThis creates all the tables defined in prisma/schema.prisma.
Schema Overview
The Prisma schema defines these tables:
| Table | Purpose |
|---|---|
User | User accounts (id, email, name, roles, isActive, planId) |
VerificationToken | Magic link tokens (identifier, token, expires) |
WaitingList | Waitlist entries with email tracking |
Invite | Invite records with token, expiry, used/revoked status |
Payment | Payment records linked to users |
Subscription | Subscription 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:
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:
npx prisma studioData Models
Both database options store the same logical entities. Here is what each model contains:
User
id- Unique identifieremail- Unique email addressname- Display nameimage- Profile image URL (from OAuth)roles- Array of roles (USER,ADMIN)isActive- Whether the account is enabledplanId- The product ID of their purchased plan (for one-time payments)emailVerified- When their email was verifiedcreatedAt/updatedAt- Timestamps
Payment
userId- Reference to the userprovider- Which payment provider (STRIPE, DODO, POLAR)providerPaymentId- The provider's payment IDstatus- Payment status (COMPLETED, etc.)amount- Payment amountcurrency- Currency codeplanId- Which plan was purchased
Subscription
userId- Reference to the userprovider- Which payment providerproviderSubscriptionId- The provider's subscription IDproviderCustomerId- The provider's customer IDplanId- Which planstatus- ACTIVE, CANCELLED, PAST_DUE, etc.currentPeriodStart/currentPeriodEnd- Billing period datescancelAt/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/0if deploying to Vercel (serverless IPs change) - For Supabase, use the pooled connection string for
DATABASE_URLin serverless environments - Run
npx prisma generatein your CI/CD build step beforenpm run build
