Publish consistent measured drive activity (#89)

Repair the collection-to-display path so each successful acquisition
publishes correct read/write deltas through the observation store and
visible dashboard.

Fixes:
- derive.py: accumulate bytes_read_delta on same-hour hour_observation
  merge (was silently dropped)
- collector.py: rebuild day_aggregates from hour observations after
  each collection run (previously only populated for cross-hour intervals)
- day_aggregate.py: add persist_day_aggregate upsert helper
- tui.py: query and display both read and write deltas in daily and
  hourly readouts, constrained summaries, and graph data queries

Tests:
- Add 14 integration tests (test_measured_activity.py) exercising the
  full collector→store→reader→display path with real fixtures and
  injected time
- Update constrained-layout assertion to match new W/R format

Closes #89
This commit is contained in:
xavierk
2026-09-17 17:43:31 +05:30
parent 54cd56e4ec
commit 366c2f55b7
6 changed files with 693 additions and 49 deletions
+7 -1
View File
@@ -325,7 +325,7 @@ def run_collection(
# Find the sample we just wrote
cursor = conn.execute("SELECT id FROM samples ORDER BY id DESC LIMIT 1")
current_id = cursor.fetchone()[0]
prev = find_previous_sample(conn, seg_info.get("segment_id"), current_id)
if prev is not None:
# Build current sample dict for derivation
@@ -340,6 +340,12 @@ def run_collection(
"data_units_read": sample["data_units_read"],
}
derive_hours_from_interval(conn, prev, current)
# Rebuild day aggregates from hour observations
from .day_aggregate import derive_all_days, persist_day_aggregate
for agg in derive_all_days(conn):
persist_day_aggregate(conn, agg)
conn.commit()
except Exception:
# Derivation failure must not prevent sample persistence (issue #73 AC6)
pass