사용자 지적 — 창을 줄이면 내용이 밖으로 나가고 글자를 못 읽었음.
원인은 세 자리의 **고정 최소폭**과 flex 기본값이었음.
- 계획노선|지형 2열이 `repeat(2, minmax(0,1fr))` 로 **고정**이라, 좁아지면 각 열이
카드 하나도 못 담고 넘쳤음 → `auto-fit` + `min(360px,100%)` 로 바꿔 스스로 1열로 접힘.
- 카드 격자 `minmax(260px,…)` · 고르는 줄 `minmax(200px,…)` 는 그 폭 아래에서 넘침
→ `min(…, 100%)` 로 컨테이너까지만 줄어들게 함.
- 카드 머리줄에 min-width/max-width 를 주어 배지·[선택]·[×] 가 안 밀려 나가게 함.
- 페이지 몸통(flex)에 min-width: 0 — 안 주면 안쪽 격자가 넘칠 때 몸통이 통째로
가로로 밀렸음.
실측(공용 브라우저): 폭 1400·1000·760·620·480 에서 여섯 컨테이너 모두 **넘침 0px**,
페이지 가로 스크롤 없음(scrollWidth = clientWidth). 트랙 폭도 확인 —
1400/1200 은 580·580(남는 트랙 0px), 1000·820 은 2열, 700 이하 1열.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
- 계획노선처럼 그릴 선이 있는 자료에는 범위 점선 상자를 그리지 않음.
점구름·래스터는 그대로 상자를 그림.
- 노선 선 색을 녹색으로. 지형 범위를 벗어나면 붉은 경고색으로 덮어쓰는
규칙은 유지.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
- 완료 카드에서도 [파일 선택]을 보임. 올리는 중에만 감춤. 교체 확인 모달과
교체 업로드 규칙은 이미 있던 것을 그대로 씀.
- 업로드 관문이 전처리 1단계 IN_PROGRESS 를 무조건 「분석 중」으로 읽어,
자동 확정이 보류된 프로젝트는 영영 새 자료를 받지 못했음. 전처리 진행 파일이
awaiting_confirmation·completed·failed 로 끝나 있으면 받도록 고침.
실제로 도는 중(analyzing)이면 그대로 막음.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
개수만 보이던 부속 파일 카드에 파일 안의 중요한 값을 함께 보임.
- .shx — 도형 종류(폴리라인 등)와 범위 크기를 머리글에서 읽음.
- .dbf — 속성 이름 목록을 머리글 서술자에서 읽음(앞 4개).
- .cpg — 같은 세트 .dbf 의 첫 글자 속성을 그 인코딩으로 읽어 견본으로 보임.
- .prj — 중앙자오선(투영 매개변수)과 길이 단위. proj 문자열 변환을 쓰지 않아
정보 손실 경고가 나지 않음.
- 카드 표시 줄 수를 2 → 3 으로 늘리고, 길이 단위 표기를 m 으로 통일.
- GeoTIFF 썸네일에 다른 미리보기와 같은 점선 테두리.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
- 미리보기를 카드 한 행 전폭·높이 120px 고정으로 키움.
- 라이다: 분류 통계를 훑는 그 길에 XY 를 성기게 주워 탑뷰 점 그림(상한 5천 점,
파일 재열람 없음). 분류가 없는 파일은 앞 3청크만 봄.
- GeoTIFF: 오버뷰가 있을 때만 128px 흑백 썸네일(2~98 백분위 대비), 없으면 종전 범위 사각형.
- 부속 파일(.shx·.dbf·.cpg·.prj·.tfw)은 그림 대신 구분되는 값 표시 — 머리글만 읽는
가벼운 분석기 추가.
- 값이 없는 완료 카드는 「보여 줄 값이 없음」 한 줄.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
- 계획노선 shapefile 분석에 `preview_path`(200점 안팎 솎은 좌표열) 추가 — 이미
메모리에 있는 정점을 쓰므로 파일 재열람 0회(솎기 0.136ms)
- LAS·GeoTIFF 는 사용자 확정대로 **bbox 사각형만** (점구름·래스터 렌더 안 함)
- `upload-overview` 응답에 분석 `metadata` 동봉 — 재접속해도 같은 그림
- 카드에 SVG 미리보기 렌더(신규 `B03_FileInput_UI_Preview.ts`), 값 없으면 미표시
- 계획노선 카드는 지형 자료 범위와 대조 — 벗어나면 경고색·안내, 좌표계가 다르면
대조 생략(재투영 안 함). shapefile 은 좌표계가 없어 같은 세트 `.prj` 값을 씀
검증: 공용 브라우저 실측(노선 선 121점·범위 안/밖·좌표계 상이 3갈래),
tmp/tests/test_b03_preview_path.py 2건, tsc --noEmit 통과
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
사용자 지시(2026-09-03).
- 고르는 자리를 flex 에서 **격자 3칸**으로 바꿈. flex 로는 내용 폭이 배분에 섞여
288·254·288 로 어긋났고 버튼 높이도 달랐다. 격자는 칸을 먼저 나누므로 1:1:1 이고,
칸을 꽉 채우게 해 세 칸 높이가 같아진다(실측 277×47 셋 다 동일).
- 빈 오류 줄이 자리를 잡아 토글 아래가 비어 보이던 것 제거 — 글자가 있을 때만 자리를
차지한다(`:empty { display: none }`, min-height·마진 제거).
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
사용자 지시(2026-09-03).
- 토글을 지형 컨테이너에서 **파일 입력 컨테이너**로 옮김 — 무엇을 받을지 정하는
스위치라 고르는 자리 옆에 선다. 서식도 입혔음(공용 체크 줄 + 켜짐 강조).
- 켜면 지형 자료를 **통째로** 받지 않음: 포인트클라우드·좌표계·래스터 카드를 모두 잠그고
컨테이너를 흐림. 필수 판정에서도 지형 슬롯 전체가 빠진다.
- 파일 거르기를 확장자가 아니라 **배정된 카드** 기준으로 바꿈 — `.prj` 는 노선·지형이 같은
확장자라 확장자로 거르면 노선 좌표계까지 함께 떨어졌다.
- 이미 올라간 자료(재입력)는 지우지 않고 **조작만 잠금** — 로컬로 고른 파일만 내린다.
좌측 안내 패널의 글자 크기도 공용 양식에 맞춤 — 본문 `--text-body-sm`·`--color-text-body`
(B04 `b04-surface__check` 와 같음), 제목 `--text-caption`.
검증: 실측 — 토글이 입력 컨테이너 안에 있고, 켜면 지형 카드 4장이 모두 disabled +
[파일 선택] 잠김, 기존 업로드분은 「완료」·파일명 유지. 끄면 원복. 패널 글자 14px/12px.
typecheck·prettier 통과.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
처음엔 B03 전용 스타일로 문단을 만들었으나, 좌측 패널 양식은 다른 단계와 같아야 한다는
사용자 지시(2026-09-03). 공용 조립으로 교체함.
- 패널 루트 `b03-file__form`, 문단은 `ui-collapsible ui-sidebar-section`,
제목은 `ui-collapsible__title` — 외곽선·캐럿·접힘 동작이 전부 공용 CSS·동작이다.
- 값도 `b04-surface__form`·`__group`·`__group-legend` 와 같게 맞춤
(gap·padding 16, 배경 `--color-surface-raised`, legend `--text-caption`).
검증: 실측 — 문단 클래스 `b03-file__guide-group ui-collapsible ui-sidebar-section`,
패딩 16px, 배경 `rgb(37,31,56)`, 제목 클릭 시 `is-collapsed` 토글·복귀 확인.
typecheck·prettier 통과.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
사용자 지시 3건(2026-09-03).
- 재접속 현황 배너(「…모두 완료된 프로젝트입니다」)를 좌측 안내 패널 「고르는 방법」
안으로 옮김 — 고르기 전에 읽을 것과 같은 자리.
- [입력 파일 선택]·[임시 보관함에서 불러오기]·[파일 업로드]를 한 줄(`b03-file__pick-row`)로
묶음. 좁아지면 접히되 선택 영역이 남는 폭을 먹음.
- 업로드 완료 항목 목록 삭제 — 같은 내용을 카드가 완료 상태로 이미 보여 줌.
쓰이지 않게 된 `renderUploadResults`와 `.b03-file__results` 규칙도 제거.
곁들여 고친 것 — 카드 격자를 2열 고정에서 `auto-fill minmax(260px, 1fr)` 로 바꿈.
안내 패널을 연 상태에서 카드 폭이 210px 로 눌려 제목이 글자 단위로 접혔음(실측).
제목은 한 줄 말줄임으로 둠.
검증: 한 줄 배치 실측 — 선택 397px · 보관함 331px · 업로드 102px, 높이 76px 로 정렬.
카드 66px(빈 칸)/117px(파일 있음), 제목 줄 높이 21px(한 줄). typecheck·prettier 통과.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
`padding: var(--spacing-20)` 은 정의되지 않은 토큰이라 선언째 무효가 되어 카드
컨테이너의 패딩이 통째로 사라졌음(2026-09-03 사용자 보고). 16px 토큰으로 교체.
검증: 실측 계산값 — 컨테이너 16px, 카드 12/16px, 선택 바 12/16px, 안내 문단 12px.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
사용자 지적(2026-09-03) — 선택 항목이 너무 크고 대중없이 놓임. 안내는 B04·B05 와 같은
공용 좌측 패널로 빼고 본문은 고르는 자리만 남김.
- `B03_FileInput_UI_Guide.ts` 신설 — 필요한 파일 / 고르는 방법 / 알아 둘 것 3묶음을
공용 오버레이 `optionsContent` 에 실음. 문단 구획은 공용 `ui-sidebar-section`.
- 선택 영역 160px 블록 → 한 줄 바. 긴 문구는 패널로 옮기고 힌트는 한 줄로 교체.
- 카드 `min-height: 220px` 폐지, [선택]을 제목 줄 오른쪽 끝 작은 버튼으로 이동,
빈 칸은 제목 줄만 남김. 진행바·속도·예상완료는 올라가는 동안만 표시.
- 여백 정리 — 컨테이너 패딩 32 → 20, 그룹 제목 24 → 16px, 격자 간격 24 → 12.
- 좌측 패널이 열리면 본문을 밀어내는 규칙 추가 — B03 은 일반 레이아웃이라 공용
워크플로 레이아웃의 padding 규칙이 없어 패널이 카드를 덮었음.
검증: 카드 높이 232 → 66px(빈 칸)·117px(파일 있음), 선택 영역 160 → 47px,
문서 높이 1408px 로 한 화면 남짓. typecheck·prettier 통과.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
파일마다 포맷 폭이 달라(≈80 대 100) 한 줄만 고쳐도 포맷터가 무관한 줄을 대량
재포맷했음. 사용자 지시로 전체를 한 번에 맞춤. 코드 동작 변경 없음 — 포맷만.
- 프론트엔드 `.ts/.css/.html` → 저장소 prettier (`.prettierrc`, printWidth 100)
- `B07_DesignDetail/openwebcad/**` → 자체 biome (tab 들여쓰기·single quote·lineWidth 100).
`biome format` 만 사용 — `biome lint --write` 는 포맷 아닌 코드 수정까지 하므로 제외
- 파이썬 → `ruff format` (엔진 코드는 이미 정합, resources·scratch 스크립트 24개만 변경)
두 포맷터가 서로 되돌리지 않도록 `.prettierignore` 신규 — openwebcad 와 빌드·산출물
폴더를 prettier 대상에서 뺌. `.prettierrc` 에 `endOfLine: "auto"` 추가 — 기본값 `lf` 가
`core.autocrlf=true` 로 받은 CRLF 파일을 매번 전부 다시 써서 `--list-different` 가
실제 포맷 차이를 가리고 있었음.
검증: `tsc --noEmit` 통과(루트·openwebcad 둘 다), pytest 349 passed / 17 skipped /
0 failed, CAD vitest 87건 중 81 passed / 6 failed(laptop-sub 기준선과 동일, 회귀 없음).
포맷터 재실행 시 prettier·biome 모두 변경 0건.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
노선 파일이 다섯이면 카드도 다섯이어야 어느 것이 왔는지 보인다(사용자 지시).
세트를 슬롯 하나에 몰아 담던 companions 구조를 걷어내고, 슬롯 하나가 파일 하나를
갖는 기존 구조로 되돌렸다 - 업로드 루프도 원래대로다.
- 왼쪽 컨테이너 계획노선 자료: csv(.csv/.shp) shx dbf cpg route_prj
- 오른쪽 컨테이너 지형 자료(LAS): las_laz prj(지형 좌표계) tfw tif + LAS 없는 설계 토글
- .prj만 확장자로 안 갈린다 - 노선 도형과 basename이 같으면 노선 좌표계 카드,
아니면 지형 카드(planSlotAssignments). 재접속 현황은 저장 경로(input/shp/)로 가른다.
- 재접속 현황 응답에 relative_path 추가.
- 필수 판정이 노선 PRJ를 route_prj로 따로 센다 - 지형 PRJ 없이 통과하던 구멍을 막았다.
- 형제 카드(shx/dbf/route_prj)는 노선 도형이 shapefile일 때만 필수 - 확장자 줄의
"선택" 꼬리표가 실시간으로 붙고 떨어진다.
- 카드가 좁아져 한글 제목이 글자 단위로 접히던 것을 word-break: keep-all과 헤더
flex-wrap으로 고쳤다.
화면 검증(공용 브라우저): 실물 7파일을 한 번에 떨어뜨려 배정 실측 - route.prj는
노선 좌표계 카드, terrain.prj는 지형 카드로 갈렸고 카드 제목 9개 모두 한 줄.
tmp/tests/test_route_shapefile_input.py 9개 통과, tsc --noEmit 통과.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
- B03: 'LAS 없이 설계' 토글 — LAS 필수카드 비활성화, las_free 플래그로
업로드·완료 검증 면제, 계획노선 CSV를 WF1 분석 입력으로 사용
- B04: 신규 Engine_SheetSurface — 도엽_등고선.geojson을 노선 bbox+300m
직사각형으로 절취, 배수유역 엔진의 등고선 정점구름·Delaunay TIN 보간을
재사용해 dtm_sheet.npz(1m 격자, LAS DTM과 동일 형식) + 프리뷰 glb 생성.
build_surface_sampler('sheet','dtm')로 종·횡단·배수 하류 계산 무수정 동작
- WF1: las_free면 run_sheet_surface_analysis로 분기, sheet/dtm 자동 확정.
VWorld·도엽 확보 블록을 download_geodata()로 추출해 두 경로가 공유
- LAS가 있어도 도엽 서피스를 함께 생성·등록(참고용), B04에
'도엽등고 3D 서피스' 별도 컨테이너로 표시
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
지형 래스터(tif)만 선택 항목이고 나머지는 모두 필수라, 계획노선과 지형 자료를
따로 묶을 이유가 없다.
- 그룹 2개(원청 계획노선/지형 분석자료)를 "입력 자료" 한 그룹으로 통합
- 계획노선 카드에만 걸려 있던 전용 서식(1열 폭·보라 배경·테두리) 제거 —
다른 카드와 같은 템플릿으로 통일
- 카드 배치 2열 -> 3열 (1280px 이하 2열, 720px 이하 1열)
- 선택 항목(tif)은 확장자 옆에 "선택" 표시
- [파일 업로드]를 누르면 버튼을 잠그고 안에 회전 원을 넣어 진행 중임을 보이며,
업로드·분석이 끝날 때까지 화면 조작을 막는다(중복 업로드·단계 이동 방지)
파일 분리: 업로드 실행부(청크 업로드/분석 대기/결과 표시/교체 확인 모달)를
B03_FileInput_UI_Upload.ts로 이관해 페이지 파일을 700줄 제한 안으로 되돌림(830 -> 622).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
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>
분석이 30초 걸리는데 B05는 일반 사용자 화면이다. 관리자 확인용 B04에서
한 번 돌려 저장하고, B05는 그 결과를 읽어 관 보충과 세부유역만 처리한다
(2026-07-31 사용자 지시).
노선 원천 변경
- B05 확정 경로 -> B03 업로드 계획 노선 파일(CSV). 분석이 노선 설계보다
먼저 끝나 있어야 하기 때문. 샘플 planned_route_sample_epsg5187.csv 로 검증.
- common_util_route_geometry.py 신설 — RouteVertex/StructureCandidate/누가거리
보간/세류 교차점/계획 노선 CSV 리더. B04와 B05가 같은 표현을 쓰도록 공용화.
열 이름은 대소문자·한글 표기를 함께 받는다(B03이 여러 형식 수용 예정).
B04 (관리자 확인용, 신규)
- Engine_Watershed_{Grid,Stream,Descent,Flow,Expand,Export} — B05에서 git mv
- Engine_Watershed_Analyze.py — 1~8단계 오케스트레이션
- Router_Watershed.py — GET /drainage/primary-region
- UI_Watershed.ts — 2D 지도 GIS 레이어 그룹에 "배수유역" 토글 추가.
격자/화살표/세류망/1차영역/2차유역/기본관을 겹쳐 그린다.
- 저장 위치 B05_wf2_Route/drainage -> B04_wf1_Surface/drainage
- 03_road_routing 단계 추가: B05가 세부유역을 나눌 최소 배열(셀->도로셀 귀속,
유하장, 강도, 도로셀 제원, 셀 표고) + 계획도로선/기본배관/2차유역 기하
B05 (일반 사용자용, 축소)
- Engine_Drainage_Basin.py — B04 산출물 로더 + 관 보충(9) + 측구 라우팅/세부유역(10,11)
- Engine_Drainage.py 는 관경 산정만 남기고 322 -> 27줄
- Router_Drainage.py 509 -> 142줄. POST /drainage/basins 만 남김
- 화살표·격자·강도 띠 렌더 제거. 계획도로선/기본배관/2차유역만 받는다
삭제
- _legacy_watershed/ 4파일 (능선 행진 방식 원본 보관본)
- Engine_Watershed_Basin.py (B04 Analyze + B05 Drainage_Basin 으로 분할)
- GET /drainage/candidates 와 propose_structure_stations (구방식 후보 제안)
E2E 검증 (실데이터)
B04 분석 28.2s -> 저장(geojson 11KB + npz 2.6MB)
B05 로드 + 세부 설계 0.11s <-- 30초가 0.1초로
면적 457,404m2 로 B04 2차 유역과 정확히 일치
관 편집 재산정 0.12s, 관 3개 -> 세부유역 3개, 면적 보존
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>