- 좌측 패널 · 아래 단추 넷 · 종단도 · 구조물 배치 폼을 페이지에 한 번만 만듦(design_shared) — 두 보기가 같은 노드 - 보기는 가운데 위 칸만: 종단 보기 = 3D(design_view_profile) · 횡단 보기 = 횡단 카드(design_view_cross · 처음 보일 때 그림) - 옛 B05_Profile_UI_Page · B06_Section_UI_Page 삭제 · 한 벌이 받은 조작은 지금 보기로, 관 목록 · 횡단 재계산 알림은 두 보기 모두로 - 진행 단계 종단설계 · 횡단설계 두 칸이 보기를 따라 켜짐 · 누르면 주소만 바꿈 · 제목도 따라감(setTitle · setActiveStep) - [저장] · [확정] 한 벌 — 두 보기 몫을 모아 saveDesign 한 번 · 종단 보기 [확정] 켬(횡단 보기를 숨긴 채 세워 횡단 자료를 얻음) - [초기화] · 계획노선 편집은 같은 페이지라도 다시 세움(remountRoute) - 덧붙임: 방향키는 초점 있는 쪽만(조정창 ↔ 종단도 계획고) · 횡단 보기 계획고 편집에도 [3D 업데이트] 대기 표시 · 종단 보기 폼 관 옵션을 횡단 캐시에도 얹음 · 종단 보기에서 횡단 조정 칸 가림 - 나눔: Cross_View 756→658(_Cross_View_Frame) · Page_Structures_Panel 700→547(_Structures_Spec) · 옛 B05 Page 786 → design_view_profile 638(_Page_Latest · _Page_Stations) - 시험: test_design_view_parity 한 벌 기준(한 패널 · 보기 오가도 같은 노드) · page_single · profile_single · save_channels · save_recompute 등 옮긴 자리로 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01KmELpdXFDRZHhfbGuRhSmL
74 lines
4.1 KiB
Python
74 lines
4.1 KiB
Python
"""상세 제원(뒷길이·돌규격·형식)을 **B06 에서 받는지** — 2026-09-08 데스크탑 창 보고.
|
|
|
|
무슨 일이었나 — 레지스트리는 그 칸들을 `phase: "detail"` 로 두고 「B05 는 유무·종류·위치만,
|
|
상세 치수는 B06/B07 에서」(2026-08-17 사용자 확정)로 갈라 놓았는데, **그 화면이 아직 안 받고
|
|
있었다.** 그래서 실무 프로젝트의 구조물 옵션에 `back_len_cm`·`stone_cm`·`form` 이 통째로 비어
|
|
있었고, **수량이 품셈 갈래를 못 골라** 금액이 0 으로 남았다(13-4 돌쌓기 뒷길이 · 13-6 큰돌쌓기
|
|
직경 · 12-3 옹벽 형식).
|
|
|
|
고침 — 폼이 `includeDetail` 을 받아 **B06 에서만** 상세 칸까지 그린다. B05 는 종전 그대로다.
|
|
"""
|
|
|
|
import sys
|
|
from pathlib import Path
|
|
|
|
PROJECT_ROOT = Path(__file__).resolve().parents[2]
|
|
if str(PROJECT_ROOT) not in sys.path:
|
|
sys.path.insert(0, str(PROJECT_ROOT))
|
|
|
|
from B05_Profile.B05_Profile_Structures_Schema import load_structure_types # noqa: E402
|
|
|
|
_PANEL = PROJECT_ROOT / "B05_Profile" / "B05_Profile_UI_Structures_Panel.ts"
|
|
# 옵션 칸 그리기는 700줄 제한으로 이 조각으로 옮겨 감(2026-09-29 · PLAN 21-4)
|
|
_PANEL_OPTIONS = PROJECT_ROOT / "B05_Profile" / "B05_Profile_UI_Structures_Panel_Options.ts"
|
|
# 폼은 두 보기가 한 벌을 쓴다 — 상세 칸은 한 벌이 보기에 따라 그린다(계획서 24-3b).
|
|
_SHARED = PROJECT_ROOT / "A00_Common" / "design" / "design_shared.ts"
|
|
_B05 = PROJECT_ROOT / "B05_Profile" / "B05_Profile_UI_Panel.ts"
|
|
|
|
|
|
def _type(type_id: str):
|
|
return next(item for item in load_structure_types() if item.type_id == type_id)
|
|
|
|
|
|
def test_B06_은_상세_칸까지_받는다():
|
|
assert 'includeDetail: () => shared.view() === "cross"' in _SHARED.read_text(encoding="utf-8")
|
|
# 그릴 때마다 지금 보기로 가린다 — 만들 때 한 번 굳히면 한 벌 폼이 보기를 못 따라간다.
|
|
assert 'typeof detail === "function" ? detail()' in _PANEL.read_text(encoding="utf-8")
|
|
|
|
|
|
def test_B05_는_종전대로_유무_종류_위치만():
|
|
"""2026-08-17 사용자 확정 — B05 폼에 상세 칸이 생기면 안 된다."""
|
|
assert "includeDetail" not in _B05.read_text(encoding="utf-8")
|
|
|
|
|
|
def test_기본값_없는_필수_항목은_빈_칸으로_연다():
|
|
"""첫 항목을 슬쩍 고르면 **근거 없는 값**(뒷길이 25㎝ 같은)이 수량·단가로 흘러간다."""
|
|
panel = _PANEL.read_text(encoding="utf-8") + _PANEL_OPTIONS.read_text(encoding="utf-8")
|
|
fields = (PROJECT_ROOT / "B05_Profile" / "B05_Profile_UI_Structures_Fields.ts").read_text(
|
|
encoding="utf-8"
|
|
)
|
|
# 2026-09-14 — 칸 만들기가 `optionControl` 로 옮겨감 · 고르기 칸은 **늘** 빈 보기(브레인 판정 ①).
|
|
# 필수 칸의 글자는 그대로 「— 선택 —」이다.
|
|
assert "optionControl(option, values[option.key])" in panel
|
|
assert '? "— 선택 —"' in fields and 'select([["", blank]' in fields
|
|
|
|
|
|
def test_큰돌쌓기에_메_찰_구분이_있다():
|
|
"""품셈이 13-6-1 메쌓기 / 13-6-2 찰쌓기로 갈라 두는데 구분 칸이 없어 못 골랐다
|
|
(2026-09-08 데스크탑 창 요청). 돌쌓기는 이미 타입이 갈려 있다(찰/메)."""
|
|
bond = next(o for o in _type("boulder_masonry").options if o.key == "bond")
|
|
assert bond.choices == ["메쌓기", "찰쌓기"]
|
|
assert bond.default is None, "기본값을 두면 안 된다 — 설계자가 고를 값이다"
|
|
assert bond.required is True
|
|
assert bond.phase == "detail", "상세 제원이라 B06/B07 에서 받는다"
|
|
|
|
|
|
def test_규격_축이_타입마다_다르다():
|
|
"""⚠ 큰돌쌓기는 **직경**(13-6), 돌쌓기는 **뒷길이**(13-4) — 섞으면 엉뚱한 계수로 돈다
|
|
(2026-09-08 데스크탑 창이 실제로 그 결함을 잡았다)."""
|
|
stone = next(o for o in _type("boulder_masonry").options if o.key == "stone_cm")
|
|
back = next(o for o in _type("masonry_wet").options if o.key == "back_len_cm")
|
|
assert stone.choices == ["40~60", "60~80", "80~100"], "큰돌쌓기 = 직경 축"
|
|
assert "35" in back.choices and "75" in back.choices, "돌쌓기 = 뒷길이 축"
|
|
assert set(stone.choices).isdisjoint(set(back.choices))
|