.do
Fundamentals

Semantic Patterns

Understanding $.Subject.predicate.Object patterns and semantic triples

Semantic Patterns: $.Subject.predicate.Object

The Foundation of Semantic Web

The $.Subject.predicate.Object pattern comes from RDF (Resource Description Framework), the foundation of the Semantic Web. It's how knowledge graphs represent information that both humans and machines can reason about.

Understanding Semantic Triples

A semantic triple is the atomic unit of knowledge:

flowchart LR S[Subject<br/>The thing being described] P[predicate<br/>The relationship/property] O[Object<br/>The value/target] S -->|"describes"| P P -->|"connects to"| O
Subject → predicate → Object

Components

Subject: The thing being described

  • Must be a noun/entity
  • Example: Customer, Order, Product

predicate: The relationship or property

  • Can be a verb, attribute, or relationship
  • Example: places, contains, costs, name

Object: The value or target entity

  • Can be another entity, a literal value, or a type
  • Example: Order, Product, $29.99, "John"

Examples

// Entity relationships
$.Customer.places.Order
// "A Customer places an Order"

$.Order.contains.Product
// "An Order contains a Product"

$.Organization.employs.Person
// "An Organization employs a Person"

// Properties
$.Product.name.value
// "A Product has a name"

$.Order.totalPrice.amount
// "An Order has a total price"

// Events
$.Payment.processed.timestamp
// "A Payment was processed at a timestamp"

The $ Proxy

In the .do platform, $ is a TypeScript Proxy that creates semantic paths dynamically.

How It Works

// The $ proxy intercepts property access
const path = $.Customer.places.Order

// Internally creates:
{
  subject: 'Customer',
  predicate: 'places',
  object: 'Order',
  path: 'Customer.places.Order'
}

Type Safety

The $ proxy provides full TypeScript autocomplete:

import $ from 'sdk.do'

// Autocomplete shows all Schema.org types
$.Organization.   // ← shows: employs, owns, publishes, etc.
$.Person.         // ← shows: knows, worksFor, owns, etc.
$.Product.        // ← shows: manufacturer, brand, offers, etc.

Pattern Types

graph TB subgraph Patterns["7 Core Pattern Types"] N[1. Noun Patterns<br/>Entity Types] V[2. Verb Patterns<br/>Relationships] P[3. Property Patterns<br/>Attributes] E[4. Event Patterns<br/>State Changes] A[5. Action Patterns<br/>Operations] VI[6. View Patterns<br/>Perspectives] AG[7. Agent Patterns<br/>Roles] end N -.->|"connects via"| V N -.->|"has"| P N -.->|"emits"| E N -.->|"performs"| A N -.->|"viewed as"| VI AG -.->|"executes"| A

1. Noun Patterns (Entity Types)

Define what type of thing something is:

// Creating entities
$.Customer.create({
  name: 'Alice',
  email: '[email protected]',
}).then((customer) => {
  console.log('Customer created:', customer.name)
})

$.Product.create({
  name: 'Widget',
  price: 29.99,
}).then((product) => {
  console.log('Product created:', product.name)
})

// Referencing types
$.Person // Person type
$.Organization // Organization type
$.Product // Product type

2. Verb Patterns (Relationships)

Express relationships between entities:

// Binary relationships (Subject → verb → Object)
$.Customer.places.Order
$.Order.contains.Product
$.Organization.employs.Person
$.Person.owns.Organization

// Usage in code
await db.relate(customer, $.places, order)
await db.relate(order, $.contains, product)

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

3. Property Patterns (Attributes)

Describe attributes of entities:

flowchart TB Entity[Entity<br/>Person, Product, Order] subgraph Properties["Property Patterns"] P1[name<br/>identifier] P2[email<br/>contact info] P3[price<br/>monetary value] P4[status<br/>state] P5[date<br/>timestamp] end Entity -->|"has property"| P1 Entity -->|"has property"| P2 Entity -->|"has property"| P3 Entity -->|"has property"| P4 Entity -->|"has property"| P5
// Properties as semantic paths
$.Person.name
$.Person.email
$.Person.birthDate
$.Product.price
$.Product.description
$.Order.orderStatus
$.Order.orderDate

// Usage
$.Person.create({
  name: 'Bob', // $.Person.name
  email: '[email protected]', // $.Person.email
  birthDate: '1990-01-01', // $.Person.birthDate
}).then((person) => {
  console.log('Created person:', person.name)
})

4. Event Patterns (State Changes)

Represent things that happen:

sequenceDiagram participant E as Entity participant S as System participant H as Handler E->>S: State change occurs S->>S: Emit event<br/>($.Entity.eventName) S->>H: Trigger handlers H->>H: Execute logic H-->>S: Complete Note over E,H: Events use past tense:<br/>created, processed, sent
// Event patterns use past tense verbs
$.Order.created
$.Payment.processed
$.Shipment.dispatched
$.Invoice.sent
$.Customer.registered

// Listen for events
on.Order.created((order) => {
  console.log('New order:', order)
})

// Emit events
send($.Order.created, order)

5. Action Patterns (Operations)

Express operations that can be performed:

// Actions use base verb form
$.Order.create
$.Order.update
$.Order.cancel
$.Order.fulfill

$.Payment.process
$.Payment.refund

$.Email.send
$.Notification.deliver

// Usage
send($.Order.cancel, { orderId, reason })
send($.Email.send, { to, subject, body })

6. View Patterns (Perspectives)

Different views or aspects of entities:

// Views provide different perspectives
$.Order.summary // Summary view
$.Order.details // Detailed view
$.Order.timeline // Timeline view
$.Customer.profile // Customer profile
$.Product.catalog // Catalog view
$.Analytics.dashboard // Dashboard view

7. Agent Patterns (Roles)

Represent actors and roles:

// Agents are entities that perform actions
$.Agent.AI // AI agent
$.Agent.Human // Human agent
$.Agent.System // System agent

// Roles
$.Role.Admin
$.Role.User
$.Role.Manager

// Usage
on.SupportTicket.created((ticket) => {
  if (ticket.priority === 'high') {
    $.Agent.Human.assign(ticket)
  } else {
    $.Agent.AI.respond(ticket)
  }
})

Advanced Patterns

Chaining

Build complex semantic paths through chaining:

// Navigate relationships
db.Product.follow(product, $.Product.manufacturer.Organization).then((manufacturer) => {
  console.log('Manufacturer:', manufacturer.name)
})

// Multi-hop queries
db.Product.follow(product, $.Product.manufacturer.Organization.employs.Person).then((employees) => {
  console.log('Manufacturer employees:', employees)
})

// Chain events
on.Order.created((order) => {
  send($.Payment.process, { order })
})

on.Payment.processed((payment) => {
  send($.Order.fulfill, { order: payment.order })
})

on.Order.fulfilled((order) => {
  send($.Shipment.create, { order })
})

Inverse Relationships

Every relationship has an inverse:

graph LR subgraph Forward["Forward Relationship"] O1[Organization] P1[Person] O1 -->|"employs"| P1 end subgraph Inverse["Inverse Relationship"] P2[Person] O2[Organization] P2 -->|"worksFor"| O2 end Forward -.->|"same relationship,<br/>different direction"| Inverse
// Forward relationship
$.Organization.employs.Person
// Inverse relationship
$.Person.worksFor.Organization

// Forward
$.Customer.places.Order
// Inverse
$.Order.placedBy.Customer

// Usage
db.Customer.related(customer, $.places, $.Order).then((orders) => {
  console.log('Customer orders:', orders)
})
db.Order.related(order, $.placedBy, $.Customer).then((customer) => {
  console.log('Order customer:', customer)
})

Contextual Patterns

Add context to semantic patterns:

graph TB Entity[Order Entity] subgraph Context["Context Modifiers"] C1[estimated] C2[actual] C3[suggested] C4[final] end subgraph Values["Property Values"] V1[deliveryDate] V2[price] V3[status] end Entity --> C1 Entity --> C2 Entity --> C3 Entity --> C4 C1 --> V1 C2 --> V1 C3 --> V2 C4 --> V3
// Context modifies meaning
$.Order.estimated.deliveryDate // Estimated delivery
$.Order.actual.deliveryDate // Actual delivery
$.Product.suggested.price // Suggested price
$.Product.sale.price // Sale price

// Usage in queries
db.Order.get(order, $.estimated.deliveryDate).then((estimatedDelivery) => {
  console.log('Estimated delivery:', estimatedDelivery)
})
db.Order.get(order, $.actual.deliveryDate).then((actualDelivery) => {
  console.log('Actual delivery:', actualDelivery)
})

Composite Patterns

Combine multiple patterns:

// Complex semantic expressions
$.Organization.owns.Brand.manufactures.Product.soldTo.Customer.via.Order

// Query across multiple relationships
db.Organization.query({
  start: organization,
  path: $.owns.Brand.manufactures.Product.soldTo.Customer,
}).then((customers) => {
  console.log('Brand customers:', customers)
})

Pattern Conventions

Naming Rules

  1. Subjects: Always TitleCase (Person, Organization, Product)
  2. Predicates: camelCase for properties and relationships (name, employs, workFor)
  3. Verbs: Present tense for actions (create, update), past tense for events (created, updated)
  4. Consistency: Follow Schema.org conventions when available

Schema.org Alignment

Use Schema.org vocabulary as the foundation:

// Good: Uses Schema.org types and properties
$.Person // from schema.org/Person
$.Organization // from schema.org/Organization
$.Product // from schema.org/Product
$.Order // from schema.org/Order

// Properties
$.Person.givenName // from schema.org/givenName
$.Person.familyName // from schema.org/familyName
$.Organization.employee // from schema.org/employee
$.Product.brand // from schema.org/brand

Practical Examples

E-commerce Business

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

// Entity creation with semantic types
$.Organization.create({
  $type: 'Organization',
  name: 'Acme Store',
}).then((store) => {
  return $.Product.create({
    $type: 'Product',
    name: 'Widget',
    manufacturer: store,
    offers: {
      $type: 'Offer',
      price: 29.99,
      priceCurrency: 'USD',
    },
  }).then((product) => {
    // Relationship modeling
    db.relate(store, $.sells, product)
    return { store, product }
  })
})

// Event-driven workflows
on.Order.created((order) => {
  // Semantic event handling
  send($.Inventory.decrement, {
    product: order.orderedItem.orderItem,
    quantity: order.orderedItem.orderQuantity,
  })

  send($.Email.send, {
    to: order.customer.email,
    template: 'order-confirmation',
  })
})

// Semantic queries
db.Organization.related(store, $.sells, $.Product).then((soldProducts) => {
  console.log('Sold products:', soldProducts)
})
db.Orders.list({
  where: { orderStatus: 'pending' },
}).then((orders) => {
  console.log('Pending orders:', orders)
})

SaaS Business

// Subscription relationships
$.Customer.subscribes.Plan
$.Plan.includes.Feature
$.Feature.requires.Permission

// State transitions
on.Subscription.created((sub) => {
  db.relate(sub.customer, $.subscribes, sub.plan)
  send($.Account.provision, { customer: sub.customer })
})

on.Subscription.cancelled((sub) => {
  db.unrelate(sub.customer, $.subscribes, sub.plan)
  send($.Account.deprovision, { customer: sub.customer })
})

// Usage tracking
on.Feature.used((event) => {
  db.Customers.increment(event.customer, $.usage.count)
})

Why Semantic Patterns Matter

1. AI Understanding

AI models are trained on semantic data. When you use semantic patterns, AI can:

  • Understand your business logic without custom training
  • Reason about relationships and workflows
  • Suggest improvements and optimizations
  • Generate code that integrates seamlessly

2. Composability

Semantic patterns enable composition:

  • Different businesses can interact using shared vocabulary
  • Workflows can be assembled from reusable patterns
  • Services integrate naturally through semantic compatibility

3. Query Power

Semantic patterns enable powerful queries:

// Find all customers who ordered products from manufacturers in Texas
db.Customers.query({
  select: $.Customer,
  where: {
    [$.places]: {
      [$.contains]: {
        [$.manufacturer]: {
          [$.address.addressRegion]: 'TX',
        },
      },
    },
  },
}).then((customers) => {
  console.log('TX manufacturer customers:', customers)
})

4. Evolution

As your business evolves, semantic patterns make it easy to:

  • Add new entity types
  • Create new relationships
  • Extend existing workflows
  • Maintain backward compatibility

Best Practices

1. Start with Schema.org

Always check if Schema.org has a type or property before creating custom ones:

// Good: Use Schema.org
$.Person.givenName
$.Organization.employee
$.Product.manufacturer

// Avoid: Custom properties when Schema.org exists
$.Person.firstName // Use givenName instead
$.Company.workers // Use employee instead

2. Be Explicit

Clear, explicit patterns are better than abbreviated ones:

// Good: Clear and explicit
$.Customer.places.Order
$.Order.contains.Product
$.Organization.employs.Person

// Avoid: Abbreviated or unclear
$.Cust.plc.Ord
$.Ord.has.Prod

3. Follow Conventions

Use established naming conventions:

// Entities: TitleCase
;($.Person, $.Organization, $.Product)

// Relationships: camelCase
;($.employs, $.manufactures, $.owns)

// Events: past tense
;($.created, $.updated, $.processed)

// Actions: base verb
;($.create, $.update, $.process)

4. Think in Graphs

Model your business as a graph of interconnected entities:

Customer --places--> Order --contains--> Product
   |                   |                    |
subscribes          sentTo              madeBy
   |                   |                    |
  Plan             Address           Organization

Summary

Semantic patterns ($.Subject.predicate.Object) are the foundation of Business-as-Code:

  • Based on RDF semantic triples
  • Enabled by TypeScript Proxy
  • Provides type safety and autocomplete
  • Enables AI understanding
  • Powers semantic queries
  • Facilitates composition

Next: Vocabulary and Types →