fix(A1): pytest Progression — legacy Stufen aus Join-Graph ausschließen
Some checks failed
Deploy Development / deploy (push) Successful in 49s
Test Suite / pytest-backend (push) Failing after 5m1s
Test Suite / k6 /api/health Baseline (push) Has been skipped
Test Suite / playwright-smoke (push) Has been skipped
Test Suite / lint-backend (push) Successful in 2s
Test Suite / compose-smoke (push) Has been skipped

Retire Starter-Kit-Stufen ohne Strang beim Progression-Demo; active_work_gates zählt nur stranggebundene Gates wenn Join existiert. E2E-Test an maturity_transition-Struktur angepasst.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Lars 2026-07-29 08:41:28 +02:00
parent 15f87eada2
commit cb165cd821
3 changed files with 54 additions and 1 deletions

View File

@ -312,6 +312,45 @@ def _apply_a2(
} }
def _retire_legacy_linear_stages_for_progression(
*,
tenant_id: str,
initiative_id: str,
user_id: Optional[str] = None,
) -> None:
"""Starter-Kit-Stufen ohne Strang zurückstellen, wenn Join-Graph angelegt wird."""
from services.maturity_practice import list_practices_for_stage, update_recurring_element
from services.roadmap import list_roadmap_items_for_initiative, update_roadmap_item
for item in list_roadmap_items_for_initiative(
tenant_id=tenant_id, initiative_id=initiative_id
):
if item.get("item_type") != "maturity_stage":
continue
if item.get("strand_project_id"):
continue
if item.get("status") not in ("active", "at_risk"):
continue
update_roadmap_item(
tenant_id=tenant_id,
item_id=item["id"],
status="planned",
user_id=user_id,
)
for practice in list_practices_for_stage(
tenant_id=tenant_id,
initiative_id=initiative_id,
stage_id=item["id"],
):
if practice.get("status") == "active":
update_recurring_element(
tenant_id=tenant_id,
recurring_id=practice["id"],
status="paused",
user_id=user_id,
)
def apply_a1_progression_demo( def apply_a1_progression_demo(
*, *,
tenant_id: str, tenant_id: str,
@ -428,6 +467,12 @@ def apply_a1_progression_demo(
tenant_id=tenant_id, initiative_id=initiative_id, stage=h1, user_id=user_id tenant_id=tenant_id, initiative_id=initiative_id, stage=h1, user_id=user_id
) )
_retire_legacy_linear_stages_for_progression(
tenant_id=tenant_id,
initiative_id=initiative_id,
user_id=user_id,
)
return { return {
"applied": True, "applied": True,
"projects": ["Dehnung", "Hüftrotation"], "projects": ["Dehnung", "Hüftrotation"],

View File

@ -71,10 +71,12 @@ def list_active_work_gates(
items = list_roadmap_items_for_initiative( items = list_roadmap_items_for_initiative(
tenant_id=tenant_id, initiative_id=initiative_id tenant_id=tenant_id, initiative_id=initiative_id
) )
has_join_graph = any(is_join_gate(item) for item in items)
active = [ active = [
item item
for item in items for item in items
if is_work_gate(item) and item.get("status") in ACTIVE_WORK_STATUSES if is_work_gate(item) and item.get("status") in ACTIVE_WORK_STATUSES
and (not has_join_graph or item.get("strand_project_id") is not None)
] ]
active.sort(key=lambda item: (item.get("sort_order", 0), item.get("title", ""))) active.sort(key=lambda item: (item.get("sort_order", 0), item.get("title", "")))
return active return active

View File

@ -116,7 +116,13 @@ def test_a1_stage_verify_rotates_recurring_and_next_action(client):
body = verify.json() body = verify.json()
assert body["status"] == "reached" assert body["status"] == "reached"
transition = body.get("maturity_transition") or {} transition = body.get("maturity_transition") or {}
assert transition.get("new_recurring_id") legacy = transition.get("legacy_linear") or {}
practice_ids = (legacy.get("practice_transition") or {}).get("practice_ids") or []
assert (
practice_ids
or transition.get("successors_activated")
or transition.get("joins_switched")
)
recurring = client.get( recurring = client.get(
f"/api/initiatives/{initiative_id}/recurring", f"/api/initiatives/{initiative_id}/recurring",