Stop dual-writing workstream_id on State Hub progress POSTs
Progress scope helpers and schedule-miss alerts now send workplan_id only. Legacy workstream_id in sink config still maps to workplan_id on the wire.
This commit is contained in:
parent
f171bb037a
commit
5a9292319e
6 changed files with 10 additions and 12 deletions
|
|
@ -178,7 +178,6 @@ def post_missed_fire_alert(
|
||||||
scope_id = workplan_id or workstream_id
|
scope_id = workplan_id or workstream_id
|
||||||
if scope_id:
|
if scope_id:
|
||||||
body["workplan_id"] = scope_id
|
body["workplan_id"] = scope_id
|
||||||
body["workstream_id"] = scope_id
|
|
||||||
|
|
||||||
# Dedup repeated alerts for the same missed window (same schedule + last fire).
|
# Dedup repeated alerts for the same missed window (same schedule + last fire).
|
||||||
last_fired = health.last_fired_at.isoformat() if health.last_fired_at else "none"
|
last_fired = health.last_fired_at.isoformat() if health.last_fired_at else "none"
|
||||||
|
|
|
||||||
|
|
@ -23,13 +23,12 @@ IDEMPOTENCY_HEADER = "Idempotency-Key"
|
||||||
def apply_progress_scope_fields(body: dict[str, Any], source: dict[str, Any]) -> None:
|
def apply_progress_scope_fields(body: dict[str, Any], source: dict[str, Any]) -> None:
|
||||||
"""Copy topic/workplan/task/decision scope from a sink config into a progress body.
|
"""Copy topic/workplan/task/decision scope from a sink config into a progress body.
|
||||||
|
|
||||||
Prefers ``workplan_id``; dual-writes ``workstream_id`` for wire-compat until
|
Prefers ``workplan_id``; accepts legacy ``workstream_id`` in sink config only
|
||||||
legacy-meter retires the alias.
|
as a fallback source (maps to ``workplan_id`` on the wire).
|
||||||
"""
|
"""
|
||||||
workplan_id = source.get("workplan_id") or source.get("workstream_id")
|
workplan_id = source.get("workplan_id") or source.get("workstream_id")
|
||||||
if workplan_id:
|
if workplan_id:
|
||||||
body["workplan_id"] = workplan_id
|
body["workplan_id"] = workplan_id
|
||||||
body["workstream_id"] = workplan_id
|
|
||||||
for key in ("topic_id", "task_id", "decision_id"):
|
for key in ("topic_id", "task_id", "decision_id"):
|
||||||
if source.get(key):
|
if source.get(key):
|
||||||
body[key] = source[key]
|
body[key] = source[key]
|
||||||
|
|
|
||||||
|
|
@ -124,7 +124,7 @@ def test_state_hub_progress_sink_posts_compact_probe_summary(monkeypatch) -> Non
|
||||||
body = posts[0]["json"]
|
body = posts[0]["json"]
|
||||||
assert body["summary"] == "Ops inventory probe: 1 ok, 0 degraded, 0 down, 1 skipped"
|
assert body["summary"] == "Ops inventory probe: 1 ok, 0 degraded, 0 down, 1 skipped"
|
||||||
assert body["workplan_id"] == "workstream-1"
|
assert body["workplan_id"] == "workstream-1"
|
||||||
assert body["workstream_id"] == "workstream-1"
|
assert "workstream_id" not in body
|
||||||
assert body["task_id"] == "task-1"
|
assert body["task_id"] == "task-1"
|
||||||
assert body["detail"]["activity_core_run_id"] == _run_id()
|
assert body["detail"]["activity_core_run_id"] == _run_id()
|
||||||
assert body["detail"]["idempotency_key"] == result[0]["idempotency_key"]
|
assert body["detail"]["idempotency_key"] == result[0]["idempotency_key"]
|
||||||
|
|
@ -192,7 +192,7 @@ def test_legacy_meter_weekly_review_sink_posts_progress(monkeypatch) -> None:
|
||||||
assert body["event_type"] == "legacy_meter_weekly_review"
|
assert body["event_type"] == "legacy_meter_weekly_review"
|
||||||
assert "2 retirement candidate(s)" in body["summary"]
|
assert "2 retirement candidate(s)" in body["summary"]
|
||||||
assert body["workplan_id"] == "923bb94a-d16c-422c-b81e-16328bd7b60c"
|
assert body["workplan_id"] == "923bb94a-d16c-422c-b81e-16328bd7b60c"
|
||||||
assert body["workstream_id"] == "923bb94a-d16c-422c-b81e-16328bd7b60c"
|
assert "workstream_id" not in body
|
||||||
|
|
||||||
|
|
||||||
def test_state_hub_progress_prefers_workplan_id(monkeypatch) -> None:
|
def test_state_hub_progress_prefers_workplan_id(monkeypatch) -> None:
|
||||||
|
|
@ -221,7 +221,7 @@ def test_state_hub_progress_prefers_workplan_id(monkeypatch) -> None:
|
||||||
|
|
||||||
body = posts[0]["json"]
|
body = posts[0]["json"]
|
||||||
assert body["workplan_id"] == "workplan-1"
|
assert body["workplan_id"] == "workplan-1"
|
||||||
assert body["workstream_id"] == "workplan-1"
|
assert "workstream_id" not in body
|
||||||
|
|
||||||
|
|
||||||
def test_core_hub_stabilization_sink_posts_progress(monkeypatch) -> None:
|
def test_core_hub_stabilization_sink_posts_progress(monkeypatch) -> None:
|
||||||
|
|
|
||||||
|
|
@ -117,7 +117,7 @@ def test_state_hub_progress_sink_posts(monkeypatch) -> None:
|
||||||
]
|
]
|
||||||
assert posts[0]["url"] == "http://state-hub.test/progress/"
|
assert posts[0]["url"] == "http://state-hub.test/progress/"
|
||||||
assert posts[0]["json"]["workplan_id"] == "workstream-1"
|
assert posts[0]["json"]["workplan_id"] == "workstream-1"
|
||||||
assert posts[0]["json"]["workstream_id"] == "workstream-1"
|
assert "workstream_id" not in posts[0]["json"]
|
||||||
assert posts[0]["json"]["detail"]["activity_core_run_id"] == payload_run_id()
|
assert posts[0]["json"]["detail"]["activity_core_run_id"] == payload_run_id()
|
||||||
assert posts[0]["json"]["detail"]["output_validated"] is True
|
assert posts[0]["json"]["detail"]["output_validated"] is True
|
||||||
assert posts[0]["json"]["detail"]["review_required"] is False
|
assert posts[0]["json"]["detail"]["review_required"] is False
|
||||||
|
|
|
||||||
|
|
@ -98,7 +98,7 @@ def test_post_missed_fire_alert_dual_writes_workplan_scope(monkeypatch) -> None:
|
||||||
assert result["status"] == "posted"
|
assert result["status"] == "posted"
|
||||||
body = posts[0]["json"]
|
body = posts[0]["json"]
|
||||||
assert body["workplan_id"] == "wp-123"
|
assert body["workplan_id"] == "wp-123"
|
||||||
assert body["workstream_id"] == "wp-123"
|
assert "workstream_id" not in body
|
||||||
|
|
||||||
|
|
||||||
def test_no_interval_and_no_fire_is_not_flagged() -> None:
|
def test_no_interval_and_no_fire_is_not_flagged() -> None:
|
||||||
|
|
|
||||||
|
|
@ -41,15 +41,15 @@ def test_apply_progress_scope_prefers_workplan_id() -> None:
|
||||||
{"workplan_id": "wp-1", "workstream_id": "ws-legacy", "topic_id": "topic-1"},
|
{"workplan_id": "wp-1", "workstream_id": "ws-legacy", "topic_id": "topic-1"},
|
||||||
)
|
)
|
||||||
assert body["workplan_id"] == "wp-1"
|
assert body["workplan_id"] == "wp-1"
|
||||||
assert body["workstream_id"] == "wp-1"
|
assert "workstream_id" not in body
|
||||||
assert body["topic_id"] == "topic-1"
|
assert body["topic_id"] == "topic-1"
|
||||||
|
|
||||||
|
|
||||||
def test_apply_progress_scope_dual_writes_legacy_workstream_id() -> None:
|
def test_apply_progress_scope_maps_legacy_workstream_config_to_workplan_id() -> None:
|
||||||
body: dict[str, str] = {}
|
body: dict[str, str] = {}
|
||||||
apply_progress_scope_fields(body, {"workstream_id": "ws-1"})
|
apply_progress_scope_fields(body, {"workstream_id": "ws-1"})
|
||||||
assert body["workplan_id"] == "ws-1"
|
assert body["workplan_id"] == "ws-1"
|
||||||
assert body["workstream_id"] == "ws-1"
|
assert "workstream_id" not in body
|
||||||
|
|
||||||
|
|
||||||
def test_distinct_identities_get_distinct_keys() -> None:
|
def test_distinct_identities_get_distinct_keys() -> None:
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue