Event-driven trigger system for automating workflows
| Tier | operations |
| Role | unclassified (baselined) |
| Path | crates/operations/triggers |
| Edition | 2021 |
| Targets | operations_triggers |
| Public items | 0 across 0 modules |
| Tests | 40 |
What it is for
operations-triggers: Event-driven trigger system for automating workflows
Overview
This crate provides a trigger system that reacts to domain events and executes configured actions. It enables automation like "when an appointment is created, send a confirmation email" or "when an order is cancelled, initiate refund processing".
Layer
Operations - depends on: foundation-basemodels
Key Types
Trigger- A trigger definition with event type, condition, and actionTriggerExecution- Record of a trigger execution attemptTriggerService- High-level business operationsTriggerEvent- Domain events emitted by the trigger systemevaluate_condition- JSON-based condition evaluation
Example
use operations_triggers::{TriggerService, CreateTriggerRequest};
use serde_json::json;
let service = TriggerService::from_pool(pool);
// Create a trigger: "When appointment created, send notification"
let (trigger, event) = service.create_trigger(CreateTriggerRequest {
tenant_id: Some(tenant_id),
name: "appointment-confirmation".to_string(),
description: Some("Send confirmation when appointment created".to_string()),
event_type: "appointment.created".to_string(),
condition: Some(json!({"status": "confirmed"})),
action_type: "send_notification".to_string(),
action_config: json!({
"channel": "email",
"template": "appointment_confirmation"
}),
retry_policy: None,
timeout_seconds: None,
priority: None,
}).await?;
// Later, when an event occurs:
let event_data = json!({
"appointment_id": "123",
"status": "confirmed",
"customer_id": "456"
});
// Evaluate triggers for this event
let executions = service.evaluate_event(
"appointment.created",
event_data,
Some(tenant_id),
None,
).await?;
// Process each matching trigger
for (execution, trigger) in executions {
// Mark as running
service.mark_execution_running(execution.id).await?;
// Execute the action (application-specific)
match execute_action(&trigger, &execution).await {
Ok(result) => {
service.mark_execution_success(execution.id, Some(result)).await?;
}
Err(e) => {
service.mark_execution_failed(execution.id, e.to_string()).await?;
}
}
}
Condition Evaluation
Triggers can have optional JSON conditions that filter which events activate them:
use operations_triggers::evaluate_condition;
use serde_json::json;
// Exact match
let condition = json!({"status": "confirmed"});
let event = json!({"status": "confirmed", "amount": 100});
assert!(evaluate_condition(&condition, &event));
// With operators
let condition = json!({"amount": {"$gt": 50}});
assert!(evaluate_condition(&condition, &json!({"amount": 100})));
// Multiple conditions with $and
let condition = json!({
"$and":
{"status": "confirmed"},
{"amount": {"$gt": 100}}
});
Action Types
Built-in action types (application executes these):
| Type | Description |
|---|---|
send_notification | Create notification via domain-notifications |
create_job | Queue background job via infrastructure-jobs |
emit_event | Emit another event (for chaining) |
http_webhook | POST to external URL |
log | Log the event (for debugging) |
Capabilities
No public items.
How to use it
From this crate's own rustdoc:
## Condition Evaluation
Triggers can have optional JSON conditions that filter which events activate them:
Module structure
No public modules: the crate root is its whole surface.
Public surface
No public items.
Re-exports. Exported here, defined elsewhere.
| Export | Defined in |
|---|---|
TriggerRepository | repository::TriggerRepository |
TriggerService | service::TriggerService |
evaluate_condition | evaluator::evaluate_condition |
Boundary
Reaches into foundation.
Shares tier operations with 40 other crates: operations-approval-workflow, operations-assessments, operations-block-imaging, operations-boot-media, operations-browser-agent-worker, operations-camera-discovery, operations-camera-liveview, operations-camera-registry, … (40 total).
_What this crate deliberately does NOT own is a judgment. No committed registry records one for it, so none is stated here._
Where it sits
| Tier (ontology) | operations |
| Architectural role (taxonomy) | unclassified (baselined) |
| Location | crates/operations/triggers |
| Vocabulary in force (lexicon) | current |
Tier flow. Which tiers this crate's own edges cross.
flowchart LR n_operations["operations"] --> n_foundation["foundation"]
Dependencies
Runtime, in this workspace.
| Crate | Tier | Optional | Only on |
|---|---|---|---|
| `foundation-basemodels` | foundation | no | always |
Runtime, from outside the workspace.
| Crate | Requirement | Features | Optional | Only on |
|---|---|---|---|---|
async-trait | ^0.1 | — | no | always |
chrono | ^0.4 | serde | no | always |
regex | ^1 | — | no | always |
serde | ^1 | derive | no | always |
serde_json | ^1 | — | no | always |
sqlx | ^0.8 | runtime-tokio, postgres, chrono, uuid, json | no | always |
thiserror | ^2 | — | no | always |
tokio | ^1 | full | no | always |
uuid | ^1 | v4, serde | no | always |
Development, from outside the workspace.
| Crate | Requirement | Features | Optional | Only on |
|---|---|---|---|---|
tokio | ^1 | full, test-util | no | always |
Build. None.
Depended on by. 1 workspace crate.
Signal flow — what reaches this crate, and what it reaches.
flowchart LR n_application_triggers["application-triggers"] -->|uses| SELF SELF["operations-triggers"] SELF -->|runtime| n_foundation_basemodels["foundation-basemodels"] classDef self fill:#1f883d,stroke:#1f883d,color:#fff; class SELF self;
Feature flags
No Cargo features are defined: every capability is unconditional, so no consumer can receive a half-wired crate.
Targets
| Kind | Name | Source |
|---|---|---|
| lib | operations_triggers | `src/lib.rs` |
Error model
No public error type was detected: no public item declares a type named *Error, and no public signature returns one.
Operational characteristics
| Property | Evidence |
|---|---|
| async public surface | none detected |
| async runtime | yes |
| database access | yes |
| network I/O | none detected |
| unsafe code | none detected |
| environment variables | none detected |
No unsafe block, unsafe fn, unsafe impl or unsafe trait was found by the parser anywhere in this crate's source.
Configuration
No environment variable is read with a literal name anywhere in this crate. A variable whose key is computed at run time cannot be listed here, and is not claimed to be absent.
Related capabilities
1 workspace crate depends on this one: application-triggers.
Verification
| Kind | Count |
|---|---|
| Unit tests | 40 |
| Integration tests | 0 |
| Examples | 0 |
| Doctests | 1 |
What the tests establish, by name:
test_and_operator—src/evaluator.rstest_array_condition—src/evaluator.rstest_comparison_operators—src/evaluator.rstest_contains_operator—src/evaluator.rstest_empty_condition—src/evaluator.rstest_eq_operator—src/evaluator.rstest_exact_match—src/evaluator.rstest_exact_no_match—src/evaluator.rstest_exists_operator—src/evaluator.rstest_in_operator—src/evaluator.rstest_missing_field—src/evaluator.rstest_multiple_fields—src/evaluator.rstest_ne_operator—src/evaluator.rstest_nested_match—src/evaluator.rstest_nin_operator—src/evaluator.rstest_not_operator—src/evaluator.rstest_null_values—src/evaluator.rstest_or_operator—src/evaluator.rstest_event_types—src/events.rstest_execution_id_extraction—src/events.rstest_trigger_id_extraction—src/events.rstest_action_type_parsing—src/lib.rstest_condition_evaluation_basic—src/lib.rstest_condition_evaluation_operators—src/lib.rstest_execution_failure_and_retry—src/lib.rstest_execution_lifecycle—src/lib.rstest_retry_policy_backoff—src/lib.rstest_trigger_creation—src/lib.rstest_trigger_events—src/lib.rstest_action_type_parsing—src/models.rs- _… 10 more_
Documentation coverage
| Measure | Documented | Total |
|---|---|---|
| Public items with rustdoc | 0 | 0 |
Public modules with a //! block | 0 | 0 |
Metrics
| Metric | Value |
|---|---|
| Rust source files | 7 |
| Source lines | 2345 |
| Code lines | 1747 |
| Public API items | 0 |
| Public modules | 0 |
| Tests | 40 |
| Examples | 0 |
| Cargo features | 0 |
| Direct runtime dependencies | 10 |
| Workspace reverse dependencies | 1 |
pie showData
title Rust source composition
"Code" : 1747
"Blank or comment" : 598
Generation
Rendered by tools-corpus corpus readme from repository evidence alone, renderer schema 2, lexicon current. No model, network service or database was consulted. Regenerate with tools-corpus corpus readme --write; verify with --check.