Installation
npm install
npm run dev
Usage
Prerequisites: Node.js 22.6+ and a Supabase project (free tier is fine). Optional integrations — Google OAuth, Stripe, Resend — can be added later; the app degrades gracefully while their keys are blank.
Configuration. Copy the template and fill in the values:
cp .env.example .env.local
| Variable | Purpose |
|---|---|
DATABASE_URL | Supabase transaction pooler (port 6543) — used by the app |
DIRECT_URL | Supabase session pooler (port 5432) — used by migrations |
AUTH_SECRET | Signing secret — generate with openssl rand -base64 32 |
NEXT_PUBLIC_APP_URL | Your app's canonical origin (e.g. http://localhost:3000) |
NEXT_PUBLIC_SUPABASE_URL / ANON_KEY / SERVICE_ROLE_KEY | Supabase API keys (storage) |
STRIPE_SECRET_KEY / WEBHOOK_SECRET / price IDs | Stripe billing |
RESEND_API_KEY | Transactional email |
Database. The schema lives in prisma/schema.prisma (19 models). Create
the tables and load the demo dataset:
npm run db:migrate
npm run db:seed
The seed is idempotent and creates demo users, organizations, subscriptions,
posts, reports, and feature flags. All seeded accounts use the password
Password123! — admin@nextstarter.dev (Admin), moderator@nextstarter.dev
(Moderator), demo@nextstarter.dev (regular user, org owner).
Extending the template.
- Add a domain model — declare it in
prisma/schema.prisma, runnpm run db:migrate, and expose it through server actions + pages following the existingPostpattern (DAL re-checks auth,requireOwnership()guards mutations,writeAuditLog()records admin actions). - Change plans/pricing — edit
src/lib/plans.ts(single source of truth for the pricing page, plan gating, and Stripe price-ID lookup). - Add an email template — drop a default-export
.tsxfile insrc/emails/and a thinsend*wrapper insrc/lib/mail.ts; preview withnpm run email:dev. - Adjust roles/permissions — edit the grant maps in
src/lib/permissions.ts. - New admin feature — add a page under
src/app/admin/, gate it withrequireAdmin(), and audit writes viawriteAuditLog(). - Notification types — extend the
NotificationTypeenum (with a migration) and register it insrc/lib/notifications-shared.ts.
Testing. The Playwright suite starts its own dev server and isolated, namespaced database seed:
npm run test:e2e
Deployment. Deploy to Vercel (or any Node host), set the same environment
variables, run npm run db:deploy against production, and point the Stripe
webhook at https://<your-domain>/api/webhooks/stripe.