FREE · TOPIC 201

Rule Engine Trigger Framework

576 words·Updated 2026-07-18·
#system-design#rule-engine#event-driven
# Rule Engine Trigger Framework A trigger framework lets product and operations define: **when this event happens, if these conditions match, run these actions.** Examples: - rider incentive after delivery, - fraud review after unusual payment, - coupon after cart abandonment, - notification after status transition, - workflow step after document approval. ## Architecture ```mermaid flowchart LR E[Event] --> N[normalize] N --> M[rule matcher] R[(rule store)] --> M M --> D[action dispatcher] D --> A1[incentive] D --> A2[notification] D --> A3[audit task] D --> Log[(execution log)] ``` ## Rule Schema ```json { "rule_id": "r123", "event_type": "delivery_completed", "priority": 50, "active": true, "version": 7, "condition": { "and": [ {"field": "city", "eq": "BLR"}, {"field": "distance_km", "gte": 8}, {"field": "completed_at_hour", "between": [18, 22]} ] }, "action": { "type": "credit_incentive", "amount": 50 } } ``` Rules should be data, but not arbitrary code. The safest starting point is a typed predicate tree with a small set of operators and allowlisted actions. ## Design Decisions | Decision | Conservative default | |---|---| | Rule language | JSON predicate tree before custom DSL | | Execution | Async unless user-facing result needs sync | | Versioning | Immutable rule versions | | Audit | Store event, matched rules, actions, outcome | | Safety | Allowlist actions, validate payloads, sandbox expressions | ## Execution Flow 1. Normalize the incoming event into a stable shape. 2. Fetch candidate rules by indexed dimensions. 3. Evaluate predicates in priority order. 4. Create an immutable execution record. 5. Dispatch actions asynchronously unless the product needs a sync result. 6. Record success, failure, retry, or suppression. That execution record is critical. When support asks why a coupon, incentive, or fraud review happened, the system must explain the event, rule version, condition result, and action output. ## Scaling Do not evaluate all rules for all events. Index rules by: - event type, - tenant/region, - active date range, - product vertical, - priority. Then each event evaluates a small candidate set. Cache active rules per event type, but make rule publishing explicit. A rule should move through draft, test, active, paused, and retired states. Hot reload is useful only if operators can see which version is active on each worker. ## Testing Rules | Test | Purpose | |---|---| | Dry run on historical events | Estimate match volume before activation. | | Shadow mode | Log matches without firing actions. | | Unit fixtures | Prove edge cases for predicate logic. | | Budget guardrail | Stop runaway money-moving actions. | | Rollback plan | Revert to previous immutable version. | For money or compliance workflows, approval and change logs are part of the design, not admin polish. ## Failure Modes - A broad rule matches every event and floods action queues. - A rule update is not versioned, so old executions cannot be explained. - Dynamic expressions allow unsafe code or access to private fields. - Action retries duplicate credits, messages, or tickets. - Rule evaluation depends on live database lookups and becomes slow or inconsistent. Prefer event payload fields and precomputed attributes over synchronous enrichment in the hot path. If enrichment is required, treat it as another dependency with timeouts and fallback behavior. ## Staff-Level Insight The hard part is not evaluating `if city == BLR`. The hard part is making rule changes safe: versioned, auditable, testable, reversible, and explainable to finance/support when money or compliance is involved. ## Related Pages - [[wiki/event-bus-for-product-events]] - [[wiki/dag-workflow-orchestration]] - [[wiki/delegation-and-async-work]]
Primary References & Engineering Sources