# ============================================================ # EX-03 冲突解决工作流黄金测试 # ============================================================ from __future__ import annotations from server.aps_domain.conflicts import apply_conflict_fix, list_conflict_center from server.aps_domain.flex import apply_equipment_fault, run_flex_schedule from server.state.seed import seed_world class _MemStore: def __init__(self, data): self.data = data def next_id(self, kind: str) -> int: key = f"_c_{kind}" self.data[key] = self.data.get(key, 2000) + 1 return self.data[key] def save(self): pass def test_conflict_center_lists_with_fixes(): store = _MemStore(seed_world()) run_flex_schedule(store, sort_mode="BOTTLENECK", actor="test") apply_equipment_fault(store, "WELD-01", status="MAINTENANCE", reschedule=True, actor="test") data = list_conflict_center(store.data, scope="flex") assert data["total"] >= 0 # 焊接故障后通常有 NO_CAPABILITY 或至少 DELAY if data["rows"]: row = data["rows"][0] assert row["fixes"] assert all("action" in f and "label" in f for f in row["fixes"]) def test_apply_mold_unlock_resolves_mold_life(): store = _MemStore(seed_world()) # 人为制造模具寿命冲突记录 run_flex_schedule(store, sort_mode="BOTTLENECK", actor="test") mold = next(m for m in store.data["flexMolds"] if m["code"] == "MOLD-HV-01") mold["status"] = "LOCKED" mold["lifeUsed"] = mold["lifeTotal"] vid = store.data["flexScheduleVersions"][-1]["id"] cid = store.next_id("flexConflict") store.data["flexConflicts"].append({ "id": cid, "versionId": vid, "conflictType": "MOLD_LIFE", "severity": "MAJOR", "resourceType": "MOLD", "resourceName": "MOLD-HV-01", "orderNo": "FO-001", "description": "模具寿命用尽", "suggestedSolution": "解锁", "isResolved": False, }) r = apply_conflict_fix(store, cid, "flex.mold.unlock", params={"moldCode": "MOLD-HV-01"}, actor="test") assert r["applied"] is True assert mold["status"] == "AVAILABLE" cf = next(c for c in store.data["flexConflicts"] if c["id"] == cid) assert cf["isResolved"] is True def test_apply_reschedule_stages_p2(): store = _MemStore(seed_world()) run_flex_schedule(store, sort_mode="BOTTLENECK", actor="test") vid = store.data["flexScheduleVersions"][-1]["id"] cid = store.next_id("flexConflict") store.data["flexConflicts"].append({ "id": cid, "versionId": vid, "conflictType": "DELAY", "severity": "MAJOR", "resourceType": "TIME", "orderNo": "FO-001", "description": "交期延误", "suggestedSolution": "重排", "isResolved": False, }) before = len(store.data["flexScheduleVersions"]) r = apply_conflict_fix(store, cid, "flex.reschedule", params={"level": "L2"}, actor="test", session_id="t1") assert r.get("staged") is True assert r.get("block") assert len(store.data["flexScheduleVersions"]) == before # 未执行 assert not next(c for c in store.data["flexConflicts"] if c["id"] == cid)["isResolved"]