feat(measure): memorizza tempo di inserimento misura (input_duration_ms)

Colonna nullable su measurements + migration 003, campo opzionale negli
schemi API (create singola e batch), passthrough nel proxy Flask e timer
lato client in task_execute: parte all'attivazione del subtask, si
resetta su auto-advance e navigazione manuale.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
2026-07-28 14:32:35 +02:00
parent edb7eb382c
commit 3f03ec8ab1
9 changed files with 141 additions and 0 deletions
@@ -80,6 +80,45 @@ class TestSaveMeasurement:
assert data["id"] == 1
assert data["pass_fail"] == "pass"
def test_save_measurement_forwards_input_duration(
self, logged_in_client, mock_api_client
):
"""input_duration_ms is forwarded to the backend payload."""
mock_api_client.post.return_value = {"id": 1, "pass_fail": "pass"}
resp = logged_in_client.post(
"/measure/save-measurement",
json={
"subtask_id": 10,
"version_id": 3,
"value": 9.95,
"input_duration_ms": 4250,
},
content_type="application/json",
)
assert resp.status_code == 201
payload = mock_api_client.post.call_args.kwargs["data"]
assert payload["input_duration_ms"] == 4250
def test_save_measurement_omits_input_duration_when_absent(
self, logged_in_client, mock_api_client
):
"""Without input_duration_ms the payload sends null (backend default)."""
mock_api_client.post.return_value = {"id": 1, "pass_fail": "pass"}
resp = logged_in_client.post(
"/measure/save-measurement",
json={
"subtask_id": 10,
"version_id": 3,
"value": 9.95,
},
content_type="application/json",
)
assert resp.status_code == 201
payload = mock_api_client.post.call_args.kwargs["data"]
assert payload.get("input_duration_ms") is None
def test_save_measurement_missing_fields(self, logged_in_client, mock_api_client):
"""Missing required fields return 400."""
resp = logged_in_client.post(