feat: utterances API routes — list, clip, tag, dismiss
Adds app/api/main.py (create_app factory with health endpoint), utterances router (GET /api/utterances with date/room/speaker/status filters, GET clip, POST tag, POST dismiss), stub routers for speakers/rooms/search/rag, and tests/routes/ with 6 passing TDD tests. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,86 @@
|
||||
def test_list_utterances_empty(api_client):
|
||||
resp = api_client.get("/api/utterances")
|
||||
assert resp.status_code == 200
|
||||
assert resp.json() == []
|
||||
|
||||
|
||||
def test_list_utterances_with_data(api_client, seeded_db):
|
||||
room = seeded_db.execute("SELECT id FROM rooms WHERE name='Kitchen'").fetchone()
|
||||
seeded_db.execute(
|
||||
"INSERT INTO utterances (room_id, transcript, match_status, start_time, end_time) "
|
||||
"VALUES (?,?,?,?,?)",
|
||||
(room["id"], "hello world", "unknown", "2026-01-01 10:00:00", "2026-01-01 10:00:03"),
|
||||
)
|
||||
seeded_db.commit()
|
||||
resp = api_client.get("/api/utterances")
|
||||
assert resp.status_code == 200
|
||||
data = resp.json()
|
||||
assert len(data) == 1
|
||||
assert data[0]["transcript"] == "hello world"
|
||||
assert data[0]["room_name"] == "Kitchen"
|
||||
|
||||
|
||||
def test_filter_utterances_by_date(api_client, seeded_db):
|
||||
room = seeded_db.execute("SELECT id FROM rooms WHERE name='Kitchen'").fetchone()
|
||||
seeded_db.execute(
|
||||
"INSERT INTO utterances (room_id, transcript, match_status, start_time, end_time) VALUES (?,?,?,?,?)",
|
||||
(room["id"], "today speech", "unknown", "2026-05-27 10:00:00", "2026-05-27 10:00:03"),
|
||||
)
|
||||
seeded_db.execute(
|
||||
"INSERT INTO utterances (room_id, transcript, match_status, start_time, end_time) VALUES (?,?,?,?,?)",
|
||||
(room["id"], "yesterday speech", "unknown", "2026-05-26 10:00:00", "2026-05-26 10:00:03"),
|
||||
)
|
||||
seeded_db.commit()
|
||||
resp = api_client.get("/api/utterances?date=2026-05-27")
|
||||
data = resp.json()
|
||||
assert len(data) == 1
|
||||
assert data[0]["transcript"] == "today speech"
|
||||
|
||||
|
||||
def test_tag_utterance_existing_speaker(api_client, seeded_db):
|
||||
room = seeded_db.execute("SELECT id FROM rooms WHERE name='Kitchen'").fetchone()
|
||||
speaker = seeded_db.execute("SELECT id FROM speakers WHERE name='Jeremy'").fetchone()
|
||||
seeded_db.execute(
|
||||
"INSERT INTO utterances (room_id, transcript, match_status, start_time, end_time, embedding) VALUES (?,?,?,?,?,?)",
|
||||
(room["id"], "tag me", "unknown", "2026-01-01 10:00:00", "2026-01-01 10:00:03",
|
||||
b"\x00" * 1024),
|
||||
)
|
||||
seeded_db.commit()
|
||||
utt = seeded_db.execute("SELECT id FROM utterances").fetchone()
|
||||
resp = api_client.post(f"/api/utterances/{utt['id']}/tag", json={"speaker_id": speaker["id"]})
|
||||
assert resp.status_code == 200
|
||||
updated = seeded_db.execute("SELECT * FROM utterances WHERE id=?", (utt["id"],)).fetchone()
|
||||
assert updated["speaker_id"] == speaker["id"]
|
||||
assert updated["match_status"] == "known"
|
||||
assert updated["match_confidence"] == 1.0
|
||||
|
||||
|
||||
def test_tag_utterance_create_new_speaker(api_client, seeded_db):
|
||||
room = seeded_db.execute("SELECT id FROM rooms WHERE name='Kitchen'").fetchone()
|
||||
seeded_db.execute(
|
||||
"INSERT INTO utterances (room_id, transcript, match_status, start_time, end_time) VALUES (?,?,?,?,?)",
|
||||
(room["id"], "new speaker", "unknown", "2026-01-01 10:00:00", "2026-01-01 10:00:03"),
|
||||
)
|
||||
seeded_db.commit()
|
||||
utt = seeded_db.execute("SELECT id FROM utterances WHERE transcript='new speaker'").fetchone()
|
||||
resp = api_client.post(
|
||||
f"/api/utterances/{utt['id']}/tag",
|
||||
json={"name": "Alice", "create_new": True},
|
||||
)
|
||||
assert resp.status_code == 200
|
||||
alice = seeded_db.execute("SELECT id FROM speakers WHERE name='Alice'").fetchone()
|
||||
assert alice is not None
|
||||
|
||||
|
||||
def test_dismiss_utterance(api_client, seeded_db):
|
||||
room = seeded_db.execute("SELECT id FROM rooms WHERE name='Kitchen'").fetchone()
|
||||
seeded_db.execute(
|
||||
"INSERT INTO utterances (room_id, transcript, match_status, start_time, end_time) VALUES (?,?,?,?,?)",
|
||||
(room["id"], "dismiss me", "unreviewed", "2026-01-01 10:00:00", "2026-01-01 10:00:03"),
|
||||
)
|
||||
seeded_db.commit()
|
||||
utt = seeded_db.execute("SELECT id FROM utterances WHERE transcript='dismiss me'").fetchone()
|
||||
resp = api_client.post(f"/api/utterances/{utt['id']}/dismiss")
|
||||
assert resp.status_code == 200
|
||||
updated = seeded_db.execute("SELECT match_status FROM utterances WHERE id=?", (utt["id"],)).fetchone()
|
||||
assert updated["match_status"] == "unknown"
|
||||
Reference in New Issue
Block a user