Engine
The engine is the core rule evaluation component. It maps incoming events to notification decisions using per-rule Python evaluators.
Rule Evaluation
For each incoming event:
- The engine resolves matching rules by
rule_idlist or event scenario mapping - Each rule's custom Python evaluator is loaded from
seed/rules/<rule_id>/evaluate.py - The evaluator decides whether the rule should fire given the event payload
- If it fires, the appropriate Jinja2 template is rendered per channel and language
- Per-community rule overrides may modify rule behavior
NudgeType
| NudgeType | Description |
|---|---|
informative |
General information, low urgency |
opportunity |
Actionable suggestion or flexibility window |
alert |
Attention required, higher urgency |
Jinja2 Templates
Templates use the event facts payload as context variables:
{% if delta_pct > 20 %}
Your import from the grid increased by {{ delta_pct|round(1) }}% compared to {{ prev_period }}.
{% else %}
Your import changed by {{ delta_pct|round(1) }}%.
{% endif %}
Templates are organized per channel (web, email) and language. The engine selects the template matching the user's preferred language or falls back to DEFAULT_LANG.
Deduplication Scopes
Deduplication prevents sending the same rule to the same user multiple times within a window:
| Scope | Window |
|---|---|
daily |
Same rule not repeated today |
weekly |
Same rule not repeated this ISO week |
monthly |
Same rule not repeated this month |
yearly |
Same rule not repeated this year |
The dedup key is: rule_id:user_id:community_id:scope.
Notification Kinds
active_kinds.yaml defines the catalog of notification kinds with i18n labels. Users can opt in or out of specific kinds via their preferences.
Rule Overrides
Per-community overrides allow customizing rule behavior (e.g., different thresholds, templates, or enabled status) without modifying the base rule definition.
Seed Directory Structure
Rules are seeded from a directory structure (default ./seed):
seed/
rules/
imported_up/
rule.yaml # Rule definition (kind, nudge_type, severity, etc.)
evaluate.py # Custom Python evaluator
templates/
web_en.j2 # Web push template (English)
web_it.j2 # Web push template (Italian)
email_en.j2 # Email template (English)
flexibility_opportunity/
rule.yaml
evaluate.py
templates/
web_en.j2
...
active_kinds.yaml # Notification kind catalog with i18n
Each rule directory contains:
- rule.yaml — rule metadata (kind, nudge_type, severity, definition)
- evaluate.py — Python module with an evaluate function that receives the event and returns a decision
- templates/ — Jinja2 templates named {channel}_{lang}.j2
Seed Management
# Apply seed data via CLI
nudging-cli seed apply ./seed --client-id celine-cli --client-secret celine-cli
# Or via taskfile
task seed
The CLI authenticates and calls POST /admin/seed/apply to upsert rules and templates from the seed directory.