M5-T07: add latest-reading cards and Recharts trend charts; readings return most-recent rows

This commit is contained in:
2026-06-22 14:17:59 +02:00
parent 2dc469274a
commit 68165f0e01
13 changed files with 1454 additions and 23 deletions
+44
View File
@@ -548,6 +548,7 @@ def test_readings_time_window_filters_correctly(modbus_client):
def test_readings_limit_applied(modbus_client):
"""When limit < total rows, exactly *limit* items are returned."""
client, engine = modbus_client
_login(client)
device = _make_device(engine)
@@ -564,6 +565,49 @@ def test_readings_limit_applied(modbus_client):
assert len(resp.json()["items"]) == 3
def test_readings_limit_returns_most_recent_rows_ascending(modbus_client):
"""When window rows > limit, the MOST RECENT limit rows are returned, ascending.
This is the regression test for REWORK-1: previously the endpoint returned
the oldest N rows (ASC + LIMIT), causing 6h/24h charts to show stale data.
Now it returns the most recent N rows (DESC + LIMIT, then reversed to ASC).
"""
client, engine = modbus_client
_login(client)
device = _make_device(engine)
now = datetime.now(UTC)
# Insert 5 readings spread over the last 5 minutes (newest first, but order shouldn't matter).
timestamps = [now - timedelta(minutes=i) for i in range(5)] # t0=now, t1=now-1m, ..., t4=now-4m
for idx, ts in enumerate(timestamps):
_make_reading(engine, device.id, ts, {"voltage": float(200 + idx)})
# Chronologically: t4 < t3 < t2 < t1 < t0
# Voltages mapped: 204 203 202 201 200
# Request only the most recent 3 rows (limit=3).
resp = client.get(
f"/api/modbus/devices/{device.uuid}/readings",
params={"limit": 3},
)
assert resp.status_code == 200
items = resp.json()["items"]
assert len(items) == 3
# Response must be in ascending recorded_at order.
recorded_ats = [item["recorded_at"] for item in items]
assert recorded_ats == sorted(recorded_ats), "Items must be ascending by recorded_at"
# The 3 most recent are timestamps[0], [1], [2] → voltages 200, 201, 202.
voltages = [item["payload"]["voltage"] for item in items]
assert voltages == [202.0, 201.0, 200.0], (
f"Expected most recent 3 rows (voltages 200/201/202 ascending), got {voltages}"
)
# The oldest row (voltage 204.0, at t4=now-4m) must NOT be in the response.
assert 204.0 not in voltages, "Oldest row must not appear when limit truncates the window"
assert 203.0 not in voltages, "Second-oldest row must not appear when limit truncates"
def test_readings_limit_exceeds_max_returns_422(modbus_client):
"""A limit > 5000 must be rejected by FastAPI query validation (422)."""
client, engine = modbus_client