- 하단선 = 수평(기초공사 기준 — 2026-08-22 사용자 확정). 깊이는 벽
발자국 안 원지반(또는 관 invert) 최저점 − 0.5m. 종전 지반 추종
경사 하단 폐지.
- 전면 1:0.3 경사선을 하단까지 연장 — 바닥이 깊어진 만큼 발끝이
바깥으로. 발끝 지반이 더 낮으면 한 번 더 내림(2-pass).
- WallLayout.height = 상단~하단 전체 높이(근입 포함)로 변경 — 툴팁
H 표기 기준. 설계 파라미터(폭·기움)는 invert 기준 높이 유지.
- 검증: 4+4.3(H 2.0/2.1)·13+15.7(H 1.9) 하단 수평·관 감싸기 SVG
실좌표 확인.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
- 조정창 ◀/▶ 요청이 한계에 잘려 벽이 안 움직일 때 이유를 토스트로
알린다(2026-08-22 사용자 요청, 13+15.7 참조).
· 안쪽 한계: 성토 물매 1:1.2가 깨지는 자리(배관 최소 길이)
· 바깥 한계: 조정 범위 초과
- 그 벽이 선택된 조작 중에만 띄운다 — 리로드로 복원된 세션 값에는 침묵.
- 검증: 공용 브라우저 실조작 — 13+15.7 안쪽 시도 토스트 표시,
바깥 정상 이동 시 무음.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
- 관 하단선은 관 시작점과 유출 벽 하단선 중점(invert)을 잇는 직선으로
고정 — 정수 맞춤이 벽을 옮길 때마다 축·법선 재유도(deriveAxis).
종전엔 옛 축을 그대로 늘려 가파른 지반(13+15.7)에서 관이 벽 바닥
아래로 삐져나갔다.
- 관 시작 기준도 유입 노견점이 아니라 실제 관 시작점(집수정 내공 벽)
으로 통일.
- 끝단면 교점을 마감면 선분 안으로 클램프(clampToFace) — 연장선
교차로 벽 밖에 꼭짓점이 생기는 것 차단.
- 검증: 13+15.7 SVG 실좌표(관 꼭짓점 385→371, 벽 하단 379 위),
4+4.3 회귀, dz 스윕 24건 이탈 0건.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
- 자동 자리 = 물매 1:1.2가 딱 성립하는 가장 안쪽(노견 최소) 지점.
관 m단위 올림 잔여만 유출 벽 바깥 이동으로 흡수(minShoulderWallOffset).
사면 끝 밖 자리는 급물매 교정일 때만 인정 — 얕은 성토 폭주 방지.
- 손으로 민 벽은 관 정수 맞춤이 절대 옮기지 않음 — 한쪽 이동 시
반대쪽 벽 동시 이동(관 +2m) 소멸. 표기 길이만 올림(m).
- 안쪽 당김 한계 = 1:1.2 성립 자리(우선순위: 배관 연장 > 높이 증가 >
바닥 띄움). 1:1.2 자리가 없는 지형 폴백에서만 높이 증가·바닥 띄움
(solveWallVertical, 한계 찰3.0/메2.0).
- 기슭막이는 관을 감싼다: 하단은 항상 관 invert 아래 0.5m 확보,
뜬 바닥도 동일(뜬 공간은 별도 지지 구조물 — 추가 예정).
- 검증: 4+4.3 관 13m→9m·노폭연장 1.52→0.08, 13+15.7 UI 조작
(◀▶↺·클램프·단독이동) 및 dz 스윕 24건 물매 이탈 0건.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
물매를 1:1.2~2.0 범위에서 역산하던 방식을 걷어내고 **수평 1.2 : 수직 1 고정**으로
바꿨다(2026-08-21 사용자 확정). 벽이 1:1.2 사면이 닿는 자리보다 밖에 있으면 물매를
완만하게 바꾸는 대신 **노폭을 그만큼 늘린다** — 기슭막이를 바깥으로 1m 밀면 노폭이
약 1m 늘어난다.
- fillSlopeOf가 [원 노견 → 연장된 노견 → 벽 이음선 상단점] 폴리라인을 돌려주고,
설계선 오버레이가 그 폴리라인을 그린다(노면 연장 구간이 수평으로 붙는다).
- 반대로 벽이 안쪽이라 물매가 1:1.2보다 급해지는 자리는 노폭으로 못 맞춘다(도로를
좁힐 수는 없다) — 자동 자리를 1:1.2가 될 때까지 바깥으로 미는 처리를 유지한다.
- fillSlope.roadWideningM 신설, 툴팁에 "노폭 연장 x.xxm" 표시.
검증(계획고 스윕 24케이스): 물매 23건이 정확히 1:1.200(나머지 1건은 성토고 0.2m로
사면이랄 게 없는 측점). 벽 이동 시험 — 밖으로 1m씩 밀 때 노폭 연장 1.52→3.27→
4.22→5.21m, 물매는 계속 1:1.200. tsc 통과, pytest 148 pass.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
기슭막이 기본 자리를 사면 끝으로 바꾼 뒤 물매가 규정보다 급해지는 측점이 생겼다
(13+15.7 실측 1:0.865 — 성토_비탈면.md §1의 1:1.2~2.0 위반). 1:1.2는 지켜야 하는
하한이므로, 사면 끝 자리의 물매가 그보다 급하면 **1:1.2에 닿을 때까지 바깥으로**
민다. 지반이 1:1.2보다 급해 끝내 못 맞추면 사면 끝을 그대로 쓰고 경고로 알린다.
물매 계산의 이음선 위치도 바로잡았다 — 자리 기준이 하단선 중점으로 바뀐 뒤에도
`REVET_TRAP_TOP_M`을 그대로 더해 실제보다 0.3m 바깥으로 보고 있었다.
`fillWallBaseWidth()`로 중점↔이음선 환산을 한곳에 모았다.
검증(계획고 스윕 24케이스, 새 계획노선): 물매 최소 1:1.202 — **1:1.2 미만 0건**
(종전 0.4~0.9까지 나왔다). 페이지 실데이터로도 13+15.7 1:1.206 확인.
tsc 통과, pytest 148 pass.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
집수정 벽 높이를 성토 경사선과의 교점으로 잡던 방식을 걷어내고, **관 아래 여유
0.5m + 관경 + 관 위 여유 0.5m**로 정한다(2026-08-21 사용자 확정). 위 여유는
기슭막이와 같은 REVET_FREEBOARD_M을 써서 좌·우 표현이 어긋나지 않는다.
BASIN_BOTTOM_CLEARANCE_M(0.5) 신설. 종전 바닥판 두께 0.45가 아래 여유 자리를
겸하고 있었다.
검증(13+15.7, D800): 집수정 깊이 1.8m = 0.5 + 0.8 + 0.5, 바닥 여유 0.5 확인.
계획고 스윕 24케이스 문제 0. tsc 통과, pytest 148 pass.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
- 조정창 숫자가 실제와 갈렸다. 안쪽으로 계속 누르니 "안쪽 10.0m"까지 올라가는데
벽은 노견 한계에서 멈춰 있었다. 기하가 **실제 적용한 이동량**(revetShift)을 돌려
주고, 카드가 그 값을 제어기에 되담는다 — 이제 한계에 닿으면 숫자도 멈춘다.
- 안쪽으로 당기면 사면이 짧아져 물매가 급해진다. **1:1.2(가장 급한 한계)**를 넘지
않는 자리까지만 들어가게 막았다(2026-08-21 사용자 지시). 바깥으로 밀 때는 완만해
지므로 막지 않고 범위 밖이면 경고로만 알린다.
검증: 4+4.3은 자동 자리가 이미 1:1.21이라 안쪽 이동 0(차단), 13+15.7은 −1m까지
허용(1:1.61)하고 그 이상 차단. 조정창 숫자도 같은 자리에서 멈춘다. 두께 16케이스
0.450 고정, 계획고 스윕 24케이스 문제 0. tsc 통과, pytest 148 pass.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
유입 벽을 조정창으로 밀면 유출 벽이 자동으로 관 길이를 맞추다가 **폭 흡수 폴백**에
걸려 0.45→0.85m로 부풀었다(4+4.3 화면 확인: 좌 0.45 / 우 0.85). 조정한 벽만 폭을
지키게 했던 앞 조치로는 반대편 벽이 보호되지 않았다.
폭 흡수를 아예 없앤다 — 벽 두께는 항상 0.45 고정이고, 자리를 더 못 옮기면 거기서
멈춘다. 남는 몫은 관이 벽을 조금 벗어나는 것으로 두는 게 기존 확정 규칙이다.
검증: 두 측점 이동 16케이스 전부 두께 0.450 고정(두께 이상 0건), 계획고 스윕
24케이스 문제 0. tsc 통과, pytest 148 pass.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
벽 밑을 관 축(유입 → 자연 사면 끝 직선) 위에 얹고 있었다. 성토측 지반이 관 물매보다
가파른 구간에서는 축이 지반 위로 떠올라 벽이 공중에 떴다 — 13+15.7 유출 벽은 자동
자리에서도 전면 0.14m, 바깥으로 2m 밀면 배면까지 0.16m 떴다.
관 끝은 원지반 위에 놓는다는 원칙대로 벽 밑을 **그 자리 원지반**(역경사는 유입 invert로
클램프)으로 바꿨다. 관 물매는 그 자리에 맞춰 다시 잡힌다. 유입 벽은 원래 지반을 따르고
있어 멀쩡했다 — 좌우가 달라 보인 이유가 이것이다.
표기 길이도 목표값이 아니라 **실제 그려진 관**의 올림값으로 바꿨다(자리 제약에 걸려
못 늘린 경우 도면보다 길게 적혔다).
검증: 이동 ±3m 전 구간 배면 근입 +0.500 고정(종전 −0.16~+0.59), 계획고 스윕
24케이스 문제 0. tsc 통과, pytest 148 pass.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
지적 3건:
- 우측(유출) 기슭막이만 좌우로 밀 때 단면이 변했다. 0.1m씩 미니 관 길이 정수의
끝수를 벽 폭이 흡수해 0.45→0.90까지 뚱뚱해졌다. 조정 단위를 **관 길이 1m**로
바꾸고, 조정창으로 옮긴 벽은 폭을 절대 건드리지 않게 했다. 자리만 옮기면 정수
길이가 성립하므로 형상이 그대로다(검증: 두께 0.450 고정, L 1m씩 증감).
- 성토 사면이 역전되는 자리가 있었다. 벽 상단이 노견보다 높아지면 사면선이 위로
올라간다 — 최소 성토고 0.3m(FILL_MIN_RISE_M)를 두고 그 앞에서 멈춘다.
- 이동이 노견을 넘어 도로 반대편까지 갔다. 벽은 제 노견 바깥에만 서게 막았다.
조정창은 "관 길이 8m · 바깥 2.0m"처럼 관 길이를 같이 적는다.
700줄 유지를 위해 clampWallOffset·cutLength·outletSlopeFactory를 _Solve로 옮겼다.
검증: 이동 ±5m 20케이스 역전 0건·두께 고정, 275.71 유출 이동 11↔7m 정상,
계획고 스윕 24케이스 회귀 문제 0. tsc 통과, pytest 148 pass.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
카드 하단 버튼 그룹을 걷어내고 **해당 횡단도 안**에 뜨는 조정창으로 바꿨다
(2026-08-21 사용자 확정). 앞으로 구조물 위치 조정은 모두 이 창을 통한다.
- _UI_Cross_Structure_Panel.ts 신설. 그래프 영역 좌측 하단에 절대 위치로 얹는다
(줌 버튼 우측 상단·면적표 중상단과 겹치지 않는 자리).
- 창 내용: 구조물 이름 · 자동 자리 대비 이동량 · ◀/▶/↺ · ✕(닫기 = 선택 해제).
- 이동량은 부호(+/−) 대신 "바깥 0.2m"처럼 적는다 — 좌·우 벽에서 부호만으로는
어느 쪽인지 읽히지 않는다.
검증(공용 브라우저 4+4.3): 유입 벽 클릭 → 창 열림(제목·자동 자리), ◀ 2회 →
"바깥 0.2m"·도형 이동, ↺ → 자동 자리 복귀, ✕ → 창 닫힘·강조 해제.
tsc 통과, pytest 148 pass.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
- 강조 색을 --color-danger(붉은색)로 변경.
- 구조물을 고르면 그 측점 카드도 같이 선택된다. 이미 선택된 카드 안에서 다른
구조물을 고를 때는 강조만 옮겨 가고 카드 선택은 건드리지 않는다.
- 구조물 선택과 절·성토 면적 강조는 같은 레벨 — 하나를 고르면 다른 하나가 풀린다.
카드가 선택에서 빠져도 구조물 선택은 풀린다.
- 조정 버튼이 안 보이던 원인: .b06-cross-card__revetctl 스타일과 .is-hidden 규칙이
아예 없었다. 스타일을 넣고 "기슭막이" 라벨을 붙여 표시 반폭 그룹과 구분했다.
미선택 카드에서 구조물이 먹히지 않던 버그도 잡았다 — 면적 비우기(onAreaSelect)가
먼저 카드를 선택해 버려, 뒤이은 onSelect가 "같은 측점 재클릭 = 해제"로 상쇄됐다.
검증(공용 브라우저 4+4.3): 미선택 카드에서 구조물 클릭 → 벽 강조 + 화살표 + 카드
선택. 같은 카드 다른 구조물 → 강조만 이동. 면적칩 → 구조물 해제. 다시 구조물 →
면적 해제. tsc 통과, pytest 148 pass.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
화면 확인에서 나온 두 가지:
- 그리기 순서가 벽 → 관 → 보호공이라 관 폴리곤이 벽 가운데를 덮어, 벽을 눌러도
관이 먼저 클릭을 먹었다. 그리기 순서는 그대로 두고 **투명 판정면**을 맨 마지막에
얹어 벽 전체가 눌리게 했다.
- 선택 강조가 존재하지 않는 --color-accent를 참조하고 있었다. 면적 밴드와 같은
규칙으로 --color-royal-amethyst를 쓰고, 규칙 위치도 기슭막이 기본 스타일 옆
(_Style_Cross_Areas.css)으로 옮겼다.
검증(공용 브라우저, 13+15.7 카드): 벽 클릭 → 강조·화살표 노출, ◀ 2회 이동 반영,
↺ 자동 자리 정확 복귀. tsc 통과, pytest 148 pass.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
- 기슭막이 폴리곤을 눌러 고르면 강조되고 카드 하단에 ◀/▶/↺가 뜬다. 0.1m씩
화면 좌우로 민다(좌우 벽에서 뜻이 뒤집히지 않게 outward 부호는 내부 환산).
- 구조물 선택이 절·성토 면적 강조보다 우선한다. 벽 클릭은 벽에서 멈춰 밴드·카드
선택으로 번지지 않고, 한쪽을 고르면 다른 쪽 강조는 꺼진다.
- computeCulvertLayout에 revetShift 인자 추가. 손으로 민 자리는 고정되어 관 길이
정수 맞춤이 벽을 다시 옮기지 않고 폭으로만 흡수한다(폭 상한 0.45×2).
- 값은 세션 보관(b06:revetx), 이동 범위 ±3m.
- 700줄 정리: Page 751→690(_UI_Page_Station_Controls 분리),
Cross_View 765→629(_UI_Cross_View_Zoom 분리).
검증: 이동 5케이스 접점 오차 0.00e+00, 계획고 스윕 24케이스 회귀 문제 0,
tsc 통과, pytest 148 pass. 화면 조작 확인은 다음 단계.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
- 기슭막이 높이 = 관경 + 여유고 0.5m (0.1m 눈금 올림). 좌우 여유고 동일.
- 관 길이는 절단 긴 변 기준 정수 m. 벽 자리 이동으로 맞추고, 물매·5m 제약에
걸리면 벽 폭으로 흡수(폭은 5m 한계를 넘지 않는 범위까지만).
- 성토 물매를 1:1.2 고정에서 1:1.2~2.0 범위(성토_비탈면.md §1)로 전환.
벽 자리가 굳은 뒤 물매를 역산해 사면선이 벽 이음선 상단점을 지나게 한다.
종전에는 관 길이 맞춤이 벽을 옮겨 접점이 깨졌고 스냅으로 가리고 있었다.
- 성토 사면선은 단일 각도 직선 하나를 배수관 레이아웃이 직접 공급(설계선 대체).
- 벽 자리 탐색 상한 = 성토 사면 끝, 사면길이 5m 초과 전까지. 성토고 3m 이상이면
5m 쪽으로 끌어올린다.
- 기슭막이로 성토를 못 받는 자리는 structureRequired로 표시(옹벽·석축 검토).
- 700줄 제한으로 Const/Types/Solve 3개 파일 분리.
검증: 계획고 -2.0~+3.0 스윕 24케이스 문제 0 (접점 오차 <1e-6, 여유고 0.5,
5m 초과는 전부 경고). tsc 통과, pytest 148 pass.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
원인: 진입 로직이 data.options.cross_half_width_m을 '사용자가 확정한 표시 반폭'으로
보고 입력칸을 덮었다. 그 값은 종·횡단을 만들 때 쓴 **샘플링(계산) 반폭**이고
백엔드 기본이 20m라, 표시 기본값 12를 넣어도 진입할 때마다 20으로 돌아왔다.
수정: 계산 범위(백엔드 20m)는 그대로 두고, 입력칸은 사용자가 실제로 고른 표시
폭만 되살린다 — 측점 개별 표시 반폭 저장값(design.display_half_width_m)의 최대값,
그다음 세션에 남은 마지막 조절값 순. 둘 다 없으면 표시 기본 12m.
검증: tsc, pytest 125 통과, 헤드 브라우저 B06 탭에서 반폭 12·횡단면도 X축 12~-12 확인.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- 종단 상단 표시줄을 법정 판정 3항목으로 축소: 최대 기울기/상한(별표2 Ⅰ.2.라),
절·성토 불균형(Ⅰ.1.나.(4)(다)), 종단곡선 필요 n곳(Ⅰ.2.마 — 대수차 5% 초과인데
곡선이 빠진 변화점). 변화점·종단곡선 개수·기본 곡선길이 L·중복 경고칩은 제거.
- [초기선 복원] → [편집 되돌리기] — 실제 동작은 화면 편집 델타 삭제이지 저장 지점
복귀가 아니다. 툴팁에 동작과 [초기화]와의 차이를 적었다.
- 3D 뷰포트 안내 라벨 삭제(로딩 완료 후 남던 조작법 문구).
- 배수유역 버튼 정비: 유역 다시 나누기 / 선택한 관 삭제 / 배관 배치 초기화 +
각 툴팁에 실제 동작 명시(선택 삭제는 툴팁 자체가 없었다).
- 유토곡선 요약 12칩 → 5칩(절토·성토·잉여|부족·운반·검산). 토질 3종 내역·다짐
환산·블록 수·장거리 운반·사토는 해당 칩 툴팁으로. B05·B06 공용 함수라 동시 반영.
- 설계속도 축 도입(임도는 속도를 낼 수 없는 노선 — 기본 20km/h):
· 임도 종류는 프로젝트 등록값(projects.road_type)을 읽어 B05가 읽기 전용 표시
(main→간선임도, fire→산불진화임도, 그 외→작업임도). 화면에서 고치지 않는다.
· 설계속도 선택(간선·산불진화 20/30/40, 작업 20 고정) 신설 — 종단기울기 상한과
종단곡선 반경이 등급이 아니라 이 값으로 정해진다(지식DB 설계제원_총괄 §6·§7).
· B02 임도 종류 선택지를 현행 3종으로 정리(지선 폐지·계류보전은 사방 구분).
· 백엔드: ROUTE_GRADE_CLASSES 3종+branch 호환, selectable_design_speeds 신설,
resolve_design_speed 신설, legal_grade_limit_pct·resolve_grade_options에
설계속도 인자, sections/context가 road_type 제공(B06도 저장값 승계).
· 계획선 정책은 그릴 때마다 현재 기준으로 동기화 — 저장분의 옛 상한이 남지 않는다.
- 검증: pytest 125 통과(설계속도 12건 신규), tsc, 헤드 브라우저 — 진입 시 상한 9%,
40km/h 전환 시 7% 즉시 반영, 원복 9%, 안내문 '간선임도 · 설계속도 20km/h ·
일반지형', 유토곡선 5칩, 유역 버튼 새 이름·툴팁, 3D 라벨 빈 문자열 확인.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- 기슭막이는 기슭(사면)을 막는 공정이라 그 아래 돌붙임이 붙을 자리가 아니다
(2026-08-19 사용자 지시). 배관 유입·유출부와 독립 기슭막이에서 보호공
(돌붙임 찰/메·도수로)·보호공 면적·도수로 폭 옵션을 전면 삭제.
- 바닥막이(bed_sill) 부활 — D군 점형, 형태(돌붙임 찰/메)·면적·높이
(기본 메·10㎡·0.3m). 바닥 보호는 이 구조물이 담당한다.
- 독립 기슭막이(D4)를 시설 서브폼에서 떼어 C군과 같은 레지스트리 옵션 방식으로
전환: 측점 범위 + 기준측점 전/후, 기본 돌쌓기(메)·높이 2.5·길이 10·전 5·후 5.
- 페이지 설정의 지형 구분·등급·최대 종단기울기를 바꾸면 안내문·placeholder와
종단 그래프 위반 판정이 즉시 갱신된다(profilePanel.setGradeLimit 신설).
계획선 자체 재산출은 서버 재계산 몫이라 건드리지 않는다.
- 지식DB 재점검(설계제원_총괄 §4·§6·§7): 종단기울기·종단곡선 반경 표는 일치.
미해결 3건(폐지된 "지선" 선택지·등급↔설계속도 고정 매핑·최소 곡선반경 안내가
종단곡선 반경)은 값을 임의로 바꾸지 않고 주석으로 남겼다 — 사용자 협의 대기.
- 검증: pytest 113 통과, tsc, 헤드 브라우저(D군 목록 바닥막이, 기슭막이 범위+
전/후·보호공 없음, 배관 서브폼 보호공 라벨 소멸, 지형 변경 7%→10%·위반 재판정).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- 위치 마지막 칸 Tab → 상세 옵션 첫 칸(잠금 해제보다 탭 계산이 빨라 메모로
건너뛰던 문제). 화면 순서(위→아래) 그대로 이동.
- [초기선 복원] → "저장선 복원"으로 문구 교정 — 복원 목표는 마지막 저장선이다
(임시저장 시 편집이 정본에 반영). 최초 자동 계산 복귀는 [초기화] 안내.
- 종단 알약에 좌측 목록과 같은 중복 번호("옹벽 1/2") — 라벨·툴팁·벌룬 동일 표기.
- [초기화] 무동작 수정: 원인은 playwright 연결 브라우저의 네이티브 confirm 자동
취소. 공용 showConfirmDialog 모달(ui_template_elements) 신설로 교체.
- C군 옵션: 전길이 → "기준측점 전" + "기준측점 후" 신설(기본 10/5/5). 나중에
입력한 쪽이 살아남고 반대쪽 = 길이 − 그 값. 저장은 before_m 기준(후는 파생).
- B06 횡단 반폭 표시 기본 20 → 12 (계산·보유 샘플 폭은 백엔드 20m 유지 — 표시
범위만 좁힘, 저장·세션값 있으면 그 값 우선).
- 측점 범위 표기 폰트 = 기준 측점 입력 칸과 동일(13.33px), 볼드 유지.
- 검증: pytest 112 통과, tsc, 헤드 브라우저 — Tab 포커스 '높이', 전7→후3·후2→전8
연동, 범위 2+12.0~3+2.0, 알약 '옹벽 1/2', 초기화 모달 표시, 저장 왕복·원복.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- C군 기본값 확정(2026-08-19 사용자): 높이 2.5·길이 10·전길이 5 — 기본값이 생겨
required 해제. 기준 측점만 넣으면 범위가 바로 계산된다.
- 드래그 민감도 완화: 종단 알약(누적→변위 14px, 임계 전 시각 이동 금지)·배수유역도
관 마커(이동 시작 8px 임계) — 고르려다 옮겨지는 문제.
- 3D 노선 우클릭 → 구조물 배치 메뉴(신규 B05_Profile_UI_Viewer_Menu) — 지형 픽을
노선 폴리라인에 투영(15m 이내), 그래프·배수유역도와 같은 2단 메뉴·addAt 경로.
- 우클릭 메뉴 전역 단일화(ui_template_context_menu): 새 메뉴가 열리면 다른 영역
메뉴는 닫히고, 좌클릭·중간버튼은 어디서든 닫는다(캡처 단계).
- 3D 비정규 측점(배관 등) 좌표를 노선 폴리라인 chainage 투영으로 정확화 — 규칙
측점 직선보간의 곡선 모서리 잘림(노선 이탈) 해소.
- 3D 측점선(노란 띠) 도로 반폭 1.5배 연장 — 측구 방향 램프는 끝단에 따라붙음.
- 검증: pytest 112 통과(정책 테스트 기본값 반영), tsc, 헤드 브라우저 저장 왕복
(기준 3+0 → 55~65·anchor 60·before 5, 목록 '배수관 1/2' 번호 표기).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- C군 5종에 전길이(before_m, 기본 0) 옵션 신설 — 시작 = 기준 − 전길이,
후길이 = 길이 − 전길이 자동. 종단 마크 = 기준점, 띠 = 시작~종료(기존 렌더 유지).
전길이 > 기준(시작 음수)은 칸 붉힘으로 거절. 구 저장분은 폼 로드 시 역산 채움.
- 옹벽(철근콘크리트) → "옹벽" (전역 표기는 레지스트리 name 단일 원천).
- 좌측 구조물 목록: 같은 이름 여럿이면 노선 시점 가까운 순 "이름 1/2…" 번호
(numberDuplicateNames 공용 헬퍼 — B06 목록 신설 시 재사용, 2026-08-19 사용자 지시).
- 검증: pytest 112 통과, tsc, 헤드 브라우저(CDP 캐시 비움 방식) — 옵션 순서
높이→길이→전길이, 전5 범위 2+15.0~3+5.0, 목록 "옹벽 1/2", 원복 확인.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- 레지스트리: C군 5종(옹벽·돌쌓기 찰/메·흙막이·큰돌쌓기)에 길이 옵션 신설,
높이와 함께 B05 필수 입력(phase b05)으로 전환. 순서 = 높이 → 길이.
- 패널: 구간 직접 입력(시작·종료) 삭제, 기준 측점 위 '측점 범위' 표시 행 신설
— 기준+길이로 "시작 ~ 종료" 실시간 계산, 저장 시 시작=기준·종료=기준+길이.
- 구간 직입 시절 저장분 호환: 폼에 열면 길이를 시작~종료에서 자동 역산.
- 검증: pytest 111 통과(tmp/tests 정책·저장소 테스트 갱신), tsc, 헤드 브라우저
저장 왕복(60~90·len=30·h=2.5) 확인.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
측점 표기 규칙(2026-08-18 사용자 확정): 잔여거리는 [0, 간격 20m) 범위만 유효,
넘치면 측점번호로 올려 표시한다(1+30 → 2+10). 저장 수치는 원래 누가거리라
계산은 이미 동일했고, 입력 칸 표시를 확정(change) 시점에 정규화한다.
시작·기준·종료 측점 세 칸 공통(stationFields 확장).
검증(헤드 브라우저): 1+30→2+10.0, 0+45→2+5.0, 3+19.9 유지, 3+20→4+0.0 PASS.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
- 3-1 우클릭 메뉴 일원화: 종단그래프·배수유역도 빈 자리 메뉴 = 사이드 「구조물
배치」와 같은 구조물군(A~G·기타) → 종류 2단 아코디언(공용 컨텍스트 메뉴에
하위 메뉴 지원 추가). 선택 = 즉시 추가가 아니라 폼 자동 지정(addAt, A군은
임시 배치까지). 구 [배관 추가]·평면 나열·기성막이/대피로 항목 흡수.
- 3-2 유역 리스트 문구: 세월교 검토→세월교 제안, BOX암거 후보→BOX암거 제안,
추천 Ø{d} 배관→Ø{d} 배관 제안.
- 3-3 구조물 알약 벌룬: 아래(테이블에 가림) 대신 위로 — 1행 좌상, 2행 우상,
솔로 위 중앙.
- 3-4 사이드: 스크롤 영역 상단 여유 + 페이지 설정 샘플 간격 2열(종단 먼저).
- 3-5 배수유역도 위성사진 기본 꺼짐.
- 3-6 B04 초기화 버튼 톤 다운 — 붉은 테두리·글자만, 채움 없음.
- 3-7 그래프 빈 공간 클릭 = 완전 해제 — 알약 해제 신호가 아예 없던 것 수정 +
외부 해제 시 구조물군·종류까지 리셋(선택 없을 땐 유지).
검증: tsc·vite + Playwright 헤드 실화면 V1~V8 전부 PASS (PLAN.md 3-8).
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Playwright 헤드 테스트(사용자 동석)로 잡은 두 버그:
1. 임시 배치 자기 삭제: 관 추가 직후 전역 선택 동기화에서 투영 측점이 아직 없어
사이드에 null(해제)이 전달 → 해제=임시 취소 규칙에 걸려 방금 넣은 관을 즉시
지웠다. 투영 측점이 없어도 누가거리를 그대로 넘기도록 수정(Selection.ts).
2. 월류 높이 미계산: 세부유역 재계산 완료 후 선택 통지가 조용히 끝나 폼이
설계유량을 못 받았다. setPipeFacilities의 임시 관 추적 지점에서
setDesignFlow로 직접 반영.
검증(테스트 프로젝트, 화면 확인): 섹션 순서·경로계산 비활성·옵션 잠금/해제 시점·
임시 배치(3+5.0)·삭제/리셋 취소·[추가] 확정·물넘이 월류폭 5m 기본·월류 높이
0.07m 자동(설계유량 1.118㎥/s)·미만 입력 보정·초과 입력 허용·목록 재클릭 해제
전부 통과.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
잔여거리까지 입력해도 입력군을 떠나기 전에는 임시 배치가 나가지 않았다
(2026-08-18 사용자 보고). 잔여거리 값 확정(change) 즉시 commitPosition을
실행하고, 측점번호 수정은 잔여거리가 이미 있을 때만 즉시 반영한다.
focusout 경로는 잔여거리 없이 정측점만 쓰는 경우의 확정용으로 유지.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
측점번호만 넣어도 옵션이 풀리던 것을, 임시 배치와 같은 시점 — 측점번호+잔여거리를
다 받고 입력군을 빠져나온 순간(commitPosition) — 으로 맞춘다(2026-08-18 사용자
지시). 값을 지우면 확정이 풀려 즉시 다시 잠긴다. 기존 항목·우클릭 추가는 위치가
실려 열리므로 처음부터 활성.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
측점번호 칸에서 Enter 시 잔여거리 0으로 즉시 배치되던 빈틈 제거. Enter는
포커스만 빼고, 임시 배치는 입력군 이탈(focusout) 한 경로에서 두 칸 합산값으로만
나간다. 배치 좌표는 스냅 없이 입력값 그대로다(노선 범위 클램프만).
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
측점번호만 넣고 잔여거리 칸으로 넘어가는 순간(blur) 임시 배치가 나가 재계산
동기화가 입력을 끊었다(2026-08-18 사용자 보고 2차).
- 임시 배치 시점 변경: 측점 입력군(positionRow)에서 포커스가 완전히 빠져나간
뒤(focusout + rAF 판정) 또는 Enter. 칸 사이 이동 중에는 나가지 않는다.
- 관이 계획선에 스냅되며 입력 누가거리와 어긋나면 임시 추적이 풀리던 것 —
허용오차를 0.05m에서 0.51m(관 매칭 공통 기준)로 넓히고, 재계산 후 실제
좌표로 임시·선택 누가거리를 갱신해 계속 따라간다.
- 우클릭 추가는 측점이 확정돼 들어오므로 즉시 임시 배치(기존과 동일).
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
기준 측점을 넣으면 임시 배치 → 세부유역 재계산 → 전역 선택 동기화가 그 관의
폼을 통째로 다시 로드해, 잔여거리를 입력하려는 순간 칸이 비워졌다(2026-08-18
사용자 보고).
임시 배치 중 그 관이 동기화로 되돌아오면 폼은 그대로 두고 설계유량만 갱신한다
(facilityOptions.setDesignFlow 신설 — 필드 값 불변, 월류 높이 재계산만).
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
- 2-1 선택 해제 복구: 목록 재클릭 = 해제(계곡 통과 시설 포함 — 기존엔 시설이
항상 재선택됨). 해제는 리셋 버튼과 같은 전체 초기화(resetForm — 구조물군·종류·
측점·옵션)이며, 시설 해제는 onPipeSelect(null)로 그래프·3D·배수유역도까지 푼다.
- 2-2 입력 순서 가이드: 측점(점형 기준, 구간형 시작·종료) 미입력이면 옵션 칸·부속
서브폼 잠금(disabled+inert+is-locked 흐림). 입력 즉시 해제.
- 2-3 월류폭·월류 높이: 기본값 세월교 10m·물넘이 5m. 월류 높이 칸 신설 —
fordSection(Manning 역산) 필요 수심을 자동 기입, 계산값 미만 입력은 되돌림.
저장 키 ford_height_m(0.01m 정밀도).
- 2-3b A군 임시 배치: 기준 측점 입력 순간 관 지점에 임시로 넣어 세부유역·설계유량
미리보기. [추가]로 확정, 삭제·리셋·다른 항목 선택·종류 변경·외부 해제 시 관을
물려 직전 상태 복원.
- 2-3c 우클릭 추가 개편: 종단도·테이블·배수유역도 [배관/구조물 추가]가 즉시 추가
대신 사이드 폼에 종류·측점을 자동 입력(A군은 임시 배치까지). BOX암거 기본
제원은 폼에 실려 유지.
- 2-4 컨테이너 병합: 등고선 간격+시작 측점·샘플링+종단 설계 기준 → 「페이지 설정」.
측점 간격 입력 삭제(STATION_INTERVAL_M=20 고정, 서버 스키마 불변). 순서 =
구조물 배치 > 페이지 설정 > 경로 계산 설정.
- 2-5 경로 계산 설정 비활성화: 사용여부 미결정 — 본문 inert(조작 불가) +
is-disabled 흐림. 제목·접기는 유지.
검증: tsc --noEmit 무오류, vite build 성공. 상세는 PLAN.md 2-6.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
한 항목 = [측점(좌측 맞춤)][구조물 이름(우측 맞춤)]. 메모·"배수유역 연동" 등
부가 표기는 지운다(2026-08-18 사용자 지시).
- labelOfStructure/labelOfPipe("측점 · 이름" 결합 문자열) 폐지 —
측점 표기만 stationOfStructure로 남기고 이름은 렌더에서 따로 그린다.
- 이름 span: margin-left:auto + text-align:right, 주 정보가 되었으므로
본문색으로 승격(기존 muted 캡션은 메모용이었다).
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
splitSidebarActions가 body 직계자식(:scope >)에서만 .ui-sidebar-actions를
찾았지만, 실제 액션 줄은 페이지 패널 루트(b05-route__panel 등) 안에 있어 분리가
아예 일어나지 않았다 — 직전 커밋에서 sticky까지 걷어낸 상태라 액션 줄이 내용을
따라 끌려 올라갔다(2026-08-18 사용자 보고).
- 깊이 무관하게 찾고, 액션 줄의 실제 부모를 기준으로 [스크롤 래퍼][액션 줄]로 쪼갠다.
- body와 그 부모 사이 중간 요소에 ui-sidebar-fill을 붙여 높이 체인(플렉스 세로
확장 + min-height:0)을 이어준다. B08 목록의 자체 overflow도 이 규칙이 덮어
스크롤이 래퍼로 옮겨간다.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
sticky + margin-top:auto 조합은 본문 높이가 패널 높이를 넘나들 때마다 액션 줄이
붙었다 떨어졌다 했다(2026-08-18 사용자 보고). 액션 줄을 스크롤 대상에서 아예 빼는
구조로 바꾼다.
- overlay.ts: 사이드 패널 생성 시 본문의 `.ui-sidebar-actions` 앞 형제들을
마진·패딩 없는 `.ui-sidebar-scroll` 래퍼로 옮기고 body에 `ui-sidebar-split`을
붙인다. 페이지 코드는 지금처럼 본문 끝에 액션 줄을 붙이기만 하면 된다.
- overlay.css: split body = 세로 플렉스 + overflow hidden + padding-bottom 0,
스크롤 래퍼 = flex:1/min-height:0/overflow-y:scroll + gap:inherit(그룹 간격 유지),
액션 줄 = flex:none(sticky·margin-top 제거).
- B08: 전용 sticky 규칙을 버리고 공용 ui-sidebar-actions로 통합 — B04~B08이 한 규칙.
스크롤바 자리 상시 예약(2026-08-17)은 래퍼가 이어받아 내용 폭은 그대로다.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
지금까지는 sticky만 걸려 있어 내용이 패널보다 짧으면 버튼 줄이 내용 바로 아래에
떠 있었다. 공용 .ui-sidebar-actions에 margin-top:auto를 주고, 액션 줄을 담은
사이드 body를 세로 플렉스로 만들어(:has) 남는 세로 공간을 액션 줄 위 여백이
전부 먹게 했다. B04·B05·B06·B07 공통 적용(B08은 .b08-drawing-actions가 이미
같은 방식).
- B05: 액션 dock 위 구분선·구조물 목록도 함께 최하단에 붙는다.
- B05 .b05-route__panel의 padding-bottom(24px) 제거 — dock이 바닥에 붙은 뒤로는
버튼 아래 빈 띠로만 남는다. 공용 body 패딩 16px는 dock의 sticky bottom:-16px가 덮는다.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
선택한 구조물의 폼 길이에 밀려 「구조물 배치」 섹션 아래 목록이 화면 밖으로
나가던 문제. 목록(<ul>)을 섹션 본문에서 빼 StructuresSection.listRoot로 노출하고,
패널이 하단 고정 영역(b05-route__dock)에 배치한다.
배치 순서: 상단 구분선(dock border-top) → 구조물 목록 → 중간 구분선 →
[초기화][임시저장][횡단 이동].
- 공용 ui-sidebar-actions(sticky·배경·상단선)는 그대로 쓰고, 안쪽만 세로 배치로
되돌리는 .b05-route__dock 규칙 추가(공용 규칙보다 좁은 선택자로 로드 순서 무관).
- 선택·폼 로드·스크롤 동작은 그대로 — DOM 부모만 바뀌었다.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
- 표시 필터 버튼 묶음을 헤더에서 지도 좌측 상단(8px 여백)으로 옮겼다. 버튼 줄과
상태 문구를 한 오버레이가 세로로 쌓아, 문구가 버튼 아래에서 시작한다
- 버튼 줄은 한 줄 유지. 오른쪽 진행단계 오버레이에 끝이 가려도 창을 넓히거나 그
오버레이를 접으면 드러난다(사용자 확정) — 두 줄로 접는 쪽이 지도를 더 가린다
- 오버레이 빈 자리는 pointer-events를 흘려 지도 팬·유역 고르기를 막지 않고,
버튼 위 pointerdown만 지도로 내려가지 않게 끊는다
- 유역 번호 배지를 원에서 라운드 사각으로. 지도 위 다른 숫자가 전부 동그라미라
크기로만 갈렸다. 크기(지름 22px)는 그대로. B04 지도 배지도 같은 함수라 함께 바뀐다
사용자 지시로 두 값을 걷어낸다. 구조물별 옵션·정의는 앞으로 타입마다
따로 정한다. 어차피 소비처가 없어(B06~B08은 structures를 읽지 않는다)
화면에만 남아 있던 값이었다.
- 폼: 설치측 select·이격 칸 행 삭제, 목록 부제·종단 벌룬에서 측 표기 제거
- 계약: StructureSide 타입, StructureInstance.side/offset_m 삭제(프론트·스키마)
- 설계지문에서 두 값 제외 — 후속 단계 무효화 판정에서 빠진다
- 구 저장분은 읽을 때 두 키만 떨어낸다. extra="forbid"라 그냥 두면 정본이
통째로 버려진다. 다른 낯선 키는 계속 거절한다
세월교 줄만 `세월교 검토 (Ø4719mm)`로 추천이 앞, 유효직경이 괄호 안이었다(구 문구
잔재). 같은 열을 위아래로 훑을 때 읽는 방향이 달라진다는 사용자 지적에 따라 네 줄을
`유효직경 Ø…mm → 추천 …` 한 형식으로 맞췄다.
- B05_Drainage_Basin_Bridge 문구에서 {d}를 빼고 "세월교 검토"만 남긴다 — 유효직경은
앞머리가 적는다
- recommendationOf()가 ford_bridge도 맡아 bridge_required 특례 분기를 없앤다
실화면 확인(서버 기동 + Playwright): 네 줄이 각각 Ø929→추천 Ø1000 배관 /
Ø4719→세월교 검토 / Ø1529→BOX암거 후보 / Ø549→추천 Ø800 배관으로 표시된다.
검증: npm run typecheck 무오류, pytest tmp/tests 124 passed·7 skipped.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
지시 2 — 배수유역도가 유효직경 다음에 추천을 보여 주고, 초기 전처리 계산이
그 값으로 관 지점을 설정한다:
- recommend_structure(): 유효직경 임계로 구조물·관경을 고른다. D≤1500 배관(규격
스냅 800·1000·1200·1500), 1500<D≤2000 BOX암거 후보, D>2000 세월교 검토.
판정 근거는 유량뿐 — 계곡 횡단경사·하천 차수는 지형 계산이 필요해 뺐고 화면이
"현장 확인"으로 안내한다(2026-08-17 사용자 확정)
- WatershedBasin에 recommended_facility·recommended_diameter_mm·required_area_m2
추가, 응답 payload와 DetailBasin 타입까지 배선
- _apply_recommendations(): 자동 배치 관의 **빈칸에만** 추천을 채운다. 사용자가
놓은 관(source=user)·이미 바꾼 시설·이미 있는 옵션 키는 건드리지 않는다.
carry_facility_attributes 뒤에 얹어 승계값이 덮이지 않게 했다
- 유역 목록 표기: `Ø1234mm → 추천 Ø1500 배관` / `→ BOX암거 후보`
- 추천 관경 목록은 레지스트리 pipe_diameter_mm 선택지와 같아야 한다 — 폼에서 못
고르는 값을 추천하지 않도록 테스트로 묶었다
지시 1 — 물넘이포장·세월교는 지정할 옵션이 거의 없으니 계산값이라도 보여 준다:
- 레지스트리에 ford_width_m(월류 폭) 신설. 기본값 없음 — 지식DB에 폭 근거가 없어
프로그램이 지어내지 않는다
- fordSection(): 설계유량과 폭으로 필요 수심을 되짚는다. 광폭 근사로 출발해 실제
동수반경(R=A/P)으로 수렴시킨다 — 근사값을 그대로 쓰면 통수능이 늘 설계유량에
못 미쳐 판정이 무의미해진다. n=0.017·S=10%는 실무 수리계산서 역산값
(울진1 물넘이·관 시트가 둘 다 S=0.10에서 검산 일치)
- 폼에 월류 폭 한 칸 + 읽기전용 요약(설계유량·필요 수심·필요 단면·유속). 설계유량은
유역 payload에서 폼까지 배선(onPipesChanged → Page → setFacility)
⚠ 실무 시트의 수심 0.27m는 Qd 역산값이 아니라 가정 수심이다(B=20·h=0.27의 통수능
41.2㎥/s ≫ 그 시트 Qd 2.54㎥/s). 실무는 단면을 가정해 통수능을 검증하고, 프로그램은
필요 최소 수심을 낸다 — 화면 문구도 "필요 수심"으로 적었다.
검증: pytest tmp/tests 124 passed·7 skipped(신규 17건), npm run typecheck 무오류,
npm run build 성공. 물넘이 산식은 프론트 전용이라 수치 손검증으로 대신했다 —
Qd=2.54·B=20에서 필요 수심 0.0503m·유속 2.526m/s, 통수능이 2.5400㎥/s로 Qd와 일치.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
앞 커밋에서 남긴 두 파일을 마저 갈랐다. 상태를 모듈로 옮기면 나머지 참조가 전부
바뀌므로 상태는 제자리에 두고 **접근자만 넘기는** 방식으로 동작·공개 인터페이스를
보존했다.
- Profile_Panel 1152 → 649
- _Profile_Layout: X축 배치(측점 칸 폭·캔버스 폭·chainage↔x 매핑). 순수 함수
- _Profile_Heights: 그래프·유토곡선·테이블 높이 배분. 드래그 플래그·상세 유무는
본체가 계속 들고 접근자로 읽는다(저장 높이 기준 판정 규칙 그대로)
- _Profile_Render: 본문 재구성(캔버스·그래프·구조물 레인·테이블·유토곡선).
그리기 시작 시 상태를 스냅숏하되 이벤트 핸들러 안에서만 현재값을 다시 읽는다
- _Profile_Balance: 상단 균형 표시줄(절·성토·불균형·위반 경고·초기선 복원)
- Page 1031 → 685
- _Page_Helpers: 설계폭 조회·모델 경계 변환·마커 복원·비정규 측점 보간 +
시설 표시 이름
- _Page_Structures: 구조물 정본과 관 지점 정본을 사이드 목록·그래프·3D에 맞추는
다리. 두 정본을 섞는 지점이라 여기만 상태(비정규 측점 목록·판번호·저장 큐·
타입 사전)를 팩토리 안으로 옮겼고, 본체는 bridge.irregularStations()로 읽는다
B05_Profile 전 파일이 700줄 이하가 됐다(최대 695).
검증: npm run typecheck 무오류, npm run build 성공(374 modules),
pytest tmp/tests 107 passed·7 skipped, prettier 정합.
프론트 테스트 러너가 없어 실제 화면 동작 확인은 남는다.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
지시 1 — 사이드 「종단 설계 기준」 컨테이너를 기본 접힘으로. section()에
collapsed 인자를 더해 초기 is-collapsed만 붙이고 토글은 전역 collapsible이
그대로 맡는다(B06 buildGroup과 같은 패턴).
지시 4 — 배수관 유입·유출 바닥 보호를 "보호공" 한 축으로 개편:
- 구 돌붙임 있음/없음 + 표면처리(찰/메) 두 축 → 돌붙임(찰)/돌붙임(메)/도수로.
도수로·산비탈수로(B4)는 유출부에서 돌붙임 대신 쓰는 공종이라 별도 구조물이
아니라 이 선택지로 받는다(별표2 유출구~원지반 도달 의무)
- "없음" 삭제 — 물이 흐르는 자리라 보호공은 필수(사용자 확정). 기본값은
유입 돌붙임(찰)·유출 돌붙임(메)
- 치수는 배타 — 돌붙임이면 면적(㎡, 기본 10), 도수로면 폭(m, 기본 1.0)
- 저장 키 개명 *_pitching → *_protection, *_pitching_finish 삭제,
*_protection_width_m 신설. 독립 기슭막이(D4)도 같은 축
- 구 저장분은 parse_pipe_points가 읽는 순간 새 키로 옮긴다("없음"은 부위
기본값으로 승격). 폼 write()도 구 키를 폴백으로 읽어 structures.json 몫을 덮는다
- revetment.pitching_area_m2가 기본값과 required를 동시에 갖던 모순도 정리
지시 5 — 700줄 초과 파일 분리(순수 이동 + import 정리, 공개 인터페이스 불변):
- Drainage_Facility 724 → 401 (+_Facility_Fields 354)
- Structures_Panel 753 → 695 (+_Structures_List 113)
- Drainage_Panel 822 → 693 (+_Drainage_Chrome 150, +_Drainage_Interact 159)
- Page 1031 → 911 (+_Page_Helpers 144) — 아직 초과
- Profile_Panel 1152 — 미착수. 두 파일은 가변 클로저 상태를 곳곳에서 직접
읽고 써 상태 승격이 선행돼야 하며, 프론트 테스트가 없어 순수 이동으로는
떼어낼 수 없다. 분리안은 PLAN.md 3-3에 기록
검증: pytest tmp/tests 107 passed·7 skipped(신규 보호공 마이그레이션 6건 포함),
npm run typecheck 무오류, npm run build 성공(374 modules).
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
- 본체 규격을 실무 관측 규격 프리셋(기본 2.0×2.0·3.0×3.0)으로 받고, 그 밖의
규격만 "사용자 지정"으로 폭·높이를 직접 입력한다. 저장 키는 어느 쪽이든
body_width_m·body_height_m 숫자 그대로 — 프리셋 전용 키를 만들지 않아야
하류(B06 횡단도·수량)가 폭·높이만 읽고 끝난다
- 날개벽 유입·유출을 createWingFields 한 조각으로 묶고(기존 기슭막이
createRevetmentFields와 같은 패턴) 설치 있음·짧은쪽 높이 1m·길이 2m·
각도 45°를 프리필. 설치 "없음"이면 제원 칸을 접는다
- setFacility 빈값 폴백을 기본값으로 — 빈 문자열 대입으로 select가
selectedIndex=-1(공백 표시)되던 문제도 함께 해소
- 레지스트리 정본에 위 기본값 10건 등재하고 required·phase:detail 해제.
이 값들은 B05 서브폼이 실제로 받으므로 detail 표기가 정본과 어긋나 있었다
- addAt의 managed_by 분기에 BOX암거 한정 defaultOptions 동봉(방어선 —
현재 우클릭 메뉴는 managed_by 타입을 제외하므로 도달하지 않는다)
기본값 전부 2026-08-17 사용자 확정. 검증: tmp/tests 101 passed·7 skipped,
npm run typecheck 무오류, prettier·ruff format 변경 없음.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
- 자동 배관·수동 배관은 같은 구조물(2026-08-17 사용자 지시) — 별도 편집 UI
(createFacilityEditor) 폐지. 배관/BOX암거/물넘이/세월교도 일반 구조물과
같은 흐름(구조물군 → 종류 → 시작·기준·종료 측점 → 옵션 → 추가/수정/삭제)
- createFacilityOptionsForm: 부속 옵션 서브폼이 구조물 폼 옵션 자리에 삽입.
시설 종류는 종류 드롭다운, 위치는 측점 칸이 담당
- loadPipeForm: 목록·그래프·3D·배수유역도 어디서 골라도 같은 폼에 로드,
버튼 [수정]. onPipeUpdate 신설(기준점 이동=관 이동, 옵션만=재계산)
- 기슭막이 총/앞/뒤 → 시작·종료 측점 칸 자동 채움. onPipesChanged에
source·options 추가. 배수유역 패널은 지도·정본 보관·재계산만 담당
- 700줄 대응: 입력 조각을 B05_Profile_UI_Structures_Fields.ts로 분리
(패널 685줄). tmp/tests 98건·typecheck·build 통과