From 8fed757fc1dc93fe1e3c632c29434bff621ed9cc Mon Sep 17 00:00:00 2001 From: umsangdon Date: Fri, 2 Oct 2026 07:57:58 +0900 Subject: [PATCH] =?UTF-8?q?fix(M02):=20=ED=91=9C=EC=A4=80=20=ED=91=9C=20?= =?UTF-8?q?=EA=B3=A0=EC=B9=9C=20=EA=B0=92=20=3D=20=5Fstandard/=20=ED=8C=8C?= =?UTF-8?q?=EC=9D=BC=EC=97=90=20=EB=B0=94=EB=A1=9C=20=C2=B7=20=EB=A1=9C?= =?UTF-8?q?=EC=A7=81=20=EB=AA=A9=EB=A1=9D=20=EC=8B=9C=ED=97=98=EC=9D=B4=20?= =?UTF-8?q?=EC=9E=90=EC=B2=B4=20=ED=8C=8C=EC=9D=BC=20=EC=B0=A8=EB=A1=80?= =?UTF-8?q?=EC=97=90=20=EC=95=88=20=EA=B8=B0=EB=8C=90(=EC=82=AC=EC=9A=A9?= =?UTF-8?q?=EC=9E=90=20=EA=B2=B0=EC=A0=95)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01KmELpdXFDRZHhfbGuRhSmL --- M02_MasterTemplete/DataFlow/M02_DF_Router.py | 15 +++++++++------ M02_MasterTemplete/DataFlow/M02_DF_Values.py | 8 +++----- resources/tester/test_m01_api.py | 3 +++ resources/tester/test_m02_df_router.py | 18 ++++++++++++------ 4 files changed, 27 insertions(+), 17 deletions(-) diff --git a/M02_MasterTemplete/DataFlow/M02_DF_Router.py b/M02_MasterTemplete/DataFlow/M02_DF_Router.py index 3892588d9..3e48df45c 100644 --- a/M02_MasterTemplete/DataFlow/M02_DF_Router.py +++ b/M02_MasterTemplete/DataFlow/M02_DF_Router.py @@ -311,20 +311,23 @@ def get_materials(q: str = "", sub: str = "", detail: str = "", page: int = 1, s @router.get("/standards") def get_standards() -> dict: - return _call(dv.standards, STANDARD, DATA) + return _call(dv.standards, STANDARD) def _standards_put(body: dict) -> dict: + """고친 표준 표 = 본 프로그램 값 — git 이 따라가는 `_standard/` 파일에 바로(시스템 관리자).""" dv.standards_check(body) for part, name in dv.STANDARDS.items(): - _write(DATA / name, body[part]) - return dv.standards(STANDARD, DATA) + tmp = STANDARD / f".{name}.tmp" + text = json.dumps(body[part], ensure_ascii=False, indent=2) + "\n" + tmp.write_text(text, encoding="utf-8", newline="\n") + os.replace(tmp, STANDARD / name) + return dv.standards(STANDARD) def _standards_reset() -> dict: - for name in dv.STANDARDS.values(): - (DATA / name).unlink(missing_ok=True) - return dv.standards(STANDARD, DATA) + """고친 값을 따로 두지 않음(바로 저장) — 되돌릴 처음 값 없음 · 지금 값 그대로.""" + return dv.standards(STANDARD) @router.put("/standards") diff --git a/M02_MasterTemplete/DataFlow/M02_DF_Values.py b/M02_MasterTemplete/DataFlow/M02_DF_Values.py index 2ddd9cb3e..4befa7693 100644 --- a/M02_MasterTemplete/DataFlow/M02_DF_Values.py +++ b/M02_MasterTemplete/DataFlow/M02_DF_Values.py @@ -550,13 +550,11 @@ def group_find(group: str, slot: dict, value: Any) -> dict: STANDARDS = {"unit": "단위표준.json", "money": "금액단위표준.json"} -def standards(first: Any, mine: Any) -> dict: - """{unit, money, saved} — 고친 것(`_data`)이 있으면 그것 · 없으면 처음 값(`_standard`).""" +def standards(folder: Any, _old: Any = None) -> dict: # _old = 옛 고친 값 폴더(안 씀 · 옛 부름 꼴) + """{unit, money, saved} — 표준 표 파일(`_standard/` · 고치면 바로 그 파일) · saved 늘 False.""" out: dict[str, Any] = {"saved": False} for part, name in STANDARDS.items(): - path = mine / name if (mine / name).is_file() else first / name - out["saved"] = out["saved"] or path.parent == mine - out[part] = json.loads(path.read_text(encoding="utf-8")) + out[part] = json.loads((folder / name).read_text(encoding="utf-8")) return out diff --git a/resources/tester/test_m01_api.py b/resources/tester/test_m01_api.py index 4bcf6e1b6..094462d2d 100644 --- a/resources/tester/test_m01_api.py +++ b/resources/tester/test_m01_api.py @@ -152,6 +152,9 @@ def test_로직_목록_하나_시험계산(client: TestClient) -> None: assert all((x["구분"], x["상세구분"]) == (LOGIC_SUB, detail) for x in listed) assert not any(x["blocked"] for x in listed) files = _get(client, "/api/m01/groups/로직/files")["files"] + files = [ + f for f in files if f["file"] != "로직_자체.json" + ] # 자체 파일은 마스터 내용 따라 있다 없다 함 assert files[0]["file"].startswith("로직_산림품셈_") and files[-1]["chapter"].startswith( "유지관리" ) diff --git a/resources/tester/test_m02_df_router.py b/resources/tester/test_m02_df_router.py index fe51c9239..686cfc776 100644 --- a/resources/tester/test_m02_df_router.py +++ b/resources/tester/test_m02_df_router.py @@ -578,7 +578,12 @@ def test_선_규칙_끝수_재료_조건_설계_때_정할_것(client: TestClien assert bad["ports"]["f"]["합"] == "#N/A" and _d(bad["cost"]["재료비"]) == 0 -def test_표준_표_읽기_쓰기_처음값(client: TestClient, folder: Path) -> None: +def test_표준_표_읽기_쓰기_바로_저장(client: TestClient, tmp_path: Path, monkeypatch) -> None: + """고친 표준 표 = `_standard/` 파일에 바로(본 프로그램 값) — 시험은 그 사본 폴더 · 정본 파일은 안 바뀜.""" + real = cf.STANDARD + before = {p.name: p.read_bytes() for p in real.glob("*.json")} + shutil.copytree(real, tmp_path / "_standard") + monkeypatch.setattr(cf, "STANDARD", tmp_path / "_standard") first = client.get("/api/m02/df/standards").json() assert first["saved"] is False and first["unit"]["줄"] and first["money"]["줄"] edited = json.loads(json.dumps(first)) @@ -586,14 +591,15 @@ def test_표준_표_읽기_쓰기_처음값(client: TestClient, folder: Path) -> res = client.put( "/api/m02/df/standards", json={"unit": edited["unit"], "money": edited["money"]} ) - assert res.status_code == 200 and res.json()["saved"] is True + assert res.status_code == 200 assert client.get("/api/m02/df/standards").json()["money"]["줄"][4]["지위"] == 1 + saved = json.loads((cf.STANDARD / "금액단위표준.json").read_text(encoding="utf-8")) + assert saved["줄"][4]["지위"] == 1 # 파일에 바로 assert client.put("/api/m02/df/standards", json={"unit": {}, "money": {}}).status_code == 400 - back = client.delete("/api/m02/df/standards").json() assert ( - back["saved"] is False and back["money"]["줄"][4]["지위"] == first["money"]["줄"][4]["지위"] - ) - assert (cf.STANDARD / "금액단위표준.json").is_file() # 처음 값 파일은 그대로 + client.delete("/api/m02/df/standards").json()["money"]["줄"][4]["지위"] == 1 + ) # 되돌릴 처음 값 없음 + assert {p.name: p.read_bytes() for p in real.glob("*.json")} == before def test_새_길도_시스템_관리자만(folder: Path) -> None: