This demonstrates how rules are added or updated in the database, ensuring flexibility for users to customize their monitoring setup.

Design Decisions

Rules are designed to be flexible and namespace-specific to avoid cross-contamination between different user environments. The use of wildcards (e.g., "*" for watching all nodes) allows for broad monitoring, while specific conditions prevent notification overload. Additionally, the acknowledgment mechanism (via ack) helps manage alert fatigue by suppressing rules until they are manually reset.

Dispatching Notifications

The notification dispatching process occurs when a node's state changes, triggering an evaluation of relevant rules. This is handled by the dispatchNotifications function, which checks for changes in effective states and propagates notifications to affected nodes.

How Dispatching Works

  1. State Change Detection: When a node's state updates, the system computes the new effective state using functions from the graph module (see Effective State).
  2. Affected Nodes Identification: The function identifies the changed node and any downstream nodes that might be impacted.
  3. Rule Matching: For each affected node, the system queries the database for active rules and checks if they match the node's ID and new effective state.
  4. Notification Sending: Matching rules trigger the appropriate delivery method (webhook or email).
  5. Event Logging: All state changes are logged in the events table for auditing (see Event Logging).

The following code snippet from dispatcher.ts illustrates the core dispatching logic:

export function dispatchNotifications(
  db: Database,
  nsId: number,
  namespace: string,
  nodeId: string,
  previousState: string | null,
  newState: string,
  previousEffectiveState: string | null,
  reason?: string | null,
  solution?: string | null,
  legendumToken?: string | null
): void {
  const newEffectiveState = computeEffectiveState(db, nsId, nodeId);
  // ... (logging and affected nodes calculation)
  const rules = db
    .query("SELECT * FROM notification_rules WHERE ns_id = ? AND suppressed = 0")
    .all(nsId) as NotificationRule[];

  for (const affected of affectedNodes) {
    for (const rule of rules) {
      if (!ruleMatchesNode(rule, affected.id) || !ruleMatchesState(rule, affected.newEffective)) {
        continue;
      }
      // Prepare and send payload via webhook or email
      if (rule.url) {
        sendWebhook(rule.url, payload, rule.secret);
      }
      if (rule.email) {
        sendEmail(rule.email, payload);
      }
    }
  }
}
Recent changes