Commit Graph
16 Commits
Author SHA1 Message Date
eomsangdon 60bbe89edb fix(B03): rerun analysis on reupload
Clear derived browser caches so B05 loads the newly generated route and section data.
2026-08-29 20:17:37 +09:00
eomsangdonandClaude Opus 5 d935013ffa feat(B03): 같은 파일 재업로드는 전송 생략, 다른 내용이면 덮어쓰기 (E2E 결함 2)
사용자 결정(2026-08-08): 복수 파일을 허용하고 중복 기준은 파일명으로 둔다. 같은 이름으로
같은 내용이 다시 들어오면 덮어쓰지 말고 건너뛰고, 내용이 다르면 덮어쓴다.

파일 지문(부분 샘플링)
- B03_FileInput_Fingerprint.ts: 파일 크기 + 앞·중간·끝 8MB를 이어 SHA-256. 24MB만 읽어
  1~2초면 끝난다. 전체 읽기(1.7GB, 10~30초)와 견줘 실용적이고, 자리를 앞·중간·끝으로
  흩어 놓아 머리말만 같은 파일도 갈린다. 한계는 주석에 적었다.
- 화면이 업로드 세션 생성 요청에 지문을 실어 보내고, 서버가 같은 이름의 최신 입력 파일
  메타데이터에 적힌 지문과 견준다. 같으면 already_uploaded=true로 답해 **전송 자체를**
  건너뛴다(1.7GB면 3~5분 절약). 지문이 없거나 다르면 그냥 올린다 — 애매하면 올리는 쪽.
- 완료 요청에도 지문을 실어 input_files.metadata에 남긴다. upload_sessions에 컬럼을
  더하지 않으려는 선택이라 DB 스키마 변경이 없다.

옛 행 정리
- supersede_previous_input_files(): 같은 이름의 이전 행을 SUPERSEDED로 내린다. 조회는
  UPLOADED/PROCESSED만 보므로 목록·분석에서 자동으로 빠지고, 행은 이력으로 남는다.
- 직접 업로드 완료와 보관함 연결 양쪽에 적용.

검증(실서버 f45243b3)
- 같은 파일 재요청 → already_uploaded=true, 세션 미발급.
- 지문이 다르면 → 세션 발급(정상 업로드 경로).
- 옛 행이 SUPERSEDED로 내려가는 것 DB에서 확인.
- 화면 코드(B03_FileInput_Fingerprint.ts)를 그대로 실행해 만든 지문과 서버측 검증
  스크립트의 지문이 20MB 표본에서 완전히 일치(f281fd08…93e4).
typecheck·ruff·prettier 통과, 정적 번들 재빌드.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-08 20:11:23 +09:00
eomsangdonandClaude Opus 5 37b4d41e0b feat(B03): 자료 교체 시 옛 산출물 정리 + 분석 중 업로드 차단 (E2E 결함 3·6 서버측)
사용자 결정(2026-08-08): 새 자료를 올리면 재계산해 덮어쓰고, 화면은 불러올 자료가 없으면
대시보드로 보낸다. 그러려면 자료가 갈리는 순간 옛 계산 결과가 남아 있으면 안 된다.

- common_util_project_reset 신설: 단계별 산출물 폴더(B04~B09)와 산출물 DB 레코드
  (surface_models·routes·route_points·route_statistics·longitudinal_sections·
  cross_sections·structures·quantity_items·outputs·processed_point_cloud)를 함께 지운다.
  **B03_FileInput(업로드 원본)은 지우지 않는다** — 같은 파일인지 가리는 중복 검사가 쓴다.
- 직접 업로드 완료·보관함 연결 양쪽에서 정리를 호출하고, 진행 단계도 1단계 이후를
  NOT_STARTED로 되돌린다(reset_stages_after_input_change).
- is_analysis_running(): 전처리가 도는 중이면 업로드 세션 생성과 보관함 연결을 409로
  막는다. 화면 버튼 잠금은 새로고침·다른 탭으로 우회되므로 서버에도 문을 단다.
- fail_stage 아래 있던 리비전(번호표) 안은 폐기 — 사용자가 "산출물이 없으면 대시보드"
  방식으로 정리했다.

곁들여: os.replace 공유 위반 재시도(replace_with_retry)
  진행률 파일은 서버가 쓰는 동안 화면이 계속 읽어 WinError 5가 났고, 전처리
  structured.npz 교체에서는 같은 이유로 분석이 통째로 죽었다(결함 3의 사망 원인).
  짧게 여러 번 다시 시도하도록 바꿨다.

검증(실서버 f45243b3, 계획노선 CSV 재업로드로 자료 교체):
  전처리 결과 112개 -> 재분석분만, 노선 2->0, 횡단 20->0,
  DB 지표면 15->0 / 노선 1->0 / 횡단 19->0, 업로드 원본 6개는 그대로.
  진행 단계가 초기로 돌아가고 재분석이 자동 시작됨.
  교체 재시도는 읽는 쪽이 파일을 잡고 있는 상황을 만들어 성공 확인.
ruff format·check 통과.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-08 19:41:51 +09:00
eomsangdonandClaude Opus 5 1f119f9845 fix(B03): 직접 업로드 마지막 파일 404 + 실패 기록이 실패하던 문제 (E2E 결함 1·4)
결함 1 — 업로드 세션이 인증 세션을 가리고 있었다
- finalize_project_upload가 Depends(verify_session)로 받은 session을 같은 이름으로
  덮어써, str(session["role"])이 업로드 세션 행에서 role을 찾다 KeyError를 냈다.
  KeyError는 LookupError 하위라 404 {"message": "'role'"}로 나가고 로그도 안 남았다.
- 업로드 세션 변수를 upload_session으로 분리(청크 업로드·finalize·상태 조회 3곳).
- B03_FileInput_Router_Errors.lookup_error_response() 신설: 조회 실패만 404,
  KeyError·IndexError는 500 + 예외 로그. 두 라우터의 LookupError 처리 13곳에 적용.
  batch 단위 엔드포인트에는 batch_id를, 프로젝트 단위에는 project_id를 로그 필드로 준다.

결함 4 — fail_stage가 예외 문자열을 그대로 넣어 UPDATE가 죽었다
- project_workflow_stages.message는 varchar(255)인데 PermissionError 메시지는 300자를
  넘겨 DataError로 실패했고, 단계가 FAILED로 못 가 화면이 영영 "분석 중"이었다.
- 200자로 자르고 말줄임표를 붙인다. 원문은 호출부 로그에 남는다.

검증(실서버, 신규 프로젝트 f45243b3에 표본 5개 직접 청크 업로드):
  finalize 성공 11건 / "'role'" 오류 0건, 마지막 파일 complete_upload=true도 성공.
  이어서 WF1 자동 분석이 시작됨(stage 0 COMPLETE, stage 1 IN_PROGRESS) — 종전에는
  예외가 스케줄링 앞에서 터져 자동 분석이 아예 걸리지 않았다.
ruff format·check 통과.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-08 19:18:42 +09:00
eomsangdonandClaude Fable 5 336335c611 change(B03): 업로드/분석 알림 메일을 초기 설계 완료 시점 한 통으로 통합
같은 업로드 한 번에 업로드 완료 메일과 지표면 분석 완료 메일이 두 통 도착했다.
사용자가 실제로 화면을 볼 수 있는 시점은 초기 설계(B04 전처리 + B05 종단 + B06 횡단)까지
끝난 때 하나뿐이므로 그 시점에 통합 메일 한 통만 보낸다.

- send_initial_analysis_complete_email 신설: 지표면 요약 + 노선 연장/측점 수 +
  종단설계 화면 링크. 자동 체인 미실행/실패 시 전처리 요약만 싣고 안내 문구 전환
- run_auto_design_chain이 요약(route_id/length_m/cross_section_count) 반환
- WF1 서비스: 체인 실행 -> 통합 메일 순으로 재배치
- 업로드 직후 메일 발송 호출 제거(일반·청크 두 경로). 발송 함수는 프로젝트 생성 전
  임시 보관함 안내용으로 남겨 두고 주석으로 용도 명시

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-08 11:30:41 +09:00
eomsangdonandClaude Fable 5 4d0d627f57 fix(B03): WF1 백그라운드 작업 유실 방지 + 파일 교체 시 개수 초과 오탐 수정
증상 1 — 업로드는 성공하고 stage 0은 COMPLETE인데 stage 1(PREPROCESS)이
NOT_STARTED로 남아 분석이 시작되지 않고 다음 페이지로 넘어가지 않음.
원인: asyncio.create_task 결과를 아무도 붙잡지 않아 이벤트 루프가 약한 참조만
보유 -> GC가 대기 중인 작업을 회수하면 WF1 트리거가 조용히 사라짐.
조치: _BACKGROUND_TASKS 집합에 강한 참조를 보관하고 완료 시 해제,
취소 경로 로깅 및 작업 시작 로그 추가.

증상 2 — 5개 슬롯을 모두 고른 뒤 한 슬롯만 교체하면 개수 초과 오류.
원인: 교체 대상 슬롯을 기존 선택 개수에서 빼지 않고 더해 6개로 계산.
조치: 대상 슬롯을 제외하고 계산, 통과 시 이전 오류 문구 제거.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-08 11:13:34 +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 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 Fable 5 8a0d640e0e refactor(B04/B05): 배수유역 분석을 B04로 이관, B05는 저장분 소비만
분석이 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>
2026-07-31 20:57:09 +09:00
eomsangdon 050a5a2ba3 B05 페이지 초안 2026-07-18 17:48:51 +09:00
eomsangdon 95a8d125de 260718_0 2026-07-18 12:25:14 +09:00
eomsangdon b98affbf99 260710_1 2026-07-10 19:01:33 +09:00
eomsangdon e3d66e717c 260710_0 2026-07-10 18:12:17 +09:00
eomsangdon 50d75fcfcd 260710_0 2026-07-10 16:41:22 +09:00
eomsangdon 3abc2edba6 260705_2 2026-07-05 21:27:23 +09:00