Rules
Rules are event-driven automation components that react to system events in Hantera. They enable you to validate state changes, enforce business logic, and trigger automated workflows.
What are Rules?
A rule is a component that executes when specific events occur in the system. Rules can:
- Validate operations before they complete (prevent invalid states)
- Automate workflows when entities change
- Enforce business logic across the platform
- Integrate with external systems via effects
Unlike Jobs which are time-triggered, rules are event-triggered - they run automatically when specific system events occur.
How Rules Work
Rules follow a three-step pattern:
- Hook Triggers: A system event occurs (e.g., order created)
- Component Evaluates: Rule component receives event data and evaluates conditions
- Effects Execute: Component returns effects to execute (commands, validations, integrations)
INFO
Rules use components with the rule runtime, which has more capabilities than the discount runtime but less than the reactor runtime. See Runtime Reference for details on what's available.
Simple Example: Order Confirmation Email
Here's a complete example that sends an email when an order is created:
Create the rule component:
filtrera//order-confirmation.hrule import 'resources' // 'input' is a special parameter and the designated type determines when/if the rule will evaluate: param input: OnOrderCreated let customerEmail = input.order.invoiceAddress.email from customerEmail match /@/ |> { effect = '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>' } category = 'order_confirmation' dynamic = { orderId = input.order.orderId } } ]Deploy via manifest:
yamluri: /resources/rules/order-confirmation spec: codeFile: order-confirmation.hruleApply the manifest:
bashh_ manage apply h_manifest.yaml
Now every time an order is created, the customer receives a confirmation email automatically.
Rule Hooks
Rules are triggered by system defined hooks.
Rule Effects
Rules return effects - instructions for what should happen.
WARNING
Effect Availability: Not all effects work in all hooks. Before hooks typically support validation and commands, while after hooks support broader effects like messageActor and scheduleJob. Check individual hook documentation in the Runtime Reference to see which effects are supported in each context.
Effects include:
Actor Commands
Apply commands to actors:
orderCommand- Modify orderspaymentCommand- Modify paymentsticketCommand- Modify ticketsskuCommand- Modify SKUsassetCommand- Modify assets
System Operations
messageActor- Send messages to other actorsscheduleJob- Schedule background jobs
Validation
validationError- Prevent operation and return error
Common Use Cases
Validation Rules
Prevent invalid state changes:
import 'iterators'
param input: OnOrderBeforeCreated
let hasItems =
input.order.deliveries
select d => d.orderLines
flatten
count > 0
from hasItems match
false |> {
effect = 'validationError'
code = 'EMPTY_ORDER'
message = 'Orders must have at least one item'
}Automation Rules
Trigger workflows automatically:
param input: OnPaymentCapture
from input.paymentCapture.capturedAmount > 10000 match
true |> {
effect = 'messageActor'
actorType = 'ticket'
actorId = 'new'
messages = [{
type = 'create'
commands = [{
type = 'setDynamicFields',
fields = {
title = 'Large Payment Review'
description = $'Payment {input.payment.paymentNumber} for {input.paymentCapture.capturedAmount} needs review'
paymentId = input.payment.paymentId
}
}]
}]
}Integration Rules
Sync with external systems:
param input: OnOrderCreated
from [{
effect = 'scheduleJob'
definition = 'sync-to-erp'
at = datetime.now addMinutes 5
parameters = {
orderId = order.id
}
}]Multiple Effects
Rules can return multiple effects as an array:
param input: OnOrderCreated
from {
effect = 'orderCommand'
type = 'createComputedOrderDiscount'
componentId = 'free-shipping'
description = 'Free Shipping'
parameters = { threshold = '500' }
}
from {
effect = 'sendEmail'
to = order.customer.email
subject = 'Order Confirmed'
body = { html = '<h1>Thank you!</h1>' }
dynamic = {}
}All effects execute in the order specified.
Access Control
Managing rule resources requires standard permissions:
rules:read # View rule configurations
rules:write # Create, update, and delete rulesRules inherit the execution permissions of the system - they run with elevated privileges to enforce business logic across the platform.
Best Practices
1. Use Before Hooks for Validation
Prevent invalid operations with before hooks:
hook OnOrderBeforeCreated
from validateOrder(order) match
Error |> [{ effect = 'validationError', code = error.code, message = error.message }]
|> []2. Use After Hooks for Automation
Trigger workflows after successful operations:
hook OnOrderCreated
from [
{ effect = 'sendEmail', ... },
{ effect = 'scheduleJob', ... }
]3. Handle Missing Data Gracefully
Always handle optional data:
from input.order.invoiceAddress.email match
email |> { effect = 'sendEmail', to = email, ... }
// Default case returns nothingSee Also
- Components - Learn about components and runtimes
- Rule Hooks - Available lifecycle hooks
- Rule Effects - Available effects
- Common Patterns - Recipe-style examples
- Runtime Reference - Detailed runtime documentation