Use server-side date filtering for device event history chart

The device event history chart previously fetched all events and filtered
client-side. This wires the existing created_from API parameter to the
frontend so filtering happens in the backend.

Also fixes a bug where the Today filter returned no results: rusqlite was
storing datetimes with a space separator ("YYYY-MM-DD HH:MM:SS+00:00")
while SQL filters used RFC 3339 with a T separator, causing string
comparisons to fail for same-day events. All datetime storage across
device_events, devices, and notifications is now consistently RFC 3339.
A migration converts existing records.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
rzuasti
2026-05-28 10:51:19 -04:00
co-authored by Claude Sonnet 4.6
parent 2e8604a354
commit e1287e5a0f
9 changed files with 42 additions and 49 deletions
+2 -2
View File
@@ -13,7 +13,7 @@ pub fn insert(event: DeviceEvent) -> Result<i64, DbError> {
"INSERT INTO device_events (mac_address, created_on, event_type, ipv4_address, vendor) VALUES (?1, ?2, ?3, ?4, ?5)",
params![
event.mac_address,
event.created_on,
event.created_on.to_rfc3339_opts(chrono::SecondsFormat::Nanos, false),
event.event_type,
event.ipv4_address,
event.vendor
@@ -92,7 +92,7 @@ pub fn purge_older_than(cutoff: DateTime<Utc>) -> Result<usize, DbError> {
match conn.execute(
"DELETE FROM device_events WHERE created_on < ?1",
params![cutoff],
params![cutoff.to_rfc3339()],
) {
Ok(count) => {
debug!("Purged {} device event(s) older than {}", count, cutoff);
+6 -22
View File
@@ -27,30 +27,14 @@ pub fn list_devices(
params.push(is_registered.into());
};
if let Some(last_seen_from) = last_seen_from {
debug!(
"Adding filter last_seen>={}",
last_seen_from.format("%Y-%m-%d %H:%M:%S")
);
debug!("Adding filter last_seen>={}", last_seen_from.to_rfc3339());
sql_statement.push_str("AND last_seen>=? ");
params.push(
last_seen_from
.format("%Y-%m-%d %H:%M:%S")
.to_string()
.into(),
);
params.push(last_seen_from.to_rfc3339().into());
};
if let Some(last_seen_to) = last_seen_to {
debug!(
"Adding filter last_seen<={}",
last_seen_to.format("%Y-%m-%d %H:%M:%S")
);
debug!("Adding filter last_seen<={}", last_seen_to.to_rfc3339());
sql_statement.push_str("AND last_seen<=? ");
params.push(
last_seen_to
.format("%Y-%m-%d %H:%M:%S")
.to_string()
.into(),
);
params.push(last_seen_to.to_rfc3339().into());
};
if let Some(owner) = owner {
debug!("Adding filter owner={}", owner);
@@ -126,7 +110,7 @@ pub fn insert(device: Device) -> Result<(), DbError> {
match conn.execute(
"INSERT INTO devices (mac_address, ipv4_address, vendor, last_seen, is_registered, owner, device_type) VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7)",
params![device.mac_address, device.ipv4_address, device.vendor, device.last_seen, device.is_registered, device.owner, device.device_type]) {
params![device.mac_address, device.ipv4_address, device.vendor, device.last_seen.to_rfc3339_opts(chrono::SecondsFormat::Nanos, false), device.is_registered, device.owner, device.device_type]) {
Ok(_) => {
debug!("Device inserted into database: {}", device);
Ok(())
@@ -145,7 +129,7 @@ pub fn update(device: Device) -> Result<(), DbError> {
params![
device.ipv4_address,
device.vendor,
device.last_seen,
device.last_seen.to_rfc3339_opts(chrono::SecondsFormat::Nanos, false),
device.is_registered,
device.owner,
device.device_type,
+2 -2
View File
@@ -67,7 +67,7 @@ pub fn insert(notification: Notification) -> Result<i64, DbError> {
match conn.execute(
"INSERT INTO notifications (created_on, notification_type, title, body, is_new, mac_address) VALUES (?1, ?2, ?3, ?4, ?5, ?6)",
params![notification.created_on, notification.notification_type, notification.title, notification.body, notification.is_new, notification.mac_address]) {
params![notification.created_on.to_rfc3339_opts(chrono::SecondsFormat::Nanos, false), notification.notification_type, notification.title, notification.body, notification.is_new, notification.mac_address]) {
Ok(_) => {
debug!("Notification inserted into database: {}", notification);
Ok(conn.last_insert_rowid())
@@ -129,7 +129,7 @@ pub fn purge_older_than(cutoff: DateTime<Utc>) -> Result<usize, DbError> {
match conn.execute(
"DELETE FROM notifications WHERE created_on < ?1",
params![cutoff],
params![cutoff.to_rfc3339()],
) {
Ok(count) => {
debug!("Purged {} notification(s) older than {}", count, cutoff);