PromptFork

Build a production-grade SaaS MVP with Stripe lifecycle, team management, and tenant isolation

Goes beyond 'build a SaaS' — specifies the patterns that actually make or break an MVP: tenant-isolated data, Stripe webhook flows, invite-based teams, usage metering, and an onboarding funnel.

Open in Studio
Prompt
Build a production-grade SaaS MVP for [YOUR IDEA — what it does, who pays, the core object they manage].

Stack: Next.js 14+ App Router, Tailwind, Supabase (auth, Postgres, RLS), Stripe.

Schema-first approach — present these tables for approval before writing code:
- organizations (id, name, slug, plan_tier enum [free/pro/enterprise], stripe_customer_id, stripe_subscription_id, subscription_status enum, current_period_end, usage_count, usage_limit)
- org_members (org_id, user_id, role enum [owner/admin/member], invited_by, invited_at, accepted_at)
- users (id, email, name, avatar_url, onboarding_completed_at)
- [CORE_OBJECT] — the thing users create/manage. Must have org_id as foreign key.
- All RLS policies enforce tenant isolation: every query filters by the user\'s current org_id. A user must NEVER see another org\'s data.

Auth + onboarding funnel:
- Email + Google OAuth via Supabase Auth.
- After first login: 3-step onboarding → (1) create or join an org, (2) set profile name + avatar, (3) create first [CORE_OBJECT]. Track completion; redirect to onboarding if incomplete.
- Auth middleware protects all /app/* routes. Public routes: landing page, login, signup, pricing.

Team management:
- Owner invites by email → generates a signed invite link (expires 7 days).
- Invite link creates the org_member row on acceptance.
- Role-based UI: owners see billing + team settings, admins manage members, members see the dashboard.

Stripe billing (use test mode):
- Products: Free (0, limited to [X] [CORE_OBJECTS]), Pro ($29/mo, higher limit), Enterprise (custom).
- Checkout: redirect to Stripe Checkout from the pricing/upgrade page. Pass org_id in metadata.
- Webhook handler at /api/webhooks/stripe — handle these events and explain what each does:
  • checkout.session.completed → activate subscription, update org plan_tier + stripe IDs.
  • invoice.payment_succeeded → extend current_period_end.
  • invoice.payment_failed → set subscription_status to past_due, show a banner.
  • customer.subscription.updated → sync plan_tier if they up/downgrade.
  • customer.subscription.deleted → downgrade to free, enforce limits.
- Webhook signature verification with STRIPE_WEBHOOK_SECRET.
- Customer portal link for self-serve plan changes.

Usage metering:
- Track [CORE_OBJECT] count per org. On create, check against usage_limit for the current plan. If at limit, show an upgrade modal instead of creating. Display "X of Y used" in the sidebar.

Dashboard:
- Sidebar layout: org switcher (if user belongs to multiple), nav links, usage indicator.
- Main area: CRUD for [CORE_OBJECT] with a table/list view, detail view, and create/edit forms.
- Settings pages: profile, team members + invites, billing (current plan, usage, portal link).

Seed script: creates a demo org with 3 users (owner, admin, member), sample [CORE_OBJECTS], and a mock Stripe subscription.

Deliver: (1) schema for approval, (2) the app, (3) a setup checklist (env vars, Stripe product/price IDs, webhook endpoint registration, Supabase RLS verification steps).

Tip: the two things that sink SaaS MVPs are leaky tenant isolation (user A sees user B\'s data) and broken subscription state. Test RLS by logging in as two different org members and confirming zero cross-contamination. Test webhooks with the Stripe CLI: `stripe listen --forward-to localhost:3000/api/webhooks/stripe`.
Source
promptfork seed
License
CC-BY-4.0
Published
6/22/2026

More prompts you might like

Next.js 15 App Router page with streaming, caching, and server data

Scaffold a production App Router page: Server Component data fetching, Suspense streaming for instant TTFB, correct cache strategy (fetch cache vs unstable_cache vs revalidatePath), loading/error boundaries, and generateMetadata — with the non-obvious patterns most tutorials skip.

New

Tailwind analytics dashboard with animated stat cards, dark mode, and skeleton loading

Production-grade dashboard layout: KPI cards with counting animations and trend sparklines, a chart area, activity table — all with dark mode, skeleton loading states, and responsive breakpoints defined to the pixel.

New

Supabase RLS: owner-write, public-read policies for a table

Generate correct, non-recursive RLS policies so anyone reads published rows and only owners edit their own.

New

Stripe webhook handler with signature verify + idempotency

Production-ready Stripe webhook route that verifies the signature and processes events exactly once.

New

.cursorrules for a strict TypeScript + React codebase

A tuned .cursorrules file that keeps Cursor's agent on-convention: strict types, no dead code, match existing patterns.

New

Refactor a React component into clean custom hooks

Extract stateful logic from a bloated component into typed, testable custom hooks.

New