From aacd21dd7c7cb719fba4c129bd99a149a68eeba3 Mon Sep 17 00:00:00 2001 From: umsangdon Date: Thu, 1 Oct 2026 16:49:20 +0900 Subject: [PATCH] =?UTF-8?q?fix(m02-cf):=20=EC=9E=85=EB=A0=A5=20=EC=83=81?= =?UTF-8?q?=EC=9E=90=20=EB=8B=A8=EC=9C=84=EB=A5=BC=20=EC=9A=94=EC=86=8C=20?= =?UTF-8?q?=C2=B7=20=EB=B3=80=EC=88=98=20=EB=8B=A8=EC=9C=84=EC=97=90=20?= =?UTF-8?q?=EB=A7=9E=EC=B6=A4=20=E2=80=94=20=EC=97=B4=20=EB=95=8C=20?= =?UTF-8?q?=EB=B0=94=EB=A1=9C=EC=9E=A1=EC=9D=8C(=EA=B2=AC=EB=B3=B8=20?= =?UTF-8?q?=EC=9D=B8=EB=A0=A5=20=EC=83=81=EC=9E=90=20=EC=9B=90/=EC=9D=BC)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Sonnet 5.5 Claude-Session: https://claude.ai/code/session_019ACSGaHdLgnkEkoA4LDtMU --- .../CostFlow/M02_CF_InputPanel.ts | 4 +++ .../CostFlow/M02_CF_InputPanel_Build.ts | 10 ++++++ .../tester/test_m02_cf_inputpanel_build.py | 33 +++++++++++++++++++ 3 files changed, 47 insertions(+) diff --git a/M02_MasterTemplete/CostFlow/M02_CF_InputPanel.ts b/M02_MasterTemplete/CostFlow/M02_CF_InputPanel.ts index 168a14005..bcaed88ba 100644 --- a/M02_MasterTemplete/CostFlow/M02_CF_InputPanel.ts +++ b/M02_MasterTemplete/CostFlow/M02_CF_InputPanel.ts @@ -31,6 +31,7 @@ import { elementOf, machineFields, queryOf, + reconcileUnit, removeElement, setKind, valueOf, @@ -143,6 +144,9 @@ export function renderInputPanel( host.replaceChildren(el("p", { className: "m02-cfip__muted", text: t("NotInput") })); return; } + // 상자 단위가 고른 요소 · 변수 단위와 다르면(견본 등) 맞춰 다시 그림 — 맞으면 바로 지나감 + const fixed = reconcileUnit(lg, boxId); + if (fixed !== lg) return on.change(fixed); const input = box.input ?? { mode: "variable" as const, elements: [], variables: [] }; const kind: CfGroup | "변수" = input.mode === "variable" ? "변수" : (input.group ?? "인력"); const body = el("div", { className: "m02-cfip__body" }); diff --git a/M02_MasterTemplete/CostFlow/M02_CF_InputPanel_Build.ts b/M02_MasterTemplete/CostFlow/M02_CF_InputPanel_Build.ts index ce2f0799b..1e392059b 100644 --- a/M02_MasterTemplete/CostFlow/M02_CF_InputPanel_Build.ts +++ b/M02_MasterTemplete/CostFlow/M02_CF_InputPanel_Build.ts @@ -282,3 +282,13 @@ export function removeVariable(lg: CfLogic, id: string, name: string, pills?: Pi pills, ); } + +/** 상자 단위를 요소 · 변수 단위에 맞춤 — 이미 맞으면 받은 것 그대로(견본처럼 단위가 안 맞게 저장된 상자를 열 때 바로잡음) */ +export function reconcileUnit(lg: CfLogic, id: string): CfLogic { + const box = lg.boxes.find((b) => b.id === id); + if (!box?.input) return lg; + const want = unitOfInput(box.input); + return box.unit === want + ? lg + : { ...lg, boxes: lg.boxes.map((b) => (b.id === id ? { ...b, unit: want } : b)) }; +} diff --git a/resources/tester/test_m02_cf_inputpanel_build.py b/resources/tester/test_m02_cf_inputpanel_build.py index 890b0639d..79aa5cb05 100644 --- a/resources/tester/test_m02_cf_inputpanel_build.py +++ b/resources/tester/test_m02_cf_inputpanel_build.py @@ -219,3 +219,36 @@ def test_환율_유가전력_알약_이름에_날짜가_안_들어감(): "값": 1900, } assert call("elementOf", "유가전력", oil)["name"] == "휘발유 서울" + + +def test_단위가_안_맞게_저장된_상자는_열_때_맞춤(): + el1, el2 = call("elementOf", "인력", LABOR), call("elementOf", "인력", LABOR2) + lg = logic() + lg["boxes"][0]["input"] = { + "mode": "group", + "group": "인력", + "elements": [el1, el2], + "variables": [], + } + assert lg["boxes"][0]["unit"] == "-" + fixed = run([{"op": "fn", "name": "reconcileUnit", "args": [lg, "b1"]}])[0] + assert fixed["boxes"][0]["unit"] == "원/일" + again = run([{"op": "fn", "name": "reconcileUnit", "args": [fixed, "b1"]}])[0] + assert again == fixed + oil = {"ref": "X", "name": "경유", "spec": "", "unit": "원/L"} + lg["boxes"][0]["input"]["elements"].append(oil) + lg["boxes"][0]["unit"] = "원/일" + assert ( + run([{"op": "fn", "name": "reconcileUnit", "args": [lg, "b1"]}])[0]["boxes"][0]["unit"] + == "-" + ) + one = { + "mode": "variable", + "elements": [], + "variables": [{"name": "면적", "type": "number", "unit": "㎡", "example": 1}], + } + lg["boxes"][0]["input"] = one + assert ( + run([{"op": "fn", "name": "reconcileUnit", "args": [lg, "b1"]}])[0]["boxes"][0]["unit"] + == "㎡" + )