feat(511-C 유토 배분 E2 · 판 haul 줄 · 서버만 넷 까닭): /haul-plan 창구 = 늘 떠 있는 Node haul.view(computeHaulPlan 화면 꼴 · design_calc_node.ts 입구만 · 시험 길 표에 두면 브라우저 첫 묶음에 실림) · [저장] 정본 면적 · 유토곡선 · 배분 = 늘 떠 있는 Node 셋(structure.layouts · masshaul.cumulative · haul.plan · 못 부르면 새 프로세스) · 옛 server-calc 묶음 = 시험 대조만 · 판 haul 줄 엶(요구 321 · 기본 server = 지금 /haul-plan 그대로 · 판 파일 바뀜 0 · both = 배분 모듈 dynamic import 해 브라우저 셈 · 정적 import 0) · 서버만 G3 D1 D2 N1 = 줄마다 까닭 글(DB 씀 · 래스터 · D1 래스터 위 · 큰 지형 파일) · 거울 test_511_c_haul_node(프로젝트 일곱 × 문맥 넷 × 그림 · 수량 + 끝 경우 여섯 = 새 길 · 옛 묶음 · 브라우저 함수 0 차 · [저장] 정본 golden 문맥 셋 0 차) — 요구 320-4
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -5,8 +5,9 @@
|
||||
멈추면 그 결과를 여기로 보내 배분을 받아 쥔다. 그래서 유토곡선 패널을 펼치는 순간이
|
||||
즉시가 된다(미리 받아 뒀으므로).
|
||||
|
||||
**계산은 한 벌이다** — 화면이 쓰던 TS 를 Node 진입점(`B06_Section_Server_Calc_Node.ts`)으로
|
||||
그대로 돌린다(CLAUDE.md 5장). 파이썬으로 옮기면 저장 정본과 화면 값이 갈린다.
|
||||
**계산은 한 벌이다** — 화면이 쓰던 TS(`computeHaulPlan`)를 늘 떠 있는 Node 시험 길 `haul.view`
|
||||
(`design_calc_node_trial.ts` · 511-C)로 그대로 돌린다(CLAUDE.md 5장). 파이썬으로 옮기면 저장 정본과
|
||||
화면 값이 갈린다.
|
||||
|
||||
정본을 만들지 않는다 — 이 응답은 **표시 전용**이다. 저장 정본은 [저장]·[확정] 뒤
|
||||
`recompute_server_side` 가 따로 낸다.
|
||||
@@ -28,21 +29,19 @@ from fastapi.responses import JSONResponse
|
||||
|
||||
from B03_FileInput.B03_FileInput_Repository import get_project_storage_relative_path
|
||||
from B06_Section.B06_Section_Server_Calc_Prebuild import (
|
||||
BUNDLE,
|
||||
_mass_haul_context,
|
||||
conversion_factors_for,
|
||||
haul_inputs_for,
|
||||
haul_limits_for,
|
||||
)
|
||||
from common_util.common_util_calc_runner import run_calc_served
|
||||
from common_util.common_util_derived_store import read_derived, write_derived
|
||||
from common_util.common_util_node_bundle import run_bundle_json
|
||||
from common_util.common_util_storage import resolve_stored_project_path
|
||||
from config.config_db import run_with_connection
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
router = APIRouter(prefix="/api/projects", tags=["B06 Profile Cross"])
|
||||
|
||||
_NPM_SCRIPT = "build:server-calc"
|
||||
# 측점 수 상한 — 정상 노선은 수백 곳이다. 그보다 크면 비정상 요청으로 본다.
|
||||
_MAX_POINTS = 5000
|
||||
# 열쇠(누가토량 결과 + 계수 · 장비 경계) → 배분 — 같은 열쇠면 Node 를 다시 안 띄움
|
||||
@@ -64,6 +63,26 @@ def _keep(key: str, plan: Any) -> None:
|
||||
_KEPT.popitem(last=False)
|
||||
|
||||
|
||||
def _run_view(result: dict[str, Any], context: dict[str, Any]) -> dict[str, Any] | None:
|
||||
"""화면 꼴 배분(그림용 · 잔진동 거름) — 옛 server-calc `haul_plan_for` 갈래와 같은 인자."""
|
||||
options = {
|
||||
key: context.get(key)
|
||||
for key in (
|
||||
"collected_stone_deduction_m3",
|
||||
"collected_stone_by_ground_m3",
|
||||
"collected_stone_ground_unknown_m3",
|
||||
"structure_spoil_m3",
|
||||
"structure_spoil_points",
|
||||
)
|
||||
}
|
||||
options["conversion"] = context.get("earthwork_conversion")
|
||||
options["drawing"] = True
|
||||
args = [result, context.get("haul_equipment_limits"), options]
|
||||
answer = run_calc_served(["haul.view"], {"args": {"haul.view": args}})
|
||||
results = answer.get("results") if isinstance(answer, dict) else None
|
||||
return {"haul_plan": results["haul.view"]} if isinstance(results, dict) else None
|
||||
|
||||
|
||||
@router.post("/{project_id}/sections/{route_id}/haul-plan", response_model=None)
|
||||
async def compute_haul_plan(
|
||||
project_id: UUID,
|
||||
@@ -114,12 +133,7 @@ async def compute_haul_plan(
|
||||
_keep(key, stored["value"])
|
||||
return JSONResponse(content={"status": "success", "haul_plan": stored["value"]})
|
||||
try:
|
||||
output = await asyncio.to_thread(
|
||||
run_bundle_json,
|
||||
BUNDLE,
|
||||
_NPM_SCRIPT,
|
||||
{"haul_plan_for": result, "context": context},
|
||||
)
|
||||
output = await asyncio.to_thread(_run_view, result, context)
|
||||
except Exception:
|
||||
logger.exception("유토 배분 계산 실패: project_id=%s route_id=%s", project_id, route_id)
|
||||
return JSONResponse(
|
||||
|
||||
Reference in New Issue
Block a user