260706_0_회사싱크 후 커밋
This commit is contained in:
@@ -12,7 +12,8 @@
|
||||
- Stage 3 B05 (경로 설계): ✅ 백엔드 완료 (Dijkstra + ridge-valley + skeleton)
|
||||
- Stage 4 B06 (종횡단 생성): ✅ 백엔드 완료 (sampler + 종횡단 + Repository/Router)
|
||||
- 공통: 전 페이지 DB 접근을 aiomysql Raw SQL로 통일, 순수 계산부는 실데이터로 검증
|
||||
- 남은 작업: B04~B06 프론트엔드(Vanilla TS/WebCAD), 실제 aislo_db 연동·구형 수치 비교
|
||||
- Stage 2~4 프론트엔드 폼/결과 UI: ✅ 완료 (B04~B06 UI_Page + Api_Fetch + CSS + locale, tsc 타입체크 통과)
|
||||
- 남은 작업: B04~B06 **WebCAD 3D/차트 뷰어**, 실제 aislo_db 연동·구형 수치 비교
|
||||
|
||||
---
|
||||
|
||||
@@ -178,7 +179,8 @@ B04로 넘길 기능:
|
||||
- [x] 등고선 생성 함수 이전
|
||||
- [x] 미리보기·메타데이터·모델 확정 라우트 추가 (analyze/models 라우트 + 파이프라인 manifest)
|
||||
- [x] `processed_point_cloud`, `surface_models`, `terrain_layers` Raw SQL 저장 함수 추가 (aiomysql)
|
||||
- [ ] B04 폼·WebCAD 뷰어를 Vanilla TypeScript로 재작성
|
||||
- [x] B04 폼·모델 목록 UI를 Vanilla TypeScript로 재작성 (UI_Page + Api_Fetch + CSS + locale)
|
||||
- [ ] B04 WebCAD 3D 뷰어(포인트클라우드/메시 렌더) 추가
|
||||
- [ ] 샘플 LAS 결과를 구형 출력과 비교 검증
|
||||
|
||||
### Stage 3 — B05_wf2_Route
|
||||
@@ -193,7 +195,8 @@ B04로 넘길 기능:
|
||||
- [ ] 입력 서명·stale 판정 함수 이전
|
||||
- [x] 경로 확정 함수 이전 (Repository confirm_route + confirm 라우트)
|
||||
- [x] `routes`, `route_points`, `route_statistics` Raw SQL 저장 함수 추가 (aiomysql)
|
||||
- [ ] B05 경로 편집·제약조건·결과 뷰어를 Vanilla TypeScript로 재작성
|
||||
- [x] B05 경로점 입력·제약조건·결과 메트릭 UI를 Vanilla TypeScript로 재작성 (UI_Page + Api_Fetch + CSS + locale)
|
||||
- [ ] B05 경로 WebCAD 뷰어(노선 폴리라인 렌더/편집) 추가
|
||||
- [x] 기존 route solver 테스트를 신규 구조로 이관·통과
|
||||
|
||||
### Stage 4 — B06_wf3_ProfileCross
|
||||
@@ -207,7 +210,8 @@ B04로 넘길 기능:
|
||||
- [ ] 입력 서명·중복 실행 방지 함수 이전 (delete_sections_for_route로 멱등 재실행만 구현)
|
||||
- [x] 결과 조회·확정 라우트 추가 (sections/generate·get·confirm 라우트)
|
||||
- [x] `longitudinal_sections`, `cross_sections` Raw SQL 저장 함수 추가 (aiomysql Repository)
|
||||
- [ ] B06 종단도·횡단 카드 UI를 Vanilla TypeScript로 재작성
|
||||
- [x] B06 측점·횡단 옵션·결과 메트릭 UI를 Vanilla TypeScript로 재작성 (UI_Page + Api_Fetch + CSS + locale)
|
||||
- [ ] B06 종단도·횡단 카드 WebCAD 뷰어(프로필 차트 렌더) 추가
|
||||
- [ ] 구형 section 결과와 수치 비교 검증
|
||||
|
||||
**B06 백엔드 구현 파일:**
|
||||
|
||||
+40
-7
@@ -96,14 +96,47 @@ my-project/
|
||||
│ ├── B03_FileInput_Engine_Analyze.py # 원본 파일 메타데이터 분석
|
||||
│ ├── B03_FileInput_Repository.py # input_files asyncpg Raw SQL
|
||||
│ └── B03_FileInput_Router.py # 다중 파일 업로드 API
|
||||
├── B04_wf1_Surface/ # 로그인 후 04: 1차 workflow (지표면 모델 분석) — 워크플로우 셸
|
||||
│ ├── B04_wf1_Surface_UI_Page.ts
|
||||
├── B04_wf1_Surface/ # 로그인 후 04: 1차 workflow (지표면 모델 분석)
|
||||
│ ├── B04_wf1_Surface_UI_Page.ts # 3단 레이아웃 (필터/표현 선택 폼 + 모델 목록)
|
||||
│ ├── B04_wf1_Surface_UI_Style.css # B04 고유 폼 그룹/모델 카드 스타일
|
||||
│ ├── B04_wf1_Surface_Api_Fetch.ts # surface/analyze·models API 클라이언트
|
||||
│ ├── B04_wf1_Surface_Schema.py # 분석 요청/응답 Pydantic 검증
|
||||
│ ├── B04_wf1_Surface_Engine.py # 지표면 분석 오케스트레이터
|
||||
│ ├── B04_wf1_Surface_Engine_Structurize.py # LAS/LAZ 구조화
|
||||
│ └── B04_wf1_Surface_Engine_Filter_Grid.py # grid minimum-Z 필터
|
||||
├── B05_wf2_Route/ # 로그인 후 05: 2차 workflow (경로설계) — 워크플로우 셸
|
||||
│ └── B05_wf2_Route_UI_Page.ts
|
||||
├── B06_wf3_ProfileCross/ # 로그인 후 06: 3차 workflow (종횡단 생성) — 워크플로우 셸
|
||||
│ └── B06_wf3_ProfileCross_UI_Page.ts
|
||||
│ ├── B04_wf1_Surface_Engine_Ground.py # 지면 분석 진입
|
||||
│ ├── B04_wf1_Surface_Engine_Filter_Grid.py # grid minimum-Z 필터
|
||||
│ ├── B04_wf1_Surface_Engine_Filter_CSF.py # CSF 필터
|
||||
│ ├── B04_wf1_Surface_Engine_Filter_PMF.py # PMF 필터
|
||||
│ ├── B04_wf1_Surface_Engine_Filter_RANSAC.py # RANSAC 필터
|
||||
│ ├── B04_wf1_Surface_Engine_ModelContext.py # 모델 공통 컨텍스트/메시 유틸
|
||||
│ ├── B04_wf1_Surface_Engine_ModelBuild.py # TIN/DTM/NURBS/implicit/meshfree 생성
|
||||
│ ├── B04_wf1_Surface_Engine_Smooth.py # DTM/TIN 스무딩
|
||||
│ ├── B04_wf1_Surface_Engine_Contour.py # 등고선 생성
|
||||
│ ├── B04_wf1_Surface_Engine_Pipeline.py # 파이프라인 manifest
|
||||
│ ├── B04_wf1_Surface_Repository.py # processed_point_cloud/surface_models aiomysql Raw SQL
|
||||
│ └── B04_wf1_Surface_Router.py # surface/analyze·models API
|
||||
├── B05_wf2_Route/ # 로그인 후 05: 2차 workflow (경로설계)
|
||||
│ ├── B05_wf2_Route_UI_Page.ts # 3단 레이아웃 (제어점/제약 폼 + 결과 메트릭)
|
||||
│ ├── B05_wf2_Route_UI_Style.css # B05 고유 제어점 행/제약 그룹 스타일
|
||||
│ ├── B05_wf2_Route_Api_Fetch.ts # route/solve·confirm API 클라이언트
|
||||
│ ├── B05_wf2_Route_Schema.py # 경로 탐색 요청/응답 Pydantic 검증
|
||||
│ ├── B05_wf2_Route_Engine.py # 경로 설계 오케스트레이터
|
||||
│ ├── B05_wf2_Route_Engine_Geometry.py # Dijkstra 단일 구간 탐색
|
||||
│ ├── B05_wf2_Route_Engine_Solver.py # 비용면 생성 + 최적 경로 조립
|
||||
│ ├── B05_wf2_Route_Engine_Skeleton.py # 지형 skeleton (D8 흐름누적)
|
||||
│ ├── B05_wf2_Route_Engine_RidgeValley.py # ridge-valley 탐색
|
||||
│ ├── B05_wf2_Route_Repository.py # routes/route_points/route_statistics aiomysql Raw SQL
|
||||
│ └── B05_wf2_Route_Router.py # route/solve·confirm API
|
||||
├── B06_wf3_ProfileCross/ # 로그인 후 06: 3차 workflow (종횡단 생성)
|
||||
│ ├── B06_wf3_ProfileCross_UI_Page.ts # 3단 레이아웃 (측점/횡단 옵션 폼 + 결과 메트릭)
|
||||
│ ├── B06_wf3_ProfileCross_UI_Style.css # B06 고유 옵션 그룹/결과 메트릭 스타일
|
||||
│ ├── B06_wf3_ProfileCross_Api_Fetch.ts # sections/generate·get·confirm API 클라이언트
|
||||
│ ├── B06_wf3_ProfileCross_Schema.py # 종횡단 생성 요청/응답 Pydantic 검증
|
||||
│ ├── B06_wf3_ProfileCross_Engine.py # 종횡단 생성 오케스트레이터
|
||||
│ ├── B06_wf3_ProfileCross_Engine_Sampler.py # 표고 sampler (Protocol + DTM/보간 5종)
|
||||
│ ├── B06_wf3_ProfileCross_Engine_Section.py # 종횡단 생성 (측점/접선/횡단 샘플)
|
||||
│ ├── B06_wf3_ProfileCross_Repository.py # longitudinal/cross_sections aiomysql Raw SQL
|
||||
│ └── B06_wf3_ProfileCross_Router.py # sections/generate·get·confirm API
|
||||
├── B07_wf4_DesignDetail/ # 로그인 후 07: 4차 workflow (상세설계) — 워크플로우 셸
|
||||
│ └── B07_wf4_DesignDetail_UI_Page.ts
|
||||
├── B08_wf5_Quantity/ # 로그인 후 08: 5차 workflow (수량 산출) — 워크플로우 셸
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
---
|
||||
document_type: entrypoint
|
||||
priority: CRITICAL
|
||||
version: 2.0
|
||||
---
|
||||
# Aislo (아이슬로) 프로젝트 지식 베이스 진입점
|
||||
|
||||
이 문서는 AI 코딩 에이전트(Codex, Claude, Antigravity 등)가 프로젝트의 방대한 정보 중 **현재 필요한 컨텍스트를 정확하게 로드**하기 위한 인덱스입니다. 임의로 구조를 추론하지 말고, 작업할 영역에 맞춰 아래 연결된 상세 명세서를 반드시 읽고 코딩을 진행하십시오.
|
||||
|
||||
## 🧭 컨텍스트 라우팅 (필요한 문서를 로드하는 방법)
|
||||
|
||||
작업 성격에 따라 다음 번호의 문서를 확인하십시오.
|
||||
모든 문서는 이 폴더(`.agent/test/`) 하위에 존재합니다.
|
||||
|
||||
1. **[구조/아키텍처 파악]** `01_Architecture_and_Structure.md`
|
||||
- **언제 읽는가:** 새로운 페이지를 추가하거나, 파일(프론트/백엔드)을 생성/수정해야 할 때.
|
||||
- **내용:** A00~B11까지의 전체 디렉토리 트리, 파일 명명 규칙(수직 통합).
|
||||
2. **[DB 연동 및 쿼리 작성]** `02_Database_Schema.md`
|
||||
- **언제 읽는가:** DB 테이블 조회, 쿼리문 작성, 관계(FK) 및 데이터 저장이 필요할 때.
|
||||
- **내용:** 18개 전체 테이블 스키마, 핵심 쿼리 예제, 공간 데이터(JSON) 설계 원칙.
|
||||
3. **[백엔드 로직/저장소 제어]** `03_Backend_Logic_and_Storage.md`
|
||||
- **언제 읽는가:** FastAPI 라우터, 비즈니스 엔진 로직, 영구저장소(물리 파일) 입출력을 다룰 때.
|
||||
- **내용:** Raw SQL 제약, 워크플로우 6단계 폴더 매핑, `workflow.json` 기반의 Stale 상태 동기화 기법.
|
||||
4. **[프론트엔드 UI/디자인 구현]** `04_Frontend_and_Design.md`
|
||||
- **언제 읽는가:** TypeScript 이벤트 핸들러, 화면 레이아웃, 다국어 처리, CSS 스타일링을 수행할 때.
|
||||
- **내용:** 3단 레이아웃 제약, 다국어(`ui_locales`) 제약, Wiza 테마(Britti Sans, 색상 토큰) 및 프롬프트 가이드.
|
||||
|
||||
---
|
||||
|
||||
## 🛑 범용 제약 사항 (절대 준수)
|
||||
1. **700줄 제한:** 단일 파일 코드 작성/수정 시 700줄이 넘으면 기능별 분할 필수.
|
||||
2. **코드 포맷팅:** 작성 후 반드시 포맷터 적용 (Python: `ruff`, TS/CSS: `prettier`).
|
||||
3. **인코딩:** 모든 파일은 UTF-8.
|
||||
4. **DB 원칙:** `aiomysql` 기반 비동기 통신. **ORM 사용은 절대 금지**하며 무조건 Raw SQL 사용.
|
||||
5. **다국어 규칙:** 프론트엔드 내 UI 텍스트 하드코딩 금지. 반드시 다국어 인덱스 배열 방식 준수.
|
||||
@@ -0,0 +1,65 @@
|
||||
---
|
||||
document_type: architecture
|
||||
priority: HIGH
|
||||
---
|
||||
# 프로젝트 구조 및 아키텍처 명세
|
||||
|
||||
## 1. 아키텍처 기본 원칙
|
||||
* **수직 통합:** 백엔드 로직과 프론트엔드 코드는 페이지 폴더(`A01_`, `B01_` 등)별로 격리. 거대 단일 모듈을 금지하고 기능별로 파일을 분할한다.
|
||||
* **루트 main.py:** FastAPI 진입점으로, 라우터 등록(`include_router`)만 수행. 비즈니스 로직 작성 금지.
|
||||
* **명명 규칙:**
|
||||
- 백엔드: `[폴더명]_Router.py`, `[폴더명]_Engine.py`, `[폴더명]_Schema.py`, `[폴더명]_Repository.py`
|
||||
- 프론트엔드: `[폴더명]_UI_Page.ts`, `[폴더명]_UI_Style.css`, `[폴더명]_Api_Fetch.ts`
|
||||
- 로그인 전은 `A01_`, 로그인 후는 `B01_`, 워크플로우는 `B04_wf1_` 형태 적용.
|
||||
- 공통 유틸 코드는 `common_util_[기능].확장자`
|
||||
|
||||
## 2. 전체 디렉토리 트리 상세
|
||||
|
||||
```text
|
||||
my-project/
|
||||
├── A00_Common/ # 프론트엔드 공통 인프라
|
||||
│ ├── main.ts # 앱 진입점
|
||||
│ ├── router.ts # 해시 기반 SPA 라우터
|
||||
│ └── app_shell.ts # 공통 헤더/푸터
|
||||
├── common_util/ # 공통 유틸리티
|
||||
│ ├── common_util_validate.ts # 프론트 유효성 검사
|
||||
│ ├── common_util_storage.py # 저장 경로 로직
|
||||
│ └── common_util_workflow.py # 상태 동기화 로직
|
||||
├── config/ # 환경 설정
|
||||
│ ├── config_system.py # 시스템 파라미터 (제어 변수 중앙화)
|
||||
│ └── config_db.py # DB 설정
|
||||
├── db_management/ # 스키마 및 마이그레이션
|
||||
├── resources/ # 정적 리소스 (에셋)
|
||||
├── storage/ # 물리 파일 영구 저장소 (DB와 매핑)
|
||||
├── templates/ # 보고서/도면 양식
|
||||
├── ui_template/ # 공통 UI 컴포넌트, 테마, 다국어
|
||||
│ ├── ui_template_theme.css
|
||||
│ ├── ui_template_locale.ts
|
||||
│ └── ui_template_elements.ts
|
||||
|
||||
# --- 로그인 전 페이지 (A 그룹) ---
|
||||
├── A01_Home/ # 홈 (소개, 소식)
|
||||
├── A02_ProgDetail/ # 프로그램 상세 (6단계 워크플로우 설명)
|
||||
├── A03_CompDetail/ # 회사 상세 (미션 등)
|
||||
├── A04_NewsHistory/ # 최신소식 및 개선 이력
|
||||
├── A05_EduDetail/ # 교육 상세
|
||||
├── A06_Login/ # 로그인 (이메일/비밀번호)
|
||||
├── A07_Register/ # 회원가입
|
||||
├── A08_Support/ # 기술지원 요청
|
||||
|
||||
# --- 로그인 후 페이지 (B 그룹) ---
|
||||
├── B01_AccountDetail/ # 계정 관리
|
||||
├── B02_ProjRegister/ # 신규 프로젝트 등록
|
||||
├── B03_FileInput/ # [WF0] 원본 파일 입력 (다중 파일 업로드)
|
||||
├── B04_wf1_Surface/ # [WF1] 지표면 모델 분석 (LAS 처리)
|
||||
├── B05_wf2_Route/ # [WF2] 경로 설계 (최적 경로 계산)
|
||||
├── B06_wf3_ProfileCross/ # [WF3] 종횡단 생성 (단면 추출)
|
||||
├── B07_wf4_DesignDetail/ # [WF4] 상세 설계 (구조물 배치)
|
||||
├── B08_wf5_Quantity/ # [WF5] 수량 산출 (물량 집계)
|
||||
├── B09_wf6_Estimation/ # [WF6] 견적/최종 산출물 생성
|
||||
├── B10_Payment/ # 결제 관리
|
||||
└── B11_Status/ # 상태 출력 페이지
|
||||
|
||||
├── main.py # FastAPI 루트
|
||||
└── package.json, requirements.txt 등
|
||||
```
|
||||
@@ -0,0 +1,20 @@
|
||||
---
|
||||
document_type: rules
|
||||
priority: CRITICAL
|
||||
---
|
||||
# 프로젝트 기본 규칙 및 제약 (Rules & Constraints)
|
||||
|
||||
## 🚨 필수 행동 지침 (Do's)
|
||||
- **[MUST]** 코드 작성 전 반드시 `02_Architecture_and_Structure.md`의 구조를 확인하고 적절한 위치에 작성한다.
|
||||
- **[MUST]** 700줄 제한: 단일 파일이 700줄을 초과할 경우 사전 공지하고 기능별로 파일을 분할한다.
|
||||
- **[MUST]** 인코딩은 반드시 **UTF-8** 표준으로 통일한다.
|
||||
- **[MUST]** 코드 작성이 완료되면 다음 포맷터를 실행한다.
|
||||
- Python: `ruff format [파일명]`, `ruff check --fix [파일명]`
|
||||
- TypeScript/CSS: `npx prettier --write [파일명]`
|
||||
- **[MUST]** 외부 라이브러리 추가 시 프로젝트 호환성을 고려하고 무분별한 사용을 지양한다.
|
||||
|
||||
## 🛑 금지 행동 지침 (Don'ts)
|
||||
- **[DON'T]** 하드코딩 금지: 제어 변수/파라미터는 `config/config_system.py`에서, UI 문자열은 `ui_template/ui_template_locale.ts`에서 가져와야 한다.
|
||||
- **[DON'T]** 임의 파일 경로 생성 금지: 모든 파일 입출력 및 저장은 `05_Workflow_and_Storage.md`에 정의된 6단계 워크플로우 폴더 경로를 준수해야 한다.
|
||||
- **[DON'T]** 백엔드에서 중간 산출물이나 임시 파일을 MariaDB에 직접 바이너리로 저장하지 않는다. 물리 파일로 저장 후 DB에는 경로(프로젝트 상대 경로)만 기록한다.
|
||||
- **[DON'T]** 삭제 및 덮어쓰기 금지: 다른 단계의 산출물을 직접 삭제하거나 덮어쓰지 않고 stale 상태를 통해 재계산 필요성을 전파한다.
|
||||
@@ -0,0 +1,27 @@
|
||||
---
|
||||
document_type: architecture
|
||||
priority: HIGH
|
||||
---
|
||||
# 파일 구조 및 명명 규칙
|
||||
|
||||
## 📂 아키텍처 원칙
|
||||
- **수직 통합:** 프론트엔드(TypeScript)와 백엔드(Python) 파일을 기능/페이지별로 같은 폴더(`A01_`, `B01_` 등)에 격리하여 관리한다. (단일 거대 모듈 금지)
|
||||
- **루트 `main.py`:** FastAPI의 진입점. 라우터 등록(`include_router`)만 수행하고 비즈니스 로직은 절대 작성하지 않는다.
|
||||
|
||||
## 📝 명명 규칙
|
||||
- **폴더명:**
|
||||
- 로그인 전 페이지: `A01_`, `A02_` ...
|
||||
- 로그인 후 페이지: `B01_`, `B02_` ...
|
||||
- 워크플로우 페이지: `B04_wf1_`, `B05_wf2_` ...
|
||||
- 공통/시스템 폴더: `A00_Common`, `common_util`, `config` 등 접두사 없이 영문명 사용.
|
||||
- **파일명:** `[폴더명(페이지명)]_[기능]_[기타사양].[확장자]` 형태 필수.
|
||||
- 예시: `B04_wf1_Surface_UI_Page.ts`, `B04_wf1_Surface_Router.py`
|
||||
- **공통 모듈:** `common_util` 폴더 내에 `common_util_[기능].[확장자]` 형태로 보관.
|
||||
|
||||
## 🏗️ 주요 폴더 구조 요약
|
||||
- `A00_Common/`: 프론트엔드 공통 인프라 (SPA 라우터, 앱 셸 등)
|
||||
- `common_util/`: 공통 유틸리티 코드 (검증, 스토리지 제어 등)
|
||||
- `config/`: 시스템 설정, DB 설정, TS/Vite 환경 설정
|
||||
- `ui_template/`: 공통 UI 테마, 컴포넌트, 다국어 파일 배열
|
||||
- `storage/`: 파일 영구 저장소 (DB 경로와 연동됨)
|
||||
- `B03_FileInput/` ~ `B09_wf6_Estimation/`: 핵심 6단계 워크플로우 페이지 및 API
|
||||
@@ -0,0 +1,60 @@
|
||||
---
|
||||
document_type: database
|
||||
priority: CRITICAL
|
||||
---
|
||||
# 데이터베이스 스키마 명세 (MariaDB)
|
||||
|
||||
MariaDB v10.6+를 사용하며, 총 18개의 테이블로 구성됩니다. ORM 없이 Raw SQL과 `aiomysql` 드라이버를 사용합니다. **공간 데이터(GEOMETRY)는 지원 한계로 인해 JSONB 또는 TEXT(GeoJSON)로 저장합니다.**
|
||||
|
||||
## 테이블 목록 및 컬럼 구조
|
||||
|
||||
### 1. 사용자 & 프로젝트 (Core)
|
||||
* **`users`**: `id`(PK), `email`, `password_hash`, `name`, `position`, `department`, `phone`, `company_id`(FK)
|
||||
* **`companies`**: `id`(PK), `name`, `business_registration_number`, `business_address`, `business_owner`, `business_status`
|
||||
* **`projects`**: `id`(UUID, PK), `user_id`(FK), `company_id`(FK), `name`, `region`, `road_type`, `status`, `crs_epsg`, `storage_path`
|
||||
* **`project_versions`**: `id`, `project_id`, `version_num`, `data`(JSONB)
|
||||
|
||||
### 2. 파일 & 지표면 데이터 (WF0, WF1)
|
||||
* **`input_files`**: `id`(PK), `project_id`(FK), `file_type`(las, tif 등), `original_filename`, `raw_file_path`, `crs_epsg`, `metadata`(JSONB)
|
||||
* **`processed_point_cloud`**: `id`, `input_file_id`, `project_id`, `processed_file_path`, `converted_file_path`, `min_z`, `max_z` 등 통계치
|
||||
* **`surface_models`**: `id`, `project_id`, `model_type`(dem_grid, tin 등), `model_file_path`, `generation_params`(JSONB)
|
||||
* **`terrain_layers`**: `id`, `surface_model_id`, `layer_name`, `layer_file_path`(geojson 등)
|
||||
|
||||
### 3. 경로 설계 (WF2)
|
||||
* **`routes`**: `id`(PK), `project_id`, `surface_model_id`, `status`, `geometry`(LineString JSON), `route_data_path`, `constraints`(JSONB)
|
||||
* **`route_points`**: `id`, `route_id`, `chainage_m`, `geometry`(Point JSON), `elevation_m`
|
||||
* **`route_statistics`**: `id`, `route_id`, `mean_slope`, `cut_volume_m3`, `fill_volume_m3`
|
||||
|
||||
### 4. 종횡단 및 구조물 설계 (WF3, WF4)
|
||||
* **`longitudinal_sections`**: `id`, `project_id`, `route_id`, `longitudinal_file_path`, `data`(JSONB - chainages, elevations 등 배열)
|
||||
* **`cross_sections`**: `id`, `route_id`, `chainage_m`, `cross_section_file_path`, `data`(JSONB - left_slope, cut_volume_m3 등)
|
||||
* **`structures`**: `id`, `cross_section_id`, `structure_type`, `location`(LEFT/RIGHT/CENTER), `length_m`, `geometry`(Polygon JSON), `structure_data_path`
|
||||
|
||||
### 5. 수량 산출 및 산출물 (WF5, WF6)
|
||||
* **`quantity_items`**: `id`, `project_id`, `category`, `item_name`, `quantity_design`, `quantity_actual`, `unit_price`, `quantity_data_path`
|
||||
* **`outputs`**: `id`, `project_id`, `output_type`, `outputs_directory_path`
|
||||
* **`output_files`**: `id`, `output_id`, `file_type`, `output_file_path`
|
||||
|
||||
### 6. 로그 (Audit)
|
||||
* **`audit_logs`**, **`change_logs`**
|
||||
|
||||
---
|
||||
|
||||
## 💡 주요 원칙 (DB vs File System)
|
||||
- **DB에는 메타데이터와 파일 시스템의 "상대 경로"만 기록합니다.** (예: `input_files.raw_file_path = "B03_FileInput/input/las/cloud.las"`)
|
||||
- 대용량 파일(LAS, TIF, GeoJSON)은 MariaDB에 Blob으로 저장하지 않습니다.
|
||||
|
||||
## 📝 쿼리 작성 예제 (Raw SQL & aiomysql)
|
||||
```python
|
||||
# 쿼리에는 ORM이 아닌 %s 플레이스홀더를 사용해야 함
|
||||
async def get_project_route(pool, project_id: str):
|
||||
async with pool.acquire() as conn:
|
||||
async with conn.cursor() as cur:
|
||||
await cur.execute("""
|
||||
SELECT r.id, r.total_length_m, r.route_data_path
|
||||
FROM routes r
|
||||
WHERE r.project_id = %s
|
||||
ORDER BY r.computed_at DESC LIMIT 1
|
||||
""", (project_id,))
|
||||
return await cur.fetchone()
|
||||
```
|
||||
@@ -0,0 +1,44 @@
|
||||
---
|
||||
document_type: backend
|
||||
priority: HIGH
|
||||
---
|
||||
# 백엔드 제어 및 저장소/워크플로우 명세
|
||||
|
||||
## 1. 물리 파일 및 저장소 구조 (Workflow Mapping)
|
||||
프로젝트 저장소 내부는 워크플로우 단계와 1:1로 매핑됩니다. 백엔드에서 파일을 다룰 때는 DB에 직접 Blob을 저장하지 않고 이 구조를 따라 저장 후 DB에 상대 경로만 기록합니다.
|
||||
|
||||
```text
|
||||
storage/{company_slug}/{user_slug}/{project_id}/
|
||||
├── B03_FileInput/
|
||||
│ └── input/ (원본 업로드 파일들: .las, .tif)
|
||||
├── B04_wf1_Surface/
|
||||
│ ├── processed/ (변환된 데이터: cloud_filtered.las 등)
|
||||
│ └── models/ (DEM, TIN 결과물: dem_2m.tif, layer.geojson)
|
||||
├── B05_wf2_Route/
|
||||
│ └── route/ (최적 경로: route_main.geojson)
|
||||
├── B06_wf3_ProfileCross/
|
||||
│ ├── longitudinal/ (종단면: longitudinal.json)
|
||||
│ └── cross_sections/ (횡단면 배열: cross_0020m.json 등)
|
||||
├── B07_wf4_DesignDetail/
|
||||
│ └── structures/ (구조물 객체: struct_0020m_001.json)
|
||||
├── B08_wf5_Quantity/
|
||||
│ └── quantities/ (수량 집계: items.json)
|
||||
└── B09_wf6_Estimation/
|
||||
└── v1/, v2/ (버전별 최종 엑셀, PDF, DXF)
|
||||
```
|
||||
**규칙:** 페이지별 백엔드 모듈은 자기 단계의 폴더만 제어합니다. 하위 단계의 파일을 강제로 지우거나 덮어쓰지 않고 `stale_from` 상태를 통해 제어합니다.
|
||||
|
||||
## 2. 워크플로우 상태 동기화 (workflow.json)
|
||||
다중 브라우저 동시 작업을 지원하기 위해 서버 측 상태 파일(`workflow.json`)을 원자적(Atomic)으로 관리합니다.
|
||||
|
||||
* **Stale (상태 무효화) 발생:**
|
||||
상위 단계(예: 지표면 분석 B04)가 재계산되면, 그에 의존하는 하위 단계(경로 B05, 횡단 B06 등) 결과는 신뢰할 수 없으므로 `workflow.json`에 `stale_from: "route"` 형태로 마킹됩니다.
|
||||
* **상태 업데이트 함수 (예시):**
|
||||
```python
|
||||
def _patch_workflow_stale(project_id: str, stale_from: str | None) -> None:
|
||||
# workflow.json의 stale_from 필드만 원자적 업데이트
|
||||
```
|
||||
|
||||
## 3. 클라이언트 폴링 (Polling)
|
||||
- 프론트는 3초 주기로 `GET /api/projects/{project_id}/workflow` 를 폴링합니다.
|
||||
- 서버가 반환하는 `stale_from` 값을 확인하여, 만약 현재 단계와 다르다면 UI에서 사용자에게 "결과가 변경되었습니다. 재계산하시겠습니까?"를 경고합니다.
|
||||
@@ -0,0 +1,23 @@
|
||||
---
|
||||
document_type: backend
|
||||
priority: HIGH
|
||||
---
|
||||
# 백엔드 & 데이터베이스 제어 명세
|
||||
|
||||
## 🐍 백엔드 (FastAPI / Python)
|
||||
- **파일 분할:** 라우터(`_Router.py`), 비즈니스 로직(`_Engine.py`), 스키마(`_Schema.py`), DB 접근(`_Repository.py`) 형태로 세분화.
|
||||
- **데이터 검증:** 모든 JSON 요청은 Pydantic 모델을 통해 라우터 진입 전 타입/범위 필수 검증.
|
||||
- **예외 처리:** 지형/메쉬 연산 등 복잡한 로직 수행 시 `try-except` 필수 처리. 에러 발생 시 `{"status": "error", "message": "원인"}` 반환 표준 포맷 유지.
|
||||
|
||||
## 🗄️ 데이터베이스 (MariaDB)
|
||||
- **[MUST]** 비동기 통신: `aiomysql` 드라이버 사용 강제. (`asyncmy` 사용 불가)
|
||||
- **[DON'T]** ORM 사용 금지: 오직 **Raw SQL**만 작성한다.
|
||||
- **[MUST]** 파라미터 바인딩: `%s` 플레이스홀더를 사용하여 SQL Injection 방지.
|
||||
- **트랜잭션:** `pool.acquire()`로 커넥션 확보 후 다건 쓰기는 `connection.begin()` → `commit()` / 예외 시 `rollback()` 필수.
|
||||
- **자동 증가 ID:** `INSERT` 후 `cursor.lastrowid`로 조회.
|
||||
- **공간 데이터 처리:** MariaDB의 GEOMETRY 타입 한계로 인해, 공간 기하 데이터(좌표, 다각형, 경로 등)는 JSON (GeoJSON 형식)으로 저장 후 애플리케이션(Python Shapely/Geopandas)에서 파싱하여 기하 연산을 처리한다.
|
||||
|
||||
## 🔄 워크플로우 상태 동기화 (Sync)
|
||||
- **공유 상태:** 다중 브라우저 대응을 위해 각 프로젝트는 `workflow.json`으로 현재 진행 단계와 'stale(무효화)' 상태를 관리한다.
|
||||
- **Stale 전파:** 상위 단계(예: 지표면 분석)가 재실행되면 하위 단계들은 자동으로 `stale_from`으로 표기되며, 클라이언트는 3초 주기의 폴링(Polling)을 통해 상태를 확인하고 경고/재계산을 유도한다.
|
||||
- **원자적 쓰기:** `workflow.json` 상태 업데이트는 `common_util_workflow.py`를 통해 원자적 업데이트로 보호되어야 한다.
|
||||
@@ -0,0 +1,47 @@
|
||||
---
|
||||
document_type: frontend
|
||||
priority: HIGH
|
||||
---
|
||||
# 프론트엔드 제어 및 Wiza 디자인 시스템
|
||||
|
||||
## 1. Wiza 디자인 시스템 (Theme Constraints)
|
||||
프론트엔드 UI는 Wiza 브랜드 가이드라인에 따라 구현해야 합니다. 하드코딩된 색상이나 수치를 금지하며, 제공되는 `ui_template_theme.css` 토큰을 사용합니다.
|
||||
|
||||
* **색상 토큰 (Monochromatic Violet):**
|
||||
- `--color-deep-iris` (#26114a): 헤드라인, 메인 버튼 배경 (강조)
|
||||
- `--color-plum-velvet` (#312749): 네비게이션, 2차 헤딩
|
||||
- `--color-royal-amethyst` (#3e0079): 링크, 포커스 링, 강조 아이콘
|
||||
- `--color-lavender-wash`: 영웅 영역 및 섹션의 부드러운 그라데이션 배경
|
||||
- `--color-canvas` (#ffffff): 카드, 입력 폼 등 캔버스 표면
|
||||
* **타이포그래피:**
|
||||
- **Display/Heading:** `Britti Sans` (대체제: Plus Jakarta Sans), 500 Weight, **Line-height 1.0 (절대 준수)**.
|
||||
- **Body/UI:** `Inter`, 400/500/700 Weight, 크기는 컴팩트하게(12~16px) 유지.
|
||||
* **형태 및 간격 (Spacing & Radius):**
|
||||
- 카드, 버튼, 인풋 폼 등 모든 사각형 컨테이너는 **8px Radius** 강제.
|
||||
- 뱃지(Badge), 필(Pill), 네비게이션 아이템 등은 **1440px Radius** 강제.
|
||||
- 요소 간 기본 간격 유닛은 **8px**.
|
||||
|
||||
## 2. 레이아웃 제약
|
||||
워크플로우 페이지(B04~B09)는 반드시 **3단 기본 레이아웃**을 따릅니다.
|
||||
1. 상단: 페이지 타이틀 및 현재 진행 단계
|
||||
2. 좌측: 데이터 입력 폼 및 설정 제어 패널 (너비 고정)
|
||||
3. 우측: WebCAD 도면 뷰어 (Canvas/WebGL) 또는 결과 데이터 그리드 (나머지 화면 너비 전체)
|
||||
|
||||
## 3. 다국어 제어 원칙 (i18n)
|
||||
모든 텍스트는 컴포넌트 내에 직접 작성할 수 없습니다.
|
||||
|
||||
```typescript
|
||||
// 선언부: ui_template/ui_template_locale.ts
|
||||
export const ui_locales = {
|
||||
A01_Home_Title: ["반갑습니다", "Welcome"],
|
||||
B04_wf1_Surface_Btn: ["지표면 분석 실행", "Run Surface Analysis"]
|
||||
};
|
||||
|
||||
// 구현부 호출 예시
|
||||
<button>{ui_locales.B04_wf1_Surface_Btn[currentLanguageIndex]}</button>
|
||||
```
|
||||
|
||||
## 4. 로직 컨벤션 (TypeScript)
|
||||
* **이벤트 핸들러:** `on[페이지명]_[기능명]_[액션]` 형태 강제. (예: `onB04_Surface_Calculate_Click`)
|
||||
* **프론트 유효성 검사:** 백엔드 API 전송 전, 1차적으로 빈 값 및 타입 유효성 검사를 수행하여 피드백합니다.
|
||||
* **로딩 스피너:** API 요청 시작 전 Overlay 활성화, 통신 성공/실패 시 즉시 해제 로직 필수.
|
||||
@@ -0,0 +1,26 @@
|
||||
---
|
||||
document_type: frontend
|
||||
priority: HIGH
|
||||
---
|
||||
# 프론트엔드 및 UI 제어 명세
|
||||
|
||||
## 🎨 테마 및 디자인 규약
|
||||
- **[DON'T]** 하드코딩된 Hex 색상 코드나 임의의 스타일 직접 입력 금지.
|
||||
- **[MUST]** 테마(라이트/다크) 전환 호환을 위해 `ui_template/ui_template_theme.css`에 선언된 CSS 변수(`var(--color-...)`)만 참조.
|
||||
- **공통 레이아웃 (3단 분리 준수):**
|
||||
1. 상단 영역: 페이지 타이틀 및 진행 상태 (헤더)
|
||||
2. 좌측 패널: 데이터 입력 폼 및 제어 설정 창 (고정 너비)
|
||||
3. 우측 영역: WebCAD 도면 뷰어 (Canvas/WebGL) 또는 데이터 그리드 (가변 너비)
|
||||
|
||||
## 🌐 다국어 지원 (i18n)
|
||||
- **[DON'T]** UI 문자열(라벨, 버튼 명, 툴팁, 안내 메시지 등)의 코드 내 하드코딩 절대 금지.
|
||||
- **[MUST]** 동시 수정 프로토콜:
|
||||
1. 신규 텍스트 발생 시 `ui_template/ui_template_locale.ts` 최하단에 키(Key)와 번역 배열(`[한국어, 영어]`) 선 등록.
|
||||
2. 컴포넌트 내에서는 `ui_locales.키값[현재언어인덱스]` 형태로만 호출한다.
|
||||
3. UI 수정 PR시 다국어 업데이트 내역 누락은 심각한 에러로 취급한다.
|
||||
|
||||
## ⚙️ TypeScript 및 로직 제어
|
||||
- **이벤트 핸들러 명명법:** `on[페이지명]_[기능명]_[액션]` 규칙 준수.
|
||||
- 예: `onB04_Surface_Calculate_Click`
|
||||
- **상태 제어 피드백:** API 비동기 호출 시작 시 전체 로딩 스피너(Overlay) 활성화, 통신 완료(성공/에러) 시 반드시 해제 보장.
|
||||
- **1차 검증:** 백엔드 전송 전 빈 값, 최대 길이, 숫자 범위 검증은 프론트엔드(`common_util_validate.ts`)에서 우선 처리하며, 에러 시 입력창 주변에 명시한다.
|
||||
@@ -0,0 +1,31 @@
|
||||
---
|
||||
document_type: workflow
|
||||
priority: HIGH
|
||||
---
|
||||
# 워크플로우 및 데이터 저장소 명세
|
||||
|
||||
## 🔄 6단계 워크플로우 (6-Stage Workflow)
|
||||
설계의 순차적 흐름을 정의하며, DB 및 폴더 구조와 1:1 맵핑됩니다.
|
||||
|
||||
- **WF0 (B03): 파일 입력** - 사용자 원본 파일 (LAS, TIF, DXF 등) 업로드
|
||||
- **WF1 (B04): 지표면 분석** - 포인트클라우드 포맷 변환 및 지표면 모델(DEM/TIN) 생성
|
||||
- **WF2 (B05): 경로 설계** - 제약조건 반영 최적 선형 도출 (GeoJSON)
|
||||
- **WF3 (B06): 종횡단 생성** - 종단면도, 횡단면도 지형/설계 데이터 생성
|
||||
- **WF4 (B07): 상세 설계** - 횡단면별 구조물(옹벽, 수로 등) 배치
|
||||
- **WF5 (B08): 수량 산출** - 구조물 수량 및 토공량 집계
|
||||
- **WF6 (B09): 견적·문서** - Excel, PDF, DXF 등 최종 산출물 패키지 생성
|
||||
|
||||
## 📁 영구 저장소 구조 (파일시스템)
|
||||
중간 산출물(LAS, TIF, GeoJSON 등) 및 대용량 파일은 DB가 아닌 파일시스템에 저장되며, DB(MariaDB)에는 저장된 파일의 **상대 경로**만 기록합니다. 임의의 위치에 파일을 쓰거나 사용자 입력을 경로에 그대로 결합하지 않습니다.
|
||||
|
||||
**저장 규칙 기반 디렉토리 구조:**
|
||||
`storage/{company_slug}/{user_slug}/{project_id}/` 내부
|
||||
- `B03_FileInput/input/` : 원본 업로드 파일
|
||||
- `B04_wf1_Surface/processed/` : 변환 완료된 파일 (ply, 필터링 las 등)
|
||||
- `B04_wf1_Surface/models/` : 생성된 DEM, TIN 모델
|
||||
- `B05_wf2_Route/route/` : 주요 경로선 (GeoJSON) 및 제약 정보
|
||||
- `B06_wf3_ProfileCross/longitudinal/` : 종단면 데이터셋
|
||||
- `B06_wf3_ProfileCross/cross_sections/` : 구간별 횡단면 데이터셋
|
||||
- `B07_wf4_DesignDetail/structures/` : 배치된 구조물 메타데이터
|
||||
- `B08_wf5_Quantity/quantities/` : 산출 물량표 내역
|
||||
- `B09_wf6_Estimation/v1/` : 완료 버전별 패키징 결과물 (엑셀, 도면)
|
||||
Reference in New Issue
Block a user