alerts
Readings come in; a limit decides who hears about it. alerts.notify stands in for a real channel such as email or a push message: here it only records what it would send, in ctx.sent, the flow's shared state, so a story can check it.
$when alerts.check (readings: Array, limit: Float) {
high = readings filter (r => r.value > limit)
if (high is empty) {
payload = "all normal"
} else {
names = high map (r => r.sensor) mkString ", "
alerts.notify (to = "on-call", text = "over ${limit}: ${names}")
if (readings exists (r => r.value > limit * 2.0)) {
alerts.notify (to = "manager", text = "critical: ${names}")
}
payload = high map (r => r.sensor)
}
}
Every notification goes through this one rule, so there's one place to change when a real channel arrives. Reading sent finds the flow's value; writing ctx.sent changes it for everyone.
$when alerts.notify (to: String, text: String) {
ctx.sent = (sent ?? []) ++ [{to: to, text: text}]
}