2026-08-08 사용자 보고: B05 좌측 사이드 패널에서 "구조물 배치" 컨테이너만
외곽 라인이 없었다. 원인은 이 섹션이 사이드 컨테이너 공통 외곽선 클래스
(ui-sidebar-section)를 붙이지 않은 것 — 같은 페이지의 다른 섹션 생성부
(B05_wf2_Route_UI_Panel.ts:82)에는 이미 붙어 있었다.
createIrregularStationsSection의 root className에 ui-sidebar-section을 추가해
나머지 컨테이너와 동일한 테두리(두께·색·테마 대응)를 갖게 했다. 형태(라운드·
패딩·배경)는 기존 b05-route__panel-section 그대로 둔다.
검증: prettier 무변경, npm run typecheck 통과.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-06 사용자 지시 일괄 구현:
반폭 체계:
- 초기 샘플 반폭 config 기본 20m(SECTION_CROSS_HALF_WIDTH_M 15→20) —
표시 반폭이 이 안이면 재계산 없이 표시만 자름(기존 crossPlotMetrics)
- 재계산 버튼 삭제, [전체 측점 반영]이 반폭 적용 담당: 축소=표시만(즉시),
확대(보유 샘플 폭 초과)=regenerate 후 상세 재로드
- regenerate에 grade_options 재구성 추가 — 계획선(profile_alignment)까지
함께 재계산·저장. 예전 재계산 버튼이 계획 횡단도선·유토곡선·테이블을
지우던 근본 원인 해결(B04 파일입력 파이프라인과 같은 엔진 경로 재활용)
- 높이 배율 옵션 폐지(항상 1), 반폭 입력은 표준 횡단면 설정의
[전체 측점 반영] 위로 이동(Standard_Panel extraControl)
개별 반폭(카드):
- 카드 하단 ◀/▶/↺(±1m·전역 복귀), 암 경계 그룹 우측 정렬. 숫자 표시 없음
- 개별값 > 전역값 우선(StationWidthControl). 세션 보관, 확정·임시저장 시
cross_patches(design.display_half_width_m)로 영구 저장 → 재접근 복원
- 프리뷰·단건 설계 재계산이 이 필드를 이월해 지우지 않게 보강
- 방위각 표기 삭제
측구 방향 확정 동기화(13측점 보고):
- B05 경로확정 uphill 병합 시 저장 횡단 설계도 새 방향으로 재계산·저장
(sync_uphill_overrides_into_designs) — 정본만 갱신하면 B06 표시와
역반영(ditch_side→uphill_side)이 옛 방향으로 순환 덮어쓰던 문제 해결
- 절/성토 역할은 엔진이 지형에서 자동 판정(정상) — 사용자 지정 대상인
측구 방향(ditch_side)이 정확히 동기화됨을 13측점 실측 확인
실측: 축소/확대/개별 조절/저장 복원/확정 동기화/B05 하단 패널 정상,
tsc·ruff·prettier 통과, 콘솔 에러 0.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
직전 커밋(673487c)의 시인성 개선이 B07에만 보이던 원인(2026-08-06 사용자
보고): B04/B05/B06 페이지 CSS가 border 전체 선언(1px solid --color-border)을
갖고 있어, 로드 순서상 공통 클래스(ui-sidebar-section)의 진한 border-color를
덮었다. B07은 로컬 선언이 없어 공통이 그대로 보였던 것.
세 페이지의 로컬 border 선언을 제거해 테두리를 공통 클래스가 전담하도록
일원화. 라운드·패딩·배경 등 형태는 각 페이지에 그대로 둠.
실측: B04·B05·B06 사이드 컨테이너 외곽선 선명 확인, 콘솔 에러 0.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-06 사용자 지시 2건:
- 3D 측점 라벨 배경을 fillRect → roundRect(반경 10)로 — 둥근 판
- 사이드 컨테이너 외곽선: 어제 45% 혼합이 아직 흐리다는 재보고로 보조색
비중 75%로 상향. 공통 클래스(ui-sidebar-section)가 테두리 두께·형태까지
소유하도록 강화 — 자체 테두리 없는 컨테이너도 클래스만 붙이면 동일 외곽선.
테마 변수 혼합이라 라이트/다크 자동 대응
- B04~B06만 적용돼 있던 것을 B07 설계 도면 그룹에도 적용(+라운드·패딩)
실측: 3D 라벨 라운드, B05·B07 외곽선 라이트/다크 모두 선명, 콘솔 에러 0.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- 컨테이너 제목 변경: 측점 및 샘플링 설정 → 시작 측점 및 샘플링 설정
- 시작 측점·시작 누가거리(m) 2열 행을 통합 컨테이너 최상단으로 이동,
별도 공사 시작점 섹션 제거 (2026-08-06 사용자 지시)
- 동작 로직(표시 오프셋 콜백)은 그대로 — 배치만 이동
실측: 통합 컨테이너 최상단 배치 확인, 콘솔 에러 0.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
경로확정 직후 같은 배관이 2개씩 뜨던 문제(2026-08-06 사용자 보고):
확정 시 종단 정본에 병합된 배관이 페이지 진입 복원(restoreSections)으로
목록에 들어오는데, 복원 항목은 structureType이 없어 isPipeStation 판정을
빠져나가 관 정본 투영(setPipeStations) 때 걷히지 않았다. 정본 연동 항목과
비연동 유령이 공존 — 로드 순서(배수유역 관 vs 종단 복원) 레이스라 서버
재시작 여부에 따라 재현이 갈렸다.
setPipeStations에서 투영되는 관과 같은 자리(±0.5m)의 종류 없는 복원
항목만 제거. 종류를 갖춘 사용자 추가 구조물은 자리가 겹쳐도 보존.
실측: 재진입 후 목록 관 4개 각 1건(중복 소멸), 콘솔 에러 0.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
사용자 보고 3건(2026-08-06) 수정:
1. 측구 방향 램프 절반 축소(반지름 1.1→0.55, 띄움 0.6→0.3) — 측점 고를 때
가리는 문제. 클릭 판정은 투명 히트 구(1.1)로 기존 범위 유지
2. 측점선을 Line → 납작 띠 Mesh(BoxGeometry 길이×0.18×0.5, 띄움 0.45→0.8)
— WebGL Line은 굵기 지정이 안 먹혀 1px라 지형에 묻혀 안 보이고 클릭도
어려웠음. 띠는 굵게 보이고 레이캐스트도 몸통 전체. selectStation 색
갱신을 Mesh 기준으로 전환
3. 회전 중심 불투명 구슬 → 링+십자 조준점 스프라이트(캔버스 텍스처, 항상
카메라 정면, 반투명). 비율 0.02 — 구슬(0.024)보다 지름 작고 속이 비어
시각적 무게 대폭 감소. 공용 유틸이라 B04 지형 뷰어들도 함께 적용
실측 확인: 띠 클릭 선택 정상(빨간 핀), 램프 축소 확인, 조준점 지형 위
또렷, 콘솔 에러 0.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
메인 패널을 끌면 3영역이 드래그 시작 시점 비율대로 같이 늘고 준다
(2026-08-06 사용자 확정). 롤백 기준: 직전 안정판 d8723f4.
- Panel: pointerdown에서 3영역 실측 스냅샷(mainDragRef), 캐스케이드에
메인 드래그 분기 — 비례 배분 + 최소(100/160/140) 고정 후 남은 영역끼리
재배분(최대 3회 수렴). 서브패널 상한(75%/80%)은 안전상 유지
- 손 떼면 결과 높이를 서브패널 저장값으로 확정(commitHeight: 리사이저와
같은 CSS 변수+세션 기록) — 이후 redraw 판정 기준이 되어 멱등성 유지
- MassHaul syncHandle() 신설 — 드래그 중 손잡이가 인라인 높이 위 경계 추종
실측 테스트: 확대 시 3영역 동일 배율(×1.41), 축소 시 최소 걸린 영역부터
정지, 손 뗀 뒤·redraw 후 고정, 서브패널 개별 드래그·밀어올림 보존,
콘솔 에러 0.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
원인 4개(2026-08-06 분석) 일괄 수정:
1. applyHeightCascade가 임시 축소 반영된 offsetHeight로 판정해 호출마다
줄임↔풀림 진동 + 풀린 호출의 deficit가 메인 패널을 멋대로 확대.
→ 판정 기준을 저장 높이(desiredHeight 신설: 리사이저 CSS 변수/기본값)로
전환해 멱등화. 축소 비율이 budget에 따라 연속 변화해 스냅 없음
2. grow 상한(window 92%)이 리사이저 max(부모 90%)보다 높아 자동 확대 후
손잡이를 잡는 순간 clamp 급락 → 상한을 같은 식으로 통일
3. 서브패널 드래그가 매 프레임 전체 draw(차트·테이블 재생성)로 덜컹
→ 메인 드래그와 같은 경량 동기화(subPanelChanged 분기), 손 뗀 뒤
전체 재구성 1회(clearDragFlags 120ms 예약)
4. pointerup 직후 지연 draw가 드래그 보호 해제 상태로 grow 발동
→ mainDragCooldown: 손 뗀 뒤 첫 전체 draw까지 grow 금지
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
원인 두 가지(2026-08-05 사용자 보고 분석):
1. 캐스케이드의 임시 축소(인라인 height)가 서브패널 자체 리사이저의 변수 값을
덮어씀 — 드래그 값이 화면에 안 먹다가 인라인이 걷힐 때 한 번에 튐
('이전 배치로 복귀' 증상). → 서브패널 드래그 중엔 인라인을 걷고 임시 축소를
중단, 자리가 모자라면 메인 패널을 즉시 키워 밀어올림
2. 자동 확장(grow)이 메인 패널 드래그 중에도 개입해 포인터가 정한 높이를
되돌림 — 서로 밀고 당기는 진동('반복적으로 돌아가려는' 증상).
→ 드래그 출처 추적(pointerdown/up 플래그): 메인 드래그 중 grow 금지,
경량 동기화는 서브패널 드래그일 때만 grow 허용
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- 유토곡선 SVG 상단 여백 padTop 옵션 신설(공용 렌더러), B05는 40px —
범례·기준 버튼 오버레이(top 34px)와 커브 겹침 해소. B06은 기존 10px 유지
- 사이드 패널 컨테이너 공통 클래스(ui-sidebar-section): 외곽선을 본문 보조색
45% 혼합으로 진하게 — 두 테마 모두 흐려 안 보이던 문제. B04/B05/B06 적용
- 하단 패널 리사이즈 끊김 해소: 끌리는 동안 프레임당 경량 높이 동기화
(캐스케이드 계산 + 캔버스/차트 높이만), 무거운 차트·테이블 재구성은
손 뗀 뒤 120ms 디바운스로 1회. 추가 리소스 없음 — 프레임당 비용 감소
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- 구조물 종류 드롭다운에 빈칸 항목 — 초기·리셋 상태는 빈칸이고 하위 옵션 전체
숨김, 미선택이면 추가 불가(2026-08-05 사용자 지시)
- 사이드 패널 최하단 고정 액션 줄 공용 클래스(ui-sidebar-actions): 계산·확정
버튼이 스크롤에서 제외되고 불투명 배경이 지나가는 내용을 가림.
B04(확정·초기화)/B05(계산·확정)/B06(재계산·저장·확정) 적용, B07은 기존
자체 sticky 유지
- 하단 패널 높이 캐스케이드: 아래로 끌면 종단 먼저 최소(100px)까지 →
테이블·유토곡선이 같이 비례 축소(각자 최소 140/160px, 인라인 임시 축소라
다시 키우면 원래 높이 복귀) → 셋 다 최소면 리사이저 동적 하한이 차단.
공용 리사이저 min을 함수 지원으로 확장. 반대로 서브패널 펼침으로 부족하면
메인 패널을 키움(기존 로직 유지)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- 3D 뷰 토글에 '흑백 지형' 추가(측점 라벨 우측, 기본 무지개). 정점색 1회
바꿔치기(원본 userData 보관)라 로딩·회전 성능 영향 없음
- 유토곡선 접힘 버튼은 항상 바닥 — 순서(종단>테이블>유토곡선)상 테이블 아래에서
나오므로. 테이블 접힘 버튼만 열린 유토곡선 위 경계에 나란히
- LONG_PAD.left 62->78: 좌측 패널 접기 버튼이 Y축 라벨·행제목을 가리는 문제.
sticky 마스크·행제목 폭이 같은 값에서 파생돼 가로 스크롤 값 누출 없음
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- 3D 빈 공간 클릭(회전 드래그 포함)으로 측점 선택이 풀리지 않게 — 해제는
그래프·사이드 패널에서만 (3D 영역 한정, 2026-08-05 사용자 지시)
- 구조물 폼: 편집 중 타입 변경 시 신규 추가로 전환(입력값 유지),
자동 배관(origin=pipe)은 타입 잠금(관종·직경만 변경 가능), 리셋 시 폼 초기화
- 접힌 서브패널 손잡이는 열린 패널의 위 경계 수평선에 일렬 배치
(테이블 접힘+유토 펼침 시 유토곡선 상단)
- 종단 그래프 최소높이(100px) 부족 시 메인 하단 패널 높이를 자동 확장
(뷰포트 92% 상한) — 서브패널 펼침으로 종단이 뒤로 넘어가는 역전 방지
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- 세월교 판정: 유효직경이 관 최대 규격(D2000, config) 초과 시 bridge_required
플래그 — 관이 아니라 세월교·물넘이·교량 대상(임도설치규정 제12조: 계류 횡단
구간은 물넘이 포장·교량으로 설계). 유역 제원에 '세월교 검토(Ø계산값)' 표기,
관경 자동 지정 제외. 실측: 41.4ha 계류 유역 D5137 -> 세월교 검토
- 사면 유역 계산식은 유지 — FHWA 유입부 조절식과 교차검증 결과 근접
(1.1ha D862/D839, 2.9ha D1426/D1255)
- 하단 패널: 서브패널이 종단도를 덮지 않고 밀어올림. 접힘=종단 전체,
하나 펼침=그만큼 종단 축소(테이블 높이 고정), 둘 펼침=종단-테이블-유토곡선
순서로 유토곡선 리사이즈 시 종단만 조절
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- 구조물 배치 폼: 종류 드롭다운(배관/기성막이/대피로/기타) + 관종·직경/폭/이름
하위 옵션. 목록·기본값은 config_frontend(정본 config_system.py 미러) 관리
- 관경 자동 지정: 기본 D800, 배수 유효직경 초과 시 바로 위 규격.
수동 변경(userSized)은 재계산에도 유지. 소구경 리스트 유지
- 종단·배수유역도 우클릭 메뉴에 기성막이/대피로/기타 추가 항목
- 유토곡선·테이블 영역 브라우저 기본 우클릭 메뉴 차단
- 측점 선택 시 배수유역도 계획선 위 다이아몬드 마킹(유역 없는 구조물 포함)
- 3D 선택 마킹: 수직 핀(기둥+역원뿔, depthTest off) — 원형 표기 지양
- 테이블을 유토곡선과 같은 바닥 고정 오버레이 서브패널로 개편.
접힘 손잡이 일렬(좌 테이블/우 유토곡선), 순서 종단도-테이블-유토곡선
- 테이블 행제목 우측 정렬+좌측 여백, 종단·유토곡선 Y축 눈금 10-13px
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
0크기 sticky 앵커를 SVG 뒤에 붙이면 흐름 위치가 차트 아래로 밀려 가로 스크롤 시
축 오버레이가 화면 밖에 놓였다(스크롤 0에서는 SVG 자체 눈금이 보여 드러나지 않던
버그). B06과 같은 규칙(첫 자식 prepend)으로 통일 — 종단 표고축·유토곡선 ㎥축 모두
스크롤 800px 상태에서 좌측 고정·불투명 확인.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
- 31: 곡선 L·R 셀이 이웃 곡선 셀과 겹치면 자리 이동 대신 측점선 위 세로쓰기
(writing-mode vertical-rl) + 행 높이 맞춤 글자 축소 — 다른 열 값 오해 방지
- 32: 곡선 L·R 수정 불가 원인 = 접힌 유토곡선 손잡이가 테이블 곡선 행 위에서 클릭
가로챔. 테이블 아래 26px 손잡이 전용 띠(MASSHAUL_HANDLE_GUTTER_PX) 확보.
검증: 배관 곡선 R 8.0→55.0 편집 정상 반영
- 33: 배수유역 side 손잡이 z 2→6 — 유토곡선 오버레이(z5) 위로, hit-test 통과
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
- 27: 종단 X라벨↔버튼 간격 70%로(bottomInset 19→15)
- 28: 사이드 패널 접힘 시 본문 24px 거터 — 손잡이가 Y축 라벨을 덮지 않음(B04~B07 공용)
- 29: B06 종단·유토곡선 가로 스크롤 고정 Y축 — buildStickyYAxis 재사용, yaxis CSS
정의처를 MassHaul css로 이동(B05·B06 공용). 앵커를 첫 자식으로 넣고 유토축 inner를
종단 높이만큼 내려 자기 구간만 덮음. 스크롤 600px 블리드 테스트 통과
- 30: 배관 측점 곡선 L·R 항상 표기(R 필수), 이웃 곡선 셀 근접 시 배관 셀만 우측 비킴,
선택 오버레이는 한 열 원위치 유지
Playwright: sticky 앵커 2개(x 고정), 거터 24px, gap 7px, 곡선 셀 8, 오류 0.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
원인: createPanelResizer가 생성 중 세션 저장 높이를 복원하며 onResize →
syncHandlePosition을 부르는데 'open'(let) 선언이 그 아래라 TDZ ReferenceError로
B05 렌더 전체가 죽었다. 저장된 높이가 있는 브라우저에서만 재현돼(새 세션 테스트는
통과) 사용자 환경에서만 접속 불가로 나타났다. 상태 선언을 리사이저 생성 앞으로 이동.
- 리사이저 상시 표시선 1px→2px, hover/드래그 3px→4px(2026-08-04 사용자 지시)
검증: masshaul-open=true + height=320 세션 상태로 진입 — 본문 렌더, 오버레이 320px
복원, 오류 0.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
확정을 거친 구조물 측점은 종단 정본(alignment.stations)에 이미 병합돼 있는데
사이드바 목록(irregular)에서 또 추가돼 ▲▼가 2개씩 생겼다(같은 자리에 겹쳐 있다가
겹침 회피 캐스케이드가 옆으로 벌리면서 드러남). 같은 chainage(소수 3자리)는 한 번만
버튼을 단다. 검증: 버튼 27→23개(배관 4곳 중복 제거), 근접 측점 비킴은 유지.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
- 12: run_redesign_chain — B04 재확정 시 사용자 입력(stage 2 params) 유지한 채
새 지표면 기준 B05 재계산·확정, 옛 측점별 설계·표준단면 설정을 chainage 매칭
이월 후 B06 확정. 경로 없으면 신규 자동 체인 폴백. B04 confirm에 백그라운드 결선
- 13: 구간 이동 글리프 ⇧⇩ → 속 찬 ⬆︎⬇︎(21×17·굵게), 규칙·비정규 측점 버튼
최소 간격 20px 캐스케이드 배치로 근접 측점 ▲▼ 겹침 해소
- 14: 유토곡선 손잡이를 표준 삼각형 손잡이(64×24, 바닥 중앙)로 통일, 캡션 제거,
'유토곡선 펼치기/접기' 툴팁
- 15: 유토곡선 스크롤러 세로 휠 → 가로 이동(종단 그래프와 동기)
Playwright 검증: 버튼 27개 최소 간격 20px, 글리프 ⬆︎ 21×17, 표준 손잡이 64×24,
휠 스크롤 0→400 종단 동기, 콘솔 오류 0. typecheck·ruff 통과.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
바로 위 종단 표고축(…m)과 같은 자리에 서므로 단위가 없으면 어느 축인지 읽히지
않았다. 유토곡선 축 라벨에 ㎥를 붙이고 0선 눈금도 "0㎥"로 표기한다.
.b05-profile__yaxis-inner에 overflow: hidden을 걸어 눈금이 자기 그래프 영역 밖으로
새어 아래 그래프의 축처럼 읽히는 것도 막았다.
확인: 실제 누가토량 범위는 -213.3~0.0㎥인데 보고된 화면 축은 527~544.7m로 표고였다.
번들 검사 결과 유토곡선 전용 sticky 축과 0㎥ 눈금은 최신 빌드에 정상 포함돼 있다.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
프리뷰 성능
- 느린 원인은 응답 크기였다(영구저장소 저장·재로드는 하지 않는다). 상세를 통째로
돌려주느라 1.09MB였고, 유토곡선이 실제로 읽는 설계 필드만 남겨 6KB로 줄였다.
제외: 지반선 원시 샘플, 설계선 좌표(250KB), 선형 구조(87KB), 계획선 샘플(85KB).
계획선은 화면이 이미 같은 규칙으로 계산해 들고 있고, 설계선 좌표는 B06 상세가 준다.
- 프론트는 온 필드만 덮어쓰는 부분 갱신으로 바꿔 안 온 값을 지우지 않는다.
디바운스 400 → 250ms.
곡선 L·R 표시 원복
- 배관 자리는 구조물 측점이라 테이블에 기본으로 안 나오는 것이 맞다(사용자 정정).
격자 밖 변화점 셀을 걷어냈다 — 선택하면 buildSelectedColumn이 곡선 L·R을 보여 준다.
검증: 응답 1,091,003 B → 6,007 B, 계산값 동일(절토 16.4㎡ / 성토 48.3㎡).
typecheck·vite build·ruff·B03 테스트 통과.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
B05에서 계획고를 끌어도 횡단 기준 유토곡선이 그대로였던 원인은 횡단 설계가 옛
계획고 기준으로 남아 있었기 때문이다. 공유 캐시(4차)는 B06→B05 방향만 해결했고,
B05에는 B06의 reconcileStaleDesigns에 해당하는 재계산 트리거가 없었다.
- POST /sections/{route_id}/cross-design/preview 신설: 계획선 편집 델타를 받아
계획선을 재구성하고 전 측점 횡단 설계를 한 번에 다시 계산해 상세를 돌려준다.
저장하지 않으며 영속화는 각 페이지의 임시저장·확정이 맡는다. 측점마다 따로
부르면 수십 번 왕복하므로 일괄 계산으로 뒀다.
- 재계산 시 사용자가 이미 고른 지반유형·단면유형·측구·암 경계는 그대로 두고
계획고만 새 선형 값으로 교체한다. 지정 없는 측점은 기본값(리핑암 + 0.5m).
- B05 rebuild()에 프리뷰 호출 결선: 400ms 디바운스로 길게 누르기 대응, 요청 번호
비교로 늦게 온 응답 폐기. 응답은 공유 캐시의 같은 객체를 제자리 갱신하므로
B06으로 넘어가도 다시 받을 필요가 없다.
검증: 100m에 계획고 +3m 편집 시 계획고 533.2→536.14m, 횡단 절토면적 합
18.6→15.8㎡, 성토면적 합 22.0→66.2㎡로 함께 이동. 지반유형 유지 확인.
typecheck·vite build·ruff·B03 테스트 통과.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
영구저장소를 직접 확인하니 R·L은 정상 저장돼 있었고, 안 보인 원인은 둘이었다.
호가 너무 짧았다
- 배관 정착 선형은 변화점 대수차가 1~3%로 작아 R 기준(250m)에서 L = R × A 가
3~7m. 350m 연장 도면에서 화면상 10~20px이라 직선과 구분되지 않았다.
- 곡선 기준을 R에서 L로 바꿨다: pipe_anchor_curve_length_m = 15.0 신설,
R = L / A 로 역산(법정 최소반경 하한 유지). 표고 보정 반복마다 대수차가
변하므로 R도 매 회 다시 역산한다. 변화점마다 호 길이가 같아 도면이 고르다.
테이블 곡선 행이 규칙 측점만 순회했다
- buildCurveRows가 20m 격자 측점만 돌아 배관 변화점(84.3m 등)의 R·L 셀이 아예
그려지지 않았다. 격자 밖 변화점 셀을 추가해 선택·하이라이트와 무관하게
기본으로 값이 보이게 했다.
검증: solve 재실행 후 84.30/200.92/275.71m 호 길이 정확히 15.00m, 149.73m만
대수차 25.2%로 최소반경 바닥에 걸려 46.07m(정상). 배관 4곳 계획고=지반고 유지.
typecheck·vite build·ruff·B03 테스트 통과.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
페이지 간 캐시 공유
- B06_wf3_ProfileCross_Section_Store.ts 신설: 종횡단 상세를 projectId:routeId
키로 들고 있는 모듈 싱글턴 캐시. B05와 B06이 같은 객체 참조를 보므로 B06이
측점 설계를 제자리 갱신하면 B05가 다음 그리기에서 그대로 본다 — 횡단을 고친
뒤 B05 유토곡선이 옛 값으로 그려지던 문제의 원인이 페이지별 개별 fetch였다.
- 두 페이지 진입을 loadSectionDetail()로 통일(동시 호출은 Promise 공유).
- 정본이 다시 쓰이는 조작에 캐시 갱신: 횡단 재생성 → replaceSectionDetail,
계획선 편집 저장 → invalidateSectionDetail.
계획선 호 기하
- 배관 지점(지면선 × 배관 세로선 교점)이 호 위에 오도록 변화점 표고를 반복
보정. 대칭 종단곡선은 꼭짓점을 지나지 않아 중앙종거만큼 어긋나 있었다.
시작점·종점과 각 호, 호와 호 사이는 직선이 접선으로 잇는다.
- 호 반경 기본값을 설계 기준의 종단곡선 최소 반경으로 지정하고 curve_radii
편집 델타에 실어 B05 테이블에서 사용자가 그대로 고칠 수 있게 했다.
유토곡선 Y축
- B05에만 있던 종단용 sticky 표고축 탓에 가로로 훑으면 유토곡선 눈금은 흘러가고
표고축만 남아 Y축이 높이로 읽혔다. createMassHaulChart에 onAxis 콜백을 더해
유토곡선용 sticky 누가토량 축을 따로 고정.
검증: solve 재실행 후 배관 4개 자리에서 계획고=지반고(오차 ≤0.0001m), 호 비겹침
확인. typecheck·vite build·ruff·B03 테스트 통과.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
계획선 1차 로직 (2026-08-03 사용자 확정)
- design_pipe_anchored_profile 신설: 배수유역도가 확정한 배관 배치 측점을
변화점으로 삼아 계획선이 각 배관 자리에서 지면선과 만나도록(계획고=지반고)
시작점→배관1→…→종점을 직선으로 잇고 기본 R을 얹는다. 배관(암거)은 계곡
유하부라 계획선이 그 지점에 붙어야 복토·유입 조건이 성립한다.
- 기존 지반 추종 직선 분할 DP 선형은 2차 폴백으로, 구 균형 최적화 계획선은
3차 폴백으로 강등. 관 지점 파일의 노선 지문이 다르면 배관을 쓰지 않는다.
- 테스트 프로젝트 solve 재실행으로 저장분 재계산 — 변화점이 배관 5개 자리와
일치하고 각 자리 계획고=지반고임을 검증.
유토곡선 UI (사용자 피드백 5건)
- 기준 버튼 라디오화: 횡단/종단 택1로 그 기준 그래프만 전체 영역에 표시
(applyLegendToggle/normalizeVisibleBasis, B05·B06 공통 저장 키 공유).
Y 범위도 표시 중인 기준으로 산정.
- B05 Y축 이중 표시 제거: MassHaulAxis.axisX 신설 — 축 선·눈금을 종단 그래프
축과 같은 자리에 그리고 데이터 매핑은 유지해 측점 세로 정렬 불변.
- 종단↔유토곡선 경계 드래그 리사이저(비율 0.25~0.75, 세션 보존, 기본 1:1).
- B05 범례를 B06과 같은 오버레이 우상단 절대배치로 이동.
- 도면 테이블: 구조물 배치로 갈라진 구배 블록 값을 기본 숨김(윤곽·툴팁만),
해당 측점 선택 시 하이라이트와 함께 표시.
typecheck·vite build·ruff·B03 테스트 통과.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
사용자 피드백 반영(2026-08-03 2차).
유토곡선 일원화
- B05 유토곡선을 B06과 같은 계산(computeMassHaulSeries: 횡단 정식 + 종단 개략
비교)으로 전환. 상세 조회가 미지정 측점에 기본 설계를 즉석 계산해 얹으므로
B05 진입 시점에 이미 정식 곡선 재료가 있다. 표시 토글 sessionStorage 키와
balloon 위치 scope를 B06과 공유해 두 화면이 같은 그림을 유지한다.
- B05 전용 개략 엔진(computeLongitudinalMassHaul) 삭제.
- 유토곡선 펼침 시 종단 그래프:곡선 세로 1:1 분할.
사토장·토취장 자동 선정 삭제
- 임도에는 토취장이 없고 부족분은 설계자가 계획선을 고쳐 맞춘다는 실무 판단에
따라 4옵션(비용/지형안정성/계곡부/임내공간) 엔진·API·UI·config·저장 훅 전부
제거. massHaulPayload/createMassHaulLegend 시그니처 원복.
기본 지반 변경
- 기본 설계 프리뷰·확정 기본값을 토사에서 리핑암 + 예상 암반 경계 0.5m로 변경.
산지 절토는 표토 아래 암이 일반적이라 전량 토사 가정은 물량이 낙관적이다.
발파암은 B06에서 측점별 수정.
계획선 R·선 연결 (배관 구조물 자리)
- 계획선 샘플이 고정 격자로만 평가되어 격자 사이 변화점(배관 측점 승격분)의
모서리를 잘라먹던 결함 수정 — 샘플 집합에 PVI·BVC·EVC를 합집합으로 포함
(프론트 buildAlignment + 서버 build_alignment 동일 규칙). 면적 가중치도
합쳐진 격자로 재계산. 37.3m 변화점 + R=150 수치 검증 통과.
표시 개선
- EP(종점) 잔량 라벨: 곡선 끝점에 "EP {누가토량}㎥" 불투명 판(B05·B06 공통).
- 유토곡선 0선을 붉은 굵은 실선(2.5px)으로, 0 눈금값도 적색.
- 3D 뷰 [측점 가로선] 우측 [측점 라벨] 토글 신설(기본 꺼짐) — 구조물 측점만
"측점번호 구조물명" 스프라이트 표시.
typecheck·vite build·ruff·B03 테스트 통과. 실서버 스모크로 리핑암 기본 프리뷰와
disposal-sites 제거 확인.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
절·성토 균형은 종단 시공계획고로 정해지고 사토장 위치도 계획고를 다시 끌어야
정리되므로, 계획용 유토곡선과 부지 선정을 B05로 옮겼다. B06은 실측 단면적으로
낸 정식 곡선과 확정·B08 인계를 맡는다.
B05 계획 유토곡선
- _UI_Profile_MassHaul.ts: 종단면 패널 안 2차 하단 슬라이드. 펼치면 12행 도면
테이블 자리를 곡선이 대신 차지한다. 곡선 SVG를 종단 그래프와 같은 가로
스크롤러 안 형제로 넣고 MassHaulAxis에 LONG_PAD + originOffset을 넘겨 X축을
종단 chainageMapper와 일치시켰다.
- computeLongitudinalMassHaul(): 횡단 설계가 없는 계획 단계용 개략 엔진. 표준횡단
노반폭을 전 구간 공통으로 물린다. 종단 기반 토량은 국내 기준상 노선계획 개산용
이므로(2026-08-03 조사) 표준단면까지 씌워 정밀화하지 않는다.
사토장·토취장 자동 선정
- B05_wf2_Route_Engine_Disposal.py + POST /route/disposal-sites: 노선 corridor
DEM 격자를 훑어 후보 부지를 추리고 옵션별 점수로 정렬한다. 기준 4가지 —
비용(최단거리+하향 운반), 지형안정성(완경사·계곡 이격), 계곡부(계곡 축 매립),
임내 공간(라이다 수고 기반 공터). 기준값 정의처는 DISPOSAL_SITE_CRITERIA.
- _UI_Profile_Disposal.ts: 범례 줄의 [토량 분배]와 [도형 위치 초기화] 사이에
구분기호와 함께 라디오 토글 4개. 부지 카드에 위치·용량·운반거리와 기준별 근거값,
측점·용량 사용자 정의 편집과 복원. 후보 부족으로 남은 토량은 경고로 알린다.
- 확정 시 종단 정본의 disposal_sites에 심는다(기준 미선택이면 저장분 삭제).
B06 연동
- common_util_mass_haul_sites.ts: 저장된 부지를 정식 곡선의 잔량 위치 기준으로
운반거리를 다시 재 표시하고 mass_haul.disposal_sites로 B08에 넘긴다.
미구현(계획서에 남김): 토취장 토질 판정(지반유형이 B06 산출물), 계곡부 암거 연장.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
유토곡선을 측점 사이에서 직선으로 잇는다(C안 확정). PARABOLIC_MASS_CURVE 한 곳으로
그리기(curvePath)와 재기(crossFrom)가 함께 바뀐다 - 둘이 어긋나면 수평선 끝이
곡선에서 뜬다. 대가는 평균운반거리가 포물선 대비 약 40% 짧아지는 것이고, 이는
20m/70m 장비 경계 판정에 직접 영향을 준다.
- 사토·토취를 balloon 계열로 통일: 단차 화살표는 22px 고정으로 잘라 위치만 가리키고
수량 라벨은 balloon과 같은 자리 찾기·지시선·드래그를 쓴다(음수 키). 도형 없이 언더바만
- 토취 색 초록 -> 주황. 초록은 "정상"으로 읽혀 흙이 모자란 경고와 안 맞았다
- balloon 내용을 도면 양식(항목별 세로 표기)으로. 165px 이상이면 6줄
(이름·번호 / Q / L / EA / RR / BR), 사토는 L 대신 M.N=측점, 토취는 지반유형 없음
- HaulResidual에 사토 지반유형 안분 추가. 장거리 상쇄로 깎이면 안분도 같은 비율로 감소
- 횡단도 휠 줌 제거, 우측 상단 + / − / ⤢ 버튼. 팬은 가운데 버튼 유지
- 암 경계선 제어를 그래프 안에서 중심고·방위각 행 가운데로 이동
- 700줄 초과 2건 분리: _UI_MassHaul_Balloon.ts, _UI_Style_Cross_Areas.css
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
상세 배수유역 정보는 페이지에 들어오면 바로 보여야 하는데 기본값이 접힘이었고,
접기/펼치기 화살표도 반대를 가리키고 있었다.
- 기본값: 저장값이 없을 때 `!== "false"`(접힘)를 `=== "true"`(펼침)로 바꿨다.
같은 페이지 하단 종단 패널(B05_wf2_Route_UI_Profile_Panel.ts:592)이 이미 쓰던 규칙과
같아졌다.
- 화살표: 공용 `createWorkflowPanelHandle`은 왼쪽에 도킹해 왼쪽으로 접히는 패널
(제목 카드)을 전제로 회전값을 고정하고 있었다. 배수유역 패널은 오른쪽에 도킹해
오른쪽으로 접히므로 같은 회전을 쓰면 열기/닫기 표시가 정확히 거꾸로 나온다.
`collapseToward` 인자를 추가하고 이 패널만 "right"를 넘긴다.
기본값 "left"라 나머지 호출처는 회전값이 이전과 동일하다:
- ui_template_overlay.ts:81 제목 카드 — "side" 기본값, 열림 180° / 닫힘 0° 그대로
- B05_wf2_Route_UI_Profile_Panel.ts:244 하단 패널 — "bottom" 배치라 애초에 무관
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
B04 2D 지도와 B05 배수유역도의 휠 판정을 deltaY > 0 기준으로 바꿨다.
커서 아래 지점을 고정하는 offset 보정은 그대로다. 3D 뷰어는 손대지 않았다.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
하이라이트 열이 덮는 자리의 규칙 측점 값 셀을 통째로 숨겨(hideCoveredCells),
비정규 측점을 고를 때마다 좌우 최대 2개 열의 값이 사라졌다. 표는 그대로 두고
선택된 값만 위에 얹도록 그 함수와 .is-covered 규칙을 걷어냈다.
하이라이트 열에서 계획고만 자주색 테두리·글자색으로 따로 강조되던 것도 없앴다.
평상시에는 다른 셀과 같은 모습이고, 고칠 수 있다는 표시는 hover·focus에서만
나타난다. 직접 입력 기능은 그대로다.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
구조물 측점이 두 곳에 있었다. 화면 정본인 사이드바 목록과, 경로 확정 때 종단
정본 파일에 병합된 kind="irregular" 측점이다. 그래프와 3D가 둘을 겹쳐 그려서
관을 옮기면 사이드바 목록만 따라가고 확정 당시 자리는 그대로 남았다.
그래프(_UI_Profile_Panel.draw)와 3D(_UI_Page.renderStationLines) 모두 종단
정본의 비정규 측점을 걷어내고 사이드바 목록만 얹는다. 저장분은 진입 시
restoreSections가 목록으로 되살리고, 관 항목은 배수유역도가 정본
(pipe_points.json)에 맞춰 갈아 끼운다.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
1) 사이드바 폼으로 이름을 "배관"이라 적어 넣은 항목은 origin이 "user"라 [초기화]로
지워지지 않고 배수유역도와도 어긋난 채 남았다. isPipeStation()(origin이 pipe이거나
이름이 "배관")으로 판정을 통일해 목록 교체·이동·삭제·선택 동기화가 같은 규칙을 쓴다.
2) 대시보드에서 곧장 B05로 들어오면 배수유역도가 비어 보이고 새로고침해야 나왔다.
패널이 배치되기 전(0×0)에 fitToRoute()가 돌아 엉뚱한 배율이 굳은 것이다. 크기가
2px 미만이면 맞춤을 미뤘다가 첫 배치 때 다시 맞춘다.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
[초기화]가 화면 목록만 자동 배치로 되돌리고 edits/pipe_points.json은 그대로 두어,
페이지를 다시 열면 옛 관이 살아났다. B04와 같은 파일을 보므로 B04에도 그대로 남았다.
- DELETE /{project_id}/drainage/pipe-points 신설: 저장분과 파생물
(04_detailed_basins.geojson)까지 지우고 자동 배치 결과를 돌려준다.
- clear_pipe_points() 헬퍼 추가.
- B05 [초기화] 버튼이 이 경로를 쓴다.
- loadSaved / analyze / resetPipes가 같은 뼈대를 반복해 run() 하나로 묶었다.
검증: 초기화 전 {user:1, stream:1, spacing:2} → 초기화 후 {stream:1, spacing:3},
두 파일 삭제 확인, 재조회도 같은 자동 배치.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
pointerdown에서 유역 고르기 후보(basinClickStart)를 기억하는 코드가 실제로는 들어가
있지 않아, pointerup의 후보가 늘 null이었고 pickBasinAt()이 한 번도 불리지 않았다.
같은 편집에 묶여 있던 좌클릭 전용 제한도 함께 빠져 있어 우클릭·가운데 클릭으로도
마커가 잡히고 있었다.
- 좌클릭일 때만 pipeEditor.handleDown()을 부르고, 잡았으면 pipeClickStart로 기록
- 마커를 못 잡은 좌클릭은 basinClickStart로 남겨 뗄 때 유역을 고른다
- 700줄 유지: basinIndexOfPipe()를 _Drainage_Parts.ts로 이동
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
하단 패널이나 우측 배수유역 패널을 늘리면 computeMapRect()가 지도를 뷰포트에 다시
맞춰(contain) 지도까지 함께 확대됐다. 배율이 바뀌니 방금 보던 자리를 다시 찾아야 했다.
화면 변환 계수(ax·bx)가 그대로가 되도록 배율·오프셋을 되계산해, 늘린 만큼은 확대가
아니라 더 넓은 범위로 채운다.
- preserveViewOnResize(): 이전 프레임의 변환 계수를 새 뷰포트에서 재현
- observeViewportSize(): 크기 변화를 지켜보며 위 보정을 걸고 다시 그린다
- 700줄 유지를 위해 fitCanvasToViewport / createProgressReporter / pipeMarkerColor도
_Drainage_Parts.ts로 이동
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
채움과 함께 그리던 번호가 등고선·흐름 화살표·관 마커에 가려 읽히지 않았다.
번호만 떼어내 프레임 맨 마지막에 얹는다.
- MapRender에 drawRingBadge()·ringCenterOnScreen()을 분리 노출.
drawFilledRing은 라벨이 있을 때 drawRingBadge를 부르는 형태로 바뀐다.
- B04: drawBasinNumbers() 호출을 관 마커 뒤로 이동(관이 없어도 번호는 그린다).
- B05: 채움은 라벨 없이 그리고 배지 자리만 모아 두었다가 배관 마커 뒤에 그린다.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
구조물 조작이 테이블과 그래프로 나뉘어 있었다. 이동은 그래프 측점선, 추가·삭제는
테이블이라 어디서 무엇을 하는지 알기 어려웠다. 메뉴를 그래프 칸으로 옮겨 셋을 한
자리에 모은다. 테이블은 값만 보여 준다.
- mountStructureMenu의 부착 대상을 테이블 → 그래프 칸(.b05-profile__chart)으로 교체
- ProfileTableOptions.structureLines 제거
- CSS 블록명 b05-profile-table__context-menu → b05-profile-chart__context-menu
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
- 테이블에 얹던 구조물 세로선을 걷어냈다. 위치는 그래프 측점선이 이미 보여 주므로
같은 것을 두 번 그리는 셈이었다. 테이블에는 우클릭 메뉴만 남는다
(가까운 구조물이 있으면 삭제, 없으면 배관 추가).
- 드래그는 종단 그래프의 구조물 측점선에서 한다. createLongitudinalProfile에
onDragStation을 추가하고 kind === "irregular" 측점선에만 붙였다(좌클릭 전용).
- 좌측 구조물 폼에서 "배관" 항목을 고치거나 지우면 그래프와 배수유역도가 함께
갱신된다. DrainagePanel.setPipeChainages() 신설.
reconcilePipes()가 목록이 같으면 null을 돌려 관↔구조물 순환을 끊는다.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>