Files
TJWaterServerBinary/app/services/tjnetwork.py
jiang 5966d039de 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.
2026-09-04 17:30:55 +08:00

282 lines
7.0 KiB
Python

"""Application-facing water-network service boundary.
The native WNDB package is organized by responsibility. This transitional
facade re-exports the operations still consumed by HTTP endpoints. Application
services and algorithms depend on their explicit native/repository modules.
"""
from typing import Any
import app.infra.epanet as epanet
from app.services.demand_allocation import (
calculate_demand_to_network,
calculate_demand_to_nodes,
calculate_demand_to_region,
)
from app.infra.db.postgresql.scada import (
get_all_scada_info,
get_scada_info,
get_scada_info_schema,
)
from app.native.wndb.commands.api import (
delete_curve_cascade as delete_curve,
delete_junction_cascade as delete_junction,
delete_pattern_cascade as delete_pattern,
delete_pipe_cascade as delete_pipe,
delete_pump_cascade as delete_pump,
delete_reservoir_cascade as delete_reservoir,
delete_tank_cascade as delete_tank,
delete_valve_cascade as delete_valve,
set_option_ex as set_option,
set_option_v3_ex as set_option_v3,
)
from app.native.wndb.core.database import ChangeSet, read_all
from app.native.wndb.core.projects import (
copy_project,
create_project,
delete_project,
have_project,
list_project,
)
from app.native.wndb.gis.backdrop import (
get_backdrop,
get_backdrop_schema,
set_backdrop,
)
from app.native.wndb.gis.coordinates import get_node_coord
from app.native.wndb.gis.labels import (
add_label,
delete_label,
get_label,
get_label_schema,
set_label,
)
from app.native.wndb.gis.network_views import (
get_major_node_coords,
get_major_pipe_nodes,
get_network_link_nodes,
get_network_node_coords,
)
from app.native.wndb.gis.region_geometry import get_nodes_in_region
from app.native.wndb.gis.regions import (
add_region,
delete_region,
get_region,
get_region_schema,
set_region,
)
from app.native.wndb.gis.vertices import (
add_vertex,
delete_vertex,
get_all_vertex_links,
get_all_vertices,
get_vertex,
get_vertex_schema,
set_vertex,
)
from app.native.wndb.inp.exporter import dump_inp, export_inp
from app.native.wndb.inp.importer import convert_inp_v3_to_v2, read_inp
from app.native.wndb.model.controls import (
get_control,
get_control_schema,
set_control,
)
from app.native.wndb.model.curves import (
add_curve,
get_curve,
get_curve_schema,
set_curve,
)
from app.native.wndb.model.demands import get_demand, get_demand_schema, set_demand
from app.native.wndb.model.elements import (
get_curves,
get_element_type,
get_element_type_value,
get_link_type,
get_links,
get_node_links,
get_node_type,
get_nodes,
get_patterns,
get_regions,
is_curve,
is_junction,
is_link,
is_node,
is_pattern,
is_pipe,
is_pump,
is_reservoir,
is_tank,
is_valve,
)
from app.native.wndb.model.emitters import (
get_emitter,
get_emitter_schema,
set_emitter,
)
from app.native.wndb.model.energy import (
get_energy,
get_energy_schema,
get_pump_energy,
get_pump_energy_schema,
set_energy,
set_pump_energy,
)
from app.native.wndb.model.junctions import (
add_junction,
get_all_junctions,
get_junction,
get_junction_schema,
set_junction,
)
from app.native.wndb.model.mixing import (
add_mixing,
delete_mixing,
get_mixing,
get_mixing_schema,
set_mixing,
)
from app.native.wndb.model.options import (
OPTION_DEMAND_MODEL_PDA,
OPTION_QUALITY_CHEMICAL,
get_option,
get_option_v3,
get_option_v3_schema,
)
from app.native.wndb.model.patterns import (
add_pattern,
get_pattern,
get_pattern_schema,
set_pattern,
)
from app.native.wndb.model.pipes import (
PIPE_STATUS_OPEN,
add_pipe,
get_all_pipes,
get_pipe,
get_pipe_schema,
set_pipe,
)
from app.native.wndb.model.pumps import (
add_pump,
get_all_pumps,
get_pump,
get_pump_schema,
set_pump,
)
from app.native.wndb.model.quality import (
get_quality,
get_quality_schema,
set_quality,
)
from app.native.wndb.model.reactions import (
get_pipe_reaction,
get_pipe_reaction_schema,
get_reaction,
get_reaction_schema,
get_tank_reaction,
get_tank_reaction_schema,
set_pipe_reaction,
set_reaction,
set_tank_reaction,
)
from app.native.wndb.model.reservoirs import (
add_reservoir,
get_all_reservoirs,
get_reservoir,
get_reservoir_schema,
set_reservoir,
)
from app.native.wndb.model.rules import get_rule, get_rule_schema, set_rule
from app.native.wndb.model.sources import (
SOURCE_TYPE_SETPOINT,
add_source,
delete_source,
get_source,
get_source_schema,
set_source,
)
from app.native.wndb.model.status import (
get_status,
get_status_schema,
set_status,
)
from app.native.wndb.model.tags import get_tag, get_tag_schema, get_tags, set_tag
from app.native.wndb.model.tanks import (
add_tank,
get_all_tanks,
get_tank,
get_tank_schema,
set_tank,
)
from app.native.wndb.model.times import get_time, get_time_schema, set_time
from app.native.wndb.model.title import get_title, get_title_schema, set_title
from app.native.wndb.model.valves import (
VALVES_TYPE_PRV,
add_valve,
get_all_valves,
get_valve,
get_valve_schema,
set_valve,
)
def run_project_return_dict(name: str) -> dict[str, Any]:
return epanet.run_project_return_dict(name, True)
def run_project(name: str) -> str:
return epanet.run_project(name)
def run_inp(name: str) -> str:
return epanet.run_inp(name)
def get_node_properties(name: str, node_id: str) -> dict[str, Any]:
if is_junction(name, node_id):
return get_junction(name, node_id)
if is_reservoir(name, node_id):
return get_reservoir(name, node_id)
if is_tank(name, node_id):
return get_tank(name, node_id)
return {}
def get_link_properties(name: str, link_id: str) -> dict[str, Any]:
if is_pipe(name, link_id):
return get_pipe(name, link_id)
if is_pump(name, link_id):
return get_pump(name, link_id)
if is_valve(name, link_id):
return get_valve(name, link_id)
return {}
def get_element_properties_with_type(
name: str, element_type: str, element_id: str
) -> dict[str, Any]:
if element_type == "node":
return get_node_properties(name, element_id)
if element_type == "link":
return get_link_properties(name, element_id)
if element_type == "scada":
return get_scada_info(name, element_id)
return {}
def get_element_properties(name: str, element_id: str) -> dict[str, Any]:
if is_node(name, element_id):
return get_node_properties(name, element_id)
if is_link(name, element_id):
return get_link_properties(name, element_id)
return get_scada_info(name, element_id)
def get_network_in_extent(
name: str, x1: float, y1: float, x2: float, y2: float
) -> dict[str, Any]:
# Kept as the existing API placeholder; spatial filtering belongs in GIS.
return {}