This commit is contained in:
2026-07-15 18:33:33 +09:00
parent 6b1583103f
commit f533082537
201 changed files with 19776 additions and 563 deletions
+74
View File
@@ -0,0 +1,74 @@
---
type: concept
status: stable
related_pages: ["[[B01_Dashboard/B01_backend]]", "[[B02_ProjRegister/B02_backend]]", "[[B03_FileInput/B03_backend]]", "[[B04_wf1_Surface/B04_backend]]", "[[B05_wf2_Route/B05_backend]]", "[[B06_wf3_ProfileCross/B06_backend]]", "[[B07_wf4_DesignDetail/B07_frontend]]", "[[B08_wf5_Quantity/B08_frontend]]", "[[B09_wf6_Estimation/B09_frontend]]"]
last_updated: 2026-07-12
source: raw/plans/plan_workflow_state_management.md (계획, 2026-07-10) + 실 코드/DB 직접 확인 (2026-07-12)
---
# Workflow 상태 관리 — 구현 완료 (실 DB 확인됨)
> **status: stable.** 2026-07-12 실 코드 전수 확인 + DB 직접 접속(`SHOW TABLES`/`DESCRIBE`)으로 검증. 계획서(2026-07-10)의 설계가 **B01~B06 전 단계에 이미 적용 완료**됨. 정식 검증보고서는 없지만 코드·DB 실측이 계획과 일치해 stable로 채택. 남은 잔재 1건은 아래 참고.
## SSOT: `project_workflow_stages` 테이블 (실 DB 확인)
| 컬럼 | 타입 |
| --------------------------------------------- | -------------------------------------------------------------------------------------------------------------- |
| id | INT PK |
| project_id | CHAR(36), FK |
| stage_no | TINYINT (0~6) |
| stage_key | VARCHAR(30) — FILE_INPUT/WF1_SURFACE/WF2_ROUTE/WF3_PROFILE_CROSS/WF4_DESIGN_DETAIL/WF5_QUANTITY/WF6_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` (기존 프로젝트 `projects.status` 해석 후 시드)
## 공통 유틸 `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` 계산 포함 |
## 실 연동 현황 (파일:줄번호)
| 페이지 | 위치 | 연동 stage_no |
|---|---|---|
| [[B02_ProjRegister/B02_backend|B02_ProjRegister]] | `B02_ProjRegister_Repository.py:90` `initialize_project_stages` 호출 | 시드(0~6) |
| [[B03_FileInput/B03_backend|B03_FileInput]] | `B03_FileInput_Router.py:175,224,256,347,570` | stage 0, 1 |
| [[B04_wf1_Surface/B04_backend|B04_wf1_Surface]] | `B04_wf1_Surface_Router.py:168,209,227,233` | stage 1 |
| [[B05_wf2_Route/B05_backend|B05_wf2_Route]] | `B05_wf2_Route_Router.py:51,96,112,117,122,128,152` | stage 2 |
| [[B06_wf3_ProfileCross/B06_backend|B06_wf3_ProfileCross]] | `B06_wf3_ProfileCross_Router.py:68,111,127,132,137,143,187` | stage 3 |
| [[B01_Dashboard/B01_backend|B01_Dashboard]] | `B01_Dashboard_Repository.py:83` `get_workflow_states_for_projects()` (배치 조회, 프로젝트 목록에 `workflow_state` 필드 포함) | 조회 전용 |
## 조회 API (실제 존재, 계획서와 경로 일치)
`GET /{project_id}/workflow-state``B03_FileInput_Router.py:667`
```json
{"status": "success", "workflow_state": {"project_id": "...", "current_stage": 2, "stages": [...]}}
```
실제 전체 경로는 B03 라우터 prefix를 포함한 `/api/projects/{project_id}/workflow-state`이다.
## 상태 전이 (구현대로)
```
NOT_STARTED → IN_PROGRESS → COMPLETE
└→ FAILED → (재실행) IN_PROGRESS
COMPLETE → (하위 단계 재작업) → STALE → (재실행) IN_PROGRESS
```
stage N이 IN_PROGRESS 전이 시 N+1~6의 COMPLETE를 전부 STALE로 전파 (`start_stage` 내부 UPDATE 쿼리로 확인됨).
## projects.status 문자열 캐시 (호환용, 계획서 방침대로 유지 중)
`start_stage`/`complete_stage`/`fail_stage``project_workflow_stages``projects.status`**동시에** 갱신 (`WF{n}_ANALYZING`/`WF{n}_COMPLETE`/`WF{n}_FAILED`, stage6 COMPLETE 시 `DONE`).
## B04 상태 조회 — 레거시 폴백 (당초 "잔재"로 표기했으나 정정)
`get_wf1_analysis_status()`([[B04_wf1_Surface/B04_backend]], `B04_wf1_Surface_Router.py:372`)는
`project_workflow_stages`(SSOT)를 **우선** 조회하고, 행이 없을 때만(백필 미작동 대비)
`projects.status` 문자열 비교로 폴백함(416 `WF1_COMPLETE`, 420 `WF1_ANALYZING`, `:412-427`).
→ B04 실 코드 확인 결과 **정상 경로가 아닌 방어적 폴백**. SSOT 안정화 후 제거 가능하나 현재는 안전장치로 유효.
별개로 `update_project_status()`(`:76`)는 정의만 있고 미호출(죽은 코드) → 정리 권장.
## 미해결 사항 (계획서 원문, 아직 결정 안 됨)
- `projects.status` 완전 제거 여부 — 현재는 유지 중(위 확인)
- STALE 하위 결과 파일: 즉시 삭제 vs 재실행 시 덮어쓰기 — 코드 레벨 확인 안 함, 별도 점검 필요