Merge origin/sub_laptop_5 into sub_laptop_8 — PLAN 702-3 · B09 Router 머리 설명 겹침 양쪽 살림([업데이트] 703-3 · calc 702-3)
남은 것: test_298_2 test_b08_b09_next[B09] 가 701-3 빈 줄 409 와 부딪힘(root=Path(".") 로 실제 셈) — sub5 다음 일 첫 걸음에서 고침
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -18,6 +18,8 @@
|
||||
POST /api/projects/{id}/estimation/prices/preview {user?}
|
||||
[업데이트] 미리 보기(703-3) — 바뀌는 단가 줄 · 다시 가져올 사본 · 지킬 고친 칸 ·
|
||||
노임 판(쓰지 않음)
|
||||
POST /api/projects/{id}/estimation/calc {user}
|
||||
조작 중 서버 셈(702-3 · 단가연결 즉시 금액) — 화면 캐시로 GET 꼴 셈 · 저장 안 함
|
||||
POST /api/projects/{id}/estimation/logic-preview {code, given, rate, picks}
|
||||
「운반 단가」 모달 계산 절차(253-3) — 그 로직 한 산근을 프로젝트 단가로 풀어 글 줄 · 단가 ·
|
||||
저장 안 함(`render_sangeun_text` 를 `Sangeun.Solver` 로) · `blocks` = 칸 나눔(277-2)
|
||||
@@ -47,6 +49,7 @@ import asyncio
|
||||
import copy
|
||||
import importlib
|
||||
import logging
|
||||
import time
|
||||
from pathlib import Path
|
||||
from typing import Any
|
||||
from uuid import UUID
|
||||
@@ -92,6 +95,25 @@ except ImportError: # pragma: no cover
|
||||
router = APIRouter(prefix="/api/projects", tags=["B09 Estimation"])
|
||||
|
||||
|
||||
# 702-3 조작 중 셈 = 마지막 GET · [저장] 이 읽은 B08 원천 다시 씀(B08 은 B09 조작으로 안 바뀜)
|
||||
# ponytail: 시간 창만 봄 — 창 안에 남이 B08 을 고치면 미리보기만 옛 수량 · [저장] 은 늘 새로 읽음
|
||||
B08_REUSE_S = 120.0
|
||||
_b08_seen: dict[UUID, tuple[float, dict[str, Any], list[str]]] = {}
|
||||
|
||||
|
||||
async def _b08_for(project_id: UUID, notes: list[str], reuse: bool) -> dict[str, Any]:
|
||||
"""B08 원천 — reuse = 시간 창 안 마지막 값(사본) · 아니면 새로 읽고 남김."""
|
||||
seen = _b08_seen.get(project_id)
|
||||
if reuse and seen and time.monotonic() - seen[0] < B08_REUSE_S:
|
||||
notes.extend(seen[2])
|
||||
return copy.deepcopy(seen[1])
|
||||
mine: list[str] = []
|
||||
out = await _b08(project_id, mine)
|
||||
_b08_seen[project_id] = (time.monotonic(), copy.deepcopy(out), mine)
|
||||
notes.extend(mine)
|
||||
return out
|
||||
|
||||
|
||||
async def _b08(project_id: UUID, notes: list[str]) -> dict[str, Any]:
|
||||
"""B08 수량 원천 — 못 읽으면 빈칸 + 알림(B09 는 B08 를 고치지 않음)."""
|
||||
out: dict[str, Any] = {}
|
||||
@@ -182,10 +204,10 @@ async def _demand(root: Path, draft: dict[str, Any] | None = None) -> list[str]:
|
||||
|
||||
|
||||
async def payload(
|
||||
project_id: UUID, root: Path, draft: dict[str, Any] | None = None
|
||||
project_id: UUID, root: Path, draft: dict[str, Any] | None = None, reuse_b08: bool = False
|
||||
) -> dict[str, Any]:
|
||||
notes: list[str] = []
|
||||
b08 = await _b08(project_id, notes)
|
||||
b08 = await _b08_for(project_id, notes, reuse_b08)
|
||||
keys = await _demand(root, draft)
|
||||
if not keys:
|
||||
notes.append(
|
||||
@@ -194,7 +216,8 @@ async def payload(
|
||||
book = await asyncio.to_thread(store.read_book, root)
|
||||
inputs = await asyncio.to_thread(prices.build_inputs, book, keys, b08["materials"])
|
||||
hauls = await asyncio.to_thread(haul_routes, root)
|
||||
user = await asyncio.to_thread(store.read_user, root)
|
||||
# 702-3 draft = 화면 캐시로 셈(저장 안 함) · 없으면 저장 값
|
||||
user = await asyncio.to_thread(store.read_user, root) if draft is None else draft
|
||||
calc = await asyncio.to_thread(library.resolve_hauls, root, {**user, **haul_user(hauls)})
|
||||
inputs["bill"] = bill_items({**b08, **calc, "haul_routes": hauls})
|
||||
inputs["hopyo"] = hopyo_prices(root)
|
||||
@@ -316,6 +339,14 @@ async def refresh_preview(
|
||||
return await asyncio.to_thread(refresh.preview, root, book, keys, user.get("daega_cover"))
|
||||
|
||||
|
||||
@router.post("/{project_id}/estimation/calc")
|
||||
async def calc_estimation(project_id: UUID, body: dict[str, Any] = Body(...)) -> dict[str, Any]:
|
||||
"""702-3 조작 중 서버 셈 — 화면 캐시(user)로 GET 꼴 셈 · 저장 안 함 · 단가 = 굳힌 책
|
||||
(없는 줄 = 지금 M01 · [저장] 때 책에 굳힘 → 같은 값)."""
|
||||
root = await _project_root(project_id)
|
||||
return await payload(project_id, root, store.clean_user(body.get("user")), reuse_b08=True)
|
||||
|
||||
|
||||
class PreviewBody(BaseModel):
|
||||
code: str = Field(min_length=1, max_length=40)
|
||||
given: dict[str, Any] = Field(default_factory=dict)
|
||||
|
||||
Reference in New Issue
Block a user