Files
Aislo/B08_Quantity/B08_Quantity_Router_Options.py
T
eomsangdonandClaude Opus 5.5 6a9506f1fb feat(b08): 좌측 패널 컨테이너 셋(구조물 · 토공 · 수리) + [저장] 줄 · 옵션 저장 길 GET/PUT quantity/options(122-1)
- 구조물 › 배관 1본 길이 · 토공 › 연암 · 경암 % 입력(공용 compact 입력 · 접이 카드)
- 조작 = 캐시 b08-options · [저장] = 프로젝트 층 M02 구조물집계표 변수 · project_settings rock_ratios_pct
- 브라우저 짝 식 파일 B08_Quantity_Options_Calc.ts

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BVPp2o6Mh2FZJr72yW3ofZ
2026-10-08 18:43:58 +09:00

92 lines
3.7 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""B08 좌측 패널 옵션 길(PLAN 122) — 배관 1본 길이 · 연암 / 경암 비율.
GET /api/projects/{id}/quantity/options 지금 값
PUT /api/projects/{id}/quantity/options [저장] — 받은 칸만 정본 자리에 씀
1본 길이 = 프로젝트 층 M02 구조물집계표 변수 `파형강관_1본_m` 한 벌(98 `one_pipe_length` 이 읽는 자리 ·
M02 표 식 `[$파형강관_1본_m]` 도 같은 값) · 프로젝트 사본이 없으면 시스템 층 문서를 바탕으로 깔고 씀 ·
M02 [초기화]면 같이 되돌아감.
연암 % = `project_settings.json › quantity › rock_ratios_pct`(연암 · 경암 = 100 − 연암) · 기본 90 은
파일에 안 쓰고 읽을 때 채움(`soft_rock_pct`).
"""
from __future__ import annotations
import asyncio
from pathlib import Path
from typing import Any
from uuid import UUID
from fastapi import APIRouter, HTTPException
from pydantic import BaseModel, Field
from B08_Quantity.B08_Quantity_Router_Hydro import _project_root
from B08_Quantity.B08_Quantity_Router_Summary import ONE_LENGTH_VAR, TABLE_NAME, one_pipe_length
from common_util.common_util_project_settings import quantity_settings, save_section, soft_rock_pct
from M02_MasterTemplete import M02_Template_Layers as layers
router = APIRouter(prefix="/api/projects", tags=["B08 Options"])
class OptionsSave(BaseModel):
"""빈칸(None) = 그 칸은 그대로."""
one_pipe_length_m: float | None = Field(default=None, gt=0, le=100)
soft_rock_pct: float | None = Field(default=None, ge=0, le=100)
def read_options(root: str | Path) -> dict[str, Any]:
soft = soft_rock_pct(quantity_settings(root))
return {
"one_pipe_length_m": one_pipe_length(root),
"rock_ratios_pct": {"연암": soft, "경암": 100.0 - soft},
}
def _write_one_pipe(root: str | Path, value: float) -> None:
"""프로젝트 층 구조물집계표 변수 한 칸 — 판이 그새 바뀌었으면 `StaleTemplate`."""
folder = layers.project_dir(root)
found = layers.read_template(folder, "table", TABLE_NAME)
version = found["판"] if found else None
found = found or layers.read_template(layers.system_dir(), "table", TABLE_NAME)
if found is None:
raise HTTPException(status_code=404, detail=f"{TABLE_NAME} 양식이 없습니다 — M02 표부터.")
document = found["문서"]
document["변수"] = {**(document.get("변수") or {}), ONE_LENGTH_VAR: value}
layers.write_template(
folder, "table", TABLE_NAME, document, version=version, check_version=True
)
def save_options(root: str | Path, body: OptionsSave) -> dict[str, Any]:
if body.one_pipe_length_m is not None:
_write_one_pipe(root, body.one_pipe_length_m)
if body.soft_rock_pct is not None:
soft = float(body.soft_rock_pct)
ratios = {
**(quantity_settings(root).get("rock_ratios_pct") or {}),
"연암": soft,
"경암": 100.0 - soft,
}
save_section(
root, "quantity", {"rock_ratios_pct": ratios}, replace_keys=("rock_ratios_pct",)
)
return read_options(root)
@router.get("/{project_id}/quantity/options")
async def options_read(project_id: UUID) -> dict[str, Any]:
root = await _project_root(project_id)
return await asyncio.to_thread(read_options, root)
@router.put("/{project_id}/quantity/options")
async def options_save(project_id: UUID, body: OptionsSave) -> dict[str, Any]:
root = await _project_root(project_id)
try:
return await asyncio.to_thread(save_options, root, body)
except layers.StaleTemplate as error:
raise HTTPException(
status_code=409, detail="구조물집계표가 그새 바뀌었습니다 — 다시 열고 저장하세요."
) from error