feat(793-3a): 근거 제안 엔진 — 번호 ∩ 값 ∩ 제목 ∩ 기계 상수 → M01 기초 + 옵션 · 품 검산 · 세 단

- M01 값 역색인 · 숫자 정규화 한 벌(N1~N10 · 단위 기준 · % ↔ 소수 · t ↔ kg · 인/양 몫) · M01 지문마다 한 번 · 서버 시작 때 뒤에서 지음
- 값 길(상수 지문 → 로직 · 우연 보정 유의 4) · 합친 길(분석 648-D2 차례 · 후보 2~6 엔진 품 대조) · 검산 · 옵션(B1~B6 → 값 길 V → 고르기 맞댐 → 입력 필요)
- 세 단 확정 · 근접(판 차이 · 현장 값 · 감률 · 할증 배수 · 단위 기준 차이) · 사람(+ 값 약한 1 등) · 없음(M01 보강 목록)
- 길 GET hopyo-basis/{키} · hopyo-basis/{키}/{번} · 파생 저장본 · 올림 때 HP 숨은식(STmate G 식) · 끝내기 때 지움 · 판정 길 그대로
- 보정 자료 = 여덟 파일 상수 1,094 · 시험 test_793_3a 11(459 블록 기초 260 · 옵션 전부 52 · 품 같음 141 · 없음 85)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-11-05 18:19:26 +09:00
co-authored by Claude Opus 5.5
parent e3262d2b49
commit 532cc52c8e
10 changed files with 2499 additions and 0 deletions
+29
View File
@@ -5,6 +5,8 @@
SC · SK · 장부 · `M02_Hopyo_Make`) · 경로 층 = 파일 층(판정 · 검산 · `to` = 만들 층) / 만들 층(옮기기).
올림 = Book + 격자 + 엑셀 사전(`Row.lexicon`) + 블록 풀이 뒤 셈(`Judge.ensure` · 파생 저장본) ·
옛 맞춤 뒤 셈 · 시동 데움 없음 · [끝내기] = 저장본도 지움.
근거 제안(793-3a) = `hopyo-basis/{키}`(목록) · `hopyo-basis/{키}/{번}`(블록) · `M02_San_Basis_Store`
(올림 때 HP `숨은식` + 뒤 셈 · 파생 저장본 · 판정 길 `hopyo-judge` 칸은 그대로).
그대로 쓰는 길(목록 · 올림 · 엑셀 보기 머리 · 격자 · 지우기 · 장부 · 모두 고정 · 붙여넣기 · 다시 잇기 ·
구조물 조합 · 칠 = B09 · M01 이 씀) · 옛 맞춤 길(호표 하나 맞춤 · 미리 셈 · 실무 호표 · 확인 만들기 · 안 이은 줄 ·
단가산출 만들기)은 785-7 에서 지움.
@@ -36,6 +38,7 @@ from M02_MasterTemplete import M02_Hopyo_Store as hopyo_store
from M02_MasterTemplete import M02_Labor_Doc as labor
from M02_MasterTemplete import M02_Layer_Access as access
from M02_MasterTemplete import M02_MasterTemplete_Store as store
from M02_MasterTemplete import M02_San_Basis_Store as san_basis
from M02_MasterTemplete.M02_MasterTemplete_Router_Items import Layer, Session, _call, _root
router = APIRouter(prefix="/api/m02", tags=["M02 Hopyo"])
@@ -93,6 +96,28 @@ def hopyo_judge_block(
return _call(folder, lambda: hopyo_judge.block(folder, key, no, target))
@router.get("/layers/{layer}/hopyo-basis/{key}")
def hopyo_basis_list(
layer: Layer, key: str, owner: str | None = None, session: Session = Depends(verify_session)
) -> dict:
"""근거 제안(793-3a) — `{셈중, 블록 {번: 제안}, 보강}` · 셈 중 = 뒤 셈 시작(읽기만)."""
folder = _root(session, layer, owner)
return _call(folder, lambda: san_basis.listing(folder, key))
@router.get("/layers/{layer}/hopyo-basis/{key}/{no}")
def hopyo_basis_block(
layer: Layer,
key: str,
no: int,
owner: str | None = None,
session: Session = Depends(verify_session),
) -> dict:
"""근거 제안 블록 하나 — 저장본 › 그 자리 셈(`M02_San_Basis.suggest` 꼴)."""
folder = _root(session, layer, owner)
return _call(folder, lambda: san_basis.block(folder, key, no))
class Pick(BaseModel):
"""고른 것(785-3 꼴) — 금액 · 품 칸 없음(서버가 셈) · 고정 단가 = 엑셀 줄 것."""
@@ -246,6 +271,7 @@ def _upload(name: str, data: bytes, who: dict[str, Any]) -> dict[str, Any]:
hopyo_forget.sweep(store.root()) # 하루 지난 작업 중 HP 끝냄(743-1)
if same := next((r for r in hopyo_store.rows(store.root()) if r.get("지문") == mark), None):
hopyo_judge.ensure(store.root(), same["키"])
san_basis.ensure(store.root(), same["키"])
return {**same, "이어서": True}
try:
parsed = hopyo_excel.read_book(name, data)
@@ -257,8 +283,10 @@ def _upload(name: str, data: bytes, who: dict[str, Any]) -> dict[str, Any]:
grid = None
sheets, _ = hopyo_excel._open(name, data, hopyo_row.SHEETS)
parsed["사전"] = hopyo_row.lexicon(sheets) # 엑셀 사전(785-3 · 1차 줄 판정)
parsed["숨은식"] = san_basis.hidden(parsed, sheets) # STmate 숨은 G 식(793-3a 근거 제안)
row = hopyo_store.save(store.root(), name, parsed, who, grid, mark)
hopyo_judge.ensure(store.root(), row["키"]) # 블록 풀이 뒤 셈(파생 저장본 · 화면 안 기다림)
san_basis.ensure(store.root(), row["키"]) # 근거 제안 뒤 셈(793-3a)
return row
@@ -411,6 +439,7 @@ def hopyo_delete(
folder = _root(session, layer, owner, write=True)
got = _call(folder, hopyo_forget.finish, folder, key)
hopyo_judge.forget(folder, key) # 블록 풀이 저장본(785-5)
san_basis.forget(folder, key) # 근거 제안 저장본(793-3a)
return got