refactor(backend)!: separate algorithm and data layers
Reorganize algorithm packages by business responsibility, move orchestration into services, and keep database access behind pooled repositories. Harden analysis API validation, remove unsafe legacy simulation endpoints, and add regression and architecture boundary coverage. BREAKING CHANGE: legacy algorithm module paths and obsolete simulation endpoints are removed.
This commit is contained in:
@@ -1,26 +1,10 @@
|
||||
from collections import defaultdict
|
||||
|
||||
from app.algorithms.isolation import valve
|
||||
from app.algorithms.valve_isolation import topology_search as valve
|
||||
|
||||
|
||||
def test_non_isolatable_omits_affected_node_ids_but_keeps_count(monkeypatch):
|
||||
pipe_adj = defaultdict(
|
||||
set,
|
||||
{
|
||||
"A": {"B"},
|
||||
"B": {"A", "C"},
|
||||
"C": {"B"},
|
||||
},
|
||||
)
|
||||
topology = (
|
||||
pipe_adj,
|
||||
{"V-optional": ("A", "C")},
|
||||
{"P-1": ("A", "B", "pipe")},
|
||||
{"A", "B", "C"},
|
||||
)
|
||||
monkeypatch.setattr(valve, "_get_network_topology", lambda _network: topology)
|
||||
def test_non_isolatable_omits_affected_node_ids_but_keeps_count():
|
||||
links = ["P-1:pipe:A:B", "P-2:pipe:B:C", "V-optional:valve:A:C"]
|
||||
|
||||
result = valve.valve_isolation_analysis("demo", "P-1")
|
||||
result = valve.valve_isolation_analysis(links, "P-1")
|
||||
|
||||
assert result["isolatable"] is False
|
||||
assert result["affected_node_count"] == 3
|
||||
@@ -28,17 +12,10 @@ def test_non_isolatable_omits_affected_node_ids_but_keeps_count(monkeypatch):
|
||||
assert result["optional_valves"] == ["V-optional"]
|
||||
|
||||
|
||||
def test_isolatable_keeps_affected_node_ids_and_count(monkeypatch):
|
||||
pipe_adj = defaultdict(set, {"A": {"B"}, "B": {"A"}})
|
||||
topology = (
|
||||
pipe_adj,
|
||||
{"V-close": ("B", "C")},
|
||||
{"P-1": ("A", "B", "pipe")},
|
||||
{"A", "B", "C"},
|
||||
)
|
||||
monkeypatch.setattr(valve, "_get_network_topology", lambda _network: topology)
|
||||
def test_isolatable_keeps_affected_node_ids_and_count():
|
||||
links = ["P-1:pipe:A:B", "V-close:valve:B:C"]
|
||||
|
||||
result = valve.valve_isolation_analysis("demo", "P-1")
|
||||
result = valve.valve_isolation_analysis(links, "P-1")
|
||||
|
||||
assert result["isolatable"] is True
|
||||
assert result["affected_node_count"] == 2
|
||||
@@ -46,21 +23,14 @@ def test_isolatable_keeps_affected_node_ids_and_count(monkeypatch):
|
||||
assert result["must_close_valves"] == ["V-close"]
|
||||
|
||||
|
||||
def test_disabled_valve_expands_affected_area_before_counting(monkeypatch):
|
||||
pipe_adj = defaultdict(set, {"A": {"B"}, "B": {"A"}})
|
||||
topology = (
|
||||
pipe_adj,
|
||||
{
|
||||
"V-disabled": ("B", "C"),
|
||||
"V-close": ("C", "D"),
|
||||
},
|
||||
{"P-1": ("A", "B", "pipe")},
|
||||
{"A", "B", "C", "D"},
|
||||
)
|
||||
monkeypatch.setattr(valve, "_get_network_topology", lambda _network: topology)
|
||||
|
||||
def test_disabled_valve_expands_affected_area_before_counting():
|
||||
links = [
|
||||
"P-1:pipe:A:B",
|
||||
"V-disabled:valve:B:C",
|
||||
"V-close:valve:C:D",
|
||||
]
|
||||
result = valve.valve_isolation_analysis(
|
||||
"demo",
|
||||
links,
|
||||
"P-1",
|
||||
disabled_valves=["V-disabled"],
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user