Requirements
- Node.js 20+
- PostgreSQL (the setup targets Supabase, but any Postgres works via Prisma)
- Optional: Stripe account (test mode), Resend account, Google OAuth app
Getting started
npm install # runs `prisma generate` on postinstall
cp .env.example .env.local # fill in real values (see comments in the file)
npm run db:deploy # apply migrations (npx prisma migrate deploy)
npm run db:seed # demo data + sign-in credentials
npm run dev # http://localhost:3000
.env.example documents every variable — Supabase DATABASE_URL (transaction pooler) / DIRECT_URL (session pooler for migrations), AUTH_SECRET + Google OAuth, Stripe, and Resend. The app validates env at boot and degrades gracefully while keys are blank: emails print to the server console, Stripe surfaces "unconfigured" states, and logo uploads explain themselves.
🔒 Security note:
.env.local(real secrets) is gitignored. Only.env.exampleis committed, and it ships with placeholder values — never commit real credentials. See the env file for how to generateAUTH_SECRET(node -e "console.log(require('crypto').randomBytes(32).toString('base64'))").
Demo accounts
All seeded users share the password Password123!:
| Role | |
|---|---|
admin@paidly.example | platform ADMIN (full admin panel + Acme Inc demo data) |
moderator@paidly.example | MODERATOR |
alice@paidly.example | user — owns Globex, member of Acme |
bob@paidly.example | user — PRO plan, PAST_DUE |
carol@paidly.example | user — unverified email |
banned@paidly.example | BANNED — cannot sign in |
Note: these are demo seed accounts tied to
paidly.example. Replace them inprisma/seed.tsbefore real use.
Common scripts
| Command | Purpose |
|---|---|
npm run dev | Start the Next.js dev server |
npm run build / start | Production build / serve |
npm run lint | Run ESLint |
npm run db:migrate | Create + apply a migration (prisma migrate dev) |
npm run db:deploy | Apply pending migrations in prod (migrate deploy) |
npm run db:seed | Seed demo data |
npm run db:studio | Open Prisma Studio |
test:unit | Run the tsx unit suites (money, numbering, dunning, recurring, entitlements, payments, portal, analytics, CSV, API, admin) |
test:e2e | Run Playwright e2e suites |
Using the Stripe webhooks locally
stripe login
stripe listen --forward-to localhost:3000/api/webhooks/stripe
# copy the printed whsec_… secret into STRIPE_WEBHOOK_SECRET in .env.local
Emails locally
npm run email:dev # react-email preview at :3001