Files
Aislo/M02_MasterTemplete/M02_Doc_Router.py
T
eomsangdonandClaude Opus 5.5 3d4b2ec1d1 feat(812-9): 가져온 기계 잇기 다시 — 기계표 전체 · 표기 정규화 · 괄호 낱말 · 범위 규격 · 별칭 먼저 · 조합 기계 둘 · 조회어 기종만
- 새 `M02_Machine_Find` — 기종 = 기계표 이름 · 괄호 붙임 · 상세구분(낱말표 24 안 씀) · 소리 표기 한 글(로우더 = 로더 · 로울러 = 롤러 · 브레이카 = 브레이커 · 굴삭기 = 굴착기 · 램 머 = 래머 …) · 기계표 괄호 낱말로 좁힘(표에 없는 낱말 발파 · 리핑 = 안 봄) · 규격 = 수 + 단위 전부(범위 · 복수 · 인치 = ㎝) · 하나 = 이음 · 여럿 = 「기계 후보 n — 고르기」 · 0 = 「기계 못 찾음」 표지(가까운 규격으로 대신 잇지 않음)
- 별칭 먼저 — 마스터 층 + 지금 층 별칭 장부 기계 짝(이름 + 규격 · 이름만 · 규격 속 할증 글 뺌) · `M02_Doc_Match_Note._ALIAS` 여섯 쌍 걷음(소리 표기 = 정규화 · 같은 기종 = 기계표 · 별칭 장부)
- 조합 기계 = 기계마다 항목 하나(요구 738-3 · 제목 = 그 기계 · 줄 쌓기 차림 `M02_Doc_NativeLayout`) · 줄 둘(「+」 · 괄호 속 다른 기종 · 「…조합」 · 덤프트럭(자동덮개) = 덤프트럭 + 자동덮개시설) — 같은 수량 식 · 엑셀 값은 첫 줄 · 다음 줄 0 + 표지 「조합 기계 — 경비는 한 덩이」 · 우리 단가로 = 각자 시간당 경비
- 원파일 EST · STmate · 엑셀 읽기기 · 일위대가 호표(`Hopyo_Elem` · `Hopyo_Fixed._eqs` · `Hopyo_Row.m01_picks`)가 같은 찾기 · STmate 묶음 기계 줄도 시간당 경비 이음
- 문서 머리 `가져온.기계`(기호마다 판정 · 후보 · 찾기어) · 못 이은 기계 줄도 기계 줄(이름 단추 · `owned_of` 파이썬 · TS 짝) · 이름 단추 조회어 = 기종 이름만(규격 뺌) · 고르면 엑셀 값 기억 그대로(금액 안 바뀜) · 문서 [저장] = 고른 EQ → 이 층 별칭 장부 줄 → M01 별칭 장부 후보(승인 흐름 그대로) · 장부 짝 글 = 「기계 EQ…」
- 마스터 층 별칭 장부(resources/master_template/실무자료/맞춤.json) = 사용자 승인 다섯(요구 735-5 · 736) — 아스팔트페이버(피니셔) = 아스팔트 피니셔 · 디젤 엔진 = 엔진(디젤) · 워터제트 = 워터젯트 · 버킷준설기 = 버킷식준설기 · 바이브레이트 봉상후렉시블 = 콘크리트 진동기 엔진식 ø45(2.6㎾)
- 시험 — 새 test_812_9(예 전부 · 정규화 · 괄호 · 범위 · 조합 둘 · 별칭 먼저 · 표지 · 고르면 별칭 줄 · 금액 전후) · test_812_3 전석쌓기 · 측구터파기 연암 항목을 기계마다 항목으로 고침(조합 기계 둘로 가름 · 요구 738-3 이 바꾼 까닭)
- 전수 목록 docs/raw/요구_1104/_목록_812-9_기계이음.xlsx

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-09 21:02:29 +09:00

94 lines
3.7 KiB
Python

"""M02 단가산출(SK) 수식 길(PLAN 802-4a 4) — `M02_Doc_Sk_Path` 를 층 권한 안에서.
GET /api/m02/layers/{층}/sangeun/{키}/doc 읽기(층 읽기) → {문서, 부름, 끊음, 셈, 사본, 판}
POST /api/m02/layers/{층}/sangeun/{키}/doc/preview 미리 셈(층 쓰기) {문서?, 끊음?, 할일?}
→ {…, 전, 후, 바뀐자원?, 버림?}
POST /api/m02/layers/{층}/sangeun/{키}/doc/save 저장(층 쓰기) {문서?, 끊음?, 할일?, 판} → 읽기 꼴
· 가져온 기계 줄에 고른 EQ = 이 층 별칭 장부(812-9)
POST /api/m02/layers/{층}/sangeun/{키}/match {할일 찾기|바꾸기|되돌리기, 판?}(층 쓰기 · 810-4)
→ {연결후보?, 판}(바꾸기 = 확정만 · 아니면 409)
⚠ 등록은 `main.py`(로그인만 · 층 권한은 길 안에서).
"""
from __future__ import annotations
from typing import Any
from fastapi import APIRouter, Depends
from pydantic import BaseModel
from common_util.common_util_auth import verify_session
from M02_MasterTemplete import M02_Doc_Sk_Path as path
from M02_MasterTemplete import M02_Machine_Find as mfind
from M02_MasterTemplete.M02_MasterTemplete_Router_Items import Layer, Session, _call, _root
router = APIRouter(prefix="/api/m02", tags=["M02 MasterTemplete Sangeun Doc"])
class DocBody(BaseModel):
문서: dict[str, Any] | None = None
끊음: dict[str, Any] | None = None
할일: str | None = None
판: str | None = None
단가기준: str | None = None # 가져온 식만(807-1 · 엑셀 | 우리)
@router.get("/layers/{layer}/sangeun/{key}/doc")
def read_doc(
layer: Layer, key: str, owner: str | None = None, session: Session = Depends(verify_session)
) -> dict:
return _call(_root(session, layer, owner), path.read, key)
@router.post("/layers/{layer}/sangeun/{key}/doc/preview")
def preview_doc(
layer: Layer,
key: str,
body: DocBody,
owner: str | None = None,
session: Session = Depends(verify_session),
) -> dict:
folder = _root(session, layer, owner, write=True)
return _call(folder, path.preview, key, body.model_dump(exclude_none=True))
class MatchBody(BaseModel):
할일: str = "찾기" # 찾기 | 바꾸기 | 되돌리기(810-4)
판: str | None = None
@router.post("/layers/{layer}/sangeun/{key}/match")
def match_doc(
layer: Layer,
key: str,
body: MatchBody,
owner: str | None = None,
session: Session = Depends(verify_session),
) -> dict:
"""가져온 식 ↔ 우리 기초(810-4) — 찾기(연결후보 적음) · 바꾸기(확정만 · M01 사본 SK) · 되돌리기."""
from fastapi import HTTPException
from M02_MasterTemplete import M02_Doc_MatchSk as msk
jobs = {"찾기": msk.find, "바꾸기": msk.swap, "되돌리기": msk.back}
if body.할일 not in jobs:
raise HTTPException(status_code=400, detail="찾기 · 바꾸기 · 되돌리기")
folder = _root(session, layer, owner, write=True)
return _call(folder, jobs[body.할일], key, body.판 or "")
@router.post("/layers/{layer}/sangeun/{key}/doc/save")
def save_doc(
layer: Layer,
key: str,
body: DocBody,
owner: str | None = None,
session: Session = Depends(verify_session),
) -> dict:
folder = _root(session, layer, owner, write=True)
got = _call(folder, path.save, key, body.model_dump(exclude_none=True))
if body.문서 is not None: # 812-9 — 가져온 기계 줄에 고른 EQ = 이 층 별칭 장부 줄
who = {"id": session.get("user_id"), "이름": session.get("name")}
_call(folder, mfind.learn, body.문서, who)
return got