Token导航 LogoToken导航

Agent Skill · 前端设计

saas-scaffolder(SAAS 脚手架)

saas-scaffolder 用于处理 GitHub 仓库、Issue、Pull Request 和代码协作信息,适合在 Codex、Claude、Cursor、Gemini CLI 中需要围绕仓库状态、代码变更或协作事项进行整理时使用。可结合来源仓库、安装命令和原始 README 继续核验具体用法。安装前建议确认权限范围、维护状态,以及是否会触发联网、命令执行或文件读写。

saas-scaffolder 是前端设计类 Agent Skill,可用宿主为 Codex、Claude、Cursor、Gemini CLI,通过GitHub 仓库获取,权限为执行命令;许可证信息还不明确,第三方扫描有提醒项,按安装量在前端设计类的 10,216 个 Skill 里排第 3,050。

总安装 1,623周安装 69GitHub Stars 103下载 569核验 2026-05-01

安装说明

本站只整理中文说明,不托管安装包,也不代用户安装。
GitHub
许可证
unknown

安装方式

通过对话安装

复制提示词发给支持本地命令或 Skills 的 AI 助手,先确认命令和权限,再让它执行。

请帮我安装这个 Agent Skill:saas-scaffolder(SAAS 脚手架)
来源仓库:https://github.com/borghei/claude-skills
仓库路径:skills/saas-scaffolder
安装命令:
npx skills add https://github.com/borghei/claude-skills --skill saas-scaffolder
安装前请先检查当前环境是否支持对应 CLI,并向我确认将要执行的命令、安装目录、联网范围和文件读写权限;确认后再执行。

命令行安装

复制命令到本机终端执行。该命令会通过 npx skills 从第三方来源获取 Skill;本站只展示命令,不托管安装包,也不自动执行。

skills.shnpx skills
npx skills add https://github.com/borghei/claude-skills --skill saas-scaffolder

这个 Skill 是做什么的

前端设计类 Skill 关注页面结构、视觉规范和组件写法,输出通常是可运行的界面代码。

saas-scaffolder 快速生成含认证、计费与多租户的完整 SaaS 应用骨架。集成主流技术栈如 Next.js、Stripe 与 shadcn/ui,缩短启动周期。产出可直接部署的生产级代码结构,支持后续功能扩展。首次使用前应审查第三方服务条款与密钥管理机制。

适用宿主包括 Codex、Claude、Cursor、Gemini CLI,接入前应确认版本、权限和运行环境要求。

来源仓库内路径:skills/saas-scaffolder

上手步骤

4 步
  1. 1

    确认自己的宿主工具

    公开资料标注支持 Codex、Claude、Cursor、Gemini CLI;先确认自己用的是其中之一,再按对应工具的 Skills 目录放置。

  2. 2

    拿到安装命令

    可以直接复制的命令是 npx skills add https://github.com/borghei/claude-skills --skill saas-scaffolder;命令里的占位符换成自己的路径或密钥再执行。

  3. 3

    安装后重启宿主

    命令执行完要完全退出宿主工具再打开,让新装的 Skill 被重新扫描到,否则列表里可能看不到。

  4. 4

    按最小权限试用

    它需要执行命令,先在测试目录或测试账号里跑,确认没问题再放到正式项目。

常见问题

6 条

saas-scaffolder 怎么安装?

在终端执行 npx skills add https://github.com/borghei/claude-skills --skill saas-scaffolder。装完完全退出宿主工具再打开,让它重新扫描本地 Skill。

saas-scaffolder 支持哪些 AI 工具?

公开资料标注支持 Codex、Claude、Cursor、Gemini CLI。其他工具只要能读取本地 Skill 目录,一般也能手动放进去,但要自己确认触发方式是否一致。

saas-scaffolder 需要什么权限?

权限级别是执行命令。安装流程涉及命令执行,可能通过 npx skills add https://github.com/borghei/claude-skills --skill saas-scaffolder 联网下载 Skill 或依赖。用户安装前应确认命令来源、仓库内容和执行环境。

saas-scaffolder 是免费的吗?

公开资料没有标注明确许可证,收费和商用限制都无法确认。正式使用前请到来源仓库核对授权说明。

saas-scaffolder 用的人多吗?

公开数据是累计安装 1,623 次,近一周安装 69 次,下载 569 次,GitHub 103 星。这些数字来自第三方目录统计,只能当作热度参考,不代表质量或安全性。

saas-scaffolder 安全吗?

第三方扫描有提醒项,说明存在需要人工确认的行为。安装前请打开源码看清它读了什么、联网到哪里。

值得选的地方和要先想清楚的地方

值得选的地方

  • 同时适配 4 种工具,换客户端不用重新找替代品。

先想清楚的地方

  • 需要执行命令,装到常用环境前要先评估影响面。
  • 许可证没有明确标注,能不能商用、能不能再分发都不确定。
  • 第三方扫描存在提醒项或未通过项,需要人工逐条确认。
  • 第三方目录整理,版本更新和行为细节以来源仓库为准。

适不适合你

更适合

  • 已经在用 Codex,想直接扩展它能力的人。
  • 需要处理前端设计类任务、又不想每次都手写提示词的人。

不太适合

  • 不能接受 Skill 在你机器上执行命令的人。
  • 需要明确授权才能用到公司项目里的场景。
  • 需要厂商级技术支持和 SLA 的生产系统。

前端设计类 Skill 对比

6 个同类
Skill总安装GitHub 星权限许可证扫描
frontend-design

前端设计 · Codex、Claude

8,823,360126,072只读MIT通过
vercel-composition-patterns

Vercel 组合模式 · Codex、Claude

3,858,81625,893需要联网MIT通过
vercel-react-native-skills

Vercel React native skills 前端 · Codex、Claude

2,468,66425,878只读MIT通过
adapt

adapt 搜索 · Codex、Claude

2,027,04023,125操作浏览器未明确通过
bolder

bolder 分析 · Codex、Claude

2,004,28823,130只读未明确通过
saas-scaffolder

SAAS 脚手架 · 本页

1,623103执行命令未明确有提醒

按安装量取同分类前几名;数字来自第三方目录统计,只作热度参考,不代表质量结论。

SKILL.md 原文

SaaS Scaffolder

Tier: POWERFUL Category: Engineering / Full-Stack Maintainer: Claude Skills Team

Overview

Generate a complete, production-ready SaaS application boilerplate including authentication (NextAuth, Clerk, or Supabase Auth), database schemas with multi-tenancy, billing integration (Stripe or Lemon Squeezy), API routes with validation, dashboard UI with shadcn/ui, and deployment configuration. Produces a working application from a product specification in under 30 minutes.

Keywords

SaaS, boilerplate, scaffolding, Next.js, authentication, Stripe, billing, multi-tenancy, subscription, starter template, NextAuth, Drizzle ORM, shadcn/ui

Input Specification

Product: [name]
Description: [1-3 sentences]
Auth: nextauth | clerk | supabase
Database: neondb | supabase | planetscale | turso
Payments: stripe | lemonsqueezy | none
Multi-tenancy: workspace | organization | none
Features: [comma-separated list]

Generated File Tree

my-saas/
├── app/
│   ├── (auth)/
│   │   ├── login/page.tsx
│   │   ├── register/page.tsx
│   │   ├── forgot-password/page.tsx
│   │   └── layout.tsx
│   ├── (dashboard)/
│   │   ├── dashboard/page.tsx
│   │   ├── settings/
│   │   │   ├── page.tsx              # Profile settings
│   │   │   ├── billing/page.tsx      # Subscription management
│   │   │   └── team/page.tsx         # Team/workspace settings
│   │   └── layout.tsx                # Dashboard shell (sidebar + header)
│   ├── (marketing)/
│   │   ├── page.tsx                  # Landing page
│   │   ├── pricing/page.tsx          # Pricing tiers
│   │   └── layout.tsx
│   ├── api/
│   │   ├── auth/[...nextauth]/route.ts
│   │   ├── webhooks/stripe/route.ts
│   │   ├── billing/
│   │   │   ├── checkout/route.ts
│   │   │   └── portal/route.ts
│   │   └── health/route.ts
│   ├── layout.tsx                    # Root layout
│   └── not-found.tsx
├── components/
│   ├── ui/                           # shadcn/ui components
│   ├── auth/
│   │   ├── login-form.tsx
│   │   └── register-form.tsx
│   ├── dashboard/
│   │   ├── sidebar.tsx
│   │   ├── header.tsx
│   │   └── stats-card.tsx
│   ├── marketing/
│   │   ├── hero.tsx
│   │   ├── features.tsx
│   │   ├── pricing-card.tsx
│   │   └── footer.tsx
│   └── billing/
│       ├── plan-card.tsx
│       └── usage-meter.tsx
├── lib/
│   ├── auth.ts                       # Auth configuration
│   ├── db.ts                         # Database client singleton
│   ├── stripe.ts                     # Stripe client
│   ├── validations.ts                # Zod schemas
│   └── utils.ts                      # Shared utilities
├── db/
│   ├── schema.ts                     # Drizzle schema
│   ├── migrations/                   # Generated migrations
│   └── seed.ts                       # Development seed data
├── hooks/
│   ├── use-subscription.ts
│   └── use-current-user.ts
├── types/
│   └── index.ts                      # Shared TypeScript types
├── middleware.ts                      # Auth + rate limiting
├── .env.example
├── drizzle.config.ts
├── tailwind.config.ts
└── next.config.ts

Database Schema (Multi-Tenant)

// db/schema.ts
import { pgTable, text, timestamp, integer, boolean, uniqueIndex, index } from 'drizzle-orm/pg-core'
import { createId } from '@paralleldrive/cuid2'

// ──── WORKSPACES (Tenancy boundary) ────
export const workspaces = pgTable('workspaces', {
  id: text('id').primaryKey().$defaultFn(createId),
  name: text('name').notNull(),
  slug: text('slug').notNull(),
  plan: text('plan').notNull().default('free'),  // free | pro | enterprise
  stripeCustomerId: text('stripe_customer_id').unique(),
  stripeSubscriptionId: text('stripe_subscription_id'),
  stripePriceId: text('stripe_price_id'),
  stripeCurrentPeriodEnd: timestamp('stripe_current_period_end'),
  createdAt: timestamp('created_at', { withTimezone: true }).defaultNow().notNull(),
  updatedAt: timestamp('updated_at', { withTimezone: true }).defaultNow().notNull(),
}, (t) => [
  uniqueIndex('workspaces_slug_idx').on(t.slug),
])

// ──── USERS ────
export const users = pgTable('users', {
  id: text('id').primaryKey().$defaultFn(createId),
  email: text('email').notNull().unique(),
  name: text('name'),
  avatarUrl: text('avatar_url'),
  emailVerified: timestamp('email_verified', { withTimezone: true }),
  createdAt: timestamp('created_at', { withTimezone: true }).defaultNow().notNull(),
})

// ──── WORKSPACE MEMBERS ────
export const workspaceMembers = pgTable('workspace_members', {
  id: text('id').primaryKey().$defaultFn(createId),
  workspaceId: text('workspace_id').notNull().references(() => workspaces.id, { onDelete: 'cascade' }),
  userId: text('user_id').notNull().references(() => users.id, { onDelete: 'cascade' }),
  role: text('role').notNull().default('member'), // owner | admin | member
  joinedAt: timestamp('joined_at', { withTimezone: true }).defaultNow().notNull(),
}, (t) => [
  uniqueIndex('workspace_members_unique').on(t.workspaceId, t.userId),
  index('workspace_members_workspace_idx').on(t.workspaceId),
])

// ──── ACCOUNTS (OAuth) ────
export const accounts = pgTable('accounts', {
  userId: text('user_id').notNull().references(() => users.id, { onDelete: 'cascade' }),
  type: text('type').notNull(),
  provider: text('provider').notNull(),
  providerAccountId: text('provider_account_id').notNull(),
  refreshToken: text('refresh_token'),
  accessToken: text('access_token'),
  expiresAt: integer('expires_at'),
})

// ──── SESSIONS ────
export const sessions = pgTable('sessions', {
  sessionToken: text('session_token').primaryKey(),
  userId: text('user_id').notNull().references(() => users.id, { onDelete: 'cascade' }),
  expires: timestamp('expires', { withTimezone: true }).notNull(),
})

Authentication Configuration

// lib/auth.ts
import { DrizzleAdapter } from '@auth/drizzle-adapter'
import NextAuth from 'next-auth'
import Google from 'next-auth/providers/google'
import GitHub from 'next-auth/providers/github'
import Resend from 'next-auth/providers/resend'
import { db } from './db'

export const { handlers, auth, signIn, signOut } = NextAuth({
  adapter: DrizzleAdapter(db),
  providers: [
    Google({
      clientId: process.env.GOOGLE_CLIENT_ID!,
      clientSecret: process.env.GOOGLE_CLIENT_SECRET!,
    }),
    GitHub({
      clientId: process.env.GITHUB_CLIENT_ID!,
      clientSecret: process.env.GITHUB_CLIENT_SECRET!,
    }),
    Resend({
      from: 'noreply@myapp.com',
    }),
  ],
  callbacks: {
    session: async ({ session, user }) => ({
      ...session,
      user: {
        ...session.user,
        id: user.id,
      },
    }),
  },
  pages: {
    signIn: '/login',
    error: '/login',
  },
})

Stripe Billing Integration

Checkout Session

// app/api/billing/checkout/route.ts
import { NextResponse } from 'next/server'
import { auth } from '@/lib/auth'
import { stripe } from '@/lib/stripe'
import { db } from '@/lib/db'
import { workspaces } from '@/db/schema'
import { eq } from 'drizzle-orm'

export async function POST(req: Request) {
  const session = await auth()
  if (!session?.user) {
    return NextResponse.json({ error: 'Unauthorized' }, { status: 401 })
  }

  const { priceId, workspaceId } = await req.json()

  // Get or create Stripe customer
  const [workspace] = await db.select().from(workspaces).where(eq(workspaces.id, workspaceId))
  if (!workspace) {
    return NextResponse.json({ error: 'Workspace not found' }, { status: 404 })
  }

  let customerId = workspace.stripeCustomerId
  if (!customerId) {
    const customer = await stripe.customers.create({
      email: session.user.email!,
      metadata: { workspaceId },
    })
    customerId = customer.id
    await db.update(workspaces)
      .set({ stripeCustomerId: customerId })
      .where(eq(workspaces.id, workspaceId))
  }

  const checkoutSession = await stripe.checkout.sessions.create({
    customer: customerId,
    mode: 'subscription',
    payment_method_types: ['card'],
    line_items: [{ price: priceId, quantity: 1 }],
    success_url: `${process.env.NEXT_PUBLIC_APP_URL}/settings/billing?success=true`,
    cancel_url: `${process.env.NEXT_PUBLIC_APP_URL}/pricing`,
    subscription_data: { trial_period_days: 14 },
    metadata: { workspaceId },
  })

  return NextResponse.json({ url: checkoutSession.url })
}

Webhook Handler

// app/api/webhooks/stripe/route.ts
import { headers } from 'next/headers'
import { stripe } from '@/lib/stripe'
import { db } from '@/lib/db'
import { workspaces } from '@/db/schema'
import { eq } from 'drizzle-orm'

export async function POST(req: Request) {
  const body = await req.text()
  const signature = (await headers()).get('Stripe-Signature')!

  let event
  try {
    event = stripe.webhooks.constructEvent(body, signature, process.env.STRIPE_WEBHOOK_SECRET!)
  } catch (err) {
    return new Response(`Webhook Error: ${err.message}`, { status: 400 })
  }

  switch (event.type) {
    case 'checkout.session.completed': {
      const session = event.data.object
      const subscription = await stripe.subscriptions.retrieve(session.subscription as string)
      await db.update(workspaces).set({
        stripeSubscriptionId: subscription.id,
        stripePriceId: subscription.items.data[0].price.id,
        stripeCurrentPeriodEnd: new Date(subscription.current_period_end * 1000),
      }).where(eq(workspaces.stripeCustomerId, session.customer as string))
      break
    }

    case 'invoice.payment_succeeded': {
      const invoice = event.data.object
      const subscription = await stripe.subscriptions.retrieve(invoice.subscription as string)
      await db.update(workspaces).set({
        stripeCurrentPeriodEnd: new Date(subscription.current_period_end * 1000),
      }).where(eq(workspaces.stripeCustomerId, invoice.customer as string))
      break
    }

    case 'customer.subscription.deleted': {
      const subscription = event.data.object
      await db.update(workspaces).set({
        plan: 'free',
        stripeSubscriptionId: null,
        stripePriceId: null,
        stripeCurrentPeriodEnd: null,
      }).where(eq(workspaces.stripeCustomerId, subscription.customer as string))
      break
    }
  }

  return new Response('OK', { status: 200 })
}

Middleware (Auth + Rate Limiting)

// middleware.ts
import { auth } from '@/lib/auth'
import { NextResponse } from 'next/server'

export default auth((req) => {
  const { pathname } = req.nextUrl
  const isAuthenticated = !!req.auth

  // Protected routes
  if (pathname.startsWith('/dashboard') || pathname.startsWith('/settings')) {
    if (!isAuthenticated) {
      return NextResponse.redirect(new URL('/login', req.url))
    }
  }

  // Redirect logged-in users away from auth pages
  if ((pathname === '/login' || pathname === '/register') && isAuthenticated) {
    return NextResponse.redirect(new URL('/dashboard', req.url))
  }

  return NextResponse.next()
})

export const config = {
  matcher: ['/dashboard/:path*', '/settings/:path*', '/login', '/register'],
}

Environment Variables

# .env.example

# ─── App ───
NEXT_PUBLIC_APP_URL=http://localhost:3000
NEXTAUTH_SECRET=           # openssl rand -base64 32
NEXTAUTH_URL=http://localhost:3000

# ─── Database ───
DATABASE_URL=              # postgresql://user:pass@host/db?sslmode=require

# ─── OAuth Providers ───
GOOGLE_CLIENT_ID=
GOOGLE_CLIENT_SECRET=
GITHUB_CLIENT_ID=
GITHUB_CLIENT_SECRET=

# ─── Stripe ───
STRIPE_SECRET_KEY=sk_test_...
STRIPE_WEBHOOK_SECRET=whsec_...
NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY=pk_test_...
STRIPE_PRO_MONTHLY_PRICE_ID=price_...
STRIPE_PRO_YEARLY_PRICE_ID=price_...

# ─── Email ───
RESEND_API_KEY=re_...

# ─── Monitoring (optional) ───
SENTRY_DSN=

Scaffolding Phases

Execute these phases in order. Validate at the end of each phase.

Phase 1: Foundation

  1. Initialize Next.js with TypeScript and App Router
  2. Configure Tailwind CSS with custom theme
  3. Install and configure shadcn/ui
  4. Set up ESLint and Prettier
  5. Create .env.example

Validate: pnpm build completes without errors.

Phase 2: Database

  1. Install and configure Drizzle ORM
  2. Write schema (users, accounts, sessions, workspaces, members)
  3. Generate and apply initial migration
  4. Export DB client singleton from lib/db.ts
  5. Create seed script with test data

Validate: pnpm db:push succeeds and pnpm db:seed creates test data.

Phase 3: Authentication

  1. Install and configure NextAuth v5 with Drizzle adapter
  2. Set up OAuth providers (Google, GitHub)
  3. Create auth API route
  4. Implement middleware for route protection
  5. Build login and register pages

Validate: OAuth login works, session persists, protected routes redirect.

Phase 4: Billing

  1. Initialize Stripe client
  2. Create checkout session API route
  3. Create customer portal API route
  4. Implement webhook handler with signature verification
  5. Build pricing page and billing settings page

Validate: Complete a test checkout with card 4242 4242 4242 4242. Verify subscription data written to DB. Replay webhook event and confirm idempotency.

Phase 5: UI and Polish

  1. Build landing page (hero, features, pricing, footer)
  2. Build dashboard layout (sidebar, header, stats)
  3. Build settings pages (profile, billing, team)
  4. Add loading states, error boundaries, and not-found pages
  5. Configure deployment (Vercel/Railway)

Validate: pnpm build succeeds. All routes render correctly. No hydration errors.

Multi-Tenancy Patterns

Workspace-Scoped Queries

// Every data query must be scoped to the current workspace
export async function getProjects(workspaceId: string) {
  return db.query.projects.findMany({
    where: eq(projects.workspaceId, workspaceId),
    orderBy: [desc(projects.updatedAt)],
  })
}

// Middleware: resolve workspace from URL or session
export function getCurrentWorkspace(req: Request) {
  // Option A: workspace slug in URL (/workspace/acme/dashboard)
  // Option B: workspace ID in session/cookie
  // Option C: header (X-Workspace-Id) for API calls
}

Plan-Based Feature Gating

export function canAccessFeature(workspace: Workspace, feature: string): boolean {
  const PLAN_FEATURES: Record<string, string[]> = {
    free: ['basic_dashboard', 'up_to_3_members'],
    pro: ['advanced_analytics', 'up_to_20_members', 'custom_domain', 'api_access'],
    enterprise: ['sso', 'unlimited_members', 'audit_log', 'sla'],
  }

  const isActive = workspace.stripeCurrentPeriodEnd
    ? workspace.stripeCurrentPeriodEnd > new Date()
    : workspace.plan === 'free'

  if (!isActive) return PLAN_FEATURES.free.includes(feature)
  return PLAN_FEATURES[workspace.plan]?.includes(feature) ?? false
}

Common Pitfalls

  • Missing NEXTAUTH_SECRET in production — causes session errors; generate with openssl rand -base64 32
  • Webhook signature verification skipped — always verify Stripe webhook signatures; test with stripe listen
  • **workspace:* in session but not refreshed** — stale subscription data; recheck on billing pages
  • Edge Runtime conflicts with Drizzle — Drizzle needs Node.js runtime; set export const runtime = 'nodejs' on API routes
  • No idempotent webhook handling — Stripe may send duplicate events; use event.id for deduplication
  • Hardcoded Stripe price IDs — store in env vars, not in code; prices change between test and live mode

Best Practices

  1. Stripe singleton — create the client once in lib/stripe.ts, import everywhere
  2. Server actions for form mutations — use Next.js Server Actions instead of API routes for forms
  3. Idempotent webhook handlers — check if the event was already processed before writing to DB
  4. Suspense boundaries for async data — wrap dashboard data in <Suspense> with loading skeletons
  5. Feature gating at the server level — check stripeCurrentPeriodEnd on the server, not the client
  6. Rate limiting on auth routes — prevent brute force with Upstash Redis + @upstash/ratelimit
  7. Workspace context in every query — never query without scoping to the current workspace
  8. Test with Stripe CLI — stripe listen --forward-to localhost:3000/api/webhooks/stripe for local development

Troubleshooting

ProblemCauseSolution
NEXTAUTH_URL mismatch errors in productionEnvironment variable not updated from localhost defaultSet NEXTAUTH_URL to your actual production domain; omit trailing slash
Stripe webhook returns 400 on every eventRaw body is consumed before signature verificationEnsure the webhook route uses req.text() before any JSON parsing; do not use body-parser middleware on the webhook endpoint
Drizzle migrations fail with "relation already exists"Migration was partially applied or schema drifted from migration historyRun pnpm drizzle-kit drop to reset the migration journal, then regenerate with pnpm drizzle-kit generate and reapply
OAuth callback redirects to wrong URLRedirect URI registered in provider console does not match NEXTAUTH_URLUpdate the authorized redirect URI in Google/GitHub developer console to match your deployment URL exactly
Multi-tenant queries return data from other workspacesMissing workspaceId filter in a database queryAudit all db.query and db.select calls to ensure every query includes a where clause scoped to the current workspace
Hydration mismatch on dashboard pagesServer-rendered HTML differs from client due to conditional auth checksMove auth-dependent rendering into client components or wrap with <Suspense>; avoid reading session in server components that also render on the client
Stripe test mode charges succeed but live mode failsLive mode price IDs differ from test mode IDsUse separate environment variables for test vs. live Stripe keys and price IDs; verify .env.production references the correct live values

Success Criteria

  • Scaffolded project passes pnpm build with zero errors and zero TypeScript warnings on first run
  • End-to-end authentication flow (register, login, logout, password reset) completes in under 60 seconds of manual testing
  • Stripe checkout creates a subscription and webhook handler updates the database within 5 seconds of payment completion
  • Multi-tenant data isolation verified: queries scoped to Workspace A return zero rows belonging to Workspace B
  • Lighthouse performance score on the landing page is 90+ on mobile with no accessibility violations at the AA level
  • Time from git clone to running local dev server with seeded data is under 10 minutes following the generated README
  • All environment variables are documented in .env.example with descriptions, and the app fails fast with clear error messages when required variables are missing

Scope & Limitations

This skill covers:

  • Full-stack SaaS scaffolding with Next.js App Router, TypeScript, Tailwind, and shadcn/ui
  • Authentication setup with NextAuth v5, Clerk, or Supabase Auth including OAuth and magic link providers
  • Stripe and Lemon Squeezy billing integration with checkout, webhooks, and customer portal
  • Multi-tenancy patterns (workspace/organization) with role-based access and plan-based feature gating

This skill does NOT cover:

  • Ongoing Stripe billing logic beyond initial integration (metered billing, usage-based pricing, invoicing customization) — see stripe-integration-expert
  • Database schema design decisions beyond the core tenancy model (complex relational modeling, indexing strategies) — see database-schema-designer
  • CI/CD pipeline configuration, deployment automation, or infrastructure provisioning — see ci-cd-pipeline-builder
  • API design standards, versioning, or OpenAPI specification generation — see api-design-reviewer

Integration Points

SkillIntegrationData Flow
stripe-integration-expertExtends the scaffolded Stripe setup with advanced billing patterns (metered, tiered, usage-based)Scaffolder outputs base Stripe config and webhook handler; Stripe expert refines pricing models and adds invoice customization
database-schema-designerDesigns extended schemas beyond the core tenancy tablesScaffolder provides baseline users/workspaces/members schema; schema designer adds domain-specific entities and optimizes indexes
api-design-reviewerReviews and improves the generated API routes for consistency and standards complianceScaffolder generates initial API routes; reviewer audits naming, error handling, and response formats
ci-cd-pipeline-builderCreates deployment pipelines for the scaffolded projectScaffolder outputs the application code; pipeline builder adds GitHub Actions, preview deployments, and production release workflows
env-secrets-managerAudits and secures the environment variable configurationScaffolder generates .env.example; secrets manager validates no secrets are hardcoded and recommends vault integration
observability-designerAdds logging, tracing, and monitoring to the scaffolded applicationScaffolder provides the application structure; observability designer instruments API routes, webhooks, and auth flows

平台分布

Codex

35.02%
按下载量换算199

Claude

28.94%
按下载量换算165

Cursor

19.96%
按下载量换算114

Gemini CLI

9.62%
按下载量换算55

安全审计

Gen Agent Trust Hub

通过

Socket

通过

Snyk

可疑

权限和风险

执行命令

安装流程涉及命令执行,可能通过 npx skills add https://github.com/borghei/claude-skills --skill saas-scaffolder 联网下载 Skill 或依赖。用户安装前应确认命令来源、仓库内容和执行环境。

安装前确认

本站仅展示第三方公开信息,不托管安装包,不提供自动安装或运行环境。安装前应自行审查源码、依赖和命令行为。来源安全扫描存在提醒或未通过项,安装前请自行复核。目前只有一个公开来源,建议同时核对源仓库。

继续浏览同类 Skills