feat(M01): 로직 「흐름」 칸 — 저장 검사 · 서버 다시 셈 · 흐름 받기 · 계산 갈래 · 신규 GX · 다른 로직 마스터 키(PLAN 36-4)

- /save 줄의 흐름 = 꼴 검사(없는 알약 · 겹친 선 · 돌고 도는 선 422 · 빈 받는 자리 경고) → M02_DF_Compute 로 다시 셈 → 받는 칸 값
- 키 없는 새 흐름 줄 = 로직_자체.json 에 GX 다음 키 · 구분 자체 · 옛 식 칸은 빈 것 · 응답 {files, added, warnings}
- GET /api/m01/logic/flow = 흐름 그대로 · 없으면 M02_DF_Convert.convert · 아직 없으면 빈 흐름 + 변환 준비 중
- /calc = 흐름 있으면 흐름 셈(입력 = 설계 때 정할 것 · sums 노무비 · 재료비 · 경비 · 계 · outputs) · 없으면 옛 셈
- DataFlow 다른 로직 입력 · /logic-value · /design-inputs 가 마스터 키도(흐름 = 흐름 셈 · 옛 로직 = 옛 셈) · 서로 부르면 막음
- Compute 의 Router _num 은 모듈로 부름(서로 부름 풀기)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KmELpdXFDRZHhfbGuRhSmL
This commit is contained in:
2026-10-01 23:41:32 +09:00
co-authored by Claude Opus 5.5
parent ff127b22cc
commit 7b90d28e22
5 changed files with 546 additions and 5 deletions
+12 -2
View File
@@ -36,6 +36,7 @@ from fastapi import APIRouter, HTTPException
from pydantic import BaseModel
from M01_MasterData import M01_MasterData_Store as store
from M01_MasterData import M01_MasterData_Store_Flow as sflow
from M01_MasterData.M01_MasterData_Router import _num
from M02_MasterTemplete.DataFlow import M02_DF_Compute as dc
from M02_MasterTemplete.DataFlow import M02_DF_Values as dv
@@ -184,7 +185,10 @@ def user_edit(op: str, element: dict | None, uid: str | None) -> dict:
# ── 저장 · 계산(`M02_DF_Compute`) ─────────────────────────────────────
def _load(key: str) -> dict:
"""다른 로직 입력이 부르는 로직 — 내 것(`_data`) · 견본(`_sample`)."""
"""다른 로직 입력이 부르는 로직 — 내 것(`_data`) · 견본(`_sample`) · 마스터 키(GX · GF …)는
M01 계산 길(흐름이면 흐름 · 옛 로직이면 옛 셈 · 정함 11)."""
if not _KEY.match(key or "") and _sample(key) is None:
return sflow.load(key)
logic, _ = _read(key)
return {**logic, "key": key}
@@ -216,6 +220,9 @@ def save(logic: dict) -> dict:
def logic_value(key: str, designs: dict) -> dict:
"""다른 로직 값 — 저장 로직 · 견본을 받은 설계 값(없으면 예시값)으로 셈 · 출력 이름 → 값."""
other = _load(key)
if callable(other.get("calc")): # 옛 마스터 로직 — 노무비 · 재료비 · 경비 · 계
got = other["calc"](designs)
return {"key": key, "outputs": got["outputs"], "cost": {}, "errors": got["errors"]}
got = dc.run(other, dc._design_values(other, designs), _load, _local(other), [key])
names = {b["id"]: b.get("name") for b in other.get("boxes") or []}
outputs = {names[i]: v for i, v in got["outputs"].items() if i in names}
@@ -224,7 +231,10 @@ def logic_value(key: str, designs: dict) -> dict:
def design_inputs(key: str) -> dict:
"""설계 때 정할 것 — 변수 · 재료 자리 · 다른 로직 받는 알약(선이 없을 때) · CfDesign 꼴."""
return {"key": key, "designs": dc.design_inputs(_load(key))}
other = _load(key)
if callable(other.get("calc")):
return {"key": key, "designs": sflow.old_designs(key)}
return {"key": key, "designs": dc.design_inputs(other)}
# ── 길 ────────────────────────────────────────────────────────────────