Commit Graph
20 Commits
Author SHA1 Message Date
eomsangdonandClaude Fable 5 8812657022 feat(B05/B02): 표시 정보 정비 + 설계속도 축 도입
- 종단 상단 표시줄을 법정 판정 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 19:46:03 +09:00
eomsangdonandClaude Fable 5 0cb772a351 feat(B05): 기슭막이 보호공 삭제·바닥막이 부활·지형 기준 즉시 반영
- 기슭막이는 기슭(사면)을 막는 공정이라 그 아래 돌붙임이 붙을 자리가 아니다
  (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>
2026-08-19 19:12:37 +09:00
eomsangdonandClaude Fable 5 0b1a66b8d1 feat(B05/B06): 입력 흐름·알약 번호·초기화 모달·전후 분할·표시 반폭 정비
- 위치 마지막 칸 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>
2026-08-19 18:56:06 +09:00
eomsangdonandClaude Fable 5 2745168888 feat(B05): C군 기본값·마커 민감도·3D 우클릭 배치·메뉴 단일화·3D 스냅·측점선 연장
- 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>
2026-08-19 18:32:55 +09:00
eomsangdonandClaude Opus 5 3c05052418 feat(B05): 사이드 패널 입력 로직·레이아웃 개편 (PLAN 2-1~2-5)
- 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 18:30:18 +09:00
eomsangdonandClaude Opus 5 a9c46b9711 feat(B05): 배수 추천 구조물·관경 자동 설정 + 물넘이·세월교 개략 단면
지시 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>
2026-08-17 19:18:28 +09:00
eomsangdonandClaude Opus 5 d8aa525bb8 refactor(B05): 700줄 초과 잔여 2파일 분리 — Page·Profile_Panel
앞 커밋에서 남긴 두 파일을 마저 갈랐다. 상태를 모듈로 옮기면 나머지 참조가 전부
바뀌므로 상태는 제자리에 두고 **접근자만 넘기는** 방식으로 동작·공개 인터페이스를
보존했다.

- 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>
2026-08-17 18:51:21 +09:00
eomsangdonandClaude Opus 5 77f833bb25 feat(B05): 보호공 개편·종단 기준 기본 접힘·700줄 파일 분리 3건
지시 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>
2026-08-17 18:19:46 +09:00
eomsangdon 3e9be53e7c auto: 2026-08-17 17:09 (ESD_LAPTOP) 2026-08-17 17:09:05 +09:00
eomsangdon 38ea71e15b refactor(B05): 배관 편집을 구조물 배치 폼으로 단일화 — 별도 시설 폼 폐지
- 자동 배관·수동 배관은 같은 구조물(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 통과
2026-08-17 15:02:45 +09:00
eomsangdon 1e4da21dbc feat(B05): 부속 옵션 폼을 사이드 구조물 배치 섹션으로 이동
- 구조물 수정은 사이드 패널이 정위치(2026-08-17 사용자 지시) — 시설 편집 폼
  DOM을 배수유역 패널에서 분리(DrainagePanel.facilityForm)해 구조물 배치
  섹션 목록 위에 마운트(mountFacilityForm). 데이터·정본 동기화는 배수유역
  패널 소유 유지, 위치만 이동
- 전역 선택 동기화(97dd7cb9)와 결합: 리스트·그래프·3D·배수유역도 어느
  경로든 사이드에서 폼 개방. A군 [추가] 시 자동 선택으로 즉시 폼 개방
- 사이드 폭 대응 CSS flex-wrap. typecheck/build 통과
2026-08-17 14:50:21 +09:00
eomsangdon 97dd7cb968 feat(B05): 구조물 전역 선택 동기화 — 어느 화면에서 골라도 부속 옵션 폼 개방
- 갭: 배관 부속 폼(시설 편집)이 배수유역도 마커 직접 클릭에서만 열림 —
  리스트·종단 그래프·3D·유역 클릭은 강조만 되고 폼 미개방 (2026-08-17 확인)
- DrainagePanel.selectPipeAtChainage 신설: 밖에서 관 선택 시 마커+폼+유역
  강조까지 (같으면 무시). onPipeSelected 콜백: 유역 없는 관도 전 화면 전파,
  같은 값 재알림 억제(재계산 후 선택 풀림 방지)
- SelectionSync.selectPipeForm 포트: 그래프·3D(syncIrregularSelection)·유역
  (selectStationOfPipe) 경로에서 폼 개방. 리스트(onPipeFacilitySelect) 배선
- 재진입은 기존 selectionSyncing 가드 차단. typecheck/build 통과
2026-08-17 14:27:56 +09:00
eomsangdonandClaude Opus 5 2028af6152 feat(B05): 구조물 컨테이너 병합 3단계 — 섹션 통합·측점 두 칸 입력·구 UI 폐기
사용자 화면 피드백 3건(2026-08-17) 반영 + PLAN 3단계(이관·폐기).

- 「구조물 배치」 단일 섹션: 구 비정규 측점 섹션을 흡수·삭제하고 「구조물
  추가」를 개칭. 위치 입력은 측점번호+잔여거리 두 칸(구 비정규 UI 방식),
  순서 = 시작 측점 → 기준 측점 → 종료 측점(점형은 기준만, 비우면 시작).
- A그룹 제어 통합: A군 종류 목록에 계곡 통과 시설(배관/BOX암거/물넘이/세월교)
  표시 — 추가는 관 지점 정본 경유(onPipeAdd, 시설 종류 = type_id), 목록에
  "배수유역 연동"으로 병합 표시·선택 동기화·삭제. 노출형 횡단수로·개거는
  수동 구조물.
- 그래프 측점 표현: 서클마크 툴팁·벌룬 위치를 누가거리에서 측점번호+잔여
  거리 표기로 변경(mountStructureMarks에 측점간격 주입).
- 구 비정규 측점 이관: POST /route/structures/migrate 신설 — 기존 Migration
  매핑(배관 제외·기성막이→기슭막이·대피로→대피소) 사용, 정본 기존 (타입,
  기준점) 점유 검사로 멱등. Page 진입 시 구 확정분을 자동 이관하고 건수를
  토스트로 알린다. TDD 라우터 테스트 4건.
- 구 UI 폐기: onIrregularChange/Select 콜백 제거, 배관 투영은 Page의
  pipesToStations()가 직접 생성(시설 종류별 라벨). 그래프 측점선 드래그·
  삭제는 배관 전용으로 단일화, 구 우클릭 항목은 레지스트리 타입으로 매핑.
  drainage addPipe(chainage, facility?) 확장 — 통합 목록에서 시설 종류를
  지정해 추가하면 재계산 요청에 실려 정본까지 간다.

tmp/tests 92건·ruff·typecheck·build 통과.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-17 09:28:07 +09:00
eomsangdonandClaude Fable 5 84eb027348 fix(B05): 크로스체크 2차 4건 반영 — 우클릭 추가 실패·미협의 기본값·STALE 통지
교차검증 2차에서 재현된 실제 실패를 수정한다.

1. 우클릭 구조물 추가가 대부분 저장 거절되던 문제
   - 메뉴가 레지스트리 앞 12개를 그대로 노출해 배관(별도 정본)과 필수 제원이
     있는 C군이 섞였고, addAt()이 값 없이 즉시 저장해 서버가 거절했다.
     실패 항목은 structure_id 없이 화면에 남아 수정·삭제도 막혔다.
   - 메뉴는 managed_by 없고 required 옵션 없는 타입만 노출한다.
   - 필수 입력 타입은 저장 대신 측점을 채운 사이드 폼을 열고 첫 필수 칸에
     포커스를 준다.
   - 저장이 실패하거나 충돌하면 서버 정본을 다시 받아 화면을 되돌린다.

2. 미협의 선택값이 기본값으로 자동 저장되던 문제
   - 재료·형식 선택형 18건의 default를 없애고 required로 바꿨다.
     화면 select에는 "선택하세요" 빈 항목을 두고, defaultOptions()가 첫
     선택지를 대신 채우던 동작을 없앴다.
   - 남긴 default는 법정 단일값, 사용자 확정값(골막이), 표시용 문자열뿐이다.

3. STALE 갱신 실패를 사용자가 알 수 없던 문제
   - 응답에 needs_downstream_invalidation을 추가해 "되돌려야 했는가"와
     "되돌렸는가"를 구분한다. 어긋나면 화면이 B06 재실행을 안내한다.

4. 회귀 방지: 레지스트리 정책 테스트 신설(우클릭 목록 구성·기본값 원칙).

pytest 49건 통과 · tsc 0 · ruff 통과 · npm run build 성공.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-16 23:13:19 +09:00
eomsangdonandClaude Fable 5 61108f540d feat(B05): 구조물 수동 추가 프론트 — 패널·종단도 서클마크·벌룬·정본 연동
구조물군 B~G 전체를 화면에서 수동 배치할 수 있게 한다. 타입 목록·옵션 폼은
서버 레지스트리(GET /structure-types)에서 받아 그리므로 구조물이 늘어도
프론트 코드는 그대로다.

- B05_Profile_Api_Structures.ts: 레지스트리·정본 CRUD 클라이언트.
  409(판번호 충돌)를 전용 오류로 구분, 구간형 기점 앵커 헬퍼.
- B05_Profile_UI_Structures_Panel.ts: 사이드바 「구조물 추가」 섹션.
  구조물군→종류→위치(점형/구간형)·설치측·이격·옵션 동적 폼·메모.
- B05_Profile_UI_Structures_Marks.ts: 종단 그래프 서클마크 오버레이.
  전 배치형태 = 마크 하나(구간형은 기점), 선택 시 벌룬 + 구간 띠 확장
  (2026-08-16 사용자 확정 표기 규칙). 드래그 이동·겹침 스택.
- B05_Profile_UI_Style_Structures.css: 마크·띠·벌룬 스타일.
- Profile_Panel: 마크 레이어 장착·타입 주입·선택 동기화 API 추가.
  우클릭 메뉴(Profile_Structures)에 레지스트리 타입 추가 항목.
- Page: 진입 시 타입·정본 로드, 변경 즉시 정본 저장(직렬화 큐),
  409 시 최신본 재적재 안내, 그래프↔사이드 선택 양방향 동기화.
  정본 주입은 onChange를 울리지 않아 저장 루프를 차단.

tsc --noEmit 통과. 기존 배관·배수유역·종단 편집 흐름은 손대지 않았다.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-16 22:30:36 +09:00
eomsangdonandClaude Opus 5 431791c257 feat(B03,B05,B06): 초기 계산 끝까지 업로드 잠금 + 자료 없으면 대시보드로 (결함 3·6 화면측)
업로드 잠금(결함 3)
- 종전에는 전처리(B04)만 끝나면 버튼이 풀려, 노선·횡단이 도는 동안 자료를 또 올릴 수
  있었다. isInitialPipelineRunning()/pollInitialPipeline()을 두어 **횡단 단계가 열릴
  때까지**(3단계가 NOT_STARTED를 벗어날 때까지) 잠근다.
- relockWhileInitialPipelineRuns(): 새로고침·재진입해도 계산이 도는 중이면 다시 잠그고
  스피너를 붙인다. 잠금이 화면 상태로만 있으면 새로고침 한 번에 풀렸다.
- 보관함 연결 경로도 같은 대기 흐름을 탄다.

자료 없으면 대시보드(결함 6)
- b_missing_data_guard 신설 — 근거 자료가 없으면 한 줄 안내 후 B01로 보낸다. 새 자료가
  올라오면 서버가 옛 산출물을 지우므로, 열어 둔 뒷단계 화면은 빈 화면이 아니라
  대시보드로 나가야 한다(2026-08-08 사용자 지시).
- B05: 확정 지표면이 없으면 이동. B06: 노선 또는 종단면이 없으면 이동.

검증: 자료가 없는 신규 프로젝트로 B05 진입 → 안내 후 #/b01-account 로 이동함을
헤드리스 크롬으로 확인. typecheck·prettier 통과, 정적 번들 재빌드.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-08 19:50:27 +09:00
eomsangdonandClaude Opus 5 d9f6fbdff1 fix(B05): 유령 마커가 계속 뜨던 이유 — 화면이 표고 null을 0으로 눕히고 있었다
앞 커밋(53ab941)에서 "표고 없는 점은 안 그린다"를 넣었는데도 그대로 보였다.
restorePoints -> placed()가 마커에 넘기기 전에 z: point.z ?? 0으로 바꿔, 마커 쪽에서는
표고를 아는 점(0m)으로 보였기 때문이다. 판정이 걸릴 자리가 없었다.

- PlacedRoutePoint.z를 number | null로 바꿔 "모름"을 모름 그대로 들고 다닌다.
- placed()는 z ?? null, 서버로 보낼 때(routePoint)만 null -> undefined로 바꾼다.
- modelToScene은 표고가 정해진 점만 받는다(z: number) — 호출부에서 이미 해결한 값을 준다.

typecheck·prettier 통과. 백엔드가 정적으로 서빙하는 번들(config/node_modules/.build)도
다시 빌드했다 — :8000으로 보면 서버 기동 때 만든 옛 번들이 떠서 수정이 반영되지 않는다.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-08 18:21:22 +09:00
eomsangdonandClaude Fable 5 ffccb846eb chore: 리팩토링 마감 — 포맷터 적용·내부 라벨 정리·계획서 체크리스트 완료 표시
- prettier 적용(편집 파일 14종), ruff format 무변경 확인
- B03 내부 백그라운드 태스크 라벨 b04-wf1-auto -> b04-preprocess-auto
- docs/raw/PLAN.md R1 체크리스트 Phase 1~7 완료 표시 (검증 대기 상태로 전환)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-08 10:35:26 +09:00
eomsangdonandClaude Fable 5 98df22f789 feat(B05,B06): 워크플로우 재정의 — 자동 계산 노란 상태·버튼 개편·초기화
자동 체인 상태 전이 분리:
- confirm_latest_route/confirm_sections에 mark_stage_complete 플래그 추가
- 자동 체인(신규·재확정)은 데이터만 확정하고 stage 2·3을 IN_PROGRESS로 남김
  (스텝바 기존 노란 테두리 = 계산됨·확정 전 상태로 재사용)
- B06 [확정]이 stage 2+3 동시 완료 + 경로 상태 CONFIRMED 보강 후 B07 수량 이동

B05 좌측 패널 개편:
- 포인트 팔레트 + 임도 기준·옵션을 경로 계산 설정 한 컨테이너로 병합,
  [최적 경로 계산] 버튼을 컨테이너 내부로 이동 (가끔 쓰는 무거운 재계산)
- 하단 액션 행 [초기화][임시저장][횡단 이동]으로 교체, 경로 단독 확정 폐지
- [임시저장] = 관로 + 계획선 델타 + 비정규 측점·상단측 저장(mark_stage_complete=false)
- [횡단 이동]/B06 [종단 이동] = 저장 없이 페이지 이동만 (B05·B06 캐시 공유 구조 유지)
- [초기화] = POST /route/reset 신설: 기존 경로 삭제 후 계획노선 CSV 기본값으로
  자동 체인 재실행(파일입력 직후 상태 복원), 분석용 타임아웃 적용

B06 액션 행: [종단 이동][임시저장][확정] 3버튼 구성, locale 키 정비

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-08 10:26:45 +09:00
eomsangdonandClaude Fable 5 54954a05e5 refactor(B05,B06): B05_wf2_Route -> B05_Profile, B06_wf3_ProfileCross -> B06_Section 동시 개명
- 한몸으로 동작하는 두 페이지라 한 커밋으로 처리 (상호 참조 다수)
- B05 37파일 + B06 20파일 접두사 개명 (git mv, 이력 보존)
- 참조 치환 91파일: import 경로, 라우트 슬러그(b05-profile/b06-section),
  라우트 키(B05_PROFILE/B06_SECTION), B03 자동 체인, storage 상수, pyproject 제외 경로
- 로직 변경 없음. typecheck·백엔드 import 검증 통과

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-08 10:03:11 +09:00