From 2ee6a7ed886f1858ff07a095df93a9ae787d6973 Mon Sep 17 00:00:00 2001 From: umsangdon Date: Thu, 17 Sep 2026 16:45:50 +0900 Subject: [PATCH] auto: 2026-09-17 16:45 (ESD_LAPTOP) --- Z01_MasterData/Z01_MasterData_WorkItems.py | 14 +++++++--- resources/tester/test_z01_work_items.py | 30 +++++++++++++++++++--- 2 files changed, 36 insertions(+), 8 deletions(-) diff --git a/Z01_MasterData/Z01_MasterData_WorkItems.py b/Z01_MasterData/Z01_MasterData_WorkItems.py index 0d955e3f..4bacb5ef 100644 --- a/Z01_MasterData/Z01_MasterData_WorkItems.py +++ b/Z01_MasterData/Z01_MasterData_WorkItems.py @@ -148,6 +148,8 @@ def notice(kind: str) -> list[str]: #: ⚠ 「임도가 쓰는 것」 같은 쓰임 가름은 잣대가 아직 없어 안 냄(지어내지 않음). FILTER_KEYS = ("division", "axis_role") ALL = "" +#: 값을 안 보냈을 때 거는 값 — 총칙 줄은 기본 감춤 · 「전부」를 고르면 보임(2026-09-17 브레인) +DEFAULTS = {"axis_role": "work_item"} def _facets(kind: str) -> dict[str, dict[str, str]]: @@ -166,7 +168,7 @@ def _role_names() -> dict[str, str]: def filters(kind: str, rows: list[dict[str, Any]]) -> list[dict[str, Any]]: - """거르기 상자 — 값이 둘 이상 갈리는 가름만 · 기본은 「전부」(안 거름).""" + """거르기 상자 — 값이 둘 이상 갈리는 가름만 · 기본은 `DEFAULTS`(그 값이 표에 있을 때) 아니면 「전부」.""" facets = _facets(kind) labels = {"division": ("부문", {}), "axis_role": ("줄 구실", _role_names())} out = [] @@ -179,13 +181,14 @@ def filters(kind: str, rows: list[dict[str, Any]]) -> list[dict[str, Any]]: if len(values) < 2: continue label, names = labels[key] + default = DEFAULTS.get(key, ALL) out.append( { "key": key, "label": label, "options": [{"value": ALL, "label": "전부", "rows": len(rows)}] + [{"value": v, "label": names.get(v, v), "rows": counts[v]} for v in values], - "default": ALL, + "default": default if default in values else ALL, } ) return out @@ -195,8 +198,11 @@ def apply_filters( kind: str, rows: list[dict[str, Any]], picked: dict[str, str] ) -> list[dict[str, Any]]: facets = _facets(kind) - for key, value in picked.items(): - if key in FILTER_KEYS and value != ALL: + # 안 보낸 가름은 상자 기본값으로 — 상자에 보이는 값과 걸린 값이 같게(찾기 결과가 아니라 표 전체로 정함) + defaults = {f["key"]: f["default"] for f in filters(kind, base_rows(kind))} + for key in FILTER_KEYS: + value = picked.get(key, defaults.get(key, ALL)) + if value != ALL: rows = [r for r in rows if facets.get(r["@id"], {}).get(key) == value] return rows diff --git a/resources/tester/test_z01_work_items.py b/resources/tester/test_z01_work_items.py index 9e8b30a8..d32ec95a 100644 --- a/resources/tester/test_z01_work_items.py +++ b/resources/tester/test_z01_work_items.py @@ -40,7 +40,7 @@ def test_산림_평평한_잎_목록과_계산_규칙(client: TestClient) -> Non forest = next(i for i in listed if i["kind"] == "work_item_forest") assert forest["group"] == "work_item" and forest["rows"] == 365 - table = _get(client, "work_item_forest", size=500) + table = _get(client, "work_item_forest", size=500, axis_role="") # 「전부」 — 총칙까지 assert table["total"] == 365 and table["stats"] == {"work_items": 365, "units": 627} assert table["editable"] == [] and set(table["locked"]) == set(table["sortable"]) rows = table["rows"] @@ -67,7 +67,7 @@ def test_산림_평평한_잎_목록과_계산_규칙(client: TestClient) -> Non def test_건설_공종_축도_같은_길(client: TestClient) -> None: """건설(2026-09-17 뽑음) — 부문이 뿌리라 경로가 부문부터 · 열쇠 CW- · 계산 규칙은 전부 choose_one.""" - table = _get(client, "work_item_const", size=500) + table = _get(client, "work_item_const", size=500, axis_role="") assert table["total"] == table["stats"]["work_items"] > 900 rows = table["rows"] assert all(r["@id"].startswith("CW-") for r in rows) @@ -118,7 +118,7 @@ def test_불변_열쇠가_오면_id_로_씀_자료_파일은_판_id_로_가림( def test_거르기는_자료에_있는_가름만_서버가_판정(client: TestClient) -> None: """화면(서브 b890fba0)이 `filters` 를 받으면 상자를 세우고 고른 값만 보냄 — 판정은 서버 한 곳. 건설 부문 다섯 · 줄 구실(이름은 axis_policy.json). ⚠ 「임도가 쓰는 것」은 잣대가 없어 안 냄.""" - const = _get(client, "work_item_const", size=1) + const = _get(client, "work_item_const", size=1, axis_role="") by_key = {f["key"]: f for f in const["filters"]} assert set(by_key) == {"division", "axis_role"} division = by_key["division"] @@ -136,7 +136,7 @@ def test_거르기는_자료에_있는_가름만_서버가_판정(client: TestCl "general_provision" ] == "총칙" - civil = _get(client, "work_item_const", size=500, division="토목부문") + civil = _get(client, "work_item_const", size=500, division="토목부문", axis_role="") assert civil["total"] == next( o["rows"] for o in division["options"] if o["value"] == "토목부문" ) @@ -149,3 +149,25 @@ def test_거르기는_자료에_있는_가름만_서버가_판정(client: TestCl assert [f["key"] for f in _get(client, "work_item_forest", size=1)["filters"]] == ["axis_role"] assert _get(client, "labor", size=1, division="토목부문")["total"] == 261 # 다른 표는 안 거름 + + +def test_총칙_줄은_기본_감춤_전부를_고르면_보임(client: TestClient) -> None: + """2026-09-17 브레인 — 값을 안 보내면 상자 기본값(공종)으로 거름 · 화면은 그 기본값을 상자에 보임.""" + for kind in ("work_item_forest", "work_item_const"): + shown = _get(client, kind, size=500) + role = next(f for f in shown["filters"] if f["key"] == "axis_role") + assert role["default"] == "work_item" + counts = {o["value"]: o["rows"] for o in role["options"]} + assert counts["general_provision"] > 0 + # 기본 = 공종만 · 찾기 결과로 기본이 흔들리지 않음(총칙만 걸리는 낱말도 기본은 감춤) + assert shown["total"] == counts["work_item"] + assert ( + _get(client, kind, size=500, q="적용기준")["total"] + < _get(client, kind, size=500, q="적용기준", axis_role="")["total"] + ) + # 「전부」(빈 값을 보냄) → 총칙까지 + assert _get(client, kind, size=1, axis_role="")["total"] == counts[""] + assert ( + _get(client, kind, size=1, axis_role="general_provision")["total"] + == (counts["general_provision"]) + )