feat(family): deploy Single-Writer DuckDB backend, Mila parent cockpit & feeding analytics, and Moritz macro tracker

This commit is contained in:
Moritz Graf
2026-10-17 07:21:49 +02:00
parent ef50d87bd7
commit 5b8432caf4
96 changed files with 16409 additions and 29 deletions
@@ -0,0 +1,129 @@
import tempfile
import pytest
from pathlib import Path
from fastapi.testclient import TestClient
from app.engine import DuckDBEngine
from app.models import EventCreateRequest, EventStopRequest
def test_add_and_stop_sleep_event(tmp_path: Path):
# Use isolated temp directory for write tests so we do not pollute wiki git repo
engine = DuckDBEngine(data_dir=tmp_path)
# 1. Add active sleep event (end=None)
add_req = EventCreateRequest(
kind="sleep.session",
subject="mila",
payload={"type": "nap", "location": "kinderwagen"},
actor="test-runner",
note="Mittagsschlaf Test",
)
res_add = engine.add_event(add_req)
assert res_add["status"] == "success"
event_id = res_add["id"]
assert event_id is not None
# Check that it appears in open sleep
open_rows = engine.query(f"SELECT * FROM sleep WHERE id = '{event_id}' AND (isOpen = true OR endIso IS NULL)")
assert len(open_rows) == 1
# 2. Stop the active sleep event
stop_req = EventStopRequest(
kind="sleep.session",
subject="mila",
event_id=event_id,
actor="test-runner",
)
res_stop = engine.stop_event(stop_req)
assert res_stop["status"] == "success"
assert res_stop["id"] == event_id
# Check that it is now closed
closed_rows = engine.query(f"SELECT isOpen, endIso FROM sleep WHERE id = '{event_id}'")
assert len(closed_rows) == 1
assert closed_rows[0]["isOpen"] is False
assert closed_rows[0]["endIso"] is not None
def test_add_nutrition_and_diaper_event(tmp_path: Path):
engine = DuckDBEngine(data_dir=tmp_path)
# Add nutrition event
nut_req = EventCreateRequest(
kind="nutrition.intake",
subject="moritz",
payload={"item": "Apfel", "qty": 150.0, "kcal": 78.0, "protein_g": 0.5},
meal="snack",
actor="test-runner",
)
res_nut = engine.add_event(nut_req)
assert res_nut["status"] == "success"
nut_id = res_nut["id"]
nut_rows = engine.query(f"SELECT * FROM nutrition WHERE id = '{nut_id}'")
assert len(nut_rows) == 1
# Add diaper event
diaper_req = EventCreateRequest(
kind="diaper.change",
subject="mila",
payload={"pee": True, "poo": False},
actor="test-runner",
)
res_diaper = engine.add_event(diaper_req)
assert res_diaper["status"] == "success"
diaper_id = res_diaper["id"]
diaper_rows = engine.query(f"SELECT * FROM mila WHERE id = '{diaper_id}'")
assert len(diaper_rows) == 1
def test_duplicate_open_sleep_rejected(tmp_path: Path):
engine = DuckDBEngine(data_dir=tmp_path)
# 1. Start first open sleep session
req1 = EventCreateRequest(
kind="sleep.session",
subject="mila",
payload={"type": "nap", "location": "bett"},
actor="parent",
)
res1 = engine.add_event(req1)
assert res1["status"] == "success"
# 2. Attempt to start second open sleep session without stopping the first
req2 = EventCreateRequest(
kind="sleep.session",
subject="mila",
payload={"type": "nap", "location": "kinderwagen"},
actor="parent",
)
with pytest.raises(ValueError, match="already active for subject 'mila'"):
engine.add_event(req2)
def test_duplicate_open_sleep_api_endpoint(client: TestClient):
# 1. Start first session via API
res1 = client.post("/duckdb-api/v1/events", json={
"kind": "sleep.session",
"subject": "test_baby",
"payload": {"type": "nap"},
})
assert res1.status_code == 200
# 2. Start second session via API -> must return 400 Bad Request
res2 = client.post("/duckdb-api/v1/events", json={
"kind": "sleep.session",
"subject": "test_baby",
"payload": {"type": "nap"},
})
assert res2.status_code == 400
assert "already active for subject 'test_baby'" in res2.json()["detail"]
# 3. Clean up by stopping
stop_res = client.post("/duckdb-api/v1/events/stop", json={
"kind": "sleep.session",
"subject": "test_baby",
})
assert stop_res.status_code == 200