Separate events and notifications into focused modules

The events.rs file mixed three domains: device-event recording, change
detection, and the entire notification pipeline (rendering + delivery +
sending). This made it long, gave functions side effects beyond their
stated goal (classify_* silently recorded events), and intertwined the
events and notifications logic.

Split along domain boundaries:
- model::device_events now owns DeviceChange, the shared contract.
- events records device events only (record_new_device/record_known_device);
  events/detection.rs holds pure change detection.
- new notifications module owns rendering, delivery, and sending
  (notifications.rs + delivery.rs + render.rs); pushover/error moved here.

Data now flows one way: events produces DeviceChange, notifications
consumes it, both depend only on model. Scanners/pipeline/main orchestrate.
classify_* renamed to record_* so the write is the stated goal; send and
send_notification collapsed into persist_and_deliver.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
rzuasti
2026-06-07 09:10:49 -04:00
co-authored by Claude Opus 4.8
parent 9efe84c099
commit 09e7915547
12 changed files with 1000 additions and 915 deletions
+30
View File
@@ -0,0 +1,30 @@
use std::{error, fmt};
#[derive(Debug)]
pub enum DeliveryError {
ParsePushover(pushover::Error),
}
impl fmt::Display for DeliveryError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match *self {
DeliveryError::ParsePushover(..) => {
write!(f, "Error delivering notification via Pushover")
}
}
}
}
impl error::Error for DeliveryError {
fn source(&self) -> Option<&(dyn error::Error + 'static)> {
match *self {
DeliveryError::ParsePushover(ref e) => Some(e),
}
}
}
impl From<pushover::Error> for DeliveryError {
fn from(err: pushover::Error) -> DeliveryError {
DeliveryError::ParsePushover(err)
}
}