11 KiB
11 KiB
Parameter Mapping Status
Quick Reference
This document provides a quick overview of what exists and what needs to be implemented for rule parameter mapping.
✅ What Already Exists
Database Schema
- Migration:
migrations/20240103000003_add_rule_action_params.sql - Column:
attune.rule.action_params(JSONB, default{}) - Index:
idx_rule_action_params_gin(GIN index for efficient querying) - Status: ✅ Complete
Data Models
- File:
crates/common/src/models.rs - Struct:
rule::Rulehaspub action_params: JsonValuefield - Status: ✅ Complete
API Layer
- File:
crates/api/src/dto/rule.rs - Request DTOs:
CreateRuleRequest.action_params(with default{})UpdateRuleRequest.action_params(optional)
- Response DTOs:
RuleResponse.action_params
- Status: ✅ Complete
Repository Layer
- File:
crates/common/src/repositories/rule.rs - Operations:
CreateRuleInput.action_paramsincluded in INSERTUpdateRuleInput.action_paramshandled in UPDATE- All SELECT queries include
action_paramscolumn
- Status: ✅ Complete
API Routes
- File:
crates/api/src/routes/rules.rs - Handlers:
create_rule()acceptsaction_paramsfrom requestupdate_rule()updatesaction_paramsif provided
- Status: ✅ Complete
Data Flow (Static Parameters)
Rule.action_params (static JSON)
↓
Enforcement.config (copied verbatim)
↓
Execution.config (passed through)
↓
Worker (receives as action parameters)
- Status: ✅ Working for static values
❌ What's Missing
Template Resolution Logic
- Needed: Parse and resolve
{{ }}templates inaction_params - Location:
crates/sensor/src/(new module needed) - Status: ❌ Not implemented
Template Resolver Module
// NEW FILE: crates/sensor/src/template_resolver.rs
pub struct TemplateContext {
pub trigger_payload: JsonValue,
pub pack_config: JsonValue,
pub system_vars: JsonValue,
}
pub fn resolve_templates(
params: &JsonValue,
context: &TemplateContext
) -> Result<JsonValue> {
// Implementation needed
}
- Status: ❌ Does not exist
Pack Config Loading
- Needed: Load pack configuration from database
- Current: Rule matcher doesn't load pack config
- Required for:
{{ pack.config.* }}templates - Status: ❌ Not implemented
Integration in Rule Matcher
- File:
crates/sensor/src/rule_matcher.rs - Method:
create_enforcement() - Current code (line 309):
let config = Some(&rule.action_params);
- Needed code:
// Load pack config
let pack_config = self.load_pack_config(&rule.pack_ref).await?;
// Build template context
let context = TemplateContext {
trigger_payload: event.payload.clone().unwrap_or_default(),
pack_config,
system_vars: self.build_system_vars(rule, event),
};
// Resolve templates
let resolved_params = resolve_templates(&rule.action_params, &context)?;
let config = Some(resolved_params);
- Status: ❌ Not implemented
Unit Tests
- File:
crates/sensor/src/template_resolver.rs(tests module) - Needed tests:
- Simple string substitution
- Nested object access
- Array element access
- Type preservation
- Missing value handling
- Pack config reference
- System variables
- Multiple templates in one string
- Invalid syntax handling
- Status: ❌ Not implemented
Integration Tests
- Needed: End-to-end test of template resolution
- Scenario: Create rule with templates → fire event → verify enforcement has resolved params
- Status: ❌ Not implemented
📋 Implementation Checklist
Phase 1: MVP (2-3 days)
-
Create template resolver module
- Define
TemplateContextstruct - Implement
resolve_templates()function - Regex pattern matching for
{{ }} - JSON path extraction with dot notation
- Type preservation logic
- Error handling for missing values
- Unit tests (9+ test cases)
- Define
-
Add pack config loading
- Add method to load pack config from database
- Implement in-memory cache with TTL
- Handle missing pack config gracefully
-
Integrate with rule matcher
- Update
create_enforcement()method - Load pack config before resolution
- Build template context
- Call template resolver
- Handle resolution errors
- Log warnings for missing values
- Update
-
System variables
- Build system context (timestamp, rule ID, event ID)
- Document available system variables
-
Testing
- Unit tests for template resolver
- Integration test: end-to-end flow
- Test with missing values
- Test with nested objects
- Test with arrays
- Test performance (benchmark)
-
Documentation
- User documentation (
docs/rule-parameter-mapping.md) ✅ - API documentation updates (
docs/api-rules.md) ✅ - Code documentation (inline comments)
- Update sensor service docs
- User documentation (
Phase 2: Advanced Features (1-2 days, future)
-
Default values
- Parse
| default: 'value'syntax - Apply defaults when value is null/missing
- Unit tests
- Parse
-
Filters
upper- Convert to uppercaselower- Convert to lowercasetrim- Remove whitespacedate: <format>- Format timestamptruncate: <length>- Truncate stringjson- Serialize to JSON string- Unit tests for each filter
-
Performance optimization
- Cache compiled regex patterns
- Skip resolution if no
{{ }}found - Parallel template resolution
- Benchmark improvements
🔍 Key Implementation Details
Current Enforcement Creation (line 306-348)
async fn create_enforcement(&self, rule: &Rule, event: &Event) -> Result<Id> {
let payload = event.payload.clone().unwrap_or_default();
let config = Some(&rule.action_params); // ← This line needs to change
let enforcement_id = sqlx::query_scalar!(
r#"
INSERT INTO attune.enforcement
(rule, rule_ref, trigger_ref, config, event, status, payload, condition, conditions)
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)
RETURNING id
"#,
Some(rule.id),
&rule.r#ref,
&rule.trigger_ref,
config, // ← Resolved params go here
Some(event.id),
EnforcementStatus::Created as EnforcementStatus,
payload,
EnforcementCondition::All as EnforcementCondition,
&rule.conditions
)
.fetch_one(&self.db)
.await?;
// ... rest of method
}
Template Examples
Input (Rule):
{
"action_params": {
"message": "Error in {{ trigger.payload.service }}: {{ trigger.payload.message }}",
"channel": "{{ pack.config.alert_channel }}",
"severity": "{{ trigger.payload.severity }}"
}
}
Context:
{
"trigger": {
"payload": {
"service": "api-gateway",
"message": "Connection timeout",
"severity": "critical"
}
},
"pack": {
"config": {
"alert_channel": "#incidents"
}
}
}
Output (Enforcement):
{
"config": {
"message": "Error in api-gateway: Connection timeout",
"channel": "#incidents",
"severity": "critical"
}
}
📊 Dependencies
Existing (Already in Cargo.toml)
serde_json- JSON manipulation ✅regex- Pattern matching ✅anyhow- Error handling ✅sqlx- Database access ✅
New Dependencies
- None required - Can implement with existing dependencies
🎯 Success Criteria
- Static parameters continue to work unchanged
- Can reference
{{ trigger.payload.* }}fields - Can reference
{{ pack.config.* }}fields - Can reference
{{ system.* }}variables - Type preservation (strings, numbers, booleans, objects, arrays)
- Nested object access with dot notation works
- Array element access by index works
- Missing values handled gracefully (null + warning)
- Invalid syntax handled gracefully (literal + error)
- Unit tests pass (90%+ coverage)
- Integration tests pass
- Documentation accurate and complete
- No performance regression (<500µs overhead)
- Backward compatibility maintained (100%)
🚀 Getting Started
-
Read documentation:
docs/rule-parameter-mapping.md- User guidework-summary/2026-01-17-parameter-templating.md- Technical spec
-
Review current code:
crates/sensor/src/rule_matcher.rs:306-348- Where to integratecrates/common/src/models.rs- Rule model structuremigrations/20240103000003_add_rule_action_params.sql- Schema
-
Start implementation:
- Create
crates/sensor/src/template_resolver.rs - Write unit tests first (TDD approach)
- Implement template parsing and resolution
- Integrate with rule_matcher
- Run integration tests
- Create
-
Test thoroughly:
- Unit tests for all edge cases
- Integration test with real database
- Manual testing with example rules
- Performance benchmarks
📚 Related Documentation
- Rule Parameter Mapping Guide - Complete user documentation
- Rule Management API - API reference with examples
- Sensor Service Architecture - Service overview
- Implementation Plan - Technical specification
- Session Summary - Discovery notes
🏷️ Status Summary
| Component | Status | Notes |
|---|---|---|
| Database schema | ✅ Complete | action_params column exists |
| Data models | ✅ Complete | Rule struct has field |
| API DTOs | ✅ Complete | Request/response support |
| API routes | ✅ Complete | CRUD operations work |
| Repository | ✅ Complete | All queries include field |
| Static parameters | ✅ Working | Flow end-to-end |
| Template resolver | ❌ Missing | Core implementation needed |
| Pack config loading | ❌ Missing | Required for {{ pack.config }} |
| Integration | ❌ Missing | Need to wire up resolver |
| Unit tests | ❌ Missing | Tests for resolver needed |
| Integration tests | ❌ Missing | E2E test needed |
| Documentation | ✅ Complete | User and tech docs done |
Overall Status: 📝 Documented, ⏳ Implementation Pending
Priority: P1 (High)
Estimated Effort: 2-3 days (MVP), 1-2 days (advanced features)
Risk: Low (backward compatible, well-scoped, clear requirements)
Value: High (unlocks production use cases, user expectation)