auto: 2026-09-17 16:45 (ESD_LAPTOP)
This commit is contained in:
@@ -148,6 +148,8 @@ def notice(kind: str) -> list[str]:
|
|||||||
#: ⚠ 「임도가 쓰는 것」 같은 쓰임 가름은 잣대가 아직 없어 안 냄(지어내지 않음).
|
#: ⚠ 「임도가 쓰는 것」 같은 쓰임 가름은 잣대가 아직 없어 안 냄(지어내지 않음).
|
||||||
FILTER_KEYS = ("division", "axis_role")
|
FILTER_KEYS = ("division", "axis_role")
|
||||||
ALL = ""
|
ALL = ""
|
||||||
|
#: 값을 안 보냈을 때 거는 값 — 총칙 줄은 기본 감춤 · 「전부」를 고르면 보임(2026-09-17 브레인)
|
||||||
|
DEFAULTS = {"axis_role": "work_item"}
|
||||||
|
|
||||||
|
|
||||||
def _facets(kind: str) -> dict[str, dict[str, str]]:
|
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]]:
|
def filters(kind: str, rows: list[dict[str, Any]]) -> list[dict[str, Any]]:
|
||||||
"""거르기 상자 — 값이 둘 이상 갈리는 가름만 · 기본은 「전부」(안 거름)."""
|
"""거르기 상자 — 값이 둘 이상 갈리는 가름만 · 기본은 `DEFAULTS`(그 값이 표에 있을 때) 아니면 「전부」."""
|
||||||
facets = _facets(kind)
|
facets = _facets(kind)
|
||||||
labels = {"division": ("부문", {}), "axis_role": ("줄 구실", _role_names())}
|
labels = {"division": ("부문", {}), "axis_role": ("줄 구실", _role_names())}
|
||||||
out = []
|
out = []
|
||||||
@@ -179,13 +181,14 @@ def filters(kind: str, rows: list[dict[str, Any]]) -> list[dict[str, Any]]:
|
|||||||
if len(values) < 2:
|
if len(values) < 2:
|
||||||
continue
|
continue
|
||||||
label, names = labels[key]
|
label, names = labels[key]
|
||||||
|
default = DEFAULTS.get(key, ALL)
|
||||||
out.append(
|
out.append(
|
||||||
{
|
{
|
||||||
"key": key,
|
"key": key,
|
||||||
"label": label,
|
"label": label,
|
||||||
"options": [{"value": ALL, "label": "전부", "rows": len(rows)}]
|
"options": [{"value": ALL, "label": "전부", "rows": len(rows)}]
|
||||||
+ [{"value": v, "label": names.get(v, v), "rows": counts[v]} for v in values],
|
+ [{"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
|
return out
|
||||||
@@ -195,8 +198,11 @@ def apply_filters(
|
|||||||
kind: str, rows: list[dict[str, Any]], picked: dict[str, str]
|
kind: str, rows: list[dict[str, Any]], picked: dict[str, str]
|
||||||
) -> list[dict[str, Any]]:
|
) -> list[dict[str, Any]]:
|
||||||
facets = _facets(kind)
|
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]
|
rows = [r for r in rows if facets.get(r["@id"], {}).get(key) == value]
|
||||||
return rows
|
return rows
|
||||||
|
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ def test_산림_평평한_잎_목록과_계산_규칙(client: TestClient) -> Non
|
|||||||
forest = next(i for i in listed if i["kind"] == "work_item_forest")
|
forest = next(i for i in listed if i["kind"] == "work_item_forest")
|
||||||
assert forest["group"] == "work_item" and forest["rows"] == 365
|
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["total"] == 365 and table["stats"] == {"work_items": 365, "units": 627}
|
||||||
assert table["editable"] == [] and set(table["locked"]) == set(table["sortable"])
|
assert table["editable"] == [] and set(table["locked"]) == set(table["sortable"])
|
||||||
rows = table["rows"]
|
rows = table["rows"]
|
||||||
@@ -67,7 +67,7 @@ def test_산림_평평한_잎_목록과_계산_규칙(client: TestClient) -> Non
|
|||||||
|
|
||||||
def test_건설_공종_축도_같은_길(client: TestClient) -> None:
|
def test_건설_공종_축도_같은_길(client: TestClient) -> None:
|
||||||
"""건설(2026-09-17 뽑음) — 부문이 뿌리라 경로가 부문부터 · 열쇠 CW- · 계산 규칙은 전부 choose_one."""
|
"""건설(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
|
assert table["total"] == table["stats"]["work_items"] > 900
|
||||||
rows = table["rows"]
|
rows = table["rows"]
|
||||||
assert all(r["@id"].startswith("CW-") for r in rows)
|
assert all(r["@id"].startswith("CW-") for r in rows)
|
||||||
@@ -118,7 +118,7 @@ def test_불변_열쇠가_오면_id_로_씀_자료_파일은_판_id_로_가림(
|
|||||||
def test_거르기는_자료에_있는_가름만_서버가_판정(client: TestClient) -> None:
|
def test_거르기는_자료에_있는_가름만_서버가_판정(client: TestClient) -> None:
|
||||||
"""화면(서브 b890fba0)이 `filters` 를 받으면 상자를 세우고 고른 값만 보냄 — 판정은 서버 한 곳.
|
"""화면(서브 b890fba0)이 `filters` 를 받으면 상자를 세우고 고른 값만 보냄 — 판정은 서버 한 곳.
|
||||||
건설 부문 다섯 · 줄 구실(이름은 axis_policy.json). ⚠ 「임도가 쓰는 것」은 잣대가 없어 안 냄."""
|
건설 부문 다섯 · 줄 구실(이름은 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"]}
|
by_key = {f["key"]: f for f in const["filters"]}
|
||||||
assert set(by_key) == {"division", "axis_role"}
|
assert set(by_key) == {"division", "axis_role"}
|
||||||
division = by_key["division"]
|
division = by_key["division"]
|
||||||
@@ -136,7 +136,7 @@ def test_거르기는_자료에_있는_가름만_서버가_판정(client: TestCl
|
|||||||
"general_provision"
|
"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(
|
assert civil["total"] == next(
|
||||||
o["rows"] for o in division["options"] if o["value"] == "토목부문"
|
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 [f["key"] for f in _get(client, "work_item_forest", size=1)["filters"]] == ["axis_role"]
|
||||||
assert _get(client, "labor", size=1, division="토목부문")["total"] == 261 # 다른 표는 안 거름
|
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"])
|
||||||
|
)
|
||||||
|
|||||||
Reference in New Issue
Block a user