关于 saas-architect
saas-architect 是面向独立开发者的 SaaS 规划技能,针对 Next.js 15 和 Supabase。它生成涵盖数据库、认证、订阅、功能、安全与交付计划的架构文档。
主要功能
- 01定义 SaaS 产品与定价
- 02规划 PostgreSQL 模式和 RLS
- 03生成 Next.js 文件结构
- 04规划认证与账单流程
- 05拆分功能并制定开发路线图
- 06提供安全与部署检查清单
适用场景
- 01规划新的订阅制 SaaS
- 02设计多租户组织与角色
- 03为现有 SaaS 增加功能
- 04制定开发和发布路线图
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ sitechfromgeorgia/ georgian-distribution-system --skill saas-architect安装后在 Claude Code 中输入/saas-architect确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
references/RLS_PATTERNS.mdSTRIPE_PATTERNS.mdscripts/validate-schema.js详细介绍
SaaS 架构师 - Next.js + Supabase 版
用途
此技能可将 SaaS 创意转化为可执行的技术架构,并针对 Next.js 15 + Supabase 技术栈进行优化。它提供全面的规划,涵盖数据库设计、身份验证流程、订阅逻辑、文件结构,以及个人开发者构建订阅制产品时切实可行的开发时间表。
核心理念
1. 订阅优先架构
- 从第一天起就面向经常性收入进行设计
- 规划多个定价层级
- 尽早构建升级/降级流程
- 考虑试用期和宽限期
2. 默认支持多租户
- 行级安全(RLS)是强制要求
- 内置组织/团队结构
- 从一开始就设置用户角色和权限
- 数据隔离不容妥协
3. 针对 Next.js 15 + Supabase 优化
- 使用服务器组件获取数据
- 利用服务器操作处理数据变更
- 使用 Supabase 的内置功能(Auth、Storage、Realtime)
- 尽量减少自定义后端代码
4. 从一开始就满足生产环境要求
- 提前考虑安全性
- 内置可扩展性模式
- 规划监控和错误跟踪
- 明确部署策略
此技能的工作方式
阶段 1:SaaS 产品定义
1.1 核心价值主张
**Product Name:** [Name]
**One-Line Pitch:** [What it does in one sentence]
**Target Market:** [Who pays for this]
**Primary Use Case:** [Main problem solved]
**Success Metric:** [How you measure value]
1.2 收入模式
**Pricing Strategy:** [Freemium / Trial / Pay-to-start]
**Tiers:** [How many pricing tiers]
**Key Differentiators:** [What makes higher tiers worth it]
**Billing Cycle:** [Monthly / Annual / Both]
示例(项目管理 SaaS):
**Product Name:** TaskFlow
**One-Line Pitch:** Project management for distributed teams with AI-powered task prioritization
**Target Market:** Remote teams, 10-50 employees, tech companies
**Primary Use Case:** Coordinate async work across timezones
**Success Metric:** Teams complete 30% more tasks on time
**Pricing Strategy:** Freemium with 14-day trial on paid plans
**Tiers:**
- Free: 1 project, 5 users, basic features
- Pro ($29/mo): Unlimited projects, 25 users, AI features
- Enterprise ($99/mo): Unlimited users, advanced integrations, priority support
**Key Differentiators:**
- Pro: AI task prioritization, integrations
- Enterprise: SSO, custom workflows, dedicated support
**Billing Cycle:** Monthly + Annual (2 months free)
阶段 2:技术架构规划
2.1 数据库架构设计
此技能会生成包含 RLS 策略的完整 PostgreSQL 架构:
每个 SaaS 都需要的核心表:
-- ============================================
-- USERS & AUTHENTICATION
-- ============================================
-- Note: Supabase Auth handles auth.users table
-- We extend it with profiles
CREATE TABLE profiles (
id UUID REFERENCES auth.users PRIMARY KEY,
email TEXT NOT NULL,
full_name TEXT,
avatar_url TEXT,
created_at TIMESTAMPTZ DEFAULT NOW(),
updated_at TIMESTAMPTZ DEFAULT NOW()
);
-- RLS Policies
ALTER TABLE profiles ENABLE ROW LEVEL SECURITY;
CREATE POLICY "Users can view own profile"
ON profiles FOR SELECT
USING (auth.uid() = id);
CREATE POLICY "Users can update own profile"
ON profiles FOR UPDATE
USING (auth.uid() = id);
-- ============================================
-- ORGANIZATIONS (Multi-Tenant Core)
-- ============================================
CREATE TABLE organizations (
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
name TEXT NOT NULL,
slug TEXT UNIQUE NOT NULL,
logo_url TEXT,
subscription_tier TEXT DEFAULT 'free',
subscription_status TEXT DEFAULT 'active',
trial_ends_at TIMESTAMPTZ,
created_at TIMESTAMPTZ DEFAULT NOW(),
updated_at TIMESTAMPTZ DEFAULT NOW()
);
ALTER TABLE organizations ENABLE ROW LEVEL SECURITY;
-- ============================================
-- ORGANIZATION MEMBERS (Team Management)
-- ============================================
CREATE TYPE member_role AS ENUM ('owner', 'admin', 'member');
CREATE TABLE organization_members (
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
organization_id UUID REFERENCES organizations(id) ON DELETE CASCADE,
user_id UUID REFERENCES auth.users(id) ON DELETE CASCADE,
role member_role DEFAULT 'member',
invited_by UUID REFERENCES auth.users(id),
joined_at TIMESTAMPTZ DEFAULT NOW(),
UNIQUE(organization_id, user_id)
);
ALTER TABLE organization_members ENABLE ROW LEVEL SECURITY;
CREATE POLICY "Members can view own org members"
ON organization_members FOR SELECT
USING (
organization_id IN (
SELECT organization_id FROM organization_members
WHERE user_id = auth.uid()
)
);
-- ============================================
-- STRIPE INTEGRATION (Subscriptions)
-- ============================================
CREATE TABLE customers (
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
organization_id UUID REFERENCES organizations(id) ON DELETE CASCADE,
stripe_customer_id TEXT UNIQUE,
email TEXT,
created_at TIMESTAMPTZ DEFAULT NOW()
);
CREATE TABLE products (
id TEXT PRIMARY KEY, -- Stripe product ID
active BOOLEAN DEFAULT true,
name TEXT NOT NULL,
description TEXT,
image TEXT,
metadata JSONB,
created_at TIMESTAMPTZ DEFAULT NOW()
);
CREATE TABLE prices (
id TEXT PRIMARY KEY, -- Stripe price ID
product_id TEXT REFERENCES products(id),
active BOOLEAN DEFAULT true,
currency TEXT DEFAULT 'usd',
type TEXT CHECK (type IN ('one_time', 'recurring')),
unit_amount BIGINT,
interval TEXT CHECK (interval IN ('day', 'week', 'month', 'year')),
interval_count INTEGER,
trial_period_days INTEGER,
metadata JSONB,
created_at TIMESTAMPTZ DEFAULT NOW()
);
CREATE TABLE subscriptions (
id TEXT PRIMARY KEY, -- Stripe subscription ID
organization_id UUID REFERENCES organizations(id),
customer_id TEXT REFERENCES customers(stripe_customer_id),
status TEXT NOT NULL,
price_id TEXT REFERENCES prices(id),
quantity INTEGER,
cancel_at_period_end BOOLEAN DEFAULT false,
current_period_start TIMESTAMPTZ,
current_period_end TIMESTAMPTZ,
trial_start TIMESTAMPTZ,
trial_end TIMESTAMPTZ,
canceled_at TIMESTAMPTZ,
ended_at TIMESTAMPTZ,
created_at TIMESTAMPTZ DEFAULT NOW()
);
-- RLS for subscription data
ALTER TABLE customers ENABLE ROW LEVEL SECURITY;
ALTER TABLE subscriptions ENABLE ROW LEVEL SECURITY;
CREATE POLICY "Org owners can view own subscription"
ON subscriptions FOR SELECT
USING (
organization_id IN (
SELECT organization_id FROM organization_members
WHERE user_id = auth.uid() AND role IN ('owner', 'admin')
)
);
-- ============================================
-- FEATURE-SPECIFIC TABLES
-- ============================================
-- This section is customized based on your SaaS features
-- Example: Project Management SaaS
CREATE TABLE projects (
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
organization_id UUID REFERENCES organizations(id) ON DELETE CASCADE,
name TEXT NOT NULL,
description TEXT,
status TEXT DEFAULT 'active',
created_by UUID REFERENCES auth.users(id),
created_at TIMESTAMPTZ DEFAULT NOW(),
updated_at TIMESTAMPTZ DEFAULT NOW()
);
ALTER TABLE projects ENABLE ROW LEVEL SECURITY;
CREATE POLICY "Org members can view org projects"
ON projects FOR SELECT
USING (
organization_id IN (
SELECT organization_id FROM organization_members
WHERE user_id = auth.uid()
)
);
CREATE POLICY "Org members can create projects"
ON projects FOR INSERT
WITH CHECK (
organization_id IN (
SELECT organization_id FROM organization_members
WHERE user_id = auth.uid()
)
);
CREATE TABLE tasks (
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
project_id UUID REFERENCES projects(id) ON DELETE CASCADE,
title TEXT NOT NULL,
description TEXT,
status TEXT DEFAULT 'todo',
priority TEXT DEFAULT 'medium',
assigned_to UUID REFERENCES auth.users(id),
due_date TIMESTAMPTZ,
created_by UUID REFERENCES auth.users(id),
created_at TIMESTAMPTZ DEFAULT NOW(),
updated_at TIMESTAMPTZ DEFAULT NOW()
);
ALTER TABLE tasks ENABLE ROW LEVEL SECURITY;
CREATE POLICY "Org members can view org tasks"
ON tasks FOR SELECT
USING (
project_id IN (
SELECT id FROM projects
WHERE organization_id IN (
SELECT organization_id FROM organization_members
WHERE user_id = auth.uid()
)
)
);
2.2 Next.js 文件结构
此技能会生成可用于生产环境的文件结构:
your-saas-app/
├── app/
│ ├── (auth)/ # Auth layout group
│ │ ├── login/
│ │ │ └── page.tsx # Login page
│ │ ├── signup/
│ │ │ └── page.tsx # Signup page
│ │ ├── forgot-password/
│ │ │ └── page.tsx
│ │ └── layout.tsx # Auth pages layout
│ │
│ ├── (dashboard)/ # Protected dashboard routes
│ │ ├── layout.tsx # Dashboard shell (sidebar, nav)
│ │ ├── page.tsx # Dashboard home
│ │ │
│ │ ├── [orgSlug]/ # Organization-specific routes
│ │ │ ├── projects/
│ │ │ │ ├── page.tsx # Projects list
│ │ │ │ ├── [id]/
│ │ │ │ │ └── page.tsx # Single project view
│ │ │ │ └── new/
│ │ │ │ └── page.tsx # Create project
│ │ │ │
│ │ │ ├── tasks/
│ │ │ │ ├── page.tsx
│ │ │ │ └── [id]/page.tsx
│ │ │ │
│ │ │ ├── team/
│ │ │ │ ├── page.tsx # Team members
│ │ │ │ └── invite/page.tsx # Invite flow
│ │ │ │
│ │ │ └── settings/
│ │ │ ├── page.tsx # Org settings
│ │ │ ├── billing/
│ │ │ │ └── page.tsx # Subscription management
│ │ │ └── members/
│ │ │ └── page.tsx # Member management
│ │ │
│ │ └── onboarding/ # Post-signup onboarding
│ │ ├── page.tsx
│ │ └── create-org/page.tsx
│ │
│ ├── (marketing)/ # Public pages
│ │ ├── page.tsx # Landing page
│ │ ├── pricing/
│ │ │ └── page.tsx # Pricing page
│ │ ├── about/
│ │ │ └── page.tsx
│ │ └── layout.tsx # Marketing layout
│ │
│ ├── api/ # API routes
│ │ ├── stripe/
│ │ │ ├── checkout/
│ │ │ │ └── route.ts # Create checkout session
│ │ │ ├── portal/
│ │ │ │ └── route.ts # Customer portal
│ │ │ └── webhook/
│ │ │ └── route.ts # Stripe webhooks
│ │ │
│ │ └── webhooks/
│ │ └── supabase/
│ │ └── route.ts # Supabase webhooks
│ │
│ ├── globals.css
│ └── layout.tsx # Root layout
│
├── components/
│ ├── ui/ # shadcn/ui components
│ │ ├── button.tsx
│ │ ├── card.tsx
│ │ ├── dialog.tsx
│ │ ├── dropdown-menu.tsx
│ │ ├── form.tsx
│ │ ├── input.tsx
│ │ ├── table.tsx
│ │ └── ...
│ │
│ ├── layouts/
│ │ ├── dashboard-shell.tsx # Dashboard wrapper
│ │ ├── marketing-header.tsx
│ │ └── marketing-footer.tsx
│ │
│ ├── auth/
│ │ ├── login-form.tsx
│ │ ├── signup-form.tsx
│ │ └── auth-guard.tsx # Protected route wrapper
│ │
│ ├── billing/
│ │ ├── pricing-card.tsx
│ │ ├── subscription-status.tsx
│ │ └── usage-meter.tsx
│ │
│ ├── organizations/
│ │ ├── org-switcher.tsx # Switch between orgs
│ │ ├── org-selector.tsx
│ │ └── invite-member-dialog.tsx
│ │
│ └── features/ # Feature-specific components
│ ├── projects/
│ │ ├── project-list.tsx
│ │ ├── project-card.tsx
│ │ └── create-project-dialog.tsx
│ └── tasks/
│ ├── task-list.tsx
│ ├── task-card.tsx
│ └── task-form.tsx
│
├── lib/
│ ├── supabase/
│ │ ├── client.ts # Browser client
│ │ ├── server.ts # Server client
│ │ ├── middleware.ts # Auth middleware
│ │ └── types.ts # Generated types
│ │
│ ├── stripe/
│ │ ├── client.ts # Stripe initialization
│ │ ├── products.ts # Product/price helpers
│ │ └── webhooks.ts # Webhook handlers
│ │
│ ├── hooks/
│ │ ├── use-user.ts # Get current user
│ │ ├── use-organization.ts # Get current org
│ │ ├── use-subscription.ts # Get subscription status
│ │ └── use-permissions.ts # Check user permissions
│ │
│ ├── actions/ # Server Actions
│ │ ├── auth.actions.ts
│ │ ├── org.actions.ts
│ │ ├── subscription.actions.ts
│ │ └── features/
│ │ ├── projects.actions.ts
│ │ └── tasks.actions.ts
│ │
│ └── utils/
│ ├── permissions.ts # Permission checking
│ ├── rate-limit.ts # Rate limiting
│ └── errors.ts # Error handling
│
├── types/
│ ├── database.types.ts # Generated from Supabase
│ ├── stripe.types.ts
│ └── app.types.ts
│
├── middleware.ts # Next.js middleware (auth)
├── .env.local
├── .env.example
├── next.config.js
├── package.json
├── tailwind.config.ts
└── tsconfig.json
阶段 3:功能规划与拆解
此技能会将 SaaS 功能拆解为可实现的部分:
3.1 核心 SaaS 功能(必备)
身份验证与用户管理
## Auth Flow
**User Stories:**
- As a user, I can sign up with email/password
- As a user, I can sign in with OAuth (Google, GitHub)
- As a user, I can reset my password
- As a user, I can update my profile
**Technical Implementation:**
- Supabase Auth handles all authentication
- Magic link email for password reset
- OAuth providers configured in Supabase dashboard
- Profile updates via Server Actions
**Acceptance Criteria:**
- [ ] Users can create accounts
- [ ] Email verification works
- [ ] Password reset flow functional
- [ ] OAuth providers work
- [ ] Sessions persist across refreshes
- [ ] Logout clears session
**Time Estimate:** 2-3 days
组织管理
## Multi-Tenant Organizations
**User Stories:**
- As a user, I can create an organization
- As an owner, I can invite team members
- As a member, I can accept invitations
- As an owner, I can manage member roles
- As a user, I can switch between organizations
**Technical Implementation:**
- Organizations table with RLS
- Invitation system via email
- Role-based access control (owner, admin, member)
- Organization switcher component
- Invites expire after 7 days
**Acceptance Criteria:**
- [ ] Users can create orgs with unique slugs
- [ ] Owners can invite via email
- [ ] Invites create pending records
- [ ] Members can accept/decline
- [ ] Role changes reflect immediately
- [ ] Users can switch orgs via dropdown
**Time Estimate:** 3-4 days
订阅与账单
## Stripe Subscription Flow
**User Stories:**
- As a user, I can view pricing plans
- As an org owner, I can subscribe to a plan
- As an org owner, I can upgrade/downgrade
- As an org owner, I can manage billing
- As an org owner, I can cancel subscription
**Technical Implementation:**
- Stripe Checkout for subscriptions
- Webhook handler for subscription events
- Customer Portal for self-service billing
- Trial period (14 days)
- Graceful downgrade handling
**Acceptance Criteria:**
- [ ] Pricing page shows all plans
- [ ] Checkout flow works end-to-end
- [ ] Webhooks update subscription status
- [ ] Features respect subscription tier
- [ ] Portal allows plan changes
- [ ] Cancellation handles end of period
**Time Estimate:** 4-5 days
3.2 特定功能规划
此技能会根据你的 SaaS 生成自定义功能拆解:
示例:项目管理功能
## Projects Feature
**User Stories:**
- As a member, I can view all org projects
- As a member, I can create new projects
- As a member, I can update project details
- As an admin, I can archive projects
**Database:**
- `projects` table with org relationship
- RLS policies for org-based access
**Components:**
- ProjectList (with search/filter)
- ProjectCard (preview)
- CreateProjectDialog (form)
- ProjectSettings (edit)
**API:**
- GET /api/projects?orgId=xxx
- POST /api/projects
- PATCH /api/projects/:id
- DELETE /api/projects/:id
**Time Estimate:** 3 days
## Tasks Feature
**User Stories:**
- As a member, I can create tasks in projects
- As a member, I can assign tasks
- As an assignee, I can update task status
- As a member, I can set due dates
**Database:**
- `tasks` table with project relationship
- Status enum (todo, in_progress, done)
- Priority enum (low, medium, high)
**Components:**
- TaskList (kanban or table view)
- TaskCard (draggable)
- CreateTaskDialog (form)
- TaskDetailView (modal)
**Time Estimate:** 3-4 days
阶段 4:开发路线图
此技能会生成切实可行的逐周计划:
第 1 周:基础与身份验证
## Days 1-2: Project Setup
**Tasks:**
- [ ] Create Next.js 15 project with TypeScript
- [ ] Install dependencies (Supabase, Stripe, shadcn/ui, Zod)
- [ ] Set up Supabase project
- [ ] Configure environment variables
- [ ] Set up database schema (run SQL)
- [ ] Configure RLS policies
- [ ] Generate TypeScript types from database
**Deliverable:** Empty project with database ready
## Days 3-4: Authentication
**Tasks:**
- [ ] Implement Supabase Auth
- [ ] Create login/signup pages
- [ ] Add OAuth providers (Google, GitHub)
- [ ] Build auth middleware
- [ ] Create protected route wrapper
- [ ] Add password reset flow
- [ ] Style auth pages with shadcn/ui
**Deliverable:** Working authentication system
## Day 5: User Profiles
**Tasks:**
- [ ] Create profile page
- [ ] Implement profile update form
- [ ] Add avatar upload (Supabase Storage)
- [ ] Build user settings page
**Deliverable:** Users can manage profiles
## Weekend: Buffer
- Fix any blocking issues
- Test auth flows
- Start organization setup
第 2 周:组织与团队
## Days 1-2: Organization Core
**Tasks:**
- [ ] Create org creation flow
- [ ] Build org switcher component
- [ ] Implement org slug validation
- [ ] Add org settings page
- [ ] Create org context/provider
**Deliverable:** Organizations functional
## Days 3-4: Team Management
**Tasks:**
- [ ] Build invitation system
- [ ] Create invite email templates
- [ ] Implement role management
- [ ] Add member list page
- [ ] Build invite acceptance flow
**Deliverable:** Team collaboration works
## Day 5: Polish
**Tasks:**
- [ ] Add loading states
- [ ] Improve error handling
- [ ] Add toast notifications
- [ ] Test org workflows
**Weekend:** Integration testing
第 3 周:Stripe 集成
## Days 1-2: Stripe Setup
**Tasks:**
- [ ] Set up Stripe account
- [ ] Create products and prices
- [ ] Implement webhook endpoint
- [ ] Test webhook locally (Stripe CLI)
- [ ] Add webhook handlers for key events
**Deliverable:** Stripe connected
## Days 3-4: Subscription Flow
**Tasks:**
- [ ] Build pricing page
- [ ] Implement checkout flow
- [ ] Create success/cancel pages
- [ ] Add subscription status indicator
- [ ] Implement Customer Portal link
**Deliverable:** Subscriptions work end-to-end
## Day 5: Feature Gates
**Tasks:**
- [ ] Add subscription checking middleware
- [ ] Implement usage limits per tier
- [ ] Build upgrade prompts
- [ ] Add billing page to dashboard
**Weekend:** Test all subscription scenarios
第 4 周:核心功能
## Days 1-3: Primary Feature (e.g., Projects)
**Tasks:**
- [ ] Build CRUD operations
- [ ] Create list/detail views
- [ ] Add search and filtering
- [ ] Implement Server Actions
- [ ] Add optimistic updates
**Deliverable:** Primary feature functional
## Days 4-5: Secondary Feature (e.g., Tasks)
**Tasks:**
- [ ] Build basic CRUD
- [ ] Create list view
- [ ] Add quick actions
- [ ] Implement status updates
**Weekend:** Feature testing and polish
第 5 周:完善与发布准备
## Days 1-2: UX Polish
**Tasks:**
- [ ] Add loading skeletons
- [ ] Improve error messages
- [ ] Add empty states
- [ ] Implement toast notifications
- [ ] Add confirmation dialogs
## Days 3-4: Testing & Bugs
**Tasks:**
- [ ] Test all user flows
- [ ] Fix critical bugs
- [ ] Test mobile responsiveness
- [ ] Check cross-browser compatibility
## Day 5: Deploy
**Tasks:**
- [ ] Set up Vercel project
- [ ] Configure production environment variables
- [ ] Set up Stripe webhook in production
- [ ] Deploy to production
- [ ] Test production deployment
**Weekend:** Monitor, fix critical issues
阶段 5:安全与最佳实践
此技能会贯彻安全模式:
5.1 行级安全(RLS)模式
-- Pattern 1: User owns resource
CREATE POLICY "Users can only access own data"
ON table_name FOR ALL
USING (user_id = auth.uid());
-- Pattern 2: Org member access
CREATE POLICY "Org members can access org data"
ON table_name FOR SELECT
USING (
organization_id IN (
SELECT organization_id FROM organization_members
WHERE user_id = auth.uid()
)
);
-- Pattern 3: Role-based access
CREATE POLICY "Only admins can delete"
ON table_name FOR DELETE
USING (
organization_id IN (
SELECT organization_id FROM organization_members
WHERE user_id = auth.uid()
AND role IN ('owner', 'admin')
)
);
-- Pattern 4: Resource creator can update
CREATE POLICY "Creator can update"
ON table_name FOR UPDATE
USING (created_by = auth.uid());
5.2 服务器操作安全
// lib/actions/secure-action.ts
import { createClient } from '@/lib/supabase/server';
import { redirect } from 'next/navigation';
export async function secureAction(
handler: (userId: string, orgId: string) => Promise<any>
) {
const supabase = await createClient();
// 1. Verify authentication
const { data: { user }, error } = await supabase.auth.getUser();
if (error || !user) {
redirect('/login');
}
// 2. Get current organization
const { data: membership } = await supabase
.from('organization_members')
.select('organization_id')
.eq('user_id', user.id)
.single();
if (!membership) {
throw new Error('No organization access');
}
// 3. Execute handler with verified context
return handler(user.id, membership.organization_id);
}
// Usage in Server Actions
export async function createProject(formData: FormData) {
'use server';
return secureAction(async (userId, orgId) => {
const name = formData.get('name') as string;
// Validation
if (!name || name.length < 3) {
return { error: 'Name must be at least 3 characters' };
}
// Database operation (RLS will further verify access)
const supabase = await createClient();
const { data, error } = await supabase
.from('projects')
.insert({
name,
organization_id: orgId,
created_by: userId
})
.select()
.single();
if (error) {
return { error: error.message };
}
return { data };
});
}
5.3 API 路由安全
// app/api/stripe/webhook/route.ts
import { headers } from 'next/headers';
import Stripe from 'stripe';
const stripe = new Stripe(process.env.STRIPE_SECRET_KEY!);
const webhookSecret = process.env.STRIPE_WEBHOOK_SECRET!;
export async function POST(req: Request) {
const body = await req.text();
const signature = headers().get('stripe-signature');
if (!signature) {
return new Response('No signature', { status: 400 });
}
try {
// Verify webhook signature
const event = stripe.webhooks.constructEvent(
body,
signature,
webhookSecret
);
// Handle different events
switch (event.type) {
case 'checkout.session.completed':
await handleCheckoutComplete(event.data.object);
break;
case 'customer.subscription.updated':
await handleSubscriptionUpdate(event.data.object);
break;
case 'customer.subscription.deleted':
await handleSubscriptionCancel(event.data.object);
break;
}
return new Response(JSON.stringify({ received: true }));
} catch (err) {
console.error('Webhook error:', err);
return new Response('Webhook error', { status: 400 });
}
}
阶段 6:部署与监控
6.1 环境变量
# .env.example
# Supabase
NEXT_PUBLIC_SUPABASE_URL=your-project-url
NEXT_PUBLIC_SUPABASE_ANON_KEY=your-anon-key
SUPABASE_SERVICE_ROLE_KEY=your-service-role-key
# Stripe
NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY=pk_test_xxx
STRIPE_SECRET_KEY=sk_test_xxx
STRIPE_WEBHOOK_SECRET=whsec_xxx
# App
NEXT_PUBLIC_APP_URL=http://localhost:3000
NEXT_PUBLIC_APP_NAME=YourSaaS
# Email (optional)
RESEND_API_KEY=re_xxx
6.2 Vercel 部署检查清单
## Pre-Deploy
- [ ] All environment variables set in Vercel
- [ ] Supabase RLS policies tested
- [ ] Stripe webhook URL configured for production
- [ ] Production Stripe keys configured
- [ ] Error tracking set up (Sentry)
- [ ] Analytics configured (PostHog, Plausible)
## Deploy
- [ ] Push to main branch
- [ ] Verify build succeeds
- [ ] Check production URL
- [ ] Test critical flows in production
## Post-Deploy
- [ ] Monitor error rates
- [ ] Check webhook delivery
- [ ] Verify subscription flows
- [ ] Test on mobile devices
输出格式
当你请求 SaaS 架构规划时,此技能会提供:
# [Your SaaS Name] - Technical Architecture Document
## Executive Summary
[2-3 paragraphs: what you're building, for whom, tech stack]
## Product Overview
**Name:** [Product Name]
**Target:** [Target Audience]
**Value Prop:** [One-liner]
**Revenue Model:** [Pricing strategy]
## Technical Stack
- **Frontend:** Next.js 15 (App Router) + TypeScript + Tailwind CSS
- **UI Components:** shadcn/ui
- **Backend:** Next.js Server Actions + API Routes
- **Database:** PostgreSQL (Supabase)
- **Auth:** Supabase Auth
- **Payments:** Stripe
- **Storage:** Supabase Storage
- **Hosting:** Vercel
- **Email:** Resend (optional)
## Database Architecture
[Complete SQL schema with RLS policies]
## File Structure
[Full Next.js directory structure]
## Feature Breakdown
### Core SaaS Features (Week 1-3)
[Authentication, Organizations, Subscriptions]
### Product Features (Week 4-6)
[Your specific features broken down]
## Development Roadmap
[Week-by-week plan with tasks and deliverables]
## Security Considerations
[RLS patterns, authentication flows, API security]
## Deployment Strategy
[Vercel setup, environment variables, monitoring]
## Success Metrics
- **Activation:** [First meaningful action]
- **Engagement:** [Regular usage indicator]
- **Retention:** [Return behavior]
- **Revenue:** [MRR growth targets]
## Risks & Mitigations
| Risk | Impact | Mitigation |
|------|--------|------------|
| [Risk 1] | [High/Med/Low] | [How to handle] |
## Next Steps
1. [First actionable task]
2. [Second task]
3. [Third task]
如何使用此技能
基本用法
I need architecture for a SaaS product.
Use saas-architect skill.
Idea: [Your SaaS idea]
Target Users: [Who]
Pricing: [How you'll charge]
详细规划
Create complete SaaS architecture plan using saas-architect.
Product: [Detailed description]
Features: [List key features]
Timeline: [Launch target]
Constraints: [Any technical/business constraints]
特定功能规划
I have existing SaaS, need to add [feature].
Use saas-architect to plan:
- Database changes needed
- File structure for feature
- Implementation steps
- Timeline estimate
Existing Stack: Next.js 15 + Supabase
与开发流程集成
搭配 Claude Code 使用
生成架构后,可与 Claude Code 配合使用:
Generate starter code for this SaaS architecture:
[Paste architecture document]
Start with:
1. Database schema (run SQL in Supabase)
2. Initial project structure
3. Auth implementation
4. Organization setup
搭配其他技能使用
推荐工作流:
- idea-validator-pro → 验证市场契合度
- saas-architect → 技术规划
- modern-ui-designer → 设计系统
- Claude Code → 实现
- code-quality-guardian → 代码审查
- deployment-automation → 发布
最佳实践
应该 ✅
- 从核心 SaaS 功能开始:先实现身份验证、组织和订阅
- 全面使用 RLS:绝不跳过行级安全
- 尽早测试订阅:Stripe Webhook 至关重要
- 规划多租户支持:即使一开始只支持单租户
- 记录决策:未来的你会感谢现在的自己
不应该 ❌
- 跳过 RLS 策略:数据泄露后果严重
- 将 Stripe 密钥硬编码:使用环境变量
- 忽略 Webhook 测试:先在本地测试 Webhook
- 过度设计:从简单开始,之后再扩展
- 不做身份验证就开始构建:从身份验证开始
常见场景
场景 1:免费增值 SaaS
Challenge: Need free tier with upgrade path
Solution:
- Free tier with feature limits
- Trial period for paid plans
- Usage tracking in database
- Upgrade prompts in UI
场景 2:团队协作
Challenge: Multiple users per organization
Solution:
- Organization-based RLS
- Role-based permissions
- Invitation system
- Activity logging
场景 3:按用量计费
Challenge: Charge based on usage, not seats
Solution:
- Usage tracking table
- Metered billing with Stripe
- Usage dashboards
- Overage handling
防止技术债务
阶段 1(第 1-2 周):预计不会产生
重点是打好基础。
阶段 2(第 3-4 周):监控以下事项
- 测试覆盖率(关键路径力争达到 >70%)
- 错误处理的一致性
- 加载状态模式
阶段 3(第 5-6 周):重构时间
- 提取可复用的钩子
- 整合相似组件
- 优化数据库查询
- 添加缺失的索引
发布检查清单
发布前(提前 1 周)
- 所有核心功能正常运行
- 已测试移动端响应式效果
- 已测试跨浏览器兼容性
- 已端到端测试支付流程
- 已配置错误跟踪
- 已设置分析工具
- 服务条款已准备就绪
- 隐私政策已准备就绪
- 已配置支持邮箱
发布当天
- 部署到生产环境
- 验证所有 Webhook 均正常运行
- 测试注册流程
- 测试订阅流程
- 监控错误率
- 检查分析跟踪
发布后(第一周)
- 每日监控
- 修复严重错误
- 收集用户反馈
- 针对痛点进行迭代
技能元数据
版本: 1.0.0
最后更新: 2025 年 11 月
针对以下技术优化: Next.js 15、Supabase、Stripe
目标用户: 构建 SaaS 产品的独立开发者
输出: 完整的技术架构文档
关键见解:优秀的 SaaS 架构不在于拥有所有功能,而在于构建能够扩展的正确基础。首先专注于身份验证、多租户和订阅。其他一切都可以逐步迭代。
评论
支持 Markdown