SaaS Products
Multi-tenant subscription software with workspaces, billing, and feature management
SaaS Products
SaaS (Software-as-a-Service) products are subscription-based applications with web interfaces for human users. They typically charge Monthly Recurring Revenue (MRR) and include both a UI application and programmatic API access. Modern SaaS products are multi-tenant, supporting workspaces, role-based access control, usage metering, and feature flags.
Characteristics
| Aspect | Value |
|---|---|
| Revenue Model | MRR (Monthly Recurring Revenue) |
| Pricing | Per seat, per tier, or usage-based subscription |
| Primary Interface | Web application (human UI) |
| Secondary Interface | REST/GraphQL API |
| Target User | Humans (with optional API access) |
| Architecture | Multi-tenant with workspace isolation |
| Example Components | Dashboard, Settings, Admin Panel |
Multi-Tenant Architecture
SaaS products serve multiple customers (tenants) from a single application instance. Each tenant's data is isolated and secure.
Tenant Isolation Models
Shared Database, Shared Schema
// All tenants share tables, rows filtered by tenant_id
interface User {
id: string
tenantId: string // Workspace/organization ID
email: string
role: 'owner' | 'admin' | 'member'
}
// All queries must filter by tenant
const users = await db.users.findMany({
where: { tenantId: currentTenant.id }
})Shared Database, Separate Schemas
// Each tenant has their own schema
const tenant = await getTenant(tenantId)
const schema = `tenant_${tenant.id}`
await db.raw(`SET search_path TO ${schema}`)
const users = await db.users.findMany() // Automatically scopedSeparate Databases
// Each tenant has dedicated database
const tenant = await getTenant(tenantId)
const db = connectToDatabase(tenant.databaseUrl)
const users = await db.users.findMany() // Complete isolationWorkspace Management
Workspaces (or organizations) are the primary tenant container:
interface Workspace {
id: string
name: string
slug: string // acme-corp
ownerId: string // User who created workspace
plan: 'free' | 'starter' | 'pro' | 'enterprise'
subscriptionId?: string // Stripe subscription
settings: WorkspaceSettings
createdAt: Date
updatedAt: Date
}
interface WorkspaceSettings {
// Branding
logo?: string
primaryColor?: string
// Features
features: {
apiAccess: boolean
sso: boolean
customDomain: boolean
auditLogs: boolean
}
// Limits (based on plan)
limits: {
seats: number // Max users
storage: number // GB
apiRequests: number // Per month
}
// Usage tracking
usage: {
seats: number // Current users
storage: number // Current GB used
apiRequests: number // This month
}
}Workspace Switching
// User can belong to multiple workspaces
interface WorkspaceMembership {
id: string
workspaceId: string
userId: string
role: 'owner' | 'admin' | 'member' | 'viewer'
invitedBy?: string
joinedAt: Date
}
// Component with workspace context
<WorkspaceSwitcher>
{workspaces.map(workspace => (
<WorkspaceOption
key={workspace.id}
workspace={workspace}
isActive={workspace.id === currentWorkspace.id}
onClick={() => switchWorkspace(workspace.id)}
/>
))}
</WorkspaceSwitcher>MDXLD Definition
---
$context: https://schema.org.ai
$type: Product
$id: https://acme.com/products/saas
name: Acme Platform
type: SaaS
business: https://acme.com
description: All-in-one project management platform
isActive: true
# Categorization
industries:
- B2B SaaS
- Project Management
productCategories:
- Collaboration Platform
- Task Management
# Interfaces
interfaces:
hasAPI: true
hasRPC: true
hasMCP: false
hasSDK: true
hasCLI: true
# Pricing Tiers
prices:
- $id: price_starter
name: Starter
amount: 1900
currency: USD
type: subscription
interval: month
features:
- Up to 10 users
- 10 GB storage
- Basic analytics
- $id: price_pro
name: Professional
amount: 4900
currency: USD
type: subscription
interval: month
features:
- Up to 50 users
- 100 GB storage
- Advanced analytics
- API access
- $id: price_enterprise
name: Enterprise
amount: 19900
currency: USD
type: subscription
interval: month
features:
- Unlimited users
- Unlimited storage
- Enterprise analytics
- Priority support
- SSO & SAML
---
# {name}
{description}
<Hero title={name} subtitle={description} />
<Features product={$id} />
<Pricing prices={prices} />
<Testimonials product={$id} />User Roles and Permissions
Multi-tenant SaaS requires role-based access control (RBAC) to manage what users can do within workspaces.
Role Hierarchy
type Role = 'owner' | 'admin' | 'member' | 'viewer'
interface RolePermissions {
role: Role
permissions: Permission[]
description: string
}
const roleHierarchy: RolePermissions[] = [
{
role: 'owner',
description: 'Full control, cannot be removed',
permissions: [
'workspace:delete',
'workspace:transfer',
'billing:manage',
'members:*',
'settings:*',
'data:*',
]
},
{
role: 'admin',
description: 'Manage workspace and members',
permissions: [
'workspace:update',
'members:invite',
'members:remove',
'members:update',
'settings:update',
'data:*',
]
},
{
role: 'member',
description: 'Standard user access',
permissions: [
'data:read',
'data:create',
'data:update',
'data:delete', // Only their own data
'settings:read',
]
},
{
role: 'viewer',
description: 'Read-only access',
permissions: [
'data:read',
'settings:read',
]
}
]Permission Checking
// Middleware to check permissions
function requirePermission(permission: string) {
return async (req, res, next) => {
const { user, workspace } = req
const membership = await db.workspaceMemberships.findFirst({
where: {
userId: user.id,
workspaceId: workspace.id
}
})
if (!membership) {
throw new ForbiddenError('Not a member of this workspace')
}
const hasPermission = checkPermission(membership.role, permission)
if (!hasPermission) {
throw new ForbiddenError(`Missing permission: ${permission}`)
}
next()
}
}
// Usage
app.delete('/api/workspaces/:id',
requireAuth,
requirePermission('workspace:delete'),
deleteWorkspace
)Custom Permissions
Advanced SaaS products support custom roles and granular permissions:
interface CustomRole {
id: string
workspaceId: string
name: string
description?: string
permissions: string[] // Custom permission strings
isDefault: boolean
}
interface Permission {
resource: string // 'projects', 'users', 'billing'
action: 'create' | 'read' | 'update' | 'delete' | 'manage'
scope?: 'own' | 'team' | 'workspace'
}
// Example: Project Manager role
const projectManagerRole: CustomRole = {
id: 'role_pm',
workspaceId: 'ws_123',
name: 'Project Manager',
permissions: [
'projects:*', // All project actions
'tasks:*', // All task actions
'members:read', // View members
'teams:read', // View teams
'reports:read', // View reports
],
isDefault: false
}Team-Based Permissions
interface Team {
id: string
workspaceId: string
name: string
description?: string
members: TeamMember[]
}
interface TeamMember {
userId: string
teamId: string
role: 'lead' | 'member'
}
// Resource can be owned by team
interface Project {
id: string
workspaceId: string
teamId?: string // Team ownership
ownerId?: string // Individual ownership
isPublic: boolean // Visible to entire workspace
}
// Check if user has access to resource
function canAccessProject(user: User, project: Project): boolean {
// Workspace admins can access everything
if (user.workspaceRole === 'admin' || user.workspaceRole === 'owner') {
return true
}
// Public projects visible to all members
if (project.isPublic) {
return true
}
// Owner can access
if (project.ownerId === user.id) {
return true
}
// Team members can access team projects
if (project.teamId && user.teams.includes(project.teamId)) {
return true
}
return false
}Billing Integration
SaaS products integrate with billing providers (typically Stripe) to manage subscriptions and payments.
Stripe Integration
interface StripeIntegration {
// Product mapping
stripeProductId: string // prod_...
// Price IDs for each tier
prices: Array<{
id: string
stripePriceId: string // price_...
name: string // 'Starter', 'Pro', 'Enterprise'
amount: number
interval: 'month' | 'year'
features: string[]
}>
}
// Create Stripe customer when workspace is created
async function createWorkspace(data: CreateWorkspaceInput) {
const workspace = await db.workspaces.create(data)
// Create Stripe customer
const customer = await stripe.customers.create({
email: data.ownerEmail,
name: data.name,
metadata: {
workspaceId: workspace.id
}
})
await db.workspaces.update({
where: { id: workspace.id },
data: { stripeCustomerId: customer.id }
})
return workspace
}
// Create subscription
async function subscribe(workspaceId: string, priceId: string) {
const workspace = await db.workspaces.findUnique({
where: { id: workspaceId }
})
const subscription = await stripe.subscriptions.create({
customer: workspace.stripeCustomerId,
items: [{ price: priceId }],
metadata: {
workspaceId: workspace.id
}
})
await db.workspaces.update({
where: { id: workspaceId },
data: {
subscriptionId: subscription.id,
plan: getPlanFromPrice(priceId),
subscriptionStatus: subscription.status
}
})
return subscription
}Webhook Handling
// Handle Stripe webhooks
app.post('/api/webhooks/stripe', async (req, res) => {
const sig = req.headers['stripe-signature']
const event = stripe.webhooks.constructEvent(
req.body,
sig,
process.env.STRIPE_WEBHOOK_SECRET
)
switch (event.type) {
case 'customer.subscription.created':
case 'customer.subscription.updated':
await handleSubscriptionUpdate(event.data.object)
break
case 'customer.subscription.deleted':
await handleSubscriptionCanceled(event.data.object)
break
case 'invoice.payment_succeeded':
await handlePaymentSuccess(event.data.object)
break
case 'invoice.payment_failed':
await handlePaymentFailed(event.data.object)
break
}
res.json({ received: true })
})
async function handleSubscriptionUpdate(subscription: Stripe.Subscription) {
const workspaceId = subscription.metadata.workspaceId
await db.workspaces.update({
where: { id: workspaceId },
data: {
subscriptionStatus: subscription.status,
currentPeriodEnd: new Date(subscription.current_period_end * 1000)
}
})
}Usage-Based Billing
// Track metered usage for hybrid pricing
interface UsageRecord {
workspaceId: string
metric: string // 'api_requests', 'storage_gb'
quantity: number
timestamp: Date
}
// Report usage to Stripe
async function reportUsage(workspaceId: string) {
const workspace = await db.workspaces.findUnique({
where: { id: workspaceId }
})
// Get usage for this billing period
const usage = await db.usageRecords.aggregate({
where: {
workspaceId,
timestamp: {
gte: workspace.currentPeriodStart,
lt: workspace.currentPeriodEnd
},
metric: 'api_requests'
},
_sum: { quantity: true }
})
// Report to Stripe
const subscription = await stripe.subscriptions.retrieve(
workspace.subscriptionId
)
const usageItem = subscription.items.data.find(
item => item.price.lookup_key === 'api_requests'
)
if (usageItem) {
await stripe.subscriptionItems.createUsageRecord(
usageItem.id,
{
quantity: usage._sum.quantity,
timestamp: Math.floor(Date.now() / 1000),
action: 'set'
}
)
}
}Billing Components
// Auto-wired billing components
<Billing workspace={currentWorkspace}>
<CurrentPlan />
<UsageMetrics />
<UpgradePlan />
<PaymentMethod />
<BillingHistory />
<Invoices />
</Billing>Feature Flags
Feature flags control which features are available to workspaces based on their plan or rollout status.
Feature Flag System
interface FeatureFlag {
id: string
name: string
description: string
type: 'boolean' | 'plan_based' | 'rollout' | 'custom'
enabled: boolean
// Plan-based features
plans?: Array<'free' | 'starter' | 'pro' | 'enterprise'>
// Rollout features
rolloutPercentage?: number
// Custom logic
evaluator?: (workspace: Workspace) => boolean
}
const features: FeatureFlag[] = [
{
id: 'api_access',
name: 'API Access',
description: 'Programmatic API access',
type: 'plan_based',
enabled: true,
plans: ['pro', 'enterprise']
},
{
id: 'sso',
name: 'Single Sign-On',
description: 'SAML/SSO authentication',
type: 'plan_based',
enabled: true,
plans: ['enterprise']
},
{
id: 'advanced_analytics',
name: 'Advanced Analytics',
description: 'Custom dashboards and reports',
type: 'rollout',
enabled: true,
rolloutPercentage: 50, // 50% of workspaces
},
{
id: 'ai_features',
name: 'AI Features',
description: 'AI-powered suggestions',
type: 'custom',
enabled: true,
evaluator: (workspace) => {
// Custom logic
return workspace.plan === 'enterprise' || workspace.betaAccess
}
}
]Feature Checking
// Check if workspace has feature
function hasFeature(workspace: Workspace, featureId: string): boolean {
const feature = features.find(f => f.id === featureId)
if (!feature || !feature.enabled) {
return false
}
switch (feature.type) {
case 'boolean':
return true
case 'plan_based':
return feature.plans?.includes(workspace.plan) ?? false
case 'rollout':
// Consistent hash-based rollout
const hash = hashWorkspaceId(workspace.id)
const threshold = (feature.rolloutPercentage ?? 0) / 100
return hash < threshold
case 'custom':
return feature.evaluator?.(workspace) ?? false
default:
return false
}
}
// Usage in components
function APIKeysPage() {
const { workspace } = useWorkspace()
if (!hasFeature(workspace, 'api_access')) {
return <UpgradePrompt feature="API Access" />
}
return <APIKeysList />
}Feature Flag Component
// Declarative feature flag component
<FeatureFlag feature="sso" workspace={workspace}>
<SSOSettings />
</FeatureFlag>
// With fallback
<FeatureFlag
feature="advanced_analytics"
workspace={workspace}
fallback={<UpgradePrompt />}
>
<AdvancedAnalytics />
</FeatureFlag>Remote Feature Flags
// Use external feature flag service (LaunchDarkly, etc.)
import { LDClient } from 'launchdarkly-node-server-sdk'
const ldClient = LDClient.initialize(process.env.LAUNCHDARKLY_SDK_KEY)
async function hasFeature(workspace: Workspace, featureId: string) {
const context = {
kind: 'workspace',
key: workspace.id,
name: workspace.name,
plan: workspace.plan,
customAttributes: {
createdAt: workspace.createdAt.toISOString(),
memberCount: workspace.memberCount
}
}
return await ldClient.variation(featureId, context, false)
}Usage Metering
Track and limit resource usage based on workspace plan limits.
Metering Infrastructure
interface UsageMetric {
workspace: string
metric: string // 'api_requests', 'storage', 'seats'
value: number
timestamp: Date
metadata?: Record<string, any>
}
// Track usage
async function trackUsage(
workspaceId: string,
metric: string,
value: number,
metadata?: Record<string, any>
) {
await db.usageMetrics.create({
data: {
workspace: workspaceId,
metric,
value,
timestamp: new Date(),
metadata
}
})
// Check if limit exceeded
await checkUsageLimit(workspaceId, metric)
}
// Check limits
async function checkUsageLimit(workspaceId: string, metric: string) {
const workspace = await db.workspaces.findUnique({
where: { id: workspaceId }
})
const limit = workspace.settings.limits[metric]
if (!limit) return
const usage = await getCurrentUsage(workspaceId, metric)
if (usage >= limit) {
// Send notification
await notifyLimitExceeded(workspace, metric, usage, limit)
// Optionally block further usage
throw new Error(`${metric} limit exceeded`)
}
// Warn at 80%
if (usage >= limit * 0.8) {
await notifyApproachingLimit(workspace, metric, usage, limit)
}
}
// Get current usage
async function getCurrentUsage(
workspaceId: string,
metric: string
): Promise<number> {
const workspace = await db.workspaces.findUnique({
where: { id: workspaceId }
})
// For current billing period
const result = await db.usageMetrics.aggregate({
where: {
workspace: workspaceId,
metric,
timestamp: {
gte: workspace.currentPeriodStart,
lt: workspace.currentPeriodEnd
}
},
_sum: { value: true }
})
return result._sum.value ?? 0
}Usage Components
// Display usage metrics
<UsageMetrics workspace={workspace}>
<UsageCard
metric="seats"
current={workspace.settings.usage.seats}
limit={workspace.settings.limits.seats}
label="Team Members"
/>
<UsageCard
metric="storage"
current={workspace.settings.usage.storage}
limit={workspace.settings.limits.storage}
label="Storage"
unit="GB"
/>
<UsageCard
metric="api_requests"
current={workspace.settings.usage.apiRequests}
limit={workspace.settings.limits.apiRequests}
label="API Requests"
period="month"
/>
</UsageMetrics>Rate Limiting
// API rate limiting per workspace
import rateLimit from 'express-rate-limit'
import RedisStore from 'rate-limit-redis'
function createWorkspaceLimiter(workspace: Workspace) {
const limit = workspace.settings.limits.apiRequestsPerMinute ?? 60
return rateLimit({
windowMs: 60 * 1000, // 1 minute
max: limit,
keyGenerator: (req) => `workspace:${workspace.id}`,
store: new RedisStore({
client: redis,
}),
handler: (req, res) => {
res.status(429).json({
error: 'Rate limit exceeded',
limit,
retryAfter: 60
})
}
})
}
// Usage
app.use('/api/*', async (req, res, next) => {
const workspace = req.workspace
const limiter = createWorkspaceLimiter(workspace)
limiter(req, res, next)
})Component Structure
SaaS products render as full applications:
Site Components (Marketing)
import type { SiteComponents } from 'mdxui'
// Marketing site for the SaaS
<Site product={saasProduct}>
<Header />
<LandingPage>
<Hero />
<Features />
<Pricing />
<Testimonials />
<CTA />
</LandingPage>
<Footer />
</Site>App Components (Application)
import type { AppComponents } from 'mdxui'
// The actual SaaS application
<App product={saasProduct}>
<Shell>
<Sidebar />
<Header />
<Dashboard />
</Shell>
</App>Typical Features
Core Features
| Feature | Description | Tier |
|---|---|---|
| User Management | Invite, roles, permissions | All |
| Team Collaboration | Workspaces, projects, tasks | All |
| File Storage | Upload and manage files | All |
| Notifications | Email, in-app, webhooks | All |
| Analytics | Usage insights and metrics | Pro+ |
| API Access | Programmatic access | Pro+ |
| SSO/SAML | Enterprise authentication | Enterprise |
| SLA & Support | Guaranteed uptime and response | Enterprise |
Auto-Wired Features
// These components auto-wire to Payload collections
<Team product={$id} /> // teams collection
<APIKeys product={$id} /> // apiKeys collection
<Webhooks product={$id} /> // webhooks collection
<Usage product={$id} /> // usage collection
<Billing product={$id} /> // subscriptions collection
<Settings product={$id} /> // settings collectionPricing Models
Per-Seat Pricing
Charge based on number of users:
interface SeatBasedPricing {
type: 'subscription'
interval: 'month' | 'year'
amount: number // e.g., $29 per seat
minSeats?: number // Minimum seats required
maxSeats?: number // Maximum seats allowed
}Example: $29/user/month, minimum 5 users
Tiered Pricing
Different feature sets at different price points:
interface TieredPricing {
tiers: Array<{
name: string // Starter, Pro, Enterprise
amount: number // $0, $49, $199
features: string[] // List of included features
limits: {
seats?: number // User limit
storage?: number // Storage limit (GB)
requests?: number // API request limit
}
}>
}Example: Free, Starter ($19), Pro ($49), Enterprise (Custom)
Usage-Based Subscription
Base subscription + usage charges:
interface UsageBasedPricing {
baseAmount: number // $49/month base
usageCharges: Array<{
metric: string // 'api_requests', 'storage_gb'
amount: number // $0.01 per request
includedQuantity?: number // First 10,000 free
}>
}Example: $49/month + $0.01 per API request over 10,000
Business Model
Metrics
Key SaaS metrics:
interface SaaSMetrics {
// Revenue
mrr: number // Monthly Recurring Revenue
arr: number // Annual Recurring Revenue
arpu: number // Average Revenue Per User
// Growth
newMRR: number // New subscriptions
expansionMRR: number // Upgrades
contractionMRR: number // Downgrades
churnedMRR: number // Cancellations
// Customers
totalCustomers: number
newCustomers: number
churnRate: number // % of customers who cancel
// Engagement
dau: number // Daily Active Users
mau: number // Monthly Active Users
dauToMau: number // Stickiness ratio
}Customer Lifecycle
1. Visitor → Trial Signup
2. Trial User → Convert to Paid
3. Paid User → Expand (upgrade tier)
4. Paid User → Renew (continue subscription)
5. Paid User → Churn (cancel)Revenue Recognition
interface Subscription {
customer: string | Customer
product: string | Product
price: string | Price
status: 'active' | 'past_due' | 'canceled' | 'trialing'
currentPeriodStart: Date
currentPeriodEnd: Date
mrr: number // Normalized to monthly
arr: number // Annual run rate
}Rendering Examples
As Full Application
// Complete SaaS application
<ProductApp product={saasProduct}>
<Shell>
<Sidebar />
<DashboardPage />
</Shell>
</ProductApp>As Marketing Site
// Marketing site for the SaaS
<ProductSite product={saasProduct}>
<LandingPage>
<Hero />
<Features />
<Pricing />
</LandingPage>
</ProductSite>As Product Card
// Card in a product directory
<ProductCard product={saasProduct}>
<ProductLogo />
<ProductName />
<ProductDescription />
<ProductPricing />
<CTAButton />
</ProductCard>Integration Points
Stripe Integration
interface SaaSProduct {
stripeProductId: string // prod_...
prices: Array<{
stripePriceId: string // price_...
amount: number
interval: 'month' | 'year'
}>
}
// Auto-sync with Stripe
await stripe.products.create({
name: saasProduct.name,
description: saasProduct.description,
})Payload CMS
// Products collection
const saasProducts = await payload.find({
collection: 'products',
where: {
type: { equals: 'SaaS' },
isActive: { equals: true },
},
})
// Subscriptions collection
const activeSubscriptions = await payload.find({
collection: 'subscriptions',
where: {
product: { equals: saasProduct.id },
status: { equals: 'active' },
},
})Analytics
// Track SaaS metrics
interface SaaSAnalytics {
trackSignup(user: User): void
trackActivation(user: User): void
trackUpgrade(subscription: Subscription): void
trackChurn(subscription: Subscription): void
getMRR(): number
getChurnRate(): number
getLTV(): number // Lifetime Value
}Examples
Project Management SaaS
name: TaskFlow
type: SaaS
description: Modern project management for distributed teams
interfaces:
- Web application
- Mobile app (iOS/Android)
- REST API
- Slack integration
pricing:
- Free: $0/month (up to 3 users)
- Starter: $19/month (up to 10 users)
- Pro: $49/month (unlimited users)
- Enterprise: Custom pricing
features:
- Task boards & lists
- Team collaboration
- File attachments
- Time tracking
- Reporting & analyticsCRM SaaS
name: SalesPilot
type: SaaS
description: AI-powered CRM for modern sales teams
interfaces:
- Web application
- Browser extension
- REST API
- Native integrations (email, calendar)
pricing:
- Professional: $49/user/month
- Business: $99/user/month
- Enterprise: $199/user/month
features:
- Contact management
- Deal pipeline
- Email sequences
- AI lead scoring
- Forecasting
- Custom fields & workflowsAnalytics SaaS
name: DataPulse
type: SaaS
description: Real-time analytics and business intelligence
interfaces:
- Web dashboard
- REST API
- JavaScript SDK
- SQL interface
pricing:
- Starter: $99/month (100k events)
- Growth: $299/month (1M events)
- Scale: $999/month (10M events)
- Enterprise: Custom (unlimited)
features:
- Event tracking
- Custom dashboards
- Funnels & retention
- Cohort analysis
- Data warehouse exportExample Configurations
Basic SaaS Product
import type { SaaSProductProps } from 'mdxui'
const projectManagementSaaS: SaaSProductProps = {
$type: 'SaaS',
$id: 'https://taskflow.com',
name: 'TaskFlow',
domain: 'taskflow.com',
description: 'Modern project management for distributed teams',
category: 'Project Management',
// Deployment
deployment: 'cloud',
targetUser: 'team',
// Free tier and trial
freeTier: true,
trialDays: 14,
// Pricing
pricingModel: 'tiered',
tiers: [
{
name: 'Free',
price: 0,
currency: 'USD',
features: [
'Up to 3 users',
'10 projects',
'Basic task management',
'Mobile app access'
],
limits: {
seats: 3,
projects: 10,
storage: 1 // GB
}
},
{
name: 'Starter',
price: 19,
annualPrice: 190,
currency: 'USD',
features: [
'Up to 10 users',
'Unlimited projects',
'File attachments',
'Time tracking',
'Basic reporting'
],
limits: {
seats: 10,
storage: 50 // GB
},
popular: true
},
{
name: 'Pro',
price: 49,
annualPrice: 490,
currency: 'USD',
features: [
'Unlimited users',
'Advanced analytics',
'API access',
'Custom fields',
'Automations',
'Priority support'
],
limits: {
storage: 250 // GB
}
},
{
name: 'Enterprise',
price: 199,
currency: 'USD',
features: [
'Everything in Pro',
'SSO / SAML',
'Advanced security',
'Audit logs',
'Dedicated support',
'SLA guarantee'
],
enterprise: true
}
],
// Features
features: [
{
name: 'Task Boards',
description: 'Visual kanban boards for task management',
category: 'Core'
},
{
name: 'Time Tracking',
description: 'Track time spent on tasks and projects',
category: 'Productivity'
},
{
name: 'Team Collaboration',
description: 'Comments, mentions, and real-time updates',
category: 'Collaboration'
},
{
name: 'Custom Workflows',
description: 'Create custom task workflows',
category: 'Advanced',
new: true
}
],
// API
api: {
enabled: true,
type: 'rest',
documentation: 'https://taskflow.com/docs/api',
rateLimit: 1000,
webhooks: true
},
// Security
security: {
sso: true,
mfa: true,
soc2: true,
gdpr: true,
encryption: 'both'
},
// Support
support: {
channels: ['email', 'chat'],
onboarding: true
}
}Enterprise SaaS with Advanced Features
const enterpriseCRM: SaaSProductProps = {
$type: 'SaaS',
$id: 'https://salesforce.example.com',
name: 'Enterprise CRM',
domain: 'salesforce.example.com',
description: 'AI-powered CRM for enterprise sales teams',
category: 'Customer Relationship Management',
deployment: 'hybrid',
targetUser: 'enterprise',
// No free tier for enterprise
freeTier: false,
trialDays: 30,
pricingModel: 'per_seat',
tiers: [
{
name: 'Professional',
price: 75,
currency: 'USD',
features: [
'Unlimited contacts',
'Sales pipeline management',
'Email integration',
'Mobile app',
'Basic reporting'
],
limits: {
apiRequests: 10000
}
},
{
name: 'Enterprise',
price: 150,
currency: 'USD',
features: [
'Everything in Professional',
'Advanced AI features',
'Custom objects',
'Workflow automation',
'Advanced analytics',
'API access',
'Priority support'
],
limits: {
apiRequests: 100000
},
popular: true
},
{
name: 'Unlimited',
price: 300,
currency: 'USD',
features: [
'Everything in Enterprise',
'Unlimited API calls',
'SSO / SAML',
'Advanced security',
'Dedicated success manager',
'99.99% SLA'
],
enterprise: true
}
],
features: [
{
name: 'AI Lead Scoring',
description: 'Machine learning-powered lead prioritization',
category: 'AI',
new: true
},
{
name: 'Sales Forecasting',
description: 'Predictive revenue forecasting',
category: 'Analytics'
},
{
name: 'Custom Objects',
description: 'Extend the data model with custom objects',
category: 'Customization'
},
{
name: 'Territory Management',
description: 'Manage sales territories and assignments',
category: 'Enterprise'
}
],
api: {
enabled: true,
type: 'both',
documentation: 'https://salesforce.example.com/api',
rateLimit: 5000,
webhooks: true
},
integrations: [
{
name: 'Salesforce',
native: true,
category: 'CRM'
},
{
name: 'HubSpot',
native: true,
category: 'Marketing'
},
{
name: 'Slack',
native: true,
category: 'Communication'
},
{
name: 'Gmail',
native: true,
category: 'Email'
},
{
name: 'Zapier',
zapier: true,
category: 'Automation'
}
],
security: {
sso: true,
mfa: true,
soc2: true,
gdpr: true,
hipaa: true,
encryption: 'e2e'
},
support: {
channels: ['email', 'chat', 'phone'],
sla: '4 hours for critical issues',
dedicatedSuccess: true,
onboarding: true
}
}Usage-Based SaaS
const analyticsService: SaaSProductProps = {
$type: 'SaaS',
$id: 'https://datalytics.com',
name: 'DataLytics',
domain: 'datalytics.com',
description: 'Real-time analytics and business intelligence',
category: 'Analytics',
deployment: 'cloud',
targetUser: 'business',
freeTier: true,
trialDays: 14,
// Usage-based pricing
pricingModel: 'usage',
tiers: [
{
name: 'Free',
price: 0,
currency: 'USD',
features: [
'10,000 events/month',
'Basic dashboards',
'7-day data retention'
],
limits: {
events: 10000,
retention: 7
}
},
{
name: 'Starter',
price: 99,
currency: 'USD',
features: [
'100,000 events/month included',
'Custom dashboards',
'90-day data retention',
'Email reports',
'$0.001 per additional event'
],
limits: {
events: 100000,
retention: 90
},
popular: true
},
{
name: 'Growth',
price: 299,
currency: 'USD',
features: [
'1M events/month included',
'Advanced analytics',
'1-year data retention',
'API access',
'Slack integration',
'$0.0005 per additional event'
],
limits: {
events: 1000000,
retention: 365
}
},
{
name: 'Enterprise',
price: 999,
currency: 'USD',
features: [
'10M events/month included',
'Unlimited data retention',
'White-label dashboards',
'Custom integrations',
'Dedicated infrastructure',
'$0.0001 per additional event'
],
enterprise: true
}
],
features: [
{
name: 'Event Tracking',
description: 'Track custom events and user actions',
category: 'Core'
},
{
name: 'Funnel Analysis',
description: 'Visualize conversion funnels',
category: 'Analytics'
},
{
name: 'Cohort Analysis',
description: 'Analyze user cohorts over time',
category: 'Analytics'
},
{
name: 'Data Warehouse Export',
description: 'Export data to your warehouse',
category: 'Enterprise',
beta: true
}
],
api: {
enabled: true,
type: 'both',
documentation: 'https://datalytics.com/docs',
rateLimit: 10000,
webhooks: true
},
integrations: [
{
name: 'Segment',
native: true,
category: 'Data'
},
{
name: 'Google Analytics',
native: true,
category: 'Analytics'
},
{
name: 'Snowflake',
native: true,
category: 'Data Warehouse'
}
],
security: {
sso: true,
mfa: true,
soc2: true,
gdpr: true,
encryption: 'both'
},
support: {
channels: ['email', 'chat'],
onboarding: true
}
}Multi-Workspace SaaS Configuration
// Workspace configuration for multi-tenant SaaS
interface WorkspaceConfig {
workspace: Workspace
subscription: Subscription
features: FeatureFlags
usage: UsageLimits
}
const workspaceConfig: WorkspaceConfig = {
workspace: {
id: 'ws_acme',
name: 'Acme Corporation',
slug: 'acme-corp',
ownerId: 'user_123',
plan: 'pro',
settings: {
logo: 'https://acme.com/logo.png',
primaryColor: '#3B82F6',
features: {
apiAccess: true,
sso: false,
customDomain: true,
auditLogs: true
},
limits: {
seats: 50,
storage: 250,
apiRequests: 100000
},
usage: {
seats: 32,
storage: 127,
apiRequests: 45230
}
},
createdAt: new Date('2024-01-15'),
updatedAt: new Date('2024-12-19')
},
subscription: {
id: 'sub_123',
stripeSubscriptionId: 'sub_1ABC...',
plan: 'pro',
status: 'active',
currentPeriodStart: new Date('2024-12-01'),
currentPeriodEnd: new Date('2025-01-01'),
cancelAtPeriodEnd: false,
trialEnd: null,
items: [
{
priceId: 'price_pro_monthly',
quantity: 32, // seats
amount: 1568 // $49 * 32
}
]
},
features: {
api_access: true,
sso: false,
custom_domain: true,
audit_logs: true,
advanced_analytics: true,
custom_roles: true,
white_label: false
},
usage: {
seats: {
current: 32,
limit: 50,
percentage: 64
},
storage: {
current: 127,
limit: 250,
unit: 'GB',
percentage: 50.8
},
apiRequests: {
current: 45230,
limit: 100000,
period: 'month',
percentage: 45.2
}
}
}Next Steps
- Product Schema - Product type definition
- API Products - Usage-based API products
- REST APIs - API interface documentation
- SDKs - Client libraries for SaaS products