feat: consolidate datastore into sleep, nutrition, mila databases

This commit is contained in:
Moritz Graf
2026-10-13 09:28:07 +02:00
parent fe4edcc217
commit 7b5d039323
5 changed files with 896 additions and 161 deletions
+110
View File
@@ -810,6 +810,116 @@ def test_website_growth_html_rendering(temp_datastore: DatastoreEngine):
assert "who_height" in html
def test_feeding_solid_brei_logging(temp_datastore: DatastoreEngine):
"""Verifies feeding solid (Brei/Beikost) events, feedback formatting, and DuckDB views."""
res = temp_datastore.add_event(
kind="feeding.solid",
subject="mila",
actor="agent:mila_tracker",
start="2026-10-12T12:00:00+02:00",
meal="Mittagessen",
payload={
"item": "Kürbis-Kartoffel-Brei",
"amount_g": 130,
"kcal": 95,
},
note="Guter Appetit",
)
assert res["status"] == "success"
fb = res["feedback"]
assert fb["solid_count"] == 1
assert fb["total_solid_g"] == 130.0
assert "130 g" in fb["day_total_formatted"]
assert "Brei" in fb["day_total_formatted"]
assert res["event"]["payload"]["item"] == "Kürbis-Kartoffel-Brei"
# Verify v_feeding view
rows = temp_datastore.query("SELECT * FROM v_feeding WHERE subject = 'mila' AND kind = 'feeding.solid'")
assert len(rows) == 1
assert rows[0]["item"] == "Kürbis-Kartoffel-Brei"
assert rows[0]["solid_g"] == 130.0
assert rows[0]["kcal"] == 95.0
# Verify v_feeding_daily combined aggregation
daily = temp_datastore.query("SELECT * FROM v_feeding_daily WHERE subject = 'mila' AND log_date = '2026-10-12'")
assert len(daily) == 1
assert daily[0]["solid_count"] == 1
assert daily[0]["total_solid_g"] == 130.0
assert daily[0]["total_kcal"] == 95.0
def test_three_databases_isolation_and_reloading(temp_datastore: DatastoreEngine):
"""Verifies that events are routed to sleep/, nutrition/, mila/ databases and reloaded correctly."""
# 1. Sleep session -> sleep/
res_sleep = temp_datastore.add_event(
kind="sleep.session",
subject="mila",
actor="agent:mila_tracker",
start="2026-10-13T09:00:00+02:00",
end="2026-10-13T10:00:00+02:00",
payload={"type": "nap", "location": "bett"},
)
assert res_sleep["status"] == "success"
# 2. Nutrition intake -> nutrition/
res_nut = temp_datastore.add_event(
kind="nutrition.intake",
subject="moritz",
actor="agent:nutrition_tracker",
start="2026-10-13T08:00:00+02:00",
meal="Frühstück",
payload={"item": "Rührei", "qty": 150, "unit": "g", "protein_g": 18.0, "kcal": 210.0},
)
assert res_nut["status"] == "success"
# 3. Diaper change -> mila/
res_diaper = temp_datastore.add_event(
kind="diaper.change",
subject="mila",
actor="agent:mila_tracker",
start="2026-10-13T10:15:00+02:00",
payload={"pee": True, "poo": False},
)
assert res_diaper["status"] == "success"
# Verify file locations on disk
data_dir = temp_datastore.data_dir
sleep_files = list((data_dir / "sleep").glob("*.jsonl"))
nutrition_files = list((data_dir / "nutrition").glob("*.jsonl"))
mila_files = list((data_dir / "mila").glob("*.jsonl"))
assert len(sleep_files) == 1
assert len(nutrition_files) == 1
assert len(mila_files) == 1
assert not (data_dir / "events").exists()
# Re-instantiate engine from disk (cold load test)
reloaded_engine = DatastoreEngine(data_dir=data_dir)
# Check that events union view contains all 3 records
all_events = reloaded_engine.query("SELECT id, kind, subject FROM events ORDER BY start ASC")
assert len(all_events) == 3
kinds = [e["kind"] for e in all_events]
assert "nutrition.intake" in kinds
assert "sleep.session" in kinds
assert "diaper.change" in kinds
# Check domain daily views
s_view = reloaded_engine.query("SELECT total_sleep_minutes FROM v_sleep_daily WHERE subject = 'mila' AND log_date = '2026-10-13'")
assert len(s_view) == 1
assert s_view[0]["total_sleep_minutes"] == 60
n_view = reloaded_engine.query("SELECT total_kcal FROM v_nutrition_daily WHERE subject = 'moritz' AND log_date = '2026-10-13'")
assert len(n_view) == 1
assert n_view[0]["total_kcal"] == 210.0
d_view = reloaded_engine.query("SELECT total_changes, wet_count FROM v_diaper_daily WHERE subject = 'mila' AND log_date = '2026-10-13'")
assert len(d_view) == 1
assert d_view[0]["total_changes"] == 1
assert d_view[0]["wet_count"] == 1