chore(plan): 324 일위대가 실무자료 조사 · 정함 — 엑셀 일위대가 시트 꼴(xlrd · 열 · 호표 · 갈래 · 검산 · 규격) · 우리 구조(로직 · 일위대가 · 사전조합 · 고르기 창 덧줄) · 호표 = 사전조합 하나 + 참조 줄 · 별칭 = 엑셀 이름 · 규격 → 입력값 · 환산 · 맞춤 기억 · 단계 324-1~5

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01C6BNBFXFndbqYxu6sZuknK
This commit is contained in:
2026-10-14 21:56:09 +09:00
co-authored by Claude Opus 5.5
parent ecd4a95ab5
commit c637ff14ea
@@ -0,0 +1,66 @@
# 324 일위대가 실무자료 — 조사 · 정함 (요구 223-5 · 2026-10-14)
요구(사용자 원문 요약): M02 좌측 「일위대가 실무자료」 버튼으로 엑셀 올림 → 「일위대가」 탭 분석 · 구조물조합 일위대가 [로직 추가] 때 실무자료 호표 불러오기 · 엑셀 단가산출 이름이 우리 로직 이름과 다름 → 맞으면 엑셀 이름 = 일위대가 별칭 · 옵션 값 = 규격 열 · 남의 실무문서를 우리 일위대가로 · 단위 다르면 환산한 결과로 맞춤 · 상세 분석 뒤 신규 계획 · 구현은 sub1(sub_laptop_1 가지).
조사 = Plan 넷(엑셀 구조 · 우리 단가산출/일위대가 구조 · M02 화면 · 맞춤/단위 도구). 경로는 저장소 기준.
## 1. 엑셀 「일위대가」 시트 (북부청 임도 공통단가 .xls 기준)
- 읽기 = **xlrd 2.0.2**(venv 에 있음 · requirements 에 없음 → 적어 넣음) · `xlrd.open_workbook(file_contents=…, logfile=io.StringIO())`(OLE2 경고가 stdout 으로 안 나가게) · .xlsx = openpyxl(빈 칸 None).
- 시트 = `일위대가`(560×15) · 목록 = `일위대가총괄표`(검산용) · 2·3행 머리 글(빈칸 빼고)로 찾음 · 자료 4행부터 · 숨김 없음.
- 열(0부터): 1 호표 · 2 품명 · 3 규격 · 4 수량 · 5 단위 · 6/7 합계 단가/금액 · 8/9 노무비 · 10/11 재료비 · 12/13 경비 · 14 비고 — **차례 = 합계 · 노무비 · 재료비 · 경비**.
- 호표 줄 = `re.fullmatch(r'제\s*(\d+)\s*호표', 1열)` · 1 단위 값은 **금액 열(7/9/11/13)** · 단가 열 빔.
- 구성 줄 = 1열 빔 · 2열 있음 · 끝 = 다음 호표 줄 또는 시트 끝(합계 줄 없음 · 빈 줄 하나로 띄움).
- 구성 줄 갈래(415 줄): 값 있음 350 · 값 없음(별도계상) 64 · % 1(4열 = 율 · 6열 = 바탕 금액 · 규격 「재료비의」 「노무비의」) · 참조 = 비고 `^(단산|일위)(\d+)참조$`(단산 268 · 일위 1).
- 갈래 나누기(맞춤 쪽 조사): 단산 참조 = 단가산출 · 참조 없고 재료비만 = 자재(143 · 자재단가 시트로 확인 가능) · 단위 hr 등 = 기계(3) · 일위N = 다른 호표.
- 검산 규칙(68 + 27 호표 어긋남 0): 줄 금액 = floor(단가 × 수량 × 10) / 10 · 6열 = 8+10+12 · 호표 노무/재료/경비 = floor(줄 금액 합) · % 줄 = floor(바탕 × 율 / 100 × 10) / 10.
- 수: 68 호표(제1~68 빈 번호 없음) · 줄 0~21 · 제61호표 = 줄 없음 · 값 빔.
- 보기: 제1호표 배수관날개벽(유입구) 「D=1,000mm,일반형」 개소 1,040,052 · 제3호표 임도표지석 「910×600×150」 개소 1,415,169(줄 = 표지석 재료 ㎥ 1 · 구조물터파기(인력100%) 토사 ㎥ 0.14 단산93 · 되메우기 ㎥ 0.05 단산12 · 잔토처리 ㎥ 0.09 단산13) · 제46호표 고화매트재료비 ㎡(제45호표가 일위46참조로 씀).
- 규격 쓰는 법: 자유 글 많음 · `B=` `H:`(쌍점) `D=` `A×B×C` `H=` `T=` `L=` · 구분 = 쉼표 · 빈칸 · 천 단위 쉼표 함정(`D=1,000mm` 만 = 뒤 숫자 셋) → `re.sub(r'(=\d{1,3}),(\d{3})(?!\d)', r'\1\2', s)` 뒤 `([A-Za-z]\d?)\s*[=:]\s*([\d.]+)\s*(mm|cm|m)?` · 원문 늘 보관 · × Φ Ø ㎜ ㎥ ㎡ 섞임.
- 단위: 호표 = M(= m) 37 · 개소 19 · ㎡ 12 / 줄 = ㎥ ㎡ M Ton/TON EA 공/㎥ kg hr 개소 % 개 · 사방 파일 더 = 식 경간 개 인 조.
- 다른 파일: 사방(계류+댐) = 같은 꼴 27 호표 · 수목진료 · 2016 사방표준품셈(안) = 일위대가 시트 없음(단가산출 · 단가산출총괄표만) → 「일위대가 시트 없음」.
- 함정: 이름만 같은 호표 많음 → 열쇠 = 파일 + 호표 번호 · 이름 끝 전각 빈칸(strip) · 이름 안 옵션(`큰돌바닥막이(H=0.5)`) · 호표 단위 ≠ 줄 단위(개소 안 ㎥ 줄).
## 2. 우리 쪽 구조
- 단가산출 로직(원본 · 손대지 않음) = `resources/master_data/로직_*.json` 1,469 줄 `{키 GF…, 이름, 결과단위 "원/㎡", 입력:[{이름, 단위, 고르기, 범위}], 중간, 호표, 덧줄, 끝수}` · 엔진 `master_formula.run` → `{줄, 노무비, 재료비, 경비, 계}` · 결과단위 읽기 `M01_MasterData_Store_Combo.combo_pills`(「원/10㎡」 = 분모 ㎡ · 배 10).
- 일위대가 문서(구조물 열 하나) = `{층}/templates/labor/<열>.json` `{종류, 열, 단위, 본뜬, 일위대가번, 담은로직:[{로직, 별칭, 메모, 입력값, 수량} | {참조:{층,주인,키}, 별칭, 메모, 수량}], 자재:[{코드, 이름, 규격, 단위, 수량, 자재구분?, 별도계상?, 운반비?}], 계산값}`(`M02_Labor_Doc.py` 머리 글) · 반영 = 기준 × 수량 ÷ 배 · **같은 로직 두 번 금지** · 별칭 ≤ 40 자(44-6 · 쓰기 됨 · B09 가 대가 이름으로 씀).
- 일위대가 사전조합 = `{층}/precombo/SC-######.json` `{종류:"사전조합", 이름, 단위, 담은로직, 자재, 구분, 상세구분, 본뜬}` · 값 = Σ(기준 ÷ 배) × 손 · 일위대가가 참조 줄로 씀(같은 층 · 위 층만) · 만들기 `POST /api/m02/layers/{l}/library/precombo`(`M02_Labor_Router.py:91` → `M02_Labor_Ref.py:257`) · **`_combo_lines`(`M02_Labor_Ref.py:202`) 가 별칭을 버림 → 한 줄 고침 필요** · 같은 로직 두 번 금지도 같음(labor.clean).
- [로직 추가] = `M02_MasterTemplete_Labor_Detail.ts:496-512`(693 줄 · 거의 끝) → `openLogicPicker`(`M02_MasterTemplete_Labor_Pick.ts:75`) = 로직 + 사전조합 한 목록 · **덧줄 자리 `LibraryPick.extra / kindFilter`(:43-54 · B09 가 이미 씀)** · 고르면 `lib.pick(ref, name)`(:487-494)이 참조 줄을 더함 · 사전조합 다듬기 = 참조 [수정] 창(`Labor_RefEdit.ts`).
- 좌측 판 = `M02_MasterTemplete_UI_Side.ts`(차례: 구조물 조합 · 일위대가 사전조합 · 구조물 옵션 정의 · 도면 양식 · 실무문서) · `section()` 꼴 · 층 = 해시 root · 사전조합은 따로 층 줄(pre) · 이름 금지 낱말(시험이 봄) = `practice` · `LaborSection` · `labor?.`.
- 「실무문서」(기존) = 올리기 없음 · `일위대가조합.json` UA 37 읽기 목록 + [통째 지우기](시스템 관리자만) — 이번 기능과 별개 · 그대로 둠.
- 올리기 본 = `M02_MasterTemplete_Router_Drawing.py:57-92`(UploadFile · 20 MB · 스레드 파싱 · 엉터리 400) + `M02_MasterTemplete_Drawing.ts:145-162 · 297-329`(숨은 file 입력 · FormData).
- 권한(`M02_Layer_Access.py`) = system 쓰기 시스템 관리자 · 회사 = 시스템 관리자 · 그 회사 관리자 · 개인 = 본인 · 회사 관리자.
- 정규화 · 단위 도구(그대로 씀): `master_material.plain / plain_spec / plain_unit`(NFKC · ㎥→m3 · M→m · Ton→톤 · EA→개) · `master_pick.UNITS / kind_of / same_kind / convert` · `M02_Labor_Inputs.logic_inputs`(입력 · 고르기 · 고르기이름 · 자동값) · 씨앗 = `일위대가조합.json` 메모(실무 이름 약 80 → 로직 43 · 읽기만) · 선례 = `resources/master_data/scripts/compare_estx.py`(PAIRS = 외부 코드 · 로직 · 입력 · 환산 배수 · `base_name` · `MACH_WORDS`).
- 맞춤 어림(북부청 단가산출 이름 95): 같음 9 · 괄호 빼면 9 · UA 씨앗 13 → 31 자동 · 64 = 후보 확정 필요(difflib 첫 후보 자주 틀림).
- 지키는 것: `resources/master_data/*.json` · `일위대가조합.json` 원본 안 고침(시험으로 sha256 확인) · M01 로직 별칭(208-1 · 원본 안) 안 씀 · `main.py`(802 줄) 안 건드림 → 길은 `M02_Labor_Router.py` 에.
## 3. 정함(브레인 · 사용자가 맡김)
1. 층 = 구조물 조합 층(root)과 같은 규칙 · 읽기 · 쓰기 권한 그대로(마스터 = 시스템 관리자) · 자리 = `{층 폴더}/실무자료/<id>.json` + 맞춤 기억 `{층 폴더}/실무자료/맞춤.json` · 템플릿 목록 · 복사 · 프로젝트 씨앗에 안 섞임.
2. 올리기 = 파싱 결과만 저장(원본 파일 안 둠) · 파일 이름 · 올린 때 · 올린 이 · 시트 · 호표 · 검산 결과.
3. 호표 불러오기 = 그 호표를 우리 **일위대가 사전조합** 하나로 만들고(같은 층에 같은 파일 · 같은 호표 것이 있으면 다시 씀) 일위대가에 참조 한 줄(별칭 = 엑셀 호표 품명 · 메모 = 규격 · 수량 손 1) — 사전조합 = 「우리 일위대가」 · 여러 구조물이 같이 씀 · 엔진 안 바꿈.
4. 사전조합 안 줄 = 엑셀 구성 줄마다 맞춘 것: 로직 줄 `{로직, 별칭 = 엑셀 품명(40 자), 메모 = 「실무 0.14㎥ × 1 · 규격」, 입력값 = 규격에서, 수량 손 = 엑셀 수량 × 환산}` · 자재 줄(우리 자재와 맞은 것 · 별도계상 표시 그대로) · 일위N참조 = 그 호표 사전조합을 먼저 만들어 참조 줄(순환 막음).
5. 같은 로직 두 번(예 레미콘타설 철근 · 무근) = 둘째부터 한 줄 사전조합으로 감싸 참조(문서 규칙 그대로).
6. 맞춤 차례 = ① 층 기억(확정분) ② 이름 같음(정규화) · 씨앗(UA 메모) ③ 정리 이름 같음(괄호 빼기 · 기계 낱말) ④ 후보 5(글자 두 개 묶음 점수 + 단위 맞음 · 산림품셈 덤) — ③④ 는 사용자 확정 뒤에만 들어감 · 확정 = 층 기억에 남아 다음부터 자동.
7. 규격 → 입력값 = 고르기 글이 규격(괄호 글 포함)에 있으면 그 값 · 기계 = 고르기이름(이름 + 용량) · 이름 붙은 수(D= H= H: B= T= L= L3=)는 입력 단위로 바꿈 · 못 읽으면 빈 값(자동값) + 표시.
8. 환산(우리 수량 = 엑셀 수량 × f): 같은 단위 f = 1(10㎡ 배는 엔진) · 같은 종류 = 단위표 · 다른 종류 = 규격 T · B 로 추정(㎡→㎥ × T · m→㎡ × B · m→㎥ × B × T · 「추정」 표시 · 확정 뒤에만) · 그 밖(개소 · 회 · hr 등) = 사용자 입력 · 두 단위 로직 = 단위 입력으로 고르고 f = 1.
9. 안 들어가는 줄 = % 줄(우리 로직 덧줄이 셈) · 못 맞춘 줄 · 값 없는 줄 중 못 맞춘 것 — 화면에 「빠진 줄 · 엑셀 금액」 · 만든 사전조합 값 ↔ 엑셀 호표 단가 한 줄 비교.
10. 일위대가 시트 없는 파일 = 400 「일위대가 시트 없음」(단가산출총괄표 대체는 이번 밖).
## 4. 단계 (PLAN 324)
- 324-1 읽기 · 저장 · 올리기 길 — `M02_Hopyo_Excel.py`(xls · xlsx → 호표 · 줄 · 갈래 · 참조 · 검산) · `M02_Hopyo_Store.py`(층 폴더 · 잠금 · 원자 쓰기) · 길(올리기 · 목록 · 읽기 · 지우기) · requirements xlrd.
- 324-2 맞춤 — `M02_Hopyo_Match.py`(정규화 · 규격 → 입력 · 후보 · 기억 · 환산) · 길(후보 · 확정 저장).
- 324-3 사전조합 만들기 — `M02_Hopyo_Build.py`(호표 → 사전조합 · 별칭 · 감싸기 · 일위N · 자재 · 다시 씀) · `_combo_lines` 별칭 살림 · 길(만들기).
- 324-4 화면 — 좌측 「일위대가 실무자료」 판(올리기 · 파일 줄) · 본 화면(호표 표 · 찾기 · 줄 맞춤 · 확정 · 빠진 줄 · 값 비교) · [로직 추가] 고르기 창에 「실무 호표」 줄(고르면 사전조합 만들고 참조 줄).
- 324-5 확인 — 시험 + typecheck · 브레인 화면 확인(북부청 파일 올림 → 제3호표 맞춤 → 구조물 일위대가에 불러오기 → 저장) → 아티팩트 보고.
## 5. 시험
- 파싱: 북부청 68 · 사방 27 · 검산 어긋남 0 · 제1 · 제3 · 제46 · 제61(빈 호표) 값 · 일위대가 없는 파일 400 · xlsx 길(작은 파일 만들어).
- 맞춤: `D=1,000mm` · `H:1.2m` · `B=2.3,H=0.4` · `Φ40×200` · 단위 정규화 · 환산(같음 · 같은 종류 · T · B 추정 · 입력) · 기억 우선.
- 길: 역할 표(시스템 관리자 · 회사 관리자 · 일반 · 남의 개인 층 403) · 엉터리 파일 400 · 20 MB · 지우기.
- 만들기: 별칭 남음 · 수량 = 엑셀 × 환산 · 같은 로직 둘 = 감쌈 · 일위N 참조 · 같은 호표 다시 = 같은 사전조합 · 빠진 줄 보고.
- 원본 지킴: 올리기 · 맞춤 · 만들기 뒤 `resources/master_data/*.json` sha256 그대로.
- 화면: 소스 확인 시험(기존 꼴) · 고르기 창 덧줄 node 시험.