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.nowlet 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 applicablelet 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 emaillet 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] flattenConditional Validation
Business Hours Validation
hook OnOrderBeforeCreated
let now = datetime.nowlet hour = now hourlet 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
- Rules Overview - Introduction to rules
- Rule Hooks - Available lifecycle hooks
- Rule Effects - Available effects
- Runtime Reference - Detailed documentation
- Order Discounts - Discount-specific patterns