Production SaaS Starter
Multi-Tenant SaaS Platform
Production-ready B2B SaaS foundation с workspace-based multi-tenancy, Stripe billing, platform admin, RBAC и i18n. Это руководство проведёт от клона до локального запуска менее чем за час.
Обзор
Production SaaS Starter — workspace-based multi-tenant платформа, а не минимальное demo. Включает реальные паттерны: PostgreSQL RLS, SECURITY DEFINER RPCs, Stripe webhook idempotency, dual RBAC и service-provider abstraction.
- Workspaces с memberships, invites и slug-scoped URLs
- Stripe subscriptions, usage metering, promo codes и enterprise deals
- Platform admin console с audit logs и модерацией users/workspaces
- Email/password + OAuth, 2FA, password reset через Resend
Stack: Next.js 16, React 19, Supabase, Stripe, Resend, next-intl с 4 локалями.
Установка зависимостей
Установите npm-пакеты из корня проекта перед настройкой переменных окружения.
Выполните один раз после клонирования репозитория:
npm installНастройка окружения
Настройте .env.local до миграций БД или запуска приложения. Сначала создайте файл, затем добавляйте значения по мере прохождения setup ниже.
Создайте локальный env-файл
Скопируйте example-файл — значения Stripe и Resend добавьте в разделах ниже. Переменные Supabase настраиваются в разделе Supabase setup.
cp .env.example .env.localПриложение
ОбязательноURL развёрнутого приложения — для редиректов checkout, email-ссылок и OAuth callbacks.
Шаги
- 1Для локальной разработки: NEXT_PUBLIC_APP_URL=http://localhost:3000
- 2Для production: URL деплоя Vercel или custom domain
- 3Добавьте переменную в Vercel → Project → Settings → Environment Variables
Переменные окружения
NEXT_PUBLIC_APP_URLОбязательноПубличный URL SaaS-приложения (без завершающего /).
Где найти
Локально: http://localhost:3000 · Production: домен проекта Vercel или custom domain
Пример: https://app.yourdomain.com
NEXT_PUBLIC_APP_NAMEНазвание бренда в транзакционных письмах.
Где найти
Любое отображаемое имя — внешний сервис не нужен
Пример: Acme SaaS
Настройка Supabase
Выполните эти шаги Supabase по порядку — создание проекта, переменные окружения и миграция БД.
Выполните эти шаги Supabase по порядку — создание проекта, переменные окружения и миграция БД.
7 шагов — выполнить по порядку
Настройка Supabase
~5 минСоздайте проект и скопируйте Project ID
Создать проект Supabase
Войдите на supabase.com, нажмите New project, выберите имя и регион, задайте пароль БД и дождитесь provisioning.
Открыть Supabase DashboardСкопировать Project ID
Понадобится при link CLI и построении API URL.
Переменные окружения Supabase
Добавьте в .env.local после создания проекта Supabase — до миграций БД.
NEXT_PUBLIC_SUPABASE_URLURL API проекта. Замените YOURPROJECTID на ваш Supabase Project ID.
NEXT_PUBLIC_SUPABASE_URL=https://YOURPROJECTID.supabase.coГде найти
Supabase Dashboard → Project Settings → API
NEXT_PUBLIC_SUPABASE_ANON_KEYПубличный anon key — безопасен для браузера. Копируйте из панели; не используйте placeholder.
Где найти
Supabase Dashboard → Project Settings → API
SUPABASE_SERVICE_ROLE_KEYТолько для server. Никогда не раскрывайте клиенту. Копируйте из панели; не используйте placeholder.
Где найти
Supabase Dashboard → Project Settings → API
Настройка БД и миграции
~15 минCLI setup, link и миграция схемы
Установить Supabase CLI
Установите глобально, затем проверьте:
npm install -g supabaseПроверить установку:
supabase --versionВойти в Supabase CLI
Откроется браузер для аутентификации. Войдите и вернитесь в терминал.
supabase loginПривязать локальный проект
Замените PROJECT_REF на Project ID из шага 2.
supabase link --project-ref <PROJECT_REF>Пример:
supabase link --project-ref abcdefghijklmnopПрименить миграции БД
Создаёт все таблицы, functions, policies и seed data. Credentials Supabase должны быть в .env.local.
supabase db pushПроверить создание таблиц
Убедитесь, что схема на месте, перед продолжением.
Обновление БД
После pull обновлений репозитория с изменениями БД:
git pull
supabase db pushНастройка Stripe
Stripe CLI
Используйте Stripe CLI для локальной аутентификации и пересылки webhooks при разработке.
- 1Установите Stripe CLI по инструкциям из официальной документации Stripe
- 2Завершите платформенные шаги установки
- 3Выполните аутентификацию/вход Stripe
- 4После аутентификации продолжите локальную разработку со Stripe
Аутентифицировать CLI
Выполните login — откроется браузер для подключения аккаунта Stripe:
stripe loginПересылать webhooks локально
В отдельном терминале пересылайте events на локальный webhook handler. Скопируйте signing secret в STRIPE_WEBHOOK_SECRET:
stripe listen --forward-to localhost:3000/api/stripe/webhookAPI keys
Скопируйте ключи из панели Stripe в .env.local — никогда не hardcode ключи в репозитории или документации.
Где найти
Stripe Dashboard → Developers → API Keys
- Publishable Key (pk_test_...)
- Secret Key (sk_test_...)
Переменные окружения
STRIPE_SECRET_KEYОбязательноServer-side Stripe API key — копируйте из панели, никогда не hardcode.
Где найти
Stripe Dashboard → Developers → API Keys — Secret key (sk_test_...)
NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEYОбязательноClient-side ключ для Stripe.js checkout — копируйте из панели, никогда не hardcode.
Где найти
Stripe Dashboard → Developers → API Keys — Publishable key (pk_test_...)
Webhooks
Шаги
- 1Для локальной разработки выполните stripe listen --forward-to localhost:3000/api/stripe/webhook и скопируйте signing secret webhook
- 2Для deployed окружений добавьте webhook endpoint: https://YOUR_APP_URL/api/stripe/webhook
- 3Выберите events: checkout.session.completed, customer.subscription.*, invoice.*, payment_method.*
- 4Скопируйте signing secret webhook в STRIPE_WEBHOOK_SECRET в .env.local
Переменные окружения
STRIPE_WEBHOOK_SECRETОбязательноПроверяет подписи webhook от Stripe.
Где найти
Stripe Dashboard → Developers → Webhooks → Signing secret · Локально: вывод stripe listen
Настройка Resend
Resend
ОбязательноТранзакционная почта — приглашения, 2FA OTP, сброс пароля. Встроенная почта Supabase не используется.
Шаги
- 1Зарегистрируйтесь на resend.com
- 2Добавьте и верифицируйте sending domain (DNS-записи)
- 3Создайте API key
- 4Установите RESEND_FROM_EMAIL на верифицированный адрес вашего домена
Переменные окружения
RESEND_API_KEYОбязательноAPI key для отправки писем.
Где найти
Resend Dashboard → API Keys → Create API Key
RESEND_FROM_EMAILОбязательноВерифицированный адрес отправителя (напр. noreply@yourdomain.com).
Где найти
Resend Dashboard → Domains → Add domain → verify DNS → используйте адрес на этом домене
Быстрый старт
После завершения настройки окружения, Supabase, Stripe и Resend выше выполните эти команды по порядку:
Установить зависимости проекта
npm installСинхронизировать seed-планы со Stripe — в основном для тестирования и синхронизации планов Stripe с базой данных
npm run sync:plansЗапустить dev-сервер на http://localhost:3000
npm run devРазработка и production
Разные команды для ежедневной разработки и локального предпросмотра production-сборки.
Разработка
Запустите dev-сервер с hot reload:
npm run devProduction preview
Предпросмотр production-окружения локально — соберите приложение, затем запустите production-сервер:
npm run buildnpm run startСправочник скриптов
| Команда | Описание |
|---|---|
| supabase db push | Применить схему БД (supabase db push) |
| npm run sync:plans | Синхронизировать seed-планы с продуктами/ценами Stripe |
| npm run dev | Запустить dev-сервер |
| npm run build | Production-сборка |
| npm run start | Запустить production-сервер (после build) |
| npm run test | Запустить Jest unit-тесты (только services) |
Архитектура
Четыре слоя со строгим порядком вызовов — agents и разработчики следуют одному пути:
UI → Server Actions / API → Services → Repositories → PostgreSQL (RLS/RPC)Ключевые расположения:
Слой 1
Presentation — src/app/, src/components/
Слой 2
Application — server actions, createRequestContext(), RBAC guards
Слой 3
Domain — src/modules/*/ *.service.ts (business rules)
Слой 4
Data — repositories + PostgreSQL RLS/RPCs через src/services/
Multi-tenancy
Workspace — это tenant; отдельной таблицы organization нет.
- Tenant key: workspaces.id (UUID); URLs используют уникальный slug
- Memberships связывают users с workspaces в ролях owner, admin или member
- RLS policies enforce workspace_id IN (memberships пользователя)
Platform admins получают доступ к /admin через platform_admins — роли super_admin, platform_admin или platform_viewer.
Аутентификация и авторизация
Auth flow: login → optional 2FA → onboarding (нет workspace) или workspace dashboard. Platform admin invites ведут на platform-onboarding.
- Email/password и OAuth через Supabase Auth
- 2FA через email OTP (Resend) — не встроенная почта Supabase
- Password reset с token-based flow и rate limiting
Workspace roles и permissions:
ownerbilling, удаление workspace, полное управление membersadmininvite/remove members, обновление настроек workspacememberчтение и участие — без admin-действий
Billing и подписки
Одна активная подписка на workspace, привязанная к Stripe customer и subscription IDs.
- Checkout для новых подписок; portal для self-serve управления
- Upgrades с proration; downgrades запланированы на конец периода
- Seed plans: Starter ($29/mo), Pro ($39/mo), Enterprise (custom)
- Webhook на /api/stripe/webhook синхронизирует state с idempotent stripe_events table
Деплой
Рекомендуемый stack: Vercel (Next.js) + Supabase Cloud + Stripe webhooks.
- 1Примените schema к production Supabase (supabase db push)
- 2Установите все env vars в Vercel — см. раздел Environment setup выше
- 3Deploy Next.js app
- 4Зарегистрируйте Stripe webhook → https://ВАШ_URL/api/stripe/webhook
- 5Bootstrap super admin и sync:plans в production

