Close lifecycle transition helper workplan

This commit is contained in:
2026-05-23 18:42:32 +02:00
parent ab23ef4f1f
commit 0ea46f081c
8 changed files with 221 additions and 19 deletions

View File

@@ -7,6 +7,8 @@ from api.services.lifecycle import (
should_activate_parent_for_active_tasks,
should_activate_parent_for_task_start,
status_value,
transition_task_status,
transition_workstream_status,
)
@@ -66,3 +68,34 @@ def test_status_value_unwraps_enum_like_values():
value = "In_Progress"
assert status_value(Status()) == "in_progress"
def test_transition_workstream_status_normalizes_aliases():
class Workstream:
status = "todo"
ws = Workstream()
result = transition_workstream_status(ws, "done")
assert ws.status == "finished"
assert result.previous_status == "ready"
assert result.target_status == "finished"
assert result.changed is True
def test_transition_task_status_activates_parent_once():
class Task:
status = "todo"
class Workstream:
status = "ready"
task = Task()
ws = Workstream()
result = transition_task_status(task, "in_progress", parent_workstream=ws)
assert task.status == "in_progress"
assert ws.status == "active"
assert result.parent_activated is True
assert result.previous_status == "todo"
assert result.target_status == "in_progress"

View File

@@ -597,6 +597,58 @@ class TestReconciliationEndpoints:
r = await client.get(f"/tasks/{task['id']}")
assert r.json()["status"] == "in_progress"
async def test_apply_task_start_write_through_activates_parent_file_and_db(self, client, tmp_path):
await _create_domain(client)
repo_root = tmp_path / "repo"
workplans = repo_root / "workplans"
workplans.mkdir(parents=True)
repo = await _create_repo(client, local_path=repo_root)
topic = await _create_topic(client)
ws = await _create_workstream(client, topic["id"], repo_id=repo["id"], status="ready")
task = await _create_task(client, ws["id"])
wp = workplans / "STATE-WP-9999-demo.md"
wp.write_text(
"---\n"
"id: STATE-WP-9999\n"
"type: workplan\n"
"title: Demo\n"
"domain: custodian\n"
"repo: state-hub\n"
"status: ready\n"
f"state_hub_workstream_id: \"{ws['id']}\"\n"
"---\n\n"
"## Demo Task\n\n"
"```task\n"
"id: STATE-WP-9999-T01\n"
"status: todo\n"
"priority: high\n"
f"state_hub_task_id: \"{task['id']}\"\n"
"```\n",
encoding="utf-8",
)
r = await client.post("/reconciliation/state-change", json={
"target_type": "task",
"target_id": task["id"],
"target_status": "in_progress",
"actor": "dashboard",
"expected_current_status": "todo",
"apply": True,
})
assert r.status_code == 200, r.text
body = r.json()
assert body["write_through_result"] == "applied"
text = wp.read_text(encoding="utf-8")
assert "status: active" in text
assert "status: in_progress" in text
r = await client.get(f"/workstreams/{ws['id']}")
assert r.json()["status"] == "active"
r = await client.get(f"/tasks/{task['id']}")
assert r.json()["status"] == "in_progress"
async def test_apply_task_confirmation_case_creates_reconciliation_message(self, client, tmp_path):
await _create_domain(client)
repo_root = tmp_path / "repo"