Skip to content

Common Rule Patterns

This page provides recipe-style examples of common rule patterns you can adapt for your own use cases.

Validation Patterns

Require Minimum Order Value

hook OnOrderBeforeCreated
from order.total >= 100 match
false |> [{
effect = 'validationError'
code = 'MINIMUM_ORDER_VALUE'
message = 'Minimum order value is 100'
}]
true |> []

Validate Email Address

hook OnOrderBeforeCreated
let hasEmail = order.customer.email match
nothing |> false
email |> email contains '@'
from hasEmail match
false |> [{
effect = 'validationError'
code = 'INVALID_EMAIL'
message = 'Valid email address required'
}]
true |> []

Prevent Deletion of Active Entities

hook OnTicketBeforeDeleted
from ticket.status = 'active' match
true |> [{
effect = 'validationError'
code = 'CANNOT_DELETE_ACTIVE'
message = 'Cannot delete active tickets'
}]
false |> []

Automation Patterns

Auto-Tag High-Value Orders

hook OnOrderCreated
let tags = order.total match
when order.total >= 10000 |> ['vip', 'high-value', 'priority-shipping']
when order.total >= 5000 |> ['high-value', 'priority-shipping']
when order.total >= 1000 |> ['high-value']
|> []
from tags select tag => {
effect = 'orderCommand'
type = 'addTag'
value = tag
}

Create Support Ticket on Payment Failure

hook OnPaymentCapture
from payment.status = 'failed' match
false |> []
true |> [{
effect = 'messageActor'
actorType = 'ticket'
actorId = 'new'
messages = [{
type = 'create'
body = {
title = 'Payment Failed'
description = $'Payment {payment.id} failed for order {payment.orderId}'
priority = 'high'
}
}]
}]

Schedule Follow-Up Actions

hook OnOrderCreated
from [{
effect = 'scheduleJob'
definition = 'order-follow-up'
at = datetime.now addDays 7
parameters = {
orderId = order.id
}
}]

Notification Patterns

Order Confirmation Email

import 'resources'
hook OnOrderCreated
from order.customer.email match
nothing |> []
email |> [
sendEmail {
to = email
subject = $'Order #{order.orderNumber} Confirmed'
body = {
html = $'
<h1>Thank you for your order!</h1>
<p>Order number: {order.orderNumber}</p>
<p>Total: {order.total} {order.currencyCode}</p>
'
}
category = 'order_confirmation'
dynamic = { orderId = order.id }
}
]

Payment Captured Notification

import 'resources'
hook OnPaymentCapture
from payment.orderId match
nothing |> []
orderId |> [
sendEmail {
subject = $'Payment Captured: {payment.amount} {payment.currencyCode}'
body = {
html = $'<p>Payment {payment.id} for order {orderId} has been captured.</p>'
}
category = 'payment_captured'
dynamic = { paymentId = payment.id }
}
]

Ticket Completion Notification

import 'resources'
hook OnTicketComplete
from [{
effect = 'messageActor'
actorType = 'order'
actorId = ticket.orderId
messages = [{
type = 'applyCommands'
body = {
commands = [{
type = 'addActivityLog'
message = $'Support ticket {ticket.id} resolved'
}]
}
}]
}]

Discount Application Patterns

Time-Limited Promotion

hook OnOrderCreated
let now = datetime.now
let promoStart = datetime.parse('2025-11-29T00:00:00Z')
let promoEnd = datetime.parse('2025-11-29T23:59:59Z')
let isPromoActive = now >= promoStart and now <= promoEnd
from isPromoActive match
false |> []
true |> [{
effect = 'orderCommand'
type = 'createComputedOrderDiscount'
componentId = 'free-shipping'
description = 'Black Friday Free Shipping'
parameters = { orderTotalThreshold = '500' }
}]

Loyalty Member Discount

hook OnOrderCreated
let isLoyaltyMember = order.customer.tags
any t => t = 'loyalty-member'
from isLoyaltyMember match
false |> []
true |> [{
effect = 'orderCommand'
type = 'createComputedOrderDiscount'
componentId = 'loyalty-discount'
description = 'Loyalty Member Discount'
parameters = { discountRate = '10' }
}]

Integration Patterns

Sync to External ERP

hook OnOrderCreated
from [{
effect = 'scheduleJob'
definition = 'erp-sync'
at = datetime.now addMinutes 5
parameters = {
orderId = order.id
action = 'create'
}
}]

Webhook on Payment Capture

hook OnPaymentCapture
from [{
effect = 'scheduleJob'
definition = 'payment-webhook'
parameters = {
paymentId = payment.id
webhookUrl = 'https://api.external.com/webhooks/payment'
}
}]

Cascading Logic Patterns

Auto-Complete Delivery on All Items Shipped

hook OnOrderCommands
let allShipped = order.orderLines
all line => line.shippedQuantity = line.quantity
let hasDelivery = order.deliveries count > 0
from allShipped and hasDelivery match
false |> []
true |>
order.deliveries select delivery => {
effect = 'orderCommand'
type = 'completeDelivery'
deliveryId = delivery.id
}

Set Invoice Address from Delivery

hook OnOrderCommands
let needsInvoiceAddress = order.invoiceAddress match
nothing |> true
|> false
from needsInvoiceAddress match
false |> []
true |>
order.deliveries first match
nothing |> []
delivery |> [{
effect = 'orderCommand'
type = 'setInvoiceAddress'
address = delivery.address
}]

Multi-Step Patterns

Order Confirmation with Discount

Combine multiple effects for complex workflows:

import 'resources'
hook OnOrderCreated
let effects = []
// Add loyalty discount if applicable
let loyaltyEffect = order.customer.tags any t => t = 'loyalty' match
false |> []
true |> [{
effect = 'orderCommand'
type = 'createComputedOrderDiscount'
componentId = 'loyalty-discount'
description = 'Loyalty Member - 10% Off'
}]
// Send confirmation email
let emailEffect = order.customer.email match
nothing |> []
email |> [
sendEmail {
to = email
subject = $'Order #{order.orderNumber} Confirmed'
body = { html = '<h1>Thank you!</h1>' }
dynamic = { orderId = order.id }
}
]
from [loyaltyEffect, emailEffect] flatten

Conditional Validation

Business Hours Validation

hook OnOrderBeforeCreated
let now = datetime.now
let hour = now hour
let isBusinessHours = hour >= 9 and hour < 17
from isBusinessHours match
true |> []
false |> [{
effect = 'validationError'
code = 'OUTSIDE_BUSINESS_HOURS'
message = 'Orders can only be placed during business hours (9 AM - 5 PM)'
}]

Stock Availability Check

hook OnOrderBeforeCreated
let stockCheck = order.orderLines select line =>
query skus(skuNumber, availableStock)
filter $'skuNumber = {line.productNumber}'
first
match
nothing |> { sku = line.productNumber, available = 0, needed = line.quantity }
sku |> { sku = line.productNumber, available = sku.availableStock, needed = line.quantity }
let outOfStock = stockCheck
filter item => item.available < item.needed
from outOfStock count > 0 match
false |> []
true |> [{
effect = 'validationError'
code = 'INSUFFICIENT_STOCK'
message = $'{outOfStock count} items out of stock'
}]

See Also