Aexol Language

DocsAexol LanguageTutorial

Build a complete Aexol specification step by step — from types to agents.

Tutorial

In this tutorial, you will build a complete e-commerce specification from scratch. By the end, you will have defined data types, enums, a state machine workflow, visitor capabilities, and autonomous agents — all in one Aexol file.

The spec will model an online store with products, orders, payment processing, and automated notifications. You will write it step by step, validating at each stage.

Step 1: Define Data Types

Start with the core data structures. An e-commerce system needs products, orders, and order items.

Create a file named ecommerce.aexol

type Product {
  id: string
  name: string
  description: string
  price: number
  inStock: boolean
  categories: string[]
}

type Order {
  id: string
  customerId: string
  items: OrderItem[]
  total: number
  status: string
}

type OrderItem {
  productId: string
  quantity: number
  unitPrice: number
}

Product models what you sell — each product has a name, price, stock flag, and category tags. Order groups items under a customer, and OrderItem links each line item to its product.

Notice that Order.status is currently a plain string. You will replace it with a proper enum in the next step.

Step 2: Add Enums

Replace the loose string status with typed enums. Add a payment method enum too.

Define enums and update Order

enum OrderStatus {
  pending
  payment_received
  processing
  shipped
  delivered
  cancelled
}

enum PaymentMethod {
  credit_card
  debit_card
  paypal
  bank_transfer
}

type Order {
  id: string
  customerId: string
  items: OrderItem[]
  total: number
  status: OrderStatus
  paymentMethod: PaymentMethod
}

Now Order.status is restricted to exactly six values. The validator will catch typos like OrderStatus.pendng immediately. The PaymentMethod enum gives you a typed way to track how each order was paid.

Step 3: Define a Workflow

Models how an order moves through the system — from placement to delivery.

Add the OrderFlow workflow

workflow OrderFlow {
  initial: pending
  pending -> payment_received when payment_confirmed
  payment_received -> processing when stock_reserved
  processing -> shipped when items_packed
  shipped -> delivered when customer_confirms
  pending -> cancelled when timeout
  payment_received -> cancelled when refund_requested
  processing -> cancelled when out_of_stock
}

The initial keyword sets pending as the starting state. Each transition has a when condition that describes what event triggers it. Some states (like pending and payment_received) have multiple possible exits — an order can be cancelled at several points, and processing can cancel if stock runs out.

When generated, this workflow produces a state machine class with canTransitionTo() and transitionTo() methods that enforce these rules at runtime.

Step 4: Define Visitors

Visitors model who can do what. Define customer and admin capabilities.

Add visitors with nested capabilities

visitor Customer {
  "browse products"
  "place orders" {
    "view order history"
    "track shipments"
    "cancel order"
  }
  "manage profile" {
    "update address"
    "update payment methods"
  }
}

visitor Admin {
  "manage inventory" {
    "add products"
    "edit products"
    "remove products"
  }
  "view all orders"
  "manage customers"
  "view reports"
  "configure system"
}

Nested capabilities (indented quote blocks) model hierarchical access — "cancel order" is a sub-capability under "place orders". This structure helps code generators produce scoped permission checks and role-based access control.

Step 5: Add Agents

Agents model autonomous services that react to system events.

Add three agents

agent InventoryBot {
  "reserve stock"
  "release stock"
  "update stock levels"
  "alert low stock"
}

agent NotificationService {
  "send order confirmation"
  "send shipping update"
  "send delivery notification"
  "send cancellation notice"
}

agent PaymentProcessor {
  "process payment"
  "issue refund"
  "verify payment method"
}

Each agent declares capabilities as quoted strings. InventoryBot manages stock levels, NotificationService sends customer emails at each workflow transition, and PaymentProcessor handles money. Agents are not visitors — they represent background services, not user-facing roles.

Step 6: Put It All Together

Here is the complete specification with everything combined:

// ── Data Types ──────────────────────────────────────

type Product {
  id: string
  name: string
  description: string
  price: number
  inStock: boolean
  categories: string[]
}

type Order {
  id: string
  customerId: string
  items: OrderItem[]
  total: number
  status: OrderStatus
  paymentMethod: PaymentMethod
}

type OrderItem {
  productId: string
  quantity: number
  unitPrice: number
}

// ── Enums ───────────────────────────────────────────

enum OrderStatus {
  pending
  payment_received
  processing
  shipped
  delivered
  cancelled
}

enum PaymentMethod {
  credit_card
  debit_card
  paypal
  bank_transfer
}

// ── Workflow ────────────────────────────────────────

workflow OrderFlow {
  initial: pending
  pending -> payment_received when payment_confirmed
  payment_received -> processing when stock_reserved
  processing -> shipped when items_packed
  shipped -> delivered when customer_confirms
  pending -> cancelled when timeout
  payment_received -> cancelled when refund_requested
  processing -> cancelled when out_of_stock
}

// ── Visitors ────────────────────────────────────────

visitor Customer {
  "browse products"
  "place orders" {
    "view order history"
    "track shipments"
    "cancel order"
  }
  "manage profile" {
    "update address"
    "update payment methods"
  }
}

visitor Admin {
  "manage inventory" {
    "add products"
    "edit products"
    "remove products"
  }
  "view all orders"
  "manage customers"
  "view reports"
  "configure system"
}

// ── Agents ──────────────────────────────────────────

agent InventoryBot {
  "reserve stock"
  "release stock"
  "update stock levels"
  "alert low stock"
}

agent NotificationService {
  "send order confirmation"
  "send shipping update"
  "send delivery notification"
  "send cancellation notice"
}

agent PaymentProcessor {
  "process payment"
  "issue refund"
  "verify payment method"
}

Validate it with the CLI to confirm everything checks out:

aexol validate ecommerce.aexol

Then generate code in your target language using Studio.

What's Next

Key Takeaways

  • Types define your data. Start with them — everything else builds on top.
  • Enums replace loose strings with typed, validated constants. Use them in type fields and align them with workflow states.
  • Workflows model state machines with explicit transitions. Every transition should have a when condition that names the real-world trigger.
  • Visitors define what each actor can do. Nest capabilities to model hierarchical access patterns.
  • Agents represent autonomous background services. Keep them separate from visitors — visitors are roles, agents are services.