Commit Graph
22 Commits
Author SHA1 Message Date
eomsangdonandClaude Opus 5 fe72ea041b feat(B03): 계획노선 shapefile 입력과 PRJ 2개 분리를 지원한다
원청 정식 계획노선이 shapefile(UTM-K)로, 지형이 별도 PRJ(동부원점 Bessel)로
들어오는데 입력 경로가 shapefile 확장자를 막고 PRJ를 프로젝트당 1개로 전제했다.

- 업로드 허용에 .shp/.shx/.dbf/.cpg 추가, 한 번에 보낼 파일 수 5 -> 10
- B03_FileInput_Engine_Shapefile: ESRI 규격 직접 파싱(GDAL 미사용). 형제 파일이
  아직 안 왔어도 .shp 하나로 기하를 읽는다. .cpg 내용이 949뿐인 실물을 CP949로
  정규화해 한글 속성을 살린다.
- 노선 판독을 read_planned_route로 일원화(CSV/shapefile), PlannedRoute에
  crs_input 추가 - 변환 입력은 EPSG 코드가 아니라 crs_input_from_prj가 주는
  값(EPSG:n 또는 원문 WKT)이다. 실물 PRJ 2종 모두 to_epsg가 None이다.
- shapefile 세트를 input/shp/ 한 폴더에 모은다(GDAL 요건). 노선 PRJ가 그 안에
  남으므로 지형 PRJ(input/prj/)와 파일명 정렬 운에 기대지 않고 갈린다.
  find_project_prj가 지형 PRJ를 프로젝트 좌표계로 고른다.
- 필수 세트를 노선 1종(csv 또는 shp) + prj + tfw로 완화, shp면 shx/dbf 동반 필수.
- UI: 확장자 단독 슬롯 매칭을 basename 그룹핑으로 바꿔 노선 PRJ와 지형 PRJ가
  같은 슬롯을 다투지 않게 하고, 노선 슬롯이 파일 한 벌을 담아 함께 전송한다.

자체검증: tmp/tests/test_route_shapefile_input.py 9개 통과, tsc --noEmit 통과,
ruff check/format 통과. 전체 스위트 잔여 실패 11건은 HEAD 사본(git archive)에서
동일하게 재현되는 기존 실패다.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-31 19:28:34 +09:00
eomsangdonandClaude Opus 5 a9694356cf feat(B01): 대시보드 목록 컨테이너를 4행까지만 보이고 나머지는 안쪽 스크롤
프로젝트·임시 보관함·사용자 관리·가입 요청·회사 관리·시스템 로그 컨테이너는 자료가
쌓일수록 세로로 계속 길어져 페이지가 늘어난다. 4행 높이에서 자르고 나머지는 컨테이너
안에서 스크롤하게 했다.

행 높이를 상수로 박지 않았다. 프로젝트 표는 셀 안에 단계 막대가 들어가고 보관함 묶음은
접힘 상태에 따라 높이가 제각각이라 4 x 고정값으로는 어긋난다. limitVisibleRows()가
4번째 항목의 실제 아래쪽 좌표를 재서 max-height를 넣는다 — 표든 묶음이든 같은 코드로
맞는다. 항목이 4개 이하면 max-height를 지워 스크롤바를 만들지 않는다.

스크롤 중 어느 열인지 알아야 하므로 표 머리행은 sticky로 붙였다. 배경이 투명하면 아래
행이 비쳐 보여 불투명 배경도 함께 준다.

임시 보관함은 표가 아니라 묶음이 한 행이다. 묶음 안 파일 표는 접혀 있어 제외했다.
묶음을 펼치면 높이가 달라지므로 토글 핸들러에서 다시 잰다. 목록을 다시 그릴 때마다
resize 청취자가 쌓이던 문제는 WeakMap으로 이전 것을 걷어내고 다시 등록해 막았다.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-08 22:16:55 +09:00
eomsangdonandClaude Opus 5 fbab749ec4 feat(B01): 프로젝트 삭제에 개발용 하드 삭제 스위치 추가
대시보드 삭제 버튼은 지금까지 projects.deleted_at만 찍는 소프트 삭제였다. 배포에서는
그게 맞다 — 사용자가 올린 라이다 원본은 다른 프로젝트에 재활용할 자산이다. 그러나 개발
중에는 프로젝트를 반복 생성·삭제하는데 정리 잡이 없어 수십 GB 원본이 계속 쌓인다.

config_system.py 맨 위에 PROJECT_DELETE_HARD_ENABLED를 두고 갈랐다. 기본값 False라
환경변수를 빠뜨린 배포 환경은 자동으로 안전한 쪽에 선다. True면 projects 행을 실제로
DELETE 하고(자식 테이블은 FK CASCADE로 함께 사라진다) storage/{회사}/{사용자}/{프로젝트ID}/
폴더를 통째로 지운다.

자식 테이블 목록은 코드에 나열하지 않았다. projects.id 참조가 전부 ON DELETE CASCADE라
행 하나면 충분하고, 목록을 복사해 두면 스키마가 바뀔 때 조용히 어긋난다.

순서는 DB 먼저 커밋, rmtree 나중이다. 파일을 먼저 지우면 DB 실패 시 실체 없는 프로젝트가
목록에 남아 화면이 깨진다. 반대면 rmtree가 실패해도 고아 폴더만 남고 정합성은 유지된다.

resolve_stored_project_path()는 끝에서 makedirs를 하므로 삭제에 쓸 수 없다 — 지우기 직전에
폴더를 되살린다. 검증만 하는 resolve_project_root_for_delete()를 따로 뒀고, 저장소 루트 안 ·
세그먼트 정확히 4개 · 마지막 세그먼트가 요청 project_id와 일치를 모두 요구한다. DB의
storage_path가 오염돼도 상위 폴더나 남의 폴더를 지우지 못한다.

하드 삭제 모드에서는 확인 모달 문구를 바꿔 원본까지 사라진다고 알린다.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-08 21:56:17 +09:00
eomsangdonandClaude Opus 5 b3d8371882 feat(B01,B03): 프로젝트에 연결된 보관함을 목록에서 제외 (E2E 결함 5)
연결된 묶음은 파일이 프로젝트로 옮겨져 내용이 비어 있는데도 목록에 남아, 파일 0건·용량
0·만료 없음·버튼 없음인 빈 껍데기가 영구히 쌓였다(2026-08-08 사용자 지시로 제외).

- list_temp_batches: status <> 'linked' 만 조회. 행 자체는 이력용으로 DB에 남긴다 —
  어느 자료가 어느 프로젝트로 갔는지 추적할 근거다.
- 대시보드 UI: 목록에 연결된 묶음이 오지 않으므로 "연결됨" 배지·삭제 버튼 숨김·파일 행
  비활성 분기를 걷어냈다(죽은 코드).

검증: 서버 재시작 후 목록 응답 0건, DB 보관 행 3건 유지.
typecheck·prettier·ruff 통과, 정적 번들 재빌드.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-08 20:00:12 +09:00
eomsangdon 9b4f603405 style(B01): 임시 보관함 캐럿·요약 텍스트를 테마 토큰으로 정정 2026-08-08 13:44:36 +09:00
eomsangdonandClaude Fable 5 ff3d819019 feat(B01): 임시 보관함 그룹 접기/펼치기 + 제목 행 한 줄 정리
- 그룹은 기본 접힘, 제목 행 전체가 토글 트리거(액션 버튼 클릭은 전파 차단)
- 목록을 다시 그려도 펼친 그룹은 유지, 업로드 시작 시 해당 그룹 자동 펼침
- 파일 수·용량·보관 만료를 상태 배지 오른쪽으로 옮겨 제목과 한 줄로 배치
- 파일 표 상하 여백 축소(셀·버튼 padding 2px, 글자 크기 유지)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-08 13:42:55 +09:00
eomsangdonandClaude Fable 5 8d51f6d334 fix(B01): 임시 보관함 안내 문단 제거, 보관 기간은 제목 옆 태그로
- 섹션 제목 오른쪽에 "30일 보관" 태그 표시(서버 retention_days 반영)
- 빈 상태를 공용 표 블록에 위임해 프로젝트 컨테이너와 같은 문구·서식 사용
- 쓰지 않게 된 locale 키 2종 정리

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-08 13:32:43 +09:00
eomsangdonandClaude Fable 5 f60ecc255f feat(B01): 임시 보관함 UI를 그룹+파일 리스트 컨테이너로 개편
프로젝트/사용자 관리 컨테이너와 같은 형태로 통일한다. 등록 폼을 화면에 상시
노출하지 않고, 우측 상단 [+] 모달로 받아 그룹(임시 프로젝트명) 아래 파일 표를
그린다.

프론트엔드
- B01_Dashboard_UI_TempModal.ts 신설: 등록/추가 모달(임시 프로젝트명 + 파일 선택,
  고른 파일을 모달 안 표로 표시, 하단 [취소][확인] — 기존 대시보드 모달과 동일 규격)
- B01_Dashboard_UI_TempUpload.ts: 섹션 전체(제목·[+]·목록)를 반환하도록 변경.
  그룹 카드 + 파일 표(종류/파일명/크기/상태/작업), 그룹별 [파일 추가],
  파일별 [삭제], 진행률은 해당 파일 행 안에서 표시
- 청크마다 목록을 다시 조회하지 않고 막대 DOM만 갱신하도록 정리
- 대시보드 배치: 프로젝트 컨테이너 바로 아래(역할 3분기 모두)

백엔드
- DELETE /api/temp-uploads/{batch_id}/files/{file_type}: DB 행과 임시 저장소
  실제 파일을 함께 삭제. 필수 파일이 빠지면 상태를 uploading으로 되돌리고
  만료일은 최초 완료 시점 기준을 유지

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-08 13:23:58 +09:00
eomsangdonandClaude Fable 5 17834d8189 feat(B01,B03): 프로젝트 생성 전 임시 보관함 (temp upload)
라이다 원본은 업로드에 오래 걸려 프로젝트 정보 확정 전에 미리 올릴 수 있어야 한다.
계정에 묶인 임시 보관함을 만들고, 나중에 만든 프로젝트로 자료를 옮겨 쓴다.

저장·DB
- storage/tmp/{user_id}/{batch_id}/ 아래에 프로젝트 저장소와 동일한 구조를 써서
  청크 저장·병합 엔진(resolve_upload_destination/merge_upload_chunks)을 그대로 재사용
- 010_temp_upload.sql: temp_upload_batches / temp_upload_files 신설,
  upload_sessions.project_id NULL 허용 + temp_batch_id 추가(FK명 조회 후 재생성)
- config: TEMP_UPLOAD_DIR_NAME / TEMP_UPLOAD_RETENTION_DAYS(30) /
  TEMP_UPLOAD_CLEANUP_INTERVAL_HOURS(6)

백엔드
- B03_FileInput_Router_Temp.py: 묶음 생성·목록·삭제, 일반/청크 업로드, finalize,
  이어올리기 상태 조회, 프로젝트 연결(attach)
- attach: 파일 이동 후 input_files 등록, stage 0 완료, WF1·자동 설계 체인 트리거
- common_util_temp_cleanup.py: 완료 시각 기준 만료분 주기 삭제(서버 시작 시 1회 포함)

프론트엔드
- B01 대시보드 임시 보관함 섹션: 프로젝트 등록과 같은 폼 + 보관 목록.
  진행률은 모달이 아니라 리스트 행에 표시, 새로고침 후 이어올리기 지원
- B03 업로드 컨테이너 내부 불러오기 버튼과 선택 모달.
  완료된 묶음만 노출하고, 선택 후 업로드를 누르면 이동과 분석으로 이어짐

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-08 12:55:14 +09:00
eomsangdon cf459f97a6 260717_0 2026-07-17 15:11:31 +09:00
eomsangdon 4ac681bd10 260717_0 2026-07-17 12:51:47 +09:00
eomsangdon f533082537 260715_0 2026-07-15 18:33:33 +09:00
eomsangdon 6b1583103f 260710_1 2026-07-10 19:52:06 +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 bbda38a013 260707_4_대시보드 완료 2026-07-08 20:51:20 +09:00
eomsangdon 76d91efcb8 1 2026-07-08 20:28:24 +09:00
eomsangdon 38b5c2492e 260707_3 2026-07-08 19:59:25 +09:00
eomsangdon 8ffa9b097a 260707_2 2026-07-08 19:32:16 +09:00
eomsangdon 9c40dec070 260707_1_대시보드정리 1차 2026-07-08 19:04:20 +09:00
eomsangdon 3485eeb096 사요자 대시보드 추가 2026-07-08 18:12:34 +09:00