feat: drawer witness flag inline-edit (T72.3)
Memories grow per-flag witness checkboxes (you / host / guest) that
auto-submit on change via HTMX. The new POST route emits a manual_edit
event with target_kind=memory_witness and a {flag, value} payload;
prior_value mirrors the same shape so an inverse edit restores the
flag. The drawer's recent-memories query now selects the three
witness columns alongside the existing fields so the template can
render checkbox state without a second query per row.
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
"""T72.1: deferred v1 drawer edits.
|
||||
"""T72: deferred v1 drawer edits + witness flag inline-edit.
|
||||
|
||||
T25 shipped affinity / significance / pin. T72.1 fills in the rest of the
|
||||
§6.4 editable surface whose ``manual_edit`` projector dispatch was already
|
||||
@@ -9,11 +9,14 @@ in place (or, for ``edge_knowledge_fact``, added alongside the route):
|
||||
* ``POST /chats/{chat_id}/drawer/memory/pov-summary`` — textarea, capped.
|
||||
* ``POST /chats/{chat_id}/drawer/edge/knowledge-facts`` — add/remove fact.
|
||||
|
||||
T72.3 layers a witness-flag toggle on top:
|
||||
|
||||
* ``POST /chats/{chat_id}/drawer/memory/witness`` — ``manual_edit`` with
|
||||
``target_kind`` = ``memory_witness`` and a ``{flag, value}`` payload.
|
||||
|
||||
Each test asserts (a) the ``manual_edit`` event lands in the log,
|
||||
(b) the projected table reflects the new value, and (c) the response is
|
||||
the refreshed drawer partial.
|
||||
|
||||
T72.3's witness-flag tests extend this file with the inline-edit pair.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
@@ -325,3 +328,76 @@ def test_edit_edge_knowledge_facts_400_on_bad_action(client, tmp_path):
|
||||
assert response.status_code == 400
|
||||
|
||||
|
||||
# --- T72.3 tests (witness flag inline-edit) -------------------------------
|
||||
|
||||
|
||||
def test_witness_flag_toggle_updates_memory_row(client, tmp_path):
|
||||
"""Memory seeded with witness [you=1, host=1, guest=0]; toggling
|
||||
``guest`` to 1 lands as ``witness_guest = 1`` after projection.
|
||||
"""
|
||||
_seed(tmp_path / "test.db")
|
||||
with open_db(tmp_path / "test.db") as conn:
|
||||
memory_id = conn.execute("SELECT id FROM memories LIMIT 1").fetchone()[0]
|
||||
|
||||
response = client.post(
|
||||
"/chats/chat_bot_a/drawer/memory/witness",
|
||||
data={
|
||||
"memory_id": str(memory_id),
|
||||
"flag": "guest",
|
||||
"new_value": "1",
|
||||
},
|
||||
)
|
||||
assert response.status_code == 200
|
||||
|
||||
with open_db(tmp_path / "test.db") as conn:
|
||||
row = conn.execute(
|
||||
"SELECT witness_you, witness_host, witness_guest "
|
||||
"FROM memories WHERE id = ?",
|
||||
(memory_id,),
|
||||
).fetchone()
|
||||
assert row == (1, 1, 1)
|
||||
|
||||
|
||||
def test_witness_flag_toggle_emits_manual_edit_event(client, tmp_path):
|
||||
_seed(tmp_path / "test.db")
|
||||
with open_db(tmp_path / "test.db") as conn:
|
||||
memory_id = conn.execute("SELECT id FROM memories LIMIT 1").fetchone()[0]
|
||||
|
||||
response = client.post(
|
||||
"/chats/chat_bot_a/drawer/memory/witness",
|
||||
data={
|
||||
"memory_id": str(memory_id),
|
||||
"flag": "guest",
|
||||
"new_value": "1",
|
||||
},
|
||||
)
|
||||
assert response.status_code == 200
|
||||
|
||||
with open_db(tmp_path / "test.db") as conn:
|
||||
rows = conn.execute(
|
||||
"SELECT payload_json FROM event_log WHERE kind = 'manual_edit'"
|
||||
).fetchall()
|
||||
assert len(rows) == 1
|
||||
payload = json.loads(rows[0][0])
|
||||
assert payload["target_kind"] == "memory_witness"
|
||||
assert payload["target_id"] == memory_id
|
||||
assert payload["prior_value"] == {"flag": "guest", "value": 0}
|
||||
assert payload["new_value"] == {"flag": "guest", "value": 1}
|
||||
|
||||
|
||||
def test_witness_flag_toggle_400_on_bad_flag(client, tmp_path):
|
||||
_seed(tmp_path / "test.db")
|
||||
with open_db(tmp_path / "test.db") as conn:
|
||||
memory_id = conn.execute("SELECT id FROM memories LIMIT 1").fetchone()[0]
|
||||
|
||||
response = client.post(
|
||||
"/chats/chat_bot_a/drawer/memory/witness",
|
||||
data={
|
||||
"memory_id": str(memory_id),
|
||||
"flag": "narrator",
|
||||
"new_value": "1",
|
||||
},
|
||||
)
|
||||
assert response.status_code == 400
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user