Files
Aislo/docs/raw/plans/2026-07-18_plan_b04_confirm_b05_rebuild.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

10 KiB

Plan History: B04 자동 확정 및 B05 페이지 재구성 (WF1/WF2)

  • 이관 일시: 2026-07-18
  • 상태: 완료 이관 (Archived)

활성 작업 1 — 역할 기반 B04 자동 확정 (WF1)

배경 및 합의사항 (2026-07-18)

  • B04는 시스템 관리자(SYSTEM_ADMIN)의 내부 테스트/검증용 페이지. ADMIN/USER는 볼 필요 없음.
  • ADMIN/USER는 B03 업로드→전처리→WF1 분석 완료 시 백엔드가 "모델 확정 버튼을 누른 것처럼" 기본값으로 자동 확정하고 B05로 진행.
  • 자동 확정 기본값은 config/config_system.py에서 관리 (고정값 아님 — 시스템 관리자가 config를 바꾸면 그 값이 적용됨).
  • 값 우선순위 (2026-07-18 추가 합의): 확정 시 적용값(수동·자동 공통)은 DB(stage 1 params 스냅샷)에 저장. 읽을 때는 DB 스냅샷이 있으면 스냅샷 우선, 없으면 config 기본값 폴백. 이후 config가 바뀌어도 이미 확정된 프로젝트는 당시 적용값을 유지한다.
  • 자동/수동 확정의 구분 로직은 두지 않음: 동일한 확정 경로에 "기본값을 적용하느냐(일반 역할) / 직접 선택하느냐(시스템 관리자)" 차이만 존재.
  • B04로 넘겨야 할 선택값 3종: 지면 필터, 지표면 표현 방식, 등고선 간격 (+스무딩). 확정 시 stage 1 params에 스냅샷 저장하여 B05가 읽음.
  • 스텝바의 B04 단계는 일반 역할에게 비활성화 (완전 숨김 여부는 추후 결정).
  • 역할 판정은 프론트 전달값이 아닌 세션의 서버 측 role 사용.

사전 결정 사항 (구현 시 준수)

  • [불일치 발견] stage 1 COMPLETE 시점 일원화: 현재 B03_FileInput_Router.py:234가 분석 DB 저장 직후 complete_stage(1)을 호출함. 이는 "사용자가 확정해야 COMPLETE" 게이팅 원칙(wiki workflow_state)과 충돌. → 본 작업에서 complete_stage(1)은 확정 로직 내부에서만 호출하도록 일원화한다. (SYSTEM_ADMIN: B04 확정 시 / 일반 역할: 자동 확정 시)
  • 기본값 매칭 모델이 없거나 분석 실패 시: 임의 모델을 확정하지 않는다. 확정 보류 + 로그 + B03 진행 메시지로 원인 노출.
  • 재분석 시: 기존 start_stage가 확정 클리어·STALE 전파 수행(현행 유지) → 분석 완료 시 일반 역할은 다시 자동 확정.

구현 체크리스트 — 백엔드

  • config/config_system.py: 자동 확정 기본값 추가 — SURFACE_CONFIRM_DEFAULT_FILTER="csf", SURFACE_CONFIRM_DEFAULT_METHOD="dtm", SURFACE_CONFIRM_DEFAULT_SMOOTH=True. 등고선 간격은 기존 SURFACE_CONTOUR_INTERVAL_M(1.0) 재사용. (기본값 변경 방법 = config 직접 수정 또는 .env 오버라이드, 서버 재시작 시 반영. 별도 설정 UI 없음 — 합의사항)
  • B04_wf1_Surface_Router.py: confirm_surface()(:206)의 확정 트랜잭션(CONFIRMED 전환 + complete_stage(1) + params 스냅샷 저장)을 재사용 가능한 서비스 함수로 분리 (API 핸들러와 자동 확정이 공유).
  • B04_wf1_Surface_Schema.py: SurfaceConfirmRequest에 선택 필드 smooth: bool | None, contour_interval_m: float | None 추가. 확정 시 project_workflow_stages(stage 1).params에 {source_filter, method, smooth, contour_interval_m} 병합 저장.
  • 스냅샷 읽기 헬퍼: stage 1 params 스냅샷 조회 함수 신설(공통) — 스냅샷 존재 시 그 값을, 없으면 config 기본값을 반환. B05 초기값·자동 확정 재실행 등 읽기 경로는 모두 이 헬퍼를 경유 (config 변경이 기존 확정 프로젝트에 소급 적용되지 않도록 보장).
  • B04_wf1_Surface_UI_Page.ts / _Api_Fetch.ts: 수동 확정 시 현재 UI의 스무딩·등고선 간격 값을 confirm 요청에 포함.
  • B03_FileInput_Router.py: 업로드/재분석 트리거 지점(:391, :617)에서 세션 사용자 role을 trigger_wf1_analysis_and_email()에 전달. 분석 DB 저장 성공 후 role ≠ SYSTEM_ADMIN이면 config 기본값 매칭 surface_models 행 조회 → 확정 서비스 호출(자동 확정). :234의 complete_stage(1) 직접 호출 제거(위 일원화 방침).
  • write_surface_progress 완료 메시지 역할 분기: 일반 역할 "지표면 모델 자동 확정 완료 — 노선 설계로 이동하세요" / SYSTEM_ADMIN 기존 문구 유지.

구현 체크리스트 — 프론트엔드

  • 공통 스텝바(ui_template_workflow_layout.ts의 createStepBar / b_page_scaffold): fetchDashboardMe() role 기준으로 일반 역할에게 B04 스텝 비활성화(disabled) 처리.
  • B03 완료 CTA/폴링 분기: WF1 완료 시 SYSTEM_ADMIN → B04, 일반 역할 → B05로 이동.
  • B04 진입 가드: 일반 역할이 URL 직접 진입 시 — stage 1 COMPLETE(확정됨)면 B05로, 아니면 B03으로 리다이렉트.

검증 기준

  • SYSTEM_ADMIN: 기존 흐름 그대로 (B03→B04 검토→확정→B05). 확정 시 params 스냅샷 저장 확인.
  • ADMIN/USER: 업로드만으로 B05 진입 가능. DB에 CONFIRMED 모델 + stage1 params 스냅샷 존재(시스템 관리자가 사후 확인 가능). B04 스텝 비활성화·URL 가드 동작.
  • 기본값 매칭 모델 부재 시 자동 확정이 일어나지 않고 원인 메시지 노출.

활성 작업 2 — B05 페이지 재구성 (0_old 기능 이식)

배경 및 합의사항 (2026-07-18)

  • 신규 B05(B05_wf2_Route_UI_Page.ts, 378줄)는 좌표 수기입력 폼 + 결과 메트릭 카드뿐이며 3D 뷰어가 미구현 상태.
  • 신규 템플릿 유지: createWorkflowLayout — 좌측 접이식 패널 + 우측 진행단계 오버레이 + mainContent(브라우저 대부분) = 3D 뷰포트.
  • 좌측 패널 내부는 전부 삭제하고 0_old RouteDesignStage.tsx(2,171줄)의 기능을 신규 템플릿 위에 재구성.
  • 3D 지형 로딩은 B04에 이미 있는 인프라 재사용: surface/models/{model_id}/preview(GLTF) + .../contour?interval= API, B04_wf1_Surface_UI_Camera.ts 유틸.
  • 확정 모델·선택 스냅샷(필터/표현/스무딩/등고선 간격)은 활성 작업 1의 stage 1 params에서 읽어 초기값으로 적용.
  • 구현은 2단계로 나눔 (기획자 재량 합의). 1차·2차 모두 이번 작업 범위 — 릴리즈 분리가 아니라 구현·검증 순서이며, 2차(AP/FP·경고·확정 제한 등 구버전 기능)까지 완료해야 본 작업 종료.

사전 결정 사항 (구현 시 준수)

  • [불일치 발견] WF2 상태 분리 (계산≠확정): 현재 solve_route()가 계산 성공만으로 complete_stage(2) 호출(B05_wf2_Route_Router.py:96). stage 1과 동일한 조기 완료 결함 → complete_stage(2)는 경로 확정(confirm_latest_route)에서만 호출하도록 일원화. 계산은 start_stage(IN_PROGRESS)+결과 저장까지만.
  • [API 신설] 최신 경로 조회 (DB 기반): RouteSolveResponse에는 route_data_path(파일 경로)만 있고 좌표가 없음. 다만 계산 시 렌더 좌표는 이미 route_points 테이블에 저장되고(:85 insert_route_points), 요청 파라미터도 stage 2 params에 저장됨(:51). → GET /{project_id}/route/latest 신설: 최신 route(확정 여부 포함) + route_points + 사용 파라미터를 DB에서 반환. 3D 경로 렌더링과 새로고침 복원을 이 API 하나로 해결 (GeoJSON 파일 서빙안은 폐기).
  • 700줄 제한: 프론트 4파일 분리 — B05_wf2_Route_UI_Page.ts(조립) / _UI_Panel.ts(좌측 패널) / _UI_Viewer.ts(지형+등고선+씬) / _UI_Markers.ts(포인트·경로 인터랙션).
  • 좌표계 변환(모델↔씬)은 0_old transformToScene/transformToModel(RouteDesignStage.tsx:153,178) 방식 준용.

구현 체크리스트 — 1차 (핵심 경로 설계 루프)

  • 좌측 패널 기존 폼(BP/EP/CP 수기입력·읽기전용 지표면 폼) 전면 제거, 0_old 섹션 구조로 재구성: 뷰 컨트롤 / 등고선 간격 / 포인트 팔레트 / 임도 기준·옵션 / 결과 카드 / 계산·확정 버튼.
  • _UI_Viewer.ts 신설: 확정 모델 preview(GLTF, meshfree는 PLY) 자동 로딩, 카메라 뷰핏(기본 탑뷰), 등고선 렌더링(초기 간격 = stage1 params, 변경·재적용 가능), 지표면·등고선 표시 토글.
  • BP/EP/CP 배치: 팔레트 칩 드래그&드롭 + 지형 레이캐스팅 배치, 마커 렌더링, 배치값 ↔ 요청 페이로드 동기화.
  • 경로 계산(solveRoute) 연동: 알고리즘(dijkstra/ridge_valley)·등급(간선/지선/작업)·최소 곡선반경·오르막/내리막 경사 상한 입력 반영.
  • GET /{project_id}/route/latest API 신설(백엔드) + 3D 경로 라인 렌더링.
  • 새로고침 복원: B05 진입 시 최신 route + stage 2 params 로드 → 포인트(BP/EP/CP/AP/FP)·옵션·경로 라인·메트릭 복원.
  • WF2 상태 분리: solve_route()의 complete_stage(2)(:96) 제거, confirm_latest_route()에서만 COMPLETE 처리.
  • 결과 메트릭 카드(연장·경사·비용) + 입력 변경 시 "재탐색 필요" STALE 배지.
  • 확정 제한: 경로 미계산 또는 stale(입력 변경 후 재계산 전) 상태면 확정 버튼 비활성화 — 구버전 동작 준용. 확정(confirmRoute)은 이 게이트 통과 시에만 가능.

구현 체크리스트 — 2차 (고급 인터랙션)

  • AP(회피)/FP(금지) 팔레트 배치 + 반경 입력 팝오버 + 반경 수정.
  • 선택 포인트 상세 설정: 위치 이동 모드, 삭제.
  • 경로 경고 마커·수직선(perpendiculars) 렌더링.
  • 뷰 프리셋(iso/top/front/side), 축 표시 토글, 초기화 버튼.
  • "사용한 조건" 접기, "최적경로란?" 도움말, 포장 여부·경사 하한(ridge_valley 전용) 입력.
  • 오르막/내리막 경사 하한 등 0_old 잔여 옵션 정합성 점검.

검증 기준

  • 일반 역할이 B03 업로드 직후 B05 진입 시: 자동 확정 모델의 지형+등고선이 3D로 표시되고, 등고선 간격 초기값 = 확정 스냅샷 값.
  • BP/EP 배치→계산→경로 라인 3D 표시→확정까지 전체 루프가 0_old와 동등하게 동작.
  • 좌측 패널 접기/펼치기, 우측 진행단계 오버레이 등 신규 템플릿 동작 유지. 700줄 제한 준수.