Commit Graph
284 Commits
Author SHA1 Message Date
eomsangdonandClaude Fable 5 69aed9d26c feat(ui): 구조물 폼 빈칸 상태·사이드 액션 고정·하단 패널 높이 캐스케이드
- 구조물 종류 드롭다운에 빈칸 항목 — 초기·리셋 상태는 빈칸이고 하위 옵션 전체
  숨김, 미선택이면 추가 불가(2026-08-05 사용자 지시)
- 사이드 패널 최하단 고정 액션 줄 공용 클래스(ui-sidebar-actions): 계산·확정
  버튼이 스크롤에서 제외되고 불투명 배경이 지나가는 내용을 가림.
  B04(확정·초기화)/B05(계산·확정)/B06(재계산·저장·확정) 적용, B07은 기존
  자체 sticky 유지
- 하단 패널 높이 캐스케이드: 아래로 끌면 종단 먼저 최소(100px)까지 →
  테이블·유토곡선이 같이 비례 축소(각자 최소 140/160px, 인라인 임시 축소라
  다시 키우면 원래 높이 복귀) → 셋 다 최소면 리사이저 동적 하한이 차단.
  공용 리사이저 min을 함수 지원으로 확장. 반대로 서브패널 펼침으로 부족하면
  메인 패널을 키움(기존 로직 유지)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-05 19:44:16 +09:00
eomsangdonandClaude Fable 5 0025538b18 feat(B05): 3D 흑백 지형 토글·서브패널 손잡이 규칙·좌측 여백 확대
- 3D 뷰 토글에 '흑백 지형' 추가(측점 라벨 우측, 기본 무지개). 정점색 1회
  바꿔치기(원본 userData 보관)라 로딩·회전 성능 영향 없음
- 유토곡선 접힘 버튼은 항상 바닥 — 순서(종단>테이블>유토곡선)상 테이블 아래에서
  나오므로. 테이블 접힘 버튼만 열린 유토곡선 위 경계에 나란히
- LONG_PAD.left 62->78: 좌측 패널 접기 버튼이 Y축 라벨·행제목을 가리는 문제.
  sticky 마스크·행제목 폭이 같은 값에서 파생돼 가로 스크롤 값 누출 없음

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-05 19:30:04 +09:00
eomsangdonandClaude Fable 5 75232b9f73 fix(B05): 3D 선택 유지·구조물 폼 규칙·패널 손잡이 정렬·종단 최소높이 확보
- 3D 빈 공간 클릭(회전 드래그 포함)으로 측점 선택이 풀리지 않게 — 해제는
  그래프·사이드 패널에서만 (3D 영역 한정, 2026-08-05 사용자 지시)
- 구조물 폼: 편집 중 타입 변경 시 신규 추가로 전환(입력값 유지),
  자동 배관(origin=pipe)은 타입 잠금(관종·직경만 변경 가능), 리셋 시 폼 초기화
- 접힌 서브패널 손잡이는 열린 패널의 위 경계 수평선에 일렬 배치
  (테이블 접힘+유토 펼침 시 유토곡선 상단)
- 종단 그래프 최소높이(100px) 부족 시 메인 하단 패널 높이를 자동 확장
  (뷰포트 92% 상한) — 서브패널 펼침으로 종단이 뒤로 넘어가는 역전 방지

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-05 19:21:48 +09:00
eomsangdonandClaude Fable 5 2876ca5cbb fix(B05): 계류 유역 세월교 판정 + 하단 패널 밀어올리기 동작
- 세월교 판정: 유효직경이 관 최대 규격(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>
2026-08-05 19:08:36 +09:00
eomsangdonandClaude Fable 5 3d5e8988c0 feat(B05): 구조물 드롭다운·관경 자동지정·우클릭/마킹·하단 패널 개편 (계획서 Phase 3~5)
- 구조물 배치 폼: 종류 드롭다운(배관/기성막이/대피로/기타) + 관종·직경/폭/이름
  하위 옵션. 목록·기본값은 config_frontend(정본 config_system.py 미러) 관리
- 관경 자동 지정: 기본 D800, 배수 유효직경 초과 시 바로 위 규격.
  수동 변경(userSized)은 재계산에도 유지. 소구경 리스트 유지
- 종단·배수유역도 우클릭 메뉴에 기성막이/대피로/기타 추가 항목
- 유토곡선·테이블 영역 브라우저 기본 우클릭 메뉴 차단
- 측점 선택 시 배수유역도 계획선 위 다이아몬드 마킹(유역 없는 구조물 포함)
- 3D 선택 마킹: 수직 핀(기둥+역원뿔, depthTest off) — 원형 표기 지양
- 테이블을 유토곡선과 같은 바닥 고정 오버레이 서브패널로 개편.
  접힘 손잡이 일렬(좌 테이블/우 유토곡선), 순서 종단도-테이블-유토곡선
- 테이블 행제목 우측 정렬+좌측 여백, 종단·유토곡선 Y축 눈금 10-13px

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-05 18:41:55 +09:00
eomsangdonandClaude Fable 5 fa6953ce6d feat(B04/B05): 확률강우량 수급·배수 유효직경 합리식 계산 (계획서 Phase 1·2)
- common_util_wamis_rainfall.py 신설: map.wamis.go.kr 등우선도 urllib 수급,
  전역 캐시(resources/wamis_contours), 거리비례 내삽, General형 IDF 적합
- /drainage/rainfall API + primary-region 백그라운드 강우량표 생성 훅
- estimate_pipe_diameter_mm TODO 구현: Kirpich 도달시간(하한5분) + 합리식(C=0.8,
  2.0배) + Manning(경사10도, n=0.024, V<=3.0) + 통수단면 70% -> 배수 유효직경
- basins 응답·B05 유역 제원에 유효면적/유효직경·산출근거(tc/I/Qd) 표기
- config_system: 계산 계수·구조물 옵션(관종/직경/대피로) 기본값 등록

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-05 18:19:48 +09:00
eomsangdonandClaude Opus 5 5378b9d807 fix(B05): sticky Y축을 편집 버튼 층 위로(z3→z5) — 스크롤로 지나가는 버튼이 축 라벨을 덮지 않음
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-04 20:09:25 +09:00
eomsangdonandClaude Opus 5 679c847072 fix(B05): sticky Y축 앵커를 첫 자식으로 — 스크롤 시 축이 안 보이던 문제 수정
0크기 sticky 앵커를 SVG 뒤에 붙이면 흐름 위치가 차트 아래로 밀려 가로 스크롤 시
축 오버레이가 화면 밖에 놓였다(스크롤 0에서는 SVG 자체 눈금이 보여 드러나지 않던
버그). B06과 같은 규칙(첫 자식 prepend)으로 통일 — 종단 표고축·유토곡선 ㎥축 모두
스크롤 800px 상태에서 좌측 고정·불투명 확인.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-04 20:06:20 +09:00
eomsangdonandClaude Opus 5 f41b223079 fix(B05): 곡선 셀 회전 표기·손잡이 클릭 가로채기·배수유역 손잡이 z(31~33)
- 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>
2026-08-04 20:02:37 +09:00
eomsangdonandClaude Opus 5 6bcd6d1209 feat(B05/B06): 하단 간격·접힘 거터·B06 sticky Y축·배관 곡선 상시 표기(27~30)
- 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>
2026-08-04 19:53:42 +09:00
eomsangdonandClaude Opus 5 8c95f8e7f2 fix(ui): 사이드 손잡이를 패널 테두리에 1px 겹쳐 외곽선 관통 이음새 제거
강조색 패널 테두리(24번)가 side 손잡이의 라운드 모서리 틈으로 비쳐 외곽선이
어긋나 보였다(2026-08-04 사용자 보고). 손잡이를 1px 안쪽으로 겹쳐 선을 덮는다.
배수유역(왼쪽 부착) 손잡이는 이상 없음 확인돼 그대로 둔다.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-04 19:40:42 +09:00
eomsangdonandClaude Opus 5 c8aaafcb54 fix(B05): 유토곡선 리사이저 TDZ 크래시로 페이지 진입 불가 수정 + 표시선 2px
원인: 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>
2026-08-04 19:37:46 +09:00
eomsangdonandClaude Opus 5 05887b6a7e feat(B05/ui): 유토곡선 스크롤바·구분선·선택 토글·패널 시인성(21~25)
- 21: 유토곡선 높이를 스크롤러 clientHeight 기준으로 — 스크롤바가 Y축 라벨을 덮던
  문제 해소, overflow-x scroll 고정으로 높이 안정화
- 22: 절토·성토 요약 줄을 종단 열 안으로 — 배수유역도 좌측 구분선 25px 끊김 해소
- 23: 선택 토글 해제 — 종단·유토곡선 측점 재클릭/빈 곳 클릭, 사이드바 구조물 재클릭
  시 해제(null 전파로 3D·그래프·목록·유역 강조 동기 해제)
- 24: 좌측 제목 패널(B04~B07 공용) 우측 가장자리 강조색 라인
- 25: 접힌 손잡이 강조색 배경 틴트 — 닫힌 패널이 있음을 상시 표시

Playwright: 재클릭 1→0, 빈곳 클릭 0, 스크롤러 226=곡선 226, 구분선 간극 1px,
접힘 틴트 확인, 콘솔 오류 0. typecheck 통과.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-04 19:34:38 +09:00
eomsangdonandClaude Opus 5 344d1fbbb9 fix(B06/ui): 손잡이 폭 글자 맞춤·화살표 크기 고정, 리사이저 표시선 경계 정착
- 이름표 손잡이: 화살표·이름표 flex 압축 제외 — 글자를 줄이지 않고 폭이 내용에 맞춰
  늘어난다(B06 '종단/유토곡선' 104px, 화살표 7px 유지)
- B06 토글 아래 테두리를 좌우와 같은 강조색으로 — 외곽선 색 섞임 해소
- B06 리사이저 상시 표시선: 히트 영역 가운데(경계 4px 위) 대신 패널 아래 경계에 정착

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-04 19:15:41 +09:00
eomsangdonandClaude Opus 5 c8eeb15b81 fix(B05): 확정된 구조물 측점의 편집 버튼 이중 생성 제거
확정을 거친 구조물 측점은 종단 정본(alignment.stations)에 이미 병합돼 있는데
사이드바 목록(irregular)에서 또 추가돼 ▲▼가 2개씩 생겼다(같은 자리에 겹쳐 있다가
겹침 회피 캐스케이드가 옆으로 벌리면서 드러남). 같은 chainage(소수 3자리)는 한 번만
버튼을 단다. 검증: 버튼 27→23개(배관 4곳 중복 제거), 근접 측점 비킴은 유지.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-04 19:08:15 +09:00
eomsangdonandClaude Opus 5 d4fc73c012 feat(B05/B06/ui): 패널 손잡이·리사이저·편집 버튼 시인성 정리(16·18~20)
- 16: 편집 버튼 전체(▲▼·↺·⬆⬇) 21×17 통일, 겹침 간격 23px, X축 라벨 상향 19px
- 18: 유토곡선 손잡이가 오버레이 위 경계를 따라 이동(펼침 시 테이블 영역 침범 허용)
- 19: 손잡이 테두리 강조색 --panel-handle-border(라이트 파랑 #2563eb / 다크 노랑
  #e0b64a) + 이름표 옵션 — B05 '종단'·'유토곡선'·세로 '배수유역', B06 '종단/유토곡선'
- 20: 공용 리사이저 상시 표시선(1px, 같은 강조색) — hover/드래그 시 3px

Playwright: 버튼 3종 21×17, 라벨·테두리색·세로 writing-mode, 리사이저 1px/0.75,
손잡이 bottom=오버레이 top 일치, 콘솔 오류 0. typecheck 통과.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-04 19:06:02 +09:00
eomsangdonandClaude Opus 5 cdd40a00f3 feat(B04/B05): 재확정 재계산 체인(12) + 편집 버튼·유토곡선 UI 정리(13~15)
- 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>
2026-08-04 18:48:18 +09:00
eomsangdonandClaude Opus 5 7d7fd64d6b feat(B03): WF1 자동 확정을 역할 무관으로 확대 — 관리자도 B06까지 자동 체인
SYSTEM_ADMIN 예외를 제거한다(2026-08-04 사용자 확정 — 관리자도 같은 사용자).
업로드 후 모두 기본값으로 지표면 자동 확정 -> B05 기본 경로 -> B06 기본 횡단
설계까지 체인을 탄다. 관리자가 B04에서 다른 모델로 재확정하는 경로는 그대로이며,
체인은 경로가 이미 있으면 스스로 건너뛴다.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-04 18:34:09 +09:00
eomsangdonandClaude Opus 5 ded617129e fix(B03): upload-overview 컬럼명 upload_at으로 수정 (input_files 스키마 정합)
서버 테스트에서 발견 — input_files에는 created_at이 없고 upload_at이다.
upload-overview 응답·Repository 조회 컬럼을 스키마에 맞춤.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-04 18:20:21 +09:00
eomsangdonandClaude Opus 5 e2f6a101b6 feat(B03): 재접속 업로드 현황(10) + B05·B06 자동 설계 체인(9)
10. 재접속 현황·완료 표시·재업로드 경고:
- GET /projects/{id}/upload-overview 신설 — 완료 파일 목록(input_files 정본),
  중단 청크 세션(진행률), 필수 파일·WF1 분석 완료 여부
- 진입 시 서버 정본으로 슬롯 카드 표시(serverUploaded), localStorage는 보조로 강등
- 파일 재선택 전에도 중단 세션 이어올리기 안내 배너
- 전체 완료 배지 + 완료 슬롯 재업로드 시 교체 확인 모달(승인 시에만 진행)
- 필수 슬롯 검증: 서버 업로드분 있으면 충족 — 단일 파일 교체 업로드 허용

9. 자동 설계 체인 연장 (B03_FileInput_Service_Chain.py):
- WF1 자동 확정 후 같은 백그라운드 태스크에서 ① 계획노선 CSV 기반 B05 기본 경로
  계산(solve) ② 경로 확정(stage 2) ③ B06 기본 횡단 설계 확정(stage 3)까지 진행
- 수동 이력 보호: 프로젝트에 경로가 이미 있으면 건너뜀
- 단계별 실패 격리: 실패 단계에서 멈추고 로그·workflow 상태로만 기록
- AUTO_DESIGN_CHAIN_ENABLED config 플래그(기본 True)

typecheck·ruff·B03 unittest(7건) 통과.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-04 18:09:15 +09:00
eomsangdonandClaude Opus 5 6080d122bb feat(B05/B06): 계획서 1·2·4·5·6·8·11 구현 + 유토곡선 오버레이 서브패널 전환(7)
- 4: volumeRange 기본 ±200㎥ 고정, 초과 시에만 확장 (B05·B06 공용)
- 11: 진행단계 오버레이 최상단 대시보드(🏠) 버튼 — 항상 활성, B01 이동
- 6: 편집 버튼 방향색 — 올림(▲⇧) --color-danger, 내림(▼⇩) 파랑 #5b8def, hover 배경 포함
- 2: 구조물 목록 5개 높이 상한 + 내부 스크롤, 선택 항목 scrollIntoView
- 5: 종단 렌더러 bottomInsetPx 옵션 신설 — B05만 X축·측점 라벨 17px 상향,
  ▼ 버튼과 오버랩 해소 (B06 무변화)
- 1: 구조물 측점 열 기본값 미표기 — 측점 값 7행·곡선 2행 빈 셀, 선택 오버레이가 값 표시
- 8: B06 진입 stale 재계산을 측점별 순차 루프에서 일괄 프리뷰 1회로 교체
  · preview API에 full_designs·rock_boundary_offsets 추가
  · B05 세션 초안(readAlignmentDraft) 우선 사용해 두 화면 계획선 일치
- 7: 유토곡선을 1:1 분할에서 패널 바닥 오버레이 서브패널로 전환
  · 종단도+테이블 배치 불변, 오버레이가 위를 덮음
  · 높이는 공용 createPanelResizer(위 경계, 세션 보존), splitBar·MASS_SPLIT 제거
  · 자체 가로 스크롤러 + 종단 스크롤러 양방향 동기화, 전용 ㎥ sticky Y축
  · buildStickyYAxis 정의처를 MassHaul 모듈로 이동(Panel과 공용)

typecheck·vite build·ruff 통과.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-04 17:54:53 +09:00
eomsangdonandClaude Opus 5 c6d930b3f1 fix(B06): 측점 선택 시 횡단도 카드 상단을 패널 손잡이 아래 정지선에 정렬
- revealCard: scrollIntoView block nearest -> start (카드 하단이 브라우저
  바닥에 걸리던 문제 수정, 카드 상단이 sticky 패널 아래에 붙음)
- syncScrollMargin 신설: 스크롤 직전 패널 높이 실측 + 손잡이 24px + 여유 8px
  (접기 시 drawPanel 미실행이어도 정지선 최신 유지)
- PLAN.md: A~D 항목 완료·취소 정리(2026-08-04 사용자 확정), 아카이빙 대기 표기

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-04 16:50:07 +09:00
eomsangdonandClaude Opus 5 b3c64625df feat(B05): 3D 측점 라벨 기본 켜짐, BP·EP·5측점 배수까지 표시
- [측점 라벨] 토글 기본값을 켜짐으로 바꿨다. 3D에서 측점 위치를 바로 읽는 것이
  기본 동작이다.
- 라벨 대상 확대: BP·EP(이름 접두), 5측점 배수 규칙 측점, 구조물(비정규) 측점
  (측점번호 + 구조물 이름). 나머지 규칙 측점은 달지 않는다 — 전부 달면 겹친다.
- 표기를 종단 그래프·도면 테이블과 같은 규칙(측점번호+잔여거리)으로 통일했다.
  서버 label은 STA.0+000.000 형식이라 화면마다 표기가 갈렸다. 누가거리와 최빈
  측점간격으로 되짚어 stationLabel()로 만든다.

확인: 23측점 노선에서 라벨 9개(BP / 5·10·15측점 / 구조물 4 / EP)만 표시됨을
실데이터로 검증. typecheck·vite build 통과.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-03 21:07:41 +09:00
eomsangdonandClaude Opus 5 f39ecf2f5e fix(B05): 유토곡선 고정 축에 단위 ㎥ 표기, 축 눈금 영역 클리핑
바로 위 종단 표고축(…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>
2026-08-03 20:53:17 +09:00
eomsangdonandClaude Opus 5 644ec64bd2 perf(B05/B06): 계획선 프리뷰 응답 1.09MB → 6KB, 곡선 셀 기본 표시 원복
프리뷰 성능
- 느린 원인은 응답 크기였다(영구저장소 저장·재로드는 하지 않는다). 상세를 통째로
  돌려주느라 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>
2026-08-03 20:47:35 +09:00
eomsangdonandClaude Opus 5 cffd65bd75 feat(B05/B06): 계획선 편집 시 횡단 설계 일괄 재계산 파이프라인
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>
2026-08-03 20:41:04 +09:00
eomsangdonandClaude Opus 5 d21b0ec51d fix(B05): 종단곡선 기준을 L로 전환하고 테이블 곡선 R·L 누락 수정
영구저장소를 직접 확인하니 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>
2026-08-03 20:35:15 +09:00
eomsangdonandClaude Opus 5 1ee6516dd5 feat(B05/B06): 종횡단 상세 프론트 공유 캐시 + 계획선 호 통과 기하
페이지 간 캐시 공유
- 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>
2026-08-03 20:28:23 +09:00
eomsangdonandClaude Opus 5 a9741277cf feat(B05): 배관 정착 계획선 1차 로직 + 유토곡선 UI 정리 5건
계획선 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 20:14:09 +09:00
eomsangdonandClaude Opus 5 f4f56069b0 feat(B05/B06): 유토곡선 횡단 기준 통일·자동선정 삭제·계획선 R 연결 외 9건
사용자 피드백 반영(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>
2026-08-03 19:54:37 +09:00
eomsangdonandClaude Opus 5 6c90c26eef feat(B05): 계획 유토곡선 이관 + 사토장·토취장 4옵션 자동 선정
절·성토 균형은 종단 시공계획고로 정해지고 사토장 위치도 계획고를 다시 끌어야
정리되므로, 계획용 유토곡선과 부지 선정을 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>
2026-08-03 19:06:46 +09:00
eomsangdonandClaude Opus 5 fceec5fb24 refactor(common): 유토곡선 엔진·렌더러를 common_util로 공용화
B05 계획 유토곡선과 B06 정식 유토곡선이 같은 엔진을 쓰도록 모듈을 옮겼다.

- B06_wf3_ProfileCross_UI_MassHaul{,_Balance,_Balance_View,_Balloon,_Curve,
  _Settle,_View}.ts + Style_MassHaul.css → common_util/common_util_mass_haul*.
- common_util_mass_haul_types.ts 신설: GroundType/EarthworkConversion/
  HaulEquipmentLimit/BalloonOffsets 정의처를 한 곳으로 모으고 B06 Api_Fetch가
  재수출. 엔진 입력은 페이지 API 타입 대신 구조적 부분집합으로 받는다.
- common_util_svg.ts 신설: svgElement/svgText/L/stationLabel/
  inferStationInterval 이관, B06 _UI_Section_Common은 재수출로 경로 유지.
- createMassHaulChart에 MassHaulAxis 인자 추가 — 종단 렌더러 상수 의존을
  걷어내고 호출한 쪽이 X축(누가거리 최댓값·좌우 여백)을 주입한다.

동작 무변경. npm run typecheck 통과.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-03 18:35:02 +09:00
eomsangdonandClaude Opus 5 e4700546bb feat(B06): 띠 외곽선 재정의 · balloon 화면 이탈 방지 · 임시 저장 · 토취 화살표 복원
[1] 띠 면이 스스로 겹쳤다. 외곽선을 "아래 현 -> 왼쪽 곡선 -> 위 현 -> 오른쪽 곡선"으로
이어 붙이다 보니, 곡선이 두 현 사이에서 요동치면 그 조각이 띠 밖으로 삐져나가 다각형이
자기교차했다. 정의를 바꿨다 - 띠는 "아래 현의 두 끝 사이에서, 아래 높이부터 곡선과 위
높이 중 안쪽까지"다. 아래 현을 밑변으로 깔고 곡선값을 두 높이 사이로 자른 값만 찍으면
어떤 지형에서도 단순 다각형이라 겹칠 수 없다.

[2] balloon이 화면 밖으로 나갔다. 두 곳이 샜다 - 빈자리를 못 찾았을 때 findSlot이 세로를
자르지 않았고, 저장해 둔 이동량을 그릴 때도 자르지 않아 화면을 줄이면 밖을 가리켰다.
둘 다 상자 안으로 자르고, 드래그 중에도 같은 함수를 쓴다.

[3] 임시 저장 - POST .../sections/{route_id}/save 신설. 저장 내용은 확정과 같고(표준횡단
설정·유토곡선·balloon 위치·암 경계선) 경로 상태·워크플로 단계를 건드리지 않아 페이지
이동이 없다. 미지정 측점을 기본값으로 채우지도 않는다. 버튼은 재계산과 확정 사이(1행 3열)
이고, 재계산이 밀려 있어도 눌린다 - 편집분을 잃지 않는 것이 목적이다.

[4] 토취·사토 화살표를 실제 단차 끝까지 되돌렸다. 끝나는 높이가 새 평형선이라 그 자체가
정보다. 라벨이 곡선을 가리는 문제는 이미 balloon처럼 떼어 놓아 해결됐다.

_Router.py(718줄) -> 저장·확정을 _Router_Confirm.py(203줄)로 분리. 임시 저장과 확정이
저장 본체(_apply_section_edits)를 공유한다.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-02 18:29:43 +09:00
eomsangdonandClaude Opus 5 b0fe443269 feat(B06): 자연방토 반영 — 사토를 자연방토/사토장 운반으로 가름
판정 기준은 성토측 자연 지반 경사(사용자 확정). 지반이 임계보다 가파르면 부어 놓은 흙이
쌓이지 않고 스스로 흘러내리므로 운반비를 세지 않는다.

계상 방식은 참고 도면을 근거로 정했다. 도면의 사토 balloon은 L=(운반거리) 없이
M.N=측점만 적는다 - 그 노선의 사토가 이미 운반비 없이 처리되고 있다는 뜻이고,
자연방토라는 이름을 안 썼을 뿐 처리 방식이 자연방토다. 그래서 새 항목을 만들지 않고
사토 안에서 가른다. 판정 통과분은 도면과 똑같이 M.N만, 실패분에만 "사토장=X㎥"를 더한다.
수량은 그대로 두고 성토로 흡수하지 않아 유토곡선 모양과 누가토량은 안 바뀐다.

- config NATURAL_SPOIL_MIN_GROUND_SLOPE = 1/1.5 (rise/run, 약 33.7도) 신설.
  유일한 정의처이며 프론트는 context로 받아 쓴다. 못 받으면 자연방토 없음(보수적)
- 엔진 fill_ground_slope(): 노면 끝~성토 사면의 첫 지반 교차까지 평균 경사.
  양쪽이 다 성토면 완만한 쪽을 택한다(보수적)
- AreaSample/MassHaulPoint에 natural_spoil - 양 끝 측점이 둘 다 가능할 때만 참
- HaulResidual.natural_m3 - 잔량 구간에서 자연방토 가능한 길이 비율만큼 계상.
  장거리 상쇄로 깎이면 안분·자연방토도 같은 비율로 감소
- HaulPlan.natural_spoil_m3 + 요약 칩

700줄 초과 2건 분리: _Engine_Areas.py(면적 적분), _UI_MassHaul_Settle.ts(안분·장비·상쇄·
직렬화). 의존은 한 방향(Balance -> Settle 함수, Settle -> Balance 타입만)이라 순환 없음.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-02 18:18:08 +09:00
eomsangdonandClaude Opus 5 d69b51509d fix(B06): 성토 사면을 지반과 첫 교차점에서 끝내고 카드 오버레이를 쌓임 맥락에 가둠
[1] 절토에는 "지반과 1회 교차하면 그 이후는 지반 추종" 규칙(cut_cross_dist)이 있었는데
성토에는 없었다. max(fill_line, ground)만 쓰면 지반이 다시 꺼졌을 때 성토 사면이
되살아나 사면이 끊겼다 이어지는 그림이 나온다. 실측 지면이라 이런 지형이 흔하다.

fill_cross_dist()를 같은 규칙으로 추가하고 design_z·breakpoints에 물렸다. 첫 교차점이
성토사면의 끝이고 그 바깥은 손대지 않은 원지반이다. 설계선뿐 아니라 fill_area_m2도
같은 design_z를 타므로 함께 바로잡힌다.

검증: 지반이 두 번 꺼지는 합성 단면에서 첫 교차(-5.4m) 이후 설계선이 지반보다 높은
점 0개(이전에는 -8m 밖에서 성토가 되살아났다).

[2] 줌 버튼이 스크롤 시 상단 패널 위로 삐져나왔다. 카드 안 오버레이의 z-index가 최상위
쌓임 축에서 겨루고 있어, sticky 패널(z-index 2)과 같은 층에서 DOM 순서로 카드가 이겼다.
.b06-cross-card에 isolation: isolate를 걸어 카드를 자체 쌓임 맥락으로 만든다.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-02 18:06:11 +09:00
eomsangdonandClaude Opus 5 dc19d09f0e feat(B06): 유토곡선 직선 확정 + 잔량 표기 통일 + 횡단도 줌 버튼
유토곡선을 측점 사이에서 직선으로 잇는다(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>
2026-08-02 17:59:30 +09:00
eomsangdonandClaude Opus 5 0826015a76 fix(B06): balloon 지시선을 평균운반거리 수평선 중앙에 맞춤
지시선이 블록 정점(극값)을 가리키고 있어 측점선과 수평선이 만나는 자리를 찍는
꼴이 됐다. balloon이 설명하는 대상은 정점이 아니라 그 띠의 평균운반거리
수평선이므로 앵커를 그 선의 한가운데로 옮긴다.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-02 17:40:52 +09:00
eomsangdonandClaude Opus 5 25d0c69b7d fix(B06): 유토곡선을 포물선 경로로 렌더 + balloon 위치 영구 보관·초기화
[1] 수평선이 곡선에서 떨어져 보이던 문제. 엔진은 포물선으로 교점을 잡는데 곡선만
직선(polyline)으로 그리고 있었다. 평형선·장비 경계현·평균운반거리선의 양 끝이
곡선 위가 아니게 되어 어긋나 보였다.

곡선을 2차 베지에 경로로 바꿨다. 제어점 (x0 + Δ/2, V0 + a0Δ/2)에 두면 2차 베지에가
구간 포물선과 정확히 같아진다. 0선 아래 음영도 같은 경로로 닫고, 띠 테두리도
측점만 잇던 것을 구간마다 4등분해 곡선에 붙였다.

[2] balloon 위치 저장 경로를 둘로 나눴다.
- 프론트 캐시(localStorage, 프로젝트+경로별 키): 끌어 옮기는 즉시
- 영구저장소: 횡단 확정 시 mass_haul.balloon_offsets로 저장
진입 시에는 영구저장소 값이 이긴다 - 다른 브라우저에서도 같은 자리에 뜬다.
상세 응답에 balloon_offsets를 실어 내려보낸다.

[3] 범례 줄에 "도형 위치 초기화" 버튼(분배 레이어를 켰을 때만). 프론트 캐시를 비우고
다시 그리며, 비워진 값이 다음 확정 때 영구저장소를 덮는다.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-02 17:28:33 +09:00
eomsangdonandClaude Opus 5 55dc5629e2 fix(B06): 유토곡선 포물선 보간 + 잉여·부족 장거리 상쇄
참고 도면(기번3, 측점별 누가토량 81점 + balloon 43개)과 대조해 오류 2건 확인·수정.

[1] 측점 사이는 직선이 아니라 포물선이다. 단면적이 선형으로 변하면 그 적분인
누가토량은 2차식이 된다. 도면에서 측점간격 20m 구간의 반종거가 20/√2 = 14.14m로
12번 반복해 찍히는 것이 근거(직선이면 10m). 직선으로 재던 평균운반거리가 약 40%
짧게 나와 20m 경계 판정이 어긋나고 있었다.

MassHaulPoint에 다짐환산 순단면적을 실어 구간마다 V(t) = V0 + a0t + (a1-a0)t²/(2Δ)를
세운다. V(Δ) = V0 + (a0+a1)Δ/2라 곡선 자체는 그대로고 현 길이만 바뀐다.

두 단면적의 평균이 구간 평균과 어긋나면 포물선이 끝점을 벗어나 수평선 교점을 못 찾고
블록이 통째로 늘어난다(도면 곡선 검증에서 성토 1455㎥가 한 블록에 묻혔다). 두 값을
같은 양만큼 옮겨 끝값을 강제로 맞춘다. 곡률은 보존되므로 포물선 모양은 그대로다.

[2] 남은 사토와 토취를 거리 가까운 짝부터 맞물려 장거리 운반으로 바꾼다. 도면 곡선은
0선 아래로 한 번도 내려가지 않는데 기존 로직은 토취 1435㎥를 만들어 냈다. 도면의
덤프 L=935/1008m가 이 장거리 운반이고, 배분 3원칙 ①(거리 최소) ③(모아서 운반)이다.

- 사토 표기에 측점(M.N) 추가 - 도면은 사토에 운반거리를 안 매긴다
- 검산 칩: 운반(띠) + 장거리 운반 + 토취 = 총 성토량
- 장거리 운반선은 1점쇄선 + 화살촉 (네 번째 선타입)
- 700줄 초과로 곡선 기하를 _UI_MassHaul_Curve.ts로 분리

도면 곡선 재현: 토취 1435 -> 0, 사토 2606 -> 1171(= 최종 누가토량),
운반계 오차 -10.1% -> -0.80%, 종무대 L 0.2~13.2 -> 10.51~18.01m(도면 8.39~15.98).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-02 17:19:48 +09:00
eomsangdonandClaude Opus 5 c490e2ff45 feat(B06): 유토곡선 balloon 축소·곡선 회피 배치·드래그 이동 + 양방향 하이라이트
도형이 크고 남는 공간을 못 찾는다는 지적 반영.

- balloon을 두 줄 상한(번호·물량 / L·장비)으로 줄이고 여백·육각 노치 축소.
  EA/RR/BR은 툴팁으로 옮김
- 배치를 세로 밀기에서 가로·세로 링 탐색으로 바꾸고 curveYAt으로 곡선까지 회피.
  못 피하면 곡선 조건만 버리고 재탐색(안 그리는 것보다 낫다)
- balloon을 끌어 옮길 수 있고 지시선 끝점이 따라간다. 옮긴 자리는 세션에 남고
  더블클릭이면 자동 배치로 복귀. 지시선은 balloon 밖에 둬야 같이 끌려가지 않는다
- 띠 면과 balloon을 같은 짝으로 묶어 어느 쪽을 눌러도 둘 다 강조된다

검증: 4개 크기에서 NaN 0건, balloon 11개 중 곡선 겹침 0~1개(이전엔 회피 없음),
도형·클릭 짝·드래그·세션 저장·더블클릭 복귀 확인.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-02 17:00:05 +09:00
eomsangdonandClaude Opus 5 bc877b832a feat(B06): 유토곡선 운반 블록을 장비 경계현으로 띠 분할 + 도면 정합 5건
참고 도면의 토량배분도는 블록마다 수평선이 여러 개(A-A' 기선 / B-B' / C-C')이고
그 사이 띠마다 번호가 붙어 종단면 해칭 구간과 1:1로 대응한다. 하단 브래킷의 폭이
각 수평선의 길이와 같다. 즉 수평선 높이는 그 현의 길이가 장비 경계거리와 같아지는
높이이고, 세로축이 곧 토량이므로 두 수평선 사이 띠 두께가 그 장비의 운반토량이다.

블록 하나에 평균운반거리 하나 / 장비 하나이던 모델을 띠(HaulBand) 여럿으로 바꿨다.

경계 탐색이 단조가 아니라는 것을 무작위 검증이 잡았다. 가지치기로 블록을 하나로
묶어도 원래 폴리라인에 잔요철이 남아 높이를 올리는 도중 현이 잠깐 다시 길어진다.
순수 이분법은 엉뚱한 근으로 수렴했다(종무대 경계현 45m). 훑기 64칸 + 이분법 24회
2단계로 바꿔, 현이 상한을 넘는 가장 높은 자리 위를 경계로 잡는다.

- 장비 경계 dozer 50 -> 70m (사용자 확정, 정의처는 config 한 곳 유지)
- balloon 도형 = 운반수단: 종무대 육각 / 도쟈 원 / 덤프 사각, 사토는 언더바만
- 띠 면 클릭 시 balloon 강조, 다른 띠·빈 곳 클릭 시 해제
- 선타입: 기선 실선 / 경계현 파선 / 평균운반거리 점선 + 방향 화살촉
- 유토곡선 0선을 파선에서 실선으로 (파선은 경계현의 몫)
- 암 경계선 오프셋 상한 0 (양수면 경계선이 지표면 위로 떠 토사층이 음수가 된다)
- 종단도 구조물 라벨을 플롯 하단으로 옮기고 맨 마지막에 그려 가리지 않게
- 암 경계선 제어를 그래프 하단 행 가운데로

검증: 수동 4종 + 실측 26측점 + 무작위 100건에서 띠 합=Q, 띠 연속성, 경계현<=상한,
안분합, 보존 성립. 렌더 스모크 4개 크기 NaN 0건 + 도형·클릭 강조 확인.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-02 16:42:10 +09:00
eomsangdonandClaude Opus 5 ac4e22f623 feat(B06): 유토곡선 토량 분배(평형선·운반 블록·평균운반거리) 엔진
누가토량 곡선은 "얼마가 남는가"만 말한다. 어디 흙을 어디로 얼마나 옮기는지를
뽑아내는 계층을 얹었다 — 평형선, 운반 블록, 운반토량 Q, 평균운반거리 L,
EA/RR/BR 안분, 장비 선정.

작도 규칙 근거는 clouds-daily.tistory.com/249 와 교과서 표준 작도법이다
(참고 도면 3공구의 수치·작도는 근거로 삼지 않았다).

평형선을 0선 하나로 고정하면 임도처럼 절토가 우세한 노선에서 사토가 전부
종점 한 덩어리로 몰린다. 그래서 곡선을 왼쪽부터 훑으며 커서를 옮기고, 성토가
절토를 다 못 받는 자리에서 평형선을 계단으로 옮긴다. 구간이 겹치지도 비지도
않고 단차의 합이 최종 누가토량과 정확히 맞는다.

- 신규 _UI_MassHaul_Balance.ts: computeHaulPlan() 순수 계산기
- 신규 _UI_MassHaul_Balance_View.ts: 계단형 평형선 + 반종거 수평선 + 육각 balloon
- MassHaulPoint에 cut_rr_m3/cut_br_m3 추가 (블록별 암종 안분 입력)
- EARTHWORK_HAUL_EQUIPMENT_LIMITS_M을 context 응답으로 노출 (프론트 사본 없음)
- massHaulPayload에 haul_plan 직렬화 (B08 인계)

검증: 수동 6종 + 무작위 100건에서 보존·안분합·L 범위·구간 무결성 성립.
렌더 스모크 4개 크기 NaN 0건. 영구저장소 프로젝트(26측점) 실측 시 블록 6개,
토취 75.4㎥가 최종 누가토량 -75.4㎥와 일치.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-02 16:12:07 +09:00
eomsangdonandClaude Opus 5 dcf5da8ba7 fix(B06): 라이트 테마에서 RR 면적이 안 보이던 색상 문제
RR이 --color-slate를 쓰고 있었는데, 이 토큰은 --color-text-secondary의 실체라
라이트 테마에서 표 글자가 비활성처럼 읽히고 28% 밴드가 흰 배경에 묻혔다.
RR을 --color-success로 옮긴다(--color-warning은 암 경계선 점선이 선점).

암반 밴드는 하나인데 표는 RR/BR로 갈려 있어 색이 어긋났다. 밴드 그룹에
암종 변형 클래스(--cut_rr / --cut_br)를 실어 표 글자색과 짝을 맞춘다.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-02 15:31:35 +09:00
eomsangdonandClaude Opus 5 c29c2098fb fix(B06): 상단 패널 접기를 B05 방식으로 맞추고 진입 시 자동 측점 선택 제거
- 손잡이가 안 보이던 원인은 패널의 overflow: hidden이었다. .b06-section__panel이
  .b06-cross-card와 한 규칙으로 묶여 있어 함께 받고 있었고, 손잡이를 패널 경계 밖으로
  내보내자 그대로 잘렸다. 패널을 그룹에서 떼어 자체 규칙으로 분리하고 overflow를 걸지 않는다.
- 접기/펴기에서 전역 ui-collapsible 의존을 끊고 B05처럼 명시한다: .is-collapsed에 height 0을
  걸고 헤더·본문·리사이저만 숨겨 손잡이만 남긴다. 펼칠 때는 다음 프레임에 그린다 —
  그래프 몫을 실측하므로 같은 프레임에 그리면 접혀 있던 0 높이를 읽는다.
- 진입 시 첫 측점을 자동 선택하던 것을 없앤다. 고르지도 않은 카드가 강조되고 유토곡선
  말풍선이 떠 있었다.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-02 15:15:19 +09:00
eomsangdonandClaude Opus 5 2dc75f7449 fix(B06): 선택해도 카드를 다시 만들지 않게, RR 밴드 폴백 불일치 해결
- 선택 반영이 아직 카드 재생성이라 그 카드의 viewBox(휠 줌·팬)가 초기화됐다. 카드 요소에
  applySelection() 핸들을 달아 클래스와 강조 상태만 갈아 끼운다. 재생성을 없애기 위해 면적
  밴드는 선택 여부와 무관하게 항상 깔아 둔다(평소 투명이라 화면 변화는 없다).
- RR 절토를 눌러도 단면이 안 켜지던 원인은 구 데이터 폴백 불일치였다. 표는 분리 필드가 없으면
  절토 전량을 측점 지반유형으로 돌려 RR에 값을 넣는데, 밴드 쪽은 cut_rock_kind가 없으면 곧장
  null을 반환해 암반 밴드를 만들지 않았다. rockKindOf()로 표·밴드·강조 매핑의 폴백 규칙을
  하나로 통일한다.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-02 15:11:06 +09:00
eomsangdonandClaude Opus 5 8a7c88e700 fix(B06): 접기 손잡이를 패널 밖으로 내보내 리사이저 hover가 비치던 문제 해결
손잡이 뒤에 보이던 보라색 바는 리사이저의 hover 색이었다. B05 하단 패널은 손잡이를 패널 밖에
두어 리사이저를 z축으로 덮지만, B06은 손잡이를 패널 안 흐름에 넣고 리사이저를 그 위에 나란히
옮겨 놔서 손잡이를 누르러 가는 길에 hover가 먼저 켜졌다.

B05와 같은 구조로 상하만 뒤집는다: 공용 --bottom 손잡이를 패널 경계 바깥 아래로 내보내고
(border-top 제거, 아래쪽 모서리 둥금) 리사이저는 경계(bottom: 0)로 되돌린다. 패널에는
overflow: hidden이 없어 밖으로 나가도 잘리지 않는다.

손잡이가 흐름 높이를 먹지 않으므로 PANEL_CHROME_PX를 줄이고, 선택 카드 스크롤 여백은 손잡이가
아래로 나온 만큼 더한다.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-02 15:04:06 +09:00
eomsangdonandClaude Opus 5 47c08cde54 fix(B06): 접기 손잡이에 공용 title 클래스를 떼고 자체 토글로 캐럿 중복 제거
전역 규칙 `.ui-collapsible.is-collapsed > .ui-collapsible__title::after`(클래스 3개)가 B06 쪽
무력화 규칙(클래스 2개)보다 특정도가 높아, 접힘 상태에서 캐럿(▸)이 삼각형 아이콘(▼)과 함께
그려졌다. 특정도 싸움을 이어 가는 대신 손잡이에서 `ui-collapsible__title` 클래스를 떼고 토글을
직접 처리한다. 접혔을 때 손잡이가 숨지 않도록 display만 다시 켠다.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-02 14:54:59 +09:00
eomsangdonandClaude Opus 5 cbb40dd7cf fix(B06): 그래프 몫을 실측으로 채우고 가운데 버튼 드래그를 팬으로 분리
- 유토곡선 아래 빈 공간: chartHeights()가 패널높이 − PANEL_CHROME_PX 어림값을 썼는데, 어림값이
  실제 chrome보다 크면 그 차이가 그대로 빈 공간이 됐다. chartWrap.clientHeight를 직접 재서
  몫으로 쓴다. chartWrap 높이는 내용이 아니라 패널에서 정해지므로 되먹임 없이 수렴하며, 화면에
  붙기 전이라 잴 수 없는 첫 렌더만 어림값으로 출발한 뒤 다음 프레임에 한 번 보정한다.
  컨테이너 최소 크기는 건드리지 않았다.
- 팬을 가운데 버튼 전용으로 바꾸고(좌클릭은 선택) 상단 그래프에도 가운데 버튼 팬을 달았다.
  가운데 버튼을 누를 때 브라우저 자동 스크롤이 같이 뜨던 문제는 mousedown/auxclick에서 막는다
  (자동 스크롤은 mousedown 기본동작이라 pointerdown에서는 막히지 않는다).

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-02 14:52:13 +09:00
eomsangdonandClaude Opus 5 b4ee022085 fix(B06): 선택 반영을 두 카드로 좁히고 그래프 세로 스크롤 제거
- 선택이 바뀔 때마다 draw()로 모든 카드를 다시 만들어 카드별 휠 줌·팬이 통째로 초기화됐다.
  이전·현재 선택 카드 두 장만 교체하고 상단 패널만 다시 그린다. 선택된 카드 안에서 값 칸을
  토글할 때는 원래부터 재렌더가 없다(DOM 클래스만 바뀐다).
- 접기 손잡이에 전역 캐럿(▸)과 삼각형 아이콘(▼)이 겹쳐 보이던 문제: 같은 특정도로 지우려 해
  로드 순서에서 밀렸다. 자식 결합자로 특정도를 올려 지운다.
- 그래프 상자 세로 스크롤 제거: 축소 시 두 그래프를 각자 비율로 줄이다 하한에 걸리면 합이
  배분 몫을 넘었다. 몫을 먼저 잡고 유토곡선 몫을 종단도 하한이 남도록 클램프해 합이 항상
  몫과 같게 했다. 한 축만 auto면 나머지 축도 auto로 올라가므로 overflow-y: hidden도 건다.
- 패널 위 휠은 끝에 닿아도 기본 동작을 넘기지 않는다(아래 횡단도 목록이 대신 스크롤되던 현상).
  범례 줄이 먼저 먹지 않도록 캡처 단계에서 잡는다.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-02 14:45:36 +09:00
eomsangdonandClaude Opus 5 24843c7143 fix(B06): 0값 칸도 선택 가능, 성토 경계는 첫 교차까지, 접기 손잡이 치수 교정
- 면적표의 모든 칸을 버튼으로 만든다. 예전에는 그 측점의 암종과 맞지 않는 칸(값 0)을 막아
  칸마다 눌리는 자리가 달라졌다. 강조 키를 cut_rock 하나에서 cut_rr/cut_br 둘로 갈라, 표는
  늘 따로 서되 그림의 암반 밴드는 암종이 맞는 쪽을 눌렀을 때만 켜진다.
- 성토 밴드는 중심선에서 바깥으로 나가다 지면과 처음 만나는 곳까지만 유효하다. 그 너머에서
  지면이 다시 설계선 아래로 내려가 생기던 조각을 버린다(좌·우 각각 안쪽 조각만 유지).
- 접기 손잡이 치수를 좌측 사이드 손잡이(24×64, 오른쪽 모서리 둥금)의 시계방향 90° 회전값인
  64×24 · 아래쪽 모서리 둥금으로 교정한다. 리사이저 위치와 패널 여유 높이도 함께 맞췄다.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-02 14:36:35 +09:00