saas-architect について
saas-architect は、Next.js 15 と Supabase で SaaS を設計する個人開発者向けの計画スキルです。データベース、認証、サブスクリプション、機能、安全性、開発計画を含む設計文書を作成します。
主な機能
- 01SaaS の製品と料金設計
- 02PostgreSQL スキーマと RLS の計画
- 03Next.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. デフォルトでマルチテナント対応
- Row Level Security(RLS)は必須
- 組織/チーム構成を組み込む
- ユーザーの役割と権限を最初から設定する
- データの分離は絶対条件
3. Next.js 15 + Supabase に最適化
- データ取得には Server Components を使用する
- 更新処理には Server Actions を活用する
- 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 Row Level Security(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 Server Action のセキュリティ
// 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 Route のセキュリティ
// 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 を使う:Row Level Security を省略しない
- サブスクリプションを早期にテストする: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 週間)
- 毎日監視
- 重大なバグを修正
- ユーザーからのフィードバックを収集
- 課題点を改善
スキルのメタデータ
バージョン: 1.0.0
最終更新日: 2025 年 11 月
最適化対象: Next.js 15、Supabase、Stripe
対象: SaaS 製品を構築する個人開発者
出力: 技術アーキテクチャの完全なドキュメント
重要なポイント:優れた SaaS アーキテクチャとは、すべての機能を備えることではなく、拡張性のある適切な基盤を構築することです。まずは認証、マルチテナンシー、サブスクリプションに注力しましょう。それ以外は後から改善できます。