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
param input: OnOrderBeforeCreated

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

Validate Email Address ​

filtrera
param input: OnOrderBeforeCreated

let hasEmail = input.order.invoiceAddress.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
param input: OnTicketBeforeDeleted

from input.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
param input: OnOrderCreated

let tags = input.order.total match
  when input.order.total >= 10000 |> ['vip', 'high-value', 'priority-shipping']
  when input.order.total >= 5000 |> ['high-value', 'priority-shipping']
  when input.order.total >= 1000 |> ['high-value']
  |> []

from tags select tag => {
  effect = 'orderCommand'
  type = 'addTag'
  value = tag
}

Create Support Ticket on Payment Failure ​

filtrera
param input: OnPaymentCapture

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

Schedule Follow-Up Actions ​

filtrera
param input: OnOrderCreated

from [{
  effect = 'scheduleJob'
  definition = 'order-follow-up'
  at = now + 7 days
  parameters = {
    orderId = input.order.orderId
  }
}]

Notification Patterns ​

Order Confirmation Email ​

filtrera
import 'resources'

param input: OnOrderCreated

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

Payment Captured Notification ​

filtrera
import 'resources'

param input: OnPaymentCapture

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

Ticket Completion Notification ​

filtrera
param input: OnTicketComplete

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

Promotion Patterns ​

Loyalty Member Promotion ​

filtrera
param input: OnOrderCreated

let isLoyaltyMember = input.order.tags
  any t => t == 'loyalty-member'

from isLoyaltyMember match
  false |> []
  true |> [{
    effect = 'orderCommand'
    type = 'createPromotion'
    componentId = 'loyalty-discount'
    promotionGroup = 'loyalty'
    description = 'Loyalty Member Discount'
    parameters = { discountRate = '10' }
  }]

Integration Patterns ​

Sync to External ERP ​

filtrera
param input: OnOrderCreated

from [{
  effect = 'scheduleJob'
  definition = 'erp-sync'
  at = now + 5 minutes
  parameters = {
    orderId = input.order.orderId
    action = 'create'
  }
}]

Webhook on Payment Capture ​

filtrera
param input: OnPaymentCapture

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

Cascading Logic Patterns ​

Auto-Complete fulfillment on All Items Shipped ​

filtrera
param input: OnOrderCommands

let allShipped = input.order.orderLines
  all line => line.shippedQuantity == line.quantity

let hasFulfillment = input.order.fulfillments count > 0

from allShipped and hasFulfillment match
  false |> []
  true |> 
    input.order.fulfillments select fulfillment => {
      effect = 'orderCommand'
      type = 'completeFulfillment'
      fulfillmentId = fulfillment.fulfillmentId
    }

Set Invoice Address from fulfillment ​

filtrera
param input: OnOrderCommands

let needsInvoiceAddress = input.order.invoiceAddress match
  nothing |> true
  |> false

from needsInvoiceAddress match
  false |> []
  true |> 
    input.order.fulfillments first match
      nothing |> []
      fulfillment |> [{
        effect = 'orderCommand'
        type = 'setInvoiceAddress'
        address = fulfillment.address
      }]

Multi-Step Patterns ​

Order Confirmation with Promotion ​

Combine multiple effects for complex workflows:

filtrera
import 'resources'

param input: OnOrderCreated

let promotionEffect = input.order.tags any t => t == 'loyalty' match
  false |> []
  true |> [{
    effect = 'orderCommand'
    type = 'createPromotion'
    componentId = 'loyalty-discount'
    promotionGroup = 'loyalty'
    description = 'Loyalty Member - 10% Off'
  }]

let emailEffect = input.order.invoiceAddress.email match
  nothing |> []
  email |> [
    sendEmail {
      to = email
      subject = $'Order #{input.order.orderNumber} Confirmed'
      body = { html = '<h1>Thank you!</h1>' }
      dynamic = { orderId = input.order.orderId :: text }
    }
  ]

from [promotionEffect, emailEffect] flatten

Conditional Validation ​

Stock Availability Check ​

filtrera
param input: OnOrderBeforeCreated

let stockCheck = input.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
  where 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 ​

© 2026 Hantera AB. Org. no.: 559242-9582