From 6b76a3f2734add8c186a30cdece2a118b1445081 Mon Sep 17 00:00:00 2001 From: umsangdon Date: Mon, 7 Sep 2026 08:06:12 +0900 Subject: [PATCH] =?UTF-8?q?feat(=EA=B5=AC=EC=A1=B0=EB=AC=BC):=20C=EA=B5=B0?= =?UTF-8?q?=20=EB=B2=BD=EC=97=90=20=E3=80=8C=EC=84=A4=EC=B9=98=20=EC=B8=A1?= =?UTF-8?q?=E3=80=8D=20=EC=B9=B8=20=EC=B6=94=EA=B0=80=20+=20=EC=B9=B8?= =?UTF-8?q?=EC=9D=84=20=EC=9E=A0=EA=B8=80=20=EC=88=98=20=EC=9E=88=EB=8A=94?= =?UTF-8?q?=20=EA=B5=AC=EC=A1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit PLAN 3-6 「설치 측을 사용자가 고르게 할지(폼에 칸 추가) 뒤에 정할 것」 — 2026-09-07 사용자 확정 「폼 선택은 가능하게 반영하고 나중에 선택 비활성화로 하자」. - 레지스트리 C군 5종(옹벽·돌쌓기(찰)·돌쌓기(메)·흙막이·큰돌쌓기)에 `side` 선택 칸. 선택지 「자동(성토 쪽)·좌·우」, 기본은 자동 — 종전 동작(성토 나는 쪽 자동)과 같음. - 기하는 이미 그 값을 봄 — `B06_Section_UI_Cross_Revetment.ts:168` 이 "좌"/"우" 면 그쪽, 아니면 `fillSide()`. 배관(`common_util_structure_walls.ts:80`)·파이썬 짝도 `options.side` 를 이미 나름. 즉 배선은 있고 **칸만 없었음**. - 옵션 칸에 `enabled` 를 둠(기본 참). 거짓이면 폼에 **회색으로 남고** 못 고르며 필수 검사 에서도 빠짐 — 칸을 지우지 않고 잠그는 자리(사용자 「나중에 비활성화」). 자체검증 — 레지스트리 5종 모두 `(['자동(성토 쪽)','좌','우'], 기본 '자동(성토 쪽)', enabled True)` 로 읽힘. 실화면 B06 C군 폼에 「설치 측」 칸이 그 세 선택지로 뜸(값 자동). tsc 통과. 시험 499 통과 — 실패 1·오류 8 은 모두 `require is not defined in ES module scope` 인 JS 도우미 건으로 내 변경과 무관(도우미 파일 날짜 8/27·9/2, 다른 환경에서 만든 것). Co-Authored-By: Claude Opus 5 (1M context) --- B05_Profile/B05_Profile_Api_Structures.ts | 2 ++ B05_Profile/B05_Profile_Structure_Types.json | 35 +++++++++++++++++++ B05_Profile/B05_Profile_Structures_Schema.py | 4 +++ .../B05_Profile_UI_Structures_Panel.ts | 9 ++++- 4 files changed, 49 insertions(+), 1 deletion(-) diff --git a/B05_Profile/B05_Profile_Api_Structures.ts b/B05_Profile/B05_Profile_Api_Structures.ts index e16ae580..b5ceb147 100644 --- a/B05_Profile/B05_Profile_Api_Structures.ts +++ b/B05_Profile/B05_Profile_Api_Structures.ts @@ -26,6 +26,8 @@ export interface StructureOptionField { default: string | number | null; /** 미확정 항목(기본값 없음) — 사용자가 값을 넣어야 저장된다. */ required?: boolean; + /** 거짓이면 폼에 **회색으로** 그려지고 못 고른다 — 칸은 남기되 잠그는 자리. */ + enabled?: boolean; /** 입력 시점 — B05는 유무·종류·위치만 받고 상세 치수(detail)는 B06/B07에서 받는다 * (2026-08-17 사용자 확정). detail이면 required여도 B05 폼에 그리지 않는다. */ phase?: "b05" | "detail"; diff --git a/B05_Profile/B05_Profile_Structure_Types.json b/B05_Profile/B05_Profile_Structure_Types.json index 3cd0db4e..9a59af11 100644 --- a/B05_Profile/B05_Profile_Structure_Types.json +++ b/B05_Profile/B05_Profile_Structure_Types.json @@ -639,6 +639,13 @@ "default": null, "required": true, "phase": "detail" + }, + { + "key": "side", + "label": "설치 측", + "input": "select", + "choices": ["자동(성토 쪽)", "좌", "우"], + "default": "자동(성토 쪽)" } ] }, @@ -697,6 +704,13 @@ "default": null, "required": true, "phase": "detail" + }, + { + "key": "side", + "label": "설치 측", + "input": "select", + "choices": ["자동(성토 쪽)", "좌", "우"], + "default": "자동(성토 쪽)" } ] }, @@ -755,6 +769,13 @@ "default": null, "required": true, "phase": "detail" + }, + { + "key": "side", + "label": "설치 측", + "input": "select", + "choices": ["자동(성토 쪽)", "좌", "우"], + "default": "자동(성토 쪽)" } ] }, @@ -813,6 +834,13 @@ "default": null, "required": true, "phase": "detail" + }, + { + "key": "side", + "label": "설치 측", + "input": "select", + "choices": ["자동(성토 쪽)", "좌", "우"], + "default": "자동(성토 쪽)" } ] }, @@ -871,6 +899,13 @@ "default": null, "required": true, "phase": "detail" + }, + { + "key": "side", + "label": "설치 측", + "input": "select", + "choices": ["자동(성토 쪽)", "좌", "우"], + "default": "자동(성토 쪽)" } ] }, diff --git a/B05_Profile/B05_Profile_Structures_Schema.py b/B05_Profile/B05_Profile_Structures_Schema.py index fc59be63..1afe9e16 100644 --- a/B05_Profile/B05_Profile_Structures_Schema.py +++ b/B05_Profile/B05_Profile_Structures_Schema.py @@ -44,6 +44,10 @@ class StructureOptionField(BaseModel): # (2026-08-17 사용자 확정). `detail`이면 required여도 B05 저장에서 강제하지 않는다 # — 필수 원칙은 유지되고 강제 시점만 B06/B07로 미뤄진다. phase: Literal["b05", "detail"] = "b05" + # 폼에 칸은 두되 **지금은 못 고르게** 할 때 거짓으로 둔다 — 회색으로 그려지고 값은 + # 기본값이 그대로 저장된다(2026-09-07 사용자: 「폼 선택은 가능하게 반영하고 나중에 + # 선택 비활성화로 하자」). 칸 자체를 없애면 나중에 켤 자리를 다시 찾아야 한다. + enabled: bool = True class StructureType(BaseModel): diff --git a/B05_Profile/B05_Profile_UI_Structures_Panel.ts b/B05_Profile/B05_Profile_UI_Structures_Panel.ts index 81fabbd1..10c1395d 100644 --- a/B05_Profile/B05_Profile_UI_Structures_Panel.ts +++ b/B05_Profile/B05_Profile_UI_Structures_Panel.ts @@ -322,11 +322,18 @@ export function createStructuresSection(callbacks: StructuresCallbacks): Structu input.value = String(preset ?? ""); } const label = option.unit ? `${option.label} (${option.unit})` : option.label; + // `enabled:false` 는 칸을 남기고 잠그기만 한다 — 값은 기본값이 그대로 저장된다. + const locked = option.enabled === false; + if (locked) { + input.disabled = true; + input.classList.add("is-locked"); + input.title = "지금은 고를 수 없는 항목입니다."; + } optionRow.append(field(label, input)); input.addEventListener("change", () => liveCommit()); optionInputs.push({ key: option.key, - required: !!option.required, + required: !locked && !!option.required, input, read: () => (option.input === "number" ? Number(input.value) || 0 : input.value), isEmpty: () => input.value.trim() === "",