fix(b09): [업데이트] 때 지운 복사 정보 뺌 — 화면 캐시 기준 수요 · M01 원본 없는 줄 굳힌 값 그대로 (296-1)

- [업데이트] = 화면 캐시(user)를 같이 보냄 · 캐시 그대로 둠(지운 줄 안 되살림 · 저장 안 함)
- 서버 수요 = 캐시 줄이 잇는 서고 사본만(지운 줄의 사본 단가 줄 안 살아남)
- M01 원본이 지워진 키 = 옛 책 줄 그대로 · 낡음 까닭에서 빠짐
- 시험 test_296_b09_update_skip_deleted

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Se7ytqbohmBQnfYpwYFnYf
This commit is contained in:
2026-10-12 21:54:43 +09:00
co-authored by Claude Opus 5.5
parent df574665b1
commit cf396d93ff
5 changed files with 143 additions and 26 deletions
+25 -16
View File
@@ -4,8 +4,9 @@
입력(굳힌 단가 · 수요 · B08 수량) + 사용자 값 → 표 전부
PUT /api/projects/{id}/estimation {user}
[저장] — 사용자 값 · 책에 없는 새 단가 줄만 굳힘 → 서버가 정본으로 다시 셈
POST /api/projects/{id}/estimation/prices
[단가 갱신] — 수요 단가 전부를 지금 M01 값으로 새로 굳힘
POST /api/projects/{id}/estimation/prices {user?}
[단가 갱신] — 수요 단가 전부를 지금 M01 값으로 새로 굳힘 · user = 화면 캐시(296 ·
지운 줄 · 그 사본은 수요에서 뺌 · 저장은 안 함) · M01 원본이 지워진 줄 = 굳힌 값 그대로
POST /api/projects/{id}/estimation/logic-preview {code, given, rate, picks}
「운반 단가」 모달 계산 절차(253-3) — 그 로직 한 산근을 프로젝트 단가로 풀어 글 줄 · 단가 ·
저장 안 함(`render_sangeun_text` 를 `Sangeun.Solver` 로) · `blocks` = 칸 나눔(277-2)
@@ -138,26 +139,29 @@ def haul_user(rows: list[dict[str, Any]]) -> dict[str, Any]:
}
def calc_user(root: Path) -> dict[str, Any]:
"""셈 · 수요 · 사본 정리용 사용자 값 — 저장 값 + 거리이정표 운반 연결 · 거리(화면엔 안 보냄) ·
운반 사본 연결 = 지금 거리의 사본(263-2)."""
user = {**store.read_user(root), **haul_user(haul_routes(root))}
def calc_user(root: Path, draft: dict[str, Any] | None = None) -> dict[str, Any]:
"""셈 · 수요 · 사본 정리용 사용자 값 — 저장 값(draft = 화면 캐시 · 296) + 거리이정표 운반 연결 ·
거리(화면엔 안 보냄) · 운반 사본 연결 = 지금 거리의 사본(263-2)."""
user = {**(store.read_user(root) if draft is None else draft), **haul_user(haul_routes(root))}
return library.resolve_hauls(root, user)
async def _demand(root: Path) -> list[str]:
async def _demand(root: Path, draft: dict[str, Any] | None = None) -> list[str]:
"""단가 수요 키 — 연결된 사본 + 설계내역서 손 줄 로직(166-2) +
거리이정표 운반 연결(251-5)."""
user = await asyncio.to_thread(calc_user, root) # 운반 값 사본 먼저(263-2)
keys = await asyncio.to_thread(linked_resource_keys, root)
거리이정표 운반 연결(251-5) · draft = 화면 캐시(296 · 서고 사본 = 그 줄이 잇는 것만)."""
user = await asyncio.to_thread(calc_user, root, draft) # 운반 값 사본 먼저(263-2)
keep = None if draft is None else library.used_folders(user)
keys = await asyncio.to_thread(linked_resource_keys, root, keep)
hand = await asyncio.to_thread(sangeun.hand_resource_keys, user)
return [*keys, *(k for k in hand if k not in keys)]
async def payload(project_id: UUID, root: Path) -> dict[str, Any]:
async def payload(
project_id: UUID, root: Path, draft: dict[str, Any] | None = None
) -> dict[str, Any]:
notes: list[str] = []
b08 = await _b08(project_id, notes)
keys = await _demand(root)
keys = await _demand(root, draft)
if not keys:
notes.append(
"연결된 구조물 조합 사본 없음 — 노무 · 경비 · 중기 단가 줄은 사본이 연결되면 생김"
@@ -213,12 +217,17 @@ async def save_estimation(project_id: UUID, body: dict[str, Any] = Body(...)) ->
@router.post("/{project_id}/estimation/prices")
async def refresh_prices(project_id: UUID) -> dict[str, Any]:
async def refresh_prices(
project_id: UUID, body: dict[str, Any] | None = Body(None)
) -> dict[str, Any]:
root = await _project_root(project_id)
keys = await _demand(root)
book = await asyncio.to_thread(prices.refresh_book, keys)
raw = (body or {}).get("user")
draft = store.clean_user(raw) if isinstance(raw, dict) else None # 296 화면 캐시(저장 안 함)
keys = await _demand(root, draft)
old = await asyncio.to_thread(store.read_book, root)
book = await asyncio.to_thread(prices.refresh_book, keys, old)
await asyncio.to_thread(store.write_book, root, book)
return await payload(project_id, root)
return await payload(project_id, root, draft)
class PreviewBody(BaseModel):