.do
Fundamentals

Core Concepts

Essential concepts for Business-as-Code development

Understanding these core concepts is essential for mastering Business-as-Code.

The Five Pillars

Every business built with Business-as-Code is composed of five fundamental elements:

graph TB E[Entities<br/>What exists] R[Relationships<br/>How things connect] EV[Events<br/>What happens] W[Workflows<br/>How to respond] D[Decisions<br/>What to choose] E -->|connected by| R R -->|trigger| EV EV -->|initiate| W W -->|require| D D -->|modify| E

1. Entities: What Exists

Entities are the things in your business domain. They use semantic types from Schema.org, O*NET, and other vocabularies.

// Core entity types
$.Person // People (customers, employees, users)
$.Organization // Companies, businesses
$.Product // Physical or digital products
$.Service // Services offered
$.Order // Purchase orders
$.Event // Events and happenings
$.Place // Physical locations
$.CreativeWork // Content, documents

// Create entities
const customer = await $.Person.create({
  $type: 'Person',
  givenName: 'Alice',
  familyName: 'Johnson',
  email: '[email protected]',
})

const business = await $.Organization.create({
  $type: 'Organization',
  name: 'Acme Corp',
  legalName: 'Acme Corporation LLC',
})

Key principles:

  • Entities are semantic (they mean something)
  • Use standard vocabularies first
  • Extend when necessary
  • Every entity has a unique $id
  • Entities carry their $type

2. Relationships: How Things Connect

Relationships express how entities relate to each other using semantic predicates.

// Relationship patterns
$.Customer.places.Order
$.Order.contains.Product
$.Organization.employs.Person
$.Person.worksFor.Organization
$.Product.manufacturedBy.Organization

// Create relationships
await db.relate(customer, $.places, order)
await db.relate(order, $.contains, product)
await db.relate(employee, $.worksFor, company)

// Query relationships
const orders = await db.related(customer, $.places, $.Order)
const products = await db.related(order, $.contains, $.Product)
const employer = await db.related(employee, $.worksFor, $.Organization)

Relationship characteristics:

  • Bidirectional (every relationship has an inverse)
  • Semantic (AI understands meaning)
  • Queryable (navigate the graph)
  • Type-safe (TypeScript enforced)

3. Events: What Happens

Events represent state changes and triggers for business logic. They use past-tense verbs.

// Common event patterns
$.Order.created
$.Payment.processed
$.Shipment.delivered
$.Customer.registered
$.Subscription.cancelled
$.Product.outOfStock
$.Invoice.sent

// Listen for events
on($.Order.created, async (order) => {
  console.log('New order:', order.orderNumber)
  // Handle the event
})

// Emit events
await send($.Order.created, {
  $type: 'Order',
  orderNumber: 'ORD-001',
  customer: customer.$id,
  totalPrice: 99.99,
})

Event characteristics:

  • Asynchronous by default
  • Can trigger multiple handlers
  • Can cascade (event triggers event)
  • Carry semantic data
  • Enable decoupled systems

4. Workflows: How to Respond

Workflows are sequences of operations triggered by events.

// Order fulfillment workflow
on($.Order.created, async (order) => {
  // Step 1: Validate inventory
  const available = await db.checkInventory(order.orderedItem)

  if (!available) {
    await send($.Order.cancel, {
      order,
      reason: 'out-of-stock',
    })
    return
  }

  // Step 2: Process payment
  const payment = await send($.Payment.process, {
    order,
    amount: order.totalPrice,
  })

  // Step 3: Update inventory
  if (payment.status === 'succeeded') {
    for (const item of order.orderedItem) {
      await db.decrement($.Product, item.orderItem, {
        inventory: item.orderQuantity,
      })
    }

    // Step 4: Send confirmation
    await send($.Email.send, {
      to: order.customer.email,
      template: 'order-confirmation',
      data: { order, payment },
    })

    // Step 5: Trigger fulfillment
    await send($.Order.fulfill, { order })
  }
})

// Fulfillment creates shipment
on($.Order.fulfilled, async (order) => {
  const shipment = await $.Shipment.create({
    $type: 'ParcelDelivery',
    order: order.$id,
    trackingNumber: generateTrackingNumber(),
    expectedDelivery: addDays(new Date(), 3),
  })

  await send($.Shipment.created, shipment)
})

// Shipment notifications
on($.Shipment.created, async (shipment) => {
  await send($.Email.send, {
    to: shipment.order.customer.email,
    template: 'shipment-notification',
    data: { shipment },
  })
})

Workflow patterns:

  • Event-driven (triggered by events)
  • Composable (workflows can call workflows)
  • Error-handling (try/catch, compensating actions)
  • Parallel execution (Promise.all)
  • Sequential chains (event cascades)

5. Decisions: What to Choose

Decisions are logic points where the business chooses between options, often powered by AI.

// Manual decision logic
on($.Order.created, async (order) => {
  // Decide shipping method based on value
  let shippingMethod

  if (order.totalPrice > 100) {
    shippingMethod = 'express'
  } else if (order.customer.membershipLevel === 'premium') {
    shippingMethod = 'priority'
  } else {
    shippingMethod = 'standard'
  }

  await send($.Shipment.create, {
    order,
    method: shippingMethod,
  })
})

// AI-powered decisions
on($.Product.needsRestock, async (product) => {
  // AI decides reorder quantity
  const decision = await ai.decide('inventory-reorder', {
    product,
    salesHistory: await db.analyze($.Order, {
      product,
      timeRange: '90d',
    }),
    seasonality: await db.analyze('seasonal-trends', {
      product,
      category: product.category,
    }),
    supplier: await db.related(product, $.suppliedBy, $.Organization),
  })

  if (decision.shouldReorder) {
    await send($.PurchaseOrder.create, {
      product,
      quantity: decision.recommendedQuantity,
      supplier: decision.preferredSupplier,
      urgency: decision.urgency,
    })
  }
})

// A/B testing decisions
on($.Customer.visits, async (customer) => {
  // Decide which variant to show
  const variant = await ai.decide('ab-test', {
    test: 'homepage-v2',
    customer,
    segmentation: customer.segment,
  })

  await send($.UI.render, {
    customer,
    variant: variant.selected,
    tracking: variant.trackingId,
  })
})

Decision characteristics:

  • Rule-based or AI-powered
  • Context-aware
  • Auditable (track decisions made)
  • Optimizable (improve over time)
  • Explainable (why this decision?)

The Semantic Graph

All entities and relationships form a knowledge graph:

graph LR C[Customer<br/>Alice] O1[Order<br/>ORD-001] O2[Order<br/>ORD-002] P1[Product<br/>Mouse] P2[Product<br/>Keyboard] B[Brand<br/>TechCo] M[Organization<br/>TechCo Inc] C -->|places| O1 C -->|places| O2 O1 -->|contains| P1 O2 -->|contains| P2 O2 -->|contains| P1 P1 -->|brand| B P2 -->|brand| B P1 -->|manufacturer| M P2 -->|manufacturer| M B -->|owner| M

Graph Queries

Navigate the graph semantically:

// Direct relationships
const orders = await db.related(customer, $.places, $.Order)

// Multi-hop queries
const manufacturers = await db.query({
  start: customer,
  path: $.places.Order.contains.Product.manufacturer.Organization,
})

// Traverse with filters
const recentOrders = await db.related(customer, $.places, $.Order, {
  where: {
    orderDate: { $gte: subDays(new Date(), 30) },
  },
})

// Aggregate queries
const totalSpent = await db.aggregate(customer, {
  relationship: $.places,
  type: $.Order,
  operation: 'sum',
  field: 'totalPrice',
})

Data Flow

Understanding how data flows through a Business-as-Code application:

sequenceDiagram participant U as User/System participant E as Event System participant W as Workflow participant AI as AI Engine participant DB as Database participant EXT as External Service U->>E: Trigger Event<br/>($.Order.created) E->>W: Invoke Handlers W->>DB: Query Data<br/>(customer, products) DB-->>W: Return Data W->>AI: Request Decision<br/>(shipping method) AI-->>W: Return Decision W->>EXT: Call Service<br/>(payment API) EXT-->>W: Response W->>DB: Update State<br/>(order status) W->>E: Emit Event<br/>($.Payment.processed) E->>W: Trigger Next Handler W->>EXT: Send Email W-->>U: Complete

Event Cascades

Events can trigger other events, creating workflows:

// Initial event
await send($.Order.created, order)

// Triggers workflow
on($.Order.created, async (order) => {
  const payment = await send($.Payment.process, { order })
  // Emits $.Payment.processed
})

// Which triggers next workflow
on($.Payment.processed, async (payment) => {
  await send($.Order.fulfill, { order: payment.order })
  // Emits $.Order.fulfilled
})

// Which triggers fulfillment
on($.Order.fulfilled, async (order) => {
  await send($.Shipment.create, { order })
  // Emits $.Shipment.created
})

// And so on...
on($.Shipment.created, async (shipment) => {
  await send($.Email.send, {
    /* notification */
  })
})

State Management

Business-as-Code uses event sourcing principles:

// State is derived from events
const order = {
  $id: 'order-001',
  status: 'created', // Initial state
  events: [],
}

// Events change state
on($.Order.created, async (order) => {
  await db.update($.Order, order.$id, {
    status: 'processing',
    events: [...order.events, { type: 'created', timestamp: new Date() }],
  })
})

on($.Payment.processed, async (payment) => {
  await db.update($.Order, payment.order.$id, {
    status: 'paid',
    events: [...order.events, { type: 'paid', timestamp: new Date() }],
  })
})

// Query current state
const order = await db.get($.Order, orderId)
console.log(order.status) // Current state

// Replay events to reconstruct state
const history = order.events.map((e) => ({
  type: e.type,
  timestamp: e.timestamp,
}))

Error Handling

Graceful error handling in workflows:

on($.Order.created, async (order) => {
  try {
    // Attempt payment
    const payment = await send($.Payment.process, {
      order,
      amount: order.totalPrice,
    })

    if (payment.status === 'succeeded') {
      await send($.Order.fulfill, { order })
    } else {
      throw new Error('Payment failed')
    }
  } catch (error) {
    // Compensating action
    await send($.Order.cancel, {
      order,
      reason: 'payment-error',
      error: error.message,
    })

    // Notify customer
    await send($.Email.send, {
      to: order.customer.email,
      template: 'order-failed',
      data: { order, error },
    })

    // Log for analysis
    await db.create($.ErrorLog, {
      type: 'payment-failure',
      order: order.$id,
      error: error.message,
      timestamp: new Date(),
    })
  }
})

Testing Concepts

Test business logic semantically:

import { test, expect } from 'vitest'
import $, { db, on, send } from 'sdk.do'

test('order fulfillment workflow', async () => {
  // Setup
  const customer = await $.Person.create({
    name: 'Test Customer',
    email: '[email protected]',
  })

  const product = await $.Product.create({
    name: 'Test Product',
    inventory: 10,
  })

  // Create order
  const order = await $.Order.create({
    customer,
    orderedItem: [
      {
        orderItem: product,
        orderQuantity: 2,
      },
    ],
    totalPrice: 99.99,
  })

  // Emit event
  await send($.Order.created, order)

  // Wait for workflow
  await waitFor(async () => {
    const updatedProduct = await db.get($.Product, product.$id)
    expect(updatedProduct.inventory).toBe(8)
  })

  // Check order status
  const updatedOrder = await db.get($.Order, order.$id)
  expect(updatedOrder.status).toBe('fulfilled')
})

Best Practices

1. Entity Design

// Good: Rich semantic entities
const customer = await $.Person.create({
  $type: 'Person',
  givenName: 'Alice',
  familyName: 'Johnson',
  email: '[email protected]',
  telephone: '+1-555-0100',
  address: {
    $type: 'PostalAddress',
    streetAddress: '123 Main St',
    addressLocality: 'Austin',
    addressRegion: 'TX',
    postalCode: '78701',
  },
  membershipLevel: 'premium',
  joinDate: new Date(),
})

// Avoid: Minimal data
const user = { name: 'Alice', email: '[email protected]' }

2. Event Naming

// Good: Past tense, specific
$.Order.created
$.Payment.processed
$.Shipment.delivered
$.Customer.registered

// Avoid: Present tense or vague
$.Order.create
$.Payment.process
$.Shipment.deliver
$.Customer.signup

3. Workflow Organization

// Good: Single responsibility
on($.Order.created, handleOrderCreation)
on($.Payment.processed, handlePaymentProcessed)
on($.Order.fulfilled, handleOrderFulfilled)

// Avoid: God workflows
on($.Order.created, async (order) => {
  // 500 lines of code handling everything
})

4. Decision Documentation

// Good: Document decision logic
on($.Product.needsRestock, async (product) => {
  const decision = await ai.decide('inventory-reorder', {
    product,
    // Document what data AI uses
    salesHistory: await db.analyze($.Order, { product, timeRange: '90d' }),
    seasonality: await db.analyze('seasonal-trends', { product }),
    leadTime: product.supplier.leadTime,
    targetStockLevel: product.reorderPoint * 2,
  })

  // Document why this threshold
  if (decision.confidence > 0.8) {
    await send($.PurchaseOrder.create, {
      product,
      quantity: decision.recommendedQuantity,
      reasoning: decision.explanation,
    })
  }
})

Summary

The five core concepts work together:

  1. Entities - Define what exists (customers, products, orders)
  2. Relationships - Connect entities semantically
  3. Events - Signal state changes
  4. Workflows - Respond to events
  5. Decisions - Choose actions (manual or AI)

Together, they form an autonomous business that:

  • Understands itself (semantic entities)
  • Connects naturally (semantic relationships)
  • Reacts automatically (event-driven)
  • Operates intelligently (AI decisions)
  • Scales seamlessly (distributed workflows)

Next: Autonomous Operations →