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

filtrera
hook OnOrderBeforeCreated

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

Validate Email Address

filtrera
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

filtrera
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

filtrera
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

filtrera
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

filtrera
hook OnOrderCreated

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

Notification Patterns

Order Confirmation Email

filtrera
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

filtrera
import 'resources'

hook OnPaymentCapture

from payment.orderId match
  nothing |> []
  orderId |> [
    sendEmail {
      to = 'finance@company.com'
      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

filtrera
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

filtrera
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

filtrera
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

filtrera
hook OnOrderCreated

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

Webhook on Payment Capture

filtrera
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

filtrera
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

filtrera
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:

filtrera
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

filtrera
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

filtrera
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

© 2024 Hantera AB. All rights reserved.