This commit is contained in:
2026-07-05 21:27:23 +09:00
parent 23d907265a
commit 3abc2edba6
83 changed files with 10351 additions and 1217 deletions
+230 -344
View File
@@ -1,388 +1,274 @@
# 프로젝트 리팩토링 및 마이그레이션 계획서
# B03~B06 기능 마이그레이션 계획서
**작성일:** 2026-07-05
**상태:** 계획 수립 완료
**목표:** 기존 POC(Proof of Concept) 코드를 정식 프로덕션 구조로 전환
**갱신일:** 2026-07-05
**상태:** 백엔드 마이그레이션 완료 — Stage 0~4 (B03~B06) 백엔드 이전 완료. 남은 항목은 프론트엔드(Vanilla TS) 재작성과 실제 DB 연동 검증.
**범위:** `B03_FileInput` ~ `B06_wf3_ProfileCross`
**DB:** MariaDB v10.6+ (aiomysql 드라이버, Raw SQL)
**진척 요약:**
- Stage 0 (공통 기반): ✅ 완료
- Stage 1 B03 (파일 입력): ✅ 백엔드 완료
- Stage 2 B04 (지표면 분석): ✅ 백엔드 완료 (필터 4종 + 모델 5종 + 스무딩 + 등고선 + 파이프라인)
- Stage 3 B05 (경로 설계): ✅ 백엔드 완료 (Dijkstra + ridge-valley + skeleton)
- Stage 4 B06 (종횡단 생성): ✅ 백엔드 완료 (sampler + 종횡단 + Repository/Router)
- 공통: 전 페이지 DB 접근을 aiomysql Raw SQL로 통일, 순수 계산부는 실데이터로 검증
- 남은 작업: B04~B06 프론트엔드(Vanilla TS/WebCAD), 실제 aislo_db 연동·구형 수치 비교
---
## 1. 현황 분석 (Baseline Assessment)
## 1. 확정 기준
### 1.1 기존 상태
- **위치:** `0_old/` 폴더에 백업 완료
- **제외 사항:** `venv/`, `node_modules/` 미포함 (별도 재설치 필요)
- **특성:** 프로토타입 개발용 단순 구조
### 1.2 신 구조 목표
- **거대 모듈 금지:** 기능별/페이지별 분할 자동화
- **수직 통합 관리:** 프론트엔드(TypeScript) + 백엔드(Python) 페어링
- **명확한 책임 분리:** 시스템 폴더 vs. 페이지 폴더 격리
- 기능 동작의 기준 원본은 `0_old/main.py``0_old/utils/`이다.
- `0_old/backend/app/`은 이전 프로토타입 참고 자료이며 최종 동작 기준으로 사용하지 않는다.
- 신규 배치 구조는 `.agent/structure.md`를 따른다. 구형 파일 구조는 승계하지 않는다.
- 백엔드는 `.agent/backend.md`, 프론트엔드는 `.agent/frontend.md`를 따른다.
- 저장 구조 및 DB 경로 열은 `.agent/db_schema_simple.md`의 단계별 파일시스템 구조를 따른다.
- DB 스키마 작성·수정은 별도 담당 작업이다. 이 마이그레이션은 확정된 DB 계약만 `aiomysql`와 Raw SQL로 사용한다.
- 루트 `main.py`에는 페이지 라우터 등록만 추가한다.
- 구형 React/TSX UI는 복사하지 않고 현재 Vanilla TypeScript 구조와 공통 UI 템플릿에 맞게 재작성한다.
---
## 2. 신 디렉토리 구조 (New Structure)
## 2. 작업 원칙
```
프로젝트_루트/
├── .agent/ # 에이전트 명세서
│ ├── structure.md # 폴더/파일 명명규칙
│ ├── agent.md # 기술스택 및 제약조건
│ ├── backend.md # 백엔드 명세서
│ ├── frontend.md # 프론트엔드 명세서
│ └── migration_plan.md # 본 파일 (마이그레이션 가이드)
├── common_util/ # 공통 유틸리티 모듈
│ ├── common_util_geometry.py # 기하학 연산 (Trimesh, Shapely)
│ ├── common_util_gis.py # GIS 유틸 (PostGIS, Geopandas)
│ ├── common_util_file.py # 파일 I/O 및 경로 관리
│ ├── common_util_validation.py # 데이터 검증 (Pydantic)
│ ├── common_util_math.py # 수학/통계 함수
│ └── common_util_string.ts # 문자열 처리 (TypeScript)
├── db_management/ # DB 스키마 및 마이그레이션
│ ├── schema.sql # PostgreSQL + PostGIS 초기 스키마
│ ├── migration_001_init.py # 마이그레이션 스크립트 v1
│ └── README.md # DB 운영 가이드
├── resources/ # UI 리소스 (로고, 이미지, 폰트)
│ ├── images/
│ │ ├── logo.svg
│ │ ├── favicon.ico
│ │ └── banners/
│ └── fonts/
│ └── noto-sans-kr.woff2
├── storage/ # 영구 저장소 (물리 파일)
│ └── README.md # 저장소 구조 설명
├── ui_template/ # 공통 UI 템플릿 및 테마
│ ├── ui_template_theme.css # 글로벌 색상/폰트 변수
│ ├── ui_template_locale.ts # 다국어 관리 (i18n)
│ ├── ui_template_elements.ts # 공통 컴포넌트 정의
│ └── ui_template_styles.css # 기본 컴포넌트 스타일
├── templates/ # 보고서/도면 템플릿
│ ├── template_report_standard.xlsx # 표준 보고서
│ ├── template_drawing_base.dwg # CAD 기본 도면
│ └── template_quantity_sheet.xlsx # 수량 산출서
├── config/ # 환경 설정
│ ├── config_system.py # 백엔드 파라미터
│ ├── config_db.py # DB 연결 설정
│ ├── config_frontend.ts # 프론트엔드 상수
│ └── .env.example # 환경 변수 템플릿
├── A01_Home/ # 로그인 전 01: 홈
│ ├── A01_Home_UI_Page.ts # 페이지 UI 컴포넌트
│ ├── A01_Home_UI_Style.css # 페이지 스타일
│ ├── A01_Home_Api_Fetch.py # API 라우터
│ └── A01_Home_Schema.py # Pydantic 스키마
├── A02_ProgDetail/ ... A08_Support/ # 로그인 전 페이지들 (동일 구조)
├── B01_AccountDetail/ # 로그인 후 01: 계정
├── B02_ProjRegister/ # 로그인 후 02: 프로젝트 등록
├── B03_FileInput/ # 로그인 후 03: 파일 입력
├── B04_wf1_Surface/ # Workflow 1: 지표면 분석
│ ├── B04_wf1_Surface_UI_View.ts # UI 뷰어
│ ├── B04_wf1_Surface_UI_Form.ts # 입력 폼
│ ├── B04_wf1_Surface_UI_Style.css
│ ├── B04_wf1_Surface_Api_Router.py # API 라우터
│ ├── B04_wf1_Surface_Engine.py # 연산 엔진 (Trimesh, PostGIS)
│ └── B04_wf1_Surface_Schema.py # 데이터 스키마
├── B05_wf2_Route/ ... B09_wf6_Estimation/ # 워크플로우 2-6 (동일 구조)
├── B10_Payment/ & B11_Status/ # 로그인 후 최종 페이지
├── main.py # FastAPI 애플리케이션 진입점
├── pyproject.toml # Python 의존성 (Poetry)
├── package.json & package-lock.json # Node.js 의존성
├── CLAUDE.md # 프로젝트 기본 정보
├── README.md # 프로젝트 개요
└── .gitignore # Git 제외 목록
### 2.1 함수 하나씩 이전
각 작업 단위는 다음 순서를 지킨다.
1. 대상 구형 함수와 직접 의존성 확인
2. 신규 페이지 폴더에 책임에 맞는 파일 하나 생성
3. 함수 하나만 이전·수정
4. 해당 함수 단위 테스트 또는 최소 실행 검증
5. 포맷터·린터 실행
6. 검증 완료 후 다음 함수 진행
한 번에 구형 모듈 전체를 복사하지 않는다. 구형 전역 경로, 동기식 파일 처리, 하드코딩 설정은 그대로 가져오지 않는다.
### 2.2 파일 분리
- `*_Router.py`: FastAPI 엔드포인트와 응답 변환
- `*_Schema.py`: Pydantic 요청·응답 검증
- `*_Engine_*.py`: 페이지 고유 연산
- `*_Repository.py`: `asyncpg` Raw SQL과 DB 경로 메타데이터 처리
- `common_util/`: 둘 이상의 페이지가 실제로 공유하는 경로·원자적 파일 쓰기·기하 유틸만 배치
- 단일 파일이 700줄에 도달하기 전에 기능별 파일 분할을 제안하고 승인 후 `structure.md`를 갱신한다.
### 2.3 저장소 경계
```text
storage/{company_slug}/{user_slug}/{project_id}/
├── B03_FileInput/
├── B04_wf1_Surface/
├── B05_wf2_Route/
└── B06_wf3_ProfileCross/
```
---
## 3. 마이그레이션 단계별 계획 (Phased Migration)
### Phase 1: 기초 인프라 (Infrastructure Setup) - 1-2주
**담당:** 전체
**목표:** 설정 및 공통 유틸 정리
#### 1.1 설정 파일 정리
- [ ] `config_system.py` 작성
- FastAPI 포트, 로깅 레벨, 알고리즘 파라미터
- 예: `MESH_GRID_SIZE`, `UPLOAD_MAX_MB`, `LOG_LEVEL`
- [ ] `config_db.py` 작성
- PostgreSQL 연결 문자열 (asyncpg)
- PostGIS 테이블 정의 위치
- [ ] `config_frontend.ts` 작성
- API 기본 URL, 파일 업로드 제한 크기
- WebCAD 렌더링 옵션
#### 1.2 공통 유틸 마이그레이션
- [ ] **0_old/** 에서 기존 유틸 함수 추출
- [ ] `common_util/` 내 분류:
- `common_util_geometry.py` ← Trimesh, Shapely 관련
- `common_util_gis.py` ← PostGIS 쿼리, Geopandas 변환
- `common_util_file.py` ← LAS, DEM, DWG 읽기/쓰기
- `common_util_validation.py` ← Pydantic 모델, 데이터 검증
#### 1.3 UI 템플릿 기초 설정
- [ ] `ui_template_theme.css` 작성
- CSS 변수 정의 (라이트/다크 모드)
- 예: `--color-bg`, `--color-text`, `--color-primary`
- [ ] `ui_template_locale.ts` 작성
- 한글 / 영문 키-값 쌍
- 예: `A01_Home_Title: ["반갑습니다", "Welcome"]`
- [ ] `ui_template_elements.ts` 작성
- 공통 버튼, 입력창, 카드 컴포넌트 정의
#### 1.4 DB 스키마 및 마이그레이션 준비
- [ ] `db_management/schema.sql` 작성
- 사용자, 프로젝트, 파일 정보 테이블
- PostGIS 기하학 타입 (geometry, raster)
- [ ] `db_management/migration_001_init.py` 작성
- asyncpg 기반 초기화 스크립트
#### 1.5 FastAPI 메인 애플리케이션 구조
- [ ] `main.py` 작성 (라우터 등록만)
```python
from fastapi import FastAPI
# A01_Home, B04_wf1_Surface 등에서 라우터 import
# app.include_router(a01_router, prefix="/api/a01")
```
각 페이지는 자기 폴더만 직접 생성·수정한다. 상위 단계 변경 시 하위 결과를 임의 삭제하지 않고 `stale_from`을 갱신한다.
---
### Phase 2: 로그인 전 페이지 (Pre-Login Pages) - 2-3주
**담당:** 프론트엔드 + 백엔드 (페이지별 페어)
**목표:** A01~A08 페이지 완성
## 3. 구형 기능 분석 결과
#### 2.1 페이지별 구조 (A01_Home 예시)
각 페이지는 다음 파일 구성:
### 3.1 B03_FileInput
**프론트엔드 (TypeScript)**
- `A01_Home_UI_Page.ts` ← 페이지 진입점 + 컴포넌트 조립
- `A01_Home_UI_Style.css` ← 페이지별 커스텀 스타일
구형 원본:
**백엔드 (Python)**
- `A01_Home_Api_Fetch.py` ← FastAPI 라우터 (`/api/a01/...`)
- `A01_Home_Schema.py` ← Pydantic 요청/응답 모델
- `0_old/main.py`: `check_sample`, `upload_files`
- 보조 참고: `0_old/backend/app/analyzer.py`의 파일 분석 함수
#### 2.2 A01_Home (홈) - Week 1
- [ ] `A01_Home_UI_Page.ts` 작성
- 로고, 최신 소식 패널, 사이트맵 링크
- [ ] `A01_Home_Api_Fetch.py` 작성
- `GET /api/a01/news` ← 최신 소식 조회
- [ ] 기본 스타일 적용
책임:
#### 2.3 A02_ProgDetail ~ A08_Support - Week 2-3
동일 구조로 순차 진행:
- [ ] A02_ProgDetail (프로그램 상세)
- [ ] A03_CompDetail (회사 상세)
- [ ] A04_NewsHistory (뉴스/이력)
- [ ] A05_EduDetail (교육)
- [ ] A06_Login (로그인) ← **핵심: JWT 토큰 발급**
- [ ] A07_Register (회원가입) ← **핵심: 사용자 생성, 이메일 검증**
- [ ] A08_Support (기술 지원)
- LAS/TIF/TFW/PRJ/DXF 업로드 검증
- `B03_FileInput/input/{file_type}/` 저장
- 파일 메타데이터 추출 및 `input_files` 기록
- 업로드 완료 상태 반환
B04로 넘길 기능:
- `process_pipeline`
- `run_ground_analysis`
- 포인트 필터링 및 지표면 모델 생성
### 3.2 B04_wf1_Surface
구형 원본:
- `0_old/main.py`: `process_pipeline`, `ensure_terrain_models`, 지표면·포인트 API
- `0_old/utils/structurizer.py`
- `filter_grid_min_z.py`, `filter_csf.py`, `filter_pmf.py`, `filter_ransac.py`
- `terrain_model_converter.py`, `surface_smoother.py`, `contour_extractor.py`
책임:
- LAS 구조화와 지면 필터 생성
- 변환 포인트클라우드 저장
- TIN/DTM/NURBS/implicit/meshfree 모델 생성
- 스무딩, 미리보기, 등고선 생성
- 지표면 모델 선택 확정 및 하위 단계 stale 전파
### 3.3 B05_wf2_Route
구형 원본:
- `0_old/main.py`: 경로점 CRUD, solve/result/confirm, stale 서명 처리
- `0_old/utils/route_solver.py`
- `0_old/utils/route_solver_ridgevalley.py`
- `0_old/utils/terrain_skeleton.py`
책임:
- BP/EP/CP/AP/FP 입력 검증과 저장
- Dijkstra 및 ridge-valley 경로 계산
- 경사·곡선반경·회피/금지 구역 검증
- 경로 결과 조회·확정 및 B06 stale 전파
### 3.4 B06_wf3_ProfileCross
구형 원본:
- `0_old/main.py`: sections generate/get/confirm 및 입력 서명 처리
- `0_old/utils/surface_elevation_sampler.py`
- `0_old/utils/section_generator.py`
책임:
- 확정 경로와 확정 지표면 모델 검증
- 종단 표고 프로필 생성
- 지정 측점 간격의 횡단면 생성
- 결과 조회·확정 및 재현성 서명 관리
---
### Phase 3: 로그인 후 기초 페이지 (Post-Login Basic Pages) - 1-2주
**담당:** 프론트엔드 + 백엔드
**목표:** B01~B03 페이지 완성
## 4. 함수 단위 실행 순서
#### 3.1 B01_AccountDetail (계정 상세)
- [ ] 사용자 정보 조회/수정
- [ ] 구독 상태, 다운로드 이력
### Stage 0 — 공통 기반
#### 3.2 B02_ProjRegister (프로젝트 등록)
- [ ] 프로젝트 생성 폼
- [ ] 고객사명 / 사용자명 / 프로젝트ID 관리
- [ ] **핵심:** `storage/[고객사]/[사용자]/[프로젝트ID]/` 자동 생성
- [x] `config_system.py`의 저장 경로에서 불필요한 `projects` 경로 제거
- [x] 프로젝트 루트와 B03~B06 단계별 경로를 안전하게 만드는 공통 경로 함수 추가
- [x] JSON 원자적 쓰기 함수 이전
- [x] `workflow.json` 읽기 및 stale 필드 원자적 갱신 함수 이전
- [x] 공통 함수별 테스트 작성
#### 3.3 B03_FileInput (파일 입력)
- [ ] 파일 업로드 UI (Drag & Drop)
- [ ] LAS, DEM, DWG 파일 검증
- [ ] `storage/` 경로에 물리 저장
### Stage 1 — B03_FileInput
- [x] `B03_FileInput_Schema.py`: 파일 종류·크기·확장자 검증 모델
- [x] `B03_FileInput_Engine.py`: 안전한 파일명과 목적 경로 결정 함수
- [x] `B03_FileInput_Engine.py`: 업로드 스트림 저장 함수
- [x] `B03_FileInput_Engine_Analyze.py`: LAS 메타데이터 분석 함수
- [x] `B03_FileInput_Engine_Analyze.py`: PRJ/TIF/TFW 메타데이터 분석 함수
- [x] `B03_FileInput_Repository.py`: `input_files` 저장 함수
- [x] `B03_FileInput_Router.py`: 업로드 엔드포인트
- [x] B03 프론트 드롭존·목록·검증·로딩 UI를 공통 컴포넌트 기반으로 작성
- [x] 업로드 통합 테스트
### Stage 2 — B04_wf1_Surface
- [x] LAS 구조화 함수 이전
- [x] grid-min-z 필터 함수 이전 및 검증
- [x] CSF 필터 함수 이전 및 검증
- [x] PMF 필터 함수 이전 및 검증
- [x] RANSAC 필터 함수 이전 및 검증
- [x] 지표면 모델 공통 컨텍스트 생성 함수 이전 (ModelContext + 메시 유틸)
- [x] TIN 생성 함수 이전
- [x] DTM 생성 함수 이전
- [x] NURBS 생성 함수 이전
- [x] implicit 생성 함수 이전
- [x] meshfree 생성 함수 이전
- [x] DTM/TIN 스무딩 함수 이전
- [x] 등고선 생성 함수 이전
- [x] 미리보기·메타데이터·모델 확정 라우트 추가 (analyze/models 라우트 + 파이프라인 manifest)
- [x] `processed_point_cloud`, `surface_models`, `terrain_layers` Raw SQL 저장 함수 추가 (aiomysql)
- [ ] B04 폼·WebCAD 뷰어를 Vanilla TypeScript로 재작성
- [ ] 샘플 LAS 결과를 구형 출력과 비교 검증
### Stage 3 — B05_wf2_Route
- [x] 경로점 Pydantic 모델 및 유효성 검사 이전 (Schema)
- [x] 경로점 저장·조회·초기화 함수 이전 (Repository)
- [x] 비용면 생성 및 캐시 함수 이전 (Solver)
- [x] Dijkstra 단일 구간 탐색 함수 이전 (Geometry)
- [x] 최적 경로 조립 함수 이전 (Solver solve_optimal_route)
- [x] 지형 skeleton 생성 함수 이전 (Skeleton, D8 흐름누적)
- [x] ridge-valley 탐색 함수 이전 (RidgeValley, 정속경사+fillet)
- [ ] 입력 서명·stale 판정 함수 이전
- [x] 경로 확정 함수 이전 (Repository confirm_route + confirm 라우트)
- [x] `routes`, `route_points`, `route_statistics` Raw SQL 저장 함수 추가 (aiomysql)
- [ ] B05 경로 편집·제약조건·결과 뷰어를 Vanilla TypeScript로 재작성
- [x] 기존 route solver 테스트를 신규 구조로 이관·통과
### Stage 4 — B06_wf3_ProfileCross
- [x] 지표면 sampler 인터페이스 이전 (Engine_Sampler: SurfaceElevationSampler Protocol)
- [x] DTM grid sampler 함수 이전 (DtmGridSampler, 4-꼭짓점 valid 검증)
- [x] 보간 sampler 함수 이전 (InterpolatedSurfaceSampler + build_surface_sampler 5종)
- [x] 측점 배열 생성 함수 이전 (Engine_Section: _chainages)
- [x] 경로 보간 및 접선 계산 함수 이전 (_interpolate_xy, _tangent_at)
- [x] 종단·횡단 생성 함수 이전 (generate_sections)
- [ ] 입력 서명·중복 실행 방지 함수 이전 (delete_sections_for_route로 멱등 재실행만 구현)
- [x] 결과 조회·확정 라우트 추가 (sections/generate·get·confirm 라우트)
- [x] `longitudinal_sections`, `cross_sections` Raw SQL 저장 함수 추가 (aiomysql Repository)
- [ ] B06 종단도·횡단 카드 UI를 Vanilla TypeScript로 재작성
- [ ] 구형 section 결과와 수치 비교 검증
**B06 백엔드 구현 파일:**
- `B06_wf3_ProfileCross_Engine_Sampler.py` — 표고 sampler (Protocol + DTM/보간 5종)
- `B06_wf3_ProfileCross_Engine_Section.py` — 종횡단 생성 (측점/접선/횡단 샘플)
- `B06_wf3_ProfileCross_Engine.py` — 오케스트레이터 (경로 GeoJSON→종횡단→파일 저장)
- `B06_wf3_ProfileCross_Repository.py` — aiomysql Raw SQL (2 테이블)
- `B06_wf3_ProfileCross_Schema.py` / `_Router.py` — Pydantic + FastAPI 라우트
**검증 상태:** B04(DTM)→B05(경로 70.71m)→B06(종단면+횡단면 5건) end-to-end 파일 생성 확인.
DB 저장 함수는 FakeCursor 기반 문법 검증만 수행 (실제 aislo_db 연동은 나스 서버 준비 후).
---
### Phase 4: Workflow 엔진 (1-4) - 4-6주
**담당:** 백엔드 주 (프론트엔드 보조)
**목표:** B04~B07 워크플로우 엔진 완성
## 5. API 및 상태 원칙
#### 4.1 B04_wf1_Surface (지표면 분석) - Week 1-2
**구조:**
```
B04_wf1_Surface/
├── B04_wf1_Surface_UI_View.ts # WebCAD 뷰어
├── B04_wf1_Surface_UI_Form.ts # 입력 폼 (좌측 패널)
├── B04_wf1_Surface_UI_Style.css
├── B04_wf1_Surface_Api_Router.py # GET/POST 엔드포인트
├── B04_wf1_Surface_Engine.py # Trimesh 메쉬 생성 로직
└── B04_wf1_Surface_Schema.py # Pydantic 모델
```
**구현:**
- [ ] LAS 포인트클라우드 → Trimesh 메쉬 변환
- [ ] 메쉬 좌표 직렬화 (JSON)
- [ ] WebGL 캔버스에서 렌더링
- [ ] 메쉬 정보 DB 저장 (경로만)
#### 4.2 B05_wf2_Route (경로 설계) - Week 2-3
- [ ] 지도 UI (2D 평면도)
- [ ] 드래그로 경로 그리기
- [ ] Geopandas + PostGIS 거리 계산
- [ ] 경로 점 배열 저장
#### 4.3 B06_wf3_ProfileCross (종횡단) - Week 3-4
- [ ] 경로 기반 고도 프로필 생성
- [ ] 종단도 + 횡단도 계산 (PostGIS)
- [ ] 기울기, 높이차 자동 산출
#### 4.4 B07_wf4_DesignDetail (상세 설계) - Week 4-5
- [ ] 도로 포장 두께, 기울기 입력
- [ ] Whitebox 토양 분석
- [ ] 3D 설계 도면 생성
- API 경로는 `/api/projects/{project_id}/...` 형태를 유지하되 페이지별 Router에서 선언한다.
- 모든 JSON 요청은 Pydantic 검증 후 Engine으로 전달한다.
- 긴 지형 연산은 이벤트 루프를 막지 않도록 실행 방식을 별도 검토한다.
- 오류 응답은 `{"status": "error", "message": "원인"}` 형식을 유지한다.
- 프론트 API 호출은 로딩 Overlay를 항상 시작·해제한다.
- UI 문자열은 `ui_template_locale.ts`에 먼저 등록한 뒤 참조한다.
- 상위 단계 재계산 시 하위 결과는 stale 처리하며 다른 페이지 폴더를 직접 삭제하지 않는다.
---
### Phase 5: 워크플로우 후반 (5-6) + 최종 페이지 - 2-3주
**담당:** 백엔드 주 + 프론트엔드
**목표:** B08~B11 완성
## 6. 검증 체크리스트
#### 5.1 B08_wf5_Quantity (수량 산출)
- [ ] 포장재, 흙 깍기/쌓기 수량 계산
- [ ] Excel 템플릿 자동 채우기
각 함수 이전 후:
#### 5.2 B09_wf6_Estimation (견적/문서)
- [ ] 단가 × 수량 = 금액 계산
- [ ] PDF 보고서 생성 (Jinja2 템플릿)
- [ ] DWG 도면 생성 (pyDWG)
- [ ] 구형 함수의 입력·출력 계약 비교
- [ ] 하드코딩 설정 제거 및 `config_system.py` 연결
- [ ] 신규 단계별 저장 경로 사용 확인
- [ ] 경로 이탈 및 파일명 공격 방지 확인
- [ ] 예외 처리와 표준 오류 응답 확인
- [ ] Python: `ruff format`, `ruff check --fix`
- [ ] TypeScript/CSS: `npx prettier --write`
- [ ] 단위 테스트 실행
- [ ] 관련 통합 테스트 실행
- [ ] 단일 파일 700줄 미만 확인
#### 5.3 B10_Payment (결재)
- [ ] 견적서 검토 및 승인
- [ ] 결재자 서명 프로세스
단계 완료 후:
#### 5.4 B11_Status (상태/다운로드)
- [ ] 프로젝트 상태 조회
- [ ] 최종 산출물 다운로드
- [ ] B03 업로드 파일과 DB 메타데이터 일치
- [ ] B04 지표면 모델의 범위·점 수·표고 통계 비교
- [ ] B05 경로 길이·경사·곡선반경·제약 위반 비교
- [ ] B06 측점 수·종단 표고·횡단 좌표 비교
- [ ] 다중 브라우저 polling 및 stale 전파 확인
---
## 4. 기술 구현 가이드 (Technical Guidelines)
## 7. 작업 경계와 보류 항목
### 4.1 백엔드 파이썬 스타일
```python
# config 반드시 import
from config.config_system import MESH_GRID_SIZE
from config.config_db import DB_URL
# 공통 유틸 사용
from common_util.common_util_geometry import create_mesh_from_points
from common_util.common_util_validation import validate_project_id
# Raw SQL (ORM 금지)
query = "SELECT ST_Volume(geom) FROM surfaces WHERE project_id = $1"
result = await db_pool.fetchval(query, project_id)
# 에러 처리
try:
mesh = create_mesh(points)
except ValueError as e:
return {"status": "error", "message": str(e)}
```
### 4.2 프론트엔드 TypeScript 스타일
```typescript
// CSS 변수 사용 (색상 하드코딩 금지)
const styles = `
.panel {
background-color: var(--color-bg);
color: var(--color-text);
}
`;
// 다국어 (i18n 필수)
const title = ui_locales.A01_Home_Title[currentLanguageIndex];
// 이벤트 핸들러 명명법
function onB04_Surface_Calculate_Click() { ... }
// 로딩 스피너 (API 호출 시 필수)
showLoadingOverlay();
const result = await fetchAPI("/api/b04/calculate", data);
hideLoadingOverlay();
```
### 4.3 파일 정보 저장 규칙
- **DB에 저장:** 메타데이터만
- 파일명, 원본 경로, 업로드 시간, 파일 크기
- **물리 저장:** `storage/[고객사]/[사용자]/[프로젝트ID]/`
- LAS, DEM, 중간 계산 파일, 최종 메쉬
- DB 테이블·FK·인덱스 정의 변경은 본 작업에서 수행하지 않는다.
- `.agent/db_schema_simple.md`는 DB 담당자의 작업 영역이므로 직접 수정하지 않는다.
- DB 스키마가 확정되지 않은 Repository 함수는 인터페이스만 계획하고 임의 열을 만들지 않는다.
- B07 이후 기능은 이번 마이그레이션 범위에서 제외한다.
- 구형 샘플 데이터는 검증 입력으로만 사용하고 신규 영구저장소로 자동 복사하지 않는다.
---
## 5. 의존성 (Dependencies)
## 8. 다음 실행 단위
### Python 라이브러리
```
fastapi==0.104.1
pydantic==2.5.0
asyncpg==0.29.0
trimesh==3.23.0
geopandas==0.14.0
shapely==2.0.1
rasterio==1.3.8
laspy==2.4.1
whitebox==2.3.0
python-multipart==0.0.6
jinja2==3.1.2
pydwg==0.2.0
```
### Node.js 라이브러리
```
typescript@5.x
react@18.x (또는 vanilla TS)
webpack@5.x
tailwindcss@3.x (또는 커스텀 CSS)
```
---
## 6. 체크리스트 (Checklist)
### 시작 전 (Pre-Migration)
- [ ] `0_old/` 백업 확인
- [ ] git 커밋 (`"Refactor: Start migration to new structure"`)
- [ ] 모든 폴더 생성 완료 (Phase 1에서 수행)
### 각 Phase별 마무리
- [ ] 코드 포맷팅 (`ruff format`, `prettier --write`)
- [ ] 린터 체크 (`ruff check`)
- [ ] 단위 테스트 작성
- [ ] git 커밋 (Phase별로 구분)
### 최종 (Post-Migration)
- [ ] 전체 시스템 통합 테스트
- [ ] 프로덕션 배포 (Docker)
- [ ] 사용자 승인
---
## 7. 참고 자료
- **폴더 구조:** `.agent/structure.md`
- **백엔드 명세:** `.agent/backend.md`
- **프론트엔드 명세:** `.agent/frontend.md`
- **기술 스택:** `.agent/agent.md`
---
**다음 단계:** Phase 1 시작 → `config/` 및 `common_util/` 작성
첫 구현은 Stage 0의 저장 경로 함수 하나로 시작한다. 함수와 테스트를 검증한 뒤 다음 공통 함수로 이동한다.