Files
Aislo/docs/raw/plans/2026-08-17_plan_B05_box_ui_recommendations.md
T
eomsangdonandClaude Opus 5 eb30b774f8 chore(docs): docs 폴더 git 추적 전환 · PLAN·OWNERS 최상위 이관
- `docs/` 를 .gitignore 에서 빼 git 추적 대상으로 전환 (위키·완료 이력·검증 기록)
- `docs/raw/PLAN.md` · `docs/raw/OWNERS.md` 를 저장소 최상위로 이동 후 .gitignore 에 등록
  — 창끼리 공유하되 저장소에는 안 올리는 장부
- 살아 있는 경로 참조 7개 파일 정정 (아카이브 107건은 그때 사실이라 그대로 둠)
- graphify 날짜별 산출물(`docs/wiki/graphify-out/20*/`) 제외 — `graphify update` 가 다시 만듦

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-09 18:19:07 +09:00

31 KiB
Raw Blame History

Completed plan archive - B05 box culvert, protection UI, and drainage recommendations

  • Archive date: 2026-08-17
  • Completion evidence: the live plan records self-verification, including Python tests, typecheck, build, formatting, and screen checks where applicable
  • Verification record: docs/raw/verification/2026-08-17_verify_B05_box_ui_recommendations_external.md preserves the user-confirmed external AI validation; this wiki session did not rerun secondary cross-verification
  • Pending preservation: unfinished B05/B06 items are retained in docs/raw/PLAN.md rather than archived as complete

2. B05 BOX암거 본체 규격·날개벽 기본값 (2026-08-17 착수)

배경: 구조물 배치 폼의 BOX암거 옵션이 전부 빈칸이라 사용자가 매번 제원을 직접 적어야 한다. 실무 관측값(본체 2.0×2.0·3.0×3.0)을 프리셋으로 굳히고, 날개벽은 기본 제원을 프리필한다.

사용자 확정값 (2026-08-17):

  • 본체 규격: 프리셋 2.0×2.0(기본) / 3.0×3.0, 필요 시 사용자 지정으로 폭·높이 직접 입력. 자유 입력 칸은 사용자 지정을 골랐을 때만 노출.
  • 날개벽(유입·유출 각각): 설치 있음, 짧은쪽 높이 1m, 길이 2m, 각도 45°.
  • 우클릭 빠른 추가 시에도 위 기본값을 관 지점 옵션에 함께 저장 (BOX암거 한정 — 배관·물넘이·세월교는 현행 유지).

설계 판단: 규격 프리셋은 저장 키를 신설하지 않는다 — 저장은 기존 body_width_m/body_height_m 숫자 그대로이고 프리셋 select는 UI 전용이다. 로드 시 저장값이 프리셋과 일치하면 해당 프리셋을, 아니면 사용자 지정을 고른다. 하류(B06 횡단도·수량)가 폭·높이만 읽으면 되도록 유지하기 위함.

구현 체크리스트 (구현 완료 2026-08-17 — 외부 AI 크로스체크 대기):

  • 레지스트리 정본 B05_Profile/B05_Profile_Structure_Types.json — box_culvert 옵션 10건에 사용자 확정 기본값 등재: body_width_m·body_height_m = 2.0, wing_in·wing_out = "있음", wing_*_height_m = 1, wing_*_length_m = 2, wing_*_angle_deg = 45. 동시에 required: true 해제 및 phase: "detail" 제거 — 이 값들은 실제로 B05 서브폼이 받고 있어 현행 detail 표기가 정본과 불일치였다. comment의 기본값 화이트리스트 근거에 "2026-08-17 사용자 확정" 추가.
    • 검증: pytest tmp/tests/test_b05_structures_registry_policy.py -q → 15 passed. test_only_confirmed_values_keep_defaults(화이트리스트), 신규 test_box_culvert_body_size_defaults_to_first_preset가 기본값 2.0·phase b05· 비필수를 직접 단언한다.
    • 계획 대비 차이: 계획서에 "옵션 8건"이라 적었으나 실제 대상은 10건이다 (본체 2 + 날개벽 유입 4 + 유출 4). 기본값을 붙인 개수만 오기였고 대상 키 목록·값은 계획과 같다.
  • 폼 B05_Profile/B05_Profile_UI_Drainage_Facility.ts (BOX암거 블록) — 본체 규격 select 신설(2.0×2.0/3.0×3.0/사용자 지정, 기본 첫 항목), 기존 폭·높이 숫자칸은 사용자 지정일 때만 노출. 날개벽 설치 기본 있음 + 높이/길이/각도 프리필, 설치 없음이면 3칸 숨김(기슭막이 돌붙임과 같은 패턴). setFacility 빈값 폴백을 기본값으로 — 빈 문자열 대입으로 select가 selectedIndex = -1(공백 표시)되던 문제도 함께 해소.
    • 검증: npm run typecheck 무오류, prettier --write 변경 없음(이미 정합). 저장 경로는 readOptions()가 boxWidth/boxHeight 두 칸만 읽고, syncBoxSize()가 프리셋 선택 시 그 두 칸을 프리셋 값으로 채우므로 프리셋· 사용자 지정 어느 쪽이든 body_width_m/body_height_m로만 저장된다(코드 대조).
    • 계획 대비 차이: 유입·유출 날개벽이 완전히 같은 구조라 계획에 없던 createWingFields 팩토리로 묶었다(기존 createRevetmentFields와 같은 패턴). 중복 8줄×2를 없애기 위한 것으로 동작·저장 키는 계획과 동일하다. 이에 따라 putNumber 헬퍼를 폼 함수 안에서 모듈 스코프로 올렸다(시그니처·동작 동일).
  • 빠른 추가 B05_Profile/B05_Profile_UI_Structures_Panel.ts (addAt) — onPipeAdd에 options: defaultOptions(type) 동봉, BOX암거 한정.
    • 검증: npm run typecheck 무오류.
    • ⚠ 계획 대비 중요 차이 — 이 경로는 현재 UI에서 도달하지 않는다: 종단 우클릭 메뉴는 B05_Profile_UI_Profile_Panel.ts:882-887에서 !type.managed_by 조건으로 계곡 통과 시설을 아예 제외한다(정책 테스트 test_quick_add_types_exclude_pipe_family도 이를 못박음). 즉 BOX암거를 넣는 실제 경로는 구조물 배치 폼의 [추가](commit() → readOptions() → onPipeAdd)뿐이고, 폼이 기본값을 프리필하므로 "추가 시 기본값 저장"이라는 사용자 확정 요구는 이 경로로 이미 충족된다. addAt 쪽 변경은 공개 API (StructuresSection.addAt)가 managed_by 분기를 갖고 있어 넣어 둔 방어선이다.
  • 정책 테스트 tmp/tests/test_b05_structures_registry_policy.py — ALLOWED_DEFAULT_KEYS에 box_culvert 10키 추가(근거 주석 포함), test_box_culvert_wing_wall_options_defined를 새 스펙으로 재작성, 본체 규격 전용 test_box_culvert_body_size_defaults_to_first_preset 신설 (프리셋 전용 저장 키 body_size가 생기지 않았는지도 단언).
    • 검증: 해당 파일 15 passed. 전체 pytest tmp/tests/ -q → 101 passed, 7 skipped(회귀 없음). test_required_options_moved_to_detail_phase(≥18)는 예상대로 무영향 — detail+required 39건 중 box_culvert 8건이 빠져 31건.
    • ruff format 변경 없음.

⚠ 자체검증에서 발견한 미해결 사항 (700줄 제한):

B05_Profile_UI_Structures_Panel.ts가 753줄로 700줄 제한을 넘는다. 다만 이는 이번 작업 이전부터의 위반이다 — HEAD 시점 748줄이었고 이번 변경은 +5줄이다. 분리는 별도 계획이 필요한 리팩터링이라 승인 범위 밖으로 두고 아래 미결에 올린다. B05_Profile_UI_Drainage_Facility.ts는 583 → 689줄로 한도 안이지만 여유가 11줄뿐이라 다음 BOX암거·구조물 옵션 작업 때 분리가 선행되어야 한다.

범위 밖: 날개벽 각도 상한(90°) 검증, 바닥 2면 산식, B06 이관 항목, 배관·물넘이·세월교의 빠른 추가 기본값.


3. B05 사이드 접힘·보호공 UI 개편·700줄 리팩터링 (2026-08-17 착수)

사용자 지시 5건 (2026-08-17). 2·3번은 확인 요청이라 조사 결과를 아래 「확인 결과」에 남기고, 1·4·5번이 코드 작업이다.

확인 결과 ① 세월교·물넘이 설계기준 (지시 2번 — 지식DB 있음)

정본: technical_info/01_임도/02_상세설계/개거_세월시설.md §3·§4.

시설 법정(별표2) 실무(교본 3장)
물넘이포장 소계류 통과 시 배수구·암거보다우선 권장. 수리계산 적정 배수단면 + 차량통과 반경 설치 구간 종단 3~5%, 계곡부 횡단경사30% 이내(초과 시 관 매설), 물받이 길이 = 낙차 H의 2배 이상, 물받이 두께 30㎝ 이상, 구체 길이는 홍수흔적법, 계획단면은 종단곡선과 일치
세월교 물넘이포장과 같은 조항(택일) 하천·3차수 이상 계곡, 계곡부 종단 3~5%, 상시 유수 시 구체에 원형 배수관 검토, 진입·진출부 뚝(유목·토사 막힘 대비)

→ 두 시설 모두 기준이 지식DB에 정리돼 있다. 다만 B05 폼에서 받는 값은 세월교의 관종·관경·수량(련)뿐이고 물넘이포장은 옵션이 없다. 물받이 길이·두께, 구체 길이, 진입·진출부 뚝은 전부 B06/B07 상세 몫 — 이번 범위 밖.

확인 결과 ② 유효직경 계산식 대조 (지시 3번 — ⚠ 불일치 4건)

코드 common_util/common_util_drainage_detail.py:574-620 size_pipe() ↔ 지식DB 03_계산정보/설계유량.md·통수단면.md 대조.

단계 코드 지식DB 판정
합리식 Q = C·I·A[km²]/3.6 Q = 0.2778·C·I·A (동일식) ✅ 일치
설계유량 배수 2.0 별표2 최대홍수유출량의 2.0배 이상 ✅ 일치
도달시간 하한 5분 KDS 2023 최소 5분 ✅ 일치
Manning V = (1/n)(D/4)^(2/3)√S (만관 R=D/4) 통수단면 §5 [구현] "만관 기준이 실무 통례" ✅ 일치(단 §4 경제단면H=0.94D 채택 여부는 협의 미완)
강우강도 I General형 IDF 적합식 한국확률강우량도 IDF·WAMIS ✅ 방식 일치
도달시간 식 Kirpich tc=0.0663·L^0.77·S^-0.385 KDS 원문에 세부 산정식없음. 실무 관측은 Kerby (종합비교 02) ⚠ 식 자체 근거 미확인
유출계수 C 0.8 고정 KDS 표 2.6-1: 가파른 산지 0.8 /수림 0.3 — 임도 유역 분류가 미결 No.7(유량 2배 차) ⚠ 미결값을 코드가 0.8로 확정
조도계수 n 0.024 (파형강관) KDS 표에파형강관 항목 자체가 없음(공백 확정). 실무 관측 파형강관 0.025 ⚠ 0.024는 지식DB 어디에도 없는 값
유효 통수비율 0.7 (→ A=0.550D²) 통수단면.md에 없음. 실무 관측은240° 유효 0.63185D²(울진1·소광) 또는 만관 0.785D²(울진2) ⚠ 세 값이 다 다름
관 경사 S tan(10°) 고정 별표2·교본에 관 경사 규정 없음 ⚠ 지식DB 근거 없음(사용자 제시 대푯값)
유속 클램프 0.8~3.0 m/s 통수단면.md에 유속 허용범위 없음(출처 "도로배수지침"은 지식DB 미수록) ⚠ 지식DB 미수록

결론: 뼈대(합리식·2.0배·Manning 만관)는 지식DB와 일치하나, 계수 4건(C·n· 유효비율·도달시간식)이 지식DB 근거 없이 코드에만 확정돼 있다. 값 자체가 틀렸다는 뜻은 아니고 config_system.py:366-387 주석의 출처(도로설계요령·도로배수지침· 2026-08-05 조사문서)가 기술정보DB로 승격되지 않은 상태다. 조정은 이번 UI 작업 범위 밖 — 아래 미결에 올린다.

구현 체크리스트

  • 3-1. 종단 설계 기준 컨테이너 기본 접힘 (지시 1번) B05_Profile/B05_Profile_UI_Panel.ts:91-102의 section()에 collapsed 인자를 더하고 section("종단 설계 기준", true)로 호출(299행). 초기 is-collapsed 클래스만 붙이는 방식 — 토글은 ui_template/ui_template_collapsible.ts 전역 핸들러가 이미 맡는다(B06 buildGroup(legend, collapsed)와 같은 패턴).

    • 검증: npm run typecheck·npm run build 통과. 다른 사이드 섹션은 section(title)을 인자 없이 부르므로 기본값 false로 종전과 같다(코드 대조).
  • 3-2. 배수관 유입·유출 보호공 개편 (지시 4번) 배경: 도수로·산비탈수로(B4)는 유출구에서 돌붙임 대신 쓸 수 있는 공종이므로 별도 구조물이 아니라 보호공 선택지의 한 항목으로 받는다(2026-08-17 사용자).

    • 제목 돌붙임 → 보호공
    • 선택지 있음/없음 → 돌붙임(찰) / 돌붙임(메) / 도수로. "없음"은 삭제 — 물이 흐르는 자리라 보호공이 무조건 있다(사용자 확정).
    • 돌붙임 표면처리(찰/메) 칸 삭제 — 선택지에 흡수됐다.
    • 치수 칸은 선택지에 따라 갈아 끼운다: 돌붙임 → 면적 (㎡), 도수로 → 폭 (m).
    • 기본값: 유입 돌붙임(찰) / 유출 돌붙임(메)(부위별 구분 유지 — 기슭막이 "형태"가 유입 찰·유출 메로 갈라 있는 것과 짝), 면적 10㎡, 도수로 폭 1.0m (2026-08-17 사용자 확정 — 실무 확인 후 개선 예정이나 미결로 남기지 않는다).
    • 저장 키 개명(사용자 확정): {inlet,outlet}_pitching → _protection, _pitching_area_m2 → _protection_area_m2, 신규 _protection_width_m, _pitching_finish 삭제. 독립 기슭막이(D4 revetment)도 동일하게 pitching→protection, pitching_area_m2→protection_area_m2, 신규 protection_width_m, pitching_finish 삭제.
    • 구 저장분 마이그레이션: 있음+찰→돌붙임(찰), 있음+메→돌붙임(메), finish 없음→부위 기본값, 없음→부위 기본값(선택지가 사라졌으므로). 적용 지점 = common_util/common_util_drainage_pipes.py의 parse_pipe_points (pipe_points.json 정본) + 폼 write()의 구 키 폴백(structures.json D4 몫).
    • 대상 파일: B05_Profile_UI_Drainage_Facility.ts, B05_Profile_Structure_Types.json, common_util_drainage_pipes.py, 정책 테스트 + 마이그레이션 테스트.
    • 검증: 신규 tmp/tests/test_b05_protection_migration.py 6건 — 있음+찰/메 → 돌붙임(찰)/돌붙임(메) 변환, 구 키 제거, "없음" → 부위 기본값 승격, 표면처리 누락분 폴백, 새 키 우선(재저장분 보호), 무관 옵션 통과. 정책 테스트는 보호공 3지 선택지·"없음" 부재·구 키 부재·기본값(면적 10㎡· 도수로 폭 1m)을 단언하도록 갱신. 전체 pytest tmp/tests/ -q 107 passed, 7 skipped. npm run typecheck·npm run build 통과.
    • 계획 대비 차이: 독립 기슭막이(D4)의 pitching_area_m2는 기본값 10이 있는데도 required: true였다 — 보호공 개편과 함께 required: false로 바로잡았다(기본값과 필수가 동시에 붙어 있던 모순).
  • 3-3. 700줄 초과 파일 분리 (지시 5번) — 5파일 전부 완료 착수 시점 대상이 5개였다(3-2 반영으로 Drainage_Facility.ts가 724줄로 한도를 넘었다). 대부분 순수 이동 + import 정리이고, Page.ts·Profile_Panel.ts는 가변 클로저 상태를 곳곳에서 직접 읽고 써 상태 승격이 필요했다 — 상태 자체는 옮기지 않고 접근자(게터·세터)로 넘겨 동작·공개 인터페이스를 보존했다.

    파일 전 후 분리 결과
    B05_Profile_UI_Drainage_Facility.ts 724 401 입력 조각·기슭막이·날개벽 →_Facility_Fields.ts
    B05_Profile_UI_Structures_Panel.ts 753 695 목록 렌더링·항목 라벨 →_Structures_List.ts
    B05_Profile_UI_Drainage_Panel.ts 822 693 DOM 뼈대 →_Drainage_Chrome.ts, 포인터·휠 조작 → _Drainage_Interact.ts
    B05_Profile_UI_Page.ts 1031 685 순수 도우미 →_Page_Helpers.ts, 구조물·측점 다리 → _Page_Structures.ts
    B05_Profile_UI_Profile_Panel.ts 1152 649 X축 배치 →_Profile_Layout.ts, 높이 배분 → _Profile_Heights.ts, 본문 재구성 → _Profile_Render.ts, 균형 표시줄 → _Profile_Balance.ts
    • 상태 승격 방식(2026-08-17): 상태를 모듈로 옮기면 나머지 참조가 전부 바뀌므로, 대신 접근자만 넘겼다. 예: 포인터 조작 모듈은 배율·오프셋을 getScale()/setScale()로 읽고 쓰고, 본문 렌더러는 그리기 시작 시점의 상태를 한 번 스냅숏하되 이벤트 핸들러 안에서만 현재값을 다시 읽는다. 유일한 예외가 _Page_Structures.ts로, 구조물 정본 상태(비정규 측점 목록· 판번호·저장 큐·타입 사전)는 두 정본을 섞는 지점이라 팩토리 안으로 옮기고 본체는 bridge.irregularStations()로만 읽게 했다.
    • 검증: 분리 단계마다 npm run typecheck, 마무리로 npm run build (374 modules 성공)·pytest tmp/tests/ -q(107 passed·7 skipped)·prettier. 프론트 테스트 러너가 없어(vitest/jest 미설치) 타입체크·빌드·코드 대조가 회귀 판정 기준이다 — 실제 화면 동작 확인은 사용자 몫으로 남는다.
    • 계획 대비 차이: 계획서에는 "4파일"이라 적었으나 3-2 반영으로 Drainage_Facility.ts가 한도를 넘어 5파일이 됐다. Profile_Panel.ts는 한 번 자르면 700줄 정확히 걸려서 균형 표시줄까지 더 떼어 649줄로 낮췄다.

범위 밖: 유효직경 계수 조정(위 확인 결과 ②), 물넘이·세월교 상세 제원(B06/B07), 도수로 재료·단면형 선택지(B4 상세 — B06 이관분).


4. 배수 추천 구조물·관경 자동 설정 + 물넘이·세월교 개략 단면 (2026-08-17 계획)

배경 (2026-08-17 사용자 지시 2건):

  1. 물넘이포장·세월교는 B05에서 사용자가 지정할 옵션이 거의 없다 — 그렇다면 개략값이라도 화면에 보여 줘야 한다.
  2. B05 배수유역도가 유효직경을 표시한 다음 추천 구조물·배관 규격까지 보여 주고, 초기 전처리(자동 배치) 때 그 값으로 설정되어야 한다.

현재 상태: 유역별 유효직경(pipe_diameter_mm, 연속값 ㎜)은 이미 산출·표시되고 2,000㎜ 초과면 "세월교 검토"로 표기된다. 빠진 것은 ① 규격으로 스냅한 추천 관경과 추천 구조물 종류 표시 ② 그 값을 관 지점(pipe_points.json) 옵션에 실제로 싣는 일 ③ 물넘이·세월교의 개략 단면이다.

사용자 확정 (2026-08-17):

  • 판정 근거는 유량(유효직경)만 쓴다. 선정 트리의 계곡 횡단경사(30%·40%)·하천 차수는 현재 계산에 없고 DEM 확장이 필요해 이번 범위에서 뺀다 — 대신 화면에 "현장 확인" 문구를 병기한다.
  • 자동 설정은 관경 + 시설 종류 둘 다. 추천이 BOX암거면 facility까지 바꾸고 본체 규격도 심는다. 사용자는 폼에서 언제든 바꾼다.
  • 물넘이·세월교는 필요 통수단면을 보여 주고 폭 B만 사용자가 입력한다.

추천 임계값 (지식DB 선정 트리 — 개거_세월시설.md §5·횡단배수관_암거 §5):

유효직경 D 추천 근거
D ≤ 1,500㎜ 배관 — 규격 스냅(800·1000·1200·1500) 별표2 Ø1,000↑(현지여건 800↑)
1,500 < D ≤ 2,000㎜ BOX암거 후보 교본 "수리계산 Ø1,500↑ 유역"
D > 2,000㎜ 세월교·물넘이 검토 관 최대 규격(파형강관 D2000) 초과

임계 2,000㎜는 기존 DRAINAGE_BRIDGE_THRESHOLD_MM과 같은 값이라 현행 "세월교 검토" 표기와 어긋나지 않는다. 규격 스냅 대상은 레지스트리 pipe_diameter_mm 선택지 4종이다 — 폼에서 고를 수 없는 값을 추천하지 않기 위함.

물넘이·세월교 개략 단면 산식 (2026-08-17 실무문서 확인으로 근거 확보):

h = (Qd·n / (B·√S))^(3/5)          광폭 직사각형 가정 R ≈ h
Qc = B·h·(1/n)·(A/P)^(2/3)·√S      A = B·h,  P = B + 2h
판정: Qc ≥ Qd 이면 충족, 미만이면 부족(단면 재검토)
  • n = 0.017 — KDS 표 2.7-1 콘크리트 수로 "보통"값이자 실무 물넘이 관측치와 일치 (통수단면.md §3).
  • S = 0.10 (10%) — 실무 수리계산서 관측값. 울진1공구 물넘이 시트 (B=20m·h=0.27m·n=0.017 → V=7.636 m/s)를 역산하면 S=0.0996이고, 같은 공사지 관 시트(Ø1000·240° 유효단면·n=0.025 → V=5.694)도 S=0.10에서 검산이 맞는다 (original/실무문서/_숨김탭분석.md §6-1·§6-2).
  • 폭 B는 사용자 입력이다 — 지식DB에 폭 수치 근거가 없어 프로그램이 지어내지 않는다(교본은 "홍수흔적법·지형 감안" 정성 규정뿐).

⚠ 부수 발견 — 관 경사 단위 혼동 의심: 코드의 DRAINAGE_PIPE_SLOPE_DEG = 10.0은 tan(10°) = 17.6%인데 실무 수리계산서는 10%(= 5.7도)를 쓴다. 다만 유속 상한 3.0 m/s 클램프에 통상 관경이 전부 걸려 관경 결과 차이는 거의 없다. 값 정정은 미결의 "유효직경 계수 4건" 항목에 함께 올려 별도 확정한다 — 이번 범위 밖.

⚠ 계획 산식 정정 (2026-08-17 구현 중 발견): 위 산식의 "판정: Qc ≥ Qd" 는 성립하지 않는다. 광폭 근사 h = (Qd·n/(B·√S))^(3/5)로 얻은 h를 실제 동수반경 (R = A/P < h)으로 되짚으면 통수능이 항상 설계유량에 조금 못 미쳐 판정이 늘 "부족"으로 나온다. 그래서 h를 B·h·V(h) = Qd가 되도록 실제 R로 수렴시키고, 화면은 필요 수심·필요 단면·유속만 보여 준다(충족/부족 판정 삭제).

함께 확인한 것: 실무 시트의 수심 0.27m는 Qd에서 역산한 값이 아니다. B=20·h=0.27의 통수능은 41.2㎥/s로 그 시트 Qd 2.54㎥/s의 16배다 — 실무는 단면을 가정하고 통수능이 설계유량을 넘는지 검증하는 방식이고, 프로그램이 내는 값은 필요 최소 수심이다. 둘은 의미가 다르므로 화면 문구도 "필요 수심"으로 적는다.

구현 체크리스트 (구현 완료 2026-08-17 — 외부 AI 크로스체크 대기):

  • 4-1. 추천 산출(백엔드) common_util/common_util_drainage_detail.py
    • size_pipe() 반환에 required_area_m2(= Qd/V) 추가.
    • WatershedBasin에 recommended_facility(pipe/box_culvert/ford_bridge)와 recommended_diameter_mm(배관일 때만) 추가. 규격 스냅은 config_system.PIPE_DIAMETERS_MM이 아니라 레지스트리 pipe_diameter_mm 선택지 4종을 기준으로 한다.
    • bridge_required는 그대로 둔다(기존 표기 호환) — 추천 필드가 그 상위 개념이다.
    • 계획 대비 차이: 임계값을 코드에 박지 않고 config_system에 DRAINAGE_BOX_THRESHOLD_MM(1500)·DRAINAGE_RECOMMEND_DIAMETERS_MM (800·1000·1200·1500)으로 뺐다. 레지스트리를 직접 읽으면 common_util이 B05 모듈을 임포트해 의존 방향이 뒤집히므로, 대신 두 목록이 어긋나면 깨지는 테스트(test_recommended_sizes_match_registry_choices)로 묶었다.
  • 4-2. 자동 배치 시 옵션 주입 B04_PreProcess/B04_PreProcess_Router_Basins.py
    • _apply_recommendations() 신설 — carry_facility_attributes로 사용자 값을 되붙인 뒤에 추천을 얹는다(순서가 뒤바뀌면 승계값이 덮인다).
    • 덮어쓰지 않는 경우 셋: ① source == "user" ② 이미 다른 시설로 바꿔 둔 지점 ③ 해당 옵션 키가 이미 있는 지점.
    • 계획 대비 차이: BOX암거로 전환할 때 본체 규격은 싣지 않는다. 레지스트리 기본값(2.0×2.0)이 이미 있어 폼이 그대로 채우므로 관 지점에 중복 저장할 이유가 없고, 저장해 두면 나중에 기본값을 바꿔도 옛 값이 남는다.
  • 4-3. 유역 목록 표기 B05_Profile/B05_Profile_UI_Drainage_Parts.ts
    • Ø1234mm → 추천 Ø1500 배관 / → BOX암거 후보 형태로 덧붙이고, 관 최대 규격 초과분은 기존 "세월교 검토 (Ø…)" 표기를 유지한다. 툴팁 셋째 줄에 "추천은 유량 근거만 — 계곡 횡단경사·하천 차수는 현장 확인" 문구를 붙였다.
  • 4-4. 물넘이·세월교 개략 단면 폼
    • 레지스트리에 ford_width_m(월류 폭) 신설 — 물넘이포장·세월교 양쪽. 기본값 없음 (지식DB에 폭 근거 없음), required: true+phase: detail.
    • 폼에 월류 폭 입력 한 칸 + 읽기 전용 요약 한 줄(설계유량·필요 수심·필요 단면·유속). 산식은 fordSection()(_Facility_Fields.ts)이고 n·S는 config_frontend.FORD_MANNING_N·FORD_SLOPE(백엔드 config_system과 같은 값).
    • 설계유량은 유역에서 폼까지 배선했다: 배수유역 패널 payload → onPipesChanged → Page → setPipeFacilities → loadPipeForm → setFacility(…, designFlow).
    • 계획 대비 차이: 위 산식 정정에 따라 "통수능 Qc·충족/부족 판정"을 빼고 "필요 수심·필요 단면·유속"으로 바꿨다.
  • 4-5. 테스트 tmp/tests/test_b05_drainage_recommend.py 17건 — 임계 경계(800/1500/2000 전후 10케이스)·규격 스냅·레지스트리 선택지 일치· 자동 관 관경 주입·BOX 시설 전환·사용자 지점 미덮어쓰기·기존 옵션 유지· 기존 시설 유지·유역 없는 관 무시.
    • 계획 대비 차이: 계획의 "실무 B=20·Qd로 h≈0.27 재현" 검증은 성립하지 않아 뺐다(위 산식 정정 참조 — 0.27은 가정 수심이다). 물넘이 산식은 프론트 전용이라 테스트 러너가 없어 수치 손검증으로 대신했다: Qd=2.54·B=20·n=0.017·S=0.10 → 필요 수심 0.0503m·유속 2.526m/s· 단면 1.006㎡이고, 이때 통수능이 2.5400㎥/s로 Qd와 일치한다(수렴 확인).
  • 자체검증 — pytest tmp/tests/ -q 124 passed·7 skipped(신규 17건 포함), npm run typecheck 무오류, npm run build 성공(374 modules), prettier·ruff format 적용.
  • 실화면 검증 (2026-08-17 사용자 지시로 서버 기동 후 직접 확인) — 로컬 main.py(8000) + npm run dev(5173), 프로젝트 c1bb453f…(노선 213m). Playwright(Chrome 채널)로 B05에 진입해 확인했다.
    • 추천 산출: 세부유역 4개가 임계 세 구간을 모두 덮었다 — Ø929→pipe/추천 Ø1000, Ø4719→ford_bridge, Ø1529→box_culvert, Ø549→pipe/추천 Ø800(하한 800 적용). required_area_m2도 응답에 실렸다.
    • 자동 주입: 관 지점 4건이 pipe_diameter_mm=1000, facility=ford_bridge, facility=box_culvert, pipe_diameter_mm=800으로 저장됐다. 폼을 열어 보면 13+15.7 배수관의 관경이 Ø800으로 뜬다 — 레지스트리 기본값이 Ø1000이므로 주입이 실제로 먹었다는 결정적 확인이다. BOX암거는 계획대로 본체 규격을 싣지 않았고 폼이 기본값 2.0×2.0을 채웠다.
    • 유역 목록 표기: 네 줄 모두 유효직경 Ø…mm → 추천 … 형식. 툴팁 셋째 줄에 "추천은 유량(유효직경) 근거만 반영합니다 — 계곡 횡단경사·하천 차수는 현장 확인."
    • 물넘이·세월교 폼: 세월교 항목을 고르면 월류 폭 칸과 요약이 뜬다. 폭을 비우면 "설계유량 36.734 ㎥/s · 월류 폭을 넣으면 필요 수심·단면을 계산합니다.", 20m를 넣으면 "필요 수심 0.25 m · 필요 단면 5.04 ㎡ · 유속 7.30 m/s"로 갱신된다.
    • 종단 설계 기준 접힘(3-1): 사이드 섹션 상태를 읽어 is-collapsed 확인.
    • 사용자 지적 반영: 세월교 줄만 세월교 검토 (Ø4719mm)로 유효직경과 추천의 자리가 뒤바뀌어 있었다(구 문구 잔재). 같은 열을 훑을 때 읽는 방향이 달라지므로 Ø4719mm → 세월교 검토로 통일했다.

범위 밖: 계곡 횡단경사·하천 차수 자동 판정(DEM 확장), 관 경사 단위 정정, 유출계수·조도계수·유효 통수비율 재확정(미결), 물넘이 물받이·구체 상세(B06/B07).