feat(496-2 단계 상태): [저장] · [>] 가 바꾸는 진행 단계 한 곳 — 요구 298-2 · 300 B1

- 공용 mark_stage — save = 그 단계 진행 중 · 뒤 완료 · 진행 중 → 낡음 / next = 그 단계 완료 · 다음 미시작 · 낡음 → 진행 중
- B05 · B06 한 본문 [저장] = 단계 2 · 3 save(빈 본문 · [>] 확정 제외) · B06 [>] = 2 완료 · 3 next
- B07 장 [저장] = 4 save · B07 [>] = 4 next
- B08 [저장] 넷(옵션 · 자재 · 수문 · 이정) = 5 save · 새 POST quantity/complete = 5 next
- B09 [저장] = 6 save · 새 POST estimation/complete = 6 next
- 자동설계 체인(mark_stage_complete=False) 그대로
- 새 시험 test_298_2_stage_state · 이웃 시험 셋 기대값 맞춤

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-20 19:54:51 +09:00
co-authored by Claude Opus 5.5
parent 5392680ec1
commit dcb7c68685
13 changed files with 375 additions and 21 deletions
+12
View File
@@ -4,6 +4,8 @@
입력(굳힌 단가 · 수요 · B08 수량) + 사용자 값 → 표 전부
PUT /api/projects/{id}/estimation {user}
[저장] — 사용자 값 · 책에 없는 새 단가 줄만 굳힘 → 서버가 정본으로 다시 셈
POST /api/projects/{id}/estimation/complete
[>] — 단계 6 완료 · 프로젝트 DONE(요구 300 B1 · 본문 없음)
POST /api/projects/{id}/estimation/prices {user?}
[단가 갱신] — 수요 단가 전부를 지금 M01 값으로 새로 굳힘 · user = 화면 캐시(296 ·
지운 줄 · 그 사본은 수요에서 뺌 · 저장은 안 함) · M01 원본이 지워진 줄 = 굳힌 값 그대로
@@ -61,6 +63,7 @@ from B09_Estimation.B09_Estimation_Rates import rate_candidates, rate_table
from B09_Estimation.B09_Estimation_Router_Quotes import router as quotes_router
from B09_Estimation.B09_Estimation_Summary import compute_summary, hopyo_lines, used_materials
from common_util.common_util_auth import verify_session
from common_util.common_util_workflow_state import mark_stage
from M02_MasterTemplete import M02_Layer_Access as access
from M02_MasterTemplete.M02_Item_Snapshot import importer
@@ -216,9 +219,18 @@ async def save_estimation(project_id: UUID, body: dict[str, Any] = Body(...)) ->
book = await asyncio.to_thread(store.read_book, root)
book = await asyncio.to_thread(prices.extend_book, book, keys)
await asyncio.to_thread(store.write_book, root, book)
await mark_stage(str(project_id), 6, "save") # [저장](B1)
return await payload(project_id, root)
@router.post("/{project_id}/estimation/complete")
async def estimation_complete(project_id: UUID) -> dict[str, Any]:
"""B09 [>] — 단계 6 완료(요구 300 B1)."""
await _project_root(project_id) # 없는 프로젝트는 404
await mark_stage(str(project_id), 6, "next")
return {"status": "success", "project_id": str(project_id)}
@router.post("/{project_id}/estimation/prices")
async def refresh_prices(
project_id: UUID, body: dict[str, Any] | None = Body(None)