.do
Use Cases

SaaS Business

Build autonomous subscription businesses with Business-as-Code

Build a complete subscription SaaS business with autonomous operations.

Overview

A SaaS business built with Business-as-Code handles:

  • User onboarding and provisioning
  • Subscription lifecycle management
  • Usage tracking and limits
  • Billing and renewals
  • Feature access control
  • Churn prevention
  • Expansion revenue

Core Implementation

1. Business Setup

// @errors: 7006
// @filename: sdk.do.d.ts
declare const $: any
declare const db: any
declare const ai: any
declare function on(event: any, handler: Function): any
declare function send(event: any, data: any): Promise<void>
declare function addDays(date: Date, days: number): Date

// @filename: example.ts
// ---cut---
import $, { db, on, send, ai } from 'sdk.do'

// Define SaaS application with Schema.org types
const saas = await $.SoftwareApplication.create({
  //                    ^^^^^^^^^^^^^^^^^^^^^
  $type: 'SoftwareApplication',
  name: 'TaskFlow Pro',
  applicationCategory: 'ProductivityApplication',
  offers: [
    {
      $type: 'Offer',
      name: 'Starter',
      price: 0,
      //    ^^^^^
      priceCurrency: 'USD',
      features: ['10-tasks', 'basic-reports'],
    },
    {
      $type: 'Offer',
      name: 'Pro',
      price: 29,
      priceCurrency: 'USD',
      billingIncrement: 'monthly',
      features: ['unlimited-tasks', 'advanced-reports', 'api-access'],
      //              ^^^^^^^^^^^^^^^^^^
    },
    {
      $type: 'Offer',
      name: 'Enterprise',
      price: 99,
      priceCurrency: 'USD',
      billingIncrement: 'monthly',
      features: ['all-pro', 'sso', 'priority-support', 'custom-integrations'],
    },
  ],
})

2. User Registration & Onboarding

// @errors: 7006
// @filename: sdk.do.d.ts
declare const $: any
declare const ai: any
declare const saas: any
declare function on(event: any, handler: Function): any
declare function send(event: any, data: any): Promise<void>
declare function addDays(date: Date, days: number): Date

// @filename: example.ts
// ---cut---
import { $, ai, on, send } from 'sdk.do'

on($.Person.registered, async (person) => {
  // ^^
  // Create 14-day trial subscription
  const subscription = await $.Service.create({
    //                            ^?
    $type: 'Service',
    provider: saas,
    customer: person,
    plan: saas.offers[0], // Free plan
    status: 'trialing',
    startDate: new Date(),
    trialEnd: addDays(new Date(), 14),
  })

  // Provision account with plan features
  await send($.Account.provision, {
    //           ^^^^^^^^^^^^^^^^^^^^
    user: person,
    subscription,
    features: subscription.plan.features,
  })

  // AI generates personalized onboarding plan
  const onboarding = await ai.generate('onboarding-plan', {
    //              ^?
    user: person,
    product: saas,
    persona: await ai.analyze('user-persona', { person }),
  })

  // Create onboarding tasks dynamically
  for (const task of onboarding.tasks) {
    await $.Action.create({
      $type: 'Action',
      name: task.name,
      description: task.description,
      agent: person,
      actionStatus: 'PotentialActionStatus',
    })
  }

  // Schedule email sequence
  await send($.Email.schedule, {
    to: person.email,
    template: 'onboarding-day-1',
    sendAt: addDays(new Date(), 1),
  })

  await send($.Email.schedule, {
    to: person.email,
    template: 'onboarding-day-3',
    sendAt: addDays(new Date(), 3),
  })

  await send($.Subscription.created, subscription)
})

3. Subscription Management

// Subscription upgrade
on($.Subscription.upgrade, async ({ subscription, newPlan }) => {
  const oldPlan = subscription.plan

  // Update subscription
  await db.update($.Service, subscription.$id, {
    plan: newPlan,
    upgradedAt: new Date(),
    status: 'active',
  })

  // Provision new features
  await send($.Account.updateFeatures, {
    user: subscription.customer,
    addFeatures: newPlan.features.filter((f) => !oldPlan.features.includes(f)),
  })

  // Process prorated payment
  const prorated = calculateProration(subscription, oldPlan, newPlan)
  await send($.Payment.process, {
    customer: subscription.customer,
    amount: prorated.amount,
    description: `Upgrade to ${newPlan.name}`,
  })

  // Send confirmation
  await send($.Email.send, {
    to: subscription.customer.email,
    template: 'subscription-upgraded',
    data: { subscription, oldPlan, newPlan },
  })
})

// Subscription cancellation
on($.Subscription.cancel, async ({ subscription, reason }) => {
  // Update status
  await db.update($.Service, subscription.$id, {
    status: 'cancelled',
    cancelledAt: new Date(),
    cancelReason: reason,
    endDate: subscription.currentPeriodEnd, // End at period end
  })

  // Schedule feature removal at period end
  await send($.Task.schedule, {
    action: async () => {
      await send($.Account.deprovision, {
        user: subscription.customer,
      })
    },
    runAt: subscription.currentPeriodEnd,
  })

  // AI-powered retention attempt
  const retention = await ai.decide('retention-offer', {
    subscription,
    customer: subscription.customer,
    cancelReason: reason,
    history: await db.related(subscription.customer, $.subscribed, $.Service),
  })

  if (retention.shouldOffer) {
    await send($.Offer.send, {
      customer: subscription.customer,
      offer: retention.offer,
      expires: addDays(new Date(), 7),
    })
  }

  await send($.Email.send, {
    to: subscription.customer.email,
    template: 'subscription-cancelled',
    data: { subscription, endDate: subscription.endDate },
  })
})

4. Usage Tracking & Limits

// Track feature usage
on($.Feature.used, async (event) => {
  const { customer, feature, metadata } = event

  // Increment usage
  const usage = await db.increment(customer, $.usage[feature])

  // Get subscription and limits
  const subscription = await db.related(customer, $.subscribes, $.Service).then((subs) => subs.find((s) => s.status === 'active'))

  const limit = subscription.plan.limits[feature]

  // Check if approaching limit
  if (usage > limit * 0.8) {
    // 80% of limit reached
    await send($.Notification.send, {
      to: customer,
      type: 'usage-warning',
      message: `You've used ${usage}/${limit} of your ${feature} quota`,
      cta: {
        text: 'Upgrade Plan',
        action: $.Subscription.upgrade,
      },
    })
  } else if (usage >= limit) {
    // Limit reached
    await send($.Feature.limitReached, {
      customer,
      feature,
      usage,
      limit,
    })

    await send($.Notification.send, {
      to: customer,
      type: 'limit-reached',
      message: `You've reached your ${feature} limit. Upgrade to continue.`,
      priority: 'high',
    })
  }

  // Log usage for analytics
  await db.create($.UsageEvent, {
    customer: customer.$id,
    feature,
    timestamp: new Date(),
    metadata,
  })
})

5. Billing & Renewals

// Automatic subscription renewal
setInterval(async () => {
  const due = await db.list($.Service, {
    where: {
      nextBillingDate: { $lte: new Date() },
      status: 'active',
    },
  })

  for (const subscription of due) {
    try {
      // Process payment
      const payment = await send($.Payment.process, {
        customer: subscription.customer,
        amount: subscription.plan.price,
        currency: subscription.plan.priceCurrency,
        description: `${subscription.plan.name} renewal`,
      })

      if (payment.status === 'succeeded') {
        // Update subscription period
        await db.update($.Service, subscription.$id, {
          currentPeriodStart: new Date(),
          currentPeriodEnd: addMonths(new Date(), 1),
          nextBillingDate: addMonths(new Date(), 1),
          lastPaymentDate: new Date(),
        })

        // Send receipt
        await send($.Email.send, {
          to: subscription.customer.email,
          template: 'payment-receipt',
          data: { subscription, payment },
        })
      } else {
        // Payment failed
        await send($.Subscription.paymentFailed, {
          subscription,
          error: payment.error,
        })
      }
    } catch (error) {
      console.error(`Renewal failed for ${subscription.$id}:`, error)
    }
  }
}, 3600000) // Check hourly

// Handle payment failures
on($.Subscription.paymentFailed, async ({ subscription, error }) => {
  // Update subscription
  await db.update($.Service, subscription.$id, {
    status: 'past_due',
    paymentFailedAt: new Date(),
  })

  // Send dunning email
  await send($.Email.send, {
    to: subscription.customer.email,
    template: 'payment-failed',
    data: { subscription, error },
  })

  // Schedule retries
  const retrySchedule = [1, 3, 7] // Days
  for (const days of retrySchedule) {
    await send($.Payment.retry, {
      subscription,
      retryAt: addDays(new Date(), days),
    })
  }

  // If all retries fail after 7 days, cancel
  await send($.Task.schedule, {
    action: async () => {
      const current = await db.get($.Service, subscription.$id)
      if (current.status === 'past_due') {
        await send($.Subscription.cancel, {
          subscription: current,
          reason: 'payment-failure',
        })
      }
    },
    runAt: addDays(new Date(), 8),
  })
})

6. Churn Prevention

// @errors: 7006
// @filename: sdk.do.d.ts
declare const $: any
declare const db: any
declare const ai: any
declare function send(event: any, data: any): Promise<void>

// @filename: example.ts
// ---cut---
import { $, db, ai, send } from 'sdk.do'

// AI-driven proactive churn prevention
setInterval(async () => {
  const subscriptions = await db.list($.Service, {
    where: { status: { $in: ['active', 'trialing'] } },
  })

  for (const sub of subscriptions) {
    // AI analyzes churn risk from multiple signals
    const risk = await ai.analyze('churn-risk', {
      //              ^?
      subscription: sub,
      customer: sub.customer,
      usage: await db.analyze('usage-metrics', {
        //                   ^^^^^^^^^^^^^^^^^^^^^^^^^^
        customer: sub.customer,
        timeRange: '30d',
      }),
      engagement: await db.analyze('engagement-score', {
        customer: sub.customer,
      }),
      support: await db.related(sub.customer, $.submitted, $.SupportTicket),
    })

    if (risk.score > 0.7) {
      //            ^^^^^
      // High churn risk - AI decides intervention strategy
      const intervention = await ai.decide('churn-prevention', {
        //                               ^^^^^^^^^
        customer: sub.customer,
        risk,
        subscription: sub,
      })

      // Execute intervention based on AI recommendation
      if (intervention.action === 'offer-discount') {
        await send($.Offer.send, {
          customer: sub.customer,
          offer: intervention.offer,
          message: intervention.message,
        })
      } else if (intervention.action === 'schedule-call') {
        await send($.Meeting.schedule, {
          customer: sub.customer,
          type: 'success-call',
          agent: intervention.assignedAgent,
        })
      } else if (intervention.action === 'feature-training') {
        await send($.Email.send, {
          to: sub.customer.email,
          template: 'feature-training',
          data: { features: intervention.suggestedFeatures },
        })
      }

      // Escalate high-value customers to human team
      if (sub.customer.lifetimeValue > 5000 && risk.score > 0.8) {
        await send($.Notification.send, {
          to: $.Role.CustomerSuccess,
          //            ^^^^^^^^^^^^^^^^^^^^^^
          priority: 'urgent',
          message: `High-value customer at risk: ${sub.customer.name}`,
          data: { customer: sub.customer, risk },
        })
      }
    }
  }
}, 86400000) // Daily

7. Feature Adoption

// Track feature usage and drive adoption
on($.Feature.released, async (feature) => {
  // Find ideal users for this feature
  const targets = await ai.recommend({
    type: $.Person,
    for: feature,
    strategy: 'ideal-users',
    limit: 100,
  })

  for (const customer of targets) {
    // Personalized feature announcement
    const announcement = await ai.generate('feature-announcement', {
      feature,
      customer,
      personalization: await ai.analyze('customer-needs', { customer }),
    })

    await send($.Email.send, {
      to: customer.email,
      subject: announcement.subject,
      body: announcement.content,
      cta: announcement.cta,
    })
  }
})

// In-app feature discovery
on($.User.login, async (user) => {
  // Check for unused features
  const subscription = await db.related(user, $.subscribes, $.Service).then((subs) => subs.find((s) => s.status === 'active'))

  const unusedFeatures = subscription.plan.features.filter((f) => {
    return !user.usedFeatures?.includes(f)
  })

  if (unusedFeatures.length > 0) {
    // Suggest feature to try
    const suggestion = await ai.recommend({
      type: $.Feature,
      for: user,
      from: unusedFeatures,
      strategy: 'highest-value',
      limit: 1,
    })

    await send($.UI.showFeatureTip, {
      user,
      feature: suggestion[0],
    })
  }
})

8. Analytics & Metrics

// Track key SaaS metrics
async function calculateMetrics() {
  const metrics = {
    // MRR (Monthly Recurring Revenue)
    mrr: await db.aggregate($.Service, {
      where: { status: 'active' },
      aggregations: {
        total: { $sum: 'plan.price' },
      },
    }),

    // Churn rate
    churn: await db.analyze('churn-rate', {
      timeRange: '30d',
    }),

    // LTV (Lifetime Value)
    ltv: await db.analyze('customer-ltv', {
      segmentBy: 'plan',
    }),

    // CAC (Customer Acquisition Cost)
    cac: await db.analyze('acquisition-cost', {
      timeRange: '30d',
    }),
  }

  return metrics
}

// Daily metrics reporting
setInterval(async () => {
  const metrics = await calculateMetrics()

  await db.create($.MetricsSnapshot, {
    date: new Date(),
    ...metrics,
  })

  // Alert on anomalies
  if (metrics.churn.rate > 0.05) {
    // 5% monthly churn
    await send($.Alert.send, {
      type: 'high-churn',
      severity: 'high',
      data: metrics.churn,
    })
  }
}, 86400000) // Daily

Complete Example

See full working code at:

Key Takeaways

  1. Automate Onboarding: AI-personalized user journeys
  2. Track Everything: Usage, engagement, metrics
  3. Prevent Churn: Proactive AI intervention
  4. Optimize Pricing: Test and iterate
  5. Drive Adoption: Feature discovery and training

Next: Marketplace →