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:
@@ -19,38 +19,38 @@ def _empty_scada_mappings(simulation):
|
||||
)
|
||||
|
||||
|
||||
def test_run_simulation_exposes_explicit_valve_control():
|
||||
def test_run_simulation_accepts_explicit_valve_control():
|
||||
from app.services import simulation
|
||||
|
||||
assert "valve_control" in inspect.signature(simulation.run_simulation).parameters
|
||||
|
||||
|
||||
def test_extended_runner_cleans_temporary_database_after_failure(monkeypatch):
|
||||
from app.algorithms.simulation import runner
|
||||
def test_valve_close_analysis_uses_normalized_scheme_type(monkeypatch):
|
||||
from app.services import simulation_scenarios
|
||||
|
||||
lifecycle: list[tuple[str, str]] = []
|
||||
captured = {}
|
||||
monkeypatch.setattr(simulation_scenarios, "get_option", lambda _name: {})
|
||||
monkeypatch.setattr(
|
||||
simulation_scenarios,
|
||||
"set_option",
|
||||
lambda _name, _changes: None,
|
||||
)
|
||||
monkeypatch.setattr(
|
||||
simulation_scenarios.simulation,
|
||||
"run_simulation",
|
||||
lambda **kwargs: captured.update(kwargs),
|
||||
)
|
||||
|
||||
@contextmanager
|
||||
def temporary_project(project: str, purpose: str):
|
||||
lifecycle.append(("create", project))
|
||||
try:
|
||||
yield "isolated_project"
|
||||
finally:
|
||||
lifecycle.append(("delete", project))
|
||||
simulation_scenarios.valve_close_analysis.__wrapped__(
|
||||
name="demo",
|
||||
modify_pattern_start_time="2026-01-01T00:00:00+08:00",
|
||||
modify_valve_opening={"V1": 0.0},
|
||||
scheme_name="valve_case",
|
||||
_temporary_project="temporary_demo",
|
||||
)
|
||||
|
||||
monkeypatch.setattr(runner, "temporary_project_database", temporary_project)
|
||||
|
||||
@runner._clean_extended_simulation
|
||||
def fail(name, simulation_type, *, _temporary_project=None):
|
||||
assert name == "demo"
|
||||
assert simulation_type == "extended"
|
||||
assert _temporary_project == "isolated_project"
|
||||
raise RuntimeError("simulation failed")
|
||||
|
||||
with pytest.raises(RuntimeError, match="simulation failed"):
|
||||
fail("demo", "extended")
|
||||
|
||||
assert lifecycle == [("create", "demo"), ("delete", "demo")]
|
||||
assert captured["scheme_type"] == "valve_close_analysis"
|
||||
assert captured["result_db_name"] == "demo"
|
||||
|
||||
|
||||
def test_apply_valve_control_matches_runner_semantics(monkeypatch):
|
||||
|
||||
Reference in New Issue
Block a user