chore(docs): docs 폴더 git 추적 전환 · PLAN·OWNERS 최상위 이관
- `docs/` 를 .gitignore 에서 빼 git 추적 대상으로 전환 (위키·완료 이력·검증 기록) - `docs/raw/PLAN.md` · `docs/raw/OWNERS.md` 를 저장소 최상위로 이동 후 .gitignore 에 등록 — 창끼리 공유하되 저장소에는 안 올리는 장부 - 살아 있는 경로 참조 7개 파일 정정 (아카이브 107건은 그때 사실이라 그대로 둠) - graphify 날짜별 산출물(`docs/wiki/graphify-out/20*/`) 제외 — `graphify update` 가 다시 만듦 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,5 @@
|
||||
graphify-out/
|
||||
log.md
|
||||
AGENTS.md
|
||||
CLAUDE.md
|
||||
ingest/
|
||||
@@ -0,0 +1,28 @@
|
||||
---
|
||||
type: wiki-governance
|
||||
status: stable
|
||||
related_pages: ["[[index]]", "[[ingest/index]]"]
|
||||
last_updated: 2026-08-16
|
||||
source: docs/AGENTS.md
|
||||
---
|
||||
|
||||
# wiki/ 폴더 규칙
|
||||
|
||||
AI가 raw/의 원본을 읽고 편집·유지하는 산출물 계층. 자세한 운영 규칙(Ingest/Query/Lint, 위키 규칙 14가지)은 `docs/CLAUDE.md`의 Wiki Schema 섹션을 따른다.
|
||||
|
||||
## 구조
|
||||
- `index.md` — 전체 카탈로그. 모든 질의는 여기서 시작한다.
|
||||
- `log.md` — 연대기 로그. append-only.
|
||||
- `pages/B0x_이름/` — 프로젝트의 실제 B01~B09 폴더와 1:1 대응하는 페이지 단위 폴더. 하위에 `frontend.md`, `backend.md`, `db.md`, `api.md`, `dependencies.md`를 필요한 것만 생성한다.
|
||||
- `concepts/` — 여러 페이지가 함께 쓰는 공유 자원의 1차 정의처. DB 스키마, 인증/RBAC, 저장 경로 규칙, 공통 유틸(`common_util_*`), API 공통 엔드포인트, 공통 Pydantic 스키마, 외부 라이브러리 의존성, workflow 상태 관리 등.
|
||||
|
||||
## 작성 규칙
|
||||
- 모든 페이지에 YAML frontmatter 포함. `status`는 `draft`/`stable`/`stale` 셋 중 하나만 사용 (draft=계획서만 반영, stable=검증보고서로 확인, stale=raw 갱신됐는데 미반영).
|
||||
- **`pages/` 하위 파일에는 반드시 `page_id: B0x_이름`(또는 `A0x_이름`)을 frontmatter에 추가한다.** 파일명(`frontend.md` 등)만으로는 소속 페이지를 알 수 없으므로, 폴더 밖에서 봐도 식별 가능해야 한다. concepts 파일에는 해당 없음.
|
||||
- 내부 참조는 `[[페이지명]]` 위키링크 형식.
|
||||
- 새 페이지를 만들기 전에 기존 페이지를 업데이트할 수 있는지 먼저 확인한다.
|
||||
- 소스 요약은 사실만, 해석·종합은 concepts 페이지에서 다룬다.
|
||||
- 계획서와 검증보고서가 충돌하면 **검증보고서를 채택**한다 (실제 코드 상태에 더 가까운 소스). 계획서 내용은 지우지 않고 "계획 당시 의도"로 남긴다.
|
||||
- **공유 자원(두 페이지 이상이 쓰는 테이블·함수·API·의존성 등)은 concepts에만 정의한다.** 페이지 쪽 파일(`db.md` 등)에는 용도 설명 + 위키링크만 남긴다. concepts 쪽에는 사용처(역참조) 목록을 직접 적어 유지한다.
|
||||
- **함수·API·테이블 등 개별 항목은 `항목 | 위치(파일:줄번호) | 역할` 표 형식으로만 기록한다.** 서술문 금지 — grep 없이 바로 코드 위치를 찾을 수 있어야 한다.
|
||||
- **페이지(파일) 하나는 100줄을 넘지 않는다.** 넘으면 하위 주제별로 즉시 분할하고 index.md를 갱신한다.
|
||||
@@ -0,0 +1,28 @@
|
||||
---
|
||||
type: wiki-governance
|
||||
status: stable
|
||||
related_pages: ["[[index]]", "[[ingest/index]]"]
|
||||
last_updated: 2026-08-16
|
||||
source: docs/AGENTS.md
|
||||
---
|
||||
|
||||
# wiki/ 폴더 규칙
|
||||
|
||||
AI가 raw/의 원본을 읽고 편집·유지하는 산출물 계층. 자세한 운영 규칙(Ingest/Query/Lint, 위키 규칙 14가지)은 `docs/CLAUDE.md`의 Wiki Schema 섹션을 따른다.
|
||||
|
||||
## 구조
|
||||
- `index.md` — 전체 카탈로그. 모든 질의는 여기서 시작한다.
|
||||
- `log.md` — 연대기 로그. append-only.
|
||||
- `pages/B0x_이름/` — 프로젝트의 실제 B01~B09 폴더와 1:1 대응하는 페이지 단위 폴더. 하위에 `frontend.md`, `backend.md`, `db.md`, `api.md`, `dependencies.md`를 필요한 것만 생성한다.
|
||||
- `concepts/` — 여러 페이지가 함께 쓰는 공유 자원의 1차 정의처. DB 스키마, 인증/RBAC, 저장 경로 규칙, 공통 유틸(`common_util_*`), API 공통 엔드포인트, 공통 Pydantic 스키마, 외부 라이브러리 의존성, workflow 상태 관리 등.
|
||||
|
||||
## 작성 규칙
|
||||
- 모든 페이지에 YAML frontmatter 포함. `status`는 `draft`/`stable`/`stale` 셋 중 하나만 사용 (draft=계획서만 반영, stable=검증보고서로 확인, stale=raw 갱신됐는데 미반영).
|
||||
- **`pages/` 하위 파일에는 반드시 `page_id: B0x_이름`(또는 `A0x_이름`)을 frontmatter에 추가한다.** 파일명(`frontend.md` 등)만으로는 소속 페이지를 알 수 없으므로, 폴더 밖에서 봐도 식별 가능해야 한다. concepts 파일에는 해당 없음.
|
||||
- 내부 참조는 `[[페이지명]]` 위키링크 형식.
|
||||
- 새 페이지를 만들기 전에 기존 페이지를 업데이트할 수 있는지 먼저 확인한다.
|
||||
- 소스 요약은 사실만, 해석·종합은 concepts 페이지에서 다룬다.
|
||||
- 계획서와 검증보고서가 충돌하면 **검증보고서를 채택**한다 (실제 코드 상태에 더 가까운 소스). 계획서 내용은 지우지 않고 "계획 당시 의도"로 남긴다.
|
||||
- **공유 자원(두 페이지 이상이 쓰는 테이블·함수·API·의존성 등)은 concepts에만 정의한다.** 페이지 쪽 파일(`db.md` 등)에는 용도 설명 + 위키링크만 남긴다. concepts 쪽에는 사용처(역참조) 목록을 직접 적어 유지한다.
|
||||
- **함수·API·테이블 등 개별 항목은 `항목 | 위치(파일:줄번호) | 역할` 표 형식으로만 기록한다.** 서술문 금지 — grep 없이 바로 코드 위치를 찾을 수 있어야 한다.
|
||||
- **페이지(파일) 하나는 100줄을 넘지 않는다.** 넘으면 하위 주제별로 즉시 분할하고 index.md를 갱신한다.
|
||||
@@ -0,0 +1,65 @@
|
||||
---
|
||||
type: architecture-status
|
||||
status: draft
|
||||
related_pages: ["[[architecture/workflow_data_flow]]", "[[workflow_state]]", "[[storage_paths]]", "[[architecture/project_map]]"]
|
||||
last_updated: 2026-08-16
|
||||
source: ["code-audit:2026-08-16"]
|
||||
---
|
||||
|
||||
# 현재 구현 현황 — 소스 읽기 감사
|
||||
|
||||
> 이 문서는 2026-08-16 소스 읽기 감사 결과다. 코드를 수정하거나 실행 검증하지 않았으므로 `draft`이며, raw 검증보고서와 충돌하면 최신 코드의 현재 구조를 우선 참고하되 동작 성공까지 보장하지 않는다.
|
||||
|
||||
## 단계별 판정
|
||||
|
||||
| 단계 | 구현 판정 | 코드 근거 | 현재 책임 |
|
||||
|---|---|---|---|
|
||||
| B03 FileInput | 구현 | `B03_FileInput_Router.py`, `B03_FileInput_Service_WF1.py` | 입력 저장, stage 0 완료, B04 이후 초기화 |
|
||||
| B04 PreProcess | 구현 | `B04_PreProcess_Router.py`, `B04_PreProcess_Service.py` | 지표면 분석·확정, stage 1 상태 관리 |
|
||||
| B05 Profile | 구현 | `B05_Profile_Router.py`, `B05_Profile_Structures_Router.py` | 경로·종단 생성/편집, B~G 일반 구조물 수동 배치·정본, stage 2와 후속 STALE 관리 |
|
||||
| B06 Section | 구현·결합 | `B06_Section_Router*.py` | 횡단 설계; 전체 확정 시 stage 2·3 동시 완료 |
|
||||
| B07 Quantity | 임시 우회 | `B07_Quantity_Router.py`, `B07_Quantity_UI_Page.ts` | 계산 없이 stage 4를 COMPLETE로 바꾸고 B08 이동 |
|
||||
| B08 DesignDetail | 부분 구현 | `B08_DesignDetail_Router.py` | CAD 도면, 횡단 확정, 단면 재계산, `quantity_table` 저장 |
|
||||
| B09 Estimation | 셸 | `B09_Estimation_UI_Page.ts` | 준비 중 화면; stage 6 완료 backend 미확인 |
|
||||
|
||||
## 비워크플로 영역 판정
|
||||
|
||||
| 영역 | 구현 형태 | 판정 |
|
||||
|---|---|---|
|
||||
| A00 Common | SPA router·App Shell·workflow navigation | 공통 기반 구현 |
|
||||
| A01~A05 | 각 1개 Frontend 페이지 | 공개 정보 화면; backend 없음 |
|
||||
| A06 Login | Frontend + 5 API route | 인증 기능 구현 |
|
||||
| A07 Register | Frontend + 3 API route | 가입 기능 구현 |
|
||||
| A08 Support | Frontend + 1 API route | 지원 문의 기능 구현 |
|
||||
| A09 Security | Frontend + 9 API route | 보안·계정 기능 구현 |
|
||||
| B01 Dashboard | Frontend/Backend + 26 API route | 관리 기능 구현 |
|
||||
| B02 Project Register | Frontend/Backend + 1 API route | 프로젝트 생성 구현 |
|
||||
| B10 Payment | Frontend 1개 | workflow 외 화면; backend 미확인 |
|
||||
| B11 Status | Frontend 2개 | 상태·로딩 화면; 독립 backend 없음 |
|
||||
|
||||
## 구현 상태 용어
|
||||
|
||||
| 용어 | 의미 |
|
||||
|---|---|
|
||||
| 구현 | 주요 API와 상태 전이가 소스에 존재 |
|
||||
| 부분 구현 | 핵심 일부가 있으나 전체 업무 완료 기능은 아님 |
|
||||
| 임시 우회 | 본문 기능 없이 다음 단계 진입만 허용 |
|
||||
| 셸 | 레이아웃·준비 중 화면만 존재 |
|
||||
| 미확인 | 소스 읽기만으로 동작 성공을 확정할 수 없음 |
|
||||
|
||||
## 반드시 유지할 구분
|
||||
|
||||
| 구분 | SSOT·처리 |
|
||||
|---|---|
|
||||
| workflow 상태 | DB `project_workflow_stages` |
|
||||
| 프로젝트 요약 상태 | DB `projects.status` 캐시 |
|
||||
| 레거시 보조 상태 | 프로젝트 루트 `workflow.json`; 현재 핵심 전이에서 사용 제한적 |
|
||||
| 단계 산출물 | 프로젝트 저장소의 B03~B08 단계별 파일 + 일부 DB 레코드 |
|
||||
| 후속 상태 무효화 | `start_stage()`가 뒤쪽 COMPLETE 단계만 STALE 처리 |
|
||||
| 산출물 무효화 | 공통 자동 삭제가 아니라 각 단계의 개별 로직에 의존 |
|
||||
|
||||
## 미결 설계
|
||||
|
||||
- B07 최종 수량 계산과 B08 CAD 수량표의 책임 경계는 확정되지 않았다.
|
||||
- B08 도면 수정이 향후 B07 수량을 역으로 무효화해야 하는지는 사용자 결정이 필요하다.
|
||||
- B09 견적·설계도서 산출 및 stage 6 완료 API는 후속 구현 대상이다.
|
||||
@@ -0,0 +1,44 @@
|
||||
---
|
||||
type: architecture-map
|
||||
status: stable
|
||||
related_pages: ["[[index]]", "[[architecture/implementation_status]]", "[[architecture/workflow_data_flow]]", "[[architecture/shared_resources]]", "[[architecture/public_admin_map]]"]
|
||||
last_updated: 2026-09-09
|
||||
source: ["docs/raw/verification/2026-08-08_verify_R1_R2_features.md", "docs/raw/verification/2026-08-08_verify_server_and_e2e_fixes.md"]
|
||||
---
|
||||
|
||||
# Aislo 프로젝트 지도
|
||||
|
||||
## 현재 명칭과 책임
|
||||
|
||||
| 영역 | 현재 책임 | 상세 진입점 | 레거시 위키명 |
|
||||
|---|---|---|---|
|
||||
| A00 | 공통 App Shell·라우터·UI | [[A00_Common/A00_Common]] | 동일 |
|
||||
| A01~A05 | 공개 소개·소식·교육 | [[architecture/public_admin_map]] | 동일 |
|
||||
| A06~A09 | 로그인·가입·지원·보안관리 | [[architecture/public_admin_map]] | 동일 |
|
||||
| B01 | 프로젝트·조직·임시보관 관리 | [[B01_Dashboard/B01_frontend]] | 동일 |
|
||||
| B02 | 프로젝트 생성·workflow 시드 | [[B02_ProjRegister/B02_backend]] | 동일 |
|
||||
| B03 | 파일 입력·검증·WF1 실행 | [[B03_FileInput/B03_backend]] | 동일 |
|
||||
| B04 | 전처리·지표면·GIS·배수유역 | [[B04_PreProcess/B04_backend]] | B04_wf1_Surface |
|
||||
| B05 | 경로·종단·구조물·배수 편집 | [[B05_Profile/B05_backend]] | B05_wf2_Route |
|
||||
| B06 | 횡단·유토곡선·단면 확정 | [[B06_Section/B06_backend]] | B06_wf3_ProfileCross |
|
||||
| B07 | 상세설계·CAD·설계도면 | [[B07_DesignDetail/B07_frontend]] | B08_DesignDetail(구 위키 경로) |
|
||||
| B08 | 수량산출·자재총괄·B09 인계 | [[B08_Quantity/B08_overview_2026_09]] | B07_Quantity(구 위키 경로) |
|
||||
| B09 | 단가산출·예산내역·공사원가계산 | [[B09_Estimation/B09_overview_2026_09]] | B09_wf6_Estimation |
|
||||
| B10~B11 | 결제·진행상태 목업 | [[B10_Payment/B10_frontend]], [[B11_Status/B11_frontend]] | workflow 외 후속 화면 |
|
||||
|
||||
## 탐색 순서
|
||||
|
||||
| 질문 | 먼저 읽을 문서 | 다음 문서 |
|
||||
|---|---|---|
|
||||
| 기능의 전체 위치 | 이 페이지 | 해당 B/A canonical 페이지 |
|
||||
| B03~B09 데이터 흐름 | [[architecture/workflow_data_flow]] | backend/api/db 세부 페이지 |
|
||||
| DB·인증·저장소·공통 유틸 영향 | [[architecture/shared_resources]] | 해당 concepts 페이지 |
|
||||
| 공개·인증·관리자 흐름 | [[architecture/public_admin_map]] | A/B01 세부 페이지 |
|
||||
| raw 반영 여부 | [[ingest/index]] | 월·유형별 원장 |
|
||||
|
||||
## 명칭 판정
|
||||
|
||||
- 2026-09-07 사용자 확정과 2026-09-08 완료·검증 문서를 현재 workflow 명칭·책임의 기준으로 채택한다.
|
||||
- 레거시 명칭은 검색 호환을 위해 이 표의 alias로만 보존하며 현재 페이지 ID로 사용하지 않는다.
|
||||
- B07은 상세설계/CAD, B08은 수량산출, B09는 원가계산이다. 2026-08 문서의 B07/B08 표기는 레거시 alias다.
|
||||
- 현재 구현 완성도와 실제 책임은 [[architecture/implementation_status]]를 기준으로 판정한다.
|
||||
@@ -0,0 +1,43 @@
|
||||
---
|
||||
type: architecture-map
|
||||
status: stable
|
||||
related_pages: ["[[architecture/project_map]]", "[[architecture/implementation_status]]", "[[auth_rbac]]", "[[a00_app_shell_framework]]", "[[ui_templates]]"]
|
||||
last_updated: 2026-08-16
|
||||
source: ["docs/raw/verification/2026-07-12_verify_add_phase4_role.md", "docs/raw/verification/2026-07-16_verify_인증주기개선.md", "docs/raw/verification/2026-07-17_verify_auth_reverify.md"]
|
||||
---
|
||||
|
||||
# 공개·인증·관리 영역 지도
|
||||
|
||||
이 지도는 [[architecture/project_map]]의 공개·인증 영역을 상세화한다. 모든 공개 화면은 [[A00_Common/A00_Common]]의 SPA router와 App Shell을 사용하며, 인증·관리 API는 [[auth_rbac]]의 세션과 권한 규칙을 따른다.
|
||||
|
||||
| 사용자 흐름 | 관계 | 대상 페이지 | 핵심 상태·데이터 |
|
||||
|---|---|---|---|
|
||||
| 방문자 진입 | `ROUTES_TO` | [[A01_Home/A01_frontend]] | 공개 홈·소개 진입 |
|
||||
| 기능 탐색 | `ROUTES_TO` | [[A02_ProgDetail/A02_frontend]], [[A03_CompDetail/A03_frontend]], [[A04_NewsHistory/A04_frontend]], [[A05_EduDetail/A05_frontend]] | 정적·목업 콘텐츠 |
|
||||
| 로그인 | `AUTHENTICATES` | [[A06_Login/A06_backend]] | 세션쿠키·신뢰기기·재인증 |
|
||||
| 회원가입 | `CREATES_IDENTITY` | [[A07_Register/A07_backend]] | OTP·회사검색·가입승인 |
|
||||
| 기술지원 | `CREATES_REQUEST` | [[A08_Support/A08_backend]] | 비로그인 문의·DB 저장·메일 |
|
||||
| 보안관리 | `GOVERNS` | [[A09_Security/A09_backend]] | 조직·회원·승인·감사 로그 |
|
||||
| 로그인 후 진입 | `ROUTES_TO` | [[B01_Dashboard/B01_frontend]] | 프로젝트·회사·사용자·임시보관 |
|
||||
|
||||
## 공통 의존
|
||||
|
||||
| 자원 | 사용 이유 |
|
||||
|---|---|
|
||||
| [[a00_app_shell_framework]] | 헤더·라우터·인증 상태·공통 레이아웃 |
|
||||
| [[auth_rbac]] | 역할별 접근과 API 권한 |
|
||||
| [[ui_templates]] | 다국어·컴포넌트·워크플로우 레이아웃 |
|
||||
| [[design]] | 테마·타이포그래피·간격 토큰 |
|
||||
| [[db_schema/users_auth]] | 사용자·회사·세션·OTP·동의 |
|
||||
| [[db_schema/logs_monitoring]] | 로그인·활동·감사·지원 로그 |
|
||||
|
||||
## 직접 구현 관계
|
||||
|
||||
| 상위 페이지 | 구현 파일 문서 | 관계 |
|
||||
|---|---|---|
|
||||
| [[A01_Home/A01_frontend]] | [[A01_Home/frontend/A01_Home_UI_Page]] | `IMPLEMENTS` |
|
||||
| [[A02_ProgDetail/A02_frontend]] | [[A02_ProgDetail/frontend/A02_ProgDetail_UI_Page]] | `IMPLEMENTS` |
|
||||
| [[A06_Login/A06_backend]] | [[A06_Login/backend/A06_Login_Router]] | `IMPLEMENTS` |
|
||||
| [[A07_Register/A07_backend]] | [[A07_Register/backend/A07_Register_Router]] | `IMPLEMENTS` |
|
||||
| [[A08_Support/A08_backend]] | [[A08_Support/backend/A08_Support_Router]] | `IMPLEMENTS` |
|
||||
| [[A09_Security/A09_backend]] | [[A09_Security/backend/A09_Security_Router]] | `IMPLEMENTS` |
|
||||
@@ -0,0 +1,46 @@
|
||||
---
|
||||
type: architecture-map
|
||||
status: draft
|
||||
related_pages: ["[[architecture/project_map]]", "[[architecture/implementation_status]]", "[[architecture/workflow_data_flow]]", "[[architecture/public_admin_map]]"]
|
||||
last_updated: 2026-08-16
|
||||
---
|
||||
|
||||
# 공유 자원 영향 지도
|
||||
|
||||
> 각 정의의 검증 상태는 링크된 concept 문서를 따른다. 이 페이지는 영향 탐색용 종합 지도다.
|
||||
|
||||
| 공유 자원 | 관계 | 주요 사용처 |
|
||||
|---|---|---|
|
||||
| [[auth_rbac]] | `GOVERNS` | A06, A07, A09, B01 및 보호 API 전체 |
|
||||
| [[workflow_state]] | `GOVERNS` | B01, B02, B03~B09 |
|
||||
| [[db_schema/overview]] | `DEFINES` | 모든 backend/db 페이지 |
|
||||
| [[storage_paths]] | `DEFINES` | B03 입력, B04~B09 산출물 |
|
||||
| [[crs_metadata]] | `NORMALIZES` | B03, B04, B05 |
|
||||
| [[api_common]] | `STANDARDIZES` | 공통 오류 응답과 workflow API |
|
||||
| [[schema_common]] | `STANDARDIZES` | 공유 Pydantic 요청·응답 모델 |
|
||||
| [[common_util]] | `SUPPORTS` | 인증·저장소·메일·workflow·삭제 |
|
||||
| [[dependencies]] | `SUPPORTS` | GIS·수치연산·DB·프론트 렌더링 |
|
||||
| [[ui_templates]] | `RENDERS` | A00~A09, B01~B11 |
|
||||
| [[design]] | `STYLES` | 전체 프론트엔드 |
|
||||
| [[drainage_watershed]] | `CONNECTS` | B04 전처리, B05 구조물·배수, B06 횡단 |
|
||||
| [[mass_haul_diagram]] | `CONNECTS` | B05 종단, B06 횡단·유토, B07 수량 |
|
||||
| [[temp_upload]] | `CONNECTS` | B01 임시보관, B03 attach·자동 체인 |
|
||||
|
||||
## 단계별 직접 연결
|
||||
|
||||
| 단계 | API·Backend 관계 | 공유 자원 |
|
||||
|---|---|---|
|
||||
| B01 | [[B01_Dashboard/B01_api]] → [[B01_Dashboard/B01_backend]] | workflow·인증·DB |
|
||||
| B03 | [[B03_FileInput/B03_api]] → [[B03_FileInput/B03_backend]] | 저장소·CRS·workflow |
|
||||
| B04 | [[B04_PreProcess/B04_api]] → [[B04_PreProcess/B04_backend]] | 저장소·GIS·workflow |
|
||||
| B05 | [[B05_Profile/B05_api]] → [[B05_Profile/B05_backend]] | 저장소·배수·workflow |
|
||||
| B06 | [[B06_Section/B06_api]] → [[B06_Section/B06_backend]] | B05 산출물·workflow |
|
||||
| B07 | [[B07_Quantity/B07_backend]] → [[workflow_state]] | stage 4 임시 완료만 사용 |
|
||||
| B08 | [[B08_DesignDetail/B08_api]] → [[B08_DesignDetail/B08_backend]] | B06 산출물·CAD·workflow |
|
||||
|
||||
## 영향 분석 규칙
|
||||
|
||||
1. 공유 자원을 변경할 때 이 표에서 소비 페이지를 먼저 찾는다.
|
||||
2. concept의 사용처 목록과 각 페이지의 `related_pages`를 양방향 대조한다.
|
||||
3. DB·API·workflow 변경은 [[architecture/workflow_data_flow]]의 생산자와 소비자를 함께 검토한다.
|
||||
4. 상세 함수·테이블은 해당 canonical concept 또는 페이지의 표에서 찾는다.
|
||||
@@ -0,0 +1,52 @@
|
||||
---
|
||||
type: architecture-flow
|
||||
status: stable
|
||||
related_pages: ["[[architecture/project_map]]", "[[architecture/implementation_status]]", "[[workflow_state]]", "[[storage_paths]]", "[[db_schema/overview]]"]
|
||||
last_updated: 2026-09-09
|
||||
source: ["docs/raw/verification/2026-08-08_verify_R1_R2_features.md", "docs/raw/verification/2026-08-04_verify_b05_b06_profile_ui_chain.md", "docs/raw/verification/2026-07-17_verify_workflow_stepbar.md"]
|
||||
---
|
||||
|
||||
# B01~B09 Workflow 데이터 흐름
|
||||
|
||||
## 단계 관계
|
||||
|
||||
| 생산 단계 | 관계 | 소비 단계 | 전달·상태 |
|
||||
|---|---|---|---|
|
||||
| [[B01_Dashboard/B01_backend]] | `SELECTS` | [[B02_ProjRegister/B02_backend]] | 사용자·회사·프로젝트 컨텍스트 |
|
||||
| [[B02_ProjRegister/B02_backend]] | `INITIALIZES` | [[workflow_state]] | 프로젝트와 stage 0~6 `NOT_STARTED` 시드 |
|
||||
| [[B03_FileInput/B03_backend]] | `PRODUCES` | [[B04_PreProcess/B04_backend]] | 업로드 파일, CRS 메타데이터, WF1 실행 |
|
||||
| [[B04_PreProcess/B04_backend]] | `PRODUCES` | [[B05_Profile/B05_backend]] | 확정 지표면, GIS, 배수유역, stage 1 params |
|
||||
| [[B05_Profile/B05_backend]] | `PRODUCES` | [[B06_Section/B06_backend]] | 경로·종단·측점과 [[B05_Profile/B05_structures|일반 구조물 정본]]; 설계 영향 변경 시 후속 STALE |
|
||||
| [[B06_Section/B06_backend]] | `PRODUCES` | [[B07_DesignDetail/B07_frontend]] | 횡단 정본을 상세설계·도면 단계가 소비 |
|
||||
| [[B07_DesignDetail/B07_frontend]] | `PRODUCES` | [[B08_Quantity/B08_overview_2026_09]] | 설계도면·구조물 정본에서 물량 산출 |
|
||||
| [[B08_Quantity/B08_overview_2026_09]] | `HANDOFF` | [[B09_Estimation/B09_overview_2026_09]] | 공종코드·수량·갈래·근거를 인계 |
|
||||
| [[B09_Estimation/B09_overview_2026_09]] | `PRICES` | [[workflow_state]] | 단가산출·예산내역·공사원가계산 |
|
||||
|
||||
## B04→B06 자동 계산과 재설계
|
||||
|
||||
| 트리거 | 호출·처리 | 저장·소비 | 상태 |
|
||||
|---|---|---|---|
|
||||
| B03 업로드 완료 | WF1 지표면 분석 | B04 모델·확정 스냅샷 | stage 1 진행/완료 |
|
||||
| B04 확정 | 자동 설계 체인 | B05 기본 경로·B06 기본 횡단 | stage 2·3 `IN_PROGRESS` |
|
||||
| B04 재확정 | `run_redesign_chain` | B05 제어점·경사와 B06 단면 설정 이월 | 하위 결과 재계산 |
|
||||
| B05 경로·종단·일반 구조물 수정 | B05 save/confirm 또는 구조물 PUT | 종단 정본·비정규 측점·`structures.json` | 설계 영향 변경이면 B06 이후 STALE; 처리 실패 시 B06 재실행 안내 |
|
||||
| B06 확정 | section confirm | 횡단 설계 정본 | stage 2·3 `COMPLETE`, B07 임시 셸 이동 |
|
||||
|
||||
## 상태와 산출물 무효화
|
||||
|
||||
| 변경 | DB 상태 | 실제 산출물 |
|
||||
|---|---|---|
|
||||
| B03 입력 교체 | stage 1~6을 `NOT_STARTED`로 초기화 | 단계별 정리 로직에 의존 |
|
||||
| B04~B08 단계 재시작 | 뒤쪽 `COMPLETE` 단계만 `STALE` | 공통 함수는 파일을 삭제하지 않음 |
|
||||
| B08 도면 무효화 | stage 5 `IN_PROGRESS`, 뒤쪽 완료 단계 `STALE` | manifest의 해당 도면 `confirmed=false` |
|
||||
|
||||
## 정본 위치
|
||||
|
||||
| 데이터 | canonical 문서 | 주요 소비자 |
|
||||
|---|---|---|
|
||||
| workflow 상태 | [[workflow_state]] | B01, B03~B09 스텝바·게이팅 |
|
||||
| DB 스키마 | [[db_schema/overview]] | 모든 backend/db 페이지 |
|
||||
| 저장 경로 | [[storage_paths]] | B03~B09 파일 산출물 |
|
||||
| CRS 메타데이터 | [[crs_metadata]] | B03 분석, B04/B05 좌표 처리 |
|
||||
| 배수유역·관 | [[drainage_watershed]] | B04·B05·B06 |
|
||||
| 유토곡선 | [[mass_haul_diagram]] | B05·B06·B07 후보 데이터 |
|
||||
@@ -0,0 +1,41 @@
|
||||
---
|
||||
status: stable
|
||||
related_pages: ["[[A01_Home/A01_frontend]]", "[[A02_ProgDetail/A02_frontend]]", "[[B01_Dashboard/B01_frontend]]", "[[B03_FileInput/B03_frontend]]", "[[B04_PreProcess/B04_frontend]]", "[[B05_Profile/B05_frontend]]", "[[B06_Section/B06_frontend]]", "[[B07_Quantity/B07_frontend]]", "[[B08_DesignDetail/B08_frontend]]", "[[B09_Estimation/B09_frontend]]", "[[architecture/shared_resources]]"]
|
||||
last_updated: 2026-07-18
|
||||
source: docs/raw/verification/2026-07-18_verify_layout_improvement.md
|
||||
---
|
||||
|
||||
# A00_Common — App Shell Framework
|
||||
|
||||
모든 페이지의 공통 스켈레톤. 헤더(로고/네비/언어·테마/인증버튼) + 콘텐츠 아울렛 + 푸터를 통합 관리. B그룹 작업 화면(B01~B11)의 경우 화면 전체 높이 사용을 위해 푸터를 동적 제외(FOOTERLESS_ROUTES) 처리.
|
||||
|
||||
## 파일 구성
|
||||
|
||||
| 파일 | 역할 |
|
||||
|---|---|
|
||||
| `app_shell.ts` (284줄) | 헤더·푸터 렌더링, 테마·언어 토글, `showFooter` 옵션 분기 및 `.app-outlet--without-footer` 뷰포트 확장 |
|
||||
| `b_page_scaffold.ts` (163줄) | B 그룹(B03~B09) 페이지용 스캐폴드—"준비 중" 임시 페이지 래퍼, 워크플로우 셸 헬퍼 |
|
||||
| `router.ts` (158줄) / `main.ts` | SPA 라우터(해시 기반), 인증 가드, `FOOTERLESS_ROUTES` 상수(B01~B11) 기준 푸터 비활성화 주입 |
|
||||
| `b_workflow_nav.ts` (신설) | 7단계 라우트 배열(`WORKFLOW_STEP_ROUTES`), 공통 `fetchWorkflowState`, 네비게이션 `goToWorkflowStage` |
|
||||
|
||||
## app_shell 구성요소
|
||||
### 테마 & 언어 관리
|
||||
- `initThemeAndLang()` — localStorage 복원 (THEME_STORAGE_KEY, LANG_STORAGE_KEY)
|
||||
- `onApp_Theme_Toggle_Click()` — light ↔ dark 전환
|
||||
- `onApp_Lang_Toggle_Click()` — 한국어 ↔ 영문 전환 + 현재 페이지 재렌더
|
||||
|
||||
### 헤더 구성 (64px 높이, sticky)
|
||||
- **로고**: `BRAND_ICON_URL`(prog_icon.jpg) + 브랜드명("Aislo")
|
||||
- **네비게이션**: 5개 링크 (A02_PROG_DETAIL, A03_COMP_DETAIL, A04_NEWS_HISTORY, A05_EDU_DETAIL, A08_SUPPORT)
|
||||
- **우측 액션**: 언어 버튼 ("EN" / "한"), 테마 버튼 ("☀" / "☾"), 인증 버튼 (로그인/로그아웃)
|
||||
|
||||
## router 라우팅 테이블
|
||||
- **A그룹 (A01~A09)**: 로그인 전/보안/지원 화면 라우팅
|
||||
- **B그룹 (B01~B11)**: 대시보드 및 7단계 워크플로우(`B03_FILE_INPUT` ~ `B09_WF6_ESTIMATION`), 결제(`B10`), 상태조회(`B11`) 라우팅
|
||||
|
||||
## 인증 가드
|
||||
- **PROTECTED_ROUTES**: 로그인 토큰 없으면 A06_LOGIN으로 리다이렉트
|
||||
- **워크플로우 라우트 (B02~B11)**: 추가 검증 (로그인 여부 + `company_id` 미보유 시 B01_ACCOUNT로 강제 이동하여 회사 가입 유도)
|
||||
|
||||
## 세부 스캐폴드·CSS·종속성
|
||||
`b_page_scaffold`, CSS 주입, 공통 종속성은 [[a00_app_shell_framework_scaffold]]에 분리했다.
|
||||
@@ -0,0 +1,38 @@
|
||||
---
|
||||
type: concept
|
||||
status: draft
|
||||
page_id: A00_Common
|
||||
related_pages: ["[[a00_app_shell_framework]]", "[[B07_Quantity/B07_frontend]]", "[[B09_Estimation/B09_frontend]]", "[[architecture/shared_resources]]"]
|
||||
last_updated: 2026-07-12
|
||||
source: 상위 프로젝트 A00_Common 코드 및 페이지 인제스트 대조 (2026-07-12)
|
||||
---
|
||||
|
||||
# A00_Common — 스캐폴드·CSS·종속성
|
||||
|
||||
## b_page_scaffold
|
||||
| 항목 | 역할 |
|
||||
|---|---|
|
||||
| `renderPendingContent` | 비 workflow 페이지용 준비 중 블록 |
|
||||
| `renderPendingWorkflow` | workflow 셸과 좌·우 준비 중 영역 |
|
||||
| `workflowSteps()` | 7단계 workflow 라벨 배열 |
|
||||
|
||||
## CSS 인젝션
|
||||
| 항목 | 역할 |
|
||||
|---|---|
|
||||
| `injectShellStyles` | 셸 스타일을 `<head>`에 1회 주입 |
|
||||
| `app-shell-style` | 헤더·아울렛·푸터 스타일 ID |
|
||||
| theme 변수 | 헤더 64px·푸터 56px·아울렛 최소높이 |
|
||||
|
||||
## 종속성
|
||||
| 항목 | 역할 |
|
||||
|---|---|
|
||||
| `ui_template_locale.ts` | 언어 상태·문자열 |
|
||||
| `ui_template_elements.ts` | 버튼·workflow 셸 |
|
||||
| `config_frontend.ts` | routes·theme·protected routes |
|
||||
| `A06_Login_Api_Fetch.ts` | 세션 조회·로그아웃 |
|
||||
|
||||
## 사용처
|
||||
| 페이지 | 역할 |
|
||||
|---|---|
|
||||
| A01~A09 | 공통 헤더·푸터·아울렛 |
|
||||
| B01~B09 | 페이지별 workflow 셸·단계 내비게이션 |
|
||||
@@ -0,0 +1,27 @@
|
||||
---
|
||||
type: concept
|
||||
status: draft
|
||||
related_pages: ["[[B01_Dashboard/B01_backend]]", "[[B03_FileInput/B03_backend]]", "[[B04_PreProcess/B04_backend]]", "[[architecture/shared_resources]]"]
|
||||
last_updated: 2026-07-12
|
||||
source: raw/plans/plan_workflow_state_management.md, raw/guidelines/backend.md + 실 코드 확인 2026-07-12
|
||||
---
|
||||
|
||||
# API 공통 (여러 페이지가 공유하는 엔드포인트)
|
||||
|
||||
## 공통 오류 응답 포맷 (전 라우터)
|
||||
```json
|
||||
{"status": "error", "message": "원인"}
|
||||
```
|
||||
→ [[schema_common]]
|
||||
|
||||
## 워크플로우 상태 조회
|
||||
| 항목 | 위치 | 역할 |
|
||||
|---|---|---|
|
||||
| `GET /api/projects/{project_id}/workflow-state` | `B03_FileInput_Router.py:667` | 단일 프로젝트의 `current_stage`와 `stages[]` 조회 |
|
||||
| `get_workflow_states_for_projects()` | `B01_Dashboard_Repository.py:83` | [[B01_Dashboard/B01_backend|B01_Dashboard]] 목록용 다중 프로젝트 상태 배치 조회 |
|
||||
|
||||
상태 모델과 사용처: [[workflow_state]].
|
||||
|
||||
## 폴링 패턴 (legacy workflow.json 설계; 현재 구현은 workflow-state API 사용)
|
||||
- 클라이언트가 3초마다 `GET /api/projects/{project_id}/workflow` 호출
|
||||
- 과거 설계의 stale 감지 UX 참고용이며, 실제 상태 조회는 [[workflow_state]] API를 사용한다.
|
||||
@@ -0,0 +1,68 @@
|
||||
---
|
||||
type: concept
|
||||
status: stable
|
||||
related_pages: ["[[B01_Dashboard/B01_frontend]]", "[[A06_Login/A06_backend]]", "[[A07_Register/A07_backend]]", "[[architecture/shared_resources]]"]
|
||||
last_updated: 2026-07-17
|
||||
source: docs/raw/verification/2026-07-17_verify_auth_reverify.md
|
||||
---
|
||||
|
||||
# 인증 / RBAC
|
||||
|
||||
## 세션 인증 (backend.md 6.3)
|
||||
- 방식: Secure HttpOnly 세션 쿠키 (`session_id`, JWT 아님), `SameSite=Lax`
|
||||
- 저장소: `sessions` 테이블 → [[db_schema/users_auth]]
|
||||
- 유효시간: 활동 기준 4시간 또는 절대 12시간 중 먼저 도달하는 쪽
|
||||
- DB 풀: `autocommit=True` (세션 즉시 조회 가능하도록)
|
||||
- 프론트: 모든 API 요청에 `credentials: "include"` (frontend.md 5.1)
|
||||
|
||||
## OTP / 비밀번호 및 디바이스 신뢰
|
||||
- OTP 6자리, 5분 유효, 해시 저장(bcrypt/PBKDF2), 재시도 최대 3회(2s/4s/8s 백오프)
|
||||
- 비밀번호 최소 8자, bcrypt(라운드≥12) 또는 PBKDF2, 평문 저장 절대 금지
|
||||
- 5회 연속 실패 시 계정 임시 잠금 및 ADMIN_EMAIL로 보안 경고 메일 발송
|
||||
- **디바이스 신뢰 (2026-07-17 도입)**:
|
||||
- 기기 신뢰를 기존 User-Agent 해시에서 **HttpOnly 디바이스 토큰 쿠키 (`device_token`)**로 전환하여 브라우저 업데이트 시 반복적인 OTP 요구를 해결.
|
||||
- 로그인 또는 가입 인증 성공 시 무작위 32바이트 토큰을 발급하여 브라우저 쿠키에 저장(만료 90일)하고, SHA256 해시값은 DB `trusted_devices` 테이블에 저장.
|
||||
- 기기 신뢰 만료 정책: `last_used_at`이 `EMAIL_REVERIFY_DAYS`(90일) 이내인 기기 토큰만 유효 처리하며, 로그인 시 `last_used_at`을 자동으로 갱신.
|
||||
|
||||
## 사용자 상태 생명주기
|
||||
```
|
||||
PENDING_EMAIL → NO_COMPANY → (PENDING | ACTIVE) → (INACTIVE | REJECTED)
|
||||
```
|
||||
| 상태 | 접근 가능 범위 |
|
||||
|---|---|
|
||||
| NO_COMPANY | 로그인 가능, B01만 (B02~B11 차단) |
|
||||
| PENDING | 로그인 가능, B01만 (승인 대기) |
|
||||
| ACTIVE | 전체 (B01 + B02~B11) |
|
||||
|
||||
## 역할 (users.role)
|
||||
| 역할 | 전체회사조회 | 역할변경 | 팀원관리 | 가입승인 | 프로젝트조회 범위 |
|
||||
|---|---|---|---|---|---|
|
||||
| SYSTEM_ADMIN | ✅ | ✅ | ✅ | ✅ | 전체 |
|
||||
| ADMIN | ✗ | ✗ | ✅(자기회사) | ✅(자기회사) | 회사별 |
|
||||
| USER | ✗ | ✗ | ✗ | ✗ | 회사별 |
|
||||
|
||||
`is_master` 플래그: TRUE=회사 생성자/ADMIN(팀원 승인권), FALSE=일반 팀원
|
||||
|
||||
## 권한 검증 헬퍼 (B01_Dashboard)
|
||||
| 항목 | 위치 | 역할 |
|
||||
|---|---|---|
|
||||
| `_can_edit_project()` | `B01_Dashboard_Router.py:79` | 역할·회사 기준 프로젝트 수정 권한 |
|
||||
| `_can_manage_automation()` | `B01_Dashboard_Router.py:87` | USER 차단과 프로젝트 범위 검사 |
|
||||
| `_can_edit_user()` | `B01_Dashboard_Router.py:93` | 사용자 수정 범위 검사 |
|
||||
| `count_company_admins()` | `B01_Dashboard_Repository.py:584` | 마지막 ADMIN 삭제·강등 방지 |
|
||||
| `canEditProject()` 외 5개 | `B01_Dashboard_UI_Helper.ts:3` | 프론트 표시 제어; 백엔드 권한을 대체하지 않음 |
|
||||
|
||||
**원칙:** 백엔드가 모든 수정/삭제/역할변경 API에서 반드시 재검증 (프론트 UI는 표시 제어만, 신뢰 금지). 위반 시 403 `{"status":"error","message":"Access denied"}`.
|
||||
|
||||
## 인증 갱신 및 만료 일원화
|
||||
- 기존의 중복된 `auth_expires_at` 컬럼 및 로직을 제거하고, 만료 개념을 **`EMAIL_REVERIFY_DAYS`(90일)로 일원화**하였습니다.
|
||||
- 로그인/가입 인증 이후 90일이 지나면 OTP 재인증을 요구하며, 대시보드 표시 시에도 `last_email_verified_at + 90일`을 계산하여 적용합니다.
|
||||
|
||||
## 라우팅 가드 (frontend.md 5.2)
|
||||
B02~B11 진입 시 `fetchDashboardMe()` → `company_id`+`status` 확인 → NO_COMPANY/PENDING이면 B01로 강제 리다이렉트.
|
||||
|
||||
## 사용처 (역참조)
|
||||
- [[B01_Dashboard/B01_frontend]] — 권한 헬퍼 5종, RBAC 접근제어 및 만료일 동적 계산 표시
|
||||
- [[A06_Login/A06_backend]] — 세션 발급/OTP 재인증, 디바이스 토큰 쿠키 신뢰 판정 및 발급
|
||||
- [[A07_Register/A07_backend]] — 가입 OTP 인증 성공 시 기기 신뢰 연계 등록
|
||||
- [[A09_Security/A09_backend]] — require_master/require_system_admin 권한 데코레이터
|
||||
@@ -0,0 +1,35 @@
|
||||
---
|
||||
status: stable
|
||||
related_pages: ["[[B08_DesignDetail/B08_frontend]]", "[[architecture/shared_resources]]"]
|
||||
last_updated: 2026-07-19
|
||||
source: docs/raw/verification/2026-07-19_verify_b07_external_webcad_demos.md
|
||||
---
|
||||
|
||||
# B07 외부 WebCAD 비교 실행환경
|
||||
|
||||
B07 2D Drawing 후보를 통합 전에 직접 비교한 독립 실행환경이다. [[B08_DesignDetail/B08_dependencies]]의 현행 의존성이 아니라 과거 선택 근거인 `HISTORICAL_REFERENCE`로만 유지한다.
|
||||
|
||||
| 후보 | 위치 | URL | 역할 |
|
||||
|---|---|---|---|
|
||||
| OpenWebCAD | `external_program/openwebcad` | `http://127.0.0.1:5175/` | 기본 Drawing, 스냅, 선택 및 변형 UX 비교 |
|
||||
| elhakimz/WebCAD | `external_program/elhakimz-webcad` | `http://127.0.0.1:5174/` | AutoCAD형 명령, 치수, 레이어 및 DXF 입출력 비교 |
|
||||
| Maker.js | `external_program/makerjs` | `http://127.0.0.1:8020/docs/playground/` | 코드 기반 파라메트릭 기하 생성 비교 |
|
||||
|
||||
## 실행과 종료
|
||||
|
||||
- 일괄 실행: `external_program/start-cad-demos.ps1`
|
||||
- 일괄 종료: `external_program/stop-cad-demos.ps1`
|
||||
- 상세 사용법: `external_program/README_CAD_DEMOS.md`
|
||||
|
||||
## 검증 상태
|
||||
|
||||
- 세 프로젝트의 프로덕션 build 성공
|
||||
- 세 URL의 HTTP 200 응답 확인
|
||||
- 실행 스크립트가 기록한 프로세스 트리만 종료하는 동작 확인
|
||||
- OpenWebCAD Vitest worker 종료 지연, elhakimz/WebCAD 테스트 픽스처 1개 누락, 각 프로젝트 npm audit 경고는 원본 프로젝트 이슈로 기록
|
||||
|
||||
## 라이선스 주의
|
||||
|
||||
- OpenWebCAD: MIT
|
||||
- Maker.js: Apache-2.0
|
||||
- elhakimz/WebCAD: README에는 MIT가 명시되어 있으나 정식 LICENSE 파일이 없어 통합 전 확인 필요. `opencascade.js`는 LGPL-2.1.
|
||||
@@ -0,0 +1,47 @@
|
||||
---
|
||||
type: concept
|
||||
status: stable
|
||||
related_pages: ["[[B01_Dashboard/B01_backend]]", "[[B03_FileInput/B03_backend]]", "[[B04_PreProcess/B04_backend]]", "[[B05_Profile/B05_backend]]", "[[B06_Section/B06_backend]]", "[[auth_rbac]]", "[[architecture/shared_resources]]"]
|
||||
last_updated: 2026-08-13
|
||||
source: ["docs/raw/verification/2026-07-19_verify_half_width_persistence.md", "docs/raw/verification/2026-07-19_verify_B05_B06_차트_레이아웃_후속보정.md", "docs/raw/verification/2026-07-20_verify_B07_상세설계개선.md", "docs/raw/verification/2026-08-01_verify_B04_detailed_basins.md", "docs/raw/verification/2026-08-08_verify_project_delete_hard.md", "docs/raw/verification/2026-08-13_verify_rainfall_wamis_station.md"]
|
||||
---
|
||||
|
||||
# 공통 유틸 (common_util/)
|
||||
|
||||
> 둘 이상의 페이지가 실제로 공유하는 경로·원자적 파일쓰기·기하 유틸만 이 폴더에 배치 (migration_plan.md 2.2)
|
||||
|
||||
| 파일 | 역할 | 사용처 |
|
||||
|---|---|---|
|
||||
| `common_util_validate.ts` | 프론트 1차 유효성 검사 (이메일/빈값/최소길이) | 전 페이지 |
|
||||
| `common_util_auth.py` | 비밀번호·OTP·세션 쿠키·권한 검증, 디바이스 토큰(32B) 발급 및 SHA256 해시, HttpOnly 쿠키 헬퍼 | 전 페이지 → [[auth_rbac]] |
|
||||
| `common_util_auth_repository.py` | 인증·조직·관리 Raw SQL 저장소 (신뢰 기기 토큰 검증 포함) | 인증 관련 |
|
||||
| `common_util_email.py` | 비동기 SMTP 발송+재시도(최대3회) | OTP/승인 알림 |
|
||||
| `common_util_email_templates.py` | 인증·조직 알림 이메일 템플릿 | common_util_email.py |
|
||||
| `common_util_string.ts` | 문자열 유틸 | 미상세 |
|
||||
| `common_util_storage.py` | 프로젝트·워크플로우 단계별 저장 경로 | → [[storage_paths]] |
|
||||
| `common_util_project_delete.py` | 프로젝트 DB/디스크 하드 삭제 유틸 | → [[concepts/common_util/common_util_project_delete]] |
|
||||
| `common_util_json.py` | JSON 원자적 저장 | workflow.json 등 |
|
||||
| `common_util_atomic.py` | 임시 파일을 활용한 바이트 및 npz 데이터 원자적 저장 오퍼레이션 | [[B04_PreProcess/B04_backend]] |
|
||||
| `common_util_workflow.py` | 공유 workflow.json 상태 처리 | ⚠️ [[workflow_state]] 재설계로 대체/정리 예정 |
|
||||
| `common_util_resource_monitor.py` | 시스템 리소스 계측(2분 주기) + log + DB 기록 | `sample_resources_loop()` → [[B01_Dashboard/B01_backend|B01_Dashboard]] |
|
||||
| `common_util_surface_confirmation.py` | 지표면 확정 params 스냅샷 저장, B05 등고선 간격 영속화(`update_contour_interval_param`), config 폴백 조회 헬퍼 | [[B03_FileInput/B03_backend]], [[B04_PreProcess/B04_backend]], [[B05_Profile/B05_backend]] |
|
||||
| `common_util_wamis_station.py` | WAMIS 621개 관측소 xlsx 기반 확률강우량 수급, 반경 10km 최대 지점 선정, Mononobe/General IDF 산출 | [[B04_PreProcess/B04_backend]], [[concepts/drainage_watershed]] |
|
||||
| `common_util_wamis_rainfall.py` | WAMIS 제주 등우선 내삽(96조합) 및 +10km 범위 밖 예외 전파 커버리지 가드 (`value_at`) | [[B04_PreProcess/B04_backend]], [[concepts/drainage_watershed]] |
|
||||
| `common_util_drainage_detail.py` | B04/B05 공용 배수유역/세부유역 분할 및 도로 흐름 수신사 할당 코어 알고리즘 엔진 | [[B04_PreProcess/B04_backend]], [[B05_Profile/B05_backend]] |
|
||||
| `common_util_route_profile.py` | 종단 Z 해석기 및 노선 동일성 판정 API (`resolve_route_profile`, `routes_match`) | [[B04_PreProcess/B04_backend]], [[B05_Profile/B05_backend]] |
|
||||
| `common_util_drainage_context.py` | B04/B05 배수 엔진 연동을 위한 공용 입력 콘텍스트 구조 정의 | [[B04_PreProcess/B04_backend]], [[B05_Profile/B05_backend]] |
|
||||
| `common_util_surface_sampler.py` | 종단/횡단 생성에 필요한 포인트 클라우드 지표면 고도 샘플러 | [[B04_PreProcess/B04_backend]], [[B05_Profile/B05_backend]] |
|
||||
| `common_util_drainage_pipes.py` | 관 매설 지점 정보(`pipe_points.json`) 저장 및 원청 CSV 해시 검증 | [[B04_PreProcess/B04_backend]], [[B05_Profile/B05_backend]] |
|
||||
| `common_util_http_cache.py` | HTTP cache-control, ETag 헤더 기반 304 Not Modified 캐시 유틸 | [[B04_PreProcess/B04_backend]], [[B05_Profile/B05_backend]] |
|
||||
| `B05_Profile_Engine_Sections.py:prune_stale_cross_files` | 유효 측점 목록(`stations`) 기반 구버전 잔재 `cross_*.json` 자동 삭제 및 오삭제 방지 가드 | [[B05_Profile/B05_backend]], [[B06_Section/B06_backend]], [[B08_DesignDetail/B08_backend]] |
|
||||
| `common_util_format.py` | 포맷 유틸 | 미상세 |
|
||||
|
||||
## 이메일 발송 (common_util_email.py)
|
||||
- 개발: Google Gmail SMTP / 상용: Google Workspace 또는 AWS SES
|
||||
- 발송 유형: OTP, 가입확인, 팀원승인요청(ADMIN), 승인/거부결과, 회사참여신청(SYSTEM_ADMIN), 인증갱신알림
|
||||
|
||||
## 리소스 모니터링 (common_util_resource_monitor.py)
|
||||
- `main.py` lifespan에서 `asyncio.create_task` 등록/취소
|
||||
- 계측: `psutil.cpu_percent`, `psutil.virtual_memory().percent`, `shutil.disk_usage`
|
||||
- 이중 기록: `system_resources` 테이블 (DB) + `log/system_resources.log` (탭 구분 1줄, `.gitignore`)
|
||||
- 30일 롤링 삭제 (DB `DELETE`, 로그파일 오래된 줄 제거)
|
||||
@@ -0,0 +1,20 @@
|
||||
---
|
||||
type: concept
|
||||
status: draft
|
||||
related_pages: ["[[architecture/shared_resources]]"]
|
||||
source_file: "common_util/common_util_project_delete.py"
|
||||
last_updated: 2026-08-08
|
||||
---
|
||||
|
||||
# common_util_project_delete.py
|
||||
|
||||
프로젝트 삭제 시 DB 행(ON DELETE CASCADE 연쇄 소멸) 및 물리 영구저장소 디스크 폴더(`storage/{회사}/{사용자}/{프로젝트ID}/`)를 통째로 지우는 하드 삭제 비즈니스 로직을 담당하는 공통 유틸리티 모듈입니다.
|
||||
|
||||
## 🛠️ 주요 함수 목록
|
||||
|
||||
| 항목 | 위치(상대 경로) | 역할 |
|
||||
|---|---|---|
|
||||
| `hard_delete_project()` | `common_util/common_util_project_delete.py` | 트랜잭션 내에서 `storage_path` 조회 및 검증 후 `projects` 행 DELETE, `PROJECT_HARD_DELETE` 감사 로그 추가를 처리하고 커밋 성공 시 rmtree 물리 삭제를 실행 |
|
||||
|
||||
## 🔗 역참조 (사용처)
|
||||
- [[B01_Dashboard/backend/B01_Dashboard_Router]] (스위치에 따른 프로젝트 하드 삭제 API 호출)
|
||||
@@ -0,0 +1,25 @@
|
||||
---
|
||||
type: concept
|
||||
status: draft
|
||||
related_pages: ["[[architecture/shared_resources]]"]
|
||||
source_file: "common_util/common_util_storage.py"
|
||||
last_updated: 2026-08-08
|
||||
---
|
||||
|
||||
# common_util_storage.py
|
||||
|
||||
프로젝트 파일 저장소의 상대 경로 및 루트 절대 경로 안전 변환/검증을 담당하는 공통 물리 파일 시스템 유틸리티 모듈입니다.
|
||||
|
||||
## 🛠️ 주요 함수 목록
|
||||
|
||||
| 항목 | 위치(상대 경로) | 역할 |
|
||||
|---|---|---|
|
||||
| `resolve_stored_project_path()` | `common_util/common_util_storage.py` | DB에 저장된 프로젝트 저장소 상대 경로를 물리 시스템 절대 경로로 해석 반환 (필요 시 디렉터리 생성) |
|
||||
| `resolve_project_root_for_delete()` | `common_util/common_util_storage.py` | 삭제용 경로를 검증 해석하여 물리 절대 경로 반환 (디렉터리를 생성하지 않고 4단계 보안 가드 적용) |
|
||||
| `ensure_project_directory()` | `common_util/common_util_storage.py` | 프로젝트 저장소 디렉토리 존재 보장 및 생성 |
|
||||
|
||||
## 🔗 역참조 (사용처)
|
||||
- [[B01_Dashboard/backend/B01_Dashboard_Router]] (하드 삭제 스위치 시 rmtree 경로 획득 목적)
|
||||
- [[B03_FileInput/backend/B03_FileInput_Router]]
|
||||
- [[B04_PreProcess/backend/B04_PreProcess_Router]]
|
||||
- [[B05_Profile/backend/B05_Profile_Router]]
|
||||
@@ -0,0 +1,26 @@
|
||||
---
|
||||
type: concept
|
||||
status: draft
|
||||
related_pages: ["[[architecture/shared_resources]]"]
|
||||
source_file: "common_util/common_util_workflow_state.py"
|
||||
last_updated: 2026-07-24
|
||||
---
|
||||
|
||||
# common_util_workflow_state.py
|
||||
|
||||
`project_workflow_stages` DB 테이블과 직접 연동하여 7단계(Stage 1~7) 워크플로우 진행 상태(`IN_PROGRESS`, `COMPLETE`, `STALE`, `FAILED`)를 원자적 트랜잭션으로 전이 및 관리하는 백엔드 공통 유틸리티 모듈입니다.
|
||||
|
||||
## 🛠️ 주요 함수 목록
|
||||
|
||||
| 항목 | 위치(상대 경로) | 역할 |
|
||||
|---|---|---|
|
||||
| `get_workflow_state()` | `common_util/common_util_workflow_state.py` | 프로젝트의 7개 스테이지 전이 상태 및 파라미터 맵 조회 |
|
||||
| `start_stage()` | `common_util/common_util_workflow_state.py` | 지정 스테이지를 `IN_PROGRESS`로 바꾸고 파라미터를 JSON 저장 |
|
||||
| `complete_stage()` | `common_util/common_util_workflow_state.py` | 지정 스테이지를 `COMPLETE`로 변경 |
|
||||
| `fail_stage()` | `common_util/common_util_workflow_state.py` | 지정 스테이지를 `FAILED`로 기록 |
|
||||
| `invalidate_subsequent_stages()` | `common_util/common_util_workflow_state.py` | 상위 스테이지 파라미터 변경 시 하위 스테이지들을 `STALE`로 전이 |
|
||||
|
||||
## 🔗 역참조 (사용처)
|
||||
- `[[B04_PreProcess/backend/B04_PreProcess_Router]]`
|
||||
- `[[B05_Profile/backend/B05_Profile_Router]]`
|
||||
- `[[B06_Section/backend/B06_Section_Router]]`
|
||||
@@ -0,0 +1,100 @@
|
||||
---
|
||||
type: concept
|
||||
status: stable
|
||||
related_pages: ["[[B03_FileInput/B03_backend]]", "[[B05_Profile/B05_frontend]]", "[[B06_Section/B06_frontend]]", "[[B07_Quantity/B07_frontend]]", "[[B08_DesignDetail/B08_frontend]]"]
|
||||
last_updated: 2026-08-29
|
||||
source: ["docs/raw/plans/2026-08-29_plan_B05_B06_structure_ui_unification.md", "docs/raw/plans/2026-08-29_plan_B07_CAD_scale_sheet_layout.md", "docs/raw/verification/2026-08-29_verify_B03_reupload_reanalysis_cache.md"]
|
||||
---
|
||||
|
||||
# 2026-08-29 완료 반영
|
||||
|
||||
## B03 재업로드·B05 최신 조회
|
||||
|
||||
| 항목 | 위치 | 역할 |
|
||||
|---|---|---|
|
||||
| `_complete_file_input_if_ready()` | `B03_FileInput/B03_FileInput_Router.py:153` | 동일 파일 전송을 생략해도 완료 요청이면 하위 산출물을 초기화하고 WF1 재실행 |
|
||||
| 업로드 완료 캐시 정리 | `B03_FileInput/B03_FileInput_UI_Page.ts:71` | route·section detail·preload 브라우저 캐시 제거 |
|
||||
| `loadLatest(true)` | `B05_Profile/B05_Profile_UI_Page.ts:747` | B05 최초 접근에서 DB 최신 노선을 강제 조회 |
|
||||
|
||||
재업로드 버튼은 파일 변경 의사로 취급한다. 바이트가 같아 전송을 생략해도 자동계산 차단을 해제하고 재분석하며, B05 초기 진입의 빈 종단·유토곡선·테이블을 유발하던 오래된 route 캐시를 사용하지 않는다.
|
||||
|
||||
## B05/B06 구조물 UI 통합
|
||||
|
||||
| 항목 | 위치 | 역할 |
|
||||
|---|---|---|
|
||||
| 공용 구조물 진입점 | `A00_Common/b_structures_section.ts` | B05 구조물 배치 구현과 스타일을 B05·B06에 동일 공급 |
|
||||
| B06 구조물 패널 | `B06_Section/B06_Section_UI_Page_Structures_Panel.ts` | 구조물 폼·목록 dock·횡단 조정 장착 |
|
||||
| `focusStation()` | `B06_Section/B06_Section_UI_Section_View.ts:714` | 구조물 선택 시 최근접 횡단 카드 선택·스크롤 |
|
||||
| `wireStructureSelection()` | `B06_Section/B06_Section_UI_Page_Structures_Panel.ts:371` | 횡단 구조물 선택을 좌측 폼과 연결 |
|
||||
|
||||
B06 A군 시설 추가·이동·삭제, 중복 제어 정리, B05 대형 패널 분리와 3D 개별 선택은 상시계획서 후속이다.
|
||||
|
||||
## B07 CAD 고정 척도·횡단 장 배치
|
||||
|
||||
| 항목 | 위치 | 역할 |
|
||||
|---|---|---|
|
||||
| 도면 척도 | `config/config_system.py:754` | 종단 1/1,000·1/200, 횡단 1/100 고정 |
|
||||
| `_section_window()` | `B07_DesignDetail/B07_DesignDetail_Engine_Cad.py:337` | 설계선·원지반 교차 범위와 여유로 측점별 표시 폭 결정 |
|
||||
| `plan_cross_sheets()` | `B07_DesignDetail/B07_DesignDetail_Engine_Cad_Sheet.py:84` | 횡단 블록을 좌하단부터 아래→위·좌→우 순서로 장 배치 |
|
||||
| `DRAWING_GROUPS` | `B07_DesignDetail/B07_DesignDetail_UI_Page.ts:78` | 좌측 도면 12분류와 미구현 항목 비활성 표시 |
|
||||
|
||||
A1 고정 도각에서 시험 노선 종단 1장, 횡단 23측점 4장을 확인했다. `DRAWING_FORMAT` 8 상향과 장 단위 확정 실측은 상시계획서 후속이다.
|
||||
|
||||
## B07 CAD 테마
|
||||
|
||||
| 항목 | 위치 | 역할 |
|
||||
|---|---|---|
|
||||
| `theme.ts` | `openwebcad/src/theme.ts` | 부모 `frd_theme`와 CAD iframe 테마 동기화 |
|
||||
| `paintColor()` | `openwebcad/src/theme.ts` | 저장 도면 색상을 화면 테마에 맞춰 표시 보정 |
|
||||
| `bumpSceneVersion()` | `openwebcad/src/theme.ts` | 테마 전환 시 정적 장면 캐시 재생성 |
|
||||
|
||||
라이트·다크 토큰, 캔버스·도면 색상, 동일 오리진 `storage` 이벤트 동기화를 사용자 검증 완료로 기록했다.
|
||||
|
||||
## B07 CAD 확대·팬
|
||||
|
||||
| 항목 | 위치 | 역할 |
|
||||
|---|---|---|
|
||||
| `handleMouseWheel()` | `openwebcad/src/input-controller.ts` | 캔버스 핀치 기본 확대 차단 및 확대 처리 |
|
||||
| `panScreen()` | `openwebcad/src/` | 트랙패드 두 손가락 이동을 팬으로 처리 |
|
||||
|
||||
마우스 휠은 델타 비례 확대, 트랙패드는 팬, `ctrl+wheel`은 CAD 내부 핀치로 처리한다. 핀치·팬 방향과 콘솔 로그 제거는 후속 결정이다.
|
||||
|
||||
## B07↔B08 순서
|
||||
|
||||
| 항목 | 변경 |
|
||||
|---|---|
|
||||
| workflow | 4=상세설계, 5=수량산출 |
|
||||
| 폴더·라우트 | `B07_DesignDetail`·`b07-design-detail`, `B08_Quantity`·`b08-quantity` |
|
||||
| 예외 | iframe 내부 `aislo:b08:*` 프로토콜·패키지명은 호환성 때문에 유지 |
|
||||
|
||||
폴더, 식별자, locale, stage, CAD 정적 경로 교환을 완료했다.
|
||||
|
||||
## 초기값 보전
|
||||
|
||||
| 항목 | 위치 | 역할 |
|
||||
|---|---|---|
|
||||
| `designing_lock_path()` | `common_util/common_util_initial_snapshot.py` | 계산 중 진입 차단 마커 경로 |
|
||||
| `discard_initial_snapshot()` | `common_util/common_util_initial_snapshot.py` | 재설계 시 초기 스냅샷 무효화 |
|
||||
| `routeAfterPreloadCheck` | `A00_Common/b_workflow_nav.ts` | `initial_design`이면 B11 준비 화면으로 라우팅 |
|
||||
| `reset_route_design` 폴백 | `B05_Profile/B05_Profile_Router.py` | 재계산 전 편집 정본 삭제 |
|
||||
|
||||
계산 중 B05·B06 진입 차단, 재설계 시 스냅샷 삭제, 편집 정본 분리와 초기화 복원 실측을 완료로 기록했다. 새 업로드 화면 실측은 후속이다.
|
||||
|
||||
## 초기화 복원 실측
|
||||
|
||||
| 항목 | 확인 |
|
||||
|---|---|
|
||||
| 복원 응답 | `restored=true`, 기존 route 삭제 후 새 route 삽입 |
|
||||
| 정본 복원 | 연장 350.11m·관 지점 4건이 스냅샷 값으로 복귀 |
|
||||
| 처리 시간 | 복원 3초 이내, 폴백 재계산은 10초 이상 |
|
||||
| 작업본 | 초기값 상태로 종결 |
|
||||
|
||||
## 배수시설 추천 기준
|
||||
|
||||
| 판단 대상 | 기준 |
|
||||
|---|---|
|
||||
| 관경 | Kirpich tc(하한 5분) → IDF → 합리식 Q → 2.0배 → Manning 유효직경 |
|
||||
| 부속 | 유량이 아니라 계곡·옆도랑·변곡점·성토 위치 등 지형·배치로 판단 |
|
||||
| 현재 단서 | 관 생성 사유 `source`, 종단 오목 변곡점, B06 성토부선·다단 기슭막이 |
|
||||
|
||||
상세 산식·DEM 기반 지형 보강·임계값 협의는 미결이다.
|
||||
@@ -0,0 +1,37 @@
|
||||
---
|
||||
type: concept
|
||||
status: stable
|
||||
related_pages: ["[[B04_PreProcess/B04_backend]]", "[[B04_PreProcess/B04_frontend]]", "[[B05_Profile/B05_structures]]", "[[B05_Profile/B05_frontend]]", "[[B06_Section/B06_culvert_controls]]"]
|
||||
last_updated: 2026-09-01
|
||||
source: ["docs/raw/plans/2026-09-01_plan_B04_B05_B06_completed_work.md", "docs/raw/verification/2026-09-01_verify_B04_B05_B06_completed_work.md"]
|
||||
---
|
||||
|
||||
# 2026-09-01 완료 — B04 지면 처리·B05/B06 배수 제어
|
||||
|
||||
## 완료 범위
|
||||
|
||||
| 항목 | 위치 | 역할 |
|
||||
|---|---|---|
|
||||
| `append_pipe_points_file()` | `common_util/common_util_drainage_pipes.py` | 저장된 노선 지문을 유지하며 레거시 기슭막이를 관 지점 정본에 추가 |
|
||||
| `MigrationPlan`·`migrate_irregular_stations()` | `B05_Profile/B05_Profile_Structures_Migration.py` | 레거시 후보를 일반 구조물과 관 시설로 분리 |
|
||||
| `migrate_structures()` | `B05_Profile/B05_Profile_Structures_Router.py` | 관 지점 파일이 있을 때만 기슭막이를 이관하고 이력을 기록 |
|
||||
| `enforce_pipe_clearance` | `B05_Profile/`·`B06_Section/` | 횡단배수 최소고 강제를 사용자 선택 옵션으로 저장·전달 |
|
||||
| `resolve_auto_source_filters()` | `B04_PreProcess/B04_PreProcess_Engine_Ground.py` | 분류 LAS는 classification+csf, 미분류 LAS는 csf를 자동 생성 |
|
||||
| `build_ground_masks()` | `B04_PreProcess/B04_PreProcess_Engine_Ground.py` | CSF·grid·classification 지면 마스크 생성과 비율 경고 |
|
||||
| `SURFACE_AUTO_METHODS` | `config/config_system.py` | 자동 생성은 기본 dtm 조합으로 제한하고 나머지는 요청 시 생성 |
|
||||
| `analyzeSurface()` | `B04_PreProcess/B04_PreProcess_Api_Fetch.ts` | 저장되지 않은 필터·표현 조합의 온디맨드 생성 요청 |
|
||||
|
||||
## 저장·호환 규칙
|
||||
|
||||
- 레거시 기슭막이는 `facility=revetment`인 `pipe_points.json` 항목으로 이관한다.
|
||||
- 관 지점 파일이 없으면 기슭막이 이력은 남기지 않아 B04 산출 후 다시 시도한다.
|
||||
- 이관 시 기존 `route_signature`를 유지하며 같은 항목을 중복 추가하지 않는다.
|
||||
- 지표면 manifest 서명은 생성 대상 목록과 분리되어 이미 만든 조합을 재사용한다.
|
||||
- `classification` 필터는 class 2가 유효할 때만 자동 후보가 된다.
|
||||
|
||||
## 검증
|
||||
|
||||
- Python 교차검증: 36 passed.
|
||||
- TypeScript 타입검사: 통과.
|
||||
- B07 CAD 편의성 작업은 별도 전체 시험 실패로 완료 범위에서 제외했다.
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
---
|
||||
type: concept
|
||||
status: stable
|
||||
related_pages: ["[[completed_2026-09-01]]", "[[completed_2026-08-29]]", "[[B03_FileInput/B03_backend]]", "[[B04_PreProcess/B04_backend]]", "[[B05_Profile/B05_frontend]]", "[[B08_DesignDetail/B08_frontend]]"]
|
||||
last_updated: 2026-09-01
|
||||
source: ["docs/raw/plans/2026-09-01_plan_remaining_checked_items.md", "docs/raw/plans/2026-09-01_plan_implementation_verification_hold.md", "docs/raw/plans/2026-09-01_plan_implementation_verification_context_hold.md", "docs/raw/verification/2026-09-01_verify_remaining_checked_items.md"]
|
||||
---
|
||||
|
||||
# 2026-09-01 잔여 완료 체크 정리
|
||||
|
||||
상시 계획서의 혼합 섹션에 남아 있던 완료 체크 37개를 추가 아카이빙한 원장이다. 세부 구현 정의는 기존 기능별 위키를 정본으로 유지한다.
|
||||
|
||||
## 범위
|
||||
|
||||
| 영역 | 완료 내용 | 상세 위키 |
|
||||
|---|---|---|
|
||||
| B03/B04 | shapefile 노선 병합, 곡선 경고 현행 유지, 라이다·도엽 서피스 정합 조사 | [[B03_FileInput/B03_backend]], [[B04_PreProcess/B04_backend]] |
|
||||
| B05/B06 | 구조물 UI 중복 정리와 관련 후속 판정 | [[B05_Profile/B05_frontend]], [[B06_Section/B06_frontend]] |
|
||||
| B08 CAD | 전환·커서·패널, 잠금 도면층, 도각·표지·유역도 표현, 프로젝트 소유 검증 | [[B08_DesignDetail/B08_CAD_interaction]], [[B08_DesignDetail/B08_frontend]] |
|
||||
| 좌표계 | 배수유역 역투영, 저장 좌표계, 도엽·라이다 공통 화면 원점 | [[crs_metadata]], [[drainage_watershed]] |
|
||||
|
||||
## 보류 구분
|
||||
|
||||
- B07 편의성 구현 기록은 CAD 전체 시험 실패로 완료 범위에 포함하지 않았다.
|
||||
- B07 항목은 상시 계획서에서 재검증 대기 미체크 항목으로 유지한다.
|
||||
- 노선 원천화·B04 3D 트림·보조 포트 분리의 구현 완료 기록은 별도 검증 보류 원문으로 분리하고, PLAN에는 실데이터·직접 기동 검증만 유지한다.
|
||||
- PRJ 관련 기존 실패 10건 분류는 결론이 나지 않아 미체크 확인 과제로 바로잡았다.
|
||||
@@ -0,0 +1,46 @@
|
||||
---
|
||||
type: concept
|
||||
status: stable
|
||||
related_pages: ["[[B04_PreProcess/B04_frontend]]", "[[B05_Profile/B05_backend]]", "[[B05_Profile/B05_corridor_cut_fill]]", "[[B08_DesignDetail/B08_frontend]]", "[[B08_DesignDetail/B08_CAD_title_block]]"]
|
||||
last_updated: 2026-09-02
|
||||
source: ["docs/raw/plans/2026-09-02_plan_completed_items.md", "docs/raw/plans/2026-09-02_plan_user_verified_completed_items.md", "docs/raw/plans/2026-09-02_plan_B05_profile_edit_followup_completed.md"]
|
||||
---
|
||||
|
||||
# 2026-09-02 완료 항목
|
||||
|
||||
## 노선·지표면
|
||||
|
||||
- 용화 관 11개 측점은 트림 노선 0~1070.39m 안에 있고, 종단 PVI 13개가 관 측점과 일치한다.
|
||||
- 용화 노선은 트림·조밀화 뒤 323정점·1070.39m이며 B04 최고 표고 평면에 표시된다.
|
||||
- B04 화면맞춤은 전체 노선을 포함하고 종단 생성 경로는 `pipe_anchored`와 `station_alignment`로 구분한다.
|
||||
- 용화 관 측점 11개의 재계산 계획고와 지반고 차이는 0.000m다.
|
||||
|
||||
## 작업 환경
|
||||
|
||||
- 보조 워크트리는 8001·5174, 메인 환경은 8000·5173으로 동시에 기동한다.
|
||||
- CAD `dist/`는 서버 기동 빌드 체인에 포함되며 재시작 절차는 `CLAUDE.md`에 있다.
|
||||
|
||||
## CAD
|
||||
|
||||
- `desynchronized` 저지연 캔버스는 스냅 결함 때문에 철회된 상태다.
|
||||
- 일반 그룹의 `groupId`는 JSON 저장·복원 시 ID 기준으로 왕복한다.
|
||||
- CAD 패널 폭은 300px이며 반복 `setScreenScale` 콘솔 로그는 제거됐다.
|
||||
- 명령행은 기본 숨김이며 전체 CAD 회귀 시험 87건이 통과했다.
|
||||
- 표제란·표지는 프로젝트·회사·담당자·축척·날짜·도면번호를 공통 치환 경로로 공급한다.
|
||||
- 회사 로고·서명 자산과 회사 도각 편집·기본 복원 경로가 연결됐다.
|
||||
|
||||
## B05 구조물 3D
|
||||
|
||||
- 평면 진단 스케치는 기본 숨김이며 디버그 스위치로 다시 표시한다.
|
||||
- `patch`·`patchClip` 저장 왕복, BOX 패치 클리핑, 마스크 고리 단순화 결함을 반영했다.
|
||||
- 지형 클리핑 윤곽 확장은 실측 최대 초과 0.23m라 현행 유지로 닫았다.
|
||||
|
||||
## B05 종단 편집 후속
|
||||
|
||||
- 최소고 판정은 `_Profile_Panel.applyEdits` 단일 창구에서 모든 편집 경로에 적용된다.
|
||||
- 종단 편집 이력은 `b05:pipes` 관 목록도 함께 기록해 되돌리기에서 구조물 위치를 복원한다.
|
||||
|
||||
## 회귀 상태
|
||||
|
||||
- Python `tmp/tests/`는 343 passed, 17 skipped, 0 failed다.
|
||||
- 별도 CAD 전체 시험은 87건 통과로 [[B08_DesignDetail/B08_CAD_usability_2026-09-01]]에서 완료 처리했다.
|
||||
@@ -0,0 +1,29 @@
|
||||
---
|
||||
type: concept
|
||||
status: stable
|
||||
related_pages: ["[[B03_FileInput/B03_route_snapshot_crs]]", "[[B04_PreProcess/B04_drainage_compass_crs]]", "[[B05_Profile/B05_masshaul_structure_2026_09]]", "[[B06_Section/B06_masshaul_culvert_2026_09]]", "[[B08_DesignDetail/B08_cad_delivery_2026_09]]"]
|
||||
last_updated: 2026-09-03
|
||||
source: ["docs/raw/plans/2026-09-03_plan_completed_items.md"]
|
||||
---
|
||||
|
||||
# 2026-09-03 완료 — 입력·배수·종횡단·CAD
|
||||
|
||||
사용자와 개발 담당 AI가 검증을 완료한 47개 항목이다. 사용자 지시에 따라 위키 관리자의 별도 2차 교차검증과 검증보고서는 생략했다.
|
||||
|
||||
## 완료 범위
|
||||
|
||||
| 영역 | 완료 내용 | 상세 |
|
||||
|---|---|---|
|
||||
| B03 | shapefile 변환 CSV 정본, LAS 없는 도엽 좌표계, 업로드 버튼 상태 | [[B03_FileInput/B03_route_snapshot_crs]] |
|
||||
| B04 | 세부유역 다중 링·면적 보존, 종단 마루 분수령, 3D 방위, 좌표계 창구 | [[B04_PreProcess/B04_drainage_compass_crs]] |
|
||||
| B05 | 유토곡선 공용화, 구조물 3D 판정, 편집 함수 유지 결정 | [[B05_Profile/B05_masshaul_structure_2026_09]] |
|
||||
| B06 | I형 집수정 관 형상, 낡은 유토곡선 차단, 사면 경고, 파일 분리 | [[B06_Section/B06_masshaul_culvert_2026_09]] |
|
||||
| B08 | SVG 서명, 횡단 장 확정, 해칭 절취, 자동 축척과 납품 표기 | [[B08_DesignDetail/B08_cad_delivery_2026_09]] |
|
||||
|
||||
## 공통 결정
|
||||
|
||||
- 절·성토 불균형은 자동 보정하지 않고 최종 누가토량으로 진단한다.
|
||||
- B05와 B06은 같은 `mass_haul` 데이터·계산·템플릿을 사용한다.
|
||||
- 세부유역은 구멍과 분리 조각을 보존하며 100㎡ 최소면적 필터를 적용하지 않는다.
|
||||
- 작업 좌표계는 지형 PRJ를 우선하며 공통 해석 창구를 사용한다.
|
||||
- B08 납품 도면은 길이별 자동 축척과 현행 표기 규약을 따른다.
|
||||
@@ -0,0 +1,29 @@
|
||||
---
|
||||
type: concept
|
||||
status: stable
|
||||
related_pages: ["[[B03_FileInput/B03_upload_ui_2026_09]]", "[[B04_PreProcess/B04_compass_crs_2026_09]]", "[[B05_Profile/B05_profile_interaction_2026_09]]", "[[B06_Section/B06_cross_design_ui_2026_09]]", "[[B08_DesignDetail/B08_cad_delivery_2026_09]]"]
|
||||
last_updated: 2026-09-03
|
||||
source: ["docs/raw/plans/2026-09-03_plan_completed_items_2.md"]
|
||||
---
|
||||
|
||||
# 2026-09-03 추가 완료 — 화면·종단·횡단
|
||||
|
||||
사용자와 개발 담당 AI가 검증을 완료한 추가 56개 항목이다. 사용자 지시에 따라 위키 관리자의 2차 교차검증과 별도 검증보고서는 생략했다.
|
||||
|
||||
## 완료 범위
|
||||
|
||||
| 영역 | 완료 내용 | 상세 |
|
||||
|---|---|---|
|
||||
| B03 | 파일 선택 화면 축소, 공용 안내 패널, LAS 없는 입력, SHP 전용 선택 | [[B03_FileInput/B03_upload_ui_2026_09]] |
|
||||
| B04 | 3D 경사 나침반 링과 작업 좌표계 불일치 차단 | [[B04_PreProcess/B04_compass_crs_2026_09]] |
|
||||
| B05 | 전 측점 종단곡선, 프론트 횡단 미러링, 3D 나침반 | [[B05_Profile/B05_profile_interaction_2026_09]] |
|
||||
| B06 | 횡단 계산 TS 미러, 성토사면 길이, 배수관 공통 표기 | [[B06_Section/B06_cross_design_ui_2026_09]] |
|
||||
| B07·B08 | 전체 성토구간 토적도 해석, 운반 블록 표시 확인, CAD 완료 판정 | [[B08_DesignDetail/B08_cad_delivery_2026_09]] |
|
||||
|
||||
## 최신 결정
|
||||
|
||||
- B03 사용자가 선택하는 계획노선은 SHP이며 CSV는 내부 계산 정본이다.
|
||||
- B04 3D 방위 위젯은 축 트라이어드 시안을 거쳐 경사 나침반 링으로 확정됐다.
|
||||
- B05 초기 종단선은 모든 내부 측점에 접선 종단곡선을 만들고 측점 계획고를 지반고와 맞춘다.
|
||||
- 사용자 편집 중 횡단 계산은 TypeScript 미러가 즉시 수행하고 Python은 저장·검증 정본이다.
|
||||
- 라이다와 도엽 좌표계 불일치는 B03 입력 단계에서 차단한다.
|
||||
@@ -0,0 +1,64 @@
|
||||
---
|
||||
type: concept
|
||||
status: stable
|
||||
related_pages: ["[[B01_Dashboard/B01_frontend]]", "[[B03_FileInput/B03_frontend]]", "[[B04_PreProcess/B04_frontend]]", "[[B05_Profile/B05_frontend]]", "[[B06_Section/B06_frontend]]", "[[B08_DesignDetail/B08_frontend]]", "[[ui_templates]]", "[[common_util]]"]
|
||||
last_updated: 2026-09-04
|
||||
source: ["docs/raw/plans/2026-09-04_plan_user_verified_completed_items.md", "docs/raw/plans/2026-09-04_plan_completed_items.md", "docs/raw/plans/2026-09-04_plan_700line_split.md", "docs/raw/plans/2026-09-04_plan_snapshot_before_cleanup.md"]
|
||||
---
|
||||
|
||||
# 2026-09-04 완료 항목
|
||||
|
||||
사용자 검증 완료 20개 작업·체크 109개와 개발 담당 AI의 자체검증이 기록된 추가 완료 5개 작업 및 700줄 제한 분리 15개를 안정 상태로 반영했다. 추가 완료분은 2026-09-04 사용자 지시에 따라 위키 관리자의 별도 2차 교차검증과 검증보고서 작성을 생략했다. 미완료 항목이 남은 「B05 초기화 범위 확대 — 전체 결과 보존」과 착수 전인 죽은 코드·중복 코드 정리는 제외했다.
|
||||
|
||||
## 완료 범위
|
||||
|
||||
| 영역 | 완료 내용 | 관련 위키 |
|
||||
|---|---|---|
|
||||
| 공통 | 사용자 입력을 shapefile 중심으로 표기하고 내부 CSV 정본과 구분 | [[B03_FileInput/B03_frontend]] |
|
||||
| 공통 | B03~B08 좌측 패널 제목 줄에 프로젝트명 표시 | [[ui_templates]] |
|
||||
| B01 | 프로젝트 수정 시 회사 로고 기본 연결 | [[B01_Dashboard/B01_frontend]] |
|
||||
| B01 | 모달 바깥 클릭 닫기와 변경 내용 확인 | [[B01_Dashboard/B01_frontend]] |
|
||||
| B02·B03 | 계획노선 시·종점 누가거리 입력과 절단 여유 3m | [[B03_FileInput/B03_backend]] |
|
||||
| B03 | 파일 카드 전폭 120px 미리보기, LAS 점 표본·GeoTIFF·부속 파일 정보 표시 | [[B03_FileInput/B03_frontend]] |
|
||||
| B04·B05 | 배수유역도 줌 한계 확대와 노선 측점 표기 | [[drainage_watershed]] |
|
||||
| B05 | 초기 진입 로딩을 3D 직전에 끝내고 3D를 후순위로 생성 | [[B05_Profile/B05_frontend]] |
|
||||
| B05 | 초기화 시 계획선 편집 초안 제거와 `draft:none` 키 폐지 | [[B05_Profile/B05_frontend_alignment]] |
|
||||
| B05 | 확정 시 포장 사용자 지정값 보존 확인 | [[B05_Profile/B05_structure_stations]] |
|
||||
| B05 | 3D 구조물 개별 선택과 B05·B06 선택 상태 공유 | [[B05_Profile/B05_structures]] |
|
||||
| B05 | 3D 절토 구간 측점 및 전체 라벨 표시 | [[B05_Profile/B05_frontend_viewer]] |
|
||||
| B05 | 3D 카메라를 원근 투영으로 복원 | [[B05_Profile/B05_frontend_viewer]] |
|
||||
| B05·B06 | 종단 줌 버튼 3개, 보이는 구간 Y 자동 맞춤, 유토곡선 연동 | [[B05_Profile/B05_profile_interaction_2026_09]] |
|
||||
| B06 | 표준 횡단면 상세값을 단일 컨테이너로 통합 | [[B06_Section/B06_frontend]] |
|
||||
| B08 도면 | 횡단면도 축척 일관성 정리 | [[B08_DesignDetail/B08_cross_structure_sheets]] |
|
||||
| B08 도면 | 표준 횡단면 변수 모식도·치수·부분확대·암반선 | [[B08_DesignDetail/B08_cross_structure_sheets]] |
|
||||
| B08 도면 | 계획평면도 3종에 수치등고선 배경 공유 | [[B08_DesignDetail/B08_frontend]] |
|
||||
| B08 도면 | 계획평면도(라이다)에 3D 탑뷰 배치 | [[B08_DesignDetail/B08_frontend]] |
|
||||
| B08 도면 | 용지도에 등고선·지적·행정구역·범례 배치 | [[B08_DesignDetail/B08_frontend]] |
|
||||
|
||||
## 추가 완료 범위
|
||||
|
||||
| 영역 | 완료 내용 | 관련 위키 |
|
||||
|---|---|---|
|
||||
| B03 | 업로드 카드에 경량 그래픽 미리보기와 노선·지형 범위 판정 추가 | [[B03_FileInput/B03_frontend]] |
|
||||
| 공통 | B03~B08 진행단계 패널 드래그·영역 제한·열림 방향 자동 전환·세션 위치 보존 | [[ui_templates]] |
|
||||
| B05 | 종단 계획선의 방향키 연속 이동과 단일 이력 처리 | [[B05_Profile/B05_profile_interaction_2026_09]] |
|
||||
| B05 | 종단 X/Y 줌 조작구와 그래프·표·구조물 레인 정렬 유지 | [[B05_Profile/B05_profile_interaction_2026_09]] |
|
||||
| B05 | 구조물 측점 값 열 표시 및 직선화 뒤 곡선 행 정리 | [[B05_Profile/B05_frontend]] |
|
||||
|
||||
## 700줄 제한 분리
|
||||
|
||||
- Python·TypeScript·CSS 대형 파일 15개를 기존 공개 심볼과 호출 경로를 유지한 채 하위 모듈로 분리했다.
|
||||
- 최종 전수 점검에서 700줄 초과 파일은 0건이다. 자체검증 기록에는 `tsc --noEmit`, `ruff check`, 분리 전후 공개 심볼·라우트 대조, 화면 실측 및 `tmp/tests` 결과가 포함된다.
|
||||
- B04 배수유역 분석 재실행 쓰기 경로는 산출물 덮어쓰기 위험 때문에 실행하지 않았다는 제한을 원문에 보존한다.
|
||||
|
||||
## 상시계획서 추가 완료 범위
|
||||
|
||||
- B03 계획노선 미리보기의 점선 상자 제거·녹색 실선, 완료 카드 파일 교체와 재분석, SHX·DBF·CPG·PRJ 상세값 및 래스터 테두리를 반영했다.
|
||||
- B08 상세설계 화면의 횡단 칸 간격·리본 높이·도면 목록 라벨을 정리했다.
|
||||
- B05/B06 종단·유토곡선의 변환 기반 세로 맞춤, 스크롤 성능, 완화된 창 전환, 클리핑과 구조물 누가거리 정본 맞춤을 반영했다.
|
||||
- 위 완료 기록은 정리 전 상시계획서 원문 스냅샷에 보존하고, 미완료 하위 작업만 새 상시계획서로 옮겼다.
|
||||
|
||||
## 보존된 미완료 범위
|
||||
|
||||
- B05 초기화 스냅샷의 3D 코리도 포함 여부와 새 프로젝트 실경로 검증은 [[B05_Profile/B05_backend]] 관련 상시 계획으로 남아 있다.
|
||||
- 죽은 코드·중복 코드 정리는 착수 지시 대기 상태이므로 완료 범위에 포함하지 않는다.
|
||||
@@ -0,0 +1,32 @@
|
||||
---
|
||||
type: completion-summary
|
||||
status: stable
|
||||
related_pages: ["[[architecture/workflow_data_flow]]", "[[B05_Profile/B05_backend]]", "[[B06_Section/B06_backend]]", "[[B07_DesignDetail/B07_frontend]]", "[[B08_Quantity/B08_overview_2026_09]]"]
|
||||
last_updated: 2026-09-09
|
||||
source: ["docs/raw/plans/2026-09-07_plan_completed_items.md", "docs/raw/plans/2026-09-07_plan_completed_items_2.md", "docs/raw/plans/2026-09-07_plan_completed_items_3.md", "docs/raw/plans/2026-09-07_speed_watershed_shelved.md"]
|
||||
---
|
||||
|
||||
# 2026-09-07 완료·보류 요약
|
||||
|
||||
## 완료 범위
|
||||
|
||||
| 영역 | 완료 내용 | 근거 상태 |
|
||||
|---|---|---|
|
||||
| 공통 | 노선 자동탐색 중단, 평면 법정검사, 계획노선 폴리라인·직선-곡선-직선 계약 | 사용자 확정과 자체검증 기록 |
|
||||
| 공통 | B05·B06 캐시·세션 및 계산 자리 일원화, 노선 변경 후속 데이터 규칙 | 완료 아카이브 기록 |
|
||||
| B01·B02 | 권한·회사·프로젝트 연결과 화면 후속 | 완료 아카이브 기록 |
|
||||
| B03·B04 | 라이다 다중 파일 병합, LAS 없는 입력 검사, 대형 파일 분리 | 완료 아카이브 기록 |
|
||||
| B05 | 구조물 선택 전달, 팬·테이블·유토곡선 UI, 누가거리 정본, 초기값 실경로 | 사용자 실측·자체검증 기록 |
|
||||
| B06 | 곡선부 확폭, 구조물 절·성토 면적, 기슭막이 분리·연계, 소단·절토경사 입력 | 사용자 실측·자체검증 기록 |
|
||||
| B07 | 외부 도각, DXF·DWG 내보내기, LibreDWG, 자리표 편집 | 완료 아카이브 기록 |
|
||||
|
||||
## 성능·운영 결정
|
||||
|
||||
- 노선 확인 시간은 293초에서 약 90초로 줄인 상태를 종료 기준으로 채택했다.
|
||||
- 유역 속도 개선의 별도 갈래 3개는 구현하지 않기로 하고 보관본에 남겼다.
|
||||
- 백엔드 감시 중단과 Vite IPv6 프록시 문제의 재발 방지 기록을 보존했다.
|
||||
|
||||
## 주의
|
||||
|
||||
- 이 페이지는 이관 문서의 완료 선언과 자체검증을 요약한다. 독립 검증보고서가 없는 항목은 세부 수치보다 원문 근거를 우선한다.
|
||||
- 이후 2026-09-08~09 변경은 [[quantity_cost_contract]]와 각 B08·B09 페이지를 기준으로 판정한다.
|
||||
@@ -0,0 +1,40 @@
|
||||
---
|
||||
type: concept
|
||||
status: stable
|
||||
related_pages: ["[[B03_FileInput/B03_backend]]", "[[B04_PreProcess/B04_backend]]", "[[dependencies]]", "[[architecture/shared_resources]]"]
|
||||
last_updated: 2026-08-16
|
||||
source: ["docs/raw/plans/2026-07-18_plan_crs_normalization.md", "docs/raw/verification/2026-07-18_verify_crs_and_polling_log.md"]
|
||||
---
|
||||
|
||||
# CRS 메타데이터 정상화
|
||||
|
||||
## 검증된 판정
|
||||
|
||||
| 항목 | 위치 | 역할·판정 |
|
||||
|---|---|---|
|
||||
| `normalize_crs_metadata()` | `B03_FileInput/B03_FileInput_Engine_Analyze.py` | 복합 CRS를 수평·수직 요소로 분리하고 JSON 직렬화 가능한 공통 구조로 정규화 |
|
||||
| `epsg` | B03 분석 메타데이터 | 복합 CRS 전체가 아니라 지도 변환에 쓰는 수평 EPSG를 유지; 실제 자료에서 `5187` 확인 |
|
||||
| `horizontal_crs` | B03 분석 메타데이터 | 수평 CRS 식별 결과와 authority 보존 |
|
||||
| `vertical_crs` | B03 분석 메타데이터 | KNGeoid24 같은 수직 기준을 수평 CRS와 분리 보존 |
|
||||
| `crs_status` | B03 분석 메타데이터 | `identified`, `custom_vertical_crs`, `unknown_horizontal_crs`, `missing_crs` 구분 |
|
||||
| `custom_authority_codes` | B03 분석 메타데이터 | KNGeoid24 WKT의 사설 코드 표식을 파싱용 WKT와 분리해 원문 정보 보존 |
|
||||
|
||||
## 데이터 흐름
|
||||
|
||||
| 생산자 | 처리 | 소비자 |
|
||||
|---|---|---|
|
||||
| GeoTIFF·PRJ·LAS 업로드 | `normalize_crs_metadata()` | `input_files` 메타데이터 및 B04/B05 좌표 변환 |
|
||||
| 복합 CRS | 수평 EPSG와 수직 기준 분리 | `epsg=5187`, `vertical_crs=KNGeoid24` 형태 |
|
||||
| 알 수 없는 수평 CRS | 추측하지 않고 `epsg=None` | 사용자 확인이 필요한 `unknown_horizontal_crs` 상태 |
|
||||
|
||||
## 검증 범위와 모순 이력
|
||||
|
||||
- 실제 `result.tif`, `result.prj`, `cloud_merged.las`로 수평 EPSG 5187과 KNGeoid24 분리 처리가 검증됐다.
|
||||
- 같은 검증보고서에서 B04 status 폴링 로그 제거 방식은 전체 access log를 꺼 부작용이 있어 FAIL이었다.
|
||||
- 해당 B04 실패는 후속 B04 검증에서 `access_log=False` 롤백과 일반 사용자 진입 가드 방식으로 대체됐다. CRS 정상화 PASS와 B04 폴링 FAIL을 하나의 상태로 합치지 않는다.
|
||||
|
||||
## 사용처
|
||||
|
||||
- [[B03_FileInput/B03_backend]] — 업로드 파일 메타데이터 분석과 DB 저장
|
||||
- [[B04_PreProcess/B04_backend]] — 지표면·GIS 처리 좌표 기준
|
||||
- [[dependencies]] — Rasterio/Pyproj PROJ 런타임 차이 모니터링
|
||||
@@ -0,0 +1,98 @@
|
||||
---
|
||||
type: concept
|
||||
status: stable
|
||||
related_pages: ["[[B03_FileInput/B03_backend]]", "[[B04_PreProcess/B04_backend]]", "[[architecture/shared_resources]]"]
|
||||
last_updated: 2026-07-17
|
||||
source: docs/raw/verification/2026-07-17_verify_b04_confirm_and_2d_map.md
|
||||
---
|
||||
|
||||
# DB: 파일/지표면분석 테이블
|
||||
|
||||
← [[db_schema/overview]]
|
||||
|
||||
## upload_sessions (업로드 세션)
|
||||
| 컬럼 | 타입 | Null | Key | Default / Extra |
|
||||
|---|---|---|---|---|
|
||||
| `id` | `varchar(36)` | NO | PRI | 세션 UUID |
|
||||
| `project_id` | `varchar(36)` | NO | MUL | FK→projects.id |
|
||||
| `original_filename` | `varchar(255)` | NO | | 원본 파일명 |
|
||||
| `file_size_bytes` / `chunk_size_bytes` | `bigint(20)` | NO | | 파일크기 / 청크크기 |
|
||||
| `total_chunks` / `completed_chunks` | `int(11)` | - | | 전체 청크수 / 완료 청크수 |
|
||||
| `status` | `enum('PENDING','IN_PROGRESS','COMPLETED','FAILED')` | YES | MUL | `PENDING` |
|
||||
| `created_at` / `updated_at` | `timestamp` | YES | | 생성 / 최종수정 일시 |
|
||||
|
||||
## upload_chunks (업로드 청크 데이터)
|
||||
| 컬럼 | 타입 | Null | Key | Default / Extra |
|
||||
|---|---|---|---|---|
|
||||
| `id` | `int(11)` | NO | PRI | `auto_increment` |
|
||||
| `session_id` | `varchar(36)` | NO | MUL | FK→upload_sessions.id |
|
||||
| `chunk_index` | `int(11)` | NO | | 청크 인덱스 (0, 1, 2...) |
|
||||
| `chunk_hash` | `varchar(64)` | YES | | 청크 검증용 체크섬 |
|
||||
| `size_bytes` | `bigint(20)` | NO | | 청크 용량 |
|
||||
| `stored_at` | `varchar(255)` | YES | | 임시 파일 저장 경로 |
|
||||
| `completed_at` | `timestamp` | YES | MUL | 완료 일시 |
|
||||
|
||||
## input_files (입력 원본 파일)
|
||||
| 컬럼 | 타입 | Null | Key | Default / Extra |
|
||||
|---|---|---|---|---|
|
||||
| `id` | `int(11)` | NO | PRI | `auto_increment` |
|
||||
| `project_id` | `char(36)` | NO | MUL | FK→projects.id |
|
||||
| `file_type` | `varchar(50)` | YES | | `las`/`tif`/`prj`/`tfw`/`dxf` 등 |
|
||||
| `original_filename` / `raw_file_path` | `varchar` | NO | | 파일명 / storage 상대경로 |
|
||||
| `file_size_mb` | `float` | YES | | 파일 크기 (MB) |
|
||||
| `upload_by` / `upload_at` | - | - | MUL | 업로드 유저 FK / 일시 |
|
||||
| `crs_epsg` | `int(11)` | YES | | EPSG 좌표계 정보 |
|
||||
| `metadata` | `longtext` | YES | | 헤더/포인트수 등 분석 JSON |
|
||||
| `status` | `varchar(50)` | YES | | `UPLOADED` ➡️ `PROCESSED` ➡️ `ARCHIVED` |
|
||||
|
||||
## processed_point_cloud (필터/변환 포인트클라우드)
|
||||
| 컬럼 | 타입 | Null | Key | Default / Extra |
|
||||
|---|---|---|---|---|
|
||||
| `id` | `int(11)` | NO | PRI | `auto_increment` |
|
||||
| `input_file_id` / `project_id` | - | NO | MUL | FK→input_files / projects |
|
||||
| `process_type` | `varchar(50)` | YES | | 변환 필터 분류 |
|
||||
| `processed_file_path` / `converted_file_path` | `varchar` | YES | | 저장 경로 / PLY/LAZ 경로 |
|
||||
| `converted_format` | `varchar(50)` | YES | | 변환 포맷 |
|
||||
| `point_count` | `int(11)` | YES | | 포인트 개수 |
|
||||
| `min_z` / `max_z` / `mean_z` | `float` | YES | | 고도 최저 / 최고 / 평균 |
|
||||
| `x_min` ~ `y_max` | `float` | YES | | X/Y 좌표 바운딩 박스 범위 |
|
||||
| `density_per_sqm` | `float` | YES | | ㎡당 점 밀도 |
|
||||
| `classification_summary` | `longtext` | YES | | ground/unclassified 통계 |
|
||||
| `processing_params` | `longtext` | YES | | 분석 파라미터 JSON |
|
||||
| `processed_at` / `status` | - | - | | 변환 일시 / `PROCESSING`\|`COMPLETE`\|`FAILED` |
|
||||
|
||||
## surface_models (지표면 모델 및 등고선)
|
||||
| 컬럼 | 타입 | Null | Key | Default / Extra |
|
||||
|---|---|---|---|---|
|
||||
| `id` | `int(11)` | NO | PRI | `auto_increment` |
|
||||
| `project_id` | `char(36)` | NO | MUL | FK→projects.id |
|
||||
| `model_type` | `varchar(50)` | YES | | `dem_grid`/`tin`/`mesh`/`contour` |
|
||||
| `source_file_id` / `processed_cloud_id` | `int(11)` | YES | MUL | FK→input_files / processed |
|
||||
| `status` | `varchar(50)` | YES | | `PROCESSING` ➡️ `COMPLETE` / `FAILED` / `CONFIRMED` |
|
||||
| `crs_epsg` / `resolution_m` | - | YES | | EPSG 좌표 / DEM 격자 해상도 |
|
||||
| `model_file_path` | `varchar(500)` | YES | | 스토리지 상대 경로 |
|
||||
| `generation_params` | `longtext` | YES | | 격자화 알고리즘 인자 JSON |
|
||||
| `created_at` / `completed_at` | `timestamp` | - | | 생성 / 완료 일시 |
|
||||
|
||||
## terrain_layers (지형 레이어)
|
||||
| 컬럼 | 타입 | Null | Key | Default / Extra |
|
||||
|---|---|---|---|---|
|
||||
| `id` | `int(11)` | NO | PRI | `auto_increment` |
|
||||
| `surface_model_id` | `int(11)` | NO | MUL | FK→surface_models.id |
|
||||
| `layer_name` | `varchar(100)` | YES | | 레이어 영문/한글 식별자 |
|
||||
| `geometry_type` | `varchar(50)` | YES | | `POINTCLOUD`/`GRID`/`MESH`/`CONTOUR` |
|
||||
| `layer_file_path` | `varchar(500)` | YES | | 개별 레이어 실 파일 경로 |
|
||||
| `file_format` / `file_size_mb` | - | YES | | 포맷 (ply, tfw, las 등) / 크기 |
|
||||
| `statistics` | `longtext` | YES | | 통계 수치 JSON |
|
||||
| `created_at` | `timestamp` | NO | | 생성 일시 |
|
||||
|
||||
## input_files.status 값
|
||||
`UPLOADED → PROCESSED → ARCHIVED`
|
||||
|
||||
## surface_models.status 값
|
||||
`PROCESSING → COMPLETE / FAILED / CONFIRMED` (CONFIRMED는 사용자가 해당 모델을 설계 지표면 정보로 최종 확정했음을 의미)
|
||||
|
||||
## processed_point_cloud.status 값
|
||||
`PROCESSING → COMPLETE / FAILED`
|
||||
|
||||
관련 함수 위치 → [[B04_PreProcess/B04_db]], 사용 라이브러리 → [[dependencies]]
|
||||
@@ -0,0 +1,99 @@
|
||||
---
|
||||
type: concept
|
||||
status: stable
|
||||
related_pages: ["[[B01_Dashboard/B01_backend]]", "[[architecture/shared_resources]]"]
|
||||
last_updated: 2026-07-19
|
||||
source: raw/guidelines/db_schema.md, raw/guidelines/backend.md, docs/raw/verification/2026-07-12_verify_add_phase4_role.md
|
||||
---
|
||||
|
||||
# DB: 로그/모니터링 테이블
|
||||
|
||||
← [[db_schema/overview]]
|
||||
|
||||
## login_logs (로그인 시도 로그)
|
||||
| 컬럼 | 타입 | Null | Key | Default / Extra |
|
||||
|---|---|---|---|---|
|
||||
| `id` | `bigint(20)` | NO | PRI | `auto_increment` |
|
||||
| `user_id` | `int(11)` | YES | MUL | FK→users.id |
|
||||
| `email` | `varchar(255)` | NO | | |
|
||||
| `status` | `enum('SUCCESS','FAILURE')` | NO | | |
|
||||
| `failure_reason` / `user_agent` | `varchar(100)` / `text` | YES | | |
|
||||
| `login_at` | `timestamp` | NO | MUL | `current_timestamp()` |
|
||||
|
||||
## activity_logs (사용자 활동 로그)
|
||||
| 컬럼 | 타입 | Null | Key | Default / Extra |
|
||||
|---|---|---|---|---|
|
||||
| `id` | `bigint(20)` | NO | PRI | `auto_increment` |
|
||||
| `user_id` | `int(11)` | NO | MUL | FK→users.id |
|
||||
| `action_type` | `varchar(100)` | NO | | 행위 종류 |
|
||||
| `action_at` | `timestamp` | NO | | `current_timestamp()` |
|
||||
| `resource_id` / `status` | `varchar(255)` / `enum` | - | | 리소스 ID / SUCCESS\|FAILURE |
|
||||
| `details` | `longtext` | YES | | JSON 상세 데이터 |
|
||||
|
||||
## audit_logs (감사 로그)
|
||||
| 컬럼 | 타입 | Null | Key | Default / Extra |
|
||||
|---|---|---|---|---|
|
||||
| `id` | `int(11)` | NO | PRI | `auto_increment` |
|
||||
| `user_id` | `int(11)` | YES | MUL | FK→users.id |
|
||||
| `action` / `entity_type` | `varchar(100)` | YES | | CRUD/EXPORT/DOWNLOAD 등 |
|
||||
| `entity_id` | `varchar(36)` | YES | | 대상 UUID 등 |
|
||||
| `timestamp` / `ip_address` | `timestamp` / `varchar(45)` | - | | 발생시각 / IP 주소 |
|
||||
| `details` | `longtext` | YES | | JSON 상세 |
|
||||
|
||||
## system_audit_logs (프로젝트/조직 변경 감사 로그)
|
||||
| 컬럼 | 타입 | Null | Key | Default / Extra |
|
||||
|---|---|---|---|---|
|
||||
| `id` | `int(11)` | NO | PRI | `auto_increment` |
|
||||
| `user_id` | `int(11)` | NO | MUL | FK→users.id (행위자) |
|
||||
| `action` / `resource_type` | `varchar(50)` | - | | PROJECT_CREATE 등 / 종류 |
|
||||
| `resource_id` | `int(11)` | YES | | |
|
||||
| `timestamp` | `timestamp` | YES | MUL | `current_timestamp()` |
|
||||
| `ip_address` / `user_agent` | `varchar(50)` / `text` | YES | | IP 주소 / 브라우저 에이전트 |
|
||||
|
||||
## system_admin_logs (시스템 관리자 행위 로그)
|
||||
| 컬럼 | 타입 | Null | Key | Default / Extra |
|
||||
|---|---|---|---|---|
|
||||
| `id` | `bigint(20)` | NO | PRI | `auto_increment` |
|
||||
| `admin_user_id` | `int(11)` | NO | MUL | FK→users.id (관리자 ID) |
|
||||
| `action_type` / `target_id` | `varchar(100)` / `varchar(255)`| - | | 변경종류(USER_STATUS) / 대상 ID |
|
||||
| `action_at` | `timestamp` | NO | | `current_timestamp()` |
|
||||
| `details` | `longtext` | YES | | JSON 형태의 변경 상세 |
|
||||
|
||||
## system_resources (시스템 자원 계측)
|
||||
| 컬럼 | 타입 | Null | Key | Default / Extra |
|
||||
|---|---|---|---|---|
|
||||
| `id` | `int(11)` | NO | PRI | `auto_increment` |
|
||||
| `timestamp` | `timestamp` | YES | MUL | `current_timestamp()` |
|
||||
| `cpu_usage_percent` / `memory_usage_percent` | `float` | YES | | |
|
||||
| `disk_usage_percent` / `total_storage_mb` | `float` | - | | 디스크사용률 / 전체 스토리지 용량 |
|
||||
| `active_user_count` / `active_project_count` | `int(11)` | NO | | 활성 사용자 / 프로젝트 수 |
|
||||
|
||||
## support_requests (기술 지원 요청)
|
||||
*실 DB 대조 및 A08 백엔드 코드와 100% 정합함 확인 완료 (계획 당시의 user_id/title 컬럼 스펙은 폐기됨).*
|
||||
| 컬럼 | 타입 | Null | Key | Default / Extra |
|
||||
|---|---|---|---|---|
|
||||
| `id` | `int(11)` | NO | PRI | `auto_increment` |
|
||||
| `company_id` | `int(11)` | YES | MUL | FK→companies.id |
|
||||
| `company_name` / `user_name` | `varchar(255)` | - | | 회사명 / 작성자명 |
|
||||
| `user_email` / `user_phone` | `varchar(255)` / `varchar(30)` | - | | 이메일 / 전화번호 |
|
||||
| `subject` / `message` | `varchar(255)` / `text` | NO | | 제목 / 문의 메시지 본문 |
|
||||
| `status` | `enum('NEW','REVIEWED','RESOLVED','DELETED')` | NO | MUL | `NEW` |
|
||||
| `reviewed_by` | `int(11)` | YES | MUL | FK→users.id (검토자) |
|
||||
| `created_at` / `reviewed_at` / `review_notes` | - | - | | 접수 / 검토일시 / 메모 |
|
||||
|
||||
## change_logs (설계 변경 이력)
|
||||
| 컬럼 | 타입 | Null | Key | Default / Extra |
|
||||
|---|---|---|---|---|
|
||||
| `id` | `int(11)` | NO | PRI | `auto_increment` |
|
||||
| `project_id` | `char(36)` | NO | | FK→projects.id |
|
||||
| `changed_by` | `int(11)` | YES | MUL | FK→users.id (수정자) |
|
||||
| `changed_at` | `timestamp` | NO | | `current_timestamp()` |
|
||||
| `entity_type` / `entity_id` | `varchar(100)` / `int(11)` | YES | | 대상엔티티(routes 등) / 대상 PK |
|
||||
| `old_value` / `new_value` | `longtext` | YES | | 변경 전 / 후 JSON 스냅샷 |
|
||||
| `reason` | `varchar(255)` | YES | | 변경 사유 |
|
||||
**사용처:** [[B01_Dashboard/B01_backend|B01_Dashboard]] (리소스·로그 섹션), [[A08_Support/A08_backend|A08_Support]] (support_requests INSERT)
|
||||
## system_audit_logs — 사용처 (B01, B02)
|
||||
- **프로젝트 생성**: `B02_ProjRegister_Repository.py:92` (`PROJECT_CREATE` 기록 ➡️ [[B02_ProjRegister/B02_backend]])
|
||||
- **기타 관리 행위**: `B01_Dashboard_Repository.py:245,265` (수정·삭제), `:336` (회사 생성), `:609` (감사 로그 조회), `:758` (자동화 제어)
|
||||
## 리소스 API (SYSTEM_ADMIN 전용)
|
||||
`GET /api/dashboard/admin/resources?days=30` (실시간 계측 `current`, 30일 다운샘플링 시계열 `history` 및 활성 지표 `stats` 제공)
|
||||
@@ -0,0 +1,64 @@
|
||||
---
|
||||
type: concept
|
||||
status: draft
|
||||
related_pages: ["[[architecture/shared_resources]]"]
|
||||
last_updated: 2026-07-12
|
||||
source: raw/guidelines/db_schema.md, raw/guidelines/agent.md
|
||||
---
|
||||
|
||||
# DB 스키마 개요
|
||||
|
||||
**DB명:** `aislo_db` / MariaDB v10.6+ / utf8mb4_unicode_ci / 드라이버 aiomysql
|
||||
|
||||
> ✅ **모순 해결 (2026-07-12, 실 DB 직접 조회 `SHOW TABLES`로 검증):** 실제 운영 DB는 **34개 테이블**. `db_schema.md`(34개)가 정확했고 `agent.md`의 18개/23개는 갱신 안 된 값 — agent.md 쪽 오기로 판정.
|
||||
>
|
||||
> **raw 문서에 없던 실제 테이블 2개 발견:**
|
||||
> - `project_workflow_stages` — [[workflow_state]] 설계가 **이미 구현되어 실 DB에 존재**함 (컬럼 구성이 계획서와 정확히 일치). status를 draft→stable로 갱신함.
|
||||
> - `system_admin_logs` — 시스템 관리자(SYSTEM_ADMIN)가 회원/조직 상태(`status`) 등을 변경할 때 감사 이력을 INSERT하는 Write-Only 성격의 테이블 ➡️ [[db_schema/logs_monitoring]].
|
||||
>
|
||||
> ⚠️ **미확정/미연동 테이블 격리 규칙**:
|
||||
> - 분석 중이거나 소스코드와의 구체적인 연결고리(백엔드/프론트엔드 실사용처)가 아직 확정되지 않은 테이블이 신규 추가될 경우, 상위 공식 그룹 파일에 포함하지 않고 [[db_schema/unconfirmed/README|미확정 폴더(unconfirmed/)]] 내에 개별 `[테이블명].md` 마크다운 파일로 저장하여 격리 관리합니다.
|
||||
|
||||
## 테이블 그룹 (9개)
|
||||
|
||||
| 그룹 | 테이블 수 | 상세 페이지 |
|
||||
|---|---|---|
|
||||
| 사용자/인증/조직 (핵심) | 7 | [[db_schema/users_auth]] |
|
||||
| 로그/모니터링 | 8 | [[db_schema/logs_monitoring]] |
|
||||
| 프로젝트 관리 | 3 | [[db_schema/projects]] |
|
||||
| 파일/지표면분석 | 6 | [[db_schema/files_surface]] |
|
||||
| 경로/종횡단 | 5 | [[db_schema/route_profile]] |
|
||||
| 구조물/수량/산출물 | 4 | [[db_schema/structure_output]] |
|
||||
| 미확정/연결 대기 테이블 | 0 | [[db_schema/unconfirmed/README]] |
|
||||
|
||||
## 파일 경로 추적 컬럼 (DB에 경로만 기록, 실 파일은 파일시스템)
|
||||
|
||||
| 테이블.컬럼 | 용도 | 사용 단계 |
|
||||
|---|---|---|
|
||||
| `input_files.raw_file_path` | 원본 입력 파일 | B03 |
|
||||
| `processed_point_cloud.converted_file_path` | 변환된 포인트클라우드 | B04 |
|
||||
| `surface_models.model_file_path` | 지표면 모델 | B04 |
|
||||
| `routes.route_data_path` | 경로 데이터(GeoJSON) | B05 |
|
||||
| `longitudinal_sections.longitudinal_file_path` | 종단면 | B06 |
|
||||
| `cross_sections.cross_section_file_path` | 횡단면 | B06 |
|
||||
| `structures.structure_data_path` | 구조물 배치 | B07 |
|
||||
| `quantity_items.quantity_data_path` | 수량 항목 | B08 |
|
||||
| `outputs.outputs_directory_path` | 산출물 폴더 | B09 |
|
||||
| `output_files.output_file_path` | 개별 산출 파일 | B09 |
|
||||
|
||||
상세 경로 규칙 → [[storage_paths]]
|
||||
|
||||
## 설계 원칙
|
||||
- DB에는 "어디에 무엇이 있는가"의 메타정보만 저장. 실제 대용량 파일(LAS/PLY/TIF/DXF/Excel/PDF/JSON)은 파일시스템.
|
||||
- 공간 기하 데이터(GEOMETRY 타입 미지원) → JSON(GeoJSON 형식)으로 저장, 애플리케이션(Shapely/Geopandas)에서 파싱.
|
||||
- 모든 주요 테이블에 soft delete(`deleted_at`) 적용.
|
||||
|
||||
## 테이블 관계 (핵심 흐름)
|
||||
```
|
||||
users ─company_id→ companies
|
||||
projects ─user_id/company_id→ users/companies
|
||||
└→ input_files → processed_point_cloud → surface_models → terrain_layers
|
||||
└→ routes → route_points/route_statistics/longitudinal_sections/cross_sections → structures
|
||||
└→ quantity_items
|
||||
└→ outputs → output_files
|
||||
```
|
||||
@@ -0,0 +1,56 @@
|
||||
---
|
||||
type: concept
|
||||
status: draft
|
||||
related_pages: ["[[B01_Dashboard/B01_backend]]", "[[B02_ProjRegister/B02_backend]]", "[[architecture/shared_resources]]"]
|
||||
last_updated: 2026-07-12
|
||||
source: raw/guidelines/db_schema.md, raw/plans/plan_workflow_state_management.md
|
||||
---
|
||||
|
||||
# DB: 프로젝트 관리 테이블
|
||||
|
||||
← [[db_schema/overview]]
|
||||
|
||||
## projects (프로젝트)
|
||||
| 컬럼 | 타입 | Null | Key | Default / Extra |
|
||||
|---|---|---|---|---|
|
||||
| `id` | `char(36)` | NO | PRI | 프로젝트 UUID |
|
||||
| `user_id` / `company_id` | `int(11)` | NO | MUL | FK→users/companies |
|
||||
| `name` | `varchar(255)` | NO | | 프로젝트명 |
|
||||
| `region` / `road_type` | `varchar(100)` | YES | | 지역 / 임도종류 |
|
||||
| `project_year` | `int(11)` | YES | | 사업년도 |
|
||||
| `estimated_length_m` | `float` | YES | | 계획 연장(m) |
|
||||
| `memo` | `text` | YES | | 메모 |
|
||||
| `status` | `varchar(50)` | YES | | `NEW` (호환용 캐시) |
|
||||
| `crs_epsg` | `int(11)` | YES | | `5178` (좌표계 EPSG) |
|
||||
| `storage_path` | `varchar(500)` | YES | | 상대경로 ➡️ [[storage_paths]] |
|
||||
| `created_at` / `updated_at` / `deleted_at` | `timestamp` | - | | 생성 / 수정 / soft-delete |
|
||||
|
||||
**사용처:** [[B01_Dashboard/B01_backend|B01_Dashboard]] (목록), [[B02_ProjRegister/B02_backend|B02_ProjRegister]] (생성)
|
||||
|
||||
## project_versions (프로젝트 버전 스냅샷)
|
||||
| 컬럼 | 타입 | Null | Key | Default / Extra |
|
||||
|---|---|---|---|---|
|
||||
| `id` | `int(11)` | NO | PRI | `auto_increment` |
|
||||
| `project_id` | `char(36)` | NO | MUL | FK→projects.id |
|
||||
| `version_num` | `int(11)` | NO | | 버전 번호 |
|
||||
| `status` | `varchar(50)` | YES | | 버전 상태 |
|
||||
| `data` | `longtext` | YES | | 설계 스냅샷 JSON 데이터 |
|
||||
| `snapshot_at` / `created_at` | `timestamp` | NO | | 생성일시 |
|
||||
|
||||
## project_automations (프로젝트 자동화 정책)
|
||||
| 컬럼 | 타입 | Null | Key | Default / Extra |
|
||||
|---|---|---|---|---|
|
||||
| `id` | `int(11)` | NO | PRI | `auto_increment` |
|
||||
| `project_id` | `char(36)` | NO | MUL | FK→projects.id |
|
||||
| `name` | `varchar(100)` | NO | | 자동화 명칭 |
|
||||
| `logic_type` | `varchar(50)` | NO | | `trigger_on_stage_complete` 등 |
|
||||
| `config_json` | `longtext` | NO | | 설정 값 JSON |
|
||||
| `status` | `enum('DRAFT','ACTIVE','INACTIVE')` | NO | MUL | `DRAFT` |
|
||||
| `created_by` / `updated_by` | `int(11)` | - | MUL | FK→users.id |
|
||||
| `last_executed_at` | `datetime` | YES | | 최종 실행 일시 |
|
||||
|
||||
**사용처:** [[B01_Dashboard/B01_backend|B01_Dashboard]] (자동화 로직 관리, USER는 조회 차단)
|
||||
|
||||
## project_workflow_stages (단계별 상세 상태)
|
||||
- 본 테이블은 워크플로우 7단계(stage 0~6)의 세부 진행도(state, params, progress_percent 등)를 관리하는 SSOT입니다.
|
||||
- 상세 테이블 정보 및 사용처 ➡️ [[workflow_state]]
|
||||
@@ -0,0 +1,86 @@
|
||||
---
|
||||
type: concept
|
||||
status: stable
|
||||
related_pages: ["[[B05_Profile/B05_backend]]", "[[B06_Section/B06_backend]]", "[[architecture/shared_resources]]"]
|
||||
last_updated: 2026-07-19
|
||||
source: docs/raw/verification/2026-07-19_verify_종횡단_생성_B05_이관.md
|
||||
---
|
||||
|
||||
# DB: 경로/종횡단 테이블
|
||||
|
||||
← [[db_schema/overview]]
|
||||
|
||||
## routes (노선 경로)
|
||||
*사용처: [[B05_Profile/B05_db]]*
|
||||
|
||||
| 컬럼 | 타입 | Null | Key | Default / Extra |
|
||||
|---|---|---|---|---|
|
||||
| `id` | `int(11)` | NO | PRI | `auto_increment` |
|
||||
| `project_id` | `char(36)` | NO | MUL | FK→projects.id |
|
||||
| `surface_model_id` | `int(11)` | YES | MUL | FK→surface_models.id |
|
||||
| `status` | `varchar(50)` | YES | | `DRAFT` ➡️ `CONFIRMED` ➡️ `ARCHIVED` |
|
||||
| `start_chainage_m` / `end_chainage_m` | `float` | YES | | 시작 시점 / 끝 시점 연장(m) |
|
||||
| `total_length_m` | `float` | YES | | 총 연장(m) |
|
||||
| `grade_percent` | `longtext` | YES | | 경사도 정보 JSON |
|
||||
| `constraints` / `algorithm_params` | `longtext` | YES | | 회피 구역 JSON / 알고리즘 가중치 파라미터 JSON |
|
||||
| `route_data_path` | `varchar(500)` | YES | | 노선 데이터 (GeoJSON) 파일 경로 |
|
||||
| `computed_at` / `created_at` | - | - | | 연산 완료 일시 / 생성 일시 |
|
||||
|
||||
## route_points (경로 좌표점)
|
||||
*사용처: [[B05_Profile/B05_db]]*
|
||||
|
||||
| 컬럼 | 타입 | Null | Key | Default / Extra |
|
||||
|---|---|---|---|---|
|
||||
| `id` | `int(11)` | NO | PRI | `auto_increment` |
|
||||
| `route_id` | `int(11)` | NO | MUL | FK→routes.id |
|
||||
| `chainage_m` | `float` | YES | | 시점 거리(m) |
|
||||
| `elevation_m` / `slope_percent` | `float` | YES | | 표고(m) / 종단 경사율(%) |
|
||||
| `sequence_num` | `int(11)` | YES | | 점 순서 |
|
||||
|
||||
## route_statistics (노선 통계)
|
||||
*사용처: [[B05_Profile/B05_db]]*
|
||||
|
||||
| 컬럼 | 타입 | Null | Key | Default / Extra |
|
||||
|---|---|---|---|---|
|
||||
| `id` | `int(11)` | NO | PRI | `auto_increment` |
|
||||
| `route_id` | `int(11)` | NO | MUL | FK→routes.id |
|
||||
| `min_slope` / `max_slope` / `mean_slope` | `float` | YES | | 최저 / 최고 / 평균 경사(%) |
|
||||
| `cut_volume_m3` / `fill_volume_m3` | `float` | YES | | 절토량(㎥) / 성토량(㎥) |
|
||||
| `tree_cutting_volume` / `cost_score` | `float` | YES | | 벌채량 / 평점 비용 스코어 |
|
||||
|
||||
## longitudinal_sections (종단면 설계)
|
||||
*사용처: [[B05_Profile/B05_db]] (생성/저장), [[B06_Section/B06_db]] (조회/확정)*
|
||||
|
||||
| 컬럼 | 타입 | Null | Key | Default / Extra |
|
||||
|---|---|---|---|---|
|
||||
| `id` | `int(11)` | NO | PRI | `auto_increment` |
|
||||
| `project_id` / `route_id` | `char(36)` / `int` | NO | MUL | FK→projects / routes |
|
||||
| `computed_at` | `timestamp` | YES | | 종단 계산 일시 |
|
||||
| `data` | `longtext` | YES | | 지반고/계획고/구배 등 설계 데이터 JSON |
|
||||
| `longitudinal_file_path` | `varchar(500)` | YES | | 종단도면 캐드 파일 경로 |
|
||||
| `status` | `varchar(50)` | YES | | `DRAFT` / `CONFIRMED` |
|
||||
|
||||
### `data` 컬럼 내 `options` 스냅샷 구조 (2026-07-19 도입)
|
||||
종횡단 계산(`solve_route`) 완료 시, `longitudinal_sections.data` 필드의 최상위 키 `"options"` 하위에 당시 적용한 측점/횡단 생성 파라미터가 JSON 구조로 영구 보존됩니다.
|
||||
|
||||
### `data` 컬럼 내 `profile_alignment` 구조 (2026-07-23 도입)
|
||||
사용자가 직접 편집 및 확정한 종단 계획고 선형 기하 데이터(PVI 목록, 곡선 제원, 절성토 균형 지표, 규정 위반 목록 등)가 `"profile_alignment"` 키 하위에 저장됩니다. 상세한 스펙 및 JSON 예시는 [[db_schema/route_profile/longitudinal_alignment]] 문서를 참조하십시오.
|
||||
|
||||
|
||||
## cross_sections (횡단면 설계)
|
||||
*사용처: [[B05_Profile/B05_db]] (생성/저장), [[B06_Section/B06_db]] (조회/확정)*
|
||||
|
||||
| 컬럼 | 타입 | Null | Key | Default / Extra |
|
||||
|---|---|---|---|---|
|
||||
| `id` | `int(11)` | NO | PRI | `auto_increment` |
|
||||
| `project_id` / `route_id` | `char(36)` / `int` | NO | MUL | FK→projects / routes |
|
||||
| `chainage_m` / `sequence_num` | - | YES | | 측정 체인 거리(m) / 단면 순서 |
|
||||
| `data` | `longtext` | YES | | 좌우 사면 경사, 폭, 절성토 단면적 JSON |
|
||||
| `cross_section_file_path` | `varchar(500)` | YES | | 횡단도면 캐드 파일 경로 |
|
||||
| `status` | `varchar(50)` | YES | | `DRAFT` / `CONFIRMED` |
|
||||
|
||||
## routes.status 흐름
|
||||
`DRAFT → CONFIRMED → ARCHIVED`
|
||||
|
||||
## cross_sections.data.structures
|
||||
횡단면 하나에 배치된 구조물 ID 배열 → [[db_schema/structure_output]]#structures 참조
|
||||
@@ -0,0 +1,68 @@
|
||||
---
|
||||
type: concept
|
||||
status: stable
|
||||
related_pages: ["[[B05_Profile/B05_backend]]", "[[B05_Profile/B05_db]]", "[[db_schema/route_profile]]", "[[architecture/shared_resources]]"]
|
||||
last_updated: 2026-07-23
|
||||
source: "docs/raw/verification/2026-07-23_verify_B05_종단_계획선_편집_체계_개편.md"
|
||||
---
|
||||
|
||||
# DB: longitudinal_sections.data.profile_alignment 구조
|
||||
|
||||
종단 계획고 편집 개편에 따라 `longitudinal_sections.data` 내 `"profile_alignment"` 키 하위에 저장되는 선형 기하의 JSON 스펙입니다.
|
||||
|
||||
```jsonc
|
||||
"profile_alignment": {
|
||||
"station_interval_m": 20.0, // 기준 측점 간격(m)
|
||||
"pvi": [ // 변화점(PVI) 목록
|
||||
{
|
||||
"chainage_m": 2400.0, // PVI 위치 누가거리(m)
|
||||
"elevation_m": 409.96, // PVI 높이 표고(m)
|
||||
"curve_l_m": 8.0, // 파생된 종단곡선 길이(m)
|
||||
"curve_r_m": 359.2, // 설정된 종단곡선 반경 R(m)
|
||||
"source": "auto" // 생성 주체: "auto"(자동산출) | "user"(사용자편집)
|
||||
}
|
||||
],
|
||||
"overrides": {
|
||||
"2440.0": 0.3 // 측점별 높이 편집 델타값 (기본값 대비 m) -> 원복(↺) 판단 근거
|
||||
},
|
||||
"segment_shifts": {
|
||||
"3": -0.2 // 직선 세그먼트 인덱스별 상하 평행이동 델타값(m)
|
||||
},
|
||||
"segments": [ // 직선 구간(기울기) 기하 분석 결과
|
||||
{
|
||||
"from_m": 2400.0,
|
||||
"to_m": 2460.0,
|
||||
"length_m": 60.0, // 구간 길이(m)
|
||||
"height_m": -2.86, // 높이 변화량(m)
|
||||
"grade_percent": -4.77 // 기울기 구배(%)
|
||||
}
|
||||
],
|
||||
"curves": [ // 종단곡선(R) 기하 분석 결과
|
||||
{
|
||||
"pvi_index": 1,
|
||||
"bvc_m": 2476.0, // 곡선 시작점(BVC) 누가거리(m)
|
||||
"evc_m": 2484.0, // 곡선 끝점(EVC) 누가거리(m)
|
||||
"l_m": 8.0, // 곡선 길이(m)
|
||||
"k": 3.59, // 곡선반경 성능 지표 K
|
||||
"r_m": 359.2, // 반경 R(m)
|
||||
"middle_ordinate_m": 0.56, // 중앙종거(m)
|
||||
"omitted": false, // 비포장/대수차 5% 이하 예외에 따른 곡선 생략 여부
|
||||
"omit_reason": null
|
||||
}
|
||||
],
|
||||
"balance": { // 절성토 균형 지표
|
||||
"cut_m3": 240.5, // 종단면 기준 간이 절토 단면적적분량
|
||||
"fill_m3": 235.1, // 종단면 기준 간이 성토 단면적적분량
|
||||
"imbalance_percent": 2.2, // 균형 오차 백분율
|
||||
"within_tolerance": true // 허용 기준(10.0%) 충족 여부
|
||||
},
|
||||
"violations": [ // 규정 위반 검증 목록
|
||||
{
|
||||
"segment_index": 2,
|
||||
"type": "grade_over", // 위반 유형 (grade_over: 구배 초과)
|
||||
"value": 15.2, // 실제 수치
|
||||
"limit": 14.0 // 규정 한계값
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
@@ -0,0 +1,70 @@
|
||||
---
|
||||
type: concept
|
||||
status: draft
|
||||
related_pages: ["[[B07_Quantity/B07_frontend]]", "[[B08_DesignDetail/B08_frontend]]", "[[B09_Estimation/B09_frontend]]", "[[architecture/shared_resources]]"]
|
||||
last_updated: 2026-07-12
|
||||
source: raw/guidelines/db_schema.md
|
||||
---
|
||||
|
||||
# DB: 구조물/수량/산출물 테이블
|
||||
|
||||
← [[db_schema/overview]]
|
||||
|
||||
## structures (배치 구조물)
|
||||
| 컬럼 | 타입 | Null | Key | Default / Extra |
|
||||
|---|---|---|---|---|
|
||||
| `id` | `int(11)` | NO | PRI | `auto_increment` |
|
||||
| `project_id` / `cross_section_id` | - | - | MUL | FK→projects / cross_sections |
|
||||
| `structure_type` | `varchar(100)` | YES | | 낙석방지책 / 계간수로 / 돌붙임 등 |
|
||||
| `chainage_m` | `float` | YES | | 구조물 배치 체인 시점 거리(m) |
|
||||
| `location` | `varchar(50)` | YES | | 좌 / 우 / 종단 등 배치 위치 |
|
||||
| `length_m` / `width_m` / `height_m` | `float` | YES | | 길이 / 폭 / 높이 규격(m) |
|
||||
| `material` | `varchar(100)` | YES | | 구조물 재질/자재 |
|
||||
| `quantity` / `unit_price` | - | YES | | 수량 / 단가 |
|
||||
| `design_notes` | `longtext` | YES | | 특기사항 등 메모 |
|
||||
| `structure_data_path` | `varchar(500)` | YES | | 세부 구조 상세 데이터 파일 경로 |
|
||||
| `last_modified_by` | `int(11)` | YES | MUL | FK→users.id (최종 수정자) |
|
||||
| `created_at` / `updated_at` | `timestamp` | - | | 생성 / 수정 일시 |
|
||||
|
||||
## quantity_items (수량 산출 항목)
|
||||
| 컬럼 | 타입 | Null | Key | Default / Extra |
|
||||
|---|---|---|---|---|
|
||||
| `id` | `int(11)` | NO | PRI | `auto_increment` |
|
||||
| `project_id` | `char(36)` | NO | MUL | FK→projects.id |
|
||||
| `category` | `varchar(100)` | YES | | 토공 / 구조물 / 포장 / 배수 등 공종 |
|
||||
| `item_name` / `unit` | `varchar` | YES | | 품목 항목명 / 단위 (㎡, m 등) |
|
||||
| `quantity_design` / `quantity_actual` | `float` | YES | | 설계 수량 / 최종 반영 수량 |
|
||||
| `unit_price` / `total_price` | `float` | YES | | 단가 / 총 금액 |
|
||||
| `standard_reference` | `varchar(255)` | YES | | 품셈 근거 코드/출처 |
|
||||
| `computed_at` / `quantity_data_path` | - | YES | | 계산 일시 / 상세 산출근거 데이터 파일 경로 |
|
||||
| `data` | `longtext` | YES | | 계산 세부 과정 통계 JSON |
|
||||
|
||||
## outputs (최종 견적/도면 산출 세션)
|
||||
| 컬럼 | 타입 | Null | Key | Default / Extra |
|
||||
|---|---|---|---|---|
|
||||
| `id` | `int(11)` | NO | PRI | `auto_increment` |
|
||||
| `project_id` | `char(36)` | NO | MUL | FK→projects.id |
|
||||
| `output_type` | `varchar(100)` | YES | | `estimation_excel`/`drawing_dxf`/`report_pdf`/`all_bundle` |
|
||||
| `status` | `varchar(50)` | YES | | `GENERATING` ➡️ `COMPLETE` / `FAILED` |
|
||||
| `generated_by` / `generated_at` | - | - | MUL | 생성자 FK / 생성일시 |
|
||||
| `version` | `int(11)` | YES | | 산출 버전 |
|
||||
| `outputs_directory_path` | `varchar(500)` | YES | | 산출 파일 번들 디렉토리 경로 |
|
||||
| `metadata` | `longtext` | YES | | 기타 도면 스케일 등 정보 JSON |
|
||||
|
||||
## output_files (개별 산출 파일 리스트)
|
||||
| 컬럼 | 타입 | Null | Key | Default / Extra |
|
||||
|---|---|---|---|---|
|
||||
| `id` | `int(11)` | NO | PRI | `auto_increment` |
|
||||
| `output_id` | `int(11)` | NO | MUL | FK→outputs.id |
|
||||
| `file_type` | `varchar(50)` | YES | | `xlsx`/`pdf`/`dxf`/`dwg`/`json`/`zip` 등 |
|
||||
| `original_filename` | `varchar(255)` | YES | | 원본 파일 식별 이름 |
|
||||
| `output_file_path` | `varchar(500)` | YES | | 개별 파일 저장 경로 |
|
||||
| `file_size_mb` / `download_count` | - | YES | | 파일 용량 / 다운로드 누적 카운트 |
|
||||
| `created_at` | `timestamp` | NO | | 생성일시 |
|
||||
|
||||
## quantity_items 총비용 계산 예
|
||||
```sql
|
||||
SELECT SUM(quantity_actual * unit_price) AS total_cost, category
|
||||
FROM quantity_items WHERE project_id = :project_id AND deleted_at IS NULL
|
||||
GROUP BY category;
|
||||
```
|
||||
@@ -0,0 +1,13 @@
|
||||
---
|
||||
status: draft
|
||||
related_pages: ["[[architecture/shared_resources]]"]
|
||||
last_updated: 2026-07-17
|
||||
---
|
||||
|
||||
# 미확정 테이블 보관소 (Unconfirmed DB Schemas)
|
||||
|
||||
본 디렉토리는 소스코드 연동 처리가 완료되지 않았거나, 비즈니스 로직(백엔드/프론트엔드) 상의 구체적인 연결고리가 식별되지 않은 미확정 테이블의 명세서 및 임시 분석 내용을 개별 마크다운 파일로 저장·격리하는 공간입니다.
|
||||
|
||||
## 운영 규칙
|
||||
1. **임시 격리**: 신규 테이블 추가 또는 레거시 테이블 중 사용처를 즉시 규명하기 어려운 경우 `[테이블명].md`로 파일을 생성해 기록합니다.
|
||||
2. **확정 이관**: 소스코드에서의 실제 사용처(라우터, 리포지토리 등)가 명확해지면, 상위의 공식 테이블 그룹(예: `users_auth.md`, `logs_monitoring.md` 등)으로 표 명세를 이관하고 본 폴더 내의 마크다운은 삭제합니다.
|
||||
@@ -0,0 +1,92 @@
|
||||
---
|
||||
type: concept
|
||||
status: stable
|
||||
related_pages: ["[[B01_Dashboard/B01_backend]]", "[[auth_rbac]]", "[[architecture/shared_resources]]"]
|
||||
last_updated: 2026-07-17
|
||||
source: docs/raw/verification/2026-07-17_verify_auth_reverify.md
|
||||
---
|
||||
|
||||
# DB: 사용자/인증/조직 테이블
|
||||
|
||||
Links: ← [[db_schema/overview]]
|
||||
|
||||
## users (사용자)
|
||||
| 컬럼 | 타입 | Null | Key | Default / Extra |
|
||||
|---|---|---|---|---|
|
||||
| `id` | `int(11)` | NO | PRI | `auto_increment` |
|
||||
| `email` | `varchar(255)` | NO | UNI | |
|
||||
| `password_hash` | `varchar(255)` | NO | | |
|
||||
| `name` | `varchar(255)` | NO | | |
|
||||
| `position` / `department` | `varchar(100)` | YES | | 직위 / 부서 |
|
||||
| `phone` | `varchar(20)` | YES | | |
|
||||
| `company_id` | `int(11)` | YES | MUL | FK→companies.id |
|
||||
| `role` | `enum('SYSTEM_ADMIN','ADMIN','USER')` | NO | MUL | `USER` |
|
||||
| `is_master` | `tinyint(1)` | NO | | `0` (마스터 여부) |
|
||||
| `status` | `enum('PENDING_EMAIL','NO_COMPANY','PENDING','ACTIVE','INACTIVE','REJECTED')` | NO | MUL | `PENDING_EMAIL` |
|
||||
| `last_login` | `datetime` | YES | | 최종 로그인 일시 |
|
||||
| `login_failures` | `int(11)` | NO | | `0` (실패 횟수) |
|
||||
| `created_at` / `updated_at` / `deleted_at` | `timestamp` | - | | 생성 / 수정 / soft-delete |
|
||||
|
||||
* **사용처:** [[B01_Dashboard/B01_backend|B01_Dashboard]] (사용자 관리), 전 페이지 공통 인증 (`auth_expires_at` 컬럼 삭제 완료)
|
||||
|
||||
## companies (회사)
|
||||
| 컬럼 | 타입 | Null | Key | Default / Extra |
|
||||
|---|---|---|---|---|
|
||||
| `id` | `int(11)` | NO | PRI | `auto_increment` |
|
||||
| `name` | `varchar(255)` | NO | UNI | 회사명 |
|
||||
| `business_registration_number` | `varchar(20)` | YES | UNI | 사업자번호 |
|
||||
| `status` | `enum('ACTIVE','INACTIVE','SUSPENDED')` | NO | | `ACTIVE` |
|
||||
| `subscription_status` | `enum('FREE','TRIAL','PAID','EXPIRED')` | NO | | `FREE` |
|
||||
| `created_by` | `int(11)` | YES | MUL | FK→users.id (생성자) |
|
||||
| `company_code` | `varchar(20)` | YES | | 참여용 코드 |
|
||||
|
||||
**사용처:** [[B01_Dashboard/B01_backend|B01_Dashboard]]
|
||||
|
||||
## sessions (세션)
|
||||
| 컬럼 | 타입 | Null | Key | Default / Extra |
|
||||
|---|---|---|---|---|
|
||||
| `id` | `varchar(255)` | NO | PRI | 세션 ID (쿠키 값) |
|
||||
| `user_id` | `int(11)` | NO | MUL | FK→users.id |
|
||||
| `user_agent_hash` | `char(64)` | NO | | |
|
||||
| `expires_at` | `timestamp` | NO | MUL | 만료일시 |
|
||||
| `last_activity_at` | `timestamp` | NO | | 최종 활동일시 |
|
||||
|
||||
**사용처:** 전 페이지 공통 (세션 인증) — 상세 → [[auth_rbac]]
|
||||
|
||||
## email_otps (이메일 OTP)
|
||||
| 컬럼 | 타입 | Null | Key | Default / Extra |
|
||||
|---|---|---|---|---|
|
||||
| `id` | `bigint(20)` | NO | PRI | `auto_increment` |
|
||||
| `user_id` | `int(11)` | NO | MUL | FK→users.id |
|
||||
| `purpose` | `enum('REGISTER','LOGIN','REVERIFY','PASSWORD_CHANGE')` | NO | | 용도 |
|
||||
| `otp_hash` | `varchar(255)` | NO | | OTP 해시값 |
|
||||
| `expires_at` / `consumed_at` | `timestamp` | - | | 만료일시 / 사용일시 |
|
||||
|
||||
## trusted_devices (신뢰 기기)
|
||||
| 컬럼 | 타입 | Null | Key | Default / Extra |
|
||||
|---|---|---|---|---|
|
||||
| `id` | `bigint(20)` | NO | PRI | `auto_increment` |
|
||||
| `user_id` | `int(11)` | NO | MUL | FK→users.id |
|
||||
| `token_hash` | `varchar(255)` | NO | UNI | 디바이스 토큰 해시 (2026-07-17 추가) |
|
||||
| `verified_at` / `last_used_at` | `timestamp` | NO | | 검증 / 최종 사용 일시 |
|
||||
|
||||
## join_requests (회사 가입 신청)
|
||||
| 컬럼 | 타입 | Null | Key | Default / Extra |
|
||||
|---|---|---|---|---|
|
||||
| `id` | `int(11)` | NO | PRI | `auto_increment` |
|
||||
| `user_id` / `company_id` | `int(11)` | NO | MUL | FK→users/companies |
|
||||
| `status` | `enum('PENDING','APPROVED','REJECTED')` | NO | | `PENDING` |
|
||||
| `requested_at` / `reviewed_at` | `timestamp` | - | | 신청 / 검토 일시 |
|
||||
| `reviewed_by` | `int(11)` | YES | MUL | FK→users.id (검토자) |
|
||||
|
||||
**사용처:** [[B01_Dashboard/B01_backend|B01_Dashboard]] (`B01_Dashboard_Repository.py:378` 가입 신청·처리)
|
||||
|
||||
## user_consents (약관 동의)
|
||||
| 컬럼 | 타입 | Null | Key | Default / Extra |
|
||||
|---|---|---|---|---|
|
||||
| `id` | `bigint(20)` | NO | PRI | `auto_increment` |
|
||||
| `user_id` | `int(11)` | NO | MUL | FK→users.id |
|
||||
| `terms_version` | `varchar(20)` | NO | | 동의한 약관 버전 |
|
||||
| `terms_agreed` / `privacy_agreed` | `tinyint(1)` | NO | | 필수 동의여부 (1=동의) |
|
||||
| `marketing_agreed` | `tinyint(1)` | NO | | `0` (선택 마케팅동의) |
|
||||
| `agreed_at` | `timestamp` | NO | | 동의 일시 |
|
||||
@@ -0,0 +1,41 @@
|
||||
---
|
||||
type: concept
|
||||
status: stable
|
||||
related_pages: ["[[B01_Dashboard/B01_backend]]", "[[B03_FileInput/B03_backend]]", "[[B04_PreProcess/B04_backend]]", "[[B05_Profile/B05_backend]]", "[[B06_Section/B06_backend]]", "[[B07_Quantity/B07_backend]]", "[[B08_DesignDetail/B08_backend]]", "[[architecture/shared_resources]]"]
|
||||
last_updated: 2026-07-20
|
||||
source: ["docs/raw/verification/2026-07-19_verify_b07_independent_cad.md", "docs/raw/verification/2026-07-20_verify_b08_quantity_template.md", "docs/raw/plans/2026-07-18_plan_dependency_upgrade.md"]
|
||||
---
|
||||
|
||||
# 외부 라이브러리 의존성
|
||||
|
||||
[[architecture/shared_resources]]는 이 문서를 전체 의존성 정본으로 참조한다. Backend 의존성은 B01·B03~B08에, Frontend 의존성은 [[a00_app_shell_framework]]과 [[ui_templates]]에 연결된다.
|
||||
|
||||
## 백엔드 (Python 3.12.7)
|
||||
| 라이브러리 | 용도 | 사용 페이지 |
|
||||
|---|---|---|
|
||||
| FastAPI / Pydantic | API 프레임워크 / 요청·응답 검증 | 전체; [[B01_Dashboard/B01_backend|B01_Dashboard]] 라우터·요청 모델 |
|
||||
| Trimesh | 3D 메시 처리 | [[B04_PreProcess/B04_backend|B04_PreProcess]] (trimesh==4.12.2 모델 생성) |
|
||||
| Whitebox | 지형 분석(D8 흐름누적 등) | [[B04_PreProcess/B04_backend|B04_PreProcess]], [[B05_Profile/B05_backend|B05_Profile]] (whitebox==2.3.6 skeleton 복구) |
|
||||
| Geopandas | 공간 데이터프레임 | [[B04_PreProcess/B04_backend|B04_PreProcess]], [[B05_Profile/B05_backend|B05_Profile]] (geopandas==1.1.4) |
|
||||
| Pyogrio | GeoPandas 파일 I/O 가속 | [[B05_Profile/B05_backend|B05_Profile]] (pyogrio==0.13.0 신규 도입) |
|
||||
| Shapely | 기하 연산 (JSON 파싱 후) | [[B05_Profile/B05_backend|B05_Profile]], [[B06_Section/B06_backend|B06_Section]] (shapely==2.1.2) |
|
||||
| NumPy | 격자·통계·비용면 및 LAS 통계 계산 | [[B03_FileInput/B03_backend|B03_FileInput]], [[B05_Profile/B05_backend|B05_Profile]] (numpy==2.5.0) |
|
||||
| SciPy | 수치 보간·계산 보조, Delaunay 삼각망 생성 | [[B04_PreProcess/B04_backend|B04_PreProcess]] (scipy==1.18.0 삼각망 생성), [[B05_Profile/B05_backend|B05_Profile]] |
|
||||
| Rasterio | 래스터(DEM/TIF) 입출력·메타데이터 | [[B03_FileInput/B03_backend|B03_FileInput]], [[B04_PreProcess/B04_backend|B04_PreProcess]] (rasterio==1.5.0) |
|
||||
| Laspy | LAS/LAZ 포인트클라우드 파싱 | [[B03_FileInput/B03_backend|B03_FileInput]], [[B04_PreProcess/B04_backend|B04_PreProcess]] (laspy==2.7.0) |
|
||||
| Pyproj | PRJ/TIF 좌표계 해석 | [[B03_FileInput/B03_backend|B03_FileInput]] |
|
||||
| Openpyxl | 과거 엑셀 원가 수량 템플릿 계획에 사용 | 현행 B07 구현에서는 사용 미확인 |
|
||||
| aiomysql | 비동기 MariaDB 드라이버 (Raw SQL) | 전체 |
|
||||
| psutil | CPU·메모리 사용률 계측 | [[B01_Dashboard/B01_backend|B01_Dashboard]] 리소스 현황 |
|
||||
|
||||
## 프론트엔드 (TypeScript/Node.js)
|
||||
| 항목 | 용도 | 사용처 |
|
||||
|---|---|---|
|
||||
| **three.js** (WebGL) | 3D 뷰어(WebGLRenderer, OrbitControls, Points/Mesh) | [[B04_PreProcess/B04_backend|B04_PreProcess]], [[B05_Profile/B05_backend|B05_Profile]] 구현 확인. B06은 미구현 (SVG 사용) |
|
||||
| **openwebcad** (Canvas) | 내장 독립 2D CAD 에디터 및 뷰어 | [[B08_DesignDetail/B08_frontend|B08_DesignDetail]] (MIT 라이선스, iframe 임베딩) |
|
||||
| Vite | 빌드 도구 | 전 프론트 |
|
||||
|
||||
> ⚠️ B04, B05는 three.js 기반 3D 지형/노선 뷰어가 구현되어 있으며, B06은 종횡단 조회 전용(SVG 렌더링)으로 Three.js를 사용하지 않습니다. B07은 내장된 독립 2D CAD(`openwebcad`)를 iframe으로 임베딩하여 활용합니다.
|
||||
|
||||
## 선정 원칙 (agent.md 3절)
|
||||
프로젝트에 맞춰 호환 라이브러리 선정, 불필요한 함수 작성 최소화. `asyncmy` 대신 `aiomysql` 채택 이유: Cython 빌드가 Windows 환경에서 불필요.
|
||||
@@ -0,0 +1,58 @@
|
||||
---
|
||||
type: concept
|
||||
status: stable
|
||||
related_pages: ["[[ui_templates]]", "[[architecture/shared_resources]]"]
|
||||
last_updated: 2026-07-19
|
||||
source: docs/raw/verification/2026-07-19_verify_scrollbar_theme.md
|
||||
---
|
||||
|
||||
# 디자인 시스템 (Design System)
|
||||
|
||||
임도설계 및 견적자동화 웹앱(Aislo)의 공통 비주얼 테마, 타이포그래피, 간격 규칙 및 CSS 변수 명세 요약입니다.
|
||||
|
||||
## 비주얼 테마
|
||||
* **Theme & Tone**: confident enterprise tool + approachable consumer product.
|
||||
* **비주얼 키워드**: Confident (Assured), Clean (Geometric), Sunlit Atmosphere (Gradient wash).
|
||||
* **대표 그라디언트**: 연한 라벤더 분위기를 연출하기 위해 흰색-보라색-피치 그라디언트를 접목하여 맑은 느낌 제공.
|
||||
|
||||
## 핵심 색상 토큰 (Colors)
|
||||
|
||||
| CSS 변수명 | hex 값 | 역할 / 비주얼 우선도 |
|
||||
|---|---|---|
|
||||
| `--color-deep-iris` | `#26114a` | 딥 바이올렛 데코레이션 디테일 (CTA 단추로 사용 금지) |
|
||||
| `--color-plum-velvet` | `#312749` | 대시보드 네비게이션 텍스트, 카드 타이틀, 보조 제목 |
|
||||
| `--color-royal-amethyst` | `#3e0079` | 링크, 입력 필드 포커스 링, 하이라이트 아이콘 (가장 채도 높음) |
|
||||
| `--color-mist-violet` | `#edecff` | 연한 라벤더 분위기를 내는 소프트 하이라이트/배경색 |
|
||||
| `--color-canvas` | `#ffffff` | 기본 페이지 배경, 카드 배경, 활성 입력 필드 |
|
||||
| `--color-paper` | `#f6f7fa` | 미세한 대비를 주는 테이블 줄무늬 교대 배경, 보조 카드 배경 |
|
||||
| `--color-mist` | `#e6e2e3` | 외곽 얇은 헤어라인 테두리, 구분선 |
|
||||
|
||||
## 타이포그래피 (Typography)
|
||||
|
||||
* **Britti Sans (display/heading)**: 24–64px 크기에 적용하며 geometric(기하학적) 인상을 강조하기 위해 line-height는 항상 `1.0` 고정. (대체 폰트: Plus Jakarta Sans / General Sans)
|
||||
* **Inter (UI/body)**: UI 라벨 및 본문 기본 폰트. 자간 및 행간을 compact하게 배치하여 고밀도(data-dense) 정보 인터페이스를 제공. (대체 폰트: Inter / IBM Plex Sans)
|
||||
|
||||
| 서체 역할 | 크기 | 행간(Line-Height) | CSS 변수명 |
|
||||
|---|---|---|---|
|
||||
| caption | 12px | 1.3 | `--text-caption` |
|
||||
| body-sm | 14px | 1.4 | `--text-body-sm` |
|
||||
| body | 16px | 1.5 | `--text-body` |
|
||||
| subheading | 24px | 1.0 | `--text-subheading` |
|
||||
| heading-sm | 32px | 1.0 | `--text-heading-sm` |
|
||||
| heading | 40px | 1.0 | `--text-heading` |
|
||||
|
||||
## 레이아웃 및 둥근 테두리 (Radius & Spacing)
|
||||
* **기본 단위**: `8px` 배수 간격 시스템 (`--spacing-8`, `--spacing-16` 등)
|
||||
* **둥근 곡률 (Border-radius)**:
|
||||
* 카드, 입력 상자, 버튼: `8px`
|
||||
* 태그/필 상태(Pills): `1440px` (원형 캡슐 스타일)
|
||||
|
||||
|
||||
## 전역 스크롤바 디자인 (Scrollbars)
|
||||
* **브라우저 충돌 가드**: Chromium/WebKit 환경에서 표준과 충돌하지 않도록 `@supports selector(::-webkit-scrollbar)` 블록 내의 `*` 선택자에 `scrollbar-width: auto;`를 적용하여 스타일 오버라이드를 제어함. (B07 WebCAD iframe 내부 제외)
|
||||
* **미니멀 디자인**:
|
||||
* 스크롤바 폭/높이: 얇은 `8px` 두께 고정 (`width: 8px; height: 8px;`)
|
||||
* 트랙 배경: 완전 투명(`transparent`)으로 UI 배경 이질감 최소화
|
||||
* 화살표 버튼: 기본 이동 버튼 제거 (`display: none; width: 0; height: 0;`)
|
||||
* 스크롤 썸(Thumb) 불투명도: 기본 12% -> hover 시 20% -> active 시 28%로 은은하게 반응 튜닝
|
||||
|
||||
@@ -0,0 +1,79 @@
|
||||
---
|
||||
status: stable
|
||||
related_pages: ["[[B04_PreProcess/B04_backend]]", "[[B04_PreProcess/B04_frontend]]", "[[B05_Profile/B05_backend]]", "[[B05_Profile/B05_frontend]]", "[[B08_DesignDetail/B08_drawing_masshaul_watershed]]", "[[architecture/shared_resources]]"]
|
||||
last_updated: 2026-08-30
|
||||
---
|
||||
|
||||
# 배수유역 해석 및 세부설계 (Drainage Watershed)
|
||||
|
||||
배수유역 구조는 B04 지표면 분석 단계에서 무거운 1차 격자 해석(30초)을 거치고, 이후 관 매설 편집 및 세부유역 분할 설계는 B04/B05 두 워크플로우 화면에서 **단일 데이터 소스(SSOT) 및 공용 API**를 통해 실시간으로 처리되도록 통합 관리됩니다.
|
||||
|
||||
사용처: [[B04_PreProcess/B04_frontend|B04_PreProcess]], [[B05_Profile/B05_frontend|B05_Profile]], [[B08_DesignDetail/B08_drawing_masshaul_watershed|B08 유역도]]
|
||||
|
||||
## 1. B04 vs B05 역할 분담 및 일원화
|
||||
|
||||
| 구분 | B04 지표면 분석 & 세부유역 설계 | B05 배수유역도 패널 & 종단 연동 |
|
||||
|---|---|---|
|
||||
| 역할 | ①~⑧ 전 해석 수행 및 관 매설 편집/세부유역 계산(분할)을 담당 | B04와 **동일한 단일 데이터**를 로드하여 지도 2D 오버레이 시각화 및 종단 그래프 드래그/우클릭과 배관 위치 양방향 동기화 |
|
||||
| 저장소 | `B04_PreProcess/drainage/` 내 **`pipe_points.json` 단일 정본**을 두 화면이 공용으로 바라봄 (B05 사본 폴더는 완전히 폐지됨) |
|
||||
| API | 두 화면 모두 **B04 공용 API**를 호출 (`GET/POST/PUT/DELETE /drainage/pipe-points` 및 `POST /drainage/detail-basins`) |
|
||||
| 노선 원본 | B03 업로드 원청 계획노선 CSV (`common_util_route_geometry.py`) | B03 업로드 원청 계획노선 CSV |
|
||||
|
||||
## 2. 공용 배수 엔진 및 WAMIS 강우량 연동 (Phase 1~2, 2026-08-13 관측소 전환)
|
||||
- **WAMIS 전국 621개 관측소 확률강우량 연동 (본토)**: `common_util/common_util_wamis_station.py`를 통해 공사지 기준 반경 10km (`WAMIS_STATION_RADIUS_M = 10000`) 내 WAMIS 관측소 xlsx를 다운로드·파싱하여 100년/24hr 강우량이 가장 높은 지점을 안전측으로 탐색·선정합니다.
|
||||
- **제주도 등우선도 존치 및 지역 분기**: 제주 지역 공사지는 기존 `common_util_wamis_rainfall.py` 등우선 내삽(96조합)을 유지하며, `value_at()`에 10km 커버리지 검사를 추가하여 본토 공사지에서 제주 등우선으로 무단 폴백되는 결함을 엄격히 차단했습니다.
|
||||
- **강우강도(IDF) 이원화 (Mononobe 기본)**: Mononobe형 IDF($a=(R_{24}/24)\cdot 1440^{0.557}$, $n=0.557$, $b=0$)를 기본 적용하고 General형 선택적 지원을 유지하여 하류 수리계산 계약을 완전 보존합니다.
|
||||
- **수리계산 체인**: 100년 빈도·5분 하한·IDF·합리식·설계유량 2배·Manning으로 유효직경을 산출한다. Kirpich·유출계수·조도계수·유효 통수비율·관 경사값의 기술정보DB 근거 승격과 재확정은 미결이다.
|
||||
- **추천과 자동 주입**: 유효직경 1,500mm 이하=규격 스냅 배관, 초과~2,000mm=BOX암거 후보, 2,000mm 초과=세월교·물넘이 검토다. 자동 배치에는 추천 관경·시설만 주입하며 사용자 수정값은 덮어쓰지 않는다. 사용처: [[B04_PreProcess/B04_backend]], [[B05_Profile/B05_structures]].
|
||||
- **공용 엔진 승격**: `common_util/common_util_drainage_detail.py`가 유역 분할 및 수리계산 코어 알고리즘을 전담.
|
||||
|
||||
## 3. 구조물 3단 옵션 체계 & UI (Phase 3~5)
|
||||
- **3단 계층 드롭다운**: 구조물 대분류(배관/기성막이/대피로/기타), 세부 유형(콘크리트관/PE관 등), 관경/규격(D800, D1000 등) 선택 드롭다운 연동.
|
||||
- **D800 법정 예외 하한**: 임도 구조물 기본 규격 하한 D800 적용 및 수리 계산 $D_{\text{eff}}$ 초과 시 규격 자동 상향 (수동 지정 `userSized` 보존).
|
||||
- **컨텍스트 메뉴 & 캔버스/3D 핀 마킹**: 종단 그래프/배수유역도 우클릭 구조물 추가, 3D 수직 핀 마커(depthTest off) 동기화.
|
||||
- **하단 패널 레이아웃**: 테이블 서브패널 오버레이, 행제목 우측 정렬, Y축 텍스트 13px, 드래그 포인터 추적으로 UX 안정화.
|
||||
|
||||
## 4. 해석 알고리즘 — 등고선 하강 (Contour Descent)
|
||||
|
||||
TIN 보간 표고면의 웅덩이(Sink) 문제를 원천 차단하기 위해 표고면을 생성하지 않고 등고선 자체를 격자에 구워 방향을 계산합니다.
|
||||
|
||||
1. 등고선을 격자에 굽고 각 셀에 가장 가까운 등고 라인의 표고(밴드)를 부여
|
||||
2. 각 밴드에서 한 단 낮은 등고 라인까지의 거리를 EDT(Euclidean Distance Transform)로 측정
|
||||
3. `potential = 밴드순위 × span + 거리` (`span = 최대거리 + 2.0`)
|
||||
- 흐름은 항상 potential이 낮은 방향으로 진행 (순환 및 웅덩이 원리적 부재)
|
||||
4. 최하단 밴드는 Sink 셀(32)로 관리하며 방위는 32방위(0~31)로 저장 (1셀 1바이트)
|
||||
5. 8이웃 중 화살표 방향에 가장 가까운 셀을 수신자로 지정하여 화살표/경로 불일치 0셀 달성
|
||||
|
||||
## 5. 적색/청색 판정 및 유역 확장
|
||||
|
||||
1. **세류선 지류 우선 확정**: 세류선과 겹치는 셀을 걷기 전 적색으로 선 확정
|
||||
2. **수신자 사슬 추적**: 최외곽 셀에서 수신자 사슬을 추적
|
||||
- 도로 셀 또는 세류 셀에 도착 시 사슬 전체 **적색** (배수 영향 유역)
|
||||
- Sink 또는 영역 이탈 시 사슬 전체 **청색** (자연 유출 유역)
|
||||
3. **세류망 노딩**: 세류망을 도로에서 절단하여 상류측만 남기고 `unary_union`으로 노딩
|
||||
4. **확장 루프**: 최외곽 적색 셀 주변으로 50m(`DRAINAGE_RED_EXPAND_BAND_M`)씩 확장을 반복하다가 새로 붙은 셀에 적색이 없으면 멈춤 (2차 전체 배수유역 경계 닫힘)
|
||||
|
||||
## 6. 평균 흐름 화살표 (Flow Arrows) 및 흐름강도 램프
|
||||
- **화살표**: 1m 격자 화살표 대신 10m 블록의 원형 평균 방위를 구하고 40m 간격으로 솎아서 백엔드가 산출합니다.
|
||||
- **흐름강도 램프 (FlowRamp)**: 1m 구간별 유입 면적 강도 프로필 데이터를 B04/B05에 동일하게 표시하며, 이를 지도 우측 세로 눈금 범례(`createFlowLegend` in `_UI_FlowRamp.ts`)로 동적 시각화합니다.
|
||||
|
||||
## 7. 영구저장소 산출물 구조
|
||||
|
||||
`storage/{회사}/{사용자}/{프로젝트}/B04_PreProcess/drainage/`
|
||||
- `00_watershed_response.json`: 백엔드 응답 전체 캐시
|
||||
- `01_primary_region.geojson` / `.npz`: 1차 영역, 상/하류망, 격자 bbox
|
||||
- `02_flow_direction.npz`: 방위, 도달여부, 수신자, 밴드 표고
|
||||
- `03_road_routing.geojson` / `.npz`: 2차 유역 외곽선, 기본 관, 평균 흐름 화살표, 슬롯 정보
|
||||
- `pipe_points.json` (정본): 사용자가 매설한 관의 지점 좌표 및 상세 속성 (구조물 유형, 관경 등)
|
||||
- `04_detailed_basins.geojson`: 관 매설에 맞춰 분할 계산된 세부 배수유역 경계 정보
|
||||
- `rainfall_table.json`: WAMIS 확률강우량 내삽 산출 테이블
|
||||
- `manifest.json`: 단계별 실행 메타데이터
|
||||
|
||||
> [!NOTE]
|
||||
> 유역 외곽선 편집기 및 오버라이드 코드(`boundary_overrides.json`)는 2026-08-01부로 전량 영구 제거되었습니다. B05 디렉토리 하위의 중복 복사본 폴더(`B05_Profile/drainage/`) 또한 완전히 폐지되었습니다.
|
||||
|
||||
## 8. B08 수리집수면적유역도
|
||||
|
||||
- B04 세부유역 GeoJSON과 등고선·하천중심선, 확정 종단 노선을 A1 1:6,000 도면으로 조립한다.
|
||||
- 정보표에는 번호·측점·배수규격·유역면적·유역표고·유하거리만 표시하며 C·I·Q는 제외한다.
|
||||
- 여러 도엽의 배경선은 합친 뒤 A1 작도영역으로 선분 절취한다. 상세는 [[B08_DesignDetail/B08_drawing_masshaul_watershed]]를 참조한다.
|
||||
@@ -0,0 +1,43 @@
|
||||
---
|
||||
type: concept
|
||||
status: stable
|
||||
related_pages: ["[[B03_FileInput/B03_frontend]]", "[[B03_FileInput/B03_backend]]", "[[B04_PreProcess/B04_frontend]]", "[[B04_PreProcess/B04_backend]]", "[[B05_Profile/B05_backend]]", "[[drainage_watershed]]"]
|
||||
last_updated: 2026-08-30
|
||||
source: ["docs/raw/plans/2026-08-30_plan_las_free_sheet_surface.md", "docs/raw/verification/2026-08-30_verify_las_free_sheet_surface.md"]
|
||||
---
|
||||
|
||||
# LAS 없는 도엽등고선 서피스
|
||||
|
||||
## 계약과 확정값
|
||||
|
||||
| 항목 | 값 |
|
||||
|---|---|
|
||||
| 입력 | 계획노선 CSV·PRJ/좌표계·1:5,000 도엽등고선 |
|
||||
| 서피스 계약 | `dtm_sheet.npz`의 x/y/z/valid_mask와 GLB 프리뷰 |
|
||||
| 절취 여유 | 300m |
|
||||
| 격자 | 1m |
|
||||
| 기본 보간 | 라플라스, 스무딩 사용 |
|
||||
| 진입 정책 | 일반 사용자 자동확정·B04 진입차단 유지 |
|
||||
|
||||
## 흐름
|
||||
|
||||
| 항목 | 위치 | 역할 |
|
||||
|---|---|---|
|
||||
| `las_free` | B03 요청·stage 0 params | LAS 카드 비활성·필수검증 면제 |
|
||||
| `run_sheet_surface_analysis()` | `B04_PreProcess_Engine_SheetSurface.py` | 도엽 병합·격자·프리뷰·모델 등록·자동확정 |
|
||||
| `build_surface_sampler()` | `common_util_surface_sampler.py` | 종단·횡단·배수 공용 표고 조회 |
|
||||
| 도엽 서피스 컨테이너 | B04 frontend | LAS 모델과 별도 비교 표시 |
|
||||
|
||||
도엽 선 정점, 등고선 사이 중간선, 하천중심선 Z 앵커와 마루 국소 경사를 이용한다. NURBS 프리뷰는 이중 평활로 확정 격자와 달라져 되돌렸으며 다시 적용하지 않는다.
|
||||
|
||||
## E2E 결과
|
||||
|
||||
- LAS 없는 업로드가 도엽 9매·등고선 3,413건에서 서피스 6종, 배수유역, B05 노선, B06 횡단까지 자동 완주했다.
|
||||
- LAS 있는 신규 프로젝트도 같은 자동체인을 완주해 기존 경로 회귀가 없었다.
|
||||
- 조밀 원청 CSV는 정점 135개·최대 평면 이탈 0m·길이 350.11m로 보존된다.
|
||||
- 관 지점은 XY를 저장하며 노선 지문이 달라도 대상 노선에 투영해 이월한다.
|
||||
|
||||
## 미결
|
||||
|
||||
- 곡선 경고는 비용면 셀 크기와 분리된 고정 검사간격 또는 정식 IP/R 직접검사가 필요하다.
|
||||
- 기본 관과 격자 유입 봉우리 2.3m 차이의 스냅 여부는 사용자 결정 대상이다.
|
||||
@@ -0,0 +1,38 @@
|
||||
---
|
||||
type: concept
|
||||
status: draft
|
||||
related_pages: ["[[architecture/shared_resources]]"]
|
||||
last_updated: 2026-08-09
|
||||
source: "직접 확인 (docs/raw/law/original/임도기술교본/15. 부록/2. 임도설치 및 관리 등에 관한 규정.md)"
|
||||
---
|
||||
|
||||
# 임도기술교본 원문 md 추출 품질 결함
|
||||
|
||||
`docs/raw/law/original/임도기술교본/` 하위 각 조항 `.md` 파일은 PDF 원문에서 추출한 텍스트다. **raw/는 절대 수정 금지**이므로 원본은 그대로 두고, 이 문서에 알려진 결함을 기록해 재조사를 반복하지 않는다.
|
||||
|
||||
## 확인 범위
|
||||
원본 기록 `15. 부록/2. 임도설치 및 관리 등에 관한 규정.md` 1개 파일만 전수 확인함. 같은 변환 파이프라인을 거친 15장의 다른 파일, 1~14장 파일은 미확인이지만 동일 결함 가능성 높음.
|
||||
|
||||
## 결함 유형 (예시 = 위 파일 기준 줄번호)
|
||||
|
||||
1. **항(①②③...) 간 줄바꿈 소실** — 첫 항만 별도 줄, 나머지는 한 줄에 전부 이어붙음.
|
||||
- L24: 제3조 ①만 분리, ②~⑮이 한 줄.
|
||||
- L62: 제5조 "...필요성③" — 공백조차 없이 다음 항 번호가 바로 붙음.
|
||||
|
||||
2. **단어 사이 공백 소실** (줄 이어붙이며 공백 누락).
|
||||
- L24: `자를포함한다`, `관리에관한법률`, `등의각종`, `나타낸것을`, `자를말한다`
|
||||
- L32: `설치한시설<16>`
|
||||
|
||||
3. **공백 과다 삽입** (원문 자간 강조 표기를 스페이스로 오인식).
|
||||
- L47: `마을의 연결을 위하여 필요한 임지` (더블스페이스 3곳)
|
||||
- L92, L143, L275: 음절 사이마다 공백 (`박 사 학 위 를 받 은 자`)
|
||||
|
||||
4. **순서목록 번호 꼬임** (구조적으로 가장 심각) — 성격이 다른 두 목록이 줄바꿈 없이 이어지면서 번호가 연속으로 재부여됨.
|
||||
- L32~35: 제3조 ⑮ 부속물 목록(1~7호) 뒤에 `<16>` "테마임도" 정의가 줄바꿈 없이 붙고, 그 하위 유형(산림휴양형/산림레포츠형)이 새 목록 1,2가 아니라 **8, 9호**로 표시됨.
|
||||
- L63~66: 제5조 ④의 서류 목록도 같은 방식으로 **7,8,9**호로 이어짐 (원래 새 목록 1,2,3).
|
||||
|
||||
## 원인 추정
|
||||
PDF → 마크다운 변환 시 조(항) 사이 개행이 소실되고, 순서목록이 markdown 렌더러에 의해 자동으로 이어서 번호매김된 것으로 보임. OCR 문제가 아니라 변환/정리 단계 문제로 추정 — 유사 증상(줄바꿈 소실 원인)이 원본 기록 `임도기술교본_한글교정_작업가이드`가 다루는 PDF `ToUnicode` 폰트 문제와는 별개 사안임 (그쪽은 글자 자체가 깨지는 문제, 이쪽은 줄바꿈/공백 손실 문제).
|
||||
|
||||
## 조치 상태
|
||||
2026-08-09 기준 **미조치**. 사용자 결정: 원본은 그대로 두고 이 노트만 남겨 다음 세션이 참고. 실제 수정(재추출 또는 wiki 교정본 작성)은 아직 요청되지 않음.
|
||||
@@ -0,0 +1,71 @@
|
||||
---
|
||||
type: concept
|
||||
status: stable
|
||||
related_pages: ["[[B05_Profile/B05_frontend_alignment]]", "[[B06_Section/B06_frontend]]", "[[B06_Section/B06_backend]]", "[[B07_Quantity/B07_frontend]]", "[[B09_Estimation/B09_frontend]]", "[[architecture/shared_resources]]"]
|
||||
last_updated: 2026-08-30
|
||||
source: ["docs/raw/2026-07-24_유토곡선_분석_및_웹앱_계산명세.md", "docs/raw/plans/2026-08-02_유토곡선_3공구_분석.md", "docs/raw/plans/2026-08-02_plan_mass_haul_multi_curve.md", "docs/raw/plans/2026-08-04_plan_mass_haul_spoil_scroll.md", "docs/raw/verification/2026-08-02_verify_mass_haul_distribution_and_refinements.md", "docs/raw/verification/2026-08-02_verify_mass_haul_multi_curve.md", "docs/raw/verification/2026-08-02_verify_panel_fold_B05_style.md", "docs/raw/verification/2026-08-02_verify_panel_height_first_render.md", "docs/raw/verification/2026-08-02_verify_backlog_reorg.md", "docs/raw/verification/2026-08-03_verify_후속작업_주의사항.md", "docs/raw/verification/2026-08-03_verify_B05_mass_haul_transfer.md", "docs/raw/verification/2026-08-03_verify_향후작업_반영완료.md", "docs/raw/verification/2026-08-04_verify_mass_haul_spoil_scroll.md"]
|
||||
---
|
||||
|
||||
# 유토곡선 (Mass Haul Diagram) 계산 명세
|
||||
|
||||
## 1. 개요 및 분석 목적
|
||||
* **분석 대상**:
|
||||
* 1공구: `07.유토곡선.pdf` (측점 `0+0.0` ~ `60+0.0`, V=1:10,000, 최종 누가토량 1,171.00㎥)
|
||||
* 3공구: `13 유토곡선(3공구).pdf` (측점 `120+0.0` ~ `176+10.0`, V=1:50,000, 최종 누가토량 12,888.98㎥)
|
||||
* **역할**: 노선 내 절토 및 성토의 차이를 누적하여 토량 이동(토공 운반계획), 사토량/토취량, 운반장비(종무대, 불도저, 덤프트럭) 및 평균운반거리를 결정하는 도면/차트.
|
||||
* **웹앱 명세 목적**: Aislo 웹앱 B08 수량산출 및 B09 내역서 연동 시 유토곡선 자동 계산 및 시각화를 위한 원리 명세화.
|
||||
|
||||
## 2. 주요 계산 수식 및 원리 (실무 관례 반영)
|
||||
* **다짐상태 기준의 산출 (운반계획 실무 표준)**:
|
||||
* 유토곡선은 다짐상태를 기준으로 유동 토량을 계산합니다.
|
||||
* **측점별 순토량 ($N_i$)**:
|
||||
$$N_i = \sum [C_{i, j} \times C_j] - F_i$$
|
||||
* $C_{i, j}$: 현재 측점 구간의 $j$번째 지반유형별 절토량 (자연상태, ㎥)
|
||||
* $C_j$: $j$번째 지반유형의 토량환산계수(다짐률)
|
||||
* $F_i$: 현재 측점 구간의 성토량 (다짐상태, ㎥)
|
||||
* **누가토량 ($M_i$)**:
|
||||
$$M_i = M_{i-1} + N_i$$
|
||||
* **곡선 증감 해석**:
|
||||
* 상승 구간 ($M_i > M_{i-1}$): 절토 우세 구간
|
||||
* 하강 구간 ($M_i < M_{i-1}$): 성토 우세 구간
|
||||
* 극댓값/극솟값: 절토/성토 우세가 전환되는 변곡점
|
||||
* 동일 누가토량 수평선: 구간 내 절토·성토 토량 균형 (Balance Line)
|
||||
|
||||
## 3. 지반유형별 토량환산계수 기본값 (`config_system.py`)
|
||||
지반유형(`soil`, `ripping_rock`, `blasting_rock`)에 따른 체적 변화 계수(L: 흐트러진 상태, C: 다져진 상태) 기본값은 다음과 같이 관리하며, 현장별 조정을 위해 설정 가능하도록 제공합니다.
|
||||
|
||||
| B06 지반유형 | 대응 암종 | 팽창률 (L) | 다짐률 (C) |
|
||||
|---|---|---|---|
|
||||
| 토사 `soil` | 풍화토~점토 | 1.25 | 0.90 |
|
||||
| 리핑암 `ripping_rock` | 풍화암~연암 하단 | 1.35 | 1.15 |
|
||||
| 발파암 `blasting_rock` | 보통암 중앙 | 1.60 | 1.30 |
|
||||
|
||||
## 4. 토공 운반장비 선정거리 및 분배 기준 (`config_system.py`)
|
||||
평균운반거리에 따른 장비 선정 기준은 오직 `config_system.py`의 `EARTHWORK_HAUL_EQUIPMENT_LIMITS_M` 상수에서 단일 관리됩니다. (3공구 도면 실측치 및 실무 관행 적용)
|
||||
* **종무대 (무대운반)**: 운반거리 $\le$ 20.0m
|
||||
* **불도저 (압토운반)**: 운반거리 $\le$ 50.0m
|
||||
* **덤프트럭 (기타운반)**: 운반거리 50.0m 초과 (나머지 전체)
|
||||
* **자연방토 (`natural_spoil_m3`)**: 성토 사면 경사가 `NATURAL_SPOIL_MIN_GROUND_SLOPE = 1/1.5` 이상으로 급하여 기계적으로 흙을 운반하지 않고 흘려보내는 자연탈락 물량. 사토 수량에서 자동 공제되어 balloon에 `M.N=측점` 형태로 표기됩니다.
|
||||
|
||||
## 5. 유토곡선 곡선 사양 (B06 구현 v2)
|
||||
사용자가 비교 분석할 수 있도록 **기준 2종 × 지반유형 1종 = 총 2개 곡선**을 중첩하여 제공합니다.
|
||||
* **기준 2종**:
|
||||
1. **횡단 기준**: 실제 횡단 단면적 기반의 정밀 산출 (`design.cut_area_m2` / `fill_area_m2`)
|
||||
2. **종단 기준**: 계획고 - 지반고 (`difference_m`) × 노반폭 기반의 개략 산출 (균형 판정 지표)
|
||||
* **지반유형 1종**:
|
||||
- 횡단도 기하 및 암 경계선 기준의 토사/암반 면적 분리 기능 신설에 따라, **지반유형별** L, C 팽창/다짐률 개별 적용 곡선만 유지합니다. (실제 정보가 없던 `토사 단일`, `환산 없음` 곡선은 삭제).
|
||||
|
||||
## 6. 웹앱 연동 및 시각화 명세 (2026-08-02 확정)
|
||||
* **웹앱 연동 및 시각화 명세 (2026-08-03 확정)**:
|
||||
* **자동 Y스케일 및 Y축 0선 표기**: Y축 눈금은 노선 데이터 범위 기반의 동적 Y스케일링을 수행하며, 차트 상 0선(Balance Line)에 명시적으로 눈금값 "0"을 렌더링합니다.
|
||||
* **평형선 엔진 및 장비 띠 분할**: 순차 평형선 탐색 알고리즘(`computeHaulPlan`)을 기반으로 사토/토취 단차를 둔 평형선을 산출하며, 장비 한계거리별로 영역을 쪼갠 띠(`HaulBand`)를 반투명 다각형으로 렌더링합니다.
|
||||
* **다중 곡선화 및 직선 보간**: `PARABOLIC_MASS_CURVE = false` 스위치 단일화로 포물선 오차를 제거하고 현 길이/그리기 기준을 직선 연결로 고정. 횡단/종단 기준 × 지반유형 옵션 오버레이 지원.
|
||||
* **장거리 운반 상쇄 (`HaulTransfer`)**: 띠 분배 후 남은 사토/토취 잔량은 토공 최소화 원칙에 따라 최단거리 쌍으로 자동 상쇄 연계(덤프 운반) 처리하여 최종 사토량 항등식의 수치적 오차를 0으로 맞춥니다.
|
||||
* **물량 육각 Balloon 인터랙션**: 충돌 회피(`findSlot` 링 탐색) 및 화면 이탈 방지 clamping이 적용되어 있고, 드래그 위치 보존 및 더블클릭 복귀를 지원합니다.
|
||||
* **UI/UX 레이아웃 보정**: B06 상단 패널 접기 손잡이 `bottom: -24px` 독립 배치(`createWorkflowPanelHandle` collapseToward: up/down 확장), 첫 렌더 시 `panelHeight()` 인라인 CSS 변수 우선 참조로 종단면도 축소 결함 해결.
|
||||
* **B05 유토곡선 슬라이드 패널 이관 & 공용화**: B05 노선 설계 화면에 유토곡선 2차 슬라이드 패널 구축, `common_util_mass_haul*.ts|css` 공용 모듈 분리 및 `MassHaulAxis` 파라미터화, B05-B06 간 싱글턴 캐시 공유(`ProfileCross_Section_Store.ts`).
|
||||
* **사토장 모델 & B08 수량산출 인계 (2026-08-04 확정)**: 사토 balloon에 `L=` 및 장비 표기, 잔량 발생 시 다중 부지 매칭(`settleResiduals`)을 적용하며, 사토장 자동 선정 취소 및 B05 구조물 직접 배치 방식 전환에 따라 유토곡선->B08 수량산출 자동 인계는 최종 취소(운반비 미계상) 처리되었습니다. 자연방토 임계 경사(`NATURAL_SPOIL_MIN_GROUND_SLOPE = 1.0 / 1.5`)는 실무 도면 기재 관행을 반영하여 그대로 유지됩니다.
|
||||
* **후속 주의사항 13개 지침**: 암 경계선 지반선 복사 오프셋, 표준단면 토큰 단일화, B06 상세조회 백엔드 반영 시점, 다짐상태 유토곡선 누적, `EARTHWORK_HAUL_EQUIPMENT_LIMITS_M` 단일참조, 토량 배분 3원칙, 사면-지반 첫 교차 정지 등 지침 통합 관리.
|
||||
* **측점 간격**: 20m 간격 기준 (`config/config_system.py`의 `SECTION_STATION_INTERVAL_M = 20.0` 적용).
|
||||
* **B08 납품도면**: 확정 종단 DB의 `mass_haul`을 사용해 A1 토적도를 H=1:2,000, 세로 1mm=50㎥로 생성합니다. 상세 구성과 후속 결정은 [[B08_DesignDetail/B08_drawing_masshaul_watershed]]를 참조합니다.
|
||||
* **사용처**: [[B05_Profile/B05_frontend_alignment]], [[B06_Section/B06_frontend]], [[B06_Section/B06_backend]], [[B07_Quantity/B07_frontend]], [[B08_DesignDetail/B08_drawing_masshaul_watershed]], [[B09_Estimation/B09_frontend]]
|
||||
@@ -0,0 +1,37 @@
|
||||
---
|
||||
type: concept
|
||||
status: stable
|
||||
related_pages: ["[[B08_Quantity/B08_overview_2026_09]]", "[[B09_Estimation/B09_overview_2026_09]]", "[[architecture/workflow_data_flow]]"]
|
||||
last_updated: 2026-09-09
|
||||
source: ["docs/raw/plans/2026-09-08_plan_B08_B09_설계합의.md"]
|
||||
---
|
||||
|
||||
# B08 수량 ↔ B09 원가 계약
|
||||
|
||||
## 책임 경계
|
||||
|
||||
| 단계 | 책임 | 산출 |
|
||||
|---|---|---|
|
||||
| B07 | 설계도면 | 도면·상세설계 |
|
||||
| B08 | 수량산출 | 물량, 공종코드, 판정 근거, 자재총괄 |
|
||||
| B09 | 원가계산 | 단가산출, 예산내역, 공사원가계산 |
|
||||
|
||||
경계선은 자재/작업이 아니라 **수량/금액**이다. B08은 금액을 만들지 않고 B09는 물량을 다시 세지 않는다.
|
||||
|
||||
## 저장·인계 규칙
|
||||
|
||||
| 자원 | 정본 | 사용처 |
|
||||
|---|---|---|
|
||||
| 공종 마스터·원단위표 | `resources/` 버전 파일+매니페스트 | B08 생산, B09 읽기 |
|
||||
| 수량 결과·자재 총괄 | 프로젝트 영구저장소 | B08 저장, B09 소비 |
|
||||
| 구조물 제원 | `B05_Profile/route/structures.json` + B06 횡단 제원 | B08 전개식 |
|
||||
| 기준자료 버전 | `dataset_id`·`effective_date`·`sha256` | 프로젝트 재현성 |
|
||||
|
||||
B08→B09 인계는 공종코드·명칭·규격·단위·수량과 공급 구분, 암 갈래, 운반거리·수단, 할증 전후, 측점 구간, 규격 상세를 포함한다.
|
||||
|
||||
## 금지 규칙
|
||||
|
||||
- 할증은 자재 총괄에서 한 번만 적용한다. 원단위와 일위대가 재료비는 할증 전 값이다.
|
||||
- `free_haul` 20m 이하는 품에 포함되므로 내역 줄을 만들지 않고 검산 수량으로만 보존한다.
|
||||
- 문자열 이름 매칭 대신 공종코드를 사용한다.
|
||||
- 성분·밑수·근거가 빠진 공종은 그럴듯한 금액을 만들지 않고 미확보로 표시한다.
|
||||
@@ -0,0 +1,19 @@
|
||||
---
|
||||
type: concept
|
||||
status: draft
|
||||
related_pages: ["[[architecture/shared_resources]]"]
|
||||
last_updated: 2026-07-12
|
||||
source: raw/guidelines/backend.md
|
||||
---
|
||||
|
||||
# 공통 스키마 (Pydantic 요청/응답 규칙)
|
||||
|
||||
## 검증 원칙 (backend.md 4절)
|
||||
- 모든 JSON 요청은 라우터 진입 전 Pydantic 모델로 타입·범위 검증.
|
||||
- 모든 지형/메쉬 연산은 `try-except` 필수.
|
||||
- 에러 응답 표준 포맷: `{"status": "error", "message": "원인"}` — 전 라우터 공통, 프론트도 동일 포맷 기대.
|
||||
|
||||
## 명명 규칙
|
||||
파일명 `[폴더명]_Schema.py`, 페이지 폴더 내부 배치 (전역 공유 스키마 폴더 없음 — 필요 시 여기에 항목 추가).
|
||||
|
||||
> 현재 raw 자료에서 페이지 간 공유되는 구체적 Pydantic 모델(예: 공통 페이지네이션, 공통 좌표 타입)은 확인되지 않음. 발견 시 이 페이지에 추가.
|
||||
@@ -0,0 +1,34 @@
|
||||
---
|
||||
type: concept
|
||||
status: draft
|
||||
related_pages: ["[[B07_DesignDetail/B07_standard_drawings_2026_09]]", "[[quantity_cost_contract]]", "[[B08_Quantity/B08_overview_2026_09]]", "[[B09_Estimation/B09_overview_2026_09]]", "[[law_source_quality]]"]
|
||||
last_updated: 2026-09-09
|
||||
source: ["docs/raw/verification/2026-09-08_표준도_위_확정대기_배치.md", "docs/raw/verification/2026-09-08_남의_결론_검증_표준도.md", "docs/raw/verification/2026-09-08_표준도_B08_일감_크기.md", "docs/raw/verification/2026-09-08_B08화면과_표준도_오가는_길.md", "docs/raw/verification/2026-09-08_지식DB_재조사_안읽은파일.md", "docs/raw/verification/2026-09-08_실무원본_돌종류_채집여부.md", "docs/raw/verification/2026-09-08_법령_행정규칙_원문_점검.md", "docs/raw/verification/2026-09-09_B07_표준도_조사와_합의.md"]
|
||||
---
|
||||
|
||||
# 표준도·수량·원가 입력의 미결 경계
|
||||
|
||||
## 확인된 분류
|
||||
|
||||
| 종류 | 예 | 처리 |
|
||||
|---|---|---|
|
||||
| 사용자 입력 | 표토 제거두께, 공급 구분, 돌 규격·쌓기 방식 | 프로젝트 설정에서 입력 |
|
||||
| 자동 계산 | 구조물 원단위, 규준틀 조건, 유토곡선 평균운반거리 | 정본 제원·설계 결과에서 산출 |
|
||||
| 기준자료 | 품셈, 노임·기계·요율, 법정 설계서 구성 | 버전 파일과 근거 보존 |
|
||||
| 미확보 | BOX 두께, 일부 표준도 치수, 사급 단가 | 임의 확정 금지 |
|
||||
|
||||
## 재조사로 바뀐 판정
|
||||
|
||||
- 이음 간격은 “사용처 없음”이 아니라 표준도 표에 들어갈 자리로 확인됐다.
|
||||
- 버림 콘크리트는 산출 대상이며 실무 원본에 두께 근거가 있다.
|
||||
- 표토 제거두께는 품셈 고정값이 아니라 공식의 설계 입력 변수다.
|
||||
- 목재틀흙막이 밑수 1㎥는 구조물 체적이 아니라 목재 채적이며 구조 등급 판정이 남는다.
|
||||
- BOX암거 두께는 사용자 선택값이 아니라 하중 검토 또는 표준도 확보가 필요한 구조설계 결과다.
|
||||
- 돌 재료는 야면석·채집석/구입석 갈래가 실무 원본에 있으나 선택 기준은 확정되지 않았다.
|
||||
|
||||
## 사용자·자료 대기
|
||||
|
||||
- 제잡비 밑수, 내역 수량 표시 자릿수, 목재틀 등급, 석재 할증 적용 여부.
|
||||
- 사급 자재 단가, 유가 지역값, 밑수 미확보 항목, 표준도 제원.
|
||||
- 미결은 `근거 미확인` 또는 사용자 확정 대기로 유지하며 웹 검색값이나 임의 수치로 채우지 않는다.
|
||||
- 상세 화면·저장·도면 계약은 [[B07_DesignDetail/B07_standard_drawings_2026_09]]에 연결한다.
|
||||
@@ -0,0 +1,50 @@
|
||||
---
|
||||
type: concept
|
||||
status: draft
|
||||
related_pages: ["[[B02_ProjRegister/B02_backend]]", "[[B03_FileInput/B03_backend]]", "[[B04_PreProcess/B04_backend]]", "[[B05_Profile/B05_backend]]", "[[B06_Section/B06_backend]]", "[[B07_Quantity/B07_backend]]", "[[B08_DesignDetail/B08_backend]]", "[[B09_Estimation/B09_frontend]]", "[[architecture/implementation_status]]", "[[architecture/shared_resources]]"]
|
||||
last_updated: 2026-08-23
|
||||
source: raw/guidelines/structure.md, raw/guidelines/db_schema.md, raw/guidelines/backend.md, raw/guidelines/agent.md, raw/plans/2026-07-17_plan_b04_defects.md, raw/plans/2026-07-26_plan_도엽_오버레이.md
|
||||
---
|
||||
|
||||
# 저장 경로 규칙 (Workflow-based Folder Structure)
|
||||
|
||||
## 경로 패턴
|
||||
```
|
||||
storage/{company_slug}/{user_slug}/{project_id}/
|
||||
├── B03_FileInput/input/{file_type}/ WF0 원본 입력
|
||||
├── B04_PreProcess/
|
||||
│ ├── processed/ 변환 지형 및 타 지도 가공 데이터
|
||||
│ │ └── map_sheets/ 1:5,000 수치지형도 도엽 zip 및 metadata
|
||||
│ └── models/ WF1 모델 (지면 필터 ground_points_{filter}.npz 캐시 포함)
|
||||
├── B05_Profile/route/ WF2 경로·일반 구조물 structures.json
|
||||
├── B05_Profile/corridor/ WF2 3D 코리도 corridor_{route:04d}.json
|
||||
├── B06_Section/longitudinal/, cross_sections/ WF3 종횡단
|
||||
├── B07_Quantity/ 현재 별도 산출물 없음
|
||||
├── B08_DesignDetail/
|
||||
│ ├── manifest.json 도면 확정 메타데이터·횡단 quantity_table
|
||||
│ └── drawings/{drawing_id}.json 확정 CAD 도면
|
||||
└── B09_Estimation/ 현재 산출 backend 미확인
|
||||
```
|
||||
|
||||
## 원칙 (backend.md 3절)
|
||||
1. **하드코딩 금지** — 경로는 `config/config_system.py`에서 import.
|
||||
2. **물리 파일은 DB 저장 금지** — 대용량 파일은 파일시스템, DB에는 경로만.
|
||||
3. **단계별 루트 강제** — 각 B0x 폴더명은 실제 워크플로우 페이지명과 동일해야 함. `raw/`, `processed/`, `computed/`를 프로젝트 루트 공용 폴더로 만들지 않음.
|
||||
4. **경로 생성 책임** — 원칙상 단계별로 분리하되, 현재 B05가 B06 종횡단 파일을 생성하고 B08이 B06 단면을 재계산하므로 실제 구현 예외를 함께 추적한다.
|
||||
5. **상대 경로만 DB 저장** — 프로젝트 루트 기준 상대경로. 사용자 입력 경로 직접 결합 금지(경로 이탈 방지), 절대경로 저장 금지.
|
||||
|
||||
## DB 컬럼 ↔ 실제 경로 매핑
|
||||
상세 표 → [[db_schema/overview]] "파일 경로 추적 컬럼"
|
||||
|
||||
## 파일명 규칙 (structure.md 1절)
|
||||
- 페이지 폴더: 로그인 전 `A0x_`, 로그인 후 `B0x_`, 워크플로우는 `wf[번호]` 접두사
|
||||
- 파일명: `폴더명(페이지명)_기능_기타사양.확장자`
|
||||
- 공통 유틸: `common_util/common_util_기능.확장자`
|
||||
|
||||
## 코드 감사 주의사항
|
||||
|
||||
- B05 `generate_sections()`가 `B06_Section/longitudinal`과 `cross_sections`를 생성한다.
|
||||
- B05 일반 구조물은 `B05_Profile/route/structures.json`, 배관은 B04 공용 `pipe_points.json`이 각각 정본이다. [[B05_Profile/B05_structures]] 참조.
|
||||
- B05 예상형상 코리도는 DB가 아닌 `B05_Profile/corridor/corridor_{route:04d}.json`에 입력 해시와 리본을 원자 저장한다. [[B05_Profile/B05_corridor_surface]] 참조.
|
||||
- B08은 `B06_Section` 산출물을 읽고 `B08_DesignDetail/manifest.json` 및 `drawings/*.json`을 저장한다.
|
||||
- `workflow.json`은 프로젝트 루트에 있지만 workflow 상태 SSOT는 아니다.
|
||||
@@ -0,0 +1,33 @@
|
||||
---
|
||||
type: concept
|
||||
status: stable
|
||||
page_id: concept_temp_upload
|
||||
related_pages: ["[[B01_Dashboard/B01_frontend]]", "[[B03_FileInput/B03_backend]]", "[[B03_FileInput/B03_frontend]]", "[[architecture/shared_resources]]"]
|
||||
last_updated: 2026-08-08
|
||||
source: docs/raw/verification/2026-08-08_verify_R1_R2_features.md
|
||||
---
|
||||
|
||||
# Temp Upload (프로젝트 생성 전 임시 보관함)
|
||||
|
||||
R2 요구사항에 따른 프로젝트 생성 전 라이다/설계 자료 임시 보관 및 관리 기능 명세.
|
||||
|
||||
## 주요 개념 및 스펙
|
||||
- **DB 테이블**: `temp_upload_batches` (임시 보관 묶음/그룹), `temp_upload_files` (보관 파일), `upload_sessions` (`project_id` NULL 허용 완화 및 `temp_batch_id` 연결).
|
||||
- **만료 관리**: 30일 경과 만료 보관 자료 자동 삭제 정리 (`common_util_temp_cleanup.py` 내 `lifespan` 주기 루프).
|
||||
- **영구 저장소 연동**: B03 파일 입력에서 [임시 보관함에서 불러오기] 선택 시 `attach` API 호출을 통해 영구 프로젝트 저장소로 이동 및 체인 자동 트리거.
|
||||
|
||||
## 주요 구성 요소
|
||||
| 항목 | 위치 | 역할 |
|
||||
|---|---|---|
|
||||
| `010_temp_upload.sql` | `db_management/010_temp_upload.sql` | DB DDL 스크립트 |
|
||||
| `B03_FileInput_Router_Temp.py` | `B03_FileInput/B03_FileInput_Router_Temp.py` | 임시 보관함 라우터 (묶음/파일 CRUD, attach) |
|
||||
| `B03_FileInput_Schema_Temp.py` | `B03_FileInput/B03_FileInput_Schema_Temp.py` | Pydantic 스키마 |
|
||||
| `B03_FileInput_Repository_Temp.py` | `B03_FileInput/B03_FileInput_Repository_Temp.py` | DB Access Repository |
|
||||
| `common_util_temp_cleanup.py` | `common_util/common_util_temp_cleanup.py` | 만료 보관 자료 자동 삭제 크론/정리 |
|
||||
| `B01_Dashboard_UI_TempUpload.ts` | `B01_Dashboard/B01_Dashboard_UI_TempUpload.ts` | 대시보드 하단 임시 보관함 표 |
|
||||
| `B01_Dashboard_UI_TempModal.ts` | `B01_Dashboard/B01_Dashboard_UI_TempModal.ts` | 파일 등록 및 업로드 모달 |
|
||||
|
||||
## 사용처
|
||||
- [[B01_Dashboard/B01_frontend]]
|
||||
- [[B03_FileInput/B03_backend]]
|
||||
- [[B03_FileInput/B03_frontend]]
|
||||
@@ -0,0 +1,97 @@
|
||||
---
|
||||
status: stable
|
||||
related_pages: ["[[A01_Home/A01_frontend]]", "[[A02_ProgDetail/A02_frontend]]", "[[B01_Dashboard/B01_frontend]]", "[[B03_FileInput/B03_frontend]]", "[[B04_PreProcess/B04_frontend]]", "[[B05_Profile/B05_frontend]]", "[[B06_Section/B06_frontend]]", "[[B07_Quantity/B07_frontend]]", "[[B08_DesignDetail/B08_frontend]]", "[[B09_Estimation/B09_frontend]]", "[[A06_Login/A06_frontend]]", "[[B10_Payment/B10_frontend]]", "[[B11_Status/B11_frontend]]", "[[architecture/shared_resources]]"]
|
||||
last_updated: 2026-08-22
|
||||
source: ["docs/raw/verification/2026-08-08_verify_dashboard_scroll_limit.md", "docs/raw/verification/2026-08-08_verify_project_delete_hard.md"]
|
||||
---
|
||||
|
||||
# UI Templates — Localization & Components
|
||||
|
||||
프론트엔드 공통 UI 요소: 다국어(i18n), 공통 컴포넌트, 테마 스타일, 레이아웃, 리사이저, 지도 팔레트. 디자인 시스템: [[design]]
|
||||
|
||||
## ui_template_locale.ts (다국어 관리)
|
||||
**파일**: `ui_template/ui_template_locale.ts` (배럴 파일) 및 하위 사전 파일 4종
|
||||
|
||||
| 항목 | 위치 | 역할 |
|
||||
|---|---|---|
|
||||
| `ui_template_locale.ts` | `ui_template/ui_template_locale.ts` | 배럴 파일. `ui_template_locale_common/a/b1/b2` 합성 및 `LANGUAGES`/`LanguageCode`/`currentLanguageIndex`/`setLanguage`/`t`/`ui_locales`/`LocaleKey` 동일 노출 |
|
||||
| `ui_template_locale_common.ts` | `ui_template/ui_template_locale_common.ts` | 헤더/푸터/버튼/공통 문구 사전 (60개 키, 105줄) |
|
||||
| `ui_template_locale_a.ts` | `ui_template/ui_template_locale_a.ts` | A그룹 (A01~A09 로그인 전) 문구 사전 (141개 키, 278줄) |
|
||||
| `ui_template_locale_b1.ts` | `ui_template/ui_template_locale_b1.ts` | B그룹 전반부 (B01~B04) 문구 사전 (하드 삭제 경고 `B01_Dashboard_Confirm_DeleteProject_Hard` 추가) |
|
||||
| `ui_template_locale_b2.ts` | `ui_template/ui_template_locale_b2.ts` | B그룹 후반부 (B05~B11) 문구 사전 (253개 키, 420줄) |
|
||||
| `t(key)` | `ui_template/ui_template_locale.ts` | 지정된 키에 대응하는 현재 언어 텍스트 반환 |
|
||||
|
||||
## ui_template_resizer.ts (패널 리사이저 템플릿)
|
||||
**파일**: `ui_template/ui_template_resizer.ts`
|
||||
|
||||
| 항목 | 위치 | 역할 |
|
||||
|---|---|---|
|
||||
| `attachResizer(opts)` | `ui_template/ui_template_resizer.ts` | 패널 상하/좌우 드래그 리사이저 핸들 조립 (Pointer Capture 적용, CSS 변수 및 `sessionStorage` 연동) |
|
||||
|
||||
## ui_template_palette.ts (지도 팔레트 캐싱 유틸)
|
||||
**파일**: `ui_template/ui_template_palette.ts`
|
||||
|
||||
| 항목 | 위치 | 역할 |
|
||||
|---|---|---|
|
||||
| `themeColor(tokenName)` | `ui_template/themeColor(tokenName)` | CSS 변수 `--map-*` 33종 색상 토큰을 캔버스/SVG용 hex/rgb로 파싱 및 캐싱 |
|
||||
|
||||
## ui_template_general_blocks.ts (일반업무 공용 블록)
|
||||
**파일**: `ui_template/ui_template_general_blocks.ts`
|
||||
|
||||
| 항목 | 위치 | 역할 |
|
||||
|---|---|---|
|
||||
| `section(title, content)` | `ui_template/ui_template_general_blocks.ts:29` | 일반업무(B01/B02/B03/B10/B11)용 레이아웃 섹션 래퍼 |
|
||||
| `buildSectionHeader(title)` | `ui_template/ui_template_general_blocks.ts:9` | 섹션 타이틀 헤더 렌더링 |
|
||||
| `table(headers, rows)` | `ui_template/ui_template_general_blocks.ts:88` | 스타일이 적용된 데이터 테이블 조립 컴포넌트 |
|
||||
| `limitVisibleRows(host, items, visible)` | `ui_template/ui_template_general_blocks.ts:53` | 지정한 개수 이상일 때 4행 높이에 맞춰 컨테이너의 `max-height`를 동적으로 재고 세로 스크롤 활성화 (WeakMap으로 리사이즈 중복 리스너 해제) |
|
||||
|
||||
## ui_template_general_layout.ts (일반업무 레이아웃)
|
||||
**파일**: `ui_template/ui_template_general_layout.ts`
|
||||
|
||||
| 항목 | 위치 | 역할 |
|
||||
|---|---|---|
|
||||
| `createGeneralLayout(opts)` | `ui_template/ui_template_general_layout.ts:20` | B01 스타일 기준의 중앙 콘텐츠 폭을 지닌 일반업무용 페이지 프레임 구성 |
|
||||
|
||||
## ui_template_elements.ts (공통 엘리먼트 템플릿)
|
||||
**파일**: `ui_template/ui_template_elements.ts`
|
||||
|
||||
| 항목 | 위치 | 역할 |
|
||||
|---|---|---|
|
||||
| `createButton(opts)` | `ui_template/ui_template_elements.ts:15` | 공통 버튼 생성 템플릿. `ButtonVariant` 타입에 `"glass"` 추가, 반투명 배경 및 블러 스타일(`.ui-btn--glass`) 지원 |
|
||||
|
||||
## ui_template_overlay.ts (오버레이 컴포넌트)
|
||||
**파일**: `ui_template/ui_template_overlay.ts`
|
||||
|
||||
| 항목 | 위치 | 역할 |
|
||||
|---|---|---|
|
||||
| `createVerticalStepBar(opts)` | `ui_template/ui_template_overlay.ts:15` | 우측 세로 진행단계 오버레이 패널 (기본 펼침, 접기/펼치기 및 sessionStorage에 토글 상태 보존) |
|
||||
| `createWorkflowPanelHandle(opts)` | `ui_template/ui_template_overlay.ts:50` | 공통 접기/펼치기 핸들 컴포넌트 (placement 'side'/'bottom' 및 collapseToward 'left'/'right'/'up'/'down' 대응, CSS 삼각형 rotate 토글 적용) |
|
||||
| `createTitleCard(title, subtitle)` | `ui_template/ui_template_overlay.ts:85` | 헤더 제거 페이지(B03, B04~B09)용 좌상단 오버레이 카드 |
|
||||
| `createOptionOverlay(content)` | `ui_template/ui_template_overlay.ts:125` | 엔지니어링 그룹용 제목 카드 하단 옵션 배치 오버레이 |
|
||||
|
||||
## ui_template_workflow_layout.ts (엔지니어링 레이아웃)
|
||||
**파일**: `ui_template/ui_template_workflow_layout.ts`
|
||||
|
||||
| 항목 | 위치 | 역할 |
|
||||
|---|---|---|
|
||||
| `createWorkflowLayout(opts)` | `ui_template/ui_template_workflow_layout.ts:28` | **상단 헤더(제목/단계)가 제거**되고, 전체 화면 폭 본문 + 좌상단 제목 카드 + 우측 세로 단계 오버레이가 결합된 완성형 엔지니어링 레이아웃 |
|
||||
|
||||
## theme.css (스타일 변수)
|
||||
**파일**: `ui_template/theme.css`
|
||||
|
||||
| 항목 | 위치 | 역할 |
|
||||
|---|---|---|
|
||||
| `--color-primary`, `--color-primary-text` | `ui_template/theme.css:10` | 기본 색상 및 기본 텍스트 색상 |
|
||||
| `--color-canvas`, `--color-paper` | `ui_template/theme.css:15` | 기본 캔버스 배경 및 레이어 카드 배경 |
|
||||
| `--color-deep-iris`, `--color-mist-violet` | `ui_template/theme.css:22` | 라벤더 그라디언트 및 브랜드 서브 컬러 |
|
||||
| `--spacing-8`, `--spacing-16` 등 | `ui_template/theme.css:45` | 기본 마진/패딩 간격 시스템 (8px 배수) |
|
||||
| `--radius-cards`, `--radius-icons` | `ui_template/theme.css:110` | 8px 등의 둥근 테두리 곡률 반지름 변수 |
|
||||
|
||||
## 제약 (backend.md §1)
|
||||
1. **다국어**: 모든 UI 문구는 반드시 `ui_locales` 등록 후 `L(key)` 또는 `t(key)`로만 참조
|
||||
2. **스타일**: CSS는 `theme.css` 변수만 사용, 하드코드 색상/단위 금지
|
||||
3. **컴포넌트 재사용**: `createGeneralLayout`, `createWorkflowLayout`, `createVerticalStepBar` 등 공용 템플릿 사용
|
||||
|
||||
## 남은 파일 한계
|
||||
|
||||
2026-08-22 현재 `ui_template_elements.ts`는 891줄이다. 동작 문제는 아니지만 단일 파일 700줄 제한을 넘으므로 후속 분리 대상이다.
|
||||
@@ -0,0 +1,66 @@
|
||||
---
|
||||
type: concept
|
||||
status: stable
|
||||
related_pages: ["[[B01_Dashboard/B01_frontend]]", "[[B02_ProjRegister/B02_backend]]", "[[B03_FileInput/B03_backend]]", "[[B04_PreProcess/B04_backend]]", "[[B05_Profile/B05_backend]]", "[[B06_Section/B06_backend]]", "[[B07_Quantity/B07_backend]]", "[[B08_DesignDetail/B08_backend]]", "[[B09_Estimation/B09_frontend]]", "[[architecture/implementation_status]]", "[[architecture/shared_resources]]"]
|
||||
last_updated: 2026-08-16
|
||||
source: ["docs/raw/verification/2026-07-19_verify_webcad_poc.md", "docs/raw/verification/2026-07-19_verify_B06_사이드바_버튼_폭_및_확정_후_B07_이동.md", "docs/raw/verification/2026-07-21_verify_B06_default_design_B07_gating.md", "docs/raw/verification/2026-08-04_verify_b05_b06_profile_ui_chain.md", "docs/raw/verification/2026-08-08_verify_R1_R2_features.md", "docs/raw/verification/2026-07-17_verify_workflow_stepbar.md"]
|
||||
---
|
||||
|
||||
# Workflow 상태 관리
|
||||
|
||||
> DB 상태 유틸은 구현돼 있다. 그러나 B07은 임시 완료 우회, B09는 셸이므로 일곱 단계 전체가 업무 기능으로 완료된 것은 아니다.
|
||||
|
||||
## SSOT: `project_workflow_stages` 테이블 (실 DB 확인)
|
||||
| 컬럼 | 타입 |
|
||||
| --- | --- |
|
||||
| id | INT PK |
|
||||
| project_id | CHAR(36), FK |
|
||||
| stage_no | TINYINT (0~6) |
|
||||
| stage_key | VARCHAR(30) — FILE_INPUT/PREPROCESS/PROFILE/SECTION/QUANTITY/DESIGN_DETAIL/ESTIMATION |
|
||||
| state | ENUM('NOT_STARTED','IN_PROGRESS','COMPLETE','FAILED','STALE') |
|
||||
| progress_percent | TINYINT |
|
||||
| params | LONGTEXT(JSON) — 재실행 시 폼 프리필용 |
|
||||
| message, started_at, completed_at, updated_at | 진행/이력 |
|
||||
|
||||
생성 SQL: `db_management/006_workflow_state.sql`, 백필: `db_management/migrate_workflow_state.py`
|
||||
|
||||
## R1 워크플로우 단계 재편 (2026-08-08 반영)
|
||||
- **B04_PreProcess** (stage 1: 지표면 분석)
|
||||
- **B05_Profile** (stage 2: 경로 및 종단)
|
||||
- **B06_Section** (stage 3: 횡단 및 유토곡선)
|
||||
- **B07_Quantity** (stage 4: 수량 셸 신설, `confirm_quantity`로 stage 4 COMPLETE 전이)
|
||||
- **B08_DesignDetail** (stage 5: CAD 도면/OpenWebCAD 이동, 정적 마운트 `/b08-cad`)
|
||||
- **B09_Estimation** (stage 6: 설계도서 및 견적)
|
||||
|
||||
## 백그라운드 자동 계산 체인 및 사용자 설정 이월
|
||||
* **업로드 후 자동 계산 체인 (B04 ➡️ B05 ➡️ B06)**: WF1(B04 지표면) 확정 성공 시 서버 백그라운드 태스크로 B05 기본 경로 계산·저장 ➡️ B06 일괄 횡단 설계를 연속 실행하여 대시보드/B05 진입 시 로딩 상태를 즉시 제공합니다.
|
||||
* **B05/B06 자유 이동 및 동시 확정**: B06 전체 확정 시 stage 2와 3을 함께 COMPLETE 처리하고 B07 임시 셸로 이동한다.
|
||||
* **B04 재확정 사용자 설정 이월 (`B03_FileInput_Service_Chain.py`)**: `run_redesign_chain`을 통해 B04 지표면이 재확정되어도 B05 사용자 제어점/경사 파라미터 및 B06 측점별 단면 설계를 이월하여 새 경로에 매칭 재계산 후 확정 전이시킵니다.
|
||||
|
||||
## 공통 유틸 `common_util/common_util_workflow_state.py`
|
||||
| 함수 | 역할 |
|
||||
|---|---|
|
||||
| `initialize_project_stages(cursor, project_id)` | 프로젝트 생성 시 7행 NOT_STARTED 시드 |
|
||||
| `start_stage(cursor, project_id, stage_no, params)` | IN_PROGRESS 전이 + N+1~6의 COMPLETE를 STALE로 전파 + `projects.status` 캐시 갱신 |
|
||||
| `complete_stage(cursor, project_id, stage_no)` | COMPLETE 전이 (stage 6 완료 시 `projects.status='DONE'`) |
|
||||
| `fail_stage(cursor, project_id, stage_no, message)` | FAILED 전이 |
|
||||
| `update_stage_progress(cursor, project_id, stage_no, progress)` | 진행률만 갱신 |
|
||||
| `get_workflow_state(cursor, project_id)` | 단건 조회, `current_stage` 계산 포함 |
|
||||
| `reset_stages_after_input_change(cursor, project_id)` | B03 입력 변경 시 stage 1~6을 NOT_STARTED로 초기화 |
|
||||
|
||||
## 무효화의 실제 범위
|
||||
|
||||
| 처리 | 범위 |
|
||||
|---|---|
|
||||
| `start_stage()` | 뒤쪽 단계 중 `COMPLETE`만 `STALE`로 변경 |
|
||||
| 공통 상태 유틸 | 단계 산출 파일·캐시를 삭제하지 않음 |
|
||||
| 산출물 정리 | B03/B04/B05/B08 등 단계별 로직에 의존 |
|
||||
| `workflow.json` | 초기 파일과 일부 호환 용도; DB workflow의 SSOT가 아님 |
|
||||
|
||||
## 조회 API
|
||||
`GET /api/projects/{project_id}/workflow-state`
|
||||
|
||||
## 프론트엔드 게이팅 및 스텝바 연동
|
||||
* **스텝바 일원화**: `createStepBar` 컴포넌트(`ui_template_workflow_layout.ts`)를 승격하여 B01 및 B03~B09에서 통합 관리.
|
||||
* **게이팅 규칙**: B06 확정 후 B07로 이동한다. B07은 산출물 검사 없이 stage 4를 완료 처리하는 임시 우회다.
|
||||
* **네비게이션**: `b_workflow_nav.ts` 모듈을 통해 `fetchWorkflowState`, `goToWorkflowStage` 공통 헬퍼 이용.
|
||||
@@ -0,0 +1,74 @@
|
||||
---
|
||||
type: index
|
||||
status: stable
|
||||
last_updated: 2026-09-09
|
||||
---
|
||||
|
||||
# Wiki Index
|
||||
|
||||
> 코드 어시스턴트는 프로젝트 전체 질문이면 아키텍처 지도, 특정 구현 질문이면 해당 canonical 페이지부터 읽는다.
|
||||
|
||||
## 우선 진입점
|
||||
|
||||
- [[architecture/project_map|프로젝트 지도]] — 현재 A/B 페이지 책임, 레거시 명칭 alias, 질문별 탐색 순서.
|
||||
- [[architecture/workflow_data_flow|B01~B09 workflow 데이터 흐름]] — 생산·소비·상태 전이·정본 위치.
|
||||
- [[architecture/implementation_status|현재 구현 현황]] — 소스 읽기 감사 기준 구현·부분 구현·임시 우회·셸 구분.
|
||||
- [[architecture/shared_resources|공유 자원 영향 지도]] — DB·인증·저장소·공통 유틸·의존성 사용처.
|
||||
- [[architecture/public_admin_map|공개·인증·관리 영역 지도]] — A01~A09와 B01 진입 흐름.
|
||||
- [[ingest/index|인제스트 감사 원장]] — raw 180개의 명시적 근거와 계획·검증 대응 상태.
|
||||
|
||||
## 로그인 후 기능
|
||||
|
||||
- [[B01_Dashboard/B01_frontend|B01 Dashboard]] — 프로젝트·조직·사용자·임시보관·workflow 현황.
|
||||
- [[B02_ProjRegister/B02_backend|B02 Project Register]] — 프로젝트 생성, workflow 7단계 시드, 저장소 초기화.
|
||||
- [[B03_FileInput/B03_backend|B03 File Input]] — 업로드·WF1 실행과 [[las_free_sheet_surface|LAS 없는 도엽등고 설계]].
|
||||
- [[B03_FileInput/B03_FileInput_plan_lidar_multi_file|B03 다중 라이다]] — 병합 방식 결정까지 보류.
|
||||
- [[B04_PreProcess/B04_backend|B04 PreProcess]] — 지표면·GIS·도엽·배수유역 분석과 확정.
|
||||
- [[B05_Profile/B05_backend|B05 Profile]] — 경로·종단·배수와 [[B05_Profile/B05_structure_stations|구조물 측점 공급]].
|
||||
- [[B05_Profile/B05_completed_followups|B05 후속 완료]] · [[B05_Profile/B05_corridor_followup_decisions|3D 후속 판정]] · [[B05_Profile/B05_corridor_turn_correction_plan|급선회 계획]].
|
||||
- [[B05_Profile/B05_corridor_plan_curves|B05 구조물 3D 투영 커브]] — 평면·비탈 투영, 날개벽 연결과 성토면 절단.
|
||||
- [[B05_Profile/B05_corridor_cut_fill|B05 구조물 절취·성토 패치]] — 합집합 절취, 측벽, B06 구간별 성토 리본.
|
||||
- [[B05_Profile/B05_corridor_patch_finish|B05 변형 성토면 마감]] — 패치 스커트, 원지반 재노출, 세월교 날개 역클리핑.
|
||||
- [[B06_Section/B06_backend|B06 Section]] — 횡단·유토곡선·확정; [[B06_Section/B06_pavement_revetment|물넘이포장]], [[B06_Section/B06_revetment_link_controls|기슭막이 연동·경사·단별 제어]], [[B06_Section/B06_culvert_link_trim|인접 측점 트림]].
|
||||
- [[B07_DesignDetail/B07_frontend|B07 DesignDetail]] — 상세설계·CAD·도각·설계도면과 [[B07_DesignDetail/B07_standard_drawings_2026_09|구조물 표준도]] 관리.
|
||||
- [[B08_Quantity/B08_overview_2026_09|B08 Quantity]] — 토공·구조물·자재 수량산출과 B09 인계.
|
||||
- [[B08_DesignDetail/B08_CAD_commands|B08 CAD 명령]] · [[B08_DesignDetail/B08_CAD_blocks|블록]] · [[B08_DesignDetail/B08_CAD_table_entity|표]] · [[B08_DesignDetail/B08_CAD_title_block|도각·표제란]].
|
||||
- [[B08_DesignDetail/B08_CAD_usability_2026-09-01|B08 CAD 편의성]] — 편집 손실·확정 잠금·도면별 복구 구현 기록과 재검증 대기 상태.
|
||||
- [[B08_DesignDetail/B08_cross_structure_sheets|B08 횡단 장]] · [[B08_DesignDetail/B08_drawing_masshaul_watershed|토적·유역도]].
|
||||
- [[B09_Estimation/B09_overview_2026_09|B09 Estimation]] — 단가산출·예산내역·공사원가계산 5표 구현.
|
||||
- [[B10_Payment/B10_frontend|B10 Payment]] · [[B11_Status/B11_frontend|B11 Status]] — 결제·진행상태 목업.
|
||||
|
||||
## 로그인 전·관리
|
||||
|
||||
- [[A00_Common/A00_Common|A00 Common]] — App Shell·라우터·공통 UI.
|
||||
- [[A01_Home/A01_frontend|A01 Home]] · [[A02_ProgDetail/A02_frontend|A02 Program]] · [[A03_CompDetail/A03_frontend|A03 Company]].
|
||||
- [[A04_NewsHistory/A04_frontend|A04 News]] · [[A05_EduDetail/A05_frontend|A05 Education]].
|
||||
- [[A06_Login/A06_backend|A06 Login]] · [[A07_Register/A07_backend|A07 Register]].
|
||||
- [[A08_Support/A08_backend|A08 Support]] · [[A09_Security/A09_backend|A09 Security]].
|
||||
|
||||
## 공통 개념
|
||||
|
||||
- 구조·UI: [[a00_app_shell_framework]], [[ui_templates]], [[design]].
|
||||
- 2026-08-29 완료: [[completed_2026-08-29]] — B03 재업로드 재분석·B05 최신 조회, B05/B06 구조물 UI 통합, B07 CAD 고정 척도·횡단 장 배치 포함.
|
||||
- 2026-09-01 완료: [[completed_2026-09-01]] — B04 지면 필터·온디맨드 산출, B05/B06 최소고 선택과 레거시 기슭막이 이관.
|
||||
- 2026-09-01 추가 정리: [[completed_2026-09-01_followups]] — 혼합 섹션 잔여 완료 체크 37개와 B07 재검증 보류 구분.
|
||||
- 2026-09-02 완료: [[completed_2026-09-02]] — 용화 노선 트림·배관 정착, 보조 포트, CAD 후속과 스테일 테스트 정리.
|
||||
- 2026-09-03 완료: [[completed_2026-09-03]] — B03 정본·좌표계, B04 세부유역, B05/B06 유토곡선, B08 납품 CAD.
|
||||
- 2026-09-03 추가 완료: [[completed_2026-09-03_additional]] — B03 화면, B04/B05 나침반, 종단곡선, 횡단 계산·표기.
|
||||
- 2026-09-04 완료: [[completed_2026-09-04]] — B01 모달·로고, B03 미리보기, 공용 진행단계 패널, B05 3D·종단, B06 횡단, B08 도면, 700줄 제한 분리.
|
||||
- 2026-09-07 완료: [[completed_2026-09-07]] — 노선·캐시·B01~B07 기능, 성능 종료 기준과 보류 갈래.
|
||||
- 수량·원가 계약: [[quantity_cost_contract]] — B08 물량과 B09 금액의 책임·저장·금지 규칙.
|
||||
- 표준도·입력 미결: [[standard_drawing_cost_inputs]] — 자동 계산·사용자 입력·기준자료·미확보 경계.
|
||||
- 인증·상태: [[auth_rbac]], [[workflow_state]], [[temp_upload]].
|
||||
- 데이터·경로: [[db_schema/overview]], [[storage_paths]], [[crs_metadata]].
|
||||
- API·스키마·유틸: [[api_common]], [[schema_common]], [[common_util]].
|
||||
- 도메인 흐름: [[drainage_watershed]], [[mass_haul_diagram]].
|
||||
- 외부 자원: [[dependencies]], [[b07_external_webcad_demos]].
|
||||
- 근거 품질: [[law_source_quality]], [[db_schema/unconfirmed/README|미확정 DB]].
|
||||
|
||||
## 현재 주의사항
|
||||
|
||||
- 2026-08-08 검증 기준 현재 workflow는 B07=수량, B08=상세설계/CAD다. 이전 B07/B08 명칭은 [[architecture/project_map]]의 alias만 사용한다.
|
||||
- `draft` 페이지는 세부 사실의 독립 검증 근거가 부족한 문서다. 상위 stable 페이지와 raw 검증보고서를 함께 확인한다.
|
||||
- 2026-09-08 기준 B07=상세설계, B08=수량산출, B09=원가계산이다. 구 `B07_Quantity`·`B08_DesignDetail` 문서는 레거시 경로다.
|
||||
- 미확정 수치·DB 구조는 확정값으로 사용하지 않는다.
|
||||
@@ -0,0 +1,40 @@
|
||||
---
|
||||
type: ingest-register-index
|
||||
status: draft
|
||||
related_pages: ["[[index]]"]
|
||||
last_updated: 2026-09-04
|
||||
---
|
||||
|
||||
# 인제스트 감사 원장
|
||||
|
||||
> raw 원본의 존재, 대응 계획·검증 후보, 현재 위키의 명시적 source 흔적을 추적한다. 상태는 내용 감사를 거쳐 확정한다.
|
||||
|
||||
## 상태 정의
|
||||
|
||||
| 상태 | 의미 |
|
||||
|---|---|
|
||||
| `referenced` | 현재 위키 또는 log에 파일명이 명시되어 있음. 내용 완전 반영 여부는 별도 감사 필요 |
|
||||
| `covered_by_verified_pair` | 계획서와 정확히 대응하는 검증보고서가 위키 근거로 명시되어 최신 검증 결과가 우선 반영됨 |
|
||||
| `covered_by_plan_reference` | 검증보고서의 대응 계획서가 위키에 명시되어 있으나 검증 결과 직접 연결은 추가 확인 필요 |
|
||||
| `verification_exists_untraced` | 대응 검증보고서는 있으나 계획서 파일명의 명시적 반영 흔적 없음 |
|
||||
| `plan_exists_untraced` | 대응 계획서는 있으나 검증보고서 파일명의 명시적 반영 흔적 없음 |
|
||||
| `plan_only` | 자동 매칭되는 검증보고서를 찾지 못한 계획서 |
|
||||
| `verification_only_untraced` | 자동 매칭되는 계획서를 찾지 못했고 명시적 반영 흔적도 없는 검증보고서 |
|
||||
|
||||
## 원장 페이지
|
||||
|
||||
- [[ingest/plan_2026_07]]
|
||||
- [[ingest/plan_2026_08]]
|
||||
- [[ingest/plan_undated]]
|
||||
- [[ingest/verification_2026_07]]
|
||||
- [[ingest/verification_2026_08]]
|
||||
- [[ingest/plan_2026_09]]
|
||||
- [[ingest/verification_2026_09]]
|
||||
|
||||
## 1차 집계
|
||||
|
||||
| 감사 상태 | 개수 |
|
||||
|---|---:|
|
||||
| `covered_by_verified_pair` | 59 |
|
||||
| `referenced` | 160 |
|
||||
| **합계** | **219** |
|
||||
@@ -0,0 +1,68 @@
|
||||
---
|
||||
type: ingest-register
|
||||
status: draft
|
||||
related_pages: ["[[ingest/index]]"]
|
||||
last_updated: 2026-08-16
|
||||
---
|
||||
|
||||
# 계획서 인제스트 원장 — 2026-07
|
||||
|
||||
> 이 표는 파일명과 현재 위키의 명시적 source 흔적을 대조한 1차 감사 결과다. `referenced`는 완전 반영을 보증하지 않는다.
|
||||
|
||||
| raw 파일 | 대응 문서 후보 | 위키 명시 참조 | 감사 상태 |
|
||||
|---|---|---:|---|
|
||||
| [2026-07-17_plan_B04_contour.md](../../raw/plans/2026-07-17_plan_B04_contour.md) | 2026-07-17_verify_B04_contour.md | 0 | `covered_by_verified_pair` |
|
||||
| [2026-07-17_plan_b04_defects.md](../../raw/plans/2026-07-17_plan_b04_defects.md) | 2026-07-17_verify_b04_defects.md | 1 | `referenced` |
|
||||
| [2026-07-17_plan_B04_Surface_Reorganization.md](../../raw/plans/2026-07-17_plan_B04_Surface_Reorganization.md) | 2026-07-17_verify_B04_Surface_Reorganization.md | 0 | `covered_by_verified_pair` |
|
||||
| [2026-07-18_plan_b04_confirm_b05_rebuild.md](../../raw/plans/2026-07-18_plan_b04_confirm_b05_rebuild.md) | 2026-07-18_verify_b04_confirm_b05_rebuild.md | 0 | `covered_by_verified_pair` |
|
||||
| [2026-07-18_plan_B04_old_align.md](../../raw/plans/2026-07-18_plan_B04_old_align.md) | 2026-07-18_verify_B04_old_align.md | 0 | `covered_by_verified_pair` |
|
||||
| [2026-07-18_plan_B06_DrawingRendering.md](../../raw/plans/2026-07-18_plan_B06_DrawingRendering.md) | 2026-07-18_verify_B06_DrawingRendering.md | 0 | `covered_by_verified_pair` |
|
||||
| [2026-07-18_plan_B06_ProfileCross.md](../../raw/plans/2026-07-18_plan_B06_ProfileCross.md) | 2026-07-18_verify_B06_ProfileCross.md | 0 | `covered_by_verified_pair` |
|
||||
| [2026-07-18_plan_crs_normalization.md](../../raw/plans/2026-07-18_plan_crs_normalization.md) | - | 2 | `referenced` |
|
||||
| [2026-07-18_plan_dependency_upgrade.md](../../raw/plans/2026-07-18_plan_dependency_upgrade.md) | - | 1 | `referenced` |
|
||||
| [2026-07-18_plan_layout_improvement.md](../../raw/plans/2026-07-18_plan_layout_improvement.md) | 2026-07-18_verify_layout_improvement.md | 0 | `covered_by_verified_pair` |
|
||||
| [2026-07-19_plan_b04_gis_theme.md](../../raw/plans/2026-07-19_plan_b04_gis_theme.md) | 2026-07-19_verify_b04_gis_theme.md | 0 | `covered_by_verified_pair` |
|
||||
| [2026-07-19_plan_B05_B06_improvements.md](../../raw/plans/2026-07-19_plan_B05_B06_improvements.md) | 2026-07-19_verify_B05_B06_improvements.md | 0 | `covered_by_verified_pair` |
|
||||
| [2026-07-19_plan_B05_B06_UI_Station_Improvement.md](../../raw/plans/2026-07-19_plan_B05_B06_UI_Station_Improvement.md) | 2026-07-19_verify_B05_B06_UI_Station_Improvement.md | 0 | `covered_by_verified_pair` |
|
||||
| [2026-07-19_plan_B05_B06_차트_레이아웃_후속보정.md](../../raw/plans/2026-07-19_plan_B05_B06_차트_레이아웃_후속보정.md) | 2026-07-19_verify_B05_B06_차트_레이아웃_후속보정.md | 0 | `covered_by_verified_pair` |
|
||||
| [2026-07-19_plan_b05_dark_theme.md](../../raw/plans/2026-07-19_plan_b05_dark_theme.md) | 2026-07-19_verify_b05_dark_theme.md | 0 | `covered_by_verified_pair` |
|
||||
| [2026-07-19_plan_B06_사이드바_버튼_폭_및_확정_후_B07_이동.md](../../raw/plans/2026-07-19_plan_B06_사이드바_버튼_폭_및_확정_후_B07_이동.md) | 2026-07-19_verify_B06_사이드바_버튼_폭_및_확정_후_B07_이동.md | 0 | `covered_by_verified_pair` |
|
||||
| [2026-07-19_plan_B07_DesignDetail.md](../../raw/plans/2026-07-19_plan_B07_DesignDetail.md) | 2026-07-19_verify_B07_DesignDetail.md | 0 | `covered_by_verified_pair` |
|
||||
| [2026-07-19_plan_b07_external_webcad_demos.md](../../raw/plans/2026-07-19_plan_b07_external_webcad_demos.md) | 2026-07-19_verify_b07_external_webcad_demos.md | 1 | `referenced` |
|
||||
| [2026-07-19_plan_b07_independent_cad.md](../../raw/plans/2026-07-19_plan_b07_independent_cad.md) | 2026-07-19_verify_b07_independent_cad.md | 0 | `covered_by_verified_pair` |
|
||||
| [2026-07-19_plan_CrossPruning_and_CADStyle.md](../../raw/plans/2026-07-19_plan_CrossPruning_and_CADStyle.md) | 2026-07-19_verify_CrossPruning_and_CADStyle.md | 0 | `covered_by_verified_pair` |
|
||||
| [2026-07-19_plan_half_width_persistence.md](../../raw/plans/2026-07-19_plan_half_width_persistence.md) | 2026-07-19_verify_half_width_persistence.md | 0 | `covered_by_verified_pair` |
|
||||
| [2026-07-19_plan_responsive_layout_drag.md](../../raw/plans/2026-07-19_plan_responsive_layout_drag.md) | 2026-07-19_verify_responsive_layout_drag.md | 0 | `covered_by_verified_pair` |
|
||||
| [2026-07-19_plan_scrollbar_theme.md](../../raw/plans/2026-07-19_plan_scrollbar_theme.md) | 2026-07-19_verify_scrollbar_theme.md | 0 | `covered_by_verified_pair` |
|
||||
| [2026-07-19_plan_종횡단_생성_B05_이관.md](../../raw/plans/2026-07-19_plan_종횡단_생성_B05_이관.md) | 2026-07-19_verify_종횡단_생성_B05_이관.md | 0 | `covered_by_verified_pair` |
|
||||
| [2026-07-19_plan_종횡단_이슈수정_3건.md](../../raw/plans/2026-07-19_plan_종횡단_이슈수정_3건.md) | 2026-07-19_verify_종횡단_이슈수정_3건.md | 0 | `covered_by_verified_pair` |
|
||||
| [2026-07-20_plan_B05_longitudinal_grade_line.md](../../raw/plans/2026-07-20_plan_B05_longitudinal_grade_line.md) | 2026-07-20_verify_B05_longitudinal_grade_line.md | 0 | `covered_by_verified_pair` |
|
||||
| [2026-07-20_plan_B06_profile_cross_design_elevation.md](../../raw/plans/2026-07-20_plan_B06_profile_cross_design_elevation.md) | 2026-07-20_verify_B06_profile_cross_design_elevation.md | 1 | `referenced` |
|
||||
| [2026-07-20_plan_B07_상세설계개선.md](../../raw/plans/2026-07-20_plan_B07_상세설계개선.md) | 2026-07-20_verify_B07_상세설계개선.md | 0 | `covered_by_verified_pair` |
|
||||
| [2026-07-20_plan_b08_quantity_template.md](../../raw/plans/2026-07-20_plan_b08_quantity_template.md) | 2026-07-20_verify_b08_quantity_template.md | 0 | `covered_by_verified_pair` |
|
||||
| [2026-07-21_plan_B06_default_design_B07_gating.md](../../raw/plans/2026-07-21_plan_B06_default_design_B07_gating.md) | 2026-07-21_verify_B06_default_design_B07_gating.md | 1 | `referenced` |
|
||||
| [2026-07-21_plan_B06_ground_section_type_B07_linkage.md](../../raw/plans/2026-07-21_plan_B06_ground_section_type_B07_linkage.md) | 2026-07-21_verify_B06_ground_section_type_B07_linkage.md | 1 | `referenced` |
|
||||
| [2026-07-22_plan_B06_B07.md](../../raw/plans/2026-07-22_plan_B06_B07.md) | 2026-07-22_verify_B06_B07.md | 1 | `referenced` |
|
||||
| [2026-07-23_plan_B05_종단_계획선_편집_체계_개편.md](../../raw/plans/2026-07-23_plan_B05_종단_계획선_편집_체계_개편.md) | 2026-07-23_verify_B05_종단_계획선_편집_체계_개편.md | 1 | `referenced` |
|
||||
| [2026-07-24_plan_B05_B06_표준횡단.md](../../raw/plans/2026-07-24_plan_B05_B06_표준횡단.md) | 2026-07-24_verify_B05_B06_표준횡단.md | 0 | `covered_by_verified_pair` |
|
||||
| [2026-07-24_plan_B05_irregular_stations.md](../../raw/plans/2026-07-24_plan_B05_irregular_stations.md) | 2026-07-24_verify_B05_irregular_stations.md | 0 | `covered_by_verified_pair` |
|
||||
| [2026-07-24_plan_B05_layout_refinements.md](../../raw/plans/2026-07-24_plan_B05_layout_refinements.md) | 2026-07-24_verify_B05_layout_refinements.md | 0 | `covered_by_verified_pair` |
|
||||
| [2026-07-24_plan_B05_layout_refinements_2.md](../../raw/plans/2026-07-24_plan_B05_layout_refinements_2.md) | 2026-07-24_verify_B05_layout_refinements_2.md | 0 | `covered_by_verified_pair` |
|
||||
| [2026-07-24_plan_b05_reorganization.md](../../raw/plans/2026-07-24_plan_b05_reorganization.md) | 2026-07-24_verify_b05_reorganization.md | 1 | `referenced` |
|
||||
| [2026-07-24_plan_B05_Route_Improvements.md](../../raw/plans/2026-07-24_plan_B05_Route_Improvements.md) | 2026-07-24_verify_B05_Route_Improvements.md | 1 | `referenced` |
|
||||
| [2026-07-24_유토곡선_분석_및_웹앱_계산명세.md](../../raw/plans/2026-07-24_유토곡선_분석_및_웹앱_계산명세.md) | - | 4 | `referenced` |
|
||||
| [2026-07-25_plan_b05_b06_3rd_4th_improvements.md](../../raw/plans/2026-07-25_plan_b05_b06_3rd_4th_improvements.md) | 2026-07-25_verify_b05_b06_3rd_4th_improvements.md | 1 | `referenced` |
|
||||
| [2026-07-25_plan_b05_b06_modifications.md](../../raw/plans/2026-07-25_plan_b05_b06_modifications.md) | 2026-07-25_verify_b05_b06_modifications.md | 1 | `referenced` |
|
||||
| [2026-07-25_plan_b06_2nd_improvements.md](../../raw/plans/2026-07-25_plan_b06_2nd_improvements.md) | 2026-07-25_verify_b06_2nd_improvements.md | 1 | `referenced` |
|
||||
| [2026-07-25_plan_b06_n6_n7.md](../../raw/plans/2026-07-25_plan_b06_n6_n7.md) | 2026-07-25_verify_b06_n6_n7.md | 1 | `referenced` |
|
||||
| [2026-07-25_plan_b07_design_detail.md](../../raw/plans/2026-07-25_plan_b07_design_detail.md) | 2026-07-25_verify_b07_design_detail.md | 1 | `referenced` |
|
||||
| [2026-07-25_plan_b08_rebuild.md](../../raw/plans/2026-07-25_plan_b08_rebuild.md) | 2026-07-25_verify_b08_rebuild.md | 1 | `referenced` |
|
||||
| [2026-07-25_plan_n2_n3_n4.md](../../raw/plans/2026-07-25_plan_n2_n3_n4.md) | 2026-07-25_verify_n2_n3_n4.md | 1 | `referenced` |
|
||||
| [2026-07-26_plan_b06_aesthetics.md](../../raw/plans/2026-07-26_plan_b06_aesthetics.md) | 2026-07-26_verify_b06_aesthetics.md | 1 | `referenced` |
|
||||
| [2026-07-26_plan_B07_도면_템플릿_및_도각_적용.md](../../raw/plans/2026-07-26_plan_B07_도면_템플릿_및_도각_적용.md) | 2026-07-26_verify_B07_도면_템플릿_및_도각_적용.md | 1 | `referenced` |
|
||||
| [2026-07-26_plan_openwebcad_성능개선.md](../../raw/plans/2026-07-26_plan_openwebcad_성능개선.md) | 2026-07-26_verify_openwebcad_성능개선.md | 1 | `referenced` |
|
||||
| [2026-07-26_plan_도엽_오버레이.md](../../raw/plans/2026-07-26_plan_도엽_오버레이.md) | 2026-07-26_verify_도엽_오버레이.md | 2 | `referenced` |
|
||||
| [2026-07-28_plan_B04_B05_Drainage_Watershed.md](../../raw/plans/2026-07-28_plan_B04_B05_Drainage_Watershed.md) | 2026-07-28_verify_B04_B05_Drainage_Watershed.md | 1 | `referenced` |
|
||||
| [2026-07-28_plan_B04_Map_Performance.md](../../raw/plans/2026-07-28_plan_B04_Map_Performance.md) | 2026-07-28_verify_B04_Map_Performance.md | 1 | `referenced` |
|
||||
| [2026-07-31_plan_B03_planned_route_csv.md](../../raw/plans/2026-07-31_plan_B03_planned_route_csv.md) | 2026-07-31_verify_B03_planned_route_csv.md | 1 | `referenced` |
|
||||
| [2026-07-31_plan_B05_drainage_watershed_pipe_edit.md](../../raw/plans/2026-07-31_plan_B05_drainage_watershed_pipe_edit.md) | 2026-07-31_verify_B05_drainage_watershed_pipe_edit.md | 1 | `referenced` |
|
||||
@@ -0,0 +1,67 @@
|
||||
---
|
||||
type: ingest-register
|
||||
status: draft
|
||||
related_pages: ["[[ingest/index]]"]
|
||||
last_updated: 2026-08-30
|
||||
---
|
||||
|
||||
# 계획서 인제스트 원장 — 2026-08
|
||||
|
||||
> 이 표는 파일명과 현재 위키의 명시적 source 흔적을 대조한 1차 감사 결과다. `referenced`는 완전 반영을 보증하지 않는다.
|
||||
|
||||
| raw 파일 | 대응 문서 후보 | 위키 명시 참조 | 감사 상태 |
|
||||
|---|---|---|---|
|
||||
| `2026-08-30_plan_B05_B06_ui_fixes.md` | B05/B06 UI | yes | ingested |
|
||||
| `2026-08-30_plan_B08_CAD_commands.md` | B08 CAD 명령 | yes | ingested |
|
||||
| `2026-08-30_plan_B08_masshaul_watershed_drawings.md` | B08 토적도·유역도 | yes | ingested |
|
||||
| `2026-08-30_plan_B08_cross_structure_sheets.md` | B08 횡단 구조물·장 배치 | yes | ingested |
|
||||
| `2026-08-30_plan_las_free_sheet_surface.md` | B03~B06 LAS 없는 설계 | yes | ingested |
|
||||
| `2026-08-30_plan_B08_CAD_blocks_interaction_tables.md` | B08 블록·조작·표 | yes | ingested |
|
||||
|
||||
| raw 파일 | 대응 문서 후보 | 위키 명시 참조 | 감사 상태 |
|
||||
|---|---|---:|---|
|
||||
| [2026-08-01_plan_B04_B05_drainage_ui_improvements.md](../../raw/plans/2026-08-01_plan_B04_B05_drainage_ui_improvements.md) | 2026-08-01_verify_B04_B05_drainage_ui_improvements.md | 1 | `referenced` |
|
||||
| [2026-08-01_plan_B04_detailed_basins.md](../../raw/plans/2026-08-01_plan_B04_detailed_basins.md) | 2026-08-01_verify_B04_detailed_basins.md | 1 | `referenced` |
|
||||
| [2026-08-01_plan_B04_inflow_strength_and_panel_cleanup.md](../../raw/plans/2026-08-01_plan_B04_inflow_strength_and_panel_cleanup.md) | 2026-08-01_verify_B04_inflow_strength_and_panel_cleanup.md | 0 | `covered_by_verified_pair` |
|
||||
| [2026-08-01_plan_S8_B05_data_saving.md](../../raw/plans/2026-08-01_plan_S8_B05_data_saving.md) | 2026-08-01_verify_S8_B05_data_saving.md | 0 | `covered_by_verified_pair` |
|
||||
| [2026-08-01_plan_ui_improvements_4_types.md](../../raw/plans/2026-08-01_plan_ui_improvements_4_types.md) | 2026-08-01_verify_ui_improvements_4_types.md | 0 | `covered_by_verified_pair` |
|
||||
| [2026-08-02_plan_B04_B05_drainage_unification.md](../../raw/plans/2026-08-02_plan_B04_B05_drainage_unification.md) | 2026-08-02_verify_B04_B05_drainage_unification.md | 1 | `referenced` |
|
||||
| [2026-08-02_plan_backlog_reorg.md](../../raw/plans/2026-08-02_plan_backlog_reorg.md) | 2026-08-02_verify_backlog_reorg.md | 0 | `covered_by_verified_pair` |
|
||||
| [2026-08-02_plan_mass_haul_and_drainage_fixes.md](../../raw/plans/2026-08-02_plan_mass_haul_and_drainage_fixes.md) | 2026-08-02_verify_mass_haul_and_drainage_fixes.md | 1 | `referenced` |
|
||||
| [2026-08-02_plan_mass_haul_distribution_and_refinements.md](../../raw/plans/2026-08-02_plan_mass_haul_distribution_and_refinements.md) | 2026-08-02_verify_mass_haul_distribution_and_refinements.md | 0 | `covered_by_verified_pair` |
|
||||
| [2026-08-02_plan_mass_haul_multi_curve.md](../../raw/plans/2026-08-02_plan_mass_haul_multi_curve.md) | 2026-08-02_verify_mass_haul_multi_curve.md | 1 | `referenced` |
|
||||
| [2026-08-02_plan_panel_fold_B05_style.md](../../raw/plans/2026-08-02_plan_panel_fold_B05_style.md) | 2026-08-02_verify_panel_fold_B05_style.md | 0 | `covered_by_verified_pair` |
|
||||
| [2026-08-02_plan_panel_height_first_render.md](../../raw/plans/2026-08-02_plan_panel_height_first_render.md) | 2026-08-02_verify_panel_height_first_render.md | 0 | `covered_by_verified_pair` |
|
||||
| [2026-08-02_plan_ui_template_locale_split.md](../../raw/plans/2026-08-02_plan_ui_template_locale_split.md) | 2026-08-02_verify_ui_template_locale_split.md | 1 | `referenced` |
|
||||
| [2026-08-02_유토곡선_3공구_분석.md](../../raw/plans/2026-08-02_유토곡선_3공구_분석.md) | - | 2 | `referenced` |
|
||||
| [2026-08-03_plan_B05_mass_haul_transfer.md](../../raw/plans/2026-08-03_plan_B05_mass_haul_transfer.md) | 2026-08-03_verify_B05_mass_haul_transfer.md | 1 | `referenced` |
|
||||
| [2026-08-03_plan_향후작업_반영완료.md](../../raw/plans/2026-08-03_plan_향후작업_반영완료.md) | 2026-08-03_verify_향후작업_반영완료.md | 1 | `referenced` |
|
||||
| [2026-08-03_plan_후속작업_주의사항.md](../../raw/plans/2026-08-03_plan_후속작업_주의사항.md) | 2026-08-03_verify_후속작업_주의사항.md | 1 | `referenced` |
|
||||
| [2026-08-04_plan_b05_b06_profile_ui_chain.md](../../raw/plans/2026-08-04_plan_b05_b06_profile_ui_chain.md) | 2026-08-04_verify_b05_b06_profile_ui_chain.md | 1 | `referenced` |
|
||||
| [2026-08-04_plan_mass_haul_spoil_scroll.md](../../raw/plans/2026-08-04_plan_mass_haul_spoil_scroll.md) | 2026-08-04_verify_mass_haul_spoil_scroll.md | 2 | `referenced` |
|
||||
| [2026-08-05_plan_b04_b05_drainage_rainfall_structure.md](../../raw/plans/2026-08-05_plan_b04_b05_drainage_rainfall_structure.md) | 2026-08-05_verify_b04_b05_drainage_rainfall_structure.md | 1 | `referenced` |
|
||||
| [2026-08-06_plan_B05_B06_feature_updates.md](../../raw/plans/2026-08-06_plan_B05_B06_feature_updates.md) | 2026-08-06_verify_B05_B06_feature_updates.md | 1 | `referenced` |
|
||||
| [2026-08-06_plan_B05_bottom_panel_resize_bug.md](../../raw/plans/2026-08-06_plan_B05_bottom_panel_resize_bug.md) | 2026-08-06_verify_B05_bottom_panel_resize_bug.md | 1 | `referenced` |
|
||||
| [2026-08-06_plan_B05_main_panel_resize_proportional.md](../../raw/plans/2026-08-06_plan_B05_main_panel_resize_proportional.md) | 2026-08-06_verify_B05_main_panel_resize_proportional.md | 1 | `referenced` |
|
||||
| [2026-08-08_plan_B05_B06_fixes.md](../../raw/plans/2026-08-08_plan_B05_B06_fixes.md) | 2026-08-08_verify_B05_B06_fixes.md | 0 | `covered_by_verified_pair` |
|
||||
| [2026-08-08_plan_dashboard_scroll_limit.md](../../raw/plans/2026-08-08_plan_dashboard_scroll_limit.md) | 2026-08-08_verify_dashboard_scroll_limit.md | 0 | `covered_by_verified_pair` |
|
||||
| [2026-08-08_plan_db_initialization.md](../../raw/plans/2026-08-08_plan_db_initialization.md) | 2026-08-08_verify_db_initialization.md | 0 | `covered_by_verified_pair` |
|
||||
| [2026-08-08_plan_project_delete_hard.md](../../raw/plans/2026-08-08_plan_project_delete_hard.md) | 2026-08-08_verify_project_delete_hard.md | 0 | `covered_by_verified_pair` |
|
||||
| [2026-08-08_plan_R1_R2_features.md](../../raw/plans/2026-08-08_plan_R1_R2_features.md) | 2026-08-08_verify_R1_R2_features.md | 0 | `covered_by_verified_pair` |
|
||||
| [2026-08-08_plan_server_and_e2e_fixes.md](../../raw/plans/2026-08-08_plan_server_and_e2e_fixes.md) | 2026-08-08_verify_server_and_e2e_fixes.md | 0 | `covered_by_verified_pair` |
|
||||
| [2026-08-13_plan_rainfall_wamis_station.md](../../raw/plans/2026-08-13_plan_rainfall_wamis_station.md) | 2026-08-13_verify_rainfall_wamis_station.md | 0 | `covered_by_verified_pair` |
|
||||
| [2026-08-16_plan_B05_구조물_수동추가.md](../../raw/plans/2026-08-16_plan_B05_구조물_수동추가.md) | 2026-08-16_verify_B05_구조물_수동추가_교차검증.md | 1 | `referenced` |
|
||||
| [2026-08-17_plan_B04_등고선_추출_가속.md](../../raw/plans/2026-08-17_plan_B04_등고선_추출_가속.md) | 2026-08-17_verify_B04_등고선_추출_가속_교차검증.md | 1 | `referenced` |
|
||||
| [2026-08-17_plan_B05_structure_options_profile_marks.md](../../raw/plans/2026-08-17_plan_B05_structure_options_profile_marks.md) | 사용자·타 AI 검증 확인(별도 보고서 생략) | 2 | `referenced` |
|
||||
| [2026-08-17_plan_B05_box_ui_recommendations.md](../../raw/plans/2026-08-17_plan_B05_box_ui_recommendations.md) | 2026-08-17_verify_B05_box_ui_recommendations_external.md | 3 | `referenced` |
|
||||
| [2026-08-18_plan_B05_sidebar_ui_page_improvements.md](../../raw/plans/2026-08-18_plan_B05_sidebar_ui_page_improvements.md) | 사용자 확인·자체검증 기록(별도 보고서 생략) | 2 | `referenced` |
|
||||
| [2026-08-20_plan_B06_배수관_횡단도_세트.md](../../raw/plans/2026-08-20_plan_B06_배수관_횡단도_세트.md) | 2026-08-20_verify_B06_배수관_횡단도_세트_자체검증근거.md | 5 | `referenced` |
|
||||
| [2026-08-22_plan_B06_배수관_구조물_기하_조작_체계.md](../../raw/plans/2026-08-22_plan_B06_배수관_구조물_기하_조작_체계.md) | 2026-08-22_verify_B06_배수관_구조물_기하_조작_체계_자체검증근거.md | 3 | `referenced` |
|
||||
| [2026-08-27_plan_B05_B06_구조물_3D_절취_패치.md](../../raw/plans/2026-08-27_plan_B05_B06_구조물_3D_절취_패치.md) | 2026-08-27_verify_B05_B06_구조물_3D_절취_패치_교차검증.md | 4 | `referenced` |
|
||||
| [2026-08-27_plan_B05_변형성토면_마감_날개패치.md](../../raw/plans/2026-08-27_plan_B05_변형성토면_마감_날개패치.md) | 2026-08-27_verify_B05_변형성토면_마감_날개패치_교차검증.md | 3 | `referenced` |
|
||||
| [2026-08-28_plan_B05_구조물측점_단일공급자.md](../../raw/plans/2026-08-28_plan_B05_구조물측점_단일공급자.md) | 2026-08-28_verify_B05_구조물측점_단일공급자.md | 2 | `covered_by_verified_pair` |
|
||||
| [2026-08-28_plan_B05_B06_물넘이포장_독립기슭막이.md](../../raw/plans/2026-08-28_plan_B05_B06_물넘이포장_독립기슭막이.md) | 2026-08-28_verify_B05_B06_물넘이포장_독립기슭막이.md | 2 | `covered_by_verified_pair` |
|
||||
| [2026-08-28_plan_B05_구조물_3D_후속판정.md](../../raw/plans/2026-08-28_plan_B05_구조물_3D_후속판정.md) | 2026-08-28_verify_B05_구조물_3D_후속판정.md | 2 | `covered_by_verified_pair` |
|
||||
| [2026-08-28_plan_B05_후속완료_정리.md](../../raw/plans/2026-08-28_plan_B05_후속완료_정리.md) | 2026-08-28_verify_B05_후속완료_정리.md | 2 | `covered_by_verified_pair` |
|
||||
| [2026-08-29_plan_B05_B06_structure_ui_unification.md](../../raw/plans/2026-08-29_plan_B05_B06_structure_ui_unification.md) | 2026-08-29_verify_B05_B06_structure_ui_unification.md | 1 | `covered_by_verified_pair` |
|
||||
| [2026-08-29_plan_B07_CAD_scale_sheet_layout.md](../../raw/plans/2026-08-29_plan_B07_CAD_scale_sheet_layout.md) | 2026-08-29_verify_B07_CAD_scale_sheet_layout.md | 1 | `covered_by_verified_pair` |
|
||||
@@ -0,0 +1,20 @@
|
||||
---
|
||||
type: ingest-register
|
||||
status: stable
|
||||
related_pages: ["[[ingest/index]]", "[[completed_2026-09-01]]", "[[completed_2026-09-03]]", "[[completed_2026-09-03_additional]]", "[[completed_2026-09-04]]"]
|
||||
last_updated: 2026-09-04
|
||||
---
|
||||
|
||||
# 2026-09 계획 인제스트
|
||||
|
||||
| 원본 | 상태 | 반영 위치 |
|
||||
|---|---|---|
|
||||
| `docs/raw/plans/2026-09-01_plan_B04_B05_B06_completed_work.md` | `covered_by_verified_pair` | [[completed_2026-09-01]] |
|
||||
| `docs/raw/plans/2026-09-01_plan_remaining_checked_items.md` | `covered_by_verified_pair` | [[completed_2026-09-01_followups]] |
|
||||
| `docs/raw/plans/2026-09-03_plan_completed_items.md` | `referenced` | [[completed_2026-09-03]] 및 B03·B04·B05·B06·B08 상세 페이지 |
|
||||
| `docs/raw/plans/2026-09-03_plan_completed_items_2.md` | `referenced` | [[completed_2026-09-03_additional]] 및 B03·B04·B05·B06 상세 페이지 |
|
||||
| `docs/raw/plans/2026-09-04_plan_user_verified_completed_items.md` | `referenced` | [[completed_2026-09-04]] 및 관련 B01·B03·B04·B05·B06·B08 페이지 |
|
||||
| `docs/raw/plans/2026-09-04_plan_completed_items.md` | `referenced_user_verification_waived` | [[completed_2026-09-04]] |
|
||||
| `docs/raw/plans/2026-09-04_plan_700line_split.md` | `referenced_user_verification_waived` | [[completed_2026-09-04]] |
|
||||
| `docs/raw/plans/2026-09-04_plan_dead_code_cleanup_parked.md` | `parked_not_started` | 위키 완료 범위 제외 |
|
||||
| `docs/raw/plans/2026-09-04_plan_snapshot_before_cleanup.md` | `referenced_completed_with_open_items_carried_forward` | [[completed_2026-09-04]]; 미완료 21건은 `docs/raw/PLAN.md` 유지 |
|
||||
@@ -0,0 +1,14 @@
|
||||
---
|
||||
type: ingest-register
|
||||
status: draft
|
||||
related_pages: ["[[ingest/index]]"]
|
||||
last_updated: 2026-08-16
|
||||
---
|
||||
|
||||
# 계획서 인제스트 원장 — undated
|
||||
|
||||
> 이 표는 파일명과 현재 위키의 명시적 source 흔적을 대조한 1차 감사 결과다. `referenced`는 완전 반영을 보증하지 않는다.
|
||||
|
||||
| raw 파일 | 대응 문서 후보 | 위키 명시 참조 | 감사 상태 |
|
||||
|---|---|---:|---|
|
||||
| [plan_workflow_state_management.md](../../raw/plans/plan_workflow_state_management.md) | - | 3 | `referenced` |
|
||||
@@ -0,0 +1,75 @@
|
||||
---
|
||||
type: ingest-register
|
||||
status: draft
|
||||
related_pages: ["[[ingest/index]]"]
|
||||
last_updated: 2026-08-16
|
||||
---
|
||||
|
||||
# 검증보고서 인제스트 원장 — 2026-07
|
||||
|
||||
> 이 표는 파일명과 현재 위키의 명시적 source 흔적을 대조한 1차 감사 결과다. `referenced`는 완전 반영을 보증하지 않는다.
|
||||
|
||||
| raw 파일 | 대응 문서 후보 | 위키 명시 참조 | 감사 상태 |
|
||||
|---|---|---:|---|
|
||||
| [2026-07-12_verify_add_phase4_role.md](../../raw/verification/2026-07-12_verify_add_phase4_role.md) | - | 3 | `referenced` |
|
||||
| [2026-07-16_verify_인증주기개선.md](../../raw/verification/2026-07-16_verify_인증주기개선.md) | - | 1 | `referenced` |
|
||||
| [2026-07-17_verify_auth_reverify.md](../../raw/verification/2026-07-17_verify_auth_reverify.md) | - | 6 | `referenced` |
|
||||
| [2026-07-17_verify_b04_confirm_and_2d_map.md](../../raw/verification/2026-07-17_verify_b04_confirm_and_2d_map.md) | - | 1 | `referenced` |
|
||||
| [2026-07-17_verify_B04_contour.md](../../raw/verification/2026-07-17_verify_B04_contour.md) | 2026-07-17_plan_B04_contour.md | 2 | `referenced` |
|
||||
| [2026-07-17_verify_b04_defects.md](../../raw/verification/2026-07-17_verify_b04_defects.md) | 2026-07-17_plan_b04_defects.md | 1 | `referenced` |
|
||||
| [2026-07-17_verify_B04_Surface_Reorganization.md](../../raw/verification/2026-07-17_verify_B04_Surface_Reorganization.md) | 2026-07-17_plan_B04_Surface_Reorganization.md | 2 | `referenced` |
|
||||
| [2026-07-17_verify_layout_and_payment_mockups.md](../../raw/verification/2026-07-17_verify_layout_and_payment_mockups.md) | - | 3 | `referenced` |
|
||||
| [2026-07-17_verify_workflow_stepbar.md](../../raw/verification/2026-07-17_verify_workflow_stepbar.md) | - | 2 | `referenced` |
|
||||
| [2026-07-18_verify_b04_confirm_b05_rebuild.md](../../raw/verification/2026-07-18_verify_b04_confirm_b05_rebuild.md) | 2026-07-18_plan_b04_confirm_b05_rebuild.md | 4 | `referenced` |
|
||||
| [2026-07-18_verify_B04_old_align.md](../../raw/verification/2026-07-18_verify_B04_old_align.md) | 2026-07-18_plan_B04_old_align.md | 1 | `referenced` |
|
||||
| [2026-07-18_verify_B06_DrawingRendering.md](../../raw/verification/2026-07-18_verify_B06_DrawingRendering.md) | 2026-07-18_plan_B06_DrawingRendering.md | 2 | `referenced` |
|
||||
| [2026-07-18_verify_B06_ProfileCross.md](../../raw/verification/2026-07-18_verify_B06_ProfileCross.md) | 2026-07-18_plan_B06_ProfileCross.md | 2 | `referenced` |
|
||||
| [2026-07-18_verify_crs_and_polling_log.md](../../raw/verification/2026-07-18_verify_crs_and_polling_log.md) | - | 5 | `referenced` |
|
||||
| [2026-07-18_verify_layout_improvement.md](../../raw/verification/2026-07-18_verify_layout_improvement.md) | 2026-07-18_plan_layout_improvement.md | 1 | `referenced` |
|
||||
| [2026-07-19_verify_b04_gis_theme.md](../../raw/verification/2026-07-19_verify_b04_gis_theme.md) | 2026-07-19_plan_b04_gis_theme.md | 2 | `referenced` |
|
||||
| [2026-07-19_verify_B05_B06_improvements.md](../../raw/verification/2026-07-19_verify_B05_B06_improvements.md) | 2026-07-19_plan_B05_B06_improvements.md | 4 | `referenced` |
|
||||
| [2026-07-19_verify_B05_B06_UI_Station_Improvement.md](../../raw/verification/2026-07-19_verify_B05_B06_UI_Station_Improvement.md) | 2026-07-19_plan_B05_B06_UI_Station_Improvement.md | 4 | `referenced` |
|
||||
| [2026-07-19_verify_B05_B06_차트_레이아웃_후속보정.md](../../raw/verification/2026-07-19_verify_B05_B06_차트_레이아웃_후속보정.md) | 2026-07-19_plan_B05_B06_차트_레이아웃_후속보정.md | 4 | `referenced` |
|
||||
| [2026-07-19_verify_b05_dark_theme.md](../../raw/verification/2026-07-19_verify_b05_dark_theme.md) | 2026-07-19_plan_b05_dark_theme.md | 1 | `referenced` |
|
||||
| [2026-07-19_verify_B06_사이드바_버튼_폭_및_확정_후_B07_이동.md](../../raw/verification/2026-07-19_verify_B06_사이드바_버튼_폭_및_확정_후_B07_이동.md) | 2026-07-19_plan_B06_사이드바_버튼_폭_및_확정_후_B07_이동.md | 2 | `referenced` |
|
||||
| [2026-07-19_verify_B07_DesignDetail.md](../../raw/verification/2026-07-19_verify_B07_DesignDetail.md) | 2026-07-19_plan_B07_DesignDetail.md | 3 | `referenced` |
|
||||
| [2026-07-19_verify_b07_external_webcad_demos.md](../../raw/verification/2026-07-19_verify_b07_external_webcad_demos.md) | 2026-07-19_plan_b07_external_webcad_demos.md | 2 | `referenced` |
|
||||
| [2026-07-19_verify_b07_independent_cad.md](../../raw/verification/2026-07-19_verify_b07_independent_cad.md) | 2026-07-19_plan_b07_independent_cad.md | 2 | `referenced` |
|
||||
| [2026-07-19_verify_CrossPruning_and_CADStyle.md](../../raw/verification/2026-07-19_verify_CrossPruning_and_CADStyle.md) | 2026-07-19_plan_CrossPruning_and_CADStyle.md | 1 | `referenced` |
|
||||
| [2026-07-19_verify_half_width_persistence.md](../../raw/verification/2026-07-19_verify_half_width_persistence.md) | 2026-07-19_plan_half_width_persistence.md | 3 | `referenced` |
|
||||
| [2026-07-19_verify_responsive_layout_drag.md](../../raw/verification/2026-07-19_verify_responsive_layout_drag.md) | 2026-07-19_plan_responsive_layout_drag.md | 4 | `referenced` |
|
||||
| [2026-07-19_verify_scrollbar_theme.md](../../raw/verification/2026-07-19_verify_scrollbar_theme.md) | 2026-07-19_plan_scrollbar_theme.md | 1 | `referenced` |
|
||||
| [2026-07-19_verify_webcad_poc.md](../../raw/verification/2026-07-19_verify_webcad_poc.md) | - | 1 | `referenced` |
|
||||
| [2026-07-19_verify_종횡단_생성_B05_이관.md](../../raw/verification/2026-07-19_verify_종횡단_생성_B05_이관.md) | 2026-07-19_plan_종횡단_생성_B05_이관.md | 3 | `referenced` |
|
||||
| [2026-07-19_verify_종횡단_이슈수정_3건.md](../../raw/verification/2026-07-19_verify_종횡단_이슈수정_3건.md) | 2026-07-19_plan_종횡단_이슈수정_3건.md | 3 | `referenced` |
|
||||
| [2026-07-20_verify_B05_longitudinal_grade_line.md](../../raw/verification/2026-07-20_verify_B05_longitudinal_grade_line.md) | 2026-07-20_plan_B05_longitudinal_grade_line.md | 2 | `referenced` |
|
||||
| [2026-07-20_verify_B06_profile_cross_design_elevation.md](../../raw/verification/2026-07-20_verify_B06_profile_cross_design_elevation.md) | 2026-07-20_plan_B06_profile_cross_design_elevation.md | 2 | `referenced` |
|
||||
| [2026-07-20_verify_B07_상세설계개선.md](../../raw/verification/2026-07-20_verify_B07_상세설계개선.md) | 2026-07-20_plan_B07_상세설계개선.md | 5 | `referenced` |
|
||||
| [2026-07-20_verify_b08_quantity_template.md](../../raw/verification/2026-07-20_verify_b08_quantity_template.md) | 2026-07-20_plan_b08_quantity_template.md | 3 | `referenced` |
|
||||
| [2026-07-21_verify_B06_default_design_B07_gating.md](../../raw/verification/2026-07-21_verify_B06_default_design_B07_gating.md) | 2026-07-21_plan_B06_default_design_B07_gating.md | 6 | `referenced` |
|
||||
| [2026-07-21_verify_B06_ground_section_type_B07_linkage.md](../../raw/verification/2026-07-21_verify_B06_ground_section_type_B07_linkage.md) | 2026-07-21_plan_B06_ground_section_type_B07_linkage.md | 7 | `referenced` |
|
||||
| [2026-07-22_verify_B06_B07.md](../../raw/verification/2026-07-22_verify_B06_B07.md) | 2026-07-22_plan_B06_B07.md | 5 | `referenced` |
|
||||
| [2026-07-22_verify_B06_cross_scale_row_height.md](../../raw/verification/2026-07-22_verify_B06_cross_scale_row_height.md) | - | 2 | `referenced` |
|
||||
| [2026-07-23_verify_B05_종단_계획선_편집_체계_개편.md](../../raw/verification/2026-07-23_verify_B05_종단_계획선_편집_체계_개편.md) | 2026-07-23_plan_B05_종단_계획선_편집_체계_개편.md | 3 | `referenced` |
|
||||
| [2026-07-24_verify_B05_B06_표준횡단.md](../../raw/verification/2026-07-24_verify_B05_B06_표준횡단.md) | 2026-07-24_plan_B05_B06_표준횡단.md | 4 | `referenced` |
|
||||
| [2026-07-24_verify_B05_irregular_stations.md](../../raw/verification/2026-07-24_verify_B05_irregular_stations.md) | 2026-07-24_plan_B05_irregular_stations.md | 2 | `referenced` |
|
||||
| [2026-07-24_verify_B05_layout_refinements.md](../../raw/verification/2026-07-24_verify_B05_layout_refinements.md) | 2026-07-24_plan_B05_layout_refinements.md | 2 | `referenced` |
|
||||
| [2026-07-24_verify_B05_layout_refinements_2.md](../../raw/verification/2026-07-24_verify_B05_layout_refinements_2.md) | 2026-07-24_plan_B05_layout_refinements_2.md | 1 | `referenced` |
|
||||
| [2026-07-24_verify_b05_reorganization.md](../../raw/verification/2026-07-24_verify_b05_reorganization.md) | 2026-07-24_plan_b05_reorganization.md | 2 | `referenced` |
|
||||
| [2026-07-24_verify_B05_Route_Improvements.md](../../raw/verification/2026-07-24_verify_B05_Route_Improvements.md) | 2026-07-24_plan_B05_Route_Improvements.md | 3 | `referenced` |
|
||||
| [2026-07-24_verify_비정규측점_런타임테스트.md](../../raw/verification/2026-07-24_verify_비정규측점_런타임테스트.md) | - | 1 | `referenced` |
|
||||
| [2026-07-25_verify_b05_b06_3rd_4th_improvements.md](../../raw/verification/2026-07-25_verify_b05_b06_3rd_4th_improvements.md) | 2026-07-25_plan_b05_b06_3rd_4th_improvements.md | 1 | `referenced` |
|
||||
| [2026-07-25_verify_b05_b06_modifications.md](../../raw/verification/2026-07-25_verify_b05_b06_modifications.md) | 2026-07-25_plan_b05_b06_modifications.md | 4 | `referenced` |
|
||||
| [2026-07-25_verify_b06_2nd_improvements.md](../../raw/verification/2026-07-25_verify_b06_2nd_improvements.md) | 2026-07-25_plan_b06_2nd_improvements.md | 2 | `referenced` |
|
||||
| [2026-07-25_verify_b06_n6_n7.md](../../raw/verification/2026-07-25_verify_b06_n6_n7.md) | 2026-07-25_plan_b06_n6_n7.md | 1 | `referenced` |
|
||||
| [2026-07-25_verify_b07_design_detail.md](../../raw/verification/2026-07-25_verify_b07_design_detail.md) | 2026-07-25_plan_b07_design_detail.md | 3 | `referenced` |
|
||||
| [2026-07-25_verify_b08_rebuild.md](../../raw/verification/2026-07-25_verify_b08_rebuild.md) | 2026-07-25_plan_b08_rebuild.md | 4 | `referenced` |
|
||||
| [2026-07-25_verify_n2_n3_n4.md](../../raw/verification/2026-07-25_verify_n2_n3_n4.md) | 2026-07-25_plan_n2_n3_n4.md | 3 | `referenced` |
|
||||
| [2026-07-26_verify_b06_aesthetics.md](../../raw/verification/2026-07-26_verify_b06_aesthetics.md) | 2026-07-26_plan_b06_aesthetics.md | 1 | `referenced` |
|
||||
| [2026-07-26_verify_B07_도면_템플릿_및_도각_적용.md](../../raw/verification/2026-07-26_verify_B07_도면_템플릿_및_도각_적용.md) | 2026-07-26_plan_B07_도면_템플릿_및_도각_적용.md | 3 | `referenced` |
|
||||
| [2026-07-26_verify_openwebcad_성능개선.md](../../raw/verification/2026-07-26_verify_openwebcad_성능개선.md) | 2026-07-26_plan_openwebcad_성능개선.md | 2 | `referenced` |
|
||||
| [2026-07-26_verify_도엽_오버레이.md](../../raw/verification/2026-07-26_verify_도엽_오버레이.md) | 2026-07-26_plan_도엽_오버레이.md | 3 | `referenced` |
|
||||
| [2026-07-28_verify_B04_B05_Drainage_Watershed.md](../../raw/verification/2026-07-28_verify_B04_B05_Drainage_Watershed.md) | 2026-07-28_plan_B04_B05_Drainage_Watershed.md | 3 | `referenced` |
|
||||
| [2026-07-28_verify_B04_Map_Performance.md](../../raw/verification/2026-07-28_verify_B04_Map_Performance.md) | 2026-07-28_plan_B04_Map_Performance.md | 2 | `referenced` |
|
||||
| [2026-07-31_verify_B03_planned_route_csv.md](../../raw/verification/2026-07-31_verify_B03_planned_route_csv.md) | 2026-07-31_plan_B03_planned_route_csv.md | 4 | `referenced` |
|
||||
| [2026-07-31_verify_B05_drainage_watershed_pipe_edit.md](../../raw/verification/2026-07-31_verify_B05_drainage_watershed_pipe_edit.md) | 2026-07-31_plan_B05_drainage_watershed_pipe_edit.md | 3 | `referenced` |
|
||||
@@ -0,0 +1,66 @@
|
||||
---
|
||||
type: ingest-register
|
||||
status: draft
|
||||
related_pages: ["[[ingest/index]]"]
|
||||
last_updated: 2026-08-30
|
||||
---
|
||||
|
||||
# 검증보고서 인제스트 원장 — 2026-08
|
||||
|
||||
> 이 표는 파일명과 현재 위키의 명시적 source 흔적을 대조한 1차 감사 결과다. `referenced`는 완전 반영을 보증하지 않는다.
|
||||
|
||||
| raw 파일 | 대응 문서 후보 | 위키 명시 참조 | 감사 상태 |
|
||||
|---|---|---|---|
|
||||
| `2026-08-30_verify_B05_B06_ui_fixes.md` | B05/B06 UI | yes | user-verified |
|
||||
| `2026-08-30_verify_B08_CAD_commands.md` | B08 CAD 명령 | yes | user-verified |
|
||||
| `2026-08-30_verify_B08_masshaul_watershed_drawings.md` | B08 토적도·유역도 | yes | user-verified |
|
||||
| `2026-08-30_verify_B08_cross_structure_sheets.md` | B08 횡단 구조물·장 배치 | yes | user-verified |
|
||||
| `2026-08-30_verify_las_free_sheet_surface.md` | B03~B06 LAS 없는 설계 | yes | user-verified |
|
||||
| `2026-08-30_verify_B08_CAD_blocks_interaction_tables.md` | B08 블록·조작·표 | yes | user-verified |
|
||||
|
||||
| raw 파일 | 대응 문서 후보 | 위키 명시 참조 | 감사 상태 |
|
||||
|---|---|---:|---|
|
||||
| [2026-08-01_verify_B04_B05_drainage_ui_improvements.md](../../raw/verification/2026-08-01_verify_B04_B05_drainage_ui_improvements.md) | 2026-08-01_plan_B04_B05_drainage_ui_improvements.md | 4 | `referenced` |
|
||||
| [2026-08-01_verify_B04_detailed_basins.md](../../raw/verification/2026-08-01_verify_B04_detailed_basins.md) | 2026-08-01_plan_B04_detailed_basins.md | 3 | `referenced` |
|
||||
| [2026-08-01_verify_B04_inflow_strength_and_panel_cleanup.md](../../raw/verification/2026-08-01_verify_B04_inflow_strength_and_panel_cleanup.md) | 2026-08-01_plan_B04_inflow_strength_and_panel_cleanup.md | 2 | `referenced` |
|
||||
| [2026-08-01_verify_S8_B05_data_saving.md](../../raw/verification/2026-08-01_verify_S8_B05_data_saving.md) | 2026-08-01_plan_S8_B05_data_saving.md | 2 | `referenced` |
|
||||
| [2026-08-01_verify_ui_improvements_4_types.md](../../raw/verification/2026-08-01_verify_ui_improvements_4_types.md) | 2026-08-01_plan_ui_improvements_4_types.md | 1 | `referenced` |
|
||||
| [2026-08-02_verify_B04_B05_drainage_unification.md](../../raw/verification/2026-08-02_verify_B04_B05_drainage_unification.md) | 2026-08-02_plan_B04_B05_drainage_unification.md | 5 | `referenced` |
|
||||
| [2026-08-02_verify_backlog_reorg.md](../../raw/verification/2026-08-02_verify_backlog_reorg.md) | 2026-08-02_plan_backlog_reorg.md | 2 | `referenced` |
|
||||
| [2026-08-02_verify_mass_haul_and_drainage_fixes.md](../../raw/verification/2026-08-02_verify_mass_haul_and_drainage_fixes.md) | 2026-08-02_plan_mass_haul_and_drainage_fixes.md | 5 | `referenced` |
|
||||
| [2026-08-02_verify_mass_haul_distribution_and_refinements.md](../../raw/verification/2026-08-02_verify_mass_haul_distribution_and_refinements.md) | 2026-08-02_plan_mass_haul_distribution_and_refinements.md | 4 | `referenced` |
|
||||
| [2026-08-02_verify_mass_haul_multi_curve.md](../../raw/verification/2026-08-02_verify_mass_haul_multi_curve.md) | 2026-08-02_plan_mass_haul_multi_curve.md | 2 | `referenced` |
|
||||
| [2026-08-02_verify_panel_fold_B05_style.md](../../raw/verification/2026-08-02_verify_panel_fold_B05_style.md) | 2026-08-02_plan_panel_fold_B05_style.md | 3 | `referenced` |
|
||||
| [2026-08-02_verify_panel_height_first_render.md](../../raw/verification/2026-08-02_verify_panel_height_first_render.md) | 2026-08-02_plan_panel_height_first_render.md | 2 | `referenced` |
|
||||
| [2026-08-02_verify_ui_template_locale_split.md](../../raw/verification/2026-08-02_verify_ui_template_locale_split.md) | 2026-08-02_plan_ui_template_locale_split.md | 1 | `referenced` |
|
||||
| [2026-08-03_verify_B05_mass_haul_transfer.md](../../raw/verification/2026-08-03_verify_B05_mass_haul_transfer.md) | 2026-08-03_plan_B05_mass_haul_transfer.md | 2 | `referenced` |
|
||||
| [2026-08-03_verify_향후작업_반영완료.md](../../raw/verification/2026-08-03_verify_향후작업_반영완료.md) | 2026-08-03_plan_향후작업_반영완료.md | 2 | `referenced` |
|
||||
| [2026-08-03_verify_후속작업_주의사항.md](../../raw/verification/2026-08-03_verify_후속작업_주의사항.md) | 2026-08-03_plan_후속작업_주의사항.md | 2 | `referenced` |
|
||||
| [2026-08-04_verify_b05_b06_profile_ui_chain.md](../../raw/verification/2026-08-04_verify_b05_b06_profile_ui_chain.md) | 2026-08-04_plan_b05_b06_profile_ui_chain.md | 2 | `referenced` |
|
||||
| [2026-08-04_verify_mass_haul_spoil_scroll.md](../../raw/verification/2026-08-04_verify_mass_haul_spoil_scroll.md) | 2026-08-04_plan_mass_haul_spoil_scroll.md | 2 | `referenced` |
|
||||
| [2026-08-05_verify_b04_b05_drainage_rainfall_structure.md](../../raw/verification/2026-08-05_verify_b04_b05_drainage_rainfall_structure.md) | 2026-08-05_plan_b04_b05_drainage_rainfall_structure.md | 2 | `referenced` |
|
||||
| [2026-08-06_verify_B05_B06_feature_updates.md](../../raw/verification/2026-08-06_verify_B05_B06_feature_updates.md) | 2026-08-06_plan_B05_B06_feature_updates.md | 2 | `referenced` |
|
||||
| [2026-08-06_verify_B05_bottom_panel_resize_bug.md](../../raw/verification/2026-08-06_verify_B05_bottom_panel_resize_bug.md) | 2026-08-06_plan_B05_bottom_panel_resize_bug.md | 2 | `referenced` |
|
||||
| [2026-08-06_verify_B05_main_panel_resize_proportional.md](../../raw/verification/2026-08-06_verify_B05_main_panel_resize_proportional.md) | 2026-08-06_plan_B05_main_panel_resize_proportional.md | 2 | `referenced` |
|
||||
| [2026-08-08_verify_B05_B06_fixes.md](../../raw/verification/2026-08-08_verify_B05_B06_fixes.md) | 2026-08-08_plan_B05_B06_fixes.md | 2 | `referenced` |
|
||||
| [2026-08-08_verify_dashboard_scroll_limit.md](../../raw/verification/2026-08-08_verify_dashboard_scroll_limit.md) | 2026-08-08_plan_dashboard_scroll_limit.md | 2 | `referenced` |
|
||||
| [2026-08-08_verify_db_initialization.md](../../raw/verification/2026-08-08_verify_db_initialization.md) | 2026-08-08_plan_db_initialization.md | 1 | `referenced` |
|
||||
| [2026-08-08_verify_project_delete_hard.md](../../raw/verification/2026-08-08_verify_project_delete_hard.md) | 2026-08-08_plan_project_delete_hard.md | 3 | `referenced` |
|
||||
| [2026-08-08_verify_R1_R2_features.md](../../raw/verification/2026-08-08_verify_R1_R2_features.md) | 2026-08-08_plan_R1_R2_features.md | 3 | `referenced` |
|
||||
| [2026-08-08_verify_server_and_e2e_fixes.md](../../raw/verification/2026-08-08_verify_server_and_e2e_fixes.md) | 2026-08-08_plan_server_and_e2e_fixes.md | 3 | `referenced` |
|
||||
| [2026-08-13_verify_rainfall_wamis_station.md](../../raw/verification/2026-08-13_verify_rainfall_wamis_station.md) | 2026-08-13_plan_rainfall_wamis_station.md | 2 | `referenced` |
|
||||
| [2026-08-16_verify_B05_구조물_수동추가.md](../../raw/verification/2026-08-16_verify_B05_구조물_수동추가.md) | 2026-08-16_plan_B05_구조물_수동추가.md | 1 | `referenced` |
|
||||
| [2026-08-16_verify_B05_구조물_수동추가_교차검증.md](../../raw/verification/2026-08-16_verify_B05_구조물_수동추가_교차검증.md) | 2026-08-16_plan_B05_구조물_수동추가.md | 1 | `referenced` |
|
||||
| [2026-08-17_verify_B04_등고선_추출_가속_교차검증.md](../../raw/verification/2026-08-17_verify_B04_등고선_추출_가속_교차검증.md) | 2026-08-17_plan_B04_등고선_추출_가속.md | 1 | `referenced` |
|
||||
| [2026-08-17_verify_B05_box_ui_recommendations_external.md](../../raw/verification/2026-08-17_verify_B05_box_ui_recommendations_external.md) | 2026-08-17_plan_B05_box_ui_recommendations.md | 3 | `referenced` |
|
||||
| [2026-08-20_verify_B06_배수관_횡단도_세트_자체검증근거.md](../../raw/verification/2026-08-20_verify_B06_배수관_횡단도_세트_자체검증근거.md) | 2026-08-20_plan_B06_배수관_횡단도_세트.md | 5 | `referenced` |
|
||||
| [2026-08-22_verify_B06_배수관_구조물_기하_조작_체계_자체검증근거.md](../../raw/verification/2026-08-22_verify_B06_배수관_구조물_기하_조작_체계_자체검증근거.md) | 2026-08-22_plan_B06_배수관_구조물_기하_조작_체계.md | 3 | `referenced` |
|
||||
| [2026-08-27_verify_B05_B06_구조물_3D_절취_패치_교차검증.md](../../raw/verification/2026-08-27_verify_B05_B06_구조물_3D_절취_패치_교차검증.md) | 2026-08-27_plan_B05_B06_구조물_3D_절취_패치.md | 4 | `referenced` |
|
||||
| [2026-08-27_verify_B05_변형성토면_마감_날개패치_교차검증.md](../../raw/verification/2026-08-27_verify_B05_변형성토면_마감_날개패치_교차검증.md) | 2026-08-27_plan_B05_변형성토면_마감_날개패치.md | 3 | `referenced` |
|
||||
| [2026-08-28_verify_B05_구조물측점_단일공급자.md](../../raw/verification/2026-08-28_verify_B05_구조물측점_단일공급자.md) | 2026-08-28_plan_B05_구조물측점_단일공급자.md | 2 | `covered_by_verified_pair` |
|
||||
| [2026-08-28_verify_B05_B06_물넘이포장_독립기슭막이.md](../../raw/verification/2026-08-28_verify_B05_B06_물넘이포장_독립기슭막이.md) | 2026-08-28_plan_B05_B06_물넘이포장_독립기슭막이.md | 2 | `covered_by_verified_pair` |
|
||||
| [2026-08-28_verify_B05_구조물_3D_후속판정.md](../../raw/verification/2026-08-28_verify_B05_구조물_3D_후속판정.md) | 2026-08-28_plan_B05_구조물_3D_후속판정.md | 2 | `covered_by_verified_pair` |
|
||||
| [2026-08-28_verify_B05_후속완료_정리.md](../../raw/verification/2026-08-28_verify_B05_후속완료_정리.md) | 2026-08-28_plan_B05_후속완료_정리.md | 2 | `covered_by_verified_pair` |
|
||||
| [2026-08-29_verify_B03_reupload_reanalysis_cache.md](../../raw/verification/2026-08-29_verify_B03_reupload_reanalysis_cache.md) | commit `60bbe89e` | 3 | `referenced` |
|
||||
| [2026-08-29_verify_B05_B06_structure_ui_unification.md](../../raw/verification/2026-08-29_verify_B05_B06_structure_ui_unification.md) | 2026-08-29_plan_B05_B06_structure_ui_unification.md | 1 | `covered_by_verified_pair` |
|
||||
| [2026-08-29_verify_B07_CAD_scale_sheet_layout.md](../../raw/verification/2026-08-29_verify_B07_CAD_scale_sheet_layout.md) | 2026-08-29_plan_B07_CAD_scale_sheet_layout.md | 1 | `covered_by_verified_pair` |
|
||||
@@ -0,0 +1,13 @@
|
||||
---
|
||||
type: ingest-register
|
||||
status: stable
|
||||
related_pages: ["[[ingest/index]]", "[[completed_2026-09-01]]"]
|
||||
last_updated: 2026-09-01
|
||||
---
|
||||
|
||||
# 2026-09 검증 인제스트
|
||||
|
||||
| 원본 | 상태 | 반영 위치 |
|
||||
|---|---|---|
|
||||
| `docs/raw/verification/2026-09-01_verify_B04_B05_B06_completed_work.md` | `covered_by_verified_pair` | [[completed_2026-09-01]] |
|
||||
| `docs/raw/verification/2026-09-01_verify_remaining_checked_items.md` | `covered_by_verified_pair` | [[completed_2026-09-01_followups]] |
|
||||
+1403
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,23 @@
|
||||
---
|
||||
type: page-frontend
|
||||
status: draft
|
||||
related_pages: ["[[architecture/project_map]]", "[[architecture/public_admin_map]]"]
|
||||
page_id: A00_Common
|
||||
last_updated: 2026-07-24
|
||||
---
|
||||
|
||||
# A00_Common — 공통 프레임워크 & 유틸
|
||||
|
||||
A00_Common은 전체 웹 애플리케이션의 셸 레이아웃, SPA 클라이언트 라우터, 7단계 워크플로우 스테이지 게이팅 및 백엔드 데이터베이스/파일시스템 공통 유틸리티 모듈로 세분화되어 구성됩니다.
|
||||
|
||||
## 📂 세분화 마크다운 문서 목록
|
||||
|
||||
| 분류 | 세분화 마크다운 문서 | 핵심 역할 |
|
||||
|---|---|---|
|
||||
| 프론트엔드 | `[[A00_Common/frontend/A00_Common_AppShell]]` | 공통 상단 네비게이션 헤더 및 셸 레이아웃 |
|
||||
| 프론트엔드 | `[[A00_Common/frontend/A00_Common_Router]]` | 해시 기반 SPA 라우터 및 페이지 라우팅 |
|
||||
| 공통 백엔드 유틸 | `[[concepts/common_util/common_util_workflow_state]]` | 7단계 워크플로우 전이 및 `project_workflow_stages` DB 연동 |
|
||||
| 공통 백엔드 유틸 | `[[concepts/common_util/common_util_storage]]` | 물리 저장소 절대경로 해석 및 디렉토리 관리 유틸 |
|
||||
|
||||
## 📋 개요
|
||||
- 애플리케이션의 뼈대가 되는 셸 레이아웃과 7단계 상태 관리 트랜잭션을 전역 제공합니다.
|
||||
@@ -0,0 +1,22 @@
|
||||
---
|
||||
type: file-frontend
|
||||
status: draft
|
||||
related_pages: ["[[architecture/project_map]]", "[[architecture/public_admin_map]]"]
|
||||
page_id: A00_Common
|
||||
source_file: "A00_Common/app_shell.ts"
|
||||
last_updated: 2026-07-24
|
||||
---
|
||||
|
||||
# app_shell.ts
|
||||
|
||||
웹 애플리케이션의 공통 상단 네비게이션 헤더, 모바일 드로어 메뉴, 시스템 대시보드 상태 및 테마 전환 레이아웃을 렌더링하는 클라이언트 셸 모듈입니다.
|
||||
|
||||
## 🛠️ 주요 함수 목록
|
||||
|
||||
| 항목 | 위치(상대 경로) | 역할 |
|
||||
|---|---|---|
|
||||
| `renderAppShell()` | `A00_Common/app_shell.ts` | 메인 헤더 및 워크플로우 셸 레이아웃 DOM 구조 렌더링 |
|
||||
| `updateActiveNav()` | `A00_Common/app_shell.ts` | 현재 URL 라우트 경로에 따라 헤더 네비게이션 활성 탭 하이라이트 |
|
||||
|
||||
## 🔗 연관 개념 및 의존성
|
||||
- `A00_Common/router.ts` — 클라이언트 라우터와 네비게이션 상태 공유
|
||||
@@ -0,0 +1,22 @@
|
||||
---
|
||||
type: file-frontend
|
||||
status: draft
|
||||
related_pages: ["[[architecture/project_map]]", "[[architecture/public_admin_map]]"]
|
||||
page_id: A00_Common
|
||||
source_file: "A00_Common/router.ts"
|
||||
last_updated: 2026-07-24
|
||||
---
|
||||
|
||||
# router.ts
|
||||
|
||||
해시 기반(`/#/path`) 클라이언트 사이드 라우팅 및 페이지 전환, 브라우저 뒤로가기/앞으로가기 이벤트를 바인딩하는 싱글 페이지 애플리케이션(SPA) 라우터 모듈입니다.
|
||||
|
||||
## 🛠️ 주요 함수 목록
|
||||
|
||||
| 항목 | 위치(상대 경로) | 역할 |
|
||||
|---|---|---|
|
||||
| `initRouter()` | `A00_Common/router.ts` | `hashchange` 이벤트 수신기 바인딩 및 초기 경로 파싱 라우팅 |
|
||||
| `navigate()` | `A00_Common/router.ts` | 프로그래밍 방식 해시 URL 변경 및 렌더러 격발 |
|
||||
|
||||
## 🔗 연관 개념 및 의존성
|
||||
- `A00_Common/b_workflow_nav.ts` — 7단계 워크플로우 게이팅 라우팅 바인딩
|
||||
@@ -0,0 +1,37 @@
|
||||
---
|
||||
type: page-frontend-detail
|
||||
status: draft
|
||||
page_id: A01_Home
|
||||
related_pages: ["[[A01_Home/A01_frontend]]", "[[ui_templates]]", "[[a00_app_shell_framework]]", "[[architecture/project_map]]", "[[architecture/public_admin_map]]"]
|
||||
last_updated: 2026-07-12
|
||||
source: 상위 프로젝트 A01_Home 코드 인제스트 보완 (2026-07-12)
|
||||
---
|
||||
|
||||
# A01_Home — 세부 구현
|
||||
|
||||
## 스타일
|
||||
| 항목 | 역할 |
|
||||
|---|---|
|
||||
| `.a01-home`, `.a01-hero` | 페이지 래퍼·히어로 배경 |
|
||||
| `.a01-news-list`, `.a01-news-row` | 뉴스 목록과 행 레이아웃 |
|
||||
| `.a01-feature-grid`, `.a01-feature-card` | 3열 기능 카드 그리드 |
|
||||
| 900px 이하 | 기능 그리드 1열·히어로 제목 축소 |
|
||||
|
||||
## 의존성
|
||||
| 항목 | 역할 |
|
||||
|---|---|
|
||||
| [[a00_app_shell_framework]] | `navigateTo()` 라우팅 |
|
||||
| `config_frontend.ts` | `ROUTES` 상수 |
|
||||
| [[ui_templates]] | 공통 버튼·카드·태그·다국어 |
|
||||
|
||||
## 데이터 흐름
|
||||
| 단계 | 흐름 |
|
||||
|---|---|
|
||||
| 1 | `renderA01Home(root)` → `buildHero()`·`buildNews()`·`buildFeatures()` |
|
||||
| 2 | `buildNews()`는 현재 `MOCK_NEWS` 사용 |
|
||||
| 3 | CTA 클릭 → A07_Register 또는 A02_ProgDetail 이동 |
|
||||
|
||||
## 미해결
|
||||
| 항목 | 상태 |
|
||||
|---|---|
|
||||
| `GET /api/a01/news` | 백엔드 미구현; 현재 뉴스는 하드코딩 |
|
||||
@@ -0,0 +1,62 @@
|
||||
---
|
||||
status: draft
|
||||
page_id: A01_Home
|
||||
related_pages: ["[[A02_ProgDetail/A02_frontend]]", "[[A04_NewsHistory/A04_frontend]]", "[[a00_app_shell_framework]]", "[[ui_templates]]", "[[architecture/project_map]]", "[[architecture/public_admin_map]]"]
|
||||
last_updated: 2026-07-12
|
||||
---
|
||||
|
||||
# A01_Home — Frontend
|
||||
|
||||
[[architecture/public_admin_map]]은 이 페이지를 방문자의 공개 진입점으로 라우팅하고, [[A01_Home/frontend/A01_Home_UI_Page]]가 화면을 구현한다.
|
||||
|
||||
로그인 전 01: 홈 페이지. 소개 히어로 + 최신 소식 + 주요 기능 3가지를 showcase하는 정적 소개 페이지. 백엔드 없음.
|
||||
|
||||
## 파일 구조
|
||||
|
||||
| 파일 | 세분화 위키 명세 | 역할 |
|
||||
|---|---|---|
|
||||
| `A01_Home_UI_Page.ts` | `[[A01_Home/frontend/A01_Home_UI_Page]]` | 페이지 렌더링 로직 (buildHero, buildNews, buildFeatures) |
|
||||
| `A01_Home_UI_Style.css` | `A01_Home/A01_Home_UI_Style.css` | 스타일 (theme.css 변수만 사용) |
|
||||
|
||||
## 컴포넌트
|
||||
|
||||
### Hero 섹션
|
||||
- **함수:** `buildHero()` (A01_Home_UI_Page.ts:52-85)
|
||||
- **구성:** 제목 + 부제목 + 2개 CTA 버튼 (회원가입/프로그램 상세)
|
||||
- **색상:** 라벤더 그라디언트 배경 (`--color-mist-violet` → `--color-canvas`)
|
||||
|
||||
### 최신 소식 섹션
|
||||
- **함수:** `buildNews()` (A01_Home_UI_Page.ts:87-116)
|
||||
- **데이터:** MOCK_NEWS 배열 (A01_Home_UI_Page.ts:32-36, 백엔드 연결 전)
|
||||
- **각 항목:** 태그 + 뉴스 제목 + 날짜
|
||||
|
||||
### 주요 기능 섹션
|
||||
- **함수:** `buildFeatures()` (A01_Home_UI_Page.ts:118-146)
|
||||
- **레이아웃:** 3열 그리드 (반응형: 900px 이하 1열)
|
||||
- **카드:** createCard 공통 컴포넌트 사용
|
||||
|
||||
## 이벤트 핸들러
|
||||
|
||||
| 함수 | 위치 | 동작 |
|
||||
|---|---|---|
|
||||
| `onA01_Home_GetStarted_Click()` | A01_Home_UI_Page.ts:41-43 | 회원가입(A07_REGISTER) 이동 |
|
||||
| `onA01_Home_Explore_Click()` | A01_Home_UI_Page.ts:45-47 | 프로그램 상세(A02_PROG_DETAIL) 이동 |
|
||||
|
||||
## 로컬라이제이션
|
||||
|
||||
모든 텍스트는 `ui_locales[key][currentLanguageIndex]` 형식으로 [[ui_templates]] 에서 로드.
|
||||
하드코딩 금지.
|
||||
|
||||
| UI 요소 | 로케일 키 |
|
||||
|---|---|
|
||||
| 제목 | `A01_Home_Title` |
|
||||
| 히어로 부제목 | `A01_Home_Hero_Subtitle` |
|
||||
| CTA 버튼 (Primary/Secondary) | `A01_Home_Hero_CtaPrimary`, `A01_Home_Hero_CtaSecondary` |
|
||||
| 소식 섹션 제목 | `A01_Home_News_SectionTitle` |
|
||||
| 소식 태그 | `A01_Home_News_Tag` |
|
||||
| 기능 섹션 제목 | `A01_Home_Features_SectionTitle` |
|
||||
| 기능 카드 1~3 | `A01_Home_Feature{1..3}_Title`, `A01_Home_Feature{1..3}_Desc` |
|
||||
|
||||
## 세부 구현
|
||||
|
||||
스타일 구조·의존성·데이터 흐름·미해결 사항은 [[A01_Home/A01_components]]에 분리했다.
|
||||
@@ -0,0 +1,29 @@
|
||||
---
|
||||
type: file-frontend
|
||||
status: draft
|
||||
related_pages: ["[[architecture/project_map]]", "[[architecture/public_admin_map]]"]
|
||||
page_id: A01_Home
|
||||
source_file: "A01_Home/A01_Home_UI_Page.ts"
|
||||
last_updated: 2026-07-24
|
||||
---
|
||||
|
||||
# A01_Home_UI_Page.ts
|
||||
|
||||
로그인 전 서비스 메인 홈 랜딩 페이지 모듈입니다. 다국어 i18n 로케일(`ui_template_locale`) 적용, 히어로 영역 CTA, 최신 소식 타임라인 목록 및 3대 핵심 기능 Showcase 카드 그리드를 조립합니다.
|
||||
|
||||
## 🛠️ 주요 함수 및 인터페이스 목록
|
||||
|
||||
| 항목 | 위치(상대 경로) | 역할 |
|
||||
|---|---|---|
|
||||
| `renderA01Home()` | `A01_Home/A01_Home_UI_Page.ts` | 메인 페이지 진입점. Hero, News, Features 섹션을 순차 빌드하여 root DOM에 마운트 |
|
||||
| `buildHero()` | `A01_Home/A01_Home_UI_Page.ts` | 메인 타이틀, 서브타이틀 및 시작하기/둘러보기 CTA 버튼 섹션 DOM 생성 |
|
||||
| `buildNews()` | `A01_Home/A01_Home_UI_Page.ts` | `MOCK_NEWS` 데이터를 순회하며 태그, 소식 제목, 날짜 행 목록 DOM 생성 |
|
||||
| `buildFeatures()` | `A01_Home/A01_Home_UI_Page.ts` | 3대 핵심 기능(Feature 1~3) 카드 그리드 DOM 생성 |
|
||||
| `onA01_Home_GetStarted_Click()` | `A01_Home/A01_Home_UI_Page.ts` | 시작하기 클릭 시 회원가입 페이지(`A07_REGISTER`)로 이동하는 라우터 핸들러 |
|
||||
| `onA01_Home_Explore_Click()` | `A01_Home/A01_Home_UI_Page.ts` | 둘러보기 클릭 시 기술 소개 페이지(`A02_PROG_DETAIL`)로 이동하는 라우터 핸들러 |
|
||||
| `L()` | `A01_Home/A01_Home_UI_Page.ts` | `ui_locales` 다국어 키 기반 현재 언어 텍스트 반환 헬퍼 |
|
||||
| `NewsItem` | `A01_Home/A01_Home_UI_Page.ts` | 최신 소식 항목 인터페이스 (`id`, `title`, `date`) |
|
||||
|
||||
## 🔗 연관 개념 및 의존성
|
||||
- `A00_Common/router.ts` — `navigateTo` SPA 페이지 이동 연동
|
||||
- `ui_template_elements.ts` — `createButton`, `createCard`, `createTag` 공통 UI 컴포넌트 활용
|
||||
@@ -0,0 +1,38 @@
|
||||
---
|
||||
type: page-frontend-detail
|
||||
status: draft
|
||||
page_id: A02_ProgDetail
|
||||
related_pages: ["[[A02_ProgDetail/A02_frontend]]", "[[ui_templates]]", "[[a00_app_shell_framework]]", "[[architecture/project_map]]", "[[architecture/public_admin_map]]"]
|
||||
last_updated: 2026-07-12
|
||||
source: A02_ProgDetail 코드 인제스트 보완 및 구조화 일관성 적용
|
||||
---
|
||||
|
||||
# A02_ProgDetail — 세부 구현
|
||||
|
||||
## 스타일 (CSS)
|
||||
| 항목 | 역할 |
|
||||
|---|---|
|
||||
| `.a02-prog-detail` | 페이지 루트 컨테이너 (gap: section-gap, padding-bottom: spacing-64) |
|
||||
| `.a02-hero`, `.a02-hero__inner` | 히어로 영역 배경(라벤더 그라디언트) 및 콘텐츠 중앙 정렬 |
|
||||
| `.a02-workflow-list`, `.a02-workflow-row` | 6단계 워크플로우 리스트(flex 열) 및 배지+텍스트 행 레이아웃 |
|
||||
| `.a02-workflow-row__badge` | 40×40px 원형 배지 (primary 배경) |
|
||||
| `.a02-tech-grid`, `.a02-tech-card` | 핵심 기술 소개 3열 카드 그리드 (900px 이하 대응) |
|
||||
|
||||
## 의존성
|
||||
| 항목 | 역할 |
|
||||
|---|---|
|
||||
| [[a00_app_shell_framework]] | `navigateTo()` 라우팅 기능 활용 |
|
||||
| `config_frontend.ts` | `ROUTES` 경로 상수 참조 |
|
||||
| [[ui_templates]] | 공통 버튼(`createButton`) 및 카드(`createCard`) 엘리먼트 활용 |
|
||||
| `ui_template_locale.ts` | 다국어 문구(`ui_locales`) 적용 |
|
||||
|
||||
## 데이터 흐름
|
||||
| 단계 | 흐름 |
|
||||
|---|---|
|
||||
| 1 | `renderA02ProgDetail(root)` ➡️ `buildHero()` ➡️ `buildWorkflow()` ➡️ `buildTech()` 순서로 구성 요소를 렌더링하고 `root`에 추가 |
|
||||
| 2 | 사용자가 히어로의 CTA 버튼 클릭 시 `onA02_ProgDetail_Start_Click()` 핸들러가 작동하여 `navigateTo(ROUTES.A07_REGISTER)` 호출 |
|
||||
|
||||
## 미해결 / 특이사항
|
||||
| 항목 | 상태 |
|
||||
|---|---|
|
||||
| 정적 페이지 | 백엔드 API와의 연동이 필요 없는 완전한 정적 소개 페이지임 |
|
||||
@@ -0,0 +1,36 @@
|
||||
---
|
||||
status: draft
|
||||
page_id: A02_ProgDetail
|
||||
related_pages: ["[[A01_Home/A01_frontend]]", "[[a00_app_shell_framework]]", "[[ui_templates]]", "[[A02_ProgDetail/A02_components]]", "[[architecture/project_map]]", "[[architecture/public_admin_map]]"]
|
||||
last_updated: 2026-07-12
|
||||
---
|
||||
|
||||
# A02_ProgDetail — Frontend
|
||||
|
||||
[[architecture/public_admin_map]]의 기능 탐색 경로이며 [[A02_ProgDetail/frontend/A02_ProgDetail_UI_Page]]가 화면을 구현한다.
|
||||
|
||||
로그인 전 프로그램 상세 페이지. 6단계 워크플로우 시각화 + 핵심 기술 소개.
|
||||
|
||||
## 구조
|
||||
- **세분화 명세**: `[[A02_ProgDetail/frontend/A02_ProgDetail_UI_Page]]`
|
||||
- **소스 경로**: `A02_ProgDetail/A02_ProgDetail_UI_Page.ts`
|
||||
- **스타일**: `A02_ProgDetail/A02_ProgDetail_UI_Style.css`
|
||||
|
||||
## 컴포넌트 분석
|
||||
|
||||
| 컴포넌트 | 역할 | 로케일 키 |
|
||||
|---|---|---|
|
||||
| `buildHero()` | 히어로 섹션(제목+부제+CTA) | `A02_ProgDetail_Title`, `A02_ProgDetail_Hero_Subtitle`, `A02_ProgDetail_Hero_Cta` |
|
||||
| `buildWorkflow()` | 6단계 워크플로우 리스트(배지+텍스트) | `A02_ProgDetail_Workflow_SectionTitle`, `A02_ProgDetail_Step[1-6]_Title`, `A02_ProgDetail_Step[1-6]_Desc` |
|
||||
| `buildTech()` | 기술 3종 카드 그리드 | `A02_ProgDetail_Tech_SectionTitle`, `A02_ProgDetail_Tech[1-3]_Title`, `A02_ProgDetail_Tech[1-3]_Desc` |
|
||||
|
||||
## 제약 준수
|
||||
|
||||
- ✅ 모든 문구 `ui_template_locale.ts` 참조
|
||||
- ✅ 색상/간격 `theme.css` 변수만 사용
|
||||
- ✅ 공통 컴포넌트 `createButton`/`createCard` 사용
|
||||
- ✅ 이벤트 핸들러 명명 `on[페이지]_[기능]_[액션]`
|
||||
|
||||
## 세부 구현
|
||||
|
||||
스타일 구조·의존성·데이터 흐름·특이사항은 [[A02_ProgDetail/A02_components]]에 분리했다.
|
||||
@@ -0,0 +1,27 @@
|
||||
---
|
||||
type: file-frontend
|
||||
status: draft
|
||||
related_pages: ["[[architecture/project_map]]", "[[architecture/public_admin_map]]"]
|
||||
page_id: A02_ProgDetail
|
||||
source_file: "A02_ProgDetail/A02_ProgDetail_UI_Page.ts"
|
||||
last_updated: 2026-07-24
|
||||
---
|
||||
|
||||
# A02_ProgDetail_UI_Page.ts
|
||||
|
||||
로그인 전 서비스 02: 프로그램 상세 소개 랜딩 페이지 모듈입니다. 6단계 임도 설계 워크플로우(지표면 분석, 경로 설계, 종횡단 상세, 구조물 설계, 수량 산출, 견적) 및 3대 핵심 지원 기술을 시각화합니다.
|
||||
|
||||
## 🛠️ 주요 함수 목록
|
||||
|
||||
| 항목 | 위치(상대 경로) | 역할 |
|
||||
|---|---|---|
|
||||
| `renderA02ProgDetail()` | `A02_ProgDetail/A02_ProgDetail_UI_Page.ts` | 프로그램 상세 메인 진입점. Hero, Workflow, Tech 섹션을 생성하여 root DOM에 마운트 |
|
||||
| `buildHero()` | `A02_ProgDetail/A02_ProgDetail_UI_Page.ts` | 메인 타이틀, 서브타이틀 및 시작하기 CTA 버튼 섹션 DOM 생성 |
|
||||
| `buildWorkflow()` | `A02_ProgDetail/A02_ProgDetail_UI_Page.ts` | 6단계 워크플로우(Step 1~6) 순번 배지 및 제목/설명 행 리스트 DOM 생성 |
|
||||
| `buildTech()` | `A02_ProgDetail/A02_ProgDetail_UI_Page.ts` | 3대 핵심 지원 기술(Tech 1~3) 카드 그리드 DOM 생성 |
|
||||
| `onA02_ProgDetail_Start_Click()` | `A02_ProgDetail/A02_ProgDetail_UI_Page.ts` | 시작하기 클릭 시 회원가입 페이지(`A07_REGISTER`)로 이동하는 라우터 핸들러 |
|
||||
| `L()` | `A02_ProgDetail/A02_ProgDetail_UI_Page.ts` | `ui_locales` 다국어 키 기반 현재 언어 텍스트 반환 헬퍼 |
|
||||
|
||||
## 🔗 연관 개념 및 의존성
|
||||
- `A00_Common/router.ts` — `navigateTo` SPA 페이지 이동 연동
|
||||
- `ui_template_elements.ts` — `createButton`, `createCard` 공통 UI 컴포넌트 활용
|
||||
@@ -0,0 +1,69 @@
|
||||
---
|
||||
status: draft
|
||||
page_id: A03_CompDetail
|
||||
related_pages: ["[[a00_app_shell_framework]]", "[[ui_templates]]", "[[architecture/project_map]]", "[[architecture/public_admin_map]]"]
|
||||
last_updated: 2026-07-12
|
||||
---
|
||||
|
||||
# A03_CompDetail — Frontend
|
||||
|
||||
[[architecture/public_admin_map]]의 공개 회사 소개 경로이며 [[a00_app_shell_framework]]의 SPA 라우터가 이 화면을 로드한다.
|
||||
|
||||
로그인 전 회사 상세 페이지. 미션 + 핵심 가치 + 연락처.
|
||||
|
||||
## 파일 구조
|
||||
|
||||
| 파일 | 위치 | 역할 |
|
||||
|---|---|---|
|
||||
| `A03_CompDetail_UI_Page.ts` | `A03_CompDetail/A03_CompDetail_UI_Page.ts:1-114` | 페이지 렌더링 로직 |
|
||||
| `A03_CompDetail_UI_Style.css` | `A03_CompDetail/A03_CompDetail_UI_Style.css:1-100` | 스타일 (theme.css 변수만 사용) |
|
||||
|
||||
## 컴포넌트 (섹션 빌더)
|
||||
|
||||
| 함수 | 위치 | 역할 |
|
||||
|---|---|---|
|
||||
| `buildHero()` | `A03_CompDetail/A03_CompDetail_UI_Page.ts:23-41` | Hero(제목+부제목), mist-violet→canvas 그라디언트 |
|
||||
| `buildMission()` | `A03_CompDetail/A03_CompDetail_UI_Page.ts:43-57` | 미션 섹션 제목+본문(중앙정렬, max 60자) |
|
||||
| `buildValues()` | `A03_CompDetail/A03_CompDetail_UI_Page.ts:59-87` | 핵심가치 3열 카드그리드(createCard 3개) |
|
||||
| `buildContact()` | `A03_CompDetail/A03_CompDetail_UI_Page.ts:89-103` | 연락처 섹션 제목+이메일 |
|
||||
| `renderA03CompDetail()` | `A03_CompDetail/A03_CompDetail_UI_Page.ts:108-113` | 페이지 진입점(4개 섹션 조립) |
|
||||
|
||||
## 로컬라이제이션
|
||||
|
||||
모든 텍스트는 `ui_locales[key][currentLanguageIndex]` 형식으로 [[ui_templates]]에서 로드.
|
||||
하드코딩 금지.
|
||||
|
||||
| UI 요소 | 로케일 키 |
|
||||
|---|---|
|
||||
| 제목 | `A03_CompDetail_Title` |
|
||||
| 히어로 부제목 | `A03_CompDetail_Hero_Subtitle` |
|
||||
| 미션 섹션 제목 | `A03_CompDetail_Mission_SectionTitle` |
|
||||
| 미션 본문 | `A03_CompDetail_Mission_Body` |
|
||||
| 가치 섹션 제목 | `A03_CompDetail_Value_SectionTitle` |
|
||||
| 가치 1~3 | `A03_CompDetail_Value{1..3}_Title`, `A03_CompDetail_Value{1..3}_Desc` |
|
||||
| 연락처 섹션 제목 | `A03_CompDetail_Contact_SectionTitle` |
|
||||
| 연락처 이메일 | `A03_CompDetail_Contact_Email` |
|
||||
|
||||
## 스타일 (CSS)
|
||||
|
||||
### CSS 클래스 구조
|
||||
- `.a03-comp-detail` — 페이지 래퍼 (flex column, gap: section-gap)
|
||||
- `.a03-hero` — 그래디언트 배경
|
||||
- `.a03-hero__inner` — 중앙 정렬 컨테이너
|
||||
- `.a03-hero__title` — heading-lg, deep-iris, max 18자
|
||||
- `.a03-hero__subtitle` — body 텍스트, slate, max 56자
|
||||
- `.a03-section` — 공통 섹션 (max-width: page-max-width, padding: spacing-32)
|
||||
- `.a03-section__title` — heading-sm, deep-iris, 중앙 정렬
|
||||
- `.a03-mission__body` — body, slate, 중앙 정렬, max 60자
|
||||
- `.a03-value-grid` — 3열 그리드 (gap: spacing-24)
|
||||
- `.a03-value-card` — 카드 (min-height: 140px)
|
||||
- `.a03-value__desc` — body-sm, slate
|
||||
- `.a03-contact__email` — body, charcoal, 중앙 정렬
|
||||
|
||||
### 반응형
|
||||
- **900px 이하:** 가치 그리드 1열, 히어로 제목 폰트 축소
|
||||
|
||||
## 의존성
|
||||
|
||||
- [[a00_app_shell_framework]] — 공통 헤더·푸터
|
||||
- [[ui_templates]] — `createCard()` 공통 컴포넌트 + 다국어
|
||||
@@ -0,0 +1,88 @@
|
||||
---
|
||||
status: draft
|
||||
page_id: A04_NewsHistory
|
||||
related_pages: ["[[A01_Home/A01_frontend]]", "[[a00_app_shell_framework]]", "[[ui_templates]]", "[[architecture/project_map]]", "[[architecture/public_admin_map]]"]
|
||||
last_updated: 2026-07-12
|
||||
---
|
||||
|
||||
# A04_NewsHistory — Frontend
|
||||
|
||||
[[architecture/public_admin_map]]의 공개 소식 경로이며 [[a00_app_shell_framework]]의 SPA 라우터가 이 화면을 로드한다.
|
||||
|
||||
로그인 전 최신 소식 및 개선 이력 페이지. 타임라인 목록 형태.
|
||||
|
||||
## 파일 구조
|
||||
|
||||
| 파일 | 위치 | 역할 |
|
||||
|---|---|---|
|
||||
| `A04_NewsHistory_UI_Page.ts` | `A04_NewsHistory/A04_NewsHistory_UI_Page.ts:1-117` | 페이지 렌더링 로직 + Mock 데이터 |
|
||||
| `A04_NewsHistory_UI_Style.css` | `A04_NewsHistory/A04_NewsHistory_UI_Style.css:1-87` | 스타일 (theme.css 변수만 사용) |
|
||||
|
||||
## 컴포넌트 (섹션 빌더)
|
||||
|
||||
| 함수 | 위치 | 역할 |
|
||||
|---|---|---|
|
||||
| `buildHero()` | `A04_NewsHistory/A04_NewsHistory_UI_Page.ts:50-68` | Hero(제목+부제목), mist-violet→canvas 그라디언트 |
|
||||
| `buildTimeline()` | `A04_NewsHistory/A04_NewsHistory_UI_Page.ts:70-106` | 타임라인(태그+제목+날짜 행), 빈 상태 처리 |
|
||||
| `renderA04NewsHistory()` | `A04_NewsHistory/A04_NewsHistory_UI_Page.ts:111-116` | 페이지 진입점(Hero+타임라인 조립) |
|
||||
|
||||
- **데이터:** MOCK_HISTORY 배열 (A04_NewsHistory_UI_Page.ts:33-38, 백엔드 연결 전) — 추후 `GET /api/a04/history`로 교체 예정
|
||||
- **빈 상태:** MOCK_HISTORY.length === 0이면 `A04_NewsHistory_Empty` 로케일 키 표시
|
||||
|
||||
## Mock 데이터 구조
|
||||
|
||||
**타입:**
|
||||
```typescript
|
||||
type HistoryKind = "feature" | "fix" | "notice";
|
||||
interface HistoryItem {
|
||||
id: number;
|
||||
kind: HistoryKind;
|
||||
title: string;
|
||||
date: string;
|
||||
}
|
||||
```
|
||||
|
||||
**태그 변형 매핑** (KIND_META):
|
||||
- `"feature"` → variant: "accent" → `A04_NewsHistory_Tag_Feature`
|
||||
- `"fix"` → variant: "success" → `A04_NewsHistory_Tag_Fix`
|
||||
- `"notice"` → variant: "neutral" → `A04_NewsHistory_Tag_Notice`
|
||||
|
||||
## 로컬라이제이션
|
||||
|
||||
모든 텍스트는 `ui_locales[key][currentLanguageIndex]` 형식으로 [[ui_templates]]에서 로드.
|
||||
하드코딩 금지.
|
||||
|
||||
| UI 요소 | 로케일 키 |
|
||||
|---|---|
|
||||
| 제목 | `A04_NewsHistory_Title` |
|
||||
| 히어로 부제목 | `A04_NewsHistory_Hero_Subtitle` |
|
||||
| 태그 라벨 (feature/fix/notice) | `A04_NewsHistory_Tag_Feature`, `A04_NewsHistory_Tag_Fix`, `A04_NewsHistory_Tag_Notice` |
|
||||
| 빈 상태 메시지 | `A04_NewsHistory_Empty` |
|
||||
|
||||
## 스타일 (CSS)
|
||||
|
||||
### CSS 클래스 구조
|
||||
- `.a04-news-history` — 페이지 래퍼 (flex column, gap: section-gap)
|
||||
- `.a04-hero` — 그래디언트 배경
|
||||
- `.a04-hero__inner` — 중앙 정렬 컨테이너
|
||||
- `.a04-hero__title` — heading-lg, deep-iris, max 18자
|
||||
- `.a04-hero__subtitle` — body 텍스트, slate, max 56자
|
||||
- `.a04-section` — 공통 섹션 (max-width: page-max-width, padding: spacing-32)
|
||||
- `.a04-timeline` — flex 열 (gap: spacing-8)
|
||||
- `.a04-timeline-row` — flex row, 태그+제목+날짜 (gap: spacing-16, padding: spacing-16 spacing-24)
|
||||
- `.a04-timeline-row__title` — flex: 1, body-sm, charcoal
|
||||
- `.a04-timeline-row__date` — caption, ash
|
||||
- `.a04-timeline__empty` — 중앙 정렬, slate, body
|
||||
|
||||
### 반응형
|
||||
- **900px 이하:** 히어로 제목 폰트 축소
|
||||
|
||||
## 의존성
|
||||
|
||||
- [[a00_app_shell_framework]] — 공통 헤더·푸터
|
||||
- [[ui_templates]] — `createTag()` 공통 컴포넌트 + 다국어
|
||||
|
||||
## 미해결 사항
|
||||
|
||||
- MOCK_HISTORY 데이터: 현재 하드코딩 (4개 항목)
|
||||
- 백엔드 API 미구현: `GET /api/a04/history` 코드 주석에 언급됨
|
||||
@@ -0,0 +1,71 @@
|
||||
---
|
||||
status: draft
|
||||
page_id: A05_EduDetail
|
||||
related_pages: ["[[a00_app_shell_framework]]", "[[ui_templates]]", "[[architecture/project_map]]", "[[architecture/public_admin_map]]"]
|
||||
last_updated: 2026-07-12
|
||||
---
|
||||
|
||||
# A05_EduDetail — Frontend
|
||||
|
||||
[[architecture/public_admin_map]]의 공개 교육 경로이며 [[a00_app_shell_framework]]의 SPA 라우터가 이 화면을 로드한다.
|
||||
|
||||
로그인 전 교육 상세 페이지. 교육 과정 소개 + 문의 CTA.
|
||||
|
||||
## 파일 구조
|
||||
|
||||
| 파일 | 위치 | 역할 |
|
||||
|---|---|---|
|
||||
| `A05_EduDetail_UI_Page.ts` | `A05_EduDetail/A05_EduDetail_UI_Page.ts:1-106` | 페이지 렌더링 로직 |
|
||||
| `A05_EduDetail_UI_Style.css` | `A05_EduDetail/A05_EduDetail_UI_Style.css:1-87` | 스타일 (theme.css 변수만 사용) |
|
||||
|
||||
## 컴포넌트 (섹션 빌더)
|
||||
|
||||
| 함수 | 위치 | 역할 |
|
||||
|---|---|---|
|
||||
| `buildHero()` | `A05_EduDetail/A05_EduDetail_UI_Page.ts:33-51` | Hero(제목+부제목), mist-violet→canvas 그라디언트 |
|
||||
| `buildCourses()` | `A05_EduDetail/A05_EduDetail_UI_Page.ts:53-81` | 교육과정 3열 카드그리드(createCard 3개) |
|
||||
| `buildCta()` | `A05_EduDetail/A05_EduDetail_UI_Page.ts:83-95` | 문의 CTA 버튼(variant: filled) |
|
||||
| `renderA05EduDetail()` | `A05_EduDetail/A05_EduDetail_UI_Page.ts:100-105` | 페이지 진입점(3개 섹션 조립) |
|
||||
|
||||
## 로컬라이제이션
|
||||
|
||||
모든 텍스트는 `ui_locales[key][currentLanguageIndex]` 형식으로 [[ui_templates]]에서 로드.
|
||||
하드코딩 금지.
|
||||
|
||||
| UI 요소 | 로케일 키 |
|
||||
|---|---|
|
||||
| 제목 | `A05_EduDetail_Title` |
|
||||
| 히어로 부제목 | `A05_EduDetail_Hero_Subtitle` |
|
||||
| 과정 섹션 제목 | `A05_EduDetail_Course_SectionTitle` |
|
||||
| 과정 1~3 | `A05_EduDetail_Course{1..3}_Title`, `A05_EduDetail_Course{1..3}_Desc` |
|
||||
| CTA 버튼 라벨 | `A05_EduDetail_Cta` |
|
||||
|
||||
## 스타일 (CSS)
|
||||
|
||||
### CSS 클래스 구조
|
||||
- `.a05-edu-detail` — 페이지 래퍼 (flex column, gap: section-gap)
|
||||
- `.a05-hero` — 그래디언트 배경
|
||||
- `.a05-hero__inner` — 중앙 정렬 컨테이너
|
||||
- `.a05-hero__title` — heading-lg, deep-iris, max 18자
|
||||
- `.a05-hero__subtitle` — body 텍스트, slate, max 56자
|
||||
- `.a05-section` — 공통 섹션 (max-width: page-max-width, padding: spacing-32)
|
||||
- `.a05-section__title` — heading-sm, deep-iris, 중앙 정렬
|
||||
- `.a05-course-grid` — 3열 그리드 (gap: spacing-24)
|
||||
- `.a05-course-card` — 카드 (min-height: 140px)
|
||||
- `.a05-course__desc` — body-sm, slate
|
||||
- `.a05-cta` — align-items: center (버튼 중앙 정렬)
|
||||
|
||||
### 반응형
|
||||
- **900px 이하:** 과정 그리드 1열, 히어로 제목 폰트 축소
|
||||
|
||||
## 이벤트 핸들러
|
||||
|
||||
| 함수 | 위치 | 동작 |
|
||||
|---|---|---|
|
||||
| `onA05_EduDetail_Inquiry_Click()` | A05_EduDetail_UI_Page.ts:26-28 | A08_SUPPORT로 이동 |
|
||||
|
||||
## 의존성
|
||||
|
||||
- [[a00_app_shell_framework]] — `navigateTo()` 라우팅
|
||||
- `config_frontend.ts` — `ROUTES` 상수 (A08_SUPPORT)
|
||||
- [[ui_templates]] — `createButton()`, `createCard()` 공통 컴포넌트 + 다국어
|
||||
@@ -0,0 +1,66 @@
|
||||
---
|
||||
status: stable
|
||||
page_id: A06_Login
|
||||
related_pages: ["[[A06_Login/A06_frontend]]", "[[A07_Register/A07_backend]]", "[[A09_Security/A09_backend]]", "[[auth_rbac]]", "[[architecture/project_map]]", "[[architecture/public_admin_map]]"]
|
||||
last_updated: 2026-07-17
|
||||
source: docs/raw/verification/2026-07-17_verify_auth_reverify.md
|
||||
---
|
||||
|
||||
# A06_Login — Backend
|
||||
|
||||
세션 쿠키 기반 로그인 + OTP 재인증 + 디바이스 토큰(기기 신뢰) + 세션/비밀번호 관리 API.
|
||||
|
||||
## 파일 구조
|
||||
|
||||
| 파일 | 세분화 위키 명세 | 역할 |
|
||||
|---|---|---|
|
||||
| `A06_Login_Router.py` | `[[A06_Login/backend/A06_Login_Router]]` | 인증 API 라우터 (prefix `/api/auth`) |
|
||||
| `A06_Login_Schema.py` | `A06_Login/A06_Login_Schema.py` | 요청 검증 Pydantic 모델 3종 |
|
||||
|
||||
## API 엔드포인트
|
||||
|
||||
| 엔드포인트 | 위치 | 역할 |
|
||||
|---|---|---|
|
||||
| `POST /api/auth/login/request` | `A06_Login/A06_Login_Router.py:51` | 1차 로그인(이메일+비번). 신규 브라우저/주기 재인증 시 `otp_required` 반환 |
|
||||
| `POST /api/auth/login/verify` | `A06_Login/A06_Login_Router.py:113` | OTP 검증 후 세션 발급, 디바이스 토큰 쿠키 생성/발급 |
|
||||
| `GET /api/auth/session` | `A06_Login/A06_Login_Router.py:145` | 현재 세션 사용자 조회 (id/email/name/role/company_id/is_master) |
|
||||
| `POST /api/auth/logout` | `A06_Login/A06_Login_Router.py:160` | 세션 삭제 + 쿠키 제거 |
|
||||
| `POST /api/auth/password` | `A06_Login/A06_Login_Router.py:170` | 비밀번호 변경 (현재 비번 검증, 재인증 필요 반환) |
|
||||
|
||||
## 내부 헬퍼
|
||||
|
||||
| 함수 | 위치 | 역할 |
|
||||
|---|---|---|
|
||||
| `_send_otp(user, purpose, label)` | `A06_Login/A06_Login_Router.py:44` | OTP 생성·해시 저장·메일 발송 |
|
||||
| `_finish_login(user, request)` | `A06_Login/A06_Login_Router.py:87` | 세션 생성·로그인 성공 기록, 디바이스 토큰 생성(32바이트) 및 SHA256 해시 DB 저장, 쿠키 설정 |
|
||||
|
||||
## 요청 스키마 (Pydantic)
|
||||
|
||||
| 모델 | 위치 | 필드 |
|
||||
|---|---|---|
|
||||
| `LoginRequest` | `A06_Login/A06_Login_Schema.py:6` | email(EmailStr), password(8~128자) |
|
||||
| `OtpVerifyRequest` | `A06_Login/A06_Login_Schema.py:11` | email(EmailStr), otp_code(정규식 `^\d{6}$`) |
|
||||
| `PasswordChangeRequest` | `A06_Login/A06_Login_Schema.py:16` | current_password, new_password(8~128자), logout_all(기본 True) |
|
||||
|
||||
## 로그인 로직 흐름
|
||||
|
||||
1. `login/request`: 이메일 조회 → 계정 잠금 확인 → 비밀번호 검증 → 계정 상태 확인(`ACTIVE`/`NO_COMPANY`/`PENDING`만 허용)
|
||||
2. **OTP 트리거 조건** (둘 중 하나면 OTP 요구):
|
||||
- 주기적 재인증: `last_email_verified_at`이 `EMAIL_REVERIFY_DAYS`(90일) 이전
|
||||
- 신규 브라우저: `device_token` 쿠키 미보유 또는 DB(`trusted_devices.token_hash`) 대조 불일치
|
||||
3. `login/verify`: OTP 검증 → 소비 → `last_email_verified_at` 갱신 → `_finish_login`
|
||||
4. `_finish_login`: 로그인 실패 초기화 → 디바이스 토큰 발급 및 쿠키(HttpOnly, Secure, SameSite=Lax, Max-Age=90일) 설정 → 세션 생성 (`auth_expires_at` 중복 필드 제거 완료)
|
||||
|
||||
## 보안 정책 (실 코드 기준)
|
||||
|
||||
- **비밀번호 실패**: `record_failed_login()` 누적, 5회 이상 & ADMIN_EMAIL 설정 시 보안 경고 메일 발송
|
||||
- **계정 잠금**: `account_locked_until`이 미래면 423 반환
|
||||
- **로그인 기록**: 모든 시도를 `record_login()`으로 기록(성공/실패 사유 포함)
|
||||
- **디바이스 토큰 신뢰**: 조회 시 `last_used_at`이 90일 이내인 기기 토큰만 유효 처리하며, 로그인 시 `last_used_at`을 주기적으로 갱신
|
||||
|
||||
## 의존성 (공통 유틸)
|
||||
|
||||
- [[common_util]] — `common_util_auth`(세션/OTP/디바이스토큰/쿠키헬퍼), `common_util_auth_repository`(DB 조회), `common_util_email`(메일 발송)
|
||||
- 인증/세션/OTP 정책 상세 → [[auth_rbac]]
|
||||
- `config_system` — `ADMIN_EMAIL`, `EMAIL_REVERIFY_DAYS`
|
||||
|
||||
@@ -0,0 +1,94 @@
|
||||
---
|
||||
status: stable
|
||||
page_id: A06_Login
|
||||
related_pages: ["[[A06_Login/A06_backend]]", "[[A07_Register/A07_frontend]]", "[[auth_rbac]]", "[[architecture/project_map]]", "[[architecture/public_admin_map]]"]
|
||||
last_updated: 2026-07-17
|
||||
source: docs/raw/verification/2026-07-17_verify_auth_reverify.md
|
||||
---
|
||||
|
||||
# A06_Login — Frontend
|
||||
|
||||
로그인 화면. 이메일+비밀번호 1차 → 필요 시 OTP 입력으로 전환하는 단일 폼 (2026-07-17 UX 개선 반영).
|
||||
|
||||
## 파일 구조
|
||||
|
||||
| 파일 | 위치 | 역할 |
|
||||
|---|---|---|
|
||||
| `A06_Login_UI_Auth_Page.ts` | `A06_Login/A06_Login_UI_Auth_Page.ts:1-80` | 로그인 폼 렌더링 + 제출/재발송/뒤로가기 제어 로직 |
|
||||
| `A06_Login_UI_Style.css` | `A06_Login/A06_Login_UI_Style.css:1-52` | 스타일 (theme.css 변수만 사용) |
|
||||
| `A06_Login_Api_Fetch.ts` | `A06_Login/A06_Login_Api_Fetch.ts:1-57` | 인증 API 클라이언트 (`credentials: "include"`) |
|
||||
|
||||
## 컴포넌트 / 함수
|
||||
|
||||
| 함수 | 위치 | 역할 |
|
||||
|---|---|---|
|
||||
| `renderA06Login(root)` | `A06_Login/A06_Login_UI_Auth_Page.ts:17` | 카드+폼(email/password/otp/submit/resend/back) 조립 |
|
||||
| `onA06_Login_Submit_Click(event)` | `A06_Login/A06_Login_UI_Auth_Page.ts:34` | 폼 제출 핸들러(검증→요청→OTP 전환/성공) |
|
||||
| `onA06_Login_Resend_Click()` | `A06_Login/A06_Login_UI_Auth_Page.ts:50` | OTP 재발송 요청 및 60초 쿨다운 비활성화 제어 |
|
||||
| `onA06_Login_Back_Click()` | `A06_Login/A06_Login_UI_Auth_Page.ts:65` | OTP 단계를 취소하고 비밀번호 입력 화면으로 복귀 |
|
||||
|
||||
## API 클라이언트 함수
|
||||
|
||||
| 함수 | 위치 | 역할 |
|
||||
|---|---|---|
|
||||
| `requestLogin(email, password)` | `A06_Login/A06_Login_Api_Fetch.ts:30` | `POST /auth/login/request` |
|
||||
| `verifyLogin(email, otpCode)` | `A06_Login/A06_Login_Api_Fetch.ts:34` | `POST /auth/login/verify` |
|
||||
| `fetchSession()` | `A06_Login/A06_Login_Api_Fetch.ts:38` | `GET /auth/session` → boolean(로그인 여부) |
|
||||
| `fetchSessionUser()` | `A06_Login/A06_Login_Api_Fetch.ts:43` | `GET /auth/session` → SessionUser 객체 |
|
||||
| `logout()` | `A06_Login/A06_Login_Api_Fetch.ts:54` | `POST /auth/logout` |
|
||||
|
||||
- `SessionUser` 타입: id, email, name?, role?, company_id?, is_master?
|
||||
- `fetchSession`/`fetchSessionUser`/`logout`은 [[a00_app_shell_framework]]에서도 사용 (공유 자원)
|
||||
|
||||
## 제출 및 OTP 제어 로직 (2단계 폼 전환)
|
||||
|
||||
1. **초기 화면**: 이메일 유효성 검사 (isBlank/isValidEmail) → 실패 시 필드 에러. `[hidden]` css 속성이 `ui_template_elements.ts` 전역 기본 스타일에 적용되어 OTP 필드는 숨김 상태로 시작.
|
||||
2. **1차 로그인**: 비밀번호 필수 입력 → `requestLogin` 호출
|
||||
3. **OTP 전환 (`status === "otp_required"`)**:
|
||||
- `otpRequired` true 설정. password 필드 숨김, OTP 필드 노출.
|
||||
- 제출 버튼 라벨 → `A06_Login_Verify`
|
||||
- **재발송 버튼 & 뒤로가기 링크 활성화**: 메일 미수신 시 대처할 수 있도록 노출.
|
||||
4. **뒤로가기 클릭**: `otpRequired` 상태를 해제하고, 이메일 필드 활성화 및 비밀번호 필드 표시 상태로 복원.
|
||||
5. **재발송 클릭**: `login/request` API를 재요청하고 60초간 버튼을 비활성화하며 `A06_Login_Resend_Cooldown` 리소스를 기준으로 남은 쿨다운 초수 표시.
|
||||
6. **2차 OTP 검증**: 6자리 숫자 입력 검증 → `verifyLogin` 호출
|
||||
7. **로그인 성공**: 성공 토스트 메시지 표출 후 `navigateTo(ROUTES.B01_ACCOUNT)`로 이동.
|
||||
|
||||
## 로컬라이제이션
|
||||
|
||||
모든 텍스트는 [[ui_templates]]에서 로드. 하드코딩 금지.
|
||||
|
||||
| UI 요소 | 로케일 키 |
|
||||
|---|---|
|
||||
| 제목 | `A06_Login_Title` |
|
||||
| 이메일/비번/OTP 필드 | `A06_Login_Field_Email`, `A06_Login_Field_Password`, `A06_Login_Field_Otp` |
|
||||
| 제출/인증 버튼 | `A06_Login_Submit`, `A06_Login_Verify` |
|
||||
| 회원가입 이동 | `A06_Login_ToRegister` |
|
||||
| 안내/성공 | `A06_Login_OtpSent`, `A06_Login_Success` |
|
||||
| 재발송 / 뒤로가기 / 쿨다운 | `A06_Login_Resend`, `A06_Login_BackToLogin`, `A06_Login_Resend_Cooldown` |
|
||||
| 오류 | `A06_Login_Error_Email`, `A06_Login_Error_Required`, `A06_Login_Error_Request` |
|
||||
|
||||
## 스타일 (CSS)
|
||||
|
||||
- `.a06-login` — 페이지 래퍼 (중앙 정렬, 상단 정렬)
|
||||
- `.a06-login__card` — 로그인 카드 (max-width: 400px, surface 배경, border)
|
||||
- `.a06-login__title` — heading-sm, deep-iris, 중앙 정렬
|
||||
- `.a06-login__form` — flex 열 (gap: spacing-16)
|
||||
- `.a06-login__submit` / `.a06-login__link` — 전체 너비 버튼
|
||||
|
||||
## 이벤트 핸들러
|
||||
|
||||
| 함수 | 위치 | 동작 |
|
||||
|---|---|---|
|
||||
| `onA06_Login_Submit_Click()` | `A06_Login/A06_Login_UI_Auth_Page.ts:34` | 로그인/OTP 제출 |
|
||||
| `onA06_Login_Resend_Click()` | `A06_Login/A06_Login_UI_Auth_Page.ts:50` | OTP 재발송 및 쿨다운 제어 |
|
||||
| `onA06_Login_Back_Click()` | `A06_Login/A06_Login_UI_Auth_Page.ts:65` | 이전 단계 복귀 |
|
||||
| (인라인) 회원가입 버튼 | `A06_Login/A06_Login_UI_Auth_Page.ts:75` | A07_REGISTER로 이동 |
|
||||
|
||||
## 의존성
|
||||
|
||||
- [[a00_app_shell_framework]] — `navigateTo()` 라우팅
|
||||
- `config_frontend.ts` — `ROUTES`, `API_BASE_URL`
|
||||
- `common_util_validate` — `isBlank`, `isValidEmail`
|
||||
- [[ui_templates]] — `createButton`, `createInputField`, `showLoadingOverlay`/`hideLoadingOverlay`, `showToast`
|
||||
- 백엔드 API → [[A06_Login/A06_backend]]
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
---
|
||||
type: file-backend
|
||||
status: draft
|
||||
related_pages: ["[[architecture/project_map]]", "[[architecture/public_admin_map]]"]
|
||||
page_id: A06_Login
|
||||
source_file: "A06_Login/A06_Login_Router.py"
|
||||
last_updated: 2026-07-24
|
||||
---
|
||||
|
||||
# A06_Login_Router.py
|
||||
|
||||
사용자 비밀번호/OTP 로그인, 디바이스 토큰(HttpOnly) 기기 신뢰 90일 만료 재인증, 세션 상태 확인 및 비밀번호 변경 API 라우터 모듈입니다.
|
||||
|
||||
## 🛠️ 라우터 API 및 주요 헬퍼 함수 목록
|
||||
|
||||
| 항목 | 위치(상대 경로) | 역할 |
|
||||
|---|---|---|
|
||||
| `request_login()` | `A06_Login/A06_Login_Router.py` | `POST /api/auth/login/request` — 이메일/비밀번호 1차 검증 (5회 실패 계정 잠금, 90일 정기/신규 브라우저 OTP 발송) |
|
||||
| `verify_login()` | `A06_Login/A06_Login_Router.py` | `POST /api/auth/login/verify` — 2차 OTP 코드 검증 및 로그인 완료 처리 |
|
||||
| `current_session()` | `A06_Login/A06_Login_Router.py` | `GET /api/auth/session` — 현재 접속 세션 사용자 상태 및 역할(role/is_master) 반환 |
|
||||
| `logout()` | `A06_Login/A06_Login_Router.py` | `POST /api/auth/logout` — 세션 쿠키 삭제 및 DB 세션 레코드 폐기 |
|
||||
| `update_password()` | `A06_Login/A06_Login_Router.py` | `POST /api/auth/password` — 현재 비밀번호 확인 후 신규 비밀번호 변경 및 세션 재인증 요구 |
|
||||
| `_finish_login()` | `A06_Login/A06_Login_Router.py` | 디바이스 토큰 생성·저장, 세션 레코드 생성 및 HttpOnly 세션/디바이스 쿠키 바인딩 헬퍼 |
|
||||
| `_send_otp()` | `A06_Login/A06_Login_Router.py` | 6자리 OTP 코드 생성, 해시 저장 및 배경 이메일 발송 헬퍼 |
|
||||
|
||||
## 🔗 연관 개념 및 의존성
|
||||
- `common_util_auth.py` — 세션 쿠키 암호화 및 디바이스 토큰 헬퍼
|
||||
- `common_util_auth_repository.py` — `users`, `sessions`, `device_tokens`, `otp_codes` DB CRUD
|
||||
@@ -0,0 +1,59 @@
|
||||
---
|
||||
status: stable
|
||||
page_id: A07_Register
|
||||
related_pages: ["[[A07_Register/A07_frontend]]", "[[A06_Login/A06_backend]]", "[[auth_rbac]]", "[[architecture/project_map]]", "[[architecture/public_admin_map]]"]
|
||||
last_updated: 2026-07-17
|
||||
source: docs/raw/verification/2026-07-17_verify_auth_reverify.md
|
||||
---
|
||||
|
||||
# A07_Register — Backend
|
||||
|
||||
회원가입(2단계: 요청 → OTP 검증) + 회사 검색 API. prefix `/api/auth` ([[A06_Login/A06_backend]]와 공유).
|
||||
|
||||
## 파일 구조
|
||||
|
||||
| 파일 | 세분화 위키 명세 | 역할 |
|
||||
|---|---|---|
|
||||
| `A07_Register_Router.py` | `[[A07_Register/backend/A07_Register_Router]]` | 회원가입/회사검색 API 라우터 |
|
||||
| `A07_Register_Schema.py` | `A07_Register/A07_Register_Schema.py` | 요청 검증 Pydantic 모델 2종 |
|
||||
|
||||
## API 엔드포인트
|
||||
|
||||
| 엔드포인트 | 위치 | 역할 |
|
||||
|---|---|---|
|
||||
| `GET /api/auth/companies?q=` | `A07_Register/A07_Register_Router.py:26` | 회사명 검색(1~100자) → id/name 목록 |
|
||||
| `POST /api/auth/register/request` | `A07_Register/A07_Register_Router.py:31` | 1차 가입 요청(202). OTP 메일 발송, PENDING_EMAIL 계정 생성 |
|
||||
| `POST /api/auth/register/verify` | `A07_Register/A07_Register_Router.py:57` | OTP 검증 → 가입 완료(NO_COMPANY 상태) 및 디바이스 토큰 발급/신뢰 등록 처리 |
|
||||
|
||||
## 요청 스키마 (Pydantic)
|
||||
|
||||
| 모델 | 위치 | 필드 |
|
||||
|---|---|---|
|
||||
| `RegisterRequest` | `A07_Register/A07_Register_Schema.py:6` | email, password/password_confirm(8~128), name, position?, phone?, terms_version, terms_agreed, privacy_agreed, marketing_agreed |
|
||||
| `RegisterVerifyRequest` | `A07_Register/A07_Register_Schema.py:27` | email(EmailStr), otp_code(정규식 `^\d{6}$`) |
|
||||
|
||||
- `RegisterRequest.validate_registration` (model_validator): 필수 약관 동의 확인 + 비밀번호 일치 확인
|
||||
|
||||
## 가입 로직 흐름
|
||||
|
||||
1. `register/request`:
|
||||
- 기존 이메일 조회 → `PENDING_EMAIL`이 아니면 409(이미 등록됨)
|
||||
- `PENDING_EMAIL`(미인증)이면 `refresh_pending_registration()`으로 갱신
|
||||
- 신규면 `create_registration()`으로 생성
|
||||
- OTP 생성·해시 저장·메일 발송
|
||||
2. `register/verify`:
|
||||
- `PENDING_EMAIL` 상태 확인 → OTP 검증(만료/해시) → 소비
|
||||
- `complete_registration()` → 상태 `NO_COMPANY`로 전환
|
||||
- **디바이스 신뢰 연계**: 무작위 32바이트 디바이스 토큰 생성 → 브라우저 쿠키(`device_token`)에 90일 만료 및 HttpOnly 옵션으로 설정 → 토큰 SHA256 해시를 `trusted_devices` 테이블에 저장하여, 첫 로그인 시 OTP 재인증 단계 생략
|
||||
- **회사 생성/연결은 로그인 후 B01_Dashboard에서 진행** (가입 시점엔 회사 없음)
|
||||
|
||||
## 의존성 (공통 유틸)
|
||||
|
||||
- [[common_util]] — `common_util_auth`(OTP/해시/디바이스토큰/쿠키헬퍼), `common_util_auth_repository`(가입/회사검색/기기신뢰 DB), `common_util_email`(메일)
|
||||
- 사용자 상태 생명주기(PENDING_EMAIL → NO_COMPANY) → [[auth_rbac]]
|
||||
- 회원 테이블 → [[db_schema/users_auth]]
|
||||
|
||||
## 참고
|
||||
|
||||
- 회원가입은 회사 없이 완료됨(NO_COMPANY). 회사 검색 API는 프론트 자동완성용이나,
|
||||
실제 회사 연결은 B01_Dashboard에서 처리 → [[B01_Dashboard/B01_backend]]
|
||||
@@ -0,0 +1,91 @@
|
||||
---
|
||||
status: draft
|
||||
page_id: A07_Register
|
||||
related_pages: ["[[A07_Register/A07_backend]]", "[[A06_Login/A06_frontend]]", "[[auth_rbac]]", "[[architecture/project_map]]", "[[architecture/public_admin_map]]"]
|
||||
last_updated: 2026-07-12
|
||||
---
|
||||
|
||||
# A07_Register — Frontend
|
||||
|
||||
회원가입 화면. 정보 입력 + 약관 아코디언 동의 → OTP 입력으로 전환하는 2단계 폼.
|
||||
|
||||
## 파일 구조
|
||||
|
||||
| 파일 | 위치 | 역할 |
|
||||
|---|---|---|
|
||||
| `A07_Register_UI_Auth_Page.ts` | `A07_Register/A07_Register_UI_Auth_Page.ts:1-208` | **실사용** 회원가입 UI (약관·OTP·실 API) |
|
||||
| `A07_Register_UI_Page.ts` | `A07_Register/A07_Register_UI_Page.ts:1-142` | ⚠️ 구버전 잔재 (미사용, 아래 참고) |
|
||||
| `A07_Register_UI_Style.css` | `A07_Register/A07_Register_UI_Style.css:1-103` | 스타일 (theme.css 변수만 사용) |
|
||||
| `A07_Register_Api_Fetch.ts` | `A07_Register/A07_Register_Api_Fetch.ts:1-47` | 회원가입/회사검색 API 클라이언트 |
|
||||
|
||||
> ⚠️ **라우터는 `A07_Register_UI_Auth_Page`만 사용** (router.ts:30 확인). `A07_Register_UI_Page.ts`는
|
||||
> 회사명+이름+이메일+비번만 받는 단순 폼이며 백엔드 미연동(TODO 주석, `navigateTo`만) — 구버전 잔재로 판단. 정리 권장.
|
||||
|
||||
## 컴포넌트 / 함수 (UI_Auth_Page — 실사용)
|
||||
|
||||
| 함수 | 위치 | 역할 |
|
||||
|---|---|---|
|
||||
| `renderA07Register(root)` | `A07_Register/A07_Register_UI_Auth_Page.ts:68` | 카드+폼 조립, 약관 텍스트 비동기 로드 후 렌더 |
|
||||
| `onA07_Register_Submit_Click(event)` | `A07_Register/A07_Register_UI_Auth_Page.ts:146` | 제출 핸들러(검증→가입요청→OTP 전환→검증) |
|
||||
| `checkboxWithAccordion(label, text)` | `A07_Register/A07_Register_UI_Auth_Page.ts:22` | 체크박스+펼침 상세(약관 본문) 컴포넌트 |
|
||||
| `loadAgreementText(filename)` | `A07_Register/A07_Register_UI_Auth_Page.ts:58` | `resources/legal/*.txt` 약관 파일 fetch |
|
||||
|
||||
## API 클라이언트 함수
|
||||
|
||||
| 함수 | 위치 | 역할 |
|
||||
|---|---|---|
|
||||
| `requestRegistration(payload)` | `A07_Register/A07_Register_Api_Fetch.ts:28` | `POST /auth/register/request` |
|
||||
| `verifyRegistration(email, otpCode)` | `A07_Register/A07_Register_Api_Fetch.ts:32` | `POST /auth/register/verify` |
|
||||
| `searchCompanies(query)` | `A07_Register/A07_Register_Api_Fetch.ts:39` | `GET /auth/companies?q=` → id/name 목록 |
|
||||
|
||||
- `RegisterPayload` 타입: email, password, password_confirm, name, position, phone, terms_version, terms_agreed, privacy_agreed, marketing_agreed
|
||||
|
||||
## 제출 로직 (2단계 폼 전환)
|
||||
|
||||
1. **입력 검증**: 이름/이메일/비번/비번확인 필수, 이메일 형식, 비번 8자 이상, 비번 일치, 필수 약관(terms/privacy) 체크
|
||||
2. `requestRegistration()` 호출 (`terms_version: "1.0"` 고정, terms_agreed/privacy_agreed true)
|
||||
3. 성공 시 `verifyStep = true`: 입력 필드 숨기고 OTP 필드 노출, 버튼 라벨 → `A07_Register_Verify`
|
||||
4. OTP 제출 → `verifyRegistration()` → 성공 토스트 → `navigateTo(ROUTES.A06_LOGIN)`
|
||||
|
||||
## 약관 동의 (아코디언)
|
||||
|
||||
- `checkboxWithAccordion`으로 이용약관/개인정보/마케팅 3종 생성
|
||||
- 약관 본문은 `resources/legal/{terms_of_service,privacy_policy,marketing_consent}.txt`에서 fetch
|
||||
- 마케팅은 선택(marketing_agreed), 이용약관·개인정보는 필수
|
||||
|
||||
## 로컬라이제이션
|
||||
|
||||
모든 텍스트는 [[ui_templates]]에서 로드. 하드코딩 금지.
|
||||
|
||||
| UI 요소 | 로케일 키 |
|
||||
|---|---|
|
||||
| 제목 | `A07_Register_Title` |
|
||||
| 필드 | `A07_Register_Field_Name`, `_Position`, `_Email`, `_Phone`, `_Password`, `_PasswordConfirm`, `_Otp` |
|
||||
| 약관 | `A07_Register_Terms`, `_Privacy`, `_Marketing` |
|
||||
| 제출/인증 | `A07_Register_Submit`, `A07_Register_Verify` |
|
||||
| 안내/성공 | `A07_Register_OtpSent`, `A07_Register_Success` |
|
||||
| 오류 | `A07_Register_Error_Required`, `_Email`, `_Password`, `_PasswordMismatch`, `_Terms`, `_Request` |
|
||||
| 로그인 이동 | `A07_Register_ToLogin` |
|
||||
|
||||
## 스타일 (CSS)
|
||||
|
||||
- `.a07-register__card` — 카드 (max-width: 420px)
|
||||
- `.a07-register__agreement` — 약관 컨테이너(border, overflow hidden)
|
||||
- `.a07-register__agreement-summary` — 체크박스+라벨 헤더(클릭 시 상세 토글)
|
||||
- `.a07-register__agreement-details` / `-content` — 펼침 약관 본문(max-height 200px, pre-wrap)
|
||||
|
||||
## 이벤트 핸들러
|
||||
|
||||
| 함수 | 위치 | 동작 |
|
||||
|---|---|---|
|
||||
| `onA07_Register_Submit_Click()` | `A07_Register/A07_Register_UI_Auth_Page.ts:146` | 가입/OTP 제출 |
|
||||
| (인라인) 로그인 버튼 | `A07_Register/A07_Register_UI_Auth_Page.ts:201` | A06_LOGIN으로 이동 |
|
||||
| (인라인) 약관 요약 클릭 | `A07_Register/A07_Register_UI_Auth_Page.ts:47` | 상세 아코디언 토글 |
|
||||
|
||||
## 의존성
|
||||
|
||||
- [[a00_app_shell_framework]] — `navigateTo()` 라우팅
|
||||
- `config_frontend.ts` — `ROUTES`, `API_BASE_URL`
|
||||
- `common_util_validate` — `isBlank`, `isValidEmail`, `hasMinLength`
|
||||
- [[ui_templates]] — `createButton`, `createInputField`, `showLoadingOverlay`/`hideLoadingOverlay`, `showToast`
|
||||
- 백엔드 API → [[A07_Register/A07_backend]]
|
||||
@@ -0,0 +1,23 @@
|
||||
---
|
||||
type: file-backend
|
||||
status: draft
|
||||
related_pages: ["[[architecture/project_map]]", "[[architecture/public_admin_map]]"]
|
||||
page_id: A07_Register
|
||||
source_file: "A07_Register/A07_Register_Router.py"
|
||||
last_updated: 2026-07-24
|
||||
---
|
||||
|
||||
# A07_Register_Router.py
|
||||
|
||||
신규 회원가입 2단계 (가입 신청 ➡️ 이메일 OTP 검증), 디바이스 신뢰 쿠키 자동 발급 및 소속 회사 검색 API 라우터 모듈입니다.
|
||||
|
||||
## 🛠️ 라우터 API 및 주요 함수 목록
|
||||
|
||||
| 항목 | 위치(상대 경로) | 역할 |
|
||||
|---|---|---|
|
||||
| `find_companies()` | `A07_Register/A07_Register_Router.py` | `GET /api/auth/companies` — 소속 회사 선택용 등록 회사명 검색 |
|
||||
| `request_registration()` | `A07_Register/A07_Register_Router.py` | `POST /api/auth/register/request` — 회원가입 1단계 신청, PENDING_EMAIL 상태 기록 및 OTP 발송 |
|
||||
| `verify_registration()` | `A07_Register/A07_Register_Router.py` | `POST /api/auth/register/verify` — 회원가입 2단계 OTP 검증, 가입 완료(`NO_COMPANY`) 및 디바이스 신뢰 쿠키 발급 |
|
||||
|
||||
## 🔗 연관 개념 및 의존성
|
||||
- `common_util_auth_repository.py` — `create_registration`, `complete_registration`, `trust_device` DB 트랜잭션
|
||||
@@ -0,0 +1,61 @@
|
||||
---
|
||||
status: stable
|
||||
page_id: A08_Support
|
||||
related_pages: ["[[A08_Support/A08_frontend]]", "[[A06_Login/A06_backend]]", "[[db_schema/logs_monitoring]]", "[[architecture/project_map]]", "[[architecture/public_admin_map]]"]
|
||||
last_updated: 2026-07-19
|
||||
source: docs/raw/verification/2026-07-12_verify_add_phase4_role.md
|
||||
---
|
||||
|
||||
# A08_Support — Backend
|
||||
|
||||
기술지원 문의 접수 API. `support_requests` 테이블 저장 + 관리자 알림 메일.
|
||||
|
||||
## 파일 구조
|
||||
|
||||
| 파일 | 세분화 위키 명세 | 역할 |
|
||||
|---|---|---|
|
||||
| `A08_Support_Router.py` | `[[A08_Support/backend/A08_Support_Router]]` | 문의 접수 API (prefix `/api/a08`) |
|
||||
| `A08_Support_Schema.py` | `A08_Support/A08_Support_Schema.py` | 문의 요청 검증 Pydantic 모델 |
|
||||
|
||||
## API 엔드포인트
|
||||
|
||||
| 엔드포인트 | 위치 | 역할 |
|
||||
|---|---|---|
|
||||
| `POST /api/a08/support` | `A08_Support/A08_Support_Router.py:27` | 문의 접수. DB 저장 + ADMIN_EMAIL로 알림 메일 |
|
||||
|
||||
## 내부 헬퍼
|
||||
|
||||
| 함수 | 위치 | 역할 |
|
||||
|---|---|---|
|
||||
| `_get_company_name(company_id)` | `A08_Support/A08_Support_Router.py:16` | company_id로 회사명 조회 (없으면 None) |
|
||||
|
||||
## 요청 스키마 (Pydantic)
|
||||
|
||||
| 모델 | 위치 | 필드 |
|
||||
|---|---|---|
|
||||
| `SupportRequestPayload` | `A08_Support/A08_Support_Schema.py:6` | name(1~255), email(EmailStr), phone?(≤30), subject(1~255), message(1~5000) |
|
||||
|
||||
## 접수 로직
|
||||
|
||||
1. `get_optional_session()`으로 로그인 여부 확인 (비로그인 허용)
|
||||
2. 로그인 상태면 세션의 `company_id` → `_get_company_name()`으로 회사명 조회, 비로그인이면 None
|
||||
3. `support_requests` INSERT (아래 컬럼)
|
||||
4. ADMIN_EMAIL 설정 시 관리자에게 문의 알림 메일 발송
|
||||
|
||||
## DB 저장 컬럼 (실 코드 INSERT 기준)
|
||||
|
||||
`support_requests`에 INSERT하는 컬럼:
|
||||
`company_id, company_name, user_name, user_email, user_phone, subject, message`
|
||||
|
||||
→ 테이블 정의 → [[db_schema/logs_monitoring]]
|
||||
|
||||
## 특징
|
||||
|
||||
- **비로그인도 문의 가능** (`get_optional_session`): 세션 없으면 회사 정보만 None으로 저장
|
||||
- 로그인 상태면 회사 정보 자동 연결
|
||||
|
||||
## 의존성 (공통 유틸)
|
||||
|
||||
- [[common_util]] — `common_util_auth`(`get_optional_session`), `common_util_email`(`send_email_background`), `common_util_email_templates`(`support_request_email`)
|
||||
- `config_system` — `ADMIN_EMAIL`
|
||||
- DB → [[db_schema/logs_monitoring]]
|
||||
@@ -0,0 +1,76 @@
|
||||
---
|
||||
status: draft
|
||||
page_id: A08_Support
|
||||
related_pages: ["[[A08_Support/A08_backend]]", "[[a00_app_shell_framework]]", "[[ui_templates]]", "[[architecture/project_map]]", "[[architecture/public_admin_map]]"]
|
||||
last_updated: 2026-07-12
|
||||
---
|
||||
|
||||
# A08_Support — Frontend
|
||||
|
||||
기술지원 문의 폼. 이름·이메일·연락처·제목·문의내용(textarea) 입력 후 제출.
|
||||
|
||||
## 파일 구조
|
||||
|
||||
| 파일 | 위치 | 역할 |
|
||||
|---|---|---|
|
||||
| `A08_Support_UI_Page.ts` | `A08_Support/A08_Support_UI_Page.ts:1-217` | 문의 폼 렌더링 + 제출 로직 |
|
||||
| `A08_Support_UI_Style.css` | `A08_Support/A08_Support_UI_Style.css:1-64` | 스타일 (theme.css 변수만 사용) |
|
||||
|
||||
## 컴포넌트 / 함수
|
||||
|
||||
| 함수 | 위치 | 역할 |
|
||||
|---|---|---|
|
||||
| `renderA08Support(root)` | `A08_Support/A08_Support_UI_Page.ts:69` | 카드+폼 조립, 세션 정보 자동 채움 |
|
||||
| `onA08_Support_Submit_Click(event)` | `A08_Support/A08_Support_UI_Page.ts:133` | 제출 핸들러(검증→fetch POST) |
|
||||
| `createTextAreaField(label, placeholder)` | `A08_Support/A08_Support_UI_Page.ts:32` | 여러 줄 textarea 필드(에러 슬롯 포함) 생성 |
|
||||
|
||||
## 제출 로직
|
||||
|
||||
1. 필수값 검사(name/email/subject/message), 이메일 형식 검사
|
||||
2. `fetch("/api/a08/support", POST)` 직접 호출 (별도 Api_Fetch 파일 없음)
|
||||
3. 성공: 폼 리셋 + 성공 메시지(`A08_Support_Success`) 표시
|
||||
4. 실패: nameField에 오류 메시지 표시
|
||||
|
||||
## 세션 자동 채움
|
||||
|
||||
- 렌더 후 백그라운드에서 `fetchSessionUser()`([[A06_Login/A06_frontend]]) 호출
|
||||
- 로그인 상태면 name/email 필드 자동 입력 (렌더링 지연 없음)
|
||||
|
||||
## 로컬라이제이션
|
||||
|
||||
모든 텍스트는 [[ui_templates]]에서 로드. 하드코딩 금지.
|
||||
|
||||
| UI 요소 | 로케일 키 |
|
||||
|---|---|
|
||||
| 제목/부제 | `A08_Support_Title`, `A08_Support_Subtitle` |
|
||||
| 필드 | `A08_Support_Field_Name`, `_Email`, `_Phone`, `_Subject`, `_Message` (+각 Placeholder) |
|
||||
| 제출 | `A08_Support_Submit` |
|
||||
| 성공 | `A08_Support_Success` |
|
||||
| 오류 | `A08_Support_Error_Required`, `A08_Support_Error_Email` |
|
||||
|
||||
## 스타일 (CSS)
|
||||
|
||||
- `.a08-support__card` — 카드 (max-width: 520px)
|
||||
- `.a08-support__success` — 성공 메시지(success 색, mist-violet 배경), 기본 hidden
|
||||
- `.a08-support__form` — flex 열 (gap: spacing-16)
|
||||
- `.a08-support__textarea` — resize vertical, min-height 120px
|
||||
- `.a08-support__submit` — 전체 너비 버튼
|
||||
|
||||
## 이벤트 핸들러
|
||||
|
||||
| 함수 | 위치 | 동작 |
|
||||
|---|---|---|
|
||||
| `onA08_Support_Submit_Click()` | `A08_Support/A08_Support_UI_Page.ts:133` | 문의 검증·제출 |
|
||||
|
||||
## 의존성
|
||||
|
||||
- `config_frontend.ts` — (직접 `/api/a08/support` 상대경로 fetch)
|
||||
- `common_util_validate` — `isBlank`, `isValidEmail`
|
||||
- [[A06_Login/A06_frontend]] — `fetchSessionUser` (세션 자동 채움)
|
||||
- [[ui_templates]] — `createButton`, `createInputField` (textarea는 자체 구현)
|
||||
- 백엔드 API → [[A08_Support/A08_backend]]
|
||||
|
||||
## 참고
|
||||
|
||||
- 문의 폼은 로그인/비로그인 모두 사용 가능 (세션 있으면 name/email 자동 입력)
|
||||
- textarea는 공통 컴포넌트에 없어 `createTextAreaField`로 자체 구현 (`.ui-field`/`.ui-input` 스타일 상속)
|
||||
@@ -0,0 +1,23 @@
|
||||
---
|
||||
type: file-backend
|
||||
status: draft
|
||||
related_pages: ["[[architecture/project_map]]", "[[architecture/public_admin_map]]"]
|
||||
page_id: A08_Support
|
||||
source_file: "A08_Support/A08_Support_Router.py"
|
||||
last_updated: 2026-07-24
|
||||
---
|
||||
|
||||
# A08_Support_Router.py
|
||||
|
||||
로그인/비로그인 사용자의 기술지원 및 문의 요청을 접수하여 `support_requests` DB 테이블에 기록하고 관리자 이메일 알림을 격발하는 백엔드 라우터 모듈입니다.
|
||||
|
||||
## 🛠️ 라우터 API 및 주요 함수 목록
|
||||
|
||||
| 항목 | 위치(상대 경로) | 역할 |
|
||||
|---|---|---|
|
||||
| `submit_support_request()` | `A08_Support/A08_Support_Router.py` | `POST /api/a08/support` — 문의 접수, 세션 회사명 조회 결합, `support_requests` INSERT 및 관리자 이메일 발송 |
|
||||
| `_get_company_name()` | `A08_Support/A08_Support_Router.py` | `company_id`로 `companies` 테이블에서 회사명 조회 |
|
||||
|
||||
## 🔗 연관 개념 및 의존성
|
||||
- `common_util_email.py` — `send_email_background` 메일 발송 헬퍼
|
||||
- `common_util_auth.py` — `get_optional_session` 비인가/인가 선택적 세션 추출
|
||||
@@ -0,0 +1,77 @@
|
||||
---
|
||||
status: draft
|
||||
page_id: A09_Security
|
||||
related_pages: ["[[A09_Security/A09_frontend]]", "[[A06_Login/A06_backend]]", "[[A07_Register/A07_backend]]", "[[auth_rbac]]", "[[architecture/project_map]]", "[[architecture/public_admin_map]]"]
|
||||
last_updated: 2026-07-12
|
||||
---
|
||||
|
||||
# A09_Security — Backend
|
||||
|
||||
마스터(회사관리자)·시스템관리자 보안/조직 관리 API + 활동 로그 기록. prefix `/api/security`.
|
||||
|
||||
## 파일 구조
|
||||
|
||||
| 파일 | 세분화 위키 명세 | 역할 |
|
||||
|---|---|---|
|
||||
| `A09_Security_Router.py` | `[[A09_Security/backend/A09_Security_Router]]` | 마스터/시스템관리자/활동로그 API |
|
||||
| `A09_Security_Schema.py` | `A09_Security/A09_Security_Schema.py` | 요청 검증 Pydantic 모델 3종 |
|
||||
|
||||
## API 엔드포인트
|
||||
|
||||
### 마스터(회사 관리자) 전용 — `require_master`
|
||||
|
||||
| 엔드포인트 | 위치 | 역할 |
|
||||
|---|---|---|
|
||||
| `GET /api/security/master/dashboard` | `A09_Security/A09_Security_Router.py:28` | 마스터 대시보드(회사 기준) |
|
||||
| `GET /api/security/master/members` | `A09_Security/A09_Security_Router.py:33` | 회사 팀원 목록 |
|
||||
| `GET /api/security/master/join-requests` | `A09_Security/A09_Security_Router.py:38` | 가입 요청 목록 |
|
||||
| `POST /api/security/master/join-requests/{id}/decision` | `A09_Security/A09_Security_Router.py:43` | 가입 승인/거부 + 결과 메일 발송 |
|
||||
| `POST /api/security/master/members/{id}/remove` | `A09_Security/A09_Security_Router.py:59` | 팀원 비활성화(내보내기) |
|
||||
|
||||
### 시스템 관리자 전용 — `require_system_admin`
|
||||
|
||||
| 엔드포인트 | 위치 | 역할 |
|
||||
|---|---|---|
|
||||
| `GET /api/security/admin/dashboard` | `A09_Security/A09_Security_Router.py:86` | 시스템 대시보드 + psutil 리소스(cpu/memory/disk/process) |
|
||||
| `GET /api/security/admin/{collection}` | `A09_Security/A09_Security_Router.py:101` | 컬렉션 목록(companies/users/support) |
|
||||
| `PATCH /api/security/admin/{entity}/{id}/status` | `A09_Security/A09_Security_Router.py:110` | 엔티티 상태 변경(company/user/support) |
|
||||
|
||||
### 인증 사용자 공통 — `verify_session`
|
||||
|
||||
| 엔드포인트 | 위치 | 역할 |
|
||||
|---|---|---|
|
||||
| `POST /api/security/activity` | `A09_Security/A09_Security_Router.py:66` | 활동 로그 기록(202), `activity_logs` INSERT |
|
||||
|
||||
## 요청 스키마 (Pydantic)
|
||||
|
||||
| 모델 | 위치 | 필드 |
|
||||
|---|---|---|
|
||||
| `JoinDecisionRequest` | `A09_Security/A09_Security_Schema.py:8` | approved(bool), comment?(≤1000) |
|
||||
| `AdminStatusRequest` | `A09_Security/A09_Security_Schema.py:13` | status(3~20), reason(1~500) |
|
||||
| `ActivityLogRequest` | `A09_Security/A09_Security_Schema.py:18` | action_type(Literal 5종), resource_id?, status(SUCCESS/FAILURE), details(dict) |
|
||||
|
||||
- `action_type` Literal: FILE_UPLOAD, FILE_DOWNLOAD, PROJECT_SAVE, DATA_PROCESS, PAGE_VIEW
|
||||
|
||||
## DB 저장 (activity_logs)
|
||||
|
||||
`POST /activity`가 INSERT하는 컬럼: `user_id, action_type, resource_id, status, details(JSON)`
|
||||
→ 테이블 정의 → [[db_schema/logs_monitoring]]
|
||||
|
||||
## 권한 헬퍼
|
||||
|
||||
- `require_master` — 회사 마스터(is_master) 권한
|
||||
- `require_system_admin` — SYSTEM_ADMIN 역할
|
||||
- `verify_session` — 로그인 세션
|
||||
- 권한 체계 상세 → [[auth_rbac]]
|
||||
|
||||
## 의존성 (공통 유틸)
|
||||
|
||||
- [[common_util]] — `common_util_auth`(권한 데코레이터), `common_util_auth_repository`(마스터/관리자 조회·처리), `common_util_email`(가입 결과 메일)
|
||||
- 외부 라이브러리: `psutil`(관리자 대시보드 리소스 계측) → [[dependencies]]
|
||||
- DB → [[db_schema/logs_monitoring]](activity_logs), [[db_schema/users_auth]](join_requests/companies)
|
||||
|
||||
## 참고
|
||||
|
||||
- 이 백엔드 API는 마스터/시스템관리자용이나, **프론트(`A09_Security_UI_Page.ts`)는 약관 열람만 하고 이 API를 사용하지 않음**.
|
||||
API 클라이언트(`A09_Security_Api_Fetch.ts`)는 정의만 되고 미연동 상태 → [[A09_Security/A09_frontend]] 참고
|
||||
- B01_Dashboard의 관리자 기능과 역할이 겹칠 수 있음 (마스터 대시보드/멤버관리) — 향후 연동처 확인 필요
|
||||
@@ -0,0 +1,78 @@
|
||||
---
|
||||
status: draft
|
||||
page_id: A09_Security
|
||||
related_pages: ["[[A09_Security/A09_backend]]", "[[A06_Login/A06_frontend]]", "[[auth_rbac]]", "[[architecture/project_map]]", "[[architecture/public_admin_map]]"]
|
||||
last_updated: 2026-07-12
|
||||
---
|
||||
|
||||
# A09_Security — Frontend
|
||||
|
||||
보안·약관 열람 페이지. 이용약관/개인정보/세션 보안정책 텍스트를 버전과 함께 표시.
|
||||
|
||||
## 파일 구조
|
||||
|
||||
| 파일 | 위치 | 역할 |
|
||||
|---|---|---|
|
||||
| `A09_Security_UI_Page.ts` | `A09_Security/A09_Security_UI_Page.ts:1-30` | **실사용** 약관 열람 페이지 렌더링 |
|
||||
| `A09_Security_Terms.ts` | `A09_Security/A09_Security_Terms.ts:1-16` | 약관 텍스트 데이터(한/영), 버전 상수 |
|
||||
| `A09_Security_UI_Style.css` | `A09_Security/A09_Security_UI_Style.css:1-14` | 스타일 (theme.css 변수만 사용) |
|
||||
| `A09_Security_Api_Fetch.ts` | `A09_Security/A09_Security_Api_Fetch.ts:1-61` | ⚠️ API 클라이언트 (정의만, **미사용** — 아래 참고) |
|
||||
|
||||
> ⚠️ **프론트/백엔드 기능 불일치**: `A09_Security_UI_Page.ts`는 약관 텍스트 열람만 하며
|
||||
> `A09_Security_Api_Fetch.ts`를 import하지 않는다. API 클라이언트(마스터/관리자 8함수)는 정의만 되고
|
||||
> 어디서도 사용되지 않음(grep 확인). 백엔드 API(`/api/security`)는 완비돼 있으나 프론트 연동 미완.
|
||||
|
||||
## 컴포넌트 / 함수
|
||||
|
||||
| 함수 | 위치 | 역할 |
|
||||
|---|---|---|
|
||||
| `renderA09Security(root)` | `A09_Security/A09_Security_UI_Page.ts:7` | 제목+버전+3개 약관 섹션 렌더 |
|
||||
|
||||
## 약관 데이터 (A09_Security_Terms.ts)
|
||||
|
||||
| 항목 | 위치 | 내용 |
|
||||
|---|---|---|
|
||||
| `SECURITY_TERMS_VERSION` | `A09_Security/A09_Security_Terms.ts:1` | 약관 버전 상수 `"1.0"` |
|
||||
| `securityTerms.terms` | `A09_Security/A09_Security_Terms.ts:4` | 이용약관(한/영) |
|
||||
| `securityTerms.privacy` | `A09_Security/A09_Security_Terms.ts:8` | 개인정보(한/영, "IP 미수집" 명시) |
|
||||
| `securityTerms.security` | `A09_Security/A09_Security_Terms.ts:12` | 세션 보안정책(한/영) |
|
||||
|
||||
## API 클라이언트 함수 (⚠️ 미사용, 정의만)
|
||||
|
||||
| 함수 | 위치 | 대응 API |
|
||||
|---|---|---|
|
||||
| `getMasterDashboard()` | `A09_Security/A09_Security_Api_Fetch.ts:14` | `GET /security/master/dashboard` |
|
||||
| `getMembers()` | `A09_Security/A09_Security_Api_Fetch.ts:18` | `GET /security/master/members` |
|
||||
| `getJoinRequests()` | `A09_Security/A09_Security_Api_Fetch.ts:22` | `GET /security/master/join-requests` |
|
||||
| `decideJoinRequest(id, approved, comment?)` | `A09_Security/A09_Security_Api_Fetch.ts:26` | `POST .../join-requests/{id}/decision` |
|
||||
| `removeMember(userId)` | `A09_Security/A09_Security_Api_Fetch.ts:37` | `POST .../members/{id}/remove` |
|
||||
| `getAdminDashboard()` | `A09_Security/A09_Security_Api_Fetch.ts:41` | `GET /security/admin/dashboard` |
|
||||
| `getAdminCollection(collection)` | `A09_Security/A09_Security_Api_Fetch.ts:45` | `GET /security/admin/{collection}` |
|
||||
| `updateAdminStatus(entity, id, status, reason)` | `A09_Security/A09_Security_Api_Fetch.ts:51` | `PATCH /security/admin/{entity}/{id}/status` |
|
||||
|
||||
## 로컬라이제이션
|
||||
|
||||
모든 텍스트는 [[ui_templates]]에서 로드. 하드코딩 금지.
|
||||
|
||||
| UI 요소 | 로케일 키 |
|
||||
|---|---|
|
||||
| 제목/버전 | `A09_Security_Title`, `A09_Security_Version` |
|
||||
| 섹션 제목 | `A09_Security_Terms`, `A09_Security_Privacy`, `A09_Security_Policy` |
|
||||
|
||||
- 약관 본문은 로케일이 아닌 `A09_Security_Terms.ts`에 한/영 배열로 별도 관리(`[currentLanguageIndex]`로 선택)
|
||||
|
||||
## 스타일 (CSS)
|
||||
|
||||
- `.a09-security` — 문서 컨테이너(max-width 800px, surface 배경, border)
|
||||
- `.a09-security section` — 섹션 간격(margin-top: spacing-32)
|
||||
|
||||
## ⚠️ 약관 텍스트와 실 코드 불일치
|
||||
|
||||
`securityTerms.security`는 "세션 12시간 또는 4시간 비활동 후 만료"로 안내하나,
|
||||
A06 실 코드는 `auth_expires_at = NOW() + 3개월` 방식 → [[A06_Login/A06_backend]] 참고.
|
||||
약관 텍스트도 [[auth_rbac]] 계획서 기준으로 작성됨 (실 정책 검증 후 갱신 필요).
|
||||
|
||||
## 의존성
|
||||
|
||||
- [[ui_templates]] — `ui_locales`, `currentLanguageIndex` (다국어)
|
||||
- 백엔드 API(미연동) → [[A09_Security/A09_backend]]
|
||||
@@ -0,0 +1,30 @@
|
||||
---
|
||||
type: file-backend
|
||||
status: draft
|
||||
related_pages: ["[[architecture/project_map]]", "[[architecture/public_admin_map]]"]
|
||||
page_id: A09_Security
|
||||
source_file: "A09_Security/A09_Security_Router.py"
|
||||
last_updated: 2026-07-24
|
||||
---
|
||||
|
||||
# A09_Security_Router.py
|
||||
|
||||
회사 마스터 조직 관리(팀원 승인/제거), 사용자 활동 감사 로그 기록(`activity_logs`) 및 시스템 관리자 전용 서버 자원 모니터링(`psutil`) API 라우터 모듈입니다.
|
||||
|
||||
## 🛠️ 라우터 API 및 주요 함수 목록
|
||||
|
||||
| 항목 | 위치(상대 경로) | 역할 |
|
||||
|---|---|---|
|
||||
| `get_master_dashboard()` | `A09_Security/A09_Security_Router.py` | `GET /api/security/master/dashboard` — 마스터 전용 회사 대시보드 통계 조회 |
|
||||
| `get_members()` | `A09_Security/A09_Security_Router.py` | `GET /api/security/master/members` — 소속 회사 팀원 목록 조회 |
|
||||
| `get_join_requests()` | `A09_Security/A09_Security_Router.py` | `GET /api/security/master/join-requests` — 대기 중인 회사 가입 요청 목록 조회 |
|
||||
| `review_join_request()` | `A09_Security/A09_Security_Router.py` | `POST /api/security/master/join-requests/{id}/decision` — 가입 신청 승인/거절 및 이메일 결과 통보 |
|
||||
| `deactivate_member()` | `A09_Security/A09_Security_Router.py` | `POST /api/security/master/members/{id}/remove` — 소속 팀원 권한 비활성화 |
|
||||
| `write_activity()` | `A09_Security/A09_Security_Router.py` | `POST /api/security/activity` — 사용자 액션 및 리소스 변경 감사 로그 `activity_logs` INSERT |
|
||||
| `get_admin_dashboard()` | `A09_Security/A09_Security_Router.py` | `GET /api/security/admin/dashboard` — 시스템 관리자 메트릭 및 `psutil` 기반 CPU/메모리/디스크 실시간 자원 조회 |
|
||||
| `get_admin_collection()` | `A09_Security/A09_Security_Router.py` | `GET /api/security/admin/{collection}` — 컬렉션별 시스템 관리자 대상 리스팅 |
|
||||
| `set_admin_status()` | `A09_Security/A09_Security_Router.py` | `PATCH /api/security/admin/{entity}/{id}/status` — 엔티티 상태 변경 패치 |
|
||||
|
||||
## 🔗 연관 개념 및 의존성
|
||||
- `common_util_auth.py` — `require_master`, `require_system_admin` RBAC 권한 검증
|
||||
- `common_util_auth_repository.py` — `master_dashboard`, `decide_join_request`, `admin_dashboard` DB 함수
|
||||
@@ -0,0 +1,61 @@
|
||||
---
|
||||
type: page-api
|
||||
status: draft
|
||||
page_id: B01_Dashboard
|
||||
related_pages: ["[[B01_Dashboard/B01_frontend]]", "[[B01_Dashboard/B01_backend]]", "[[B01_Dashboard/B01_db]]", "[[architecture/project_map]]", "[[architecture/workflow_data_flow]]"]
|
||||
last_updated: 2026-08-08
|
||||
source: 상위 프로젝트 B01_Dashboard_Router.py 실 코드 직접 확인 (2026-08-08)
|
||||
---
|
||||
|
||||
# B01_Dashboard — API
|
||||
|
||||
이 API는 [[B01_Dashboard/B01_frontend]]의 요청을 받아 [[B01_Dashboard/B01_backend]]가 처리하며, 인증·오류 규칙은 [[auth_rbac]]과 [[api_common]]을 사용한다.
|
||||
|
||||
기본 prefix: `/api/dashboard` (`B01_Dashboard_Router.py:50`). 공통 인증·오류 형식은 [[auth_rbac]], [[api_common]] 참조.
|
||||
|
||||
## 사용자·회사
|
||||
| 항목 | 위치 | 역할 |
|
||||
|---|---|---|
|
||||
| `GET /me` | `B01_Dashboard_Router.py:88` | 로그인 사용자 대시보드 정보 조회 (하드 삭제 스위치 `project_delete_hard` 포함) |
|
||||
| `PATCH /me` | `B01_Dashboard_Router.py:98` | 내 기본정보 수정 |
|
||||
| `GET /user/projects` | `B01_Dashboard_Router.py:107` | 내 프로젝트와 workflow 상태 조회 |
|
||||
| `GET /user/company` | `B01_Dashboard_Router.py:112` | 소속 회사 조회 |
|
||||
| `GET /user/companies` | `B01_Dashboard_Router.py:117` | 가입 대상 회사 검색 |
|
||||
| `POST /user/company/create` | `B01_Dashboard_Router.py:126` | 회사 생성 후 생성자 연결 |
|
||||
| `POST /user/company/join` | `B01_Dashboard_Router.py:135` | 회사 가입 신청 |
|
||||
|
||||
## 회사 관리자
|
||||
| 항목 | 위치 | 역할 |
|
||||
|---|---|---|
|
||||
| `GET /admin/members` | `B01_Dashboard_Router.py:144` | 회사 팀원 목록 |
|
||||
| `POST /admin/members` | `B01_Dashboard_Router.py:152` | 이메일로 팀원 추가 |
|
||||
| `DELETE /admin/members/{user_id}` | `B01_Dashboard_Router.py:163` | 팀원 회사 연결 해제 |
|
||||
| `GET /admin/join-requests` | `B01_Dashboard_Router.py:172` | 회사 가입 신청 목록 |
|
||||
| `PATCH /admin/join-requests/{request_id}` | `B01_Dashboard_Router.py:177` | 가입 신청 승인·거절 |
|
||||
| `GET /admin/projects` | `B01_Dashboard_Router.py:195` | 회사 프로젝트 목록 |
|
||||
|
||||
## 프로젝트·자동화
|
||||
| 항목 | 위치 | 역할 |
|
||||
|---|---|---|
|
||||
| `PUT /projects/{project_id}` | `B01_Dashboard_Router.py:203` | 프로젝트 기본정보 수정 |
|
||||
| `DELETE /projects/{project_id}` | `B01_Dashboard_Router.py:219` | SYSTEM_ADMIN 프로젝트 삭제 (개발 모드 시 하드 삭제, 운영 모드 시 소프트 삭제 분기) |
|
||||
| `GET /projects/{project_id}/automations` | `B01_Dashboard_Router.py:366` | 자동화 목록; USER 차단 |
|
||||
| `POST /projects/{project_id}/automations` | `B01_Dashboard_Router.py:379` | 자동화 생성 |
|
||||
| `PUT /automations/{automation_id}` | `B01_Dashboard_Router.py:396` | 자동화 수정 |
|
||||
| `DELETE /automations/{automation_id}` | `B01_Dashboard_Router.py:414` | 자동화 삭제 |
|
||||
| `POST /automations/{automation_id}/execute` | `B01_Dashboard_Router.py:429` | 자동화 실행시각 기록 |
|
||||
|
||||
## 시스템 관리자
|
||||
| 항목 | 위치 | 역할 |
|
||||
|---|---|---|
|
||||
| `GET /admin/companies` | `B01_Dashboard_Router.py:246` | 전체 회사 조회 |
|
||||
| `POST /admin/companies` | `B01_Dashboard_Router.py:252` | 시스템 관리자 회사 생성 |
|
||||
| `GET /admin/users` | `B01_Dashboard_Router.py:261` | 전체 사용자 조회 |
|
||||
| `PATCH /admin/users/{user_id}/role` | `B01_Dashboard_Router.py:267` | 역할 변경과 마지막 ADMIN 보호 |
|
||||
| `PUT /admin/users/{user_id}` | `B01_Dashboard_Router.py:285` | 사용자 관리정보 수정 |
|
||||
| `PATCH /admin/users/{user_id}/company` | `B01_Dashboard_Router.py:304` | 사용자 회사 배정·해제 |
|
||||
| `GET /admin/join-requests-all` | `B01_Dashboard_Router.py:316` | 전체 가입 신청 조회 |
|
||||
| `PATCH /admin/join-requests/{request_id}/approve` | `B01_Dashboard_Router.py:322` | 시스템 관리자 가입 승인 |
|
||||
| `GET /admin/audit-logs` | `B01_Dashboard_Router.py:332` | 시스템 감사 로그 페이지 조회 |
|
||||
| `GET /admin/resources` | `B01_Dashboard_Router.py:342` | 1~90일 리소스 통계 조회 |
|
||||
| `GET /admin/projects-all` | `B01_Dashboard_Router.py:351` | 전체 프로젝트 조회 |
|
||||
@@ -0,0 +1,66 @@
|
||||
---
|
||||
type: page-backend
|
||||
status: stable
|
||||
page_id: B01_Dashboard
|
||||
related_pages: ["[[B01_Dashboard/B01_frontend]]", "[[B01_Dashboard/B01_api]]", "[[B01_Dashboard/B01_db]]", "[[B01_Dashboard/B01_dependencies]]", "[[auth_rbac]]", "[[architecture/project_map]]", "[[architecture/workflow_data_flow]]"]
|
||||
last_updated: 2026-08-08
|
||||
source: docs/raw/verification/2026-08-08_verify_project_delete_hard.md
|
||||
---
|
||||
|
||||
# B01_Dashboard — Backend
|
||||
|
||||
## 세분화 백엔드 위키 명세
|
||||
- `[[B01_Dashboard/backend/B01_Dashboard_Router]]`: FastAPI 대시보드 API 엔드포인트 명세
|
||||
- `B01_Dashboard_Repository.py`: Raw SQL 회사, 사용자, 프로젝트 CRUD
|
||||
- `B01_Dashboard_Schema.py`: Pydantic 요청/응답 검증 모델
|
||||
- `common_util_project_delete.py`: 프로젝트 하드 삭제 전용 분리 모듈 (700줄 제한 준수)
|
||||
|
||||
## 라우터 권한 헬퍼
|
||||
| 항목 | 위치(상대 경로) | 역할 |
|
||||
|---|---|---|
|
||||
| `require_company_admin()` | `B01_Dashboard_Router.py` | ADMIN 또는 SYSTEM_ADMIN 의존성 검사 |
|
||||
| `_require_company_id()` | `B01_Dashboard_Router.py` | 세션 회사 ID 필수 검사 |
|
||||
| `_same_company()` | `B01_Dashboard_Router.py` | 요청자와 대상의 회사 일치 검사 |
|
||||
| `_can_edit_project()` | `B01_Dashboard_Router.py` | 역할·회사 기준 프로젝트 수정 검사 |
|
||||
| `_can_manage_automation()` | `B01_Dashboard_Router.py` | 자동화 관리 권한 검사 |
|
||||
| `_can_edit_user()` | `B01_Dashboard_Router.py` | 사용자 수정 범위 검사 |
|
||||
|
||||
상세 권한 규칙은 [[auth_rbac]]에서 1차 정의한다.
|
||||
|
||||
## 저장소 및 삭제 함수
|
||||
| 항목 | 위치 | 역할 |
|
||||
| ----------------------------------------------------------------------------- | ----------------------------------------- | -------------------------- |
|
||||
| `get_dashboard_me()` / `update_user_profile()` | `B01_Dashboard_Repository.py:47,65` | 내 정보 조회(auth_expires_at 대신 `last_email_verified_at + 90일`로 만료일 동적 계산 표시)·수정 |
|
||||
| `get_workflow_states_for_projects()` | `B01_Dashboard_Repository.py:83` | 여러 프로젝트의 workflow 상태 배치 조회 |
|
||||
| `list_user_projects()` / `list_company_projects()` / `list_all_projects()` | `B01_Dashboard_Repository.py:144,165,188` | 역할 범위별 프로젝트 목록 조회 |
|
||||
| `get_project()` / `update_project()` / `soft_delete_project()` | `B01_Dashboard_Repository.py:210,222,253` | 프로젝트 조회·수정·소프트 삭제 |
|
||||
| `hard_delete_project()` | `common_util/common_util_project_delete.py:18` | 프로젝트 DB 삭제(ON DELETE CASCADE 연쇄) 및 영구저장소 디스크 통삭제 |
|
||||
| `get_user_company()` / `search_companies()` | `B01_Dashboard_Repository.py:273,293` | 소속 회사와 회사 검색 |
|
||||
| `create_company()` / `create_system_company()` | `B01_Dashboard_Repository.py:307,347` | 사용자·시스템 관리자 회사 생성 |
|
||||
| `join_company()` | `B01_Dashboard_Repository.py:378` | 회사 가입 신청과 사용자 상태 전이 |
|
||||
| `list_company_members()` / `add_company_member()` / `remove_company_member()` | `B01_Dashboard_Repository.py:401,416,439` | 회사 팀원 관리 |
|
||||
| `list_join_requests()` / `process_join_request()` | `B01_Dashboard_Repository.py:453,471` | 가입 신청 조회·승인·거절 |
|
||||
| `list_all_companies()` / `list_all_users()` | `B01_Dashboard_Repository.py:507,522` | 시스템 관리자 전체 목록 |
|
||||
| `change_user_role()` / `get_user_admin_target()` / `update_admin_user()` | `B01_Dashboard_Repository.py:538,547,562` | 사용자 역할·관리정보 변경 |
|
||||
| `count_company_admins()` / `assign_user_company()` | `B01_Dashboard_Repository.py:584,596` | 마지막 관리자 보호와 회사 배정 |
|
||||
| `list_audit_logs()` / `get_system_resources()` | `B01_Dashboard_Repository.py:609,624` | 감사 로그와 리소스 통계 조회 |
|
||||
| `list_project_automations()` / `create_project_automation()` | `B01_Dashboard_Repository.py:682,696` | 자동화 목록·생성 |
|
||||
| `get_project_automation()` / `update_project_automation()` | `B01_Dashboard_Repository.py:722,735` | 자동화 단건 조회·수정 |
|
||||
| `delete_project_automation()` / `mark_project_automation_executed()` | `B01_Dashboard_Repository.py:758,779` | 자동화 삭제·실행시각 기록 |
|
||||
|
||||
## 요청 스키마
|
||||
| 항목 | 위치 | 역할 |
|
||||
|---|---|---|
|
||||
| `UpdateUserRequest` | `B01_Dashboard_Schema.py:6` | 내 정보 수정 검증 |
|
||||
| `CreateCompanyRequest` | `B01_Dashboard_Schema.py:13` | 회사 생성 검증 |
|
||||
| `JoinCompanyRequest` / `AddMemberRequest` | `B01_Dashboard_Schema.py:20,24` | 회사 가입·팀원 추가 검증 |
|
||||
| `ProcessJoinRequest` / `ChangeUserRoleRequest` | `B01_Dashboard_Schema.py:28,33` | 가입 처리·역할 변경 검증 |
|
||||
| `AssignCompanyRequest` / `UpdateProjectRequest` | `B01_Dashboard_Schema.py:37,41` | 회사 배정·프로젝트 수정 검증 |
|
||||
| `AdminUpdateUserRequest` / `AutomationRequest` | `B01_Dashboard_Schema.py:51,57` | 관리자 사용자 수정·자동화 검증 |
|
||||
|
||||
## 기술부채
|
||||
| 항목 | 위치 | 역할 |
|
||||
|---|---|---|
|
||||
| 레거시 상태 추론 | `B01_Dashboard_Repository.py:20` | `_stage_from_status()`가 `project_workflow_stages` 미조회 시 보조값 생성 |
|
||||
| 700줄 초과 | `B01_Dashboard_Repository.py:1` | 790줄로 프로젝트 단일 파일 제한 초과; 도메인별 저장소 분할 검토 필요 |
|
||||
| 물리적 파일 하드 삭제 모듈 분산 | `common_util_project_delete.py` | 700줄 한계 준수를 위해 신규 파일 삭제 모듈은 레포지토리 외부에 위치 |
|
||||
@@ -0,0 +1,33 @@
|
||||
---
|
||||
type: page-db
|
||||
status: draft
|
||||
page_id: B01_Dashboard
|
||||
related_pages: ["[[B01_Dashboard/B01_backend]]", "[[B01_Dashboard/B01_api]]", "[[architecture/project_map]]", "[[architecture/workflow_data_flow]]"]
|
||||
last_updated: 2026-08-08
|
||||
source: 상위 프로젝트 B01_Dashboard_Repository.py 및 common_util_project_delete.py 실 코드 직접 확인 (2026-08-08)
|
||||
---
|
||||
|
||||
# B01_Dashboard — DB 사용 관계
|
||||
|
||||
공유 테이블의 정의는 concepts에만 둔다. 이 문서는 B01의 사용 목적과 실제 접근 위치만 기록한다.
|
||||
|
||||
| 항목 | 위치 | 역할 |
|
||||
|---|---|---|
|
||||
| `users` | `B01_Dashboard_Repository.py:47` | 내 정보·팀원·전체 사용자·역할·회사 연결 관리 → [[db_schema/users_auth]] |
|
||||
| `companies` | `B01_Dashboard_Repository.py:273` | 소속·검색·생성·전체 회사 조회 → [[db_schema/users_auth]] |
|
||||
| `join_requests` | `B01_Dashboard_Repository.py:378` | 회사 가입 신청·승인·거절 → [[db_schema/users_auth]] |
|
||||
| `projects` | `B01_Dashboard_Repository.py:144`, `common_util_project_delete.py:33` | 역할 범위별 목록·수정·소프트 삭제, 개발 모드 시 하드 삭제 → [[db_schema/projects]] |
|
||||
| `project_workflow_stages` | `B01_Dashboard_Repository.py:83` | 프로젝트 목록의 7단계 상태 배치 조회 → [[workflow_state]] |
|
||||
| `project_automations` | `B01_Dashboard_Repository.py:682` | 자동화 CRUD와 실행시각 기록 → [[db_schema/projects]] |
|
||||
| `system_audit_logs` | `B01_Dashboard_Repository.py:245`, `common_util_project_delete.py:64` | 프로젝트·회사·자동화 관리 행위 기록·조회 → [[db_schema/logs_monitoring]] |
|
||||
| `system_resources` | `B01_Dashboard_Repository.py:624` | 기간별 CPU·메모리·디스크 시계열 조회 → [[db_schema/logs_monitoring]] |
|
||||
|
||||
## 트랜잭션 경계
|
||||
| 항목 | 위치 | 역할 |
|
||||
|---|---|---|
|
||||
| 회사 생성 | `B01_Dashboard_Repository.py:307` | 회사 INSERT, 사용자 연결, 감사 로그를 한 트랜잭션으로 처리 |
|
||||
| 가입 신청 처리 | `B01_Dashboard_Repository.py:471` | `FOR UPDATE`로 신청 행 잠금 후 신청·사용자 상태 동시 변경 |
|
||||
| 프로젝트 수정·소프트 삭제 | `B01_Dashboard_Repository.py:222,253` | 프로젝트 변경과 감사 로그를 같은 트랜잭션으로 처리 |
|
||||
| 프로젝트 하드 삭제 | `common_util_project_delete.py:31` | 프로젝트 SELECT(검증), DELETE 및 `PROJECT_HARD_DELETE` 감사 로그 인서트 성공 시 커밋 |
|
||||
|
||||
> B01 코드가 직접 기록하는 감사 테이블은 `audit_logs`가 아니라 `system_audit_logs`다.
|
||||
@@ -0,0 +1,29 @@
|
||||
---
|
||||
type: page-dependencies
|
||||
status: draft
|
||||
page_id: B01_Dashboard
|
||||
related_pages: ["[[B01_Dashboard/B01_frontend]]", "[[B01_Dashboard/B01_backend]]", "[[architecture/project_map]]", "[[architecture/workflow_data_flow]]"]
|
||||
last_updated: 2026-07-12
|
||||
source: 상위 프로젝트 B01_Dashboard import 구문 직접 확인 (2026-07-12)
|
||||
---
|
||||
|
||||
# B01_Dashboard — Dependencies
|
||||
|
||||
외부 라이브러리의 1차 정의는 [[dependencies]]에 둔다.
|
||||
|
||||
| 항목 | 위치 | 역할 |
|
||||
|---|---|---|
|
||||
| FastAPI | `B01_Dashboard_Router.py:5` | APIRouter·Depends·HTTPException 제공 |
|
||||
| Pydantic | `B01_Dashboard_Schema.py:3` | 요청 모델 타입·범위 검증 |
|
||||
| aiomysql | `B01_Dashboard_Repository.py:10` | MariaDB 비동기 Raw SQL 접근 |
|
||||
| psutil | `B01_Dashboard_Repository.py:11` | 현재 CPU·메모리 사용률 측정 |
|
||||
| `shutil` | `B01_Dashboard_Repository.py:6` | 저장소 디스크 사용량 측정 |
|
||||
| TypeScript DOM | `B01_Dashboard_UI_Page.ts:81` | 역할별 대시보드와 이벤트 구성 |
|
||||
|
||||
## 프로젝트 공통 모듈
|
||||
| 항목 | 위치 | 역할 |
|
||||
|---|---|---|
|
||||
| `common_util_auth` | `B01_Dashboard_Router.py:10` | 세션·SYSTEM_ADMIN 권한 의존성 → [[auth_rbac]] |
|
||||
| `config_db.get_db_pool` | `B01_Dashboard_Repository.py:13` | MariaDB 커넥션 풀 획득 |
|
||||
| `ui_template_elements` | `B01_Dashboard_UI_Resources.ts:2` | 공통 선형 차트 생성 → [[ui_templates]] |
|
||||
| `ui_template_locale` | `B01_Dashboard_UI_Resources.ts:1` | 한·영 UI 문자열 선택 → [[ui_templates]] |
|
||||
@@ -0,0 +1,65 @@
|
||||
---
|
||||
type: page-frontend
|
||||
status: stable
|
||||
page_id: B01_Dashboard
|
||||
related_pages: ["[[B01_Dashboard/B01_backend]]", "[[B01_Dashboard/B01_api]]", "[[B01_Dashboard/B01_db]]", "[[ui_templates]]", "[[architecture/project_map]]", "[[architecture/workflow_data_flow]]"]
|
||||
last_updated: 2026-08-08
|
||||
source: ["docs/raw/verification/2026-08-08_verify_dashboard_scroll_limit.md", "docs/raw/verification/2026-07-17_verify_workflow_stepbar.md"]
|
||||
---
|
||||
|
||||
# B01_Dashboard — Frontend
|
||||
|
||||
## 파일과 진입점
|
||||
| 항목 | 위치 | 역할 |
|
||||
|---|---|---|
|
||||
| `renderB01Dashboard()` | `B01_Dashboard_UI_Page.ts` | 대시보드 조립 및 메인 오케스트레이션 |
|
||||
| `request()` | `B01_Dashboard_Api_Fetch.ts` | 쿠키 포함 요청과 공통 오류 처리 |
|
||||
| `buildResourcePanel()` | `B01_Dashboard_UI_Resources.ts` | CPU·메모리·디스크 현황과 추이 차트 생성 |
|
||||
| `B01_Dashboard_UI_Style.css` | `B01_Dashboard_UI_Style.css` | 대시보드·표·모달 스타일 |
|
||||
|
||||
## 분할된 UI 컴포넌트 파일
|
||||
| 파일 | 역할 | 주요 구성 요소 |
|
||||
|---|---|---|
|
||||
| [[B01_Dashboard/frontend/B01_Dashboard_UI_Page|B01_Dashboard_UI_Page.ts]] | 메인 진입점, 조립 | `renderB01Dashboard`, `loadRoleData`, `buildPage`, `buildHeader` |
|
||||
| `B01_Dashboard_UI_Common.ts` | 공용 빌딩 블록 | `roleLabel` 및 페이지 전용 텍스트/액션 페어, `DASHBOARD_VISIBLE_ROWS = 4` 높이 제한 상수 정의 |
|
||||
| `B01_Dashboard_UI_Projects.ts` | 프로젝트 목록 렌더링 | `projectTable`, `workflow` (4행 제한 `limitVisibleRows` 동적 적용) |
|
||||
| `B01_Dashboard_UI_Company.ts` | 회사 및 멤버 관리 패널 | `buildCompanyPanel`, `memberTable`, `joinRequestTable`, `companyTable` (각 4행 제한 적용) |
|
||||
| `B01_Dashboard_UI_Admin.ts` | 시스템 관리자 전용 뷰 | `userTable`, `auditLogTable` (각 4행 제한 적용) |
|
||||
| `B01_Dashboard_UI_Profile.ts` | 사용자 프로필 및 보안 설정 폼 | `buildProfileForm`, `buildSecurityForm` |
|
||||
| `B01_Dashboard_UI_TempUpload.ts` | 임시 보관함 목록 렌더링 | R2 프로젝트 생성 전 임시 보관함 그룹 렌더링 (4행 스크롤 제한 및 접기/펼치기 토글 시 `remeasureGroups` 재계산 처리) |
|
||||
| `B01_Dashboard_UI_TempModal.ts` | 임시 보관함 등록 모달 | 모달 내부 업로드 진행률(Progress bar) 표시 및 파일 등록 관리 |
|
||||
| `B01_Dashboard_Api_Temp.ts` | 임시 보관함 API 바인딩 | 임시 보관함 묶음/파일 API 호출 |
|
||||
|
||||
## UI 권한 헬퍼
|
||||
| 항목 | 위치 | 역할 |
|
||||
|---|---|---|
|
||||
| `canEditProject()` | `B01_Dashboard_UI_Helper.ts` | 프로젝트 수정 버튼 표시 판단 |
|
||||
| `canDeleteProject()` | `B01_Dashboard_UI_Helper.ts` | SYSTEM_ADMIN 삭제 버튼 표시 판단 |
|
||||
| `canAddUser()` | `B01_Dashboard_UI_Helper.ts` | ADMIN 이상 팀원 추가 표시 판단 |
|
||||
| `canChangeRole()` | `B01_Dashboard_UI_Helper.ts` | SYSTEM_ADMIN 역할 변경 표시 판단 |
|
||||
| `canDeleteUser()` | `B01_Dashboard_UI_Helper.ts` | 사용자 제거 표시 판단 |
|
||||
| `canManageAutomation()` | `B01_Dashboard_UI_Helper.ts` | ADMIN 이상 자동화 관리 표시 판단 |
|
||||
|
||||
> UI 헬퍼는 표시만 제어한다. 최종 권한 검증은 백엔드가 수행한다. 상세: [[auth_rbac]].
|
||||
|
||||
## 모달
|
||||
| 항목 | 위치 | 역할 |
|
||||
|---|---|---|
|
||||
| `openEditProjectModal()` | `B01_Dashboard_UI_Modals.ts` | 프로젝트 기본정보 수정 |
|
||||
| `openDeleteProjectModal()` | `B01_Dashboard_UI_Modals.ts` | 프로젝트 삭제 확인 (`DashboardUser.project_delete_hard` 플래그에 따라 하드 삭제 전용 물리 삭제 경고 문구로 스위칭) |
|
||||
| `openEditUserModal()` | `B01_Dashboard_UI_Modals.ts` | 사용자 정보 수정 |
|
||||
| `openChangeRoleModal()` | `B01_Dashboard_UI_Modals.ts` | 사용자 역할 변경 |
|
||||
| `openDeleteUserModal()` | `B01_Dashboard_UI_Modals.ts` | 사용자 제거 확인 |
|
||||
| `openCreateCompanyModal()` | `B01_Dashboard_UI_Modals.ts` | 회사 생성 |
|
||||
| `openFindCompanyModal()` | `B01_Dashboard_UI_Modals.ts` | 회사 검색·가입 신청 |
|
||||
| `openAddMemberModal()` | `B01_Dashboard_UI_Modals.ts` | 회사 팀원 추가 |
|
||||
| `openAutomationModal()` | `B01_Dashboard_UI_Modals.ts` | 프로젝트 자동화 조회·관리 |
|
||||
| `openTempUploadModal()` | `B01_Dashboard_UI_TempModal.ts` | 임시 보관함 자료 등록 모달 |
|
||||
|
||||
## 공유 자원 연결
|
||||
| 항목 | 위치 | 역할 |
|
||||
|---|---|---|
|
||||
| 인증·역할 | `B01_Dashboard_UI_Page.ts` | 역할별 섹션 제어 → [[auth_rbac]] |
|
||||
| workflow 상태 | `B01_Dashboard_UI_Projects.ts` | 공통 `createStepBar(compact)` 호출 및 배치 `workflow_state` 데이터 매핑 → [[workflow_state]] |
|
||||
| 임시 보관함 | `B01_Dashboard_UI_TempUpload.ts` | R2 임시 보관함 자료 관리 → [[temp_upload]] |
|
||||
| 공통 UI / 높이 제한 | `B01_Dashboard_UI_Projects.ts` | `limitVisibleRows()` 헬퍼를 이용해 4행 제한 안쪽 스크롤 레이아웃 적용 → [[ui_templates]] |
|
||||
@@ -0,0 +1,29 @@
|
||||
---
|
||||
type: file-backend
|
||||
status: draft
|
||||
related_pages: ["[[architecture/project_map]]", "[[architecture/workflow_data_flow]]"]
|
||||
page_id: B01_Dashboard
|
||||
source_file: "B01_Dashboard/B01_Dashboard_Router.py"
|
||||
last_updated: 2026-08-08
|
||||
---
|
||||
|
||||
# B01_Dashboard_Router.py
|
||||
|
||||
역할별(USER, ADMIN, SYSTEM_ADMIN, MASTER) 대시보드, 내 프로젝트 관리, 소속 회사 생성/가입 신청, 팀원 관리 및 시스템 자원 모니터링 API 라우터 모듈입니다.
|
||||
|
||||
## 🛠️ 라우터 API 및 주요 함수 목록
|
||||
|
||||
| 항목 | 위치(상대 경로) | 역할 |
|
||||
|---|---|---|
|
||||
| `dashboard_me()` / `patch_dashboard_me()` | `B01_Dashboard/B01_Dashboard_Router.py` | `GET/PATCH /api/dashboard/me` — 사용자 프로필 조회 및 수정 (GET 응답 `user`에 `project_delete_hard` 포함) |
|
||||
| `user_projects()` | `B01_Dashboard/B01_Dashboard_Router.py` | `GET /api/dashboard/user/projects` — 내 참여/소유 프로젝트 목록 조회 |
|
||||
| `user_company()` / `user_company_create()` | `B01_Dashboard/B01_Dashboard_Router.py` | `GET/POST /api/dashboard/user/company` — 소속 회사 정보 조회 및 신규 회사 생성(마스터 권한 자동 부여) |
|
||||
| `user_company_join()` | `B01_Dashboard/B01_Dashboard_Router.py` | `POST /api/dashboard/user/company/join` — 기존 회사 가입 신청 접수 |
|
||||
| `admin_members()` / `admin_add_member()` / `admin_remove_member()` | `B01_Dashboard/B01_Dashboard_Router.py` | `/api/dashboard/admin/members` — 회사 팀원 목록 조회, 초대 추가 및 제거 |
|
||||
| `admin_join_requests()` / `admin_process_join_request()` | `B01_Dashboard/B01_Dashboard_Router.py` | `/api/dashboard/admin/join-requests` — 회사 가입 신청 목록 조회 및 승인/거절 처리 |
|
||||
| `dashboard_update_project()` / `dashboard_delete_project()` | `B01_Dashboard/B01_Dashboard_Router.py` | `/api/dashboard/projects/{id}` — 권한 체크 기반 프로젝트 정보 수정 및 삭제 (`PROJECT_DELETE_HARD_ENABLED` 스위치에 따라 소프트 또는 하드 삭제 실행) |
|
||||
|
||||
## 🔗 연관 개념 및 의존성
|
||||
- `B01_Dashboard_Repository.py` — Raw SQL 기반 회사, 사용자, 프로젝트 DB 조작
|
||||
- `common_util_project_delete.py` — 프로젝트 하드 삭제 처리 함수 (`hard_delete_project`)
|
||||
- `common_util_auth.py` — `verify_session`, `require_system_admin` 권한 체크
|
||||
@@ -0,0 +1,21 @@
|
||||
---
|
||||
type: file-frontend
|
||||
status: draft
|
||||
related_pages: ["[[architecture/project_map]]", "[[architecture/workflow_data_flow]]"]
|
||||
page_id: B01_Dashboard
|
||||
source_file: "B01_Dashboard/B01_Dashboard_UI_Page.ts"
|
||||
last_updated: 2026-07-24
|
||||
---
|
||||
|
||||
# B01_Dashboard_UI_Page.ts
|
||||
|
||||
프로젝트 대시보드 메인 페이지 조립, 워크플로우 진행 상태 바인딩 및 회사/사용자/시스템 리소스 모니터링 컴포넌트를 연결하는 프론트엔드 UI 페이지 모듈입니다.
|
||||
|
||||
## 🛠️ 주요 함수 목록
|
||||
|
||||
| 항목 | 위치(상대 경로) | 역할 |
|
||||
|---|---|---|
|
||||
| `renderB01Dashboard()` | `B01_Dashboard/B01_Dashboard_UI_Page.ts` | 프로젝트 대시보드 카드, 7단계 진행 배지 및 시스템 자원 모니터링 DOM 렌더링 |
|
||||
|
||||
## 🔗 연관 개념 및 의존성
|
||||
- `B01_Dashboard_UI_Panel.ts` — 대시보드 관리자 제어 패널
|
||||
@@ -0,0 +1,75 @@
|
||||
---
|
||||
status: draft
|
||||
page_id: B02_ProjRegister
|
||||
related_pages: ["[[B02_ProjRegister/B02_frontend]]", "[[B02_ProjRegister/B02_db]]", "[[B01_Dashboard/B01_backend]]", "[[B03_FileInput/B03_backend]]", "[[workflow_state]]", "[[storage_paths]]", "[[architecture/project_map]]", "[[architecture/workflow_data_flow]]"]
|
||||
last_updated: 2026-07-12
|
||||
---
|
||||
|
||||
# B02_ProjRegister — Backend
|
||||
|
||||
신규 임도 설계 프로젝트 생성. DB 저장 + 저장소 폴더 초기화 + 워크플로우 7단계 시드 + 감사 로그.
|
||||
|
||||
> ⚠️ raw structure.md에는 B02가 프론트만 있는 것으로 기재됐으나, 실 코드에 백엔드가 이미 구현됨 (2026-07-12 확인).
|
||||
|
||||
## 파일 구조
|
||||
|
||||
| 파일 | 위치 | 역할 |
|
||||
|---|---|---|
|
||||
| `B02_ProjRegister_Router.py` | `B02_ProjRegister/B02_ProjRegister_Router.py:1-44` | 프로젝트 생성 API (prefix `/api/b02`) |
|
||||
| `B02_ProjRegister_Schema.py` | `B02_ProjRegister/B02_ProjRegister_Schema.py:1-30` | 요청/응답 Pydantic 모델 2종 |
|
||||
| `B02_ProjRegister_Repository.py` | `B02_ProjRegister/B02_ProjRegister_Repository.py:1-136` | Raw SQL 저장소 + 저장소 초기화 |
|
||||
|
||||
## API 엔드포인트
|
||||
|
||||
| 엔드포인트 | 위치 | 역할 |
|
||||
|---|---|---|
|
||||
| `POST /api/b02/project` | `B02_ProjRegister/B02_ProjRegister_Router.py:15` | 신규 프로젝트 생성. `require_company`로 회사 연결 확인 |
|
||||
|
||||
## 함수
|
||||
|
||||
| 함수 | 위치 | 역할 |
|
||||
|---|---|---|
|
||||
| `post_project()` | `B02_ProjRegister/B02_ProjRegister_Router.py:15` | 세션 company_id 검증 → create_project 호출, ValueError→400, 기타→500 |
|
||||
| `create_project()` | `B02_ProjRegister/B02_ProjRegister_Repository.py:44` | 트랜잭션: projects INSERT + 워크플로우 시드 + 감사로그 + 저장소 초기화 |
|
||||
| `get_project_by_id()` | `B02_ProjRegister/B02_ProjRegister_Repository.py:120` | 프로젝트 단건 조회(deleted_at IS NULL) |
|
||||
| `_build_project_storage()` | `B02_ProjRegister/B02_ProjRegister_Repository.py:20` | 저장 경로 생성 + 저장소 루트 이탈 방지 검증 |
|
||||
| `_initialize_project_storage()` | `B02_ProjRegister/B02_ProjRegister_Repository.py:29` | 단계별 폴더 생성 + workflow.json/project_manifest.json 원자적 기록 |
|
||||
|
||||
## 요청/응답 스키마 (Pydantic)
|
||||
|
||||
| 모델 | 위치 | 필드 |
|
||||
|---|---|---|
|
||||
| `CreateProjectRequest` | `B02_ProjRegister/B02_ProjRegister_Schema.py:6` | name(1~255), region(1~100), road_type(main/branch/fire/stream), project_year(2000~2100), estimated_length_m?(≥0), memo?(≤1000) |
|
||||
| `CreateProjectResponse` | `B02_ProjRegister/B02_ProjRegister_Schema.py:17` | project_id, name, region, road_type, project_year, estimated_length_m, memo, status, storage_path, created_at |
|
||||
|
||||
## 생성 로직 (create_project 트랜잭션)
|
||||
|
||||
1. `project_id = uuid4()`, 저장 경로 생성·검증(`_build_project_storage`)
|
||||
2. **트랜잭션 시작**:
|
||||
- `projects` INSERT (status `'NEW'`, crs_epsg `5178` 고정)
|
||||
- `initialize_project_stages(cursor, project_id)` — 워크플로우 7단계 시드 → [[workflow_state]]
|
||||
- `system_audit_logs` INSERT (`PROJECT_CREATE`, resource_type `project`)
|
||||
- `_initialize_project_storage()` — 저장소 폴더 + workflow.json + project_manifest.json
|
||||
- commit (실패 시 rollback)
|
||||
3. 생성된 프로젝트 재조회 후 반환
|
||||
|
||||
## DB 저장 컬럼 (projects INSERT)
|
||||
|
||||
`id, user_id, company_id, name, region, road_type, project_year, estimated_length_m, memo, status('NEW'), crs_epsg(5178), storage_path, created_at, updated_at`
|
||||
→ 테이블 정의 → [[db_schema/projects]]
|
||||
|
||||
## 의존성 (공통 유틸)
|
||||
|
||||
- [[common_util]] — `common_util_auth`(`require_company`), `common_util_json`(`atomic_write_json`), `common_util_storage`(`PROJECT_STORAGE_LAYOUT_V2`), `common_util_workflow`(`load_project_workflow`), `common_util_workflow_state`(`initialize_project_stages`)
|
||||
- 워크플로우 시드 → [[workflow_state]]
|
||||
- 저장소 경로 규칙 → [[storage_paths]]
|
||||
- `config_system` — `STORAGE_BASE_DIR`
|
||||
- DB → [[db_schema/projects]], `system_audit_logs` → [[db_schema/logs_monitoring]]
|
||||
|
||||
## 참고
|
||||
|
||||
- 프로젝트 생성이 워크플로우 진입점: 생성 직후 프론트는 B03_FileInput으로 이동
|
||||
- `workflow.json`은 저장소에 기록되나 실제 단계 판정은 `project_workflow_stages`(DB)가 SSOT → [[workflow_state]]
|
||||
|
||||
|
||||
- 하위 컴포넌트: [[B02_ProjRegister/backend/B02_ProjRegister_Router|B02_ProjRegister_Router]]
|
||||
@@ -0,0 +1,30 @@
|
||||
---
|
||||
status: draft
|
||||
page_id: B02_ProjRegister
|
||||
related_pages: ["[[B02_ProjRegister/B02_backend]]", "[[B02_ProjRegister/B02_frontend]]", "[[db_schema/projects]]", "[[workflow_state]]", "[[architecture/project_map]]", "[[architecture/workflow_data_flow]]"]
|
||||
last_updated: 2026-07-12
|
||||
---
|
||||
|
||||
# B02_ProjRegister — DB
|
||||
|
||||
이 페이지가 쓰는 테이블 (정의는 concepts에, 여기선 용도만).
|
||||
|
||||
## 쓰는 테이블
|
||||
|
||||
| 테이블 | 이 페이지의 용도 | 정의 |
|
||||
|---|---|---|
|
||||
| `projects` | 신규 프로젝트 INSERT (status `'NEW'`, crs_epsg `5178`). 단건 조회 | [[db_schema/projects]] |
|
||||
| `project_workflow_stages` | 생성 시 7단계 시드(`initialize_project_stages`) | [[workflow_state]] |
|
||||
| `system_audit_logs` | `PROJECT_CREATE` 행위 기록 | [[db_schema/logs_monitoring]] |
|
||||
|
||||
## 저장소(파일시스템)
|
||||
|
||||
- `storage/{company_id}/{user_id}/{project_id}/` 생성 + `workflow.json`/`project_manifest.json` 원자적 기록
|
||||
- 경로 생성 책임·규칙 → [[storage_paths]]
|
||||
- `PROJECT_STORAGE_LAYOUT_V2` 기준 단계별 폴더
|
||||
|
||||
## 참고 (계획 당시 의도)
|
||||
|
||||
- 계획서(plan_workflow_state_management)에는 "생성 시 project_workflow_stages 7행 시드"가 마이그레이션 Phase 1 과제로 기재됐으나,
|
||||
**실 코드에 이미 구현됨**(`B02_ProjRegister_Repository.py:90` `initialize_project_stages`). → 규칙6, 실 코드 채택
|
||||
- `workflow.json`도 저장소에 기록되나 단계 판정 SSOT는 `project_workflow_stages`(DB) → [[workflow_state]]
|
||||
@@ -0,0 +1,83 @@
|
||||
---
|
||||
status: draft
|
||||
page_id: B02_ProjRegister
|
||||
related_pages: ["[[B02_ProjRegister/B02_backend]]", "[[B02_ProjRegister/B02_db]]", "[[ui_templates]]", "[[a00_app_shell_framework]]", "[[architecture/project_map]]", "[[architecture/workflow_data_flow]]"]
|
||||
last_updated: 2026-07-12
|
||||
---
|
||||
|
||||
# B02_ProjRegister — Frontend
|
||||
|
||||
신규 임도 설계 프로젝트 등록 폼. 기본정보(이름·지역·임도종류·연도·연장·메모) 입력 → 생성 후 B03으로 이동.
|
||||
|
||||
## 파일 구조
|
||||
|
||||
| 파일 | 위치 | 역할 |
|
||||
|---|---|---|
|
||||
| `B02_ProjRegister_UI_Page.ts` | `B02_ProjRegister/B02_ProjRegister_UI_Page.ts:1-179` | 등록 폼 렌더링 + 제출 로직 |
|
||||
| `B02_ProjRegister_UI_Style.css` | `B02_ProjRegister/B02_ProjRegister_UI_Style.css:1-66` | 스타일 (theme.css 변수만 사용) |
|
||||
|
||||
## 컴포넌트 / 함수
|
||||
|
||||
| 함수 | 위치 | 역할 |
|
||||
|---|---|---|
|
||||
| `renderB02ProjRegister(root)` | `B02_ProjRegister/B02_ProjRegister_UI_Page.ts:35` | 헤더+카드(2열 그리드 폼) 조립 |
|
||||
| `onB02_Proj_Submit_Click()` | `B02_ProjRegister/B02_ProjRegister_UI_Page.ts:96` | 제출 핸들러(검증→fetch POST→B03 이동) |
|
||||
|
||||
## 입력 필드
|
||||
|
||||
| 필드 | 컴포넌트 | 비고 |
|
||||
|---|---|---|
|
||||
| 프로젝트명 | createInputField | 필수 |
|
||||
| 지역 | createInputField | 필수 |
|
||||
| 임도 종류 | createSelectField | main/branch/fire/stream 4종 |
|
||||
| 사업연도 | createInputField(number) | 기본 올해, min 2000/max 올해+5 |
|
||||
| 예상 연장(m) | createInputField(number) | 선택, min 0 |
|
||||
| 메모 | createInputField(text) | 선택 |
|
||||
|
||||
## 제출 로직
|
||||
|
||||
1. **1차 유효성 검사**: name/region 필수, project_year 정수·2000~2100, estimated_length_m ≥0(입력 시)
|
||||
2. `fetch("${API_BASE_URL}/b02/project", POST)` 직접 호출 (별도 Api_Fetch 파일 없음)
|
||||
- body: name, region, road_type, project_year, estimated_length_m, memo
|
||||
3. 성공: `localStorage`에 `CURRENT_PROJECT_ID_KEY`로 project_id 저장 → 성공 토스트 → `navigateTo(ROUTES.B03_FILE_INPUT)`
|
||||
4. 실패: 응답 detail/message 파싱해 에러 토스트
|
||||
|
||||
## 로컬라이제이션
|
||||
|
||||
모든 텍스트는 [[ui_templates]]에서 로드. 하드코딩 금지.
|
||||
|
||||
| UI 요소 | 로케일 키 |
|
||||
|---|---|
|
||||
| 제목/부제 | `B02_Proj_Title`, `B02_Proj_Subtitle` |
|
||||
| 필드 | `B02_Proj_Field_Name`, `_Region`, `_RoadType`, `_Year`, `_Length`, `_Memo` (+각 Placeholder) |
|
||||
| 임도종류 옵션 | `B02_Proj_RoadType_Main`, `_Branch`, `_Fire`, `_Stream` |
|
||||
| 제출/성공 | `B02_Proj_Submit`, `B02_Proj_Success` |
|
||||
| 오류 | `B02_Proj_Error_Required`, `Common_Validation_NumberRange`(공통) |
|
||||
|
||||
## 스타일 (CSS)
|
||||
|
||||
- `.b02-proj` — 페이지 래퍼 (max-width: 720px)
|
||||
- `.b02-proj__header` — 제목+부제
|
||||
- `.b02-proj__grid` — 2열 필드 그리드 (640px 이하 1열)
|
||||
- `.b02-proj__select` — 드롭다운 화살표 여백
|
||||
- `.b02-proj__submit` — 좌측 정렬 버튼
|
||||
- 폼 전체는 `createCard({ raised: true })`로 감쌈
|
||||
|
||||
## 이벤트 핸들러
|
||||
|
||||
| 함수 | 위치 | 동작 |
|
||||
|---|---|---|
|
||||
| `onB02_Proj_Submit_Click()` | `B02_ProjRegister/B02_ProjRegister_UI_Page.ts:96` | 프로젝트 생성 검증·제출 |
|
||||
|
||||
## 의존성
|
||||
|
||||
- [[a00_app_shell_framework]] — `navigateTo()` 라우팅
|
||||
- `config_frontend.ts` — `ROUTES`, `API_BASE_URL`, `CURRENT_PROJECT_ID_KEY`
|
||||
- `common_util_validate` — `isBlank`
|
||||
- [[ui_templates]] — `createButton`, `createInputField`, `createSelectField`, `createCard`, `showLoadingOverlay`/`hideLoadingOverlay`, `showToast`
|
||||
- 백엔드 API → [[B02_ProjRegister/B02_backend]]
|
||||
|
||||
## 참고
|
||||
|
||||
- 프론트가 fetch를 직접 호출 (A08처럼 별도 API 클라이언트 파일 없음)
|
||||
- 프로젝트 생성 성공 시 `CURRENT_PROJECT_ID_KEY`가 이후 워크플로우(B03~) 진입의 컨텍스트가 됨
|
||||
@@ -0,0 +1,21 @@
|
||||
---
|
||||
type: file-backend
|
||||
status: draft
|
||||
related_pages: ["[[architecture/project_map]]", "[[architecture/workflow_data_flow]]"]
|
||||
page_id: B02_ProjRegister
|
||||
source_file: "B02_ProjRegister/B02_ProjRegister_Router.py"
|
||||
last_updated: 2026-07-24
|
||||
---
|
||||
|
||||
# B02_ProjRegister_Router.py
|
||||
|
||||
신규 임도 설계 프로젝트 생성(`POST /api/b02/project`) 트랜잭션 라우터입니다. `projects` 레코드 INSERT, 7단계 워크플로우 상태 시드, 감사 로그 작성 및 저장소 디렉토리 생성을 트랜잭션으로 처리합니다.
|
||||
|
||||
## 🛠️ 주요 함수 목록
|
||||
|
||||
| 항목 | 위치(상대 경로) | 역할 |
|
||||
|---|---|---|
|
||||
| `create_project()` | `B02_ProjRegister/B02_ProjRegister_Router.py` | `POST /api/b02/project` 신규 프로젝트 생성 및 7단계 워크플로우 시드 데이터 트랜잭션 기입 |
|
||||
|
||||
## 🔗 연관 개념 및 의존성
|
||||
- `common_util_workflow_state.py` — 7단계 시드 데이터 초기화
|
||||
@@ -0,0 +1,16 @@
|
||||
---
|
||||
type: page-plan
|
||||
status: draft
|
||||
page_id: B03_FileInput
|
||||
related_pages: ["[[B03_FileInput/B03_backend]]", "[[storage_paths]]", "[[workflow_state]]"]
|
||||
last_updated: 2026-08-18
|
||||
source: ["docs/raw/PLAN.md"]
|
||||
---
|
||||
|
||||
# B03 다중 라이다 파일·대용량 처리 보류 계획
|
||||
|
||||
라이다 원본은 공사 면적에 따라 여러 도엽으로 나뉘지만 현재 파일 종류별 업로드 슬롯은 하나다. 확인된 운용 범위는 평상시 최대 2장·30GB 미만, 최대 3장·50GB 미만이다.
|
||||
|
||||
현재 결정은 구현 보류다. 드론 라이다 프로그램 전처리에서 병합 가능 여부를 먼저 확인하며, 이번 범위에서는 병합 로직과 노선 버퍼 클리핑을 구현하지 않는다. 전처리 분석은 병합된 전체 범위를 대상으로 하는 방침이다.
|
||||
|
||||
착수 전 완료 조건은 드론 프로그램의 병합 가능 여부 확인, 용량 대책 방식 합의, 별도 계획 수립이다.
|
||||
@@ -0,0 +1,35 @@
|
||||
---
|
||||
type: page-api
|
||||
status: stable
|
||||
page_id: B03_FileInput
|
||||
related_pages: ["[[B03_FileInput/B03_frontend]]", "[[B03_FileInput/B03_backend]]", "[[B03_FileInput/B03_db]]", "[[architecture/project_map]]", "[[architecture/workflow_data_flow]]"]
|
||||
last_updated: 2026-07-31
|
||||
source: ["docs/raw/verification/2026-07-31_verify_B03_planned_route_csv.md"]
|
||||
---
|
||||
|
||||
# B03_FileInput — API
|
||||
|
||||
이 API는 [[B03_FileInput/B03_frontend]]의 업로드 요청을 [[B03_FileInput/B03_backend]]에 연결하고 [[workflow_state]]의 stage 0·1 상태를 조회·변경한다.
|
||||
|
||||
기본 prefix: `/api/projects` (`B03_FileInput_Router.py:66`). 세션 인증과 공통 오류 형식은 [[auth_rbac]], [[api_common]]을 참조한다.
|
||||
|
||||
## 일반 업로드
|
||||
| 항목 | 위치 | 역할 |
|
||||
|---|---|---|
|
||||
| `POST /{project_id}/files` | `B03_FileInput_Router.py:267` | 계획노선 CSV (필수) / LAS / TIF / TFW / PRJ / DXF 다중 업로드·검증·메타데이터 등록 |
|
||||
|
||||
## 청크 업로드
|
||||
| 항목 | 위치 | 역할 |
|
||||
|---|---|---|
|
||||
| `POST /{project_id}/upload-sessions` | `B03_FileInput_Router.py:400` | 청크 업로드 세션 생성 |
|
||||
| `POST /{project_id}/chunks` | `B03_FileInput_Router.py:443` | 청크 1개 저장 및 진행률 반환 |
|
||||
| `POST /{project_id}/finalize` | `B03_FileInput_Router.py:507` | 모든 청크 병합·원본 파일 등록 |
|
||||
| `GET /{project_id}/upload-status/{session_id}` | `B03_FileInput_Router.py:623` | 세션 상태·완료 청크 인덱스 조회 |
|
||||
|
||||
## workflow 조회
|
||||
| 항목 | 위치 | 역할 |
|
||||
|---|---|---|
|
||||
| `GET /{project_id}/workflow-state` | `B03_FileInput_Router.py:667` | `current_stage`와 7단계 상태 반환 (필수 계획노선 검증 연동) |
|
||||
|
||||
전체 경로는 `/api/projects/{project_id}/...`이며, workflow 상태 공통 정의는 [[workflow_state]]에 둔다.
|
||||
|
||||
@@ -0,0 +1,63 @@
|
||||
---
|
||||
type: page-backend
|
||||
status: stable
|
||||
page_id: B03_FileInput
|
||||
related_pages: ["[[B03_FileInput/B03_frontend]]", "[[B03_FileInput/B03_api]]", "[[B03_FileInput/B03_db]]", "[[B03_FileInput/B03_dependencies]]", "[[las_free_sheet_surface]]", "[[architecture/project_map]]", "[[architecture/workflow_data_flow]]"]
|
||||
last_updated: 2026-08-30
|
||||
source: ["docs/raw/verification/2026-08-08_verify_server_and_e2e_fixes.md", "docs/raw/verification/2026-08-29_verify_B03_reupload_reanalysis_cache.md"]
|
||||
---
|
||||
|
||||
# B03_FileInput — Backend
|
||||
|
||||
`las_free=true`이면 LAS 필수검사를 면제하고 stage 0 params에 저장해 [[las_free_sheet_surface|도엽등고선 서피스 체인]]으로 분기한다. 청크 세션을 포함한 LAS 업로드는 세션·API·화면에서 차단한다.
|
||||
|
||||
## 입력 검증·파일 처리
|
||||
| 항목 | 위치 | 역할 |
|
||||
|---|---|---|
|
||||
| `FileUploadDescriptor` | `B03_FileInput_Schema.py` | 경로 이탈·확장자·크기 검증 및 계획노선 CSV 헤더(`route_name`, `sequence`, `x`, `y`, `z`, `crs_epsg`), 순번, 수치, 단일 EPSG 일치성 검증 |
|
||||
| `resolve_upload_destination()` | `B03_FileInput_Engine.py` | 프로젝트 WF0 저장 목적지 결정 |
|
||||
| `save_upload_stream()` | `B03_FileInput_Engine.py` | 일반 업로드 스트림 저장 및 계획노선 CSV 원본 보존 |
|
||||
| `resolve_chunk_session_dir()` | `B03_FileInput_Engine.py` | 임시 청크 디렉터리 결정 |
|
||||
| `save_upload_chunk()` / `merge_upload_chunks()` | `B03_FileInput_Engine.py` | 청크 저장·순서 병합 |
|
||||
| `remove_chunk_session()` | `B03_FileInput_Engine.py` | 청크 임시 디렉터리 정리 |
|
||||
| `finalize_project_upload()` | `B03_FileInput_Router.py` | finalize 시 `upload_session` 변수 분리로 404 방지 및 WF1 자동 실행 복구 |
|
||||
| `_complete_file_input_if_ready()` | `B03_FileInput_Router.py:153` | 동일 파일 전송 생략을 포함한 완료 요청에서 하위 산출물·초기설계 상태를 초기화하고 WF1 예약 |
|
||||
|
||||
## 메타데이터 분석 및 파일 지문
|
||||
| 항목 | 위치 | 역할 |
|
||||
|---|---|---|
|
||||
| `normalize_crs_metadata()` | `B03_FileInput_Engine_Analyze.py` | 복합 CRS 수평/수직 분리 및 규격화 (사설 수직 CRS 보존 포함) |
|
||||
| `analyze_las_metadata()` | `B03_FileInput_Engine_Analyze.py` | LAS 포인트 수·범위·밀도 분석 |
|
||||
| `analyze_prj_metadata()` | `B03_FileInput_Engine_Analyze.py` | PRJ CRS 분석 |
|
||||
| `analyze_tfw_metadata()` | `B03_FileInput_Engine_Analyze.py` | TFW 변환계수 분석 |
|
||||
| `analyze_tif_metadata()` | `B03_FileInput_Engine_Analyze.py` | TIF 래스터·CRS·범위 분석 |
|
||||
| `analyze_input_metadata()` | `B03_FileInput_Engine_Analyze.py` | 확장자별 분석 라우팅 |
|
||||
| `B03_FileInput_Fingerprint.ts` | `B03_FileInput_Fingerprint.ts` | SHA-256 파일 지문 기반 중복 전송 스킵 및 다른 파일 변경 시 SUPERSEDED 처리 |
|
||||
|
||||
## 임시 보관함 (R2 Temp Upload)
|
||||
| 항목 | 위치 | 역할 |
|
||||
|---|---|---|
|
||||
| `B03_FileInput_Router_Temp.py` | `B03_FileInput_Router_Temp.py` | 임시 보관함 묶음/파일 CRUD, attach API (`linked` 묶음 대시보드 목록 쿼리 제외) |
|
||||
| `B03_FileInput_Schema_Temp.py` | `B03_FileInput_Schema_Temp.py` | 임시 보관함 Pydantic 스키마 |
|
||||
| `B03_FileInput_Repository_Temp.py` | `B03_FileInput_Repository_Temp.py` | `temp_upload_batches`, `temp_upload_files` Access |
|
||||
| `cleanup_expired_temp_uploads()` | `common_util_temp_cleanup.py` | 30일 경과 만료 임시 보관 자료 자동 삭제 |
|
||||
|
||||
## 저장소 및 초기화
|
||||
| 항목 | 위치 | 역할 |
|
||||
|---|---|---|
|
||||
| `create_input_file()` | `B03_FileInput_Repository.py` | `input_files` 원본 메타데이터 및 계획노선 CSV 용도 등록 |
|
||||
| `get_project_storage_relative_path()` | `B03_FileInput_Repository.py` | 프로젝트 상대 저장경로 조회 |
|
||||
| `create_upload_session()` / `get_upload_session()` | `B03_FileInput_Repository.py` | 청크 세션 생성·조회 |
|
||||
| `upsert_upload_chunk()` / `list_completed_chunk_indexes()` | `B03_FileInput_Repository.py` | 청크 기록·완료 인덱스 조회 |
|
||||
| `reset_project_subsequent_stages()` | `common_util_project_reset.py` | 자료 교체/연결 시 stage 1 이후 하위 단계 산출물 자동 초기화 |
|
||||
|
||||
## workflow·알림
|
||||
| 항목 | 위치 | 역할 |
|
||||
|---|---|---|
|
||||
| `trigger_wf1_analysis_and_email()` | `B03_FileInput_Router.py` | WF1 분석 실행과 완료·실패 이메일 연결 |
|
||||
| `start_stage()` | `B03_FileInput_Router.py` | WF1 시작, stage 1 IN_PROGRESS 전이 (동시 실행 가드 및 stage 3 완료 스피너 잠금) |
|
||||
| `complete_stage()` | `B03_FileInput_Router.py` | WF0/WF1 완료 전이 (계획노선 CSV 필수 검증 후 전이 허용) |
|
||||
| `fail_stage()` | `B03_FileInput_Router.py` | WF1 실패 전이 (`fail_stage` 메시지 200자 제한 클램프) |
|
||||
| `get_project_workflow_state()` | `B03_FileInput_Router.py` | 단일 프로젝트 workflow 상태 반환 |
|
||||
|
||||
workflow 정의: [[workflow_state]], 저장경로: [[storage_paths]], 임시보관함: [[temp_upload]].
|
||||
@@ -0,0 +1,29 @@
|
||||
---
|
||||
type: page-db
|
||||
status: draft
|
||||
page_id: B03_FileInput
|
||||
related_pages: ["[[B03_FileInput/B03_backend]]", "[[B03_FileInput/B03_api]]", "[[architecture/project_map]]", "[[architecture/workflow_data_flow]]"]
|
||||
last_updated: 2026-07-12
|
||||
source: 상위 프로젝트 B03_FileInput_Repository.py 실 코드 직접 확인 (2026-07-12)
|
||||
---
|
||||
|
||||
# B03_FileInput — DB 사용 관계
|
||||
|
||||
공유 테이블 정의는 [[db_schema/files_surface]]에서 1차 관리한다.
|
||||
|
||||
| 항목 | 위치 | 역할 |
|
||||
|---|---|---|
|
||||
| `input_files` | `B03_FileInput_Repository.py:11` | 원본 파일 유형·상대경로·크기·메타데이터 등록 |
|
||||
| `upload_sessions` | `B03_FileInput_Repository.py:89` | 청크 업로드 세션과 전체 파일 정보 저장 |
|
||||
| `upload_chunks` | `B03_FileInput_Repository.py:165` | 청크 인덱스·해시·크기 저장 |
|
||||
| `projects` | `B03_FileInput_Router.py:111` | 업로드·WF1 진행상태 호환 캐시 갱신 |
|
||||
| `project_workflow_stages` | `B03_FileInput_Router.py:175` | stage 0/1 시작·완료·실패 전이와 상태 조회 |
|
||||
|
||||
## 파일 경로
|
||||
| 항목 | 위치 | 역할 |
|
||||
|---|---|---|
|
||||
| 원본 입력 | `B03_FileInput_Engine.py:15` | `B03_FileInput/input/{file_type}/`에 저장 |
|
||||
| 청크 임시파일 | `B03_FileInput_Engine.py:64` | 프로젝트 저장소 하위 임시 세션 디렉터리 사용 |
|
||||
| DB 저장값 | `B03_FileInput_Repository.py:64` | 프로젝트 루트 기준 상대경로 저장 |
|
||||
|
||||
경로 규칙 상세: [[storage_paths]].
|
||||
@@ -0,0 +1,30 @@
|
||||
---
|
||||
type: page-dependencies
|
||||
status: draft
|
||||
page_id: B03_FileInput
|
||||
related_pages: ["[[B03_FileInput/B03_frontend]]", "[[B03_FileInput/B03_backend]]", "[[architecture/project_map]]", "[[architecture/workflow_data_flow]]"]
|
||||
last_updated: 2026-07-12
|
||||
source: 상위 프로젝트 B03_FileInput import 구문 직접 확인 (2026-07-12)
|
||||
---
|
||||
|
||||
# B03_FileInput — Dependencies
|
||||
|
||||
공유 의존성의 1차 정의는 [[dependencies]]에 둔다.
|
||||
|
||||
| 항목 | 위치 | 역할 |
|
||||
|---|---|---|
|
||||
| FastAPI | `B03_FileInput_Router.py:10` | multipart 파일·폼 요청과 라우터 |
|
||||
| Pydantic | `B03_FileInput_Schema.py:6` | 파일명·크기·확장자·청크 요청 검증 |
|
||||
| aiomysql | `B03_FileInput_Router.py:9` | MariaDB 비동기 트랜잭션 |
|
||||
| laspy | `B03_FileInput_Engine_Analyze.py:7` | LAS 포인트클라우드 메타데이터 분석 |
|
||||
| rasterio | `B03_FileInput_Engine_Analyze.py:9` | TIF 래스터 메타데이터 분석 |
|
||||
| pyproj | `B03_FileInput_Engine_Analyze.py:10` | PRJ/TIF CRS 해석 |
|
||||
| numpy | `B03_FileInput_Engine_Analyze.py:8` | LAS 통계 계산 |
|
||||
|
||||
## 공통 모듈
|
||||
| 항목 | 위치 | 역할 |
|
||||
|---|---|---|
|
||||
| `common_util_storage` | `B03_FileInput_Engine.py:11` | 단계별 저장경로 생성·해석 → [[storage_paths]] |
|
||||
| `common_util_workflow_state` | `B03_FileInput_Router.py:50` | stage 상태 전이 → [[workflow_state]] |
|
||||
| `common_util_email` | `B03_FileInput_Email.py:8` | 업로드·분석 완료/실패 이메일 발송 |
|
||||
| `common_util_json` | `B03_FileInput_Router.py:47` | workflow 보조 JSON 원자적 저장 |
|
||||
@@ -0,0 +1,49 @@
|
||||
---
|
||||
type: page-frontend
|
||||
status: stable
|
||||
page_id: B03_FileInput
|
||||
related_pages: ["[[B03_FileInput/B03_backend]]", "[[B03_FileInput/B03_api]]", "[[B03_FileInput/B03_db]]", "[[las_free_sheet_surface]]", "[[architecture/project_map]]", "[[architecture/workflow_data_flow]]"]
|
||||
last_updated: 2026-08-30
|
||||
source: ["docs/raw/verification/2026-07-31_verify_B03_planned_route_csv.md", "docs/raw/verification/2026-08-29_verify_B03_reupload_reanalysis_cache.md"]
|
||||
---
|
||||
|
||||
# B03_FileInput — Frontend
|
||||
|
||||
`las_free` 토글은 LAS 카드와 필수검증을 비활성화하고 계획노선·도엽등고선만으로 WF1을 실행한다. 상세 계약은 [[las_free_sheet_surface]]를 따른다.
|
||||
|
||||
## 페이지·업로드 흐름
|
||||
| 항목 | 위치 | 역할 |
|
||||
|---|---|---|
|
||||
| `renderB03FileInput()` | `B03_FileInput_UI_Page.ts:52` | 일반업무 레이아웃(`createGeneralLayout`) 적용 및 계획노선 CSV 선택 필수 입력 영역 조립 |
|
||||
| 청크 세션 생성 | `B03_FileInput_UI_Page.ts` | 대용량 파일을 청크 업로드로 시작 |
|
||||
| 청크 병합 완료 | `B03_FileInput_UI_Page.ts` | 서버 병합 결과를 상태에 저장 |
|
||||
| 필수 파일 검증 | `B03_FileInput_UI_Page.ts` | 계획노선 CSV 누락/오류 시 B04 이동 버튼 차단 |
|
||||
| WF1 진행률 폴링 | `B03_FileInput_UI_Page.ts` | 분석 상태와 진행률 갱신 |
|
||||
| 업로드 완료 캐시 정리 | `B03_FileInput_UI_Page.ts:71` | route 최신값·section detail·preload 표식을 제거해 B05가 재분석 결과를 조회 |
|
||||
| B04 이동 | `B03_FileInput_UI_Page.ts` | WF1 및 필수 계획노선 검증 완료 시 `ROUTES.B04_WF1_SURFACE`로 이동 |
|
||||
|
||||
## UI 지원 유틸리티 (분할 완료)
|
||||
| 항목 | 위치 | 역할 |
|
||||
|---|---|---|
|
||||
| 카드 템플릿 및 포맷터 | `B03_FileInput_UI_Support.ts` | UI 생성 템플릿 및 파일 크기/ETA 포맷터 등 분리하여 단일 파일 700줄 제한 준수 |
|
||||
|
||||
## API 클라이언트
|
||||
| 항목 | 위치 | 역할 |
|
||||
|---|---|---|
|
||||
| `uploadProjectFiles()` | `B03_FileInput_Api_Fetch.ts:60` | 계획노선 CSV 및 지형 다중 파일 업로드 |
|
||||
| `createUploadSession()` | `B03_FileInput_Api_Fetch.ts:82` | 청크 세션 생성 |
|
||||
| `uploadFileChunk()` | `B03_FileInput_Api_Fetch.ts:100` | 단일 청크 전송 |
|
||||
| `finalizeUploadSession()` | `B03_FileInput_Api_Fetch.ts:119` | 청크 병합 요청 |
|
||||
| `fetchUploadStatus()` | `B03_FileInput_Api_Fetch.ts:133` | 청크 업로드 상태 조회 |
|
||||
| `checkWF1AnalysisStatus()` | `B03_FileInput_Api_Fetch.ts:154` | WF1 분석 상태 조회 |
|
||||
|
||||
## 브라우저 상태·오프라인 보조
|
||||
| 항목 | 위치 | 역할 |
|
||||
|---|---|---|
|
||||
| `loadB03ProjectState()` | `B03_FileInput_State.ts:23` | 프로젝트별 저장 상태 복원 |
|
||||
| `saveB03UploadedFile()` | `B03_FileInput_State.ts:34` | 업로드 파일 결과 저장 |
|
||||
| `updateB03AnalysisState()` | `B03_FileInput_State.ts:53` | 분석 상태·진행률 저장 |
|
||||
| `restoreB03ProjectState()` | `B03_FileInput_State.ts:71` | 재진입 시 상태와 완료 콜백 복원 |
|
||||
|
||||
공통 UI는 [[ui_templates]], 단계 상태는 [[workflow_state]]를 참조한다.
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
---
|
||||
type: page-backend
|
||||
status: stable
|
||||
page_id: B03_FileInput
|
||||
related_pages: ["[[B03_FileInput/B03_backend]]", "[[B03_FileInput/B03_frontend]]", "[[B04_PreProcess/B04_drainage_compass_crs]]", "[[completed_2026-09-03]]"]
|
||||
last_updated: 2026-09-03
|
||||
source: ["docs/raw/plans/2026-09-03_plan_completed_items.md"]
|
||||
---
|
||||
|
||||
# B03 계획노선 정본·좌표계 후속
|
||||
|
||||
## 계획노선 정본
|
||||
|
||||
| 항목 | 위치 | 역할 |
|
||||
|---|---|---|
|
||||
| `save_initial_snapshot()` | `common_util/common_util_initial_snapshot.py` | 사업지 좌표계로 변환·트림·조밀화한 `planned_route.csv`를 초기값 정본으로 저장 |
|
||||
| 스냅샷 체인 | `B03_FileInput/B03_FileInput_Service_Chain.py` | 체인에서 만든 계획노선 점을 정본 저장 창구에 전달 |
|
||||
| `load_design_route()` | `common_util/common_util_route_geometry.py` | `surface_params`가 있는 설계 호출은 초기값 CSV를 우선 사용 |
|
||||
| `discard_initial_snapshot()` | `common_util/common_util_initial_snapshot.py` | 지표면·노선 변경 시 CSV를 포함한 초기 스냅샷 폐기 |
|
||||
|
||||
프론트엔드는 업로드한 원본 파일명을 표시하고, 백엔드는 변환 CSV를 계산 정본으로 사용한다. 트림 전 범위가 필요한 호출은 원본 경로를 유지한다.
|
||||
|
||||
## LAS 없는 설계와 업로드 상태
|
||||
|
||||
| 항목 | 위치 | 역할 |
|
||||
|---|---|---|
|
||||
| `run_sheet_surface_analysis()` | `B04_PreProcess/B04_PreProcess_Engine_SheetSurface.py` | 공통 계획노선 로더와 지형 PRJ 좌표계로 도엽 서피스 생성 |
|
||||
| `download_geodata()` | `B04_PreProcess/` | 노선 PRJ가 아닌 지형 PRJ 폴더에서 도엽 좌표계 탐색 |
|
||||
| `lasFreeCheck` change | `B03_FileInput/B03_FileInput_UI_Page.ts` | 토글 직후 필수 슬롯과 업로드 버튼 활성 상태 재평가 |
|
||||
|
||||
검증 자료에서는 변환 정본 643점, 최대 좌표차 0.00007m, 연장 2136.2m가 원본 처리 결과와 일치했고 LAS 없는 자동 체인이 완료됐다.
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user