feat(M02): 마스터 템플릿 라우터 연결 · formula 빌드 경로 정리

- main.py: M02_MasterTemplete 라우터 3개(시스템·층·도면) 등록
- tsconfig.json: include 목록에 M0* 추가
- package.json: build:formula 대상을 common_util_sheet_recalc_node.ts 로 변경
This commit is contained in:
2026-09-25 22:29:21 +09:00
parent abd37e8979
commit 4f71b4a5ce
4 changed files with 253 additions and 2 deletions
@@ -0,0 +1,244 @@
# 완료 계획 — 단가산출 로직 화면 · 전수 점검 · 재료/기계 고르기 · 일위대가 조합 (2026-09-22 ~ 09-25)
## 2. 단가산출 상세 — 알약 + 사칙연산 (승인 대기)
검토 = `ref/_분석_알약_상세줄.md`. 결론: **지금 호표 표를 그대로 두고 수량 칸 글자를 알약으로 바꿈** · 계산 코드는 안 건드려 금액 그대로.
### 2-0. 사용자 확정
- 알약 = 요소 · 표 · 로직 참조 / 글자 = 계산된 중간값 · 소계 · 설계 입력.
- 알약을 누르면 그 자료를 모달로 보임(모달 안 알약 목록은 없앰).
- 자리가 모자라면 그 칸 폭에 맞춰 행바꿈 · 세 묶음(인력·재료·경비) 열 폭을 서로 같게.
- 390px 은 보고 판단(지금 안 봄).
### 2-1. 조각 계약 (브레인 확정 · 서버·화면 두 창이 같이 씀)
`/text` 가 한 줄을 조각 목록으로도 줌. 조각 하나 = `{ "kind": …, "글": 보이는 글, "참조": … }`
| kind | 뜻 | 화면 |
| -------- | ---------------------------------- | ------------------------------------------------------------- |
| `요소` | 인력·자재·기계 등 마스터 한 줄 | 알약 ·`참조` = `{"테이블":"MT","키":"MT000123"}` |
| `표` | 소요량·계수 표 찾기 | 알약 ·`참조` = `{"테이블":"QF","키":…,"행":…,"열":…}` |
| `로직` | 다른 단가산출 로직 부르기 | 알약 ·`참조` = `{"테이블":"GF","키":…}` |
| `값` | 계산된 중간값 · 소계 · 설계 입력 | 그냥 글자 |
| `기호` | `+ - × ÷ ( )` 사칙연산 | 그냥 글자 |
| `글` | 나머지(단위·꼬리말) | 그냥 글자 |
### 2-1. 할 일
- [X] 서버 `/text` 가 한 줄을 **조각 목록**(종류 · 보임 · 참조)으로도 주게 — `master_text.py` · 시험 `test_m01_text.py` — 검증완료(2026-09-22): 시험 16개 통과(새 조각 시험 6개 포함) · 13-4-1·12-4·12-17-1 금액이 앞과 같음(계산 시험과 대조) · 지금 주던 이름글·글·금액·까닭은 그대로
- [X] 단가산출 상세의 수량 칸을 알약+기호로 그림 — `UI_LogicLab_Detail.ts` · 금액 칸은 그대로 둠
- [X] 알약 누르면 모달로 그 자료 · 모달 안 알약 목록은 걷음 — `UI_LogicLab_Modal.ts`
- [X] 칸 폭 맞춰 행바꿈 · 세 묶음 열 폭 통일 — `LogicLab_Style.css`(지목한 `Logic_Style.css` 엔 고칠 자리 없었음)
- [X] ORCA 로 13-4-1 · 12-4 · 12-17-1 확인 — 검증완료: 세 표 폭 729.57px 동일 · 금액 앞과 같음 · typecheck 통과
### 2-2. 이름 식을 계산 없이 (검토 끝 · 승인 대기)
계산이 필요한 자리 셋 — `만약()` 갈래 · 자리 표시 든 요소 참조(14파일) · **로직 부르는 줄 990개의 비목 미정**(가장 큰 걸림돌).
`만약()` 은 417 로직(31%)이 쓰고 88%가 1~2겹 · 한 로직만 28겹. 계산 멈춘 로직 60개는 모두 재료 단가가 비어서이고 `만약()` 과 무관.
- [X] `만약()` — 계산되면 지금처럼 걸린 가지만 · 안 되면 양쪽 다(겹이 셋 이상이면 접어 둠) · `master_text.py` — 검증완료: 조각 단위 시험 둘(계산됨/안 됨)로 확인 · 안 되면 깊이 칸이 붙음
- [X] 자리 표시 요소 참조 — 이름만으로 적고 값은 비움 — 검증완료: `_elem_piece` 시험으로 확인(참조 키 없이 이름만)
- [X] 로직 부르는 줄의 비목 — **확정: 세 비목에 다 걸쳐 보이고 금액 자리는 비움**(계산 전에는 읽기만 하면 됨) · 계산되면 지금처럼 몫대로 — 검증완료: `row` 를 일부러 깨뜨려(요소 없음) 계산이 막혀도 ok:true·이름 식·조각은 남고 금액만 비는 것을 STACK 견본으로 확인(이 견본은 비목이 이미 정해진 인력 줄이라 한 비목에만 걸림 — 세 비목 걸침은 코드 조건(`종류==로직 and 비목 없음`)으로 분기, 990개 전량은 돌리지 않음)
### 2-4. 이름 식을 열자마자 (사용자 지시)
서버는 이미 값 없이 이름 식을 줌(`b9a3fe3a`) · 화면이 `[계산]` 눌러야만 `/text` 를 불러 두 칸이 비어 있음.
- [X] 로직을 열 때 `/text` 를 한 번 불러 **왼쪽 이름 식만** 채움 — `UI_LogicLab_Formula.ts` · `UI_Logic_Calc.ts` · 오른쪽 값 식은 `[계산]` 뒤 그대로 — 검증완료: typecheck 통과 · ORCA로 GF000001(계산 잘 됨) 열자마자 왼쪽 칸에 이름 식 · 오른쪽은 안내 글만 확인 · `[계산]` 뒤 오른쪽도 채워지고 34,413.6 앞과 같음 · GC000677(막힘) 은 열자마자·계산 뒤 둘 다 같은 멈춤 사유(회귀 없음) · onText 가 redraw 를 안 불러 화면에 안 닿는 것을 찾아 `UI_LogicLab.ts` 한 줄(onLines 와 같은 자리) 까지 고침(대상 밖이나 배선상 불가피해 판단으로 포함)
### 2-5. 브레인 직접 확인에서 나온 흠 (사용자 지시)
ORCA 실측 — 모달 막 없앰 ✓ · 알약 ✓ · 세 표 폭 705.58px 통일 ✓ · 돈 자리 정수 ✓.
- [X] 설계 입력이 비면 텍스트 수식이 「멈춤」 한 줄로 덮여 **이름 식이 아예 안 그려짐**(`GF000219` 실측) — 두 칸 얼개를 늘 그리고 왼쪽 이름 식을 보임 · 멈춤 까닭은 곁줄로 — 검증완료: 일찍 되돌아오는 자리는 `master_text._env_of`(입력이 안 갖춰지면 받은 것만 담고 `중간` 은 건너뜀) · 고른 값이 틀린 경우(고르기·범위 밖)는 지금처럼 그대로 멈춤(구분해서 시험 둘로 확인) · 시험 17개 통과 · ORCA로 GF000219 열자마자 왼쪽 칸 이름 식 확인(멈춤 배너 없음) · 값 채워 계산 누르면 79,279.668(비목합·계 둘 다) · GF000001 회귀 없음(34,413.6 그대로) — 프런트는 PLAN 2-4 에서 이미 두 칸을 그리는 자리라 따로 안 고침
- [X] 시험 계산이 2열이 아니라 **3열**(실측 229.85px × 3) — 2열로 고정 — 검증완료: `.m01lab__calc .m01-logic__head`(실제 그릇 — `.m01-logic__calc` 는 안 걸림) 에 `repeat(2, 1fr)` 추가 · ORCA 실측 360.785px × 2 · 요소 표 쪽(auto-fill) 은 그대로
- [X] 데스크탑 메인 `.git/index.lock` — 죽은 `git.exe` 12개(09-22 18:41 이후)가 뿌리 · 정리 뒤 받기 — 검증완료: 12개 정리 · 잠금 지움 · `abd37e89` 도달
### 2-3. 화면 개선 셋 (검토 끝 · 승인 대기)
- [X] 원 단위 소수점 0 — `formatNumber()` 가 돈·수량·비율을 안 가름 · 돈 자리(`m01-logic__money`)만 정수로 · 조합 미리 보기는 딴 사본이라 같이 · 시험 계산 결과·중간값은 값 성격 표식이 없어 못 자름
- [X] 시험 계산 입력 2열 — 요소 표의 `auto-fill` 그리드 재사용 · 그릇 폭 280px 고정을 풀어야 함 · 긴 이름과 고르기/글자 섞인 줄이 걸림
- [X] 계산 입력이 키값만 보임(자재·기계·직종 모두) — 검증완료: 179줄 이름으로 · 못 바꾼 자리 0 · `GC000031` 계산 15,020.927 앞과 같음 — `openPicker` 의 `searchElements` 로 키→이름 · 고른 뒤 품명만 보임 · **한 번에 100건 상한**이라 후보 많은 묶음은 못 다 채움
---
## 3. 단가산출 로직 — 열자마자 계산된 모습 · 알약 항목 · 쉬운 식 · 돈 정수
사용자 확정 — 자동값은 **마스터 보기용**(프로젝트 기본값 아님 · 저장 안 함 · 입력창에서 바로 바꿈) · 글자 고르기 = **목록 첫째** · 숫자 = 쓸 수 있는 가장 낮은 값 · 알약 = **항목만** · 돈 = **계산은 소수 그대로, 화면만 정수** · 후보 0 · 값 빈 품목 = **그 줄만 비우고 로직은 계속**.
실측(앞) — 자동값 없이 열면 멈춤 180 · 첫 후보·0 으로 채우면 계산 1,217/1,354 · 재료 고르기 줄 634 클릭 무반응 · 같은 표 알약 겹침 로직 564.
### 3-1. 계약 (브레인 확정)
| 무엇 | 모양 |
| ---------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| 자동값 | `GET /api/m01/logic/auto?key=` → `{"값": {입력이름: 값}}` — 고르기 = 목록 첫째 · 범위 = 최솟값 · 표에서 찾는 수 = 그 표 가장 낮은 줄 · 나누는 수 = 1 · 그 밖 0 |
| 표 조각 | `글` = 「찾은 줄 · 칸」(예 「합판 · 1회사용」) · `참조.행` = 찾기 조건(예 `{"구분":"합판"}`) |
| 값 조각 | 중간값은`글` 에 이름(예 「재료율」) — 지금은 빈 글 |
| 만약 | 「~이면 · 아니면」 조각 · 안 걸린 갈래 조각에`"흐림": true` · 조건 입력이 비면 두 갈래 다 |
| 돈 | 서버가 만드는 글 안의 돈은 정수 · 화면 돈 모양은 한 벌 |
| 빈 줄 | `/calc` `lines` 한 줄 — 후보 0 · 값 빈 품목(덧줄 포함)은 `단가`·`금액` = `null` · `비목` = `{비목: null}` · `까닭` 글 · 소계·계는 빈 줄 빼고 더함 · 없는 키는 지금처럼 멈춤 — ⚠ `master_text` 가 `null` 금액을 못 더해 자동값으로 62 로직 `/text` 멈춤(sub2) |
| 요소조각 | `/text` 줄마다 단가 자리(요소 · 로직 부르기)를 조각으로 — 로직 = `{kind:로직, 글: 그 로직 이름, 참조:{테이블,키}}` + 인자 `{kind:글, 글: 「기계 트럭(2.5ton) · 지역 전국평균」}` · 요소 = `{kind:요소, 글: 품명}` |
| 표 찾은 줄 | 표 조각`참조.줄` = 엔진 `find` 가 찾은 줄의 차례(그 표 `줄` 배열 · 0부터) · 못 찾으면 없음 |
### 3-2. 서버 — 자동값 · 줄만 비움 (sub1)
- [X] 자동값 길 — 위 규칙대로 · `M01_MasterData_Store.py` · Router · 시험 — 규칙은 새 `master_auto.py` · 한 입력을 표 둘이 쓰면 둘 다에 드는 가장 낮은 값 · 아래 끝 열린 줄(「60 미만」)은 0
- [X] 후보 0 · 값 빈 품목 → 그 줄만 단가·금액 비움 + 까닭 · 로직은 계속 · `master_material.py` · 계산 쪽 — 자리는 `master_formula.run`(호표 줄 · 덧줄) · `master_material` 은 안 고침
- [X] 확인 — 자동값으로 1,354 전부 돌려 멈춤 0(남으면 까닭별 개수) · 13-4-1 · 12-4 금액 앞과 같음 — 검증완료: 1,354 계산 · 멈춤 0 · 빈 줄 153 · 새 시험 `test_m01_auto.py` 8 + `test_m01_text` 17 + api·combo 통과 · GF000160 자동값 계 117,485.212 · GF000219 79,279.668 · GF000001 34,413.6 앞과 같음
### 3-3. 서버 — 조각 글 (sub2)
- [X] 표 조각 글 = 「찾은 줄 · 칸」 · 중간값 이름 · `만약` 쉬운 말 + 흐림 · 조건 입력 비어도 안 멈춤 · `master_text.py`
- [X] 텍스트 수식 글 안의 돈 정수 · 확인 — `GF000160` 일곱 줄 알약 글이 서로 다름 · 값 없이 열어도 멈춤 0 — 검증완료(sub2 `a5d8b53b`): 일곱 줄 글 다름 · 텍스트 멈춤 180→0 · 1,354 금액 변화 0 · 시험 21
### 3-4. 화면 (sub3)
- [X] 열 때 자동값을 시험 계산 입력에 채우고 「견본」 딱지 · 바로 계산 · 바꾸면 다시 계산 · `UI_Logic_Calc.ts`
- [X] 수량 칸을 서버 조각으로 그림(화면 쪽 식 풀이 걷음 · 한 벌) · 알약 글 = 조각 글 · `UI_LogicLab_Detail.ts`
- [X] 재료 고르기 줄 누르면 모달 — 잡힌 품목 + 후보 · 표 알약은 찾은 칸에 색 · `UI_LogicLab_Modal.ts`
- [X] 돈 모양 한 벌 — 상세 · 모달 · 텍스트 수식 소계·계 · 시험 계산 결과 · 일위대가 조합 전부 정수
- [X] 확인 — ORCA 로 `GF000160` · `GF000219` · `GF000001` 열어 수치로 — 검증완료(브레인 ORCA 직접 · `bb4500b4`): 견본 9칸 · 알약 7개 서로 다름 · 표 알약 → 「합판 1.03」 줄·칸 칠함 · 각재 모달 MT000339 616,464 + 후보 72 · 폼타이 사용 → 멈춤 없음·그 줄만 빈칸 · 계 117,485 · 소계 36,163 정수
---
## 4. 무작위 5개 확인에서 나온 흠 (사용자 지시 · 브레인 제안대로)
- [X] 입력 없는 로직(267)도 열 때 한 번 계산 — 지금 줄 금액·값 식이 빔(`GC000657` · `GC000467`) · `UI_Logic_Calc.ts` (sub3) — 검증완료(GC000657 · GC000467 줄 금액 참)
- [X] 이름 식 괄호 — 「노임 * 가1.수량 + … 」 를 「노임 × (… 합)」 으로 · 번호 별칭은 되돌리기 시험이 통과하면 찾은 줄 이름으로(`GC000467`) · `master_text.py` (sub2) — 검증완료: 이름 식·값 식 괄호 살림(GC000467 「노임 * (… 합)」) · 번호 별칭은 이름글에서 그대로 둠(별칭표 이름이어야 되돌려짐 — 찾은 줄 이름은 빈칸·가운뎃점이라 되돌리기 안 됨) · 1,354 금액 변화 0 · 값 없이 멈춤 0 · 시험 25개 통과.
- [X] 원 단위 입력은 견본 0 대신 비움(`null`) → 그 줄만 빈칸 · 로직 계속(`GF000056` 체인톱가격·체인오일단가) · `master_auto.py` · 계산 쪽 (sub1) · 화면은 빈 입력으로 둠 (sub3) — **서버 쪽 끝**(화면 sub3 남음) — 검증완료: 단위에 「원」 든 수 입력 자동값 null(`EmptyInput` — 그 입력을 쓰는 호표·덧줄 줄만 단가·금액 null + 까닭 「입력 비어 있음」) · 1,354 계산 · 멈춤 0(빈 줄 188) · GF000056 체인오일·체인톱 손료 빈칸 · GF000160 계 117,485.212 그대로 · `/text` 자동값 멈춤 0 · 시험 33 통과 — 화면 쪽 null 빈 입력·딱지 없음 코드 끝(sub1 합친 뒤 GF000056 확인 대기) — 검증완료(브레인 ORCA: `GF000056` 가격 두 칸 빔 · 두 줄만 빈칸 · 계 1,066,326)
- [X] 비목 몫으로 갈린 줄에 「노무비 몫」 같은 작은 표시(`GC000007` 굴착기·크레인 세 번) · `UI_LogicLab_Detail.ts` (sub3) — 검증완료(GC000007 노무비·재료비·경비 몫)
- [X] 화면이 빈 입력을 아예 안 보내면 서버가 「입력 없음」으로 멈춤(`GF000056`) — 빠진 입력도 `null` 과 똑같이 그 줄만 비움 (sub1) — 검증완료: 단위에 「원」 든 빠진 입력을 `mf.fill_empty` 가 null 로 채움(`/calc`·`/text` 둘 다) · 입력 둘 뺀 GF000056 체인오일·체인톱 손료만 빈칸 · 1,354 자동값 멈춤 0 · 시험 11 통과(+1) · api·text 시험 통과
- [X] 시험 계산 중간값 칸에 날것 글 `{"중급기술자(건설)":3178696.5,…}` 이 그대로 보임(`GC000467`) — 줄 묶음은 숨기거나 표로 · 돈은 정수 (sub3) — 검증완료(브레인 ORCA: 날것 글 없음)
---
## 5. 무작위 확인 반복 — 사용자처럼 · 두 바퀴(10개) 연속 문제 0 까지 (사용자 지시 · 브레인 자율)
점검 = 브레인 ORCA 스크립트(줄마다 단가×수량=금액 · 소계 합 · 날식 · 깨진 글 · 돈 소수 · 빈 입력 · 줄 모달 · 표 알약 칠하기).
- [X] 1바퀴 — 몫 줄 단가 칸에 전체 단가(`GC001093` 트럭 63,690 × 2 ≠ 99,557) → 몫 단가 = 단가 × 몫 금액 ÷ 줄 금액 · `UI_LogicLab_Detail.ts` (sub3) — 검증완료(GC001093 몫 줄 셋 단가 49,778 · 7,389 · 6,522 × 2 = 금액 · GF000160 117,485 · GC000007 31,078 그대로)
- [X] 1바퀴 — 기계·로직 줄 모달이 날식 「로직(GC000268, 기계='0602-0025', 지역=지역)」 → 서버 `/text` 줄에 `요소조각`(로직 이름 알약 + 인자 이름) (sub2) · 모달은 조각으로 그리고 로직 알약 누르면 그 로직 열기 · 날식은 접은 「원래 식」에만 (sub3) — 검증완료(브레인 ORCA 재점검 0건)
- 서버 쪽 끝(sub2) — `/text` 줄마다 `요소조각` · 시험 26 통과 · 1,354 금액 변화 0 · 값 없이 멈춤 0 · 검증완료 — 화면 쪽 끝(sub3): 모달 윗줄 = 요소조각 · 없으면 로직 키 알약 · 풀이 = 조각 · 날식은 「수량 식」 접힘 안 · 알약 눌러 GC000268 열림 확인 · sub2 요소조각 합친 뒤 알약 글 재확인 대기)
- [X] 2바퀴 — 금액 0 인 로직 부름 줄(`GC000581` 지게차 「사용 안 함」)은 몫으로 안 갈려 조각이 없는 묶음에 놓이고 수량 칸이 날식 「만약(지게차 == '사용', …)」 → 조각은 묶음이 아니라 호표 줄 차례로 찾고 날식으로 떨어지지 않게 · `UI_LogicLab_Detail.ts` (sub3) — 검증완료(GC000581 · GC000187 수량 칸 만약( 없음 · GC001093 · GF000160 회귀 없음)
- [X] 4바퀴 — 값 식 수량이 소수 넷째 자리에서 잘려 산수가 틀려 보임(`GC001064` 「273,308 × 0.0017 = 456」 · 실제 수량 0.00167) → 값 식 수량은 유효숫자로(넷 이상) · `master_text.py` (sub2)
- 검증완료 — 시험 27 통과 · 1,354 금액 변화 0 · 값 없이 멈춤 0 · 보인 수 재계산 어긋남 101 → 1(반올림 경계 GC000295)
- [X] 5바퀴 — 원 미만이 붙은 단가(`GC000360` 산소가스 3.5원)가 상세 표엔 `4`, 값 식엔 `3.5` · 상세 산수 틀려 보임 → 200원 미만 **단가**는 값 식과 같게 유효숫자(브레인 판정: 마스터에 적힌 값이라 「계산된 돈」 아님 · 금액·소계·계는 정수 그대로) · `Logic_Money.ts` · 상세 · 모달 (sub3) · 검증완료(GC000360 산소 3.5 · 3.5×2,143≈7,501 · GF000160 계 117,485 · GC001093 회귀 없음)
- [X] 5바퀴 — 이름 식 별칭이 읽히지 않음(6,811줄 중 표 키 1,188 · 번호 별칭 654 · 붙인 긴 이름 72 · 로직 약 30%) → 별칭 = 표 제목 + 찾은 줄(`낙석방지망설치재료_철망` 꼴) · 표 키 대신 표 제목 · 긴 품명은 줄임 · 식으로 되돌리기 그대로 · `master_copy.py` 별칭 짓기 (sub2 · Opus) · 검증완료(자동값 7,008줄: 표 키 1,188→0 · 번호 별칭 982→4 · 붙인 20자 넘는 이름 108→0 · 펴고 되돌리기 1,354 어긋남 0 · 금액 변화 0 · 빈 입력 멈춤 0 · test_m01 137 통과)
- [X] 5바퀴 — 일위대가 조합 미리 보기가 자동값을 안 씀(`UA000001` 숫자 입력 높이 · t2 가 비어 셋 중 둘 「못 셈」 · 열어도 계산 안 됨) → 담은 로직마다 `/logic/auto` 로 채우고 견본 딱지 · 열자마자 한 번 계산 · `UI_Combo_Preview.ts` (sub1) — 검증완료: typecheck · ORCA UA000001 열자마자 셋 다 계산(못 셈 0) · 합계 167,747 정수 · 견본 딱지 · t2 바꾸면 다시 계산(되돌림)
- [X] 6바퀴 — 표 알약 모달이 찾은 줄을 못 칠함(`GC000010` 「크레인 · 3m이하 · 설치 · 수량」 · 줄에 없는 조건 칸은 무엇이든 맞는 엔진 규칙을 화면이 모름) → 서버가 표 조각 `참조.줄` = 엔진이 찾은 줄 차례(0부터) · 화면은 그 차례로 칠함 (sub2 서버 · sub3 화면) · 화면 쪽 끝(sub3: 참조.줄 있으면 그 차례로 칠함 · GF000160 · GF000047 회귀 없음) · 서버 참조.줄 합친 뒤 GC000010 크레인 칠함 재확인 대기 · 서버 쪽 끝(sub2): 표 조각 참조.줄 = find 가 고른 줄 차례 · 검증완료(GC000010 크레인 줄 · GF000160 합판 7줄 · 금액 변화 0 · test_m01_text 31 통과) · 화면 쪽 남음 — 검증완료(브레인 ORCA 재점검 0건)
- [X] 끝 조건 — 합친 코드로 무작위 5개 두 바퀴 연속 0건(`GF000138` `GF000230` `GF000117` `GC000107` `GC000774` / `GF000240` `GF000249` `GF000037` `GC000718` `GC000002`) · 조합 `UA000001` 열자마자 셋 다 계산 167,747
- [X] 다시 돌림(사용자 지시 · 앞서 잰 74개 뺌) — 점검 넓힘(숫자 입력 바꿔 계산 · 알약 셋까지 · 세 곳 계 대조 · 기본정보 날식) · 새 10개 두 바퀴 연속 0건(`GF000097` `GF000098` `GF000128` `GC000952` `GC000023` / `GF000092` `GF000174` `GF000140` `GC000070` `GC000205`)
- [X] 다시 돌림 2 — 자리 표시 든 참조가 조각에 날글로(`GF000081` 잡품 덧줄 「MO:휘발유:{지역}」 · 모달 「{지역}」) · 쓰는 곳 EQ 82 · MO 42 · LB 14 · MT 2(로직 약 60) → 조각 글은 사람이 읽는 이름 + 지금 입력값(「휘발유 · 전국평균」) · 참조는 풀린 키 · `master_text.py` (sub2) · 검증완료(자동값·빈 입력 14,490줄 날글 48줄(로직 13) → 0 · 금액 변화 0 · test_m01 110 통과)
- [X] 다시 돌림 3 — 자리 표시 든 요소 줄 모달이 스스로 풀다 실패해 날글(`GC000138` 「{연료}:{지역} — 고르기 조건에 맞는 마스터 줄이 없음」 · `GC000559` 「{공수직종} …」) · 계산은 맞음 → 모달은 서버 `요소조각` 의 풀린 이름·참조 키로 단가를 보임 · 날글 금지 · `UI_LogicLab_Modal.ts` (sub3) · 검증완료(GC000138 주연료 할증 자동차용경유 1,846 · GC000559 철골 가공조립공 철골공 252,641 · 날글 없음 · GF000160 각재 · GC001093 트럭 회귀 없음)
- [X] 다시 돌림 끝 — 무작위 8바퀴(40개) + 자리 표시 쓰는 로직 6개 · 흠 둘 고침 · 마지막 두 바퀴 연속 0건
## 6. 전수 점검 — 서버 1,354 × 고르기 후보(계산 17,711) · 화면 1,354 (사용자 지시)
- [X] 표에 없는 입력 조합(「맞는 줄 0개」 329번 · 로직 47 · 예 `GC001000` 조형전정 기계시공)이면 로직 전체 멈춤 → 그 줄만 비우고 계속(브레인 판정 · 「줄만 비움」 원칙) · 까닭 글에 `{…}` · `Decimal('100')` 날글 금지 → 「표 1-2-3 에 시공구분 기계시공 · 수종 낙엽수 · 흉고직경 11㎝미만 인 줄이 없음」 · `master_formula.py` (sub1) — 검증완료: `NoRow`(표 찾기 실패)·`Blank`(못 구한 중간값)로 그 줄만 비움 · 멈춤(calc) 329 → 6(모두 `GC000422` 결과 수 로직 — 비울 줄이 없어 까닭만 날글 없이 멈춤) · 까닭 날글 0(재료 고르기 후보 없음 포함) · 시험 12 통과 · `/text` 는 `master_text._env_of` 가 중간값에서 멈춤(sub2 몫 · PLAN 3-1 빈 줄 계약대로 보고만)
- [X] 값 조각 글 `None`(`GF000185` 콘크리트다짐 38줄) · 값 식 할증 괄호(`GC000376` 「× 1 + 60 %」) · 로직 조각 글이 붙인 별칭(`GC000111` 「굴착기시간당기계경비」 → 로직 이름) · `master_text.py` (sub2) — 검증완료(자동값 · 고르기 후보 전수 날글 0 · 산수 0 · 금액 변화 0)
- [X] 계산이 멈추거나 줄이 비어도 수량 칸 · 시험 계산 칸에 날식 · 날글 금지(`GC001000` 수량 칸 「만약(시공구분 = …」) · `UI_LogicLab_Detail.ts` · `UI_Logic_Calc.ts` (sub3) — 검증완료(GC001000 기계시공 계산 수량 칸 날식 · 날글 없음 · 인력시공 되돌림 · GF000160 회귀 없음)
- [X] 표에 없는 조합에서 `/text` 는 아직 중간값 풀다 멈춤(`master_text._env_of`) · `/calc` 는 줄만 비움으로 계속 → `/text` 도 같은 빈 줄 규칙(이름 식 · 조각은 그대로 · 금액만 빔 · 까닭 사람 말) · `master_text.py` (sub2) — 검증완료(멈춤(calc) 46로직 329조합 /text 멈춤 309 → 0 · 계 /calc 와 같음)
- [X] 전수 끝 — 서버 재점검 17,711번 중 흠 줄 6(`GC000422` 구분↔세부 짝 안 맞는 조합 · 까닭 사람 말 · 흠 아님) · 화면 1,354 첫 전수 흠 3 → 고친 뒤 0 · 마무리 무작위 10개 0건
## 7. 사용자 지시 (2026-09-24 오후)
— 검증완료(GF000160 · UA000001 견본 딱지 0 · 계 117,485 · 167,747 그대로)
- [x] 시험 계산 · 일위대가 조합 미리 보기의 「견본」 딱지 없앰 — 늘 보기용 값이라 뜻 없음(사용자) · `UI_Logic_Calc.ts` · `UI_Combo_Preview.ts` (sub3)
---
## 8. 재료 · 기계 고르기 — 기본 검색어 + 마스터 표 모달 (검토 끝 · 승인 대기)
사용자 확정 — 단위 다르면 막지 않고 경고 · 같은 성격(g ↔ kg ↔ Ton 등)은 환산 · **키를 못 박지 않음**(기본 검색어) · 폐기 품목은 지움 · 고르기는 **자재품목 표 모달**(검색어로 엶 · 드롭다운 걷음) · 고른 품목은 **저장 안 함**(계산 요청에만 실음) · 인력은 뺌(지정값) · 기계는 모달만(기본값 = 원문 분류번호 목록 첫째).
근거 — 재료 줄 675: 키 박음 339 · 조건 첫 후보 315 · 입력 자리 21 · 입력 줄 19 중 14 는 조건 첫째로 바꾸면 자동값이 달라짐(결속선 어닐링철선 → 보통철선) · 같은 단위 후보 0 인 29줄 중 12줄은 단위만 다름.
### 8-1. 계약 — 아래 표를 `_화면_계약.md` · `_틀.md` 에 먼저 적음 (sub4) · 8-2~8-4 는 이 표를 따름 — 끝(`_틀.md` 7장 · `_화면_계약.md` 10장)
| 무엇 | 모양 |
| ----------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| 기본 검색어 | 재료 줄 요소(객체)에`"검색어": "합판(내수) 12t 서울"` · `대표` 키 · 재료 입력 키 목록은 걷음 · 줄에 키를 박은 재료 줄(41)도 객체 + 검색어로 |
| 찾기 규칙 | 검색어 낱말(띄어쓰기로 나눔 ·**지역 낱말은 빼고**)이 모두 이름 또는 규격에 든 자재품목 줄 · 지역 낱말은 차례에만 씀 · 요소에 구분 · 상세구분이 있으면 그 안에서 · 단위는 같은 성격까지(아래 환산) |
| 자동값 차례 | 값 있는 줄 → 줄 단위와 똑같은 단위 → 검색어 안 지역 낱말(서울 등)과 맞는 줄 → 키 차례 · 첫째 |
| 고른 품목 | `/calc` · `/text` 몸에 `"고름": {"<호표 배열 차례 · 0부터 · 맨 위 로직만>": "MT000019"}` · 저장 안 함 · 기계는 그 입력값에 원문 분류번호(목록 밖 번호도 기계 마스터에 있으면 받음) |
| 단위 환산 | 같은 성격만 — 무게 g · kg · ton(톤 · Ton) / 길이 mm · cm · m · km / 넓이 ㎠ · ㎡ / 부피 ㎤ · ℓ · ㎥ · 단가를 줄 단위로 바꿔 계산 |
| 단위 경고 | 성격이 다르면 계산은 하되`/calc` 줄에 `"단위경고": "줄 m · 자재 Ton"` · 화면은 그 줄에 딱지 |
| 모달 검색 | 재료 = 자재품목 표 · 검색 칸 = 검색어 첫 낱말의 괄호 앞(예 「합판(내수)」 → 「합판」) · 잡힌 품목 칠함 / 기계 = 기계 표 · 검색 칸 = 기계 이름(예 「크레인(타이어)」) |
### 8-2. 서버 계산 (sub1)
- [X] 기본 검색어로 찾기 · `고름` 받기 · 단위 환산과 경고 · `master_pick.py`(새) · `master_material.py` · Router 몸 칸 `고름` — 검증완료: `test_m01_pick` 8개 통과 · 1,354 자동값 금액 옛 코드와 변화 0 · 멈춤 0. `고름` 키 = 호표 배열 0부터 차례(맨 위 로직만) · 검색어 낱말은 지역 낱말 빼고 모두 든 줄 · 지역 낱말은 고르는 차례에만 · `cond_text` 는 검색어 있으면 끝에 `|검색어` 더함 · `/calc` 줄에 `단위경고` 칸
- [X] `check_master` — 검색어 후보 0(`로직`) · 단위 경고(`단위`) 줄 세기 — 검증완료
### 8-3. 데이터 바꿔 넣기 (sub2)
- [X] 도구로 대표 키 279 · 줄에 박은 키 41 · 입력 키 목록(재료 76) → 기본 검색어 · 조건만 315줄도 지금 첫 후보가 검색 첫째가 되게 · 1,354 금액 변화 0(`_틀.md` 는 sub4)
- 검증완료(`build_재료_검색어.py` · 재료 줄 591 → 검색어 · 입력 76 걷음 · 1,354 자동값 금액 변화 0 · 계산전부 멈춤 0 → 0 · check_master 로직 0 · 단위 16 그대로 · 점검 스크립트 10로직 143계산 흠 0) · 브레인 판단 뒤: 값 빈 자리표 MT0306… 14줄 그대로(사용자가 채울 자리) · 단위 후보 0 빈 줄 12 중 같은 성격만 검색어로 — 혼화제 g ↔ kg 1줄(GC000684 단가 0 → 5 · 금액은 수량 0 이라 0 그대로) · 성격 다른 11줄(철근 m ↔ Ton · 폼타이 본 등) 빈칸 그대로 · 남은 못 맞춘 25줄 · 유가전력 틀 `MO:{연료}:{지역}` 41줄은 자재품목 키 아님 — 그대로
### 8-4. 화면 (sub3)
- [X] 재료 줄 · 기계 입력에 「품목 고르기」 → 자재품목 · 기계 표 모달(재료 컨테이너 표 재사용) · 검색 칸 채워 엶 · 고르면 다시 계산 · 드롭다운 걷음 — 검증완료(서버 · 데이터 합쳐진 뒤 재확인 대기)
- [X] 단위 경고 딱지 · 확인 — ORCA `GF000160`(합판 17 지역) · `GC000031`(결속선 어닐링철선 그대로) · 기계 크레인(타이어) · 금액 앞과 같음 — 검증완료(GF000160 합판 모달 인천 고름 · GC000031 · 크레인(타이어) 모달 · 계 117,485 · 단위경고 딱지는 가짜 응답으로)
---
### 8-5. 브레인 브라우저 확인에서 나온 흠
- [X] 서버가 재료 줄마다 고른 품목(키 · 이름 · 규격 · 단위 · 값 칸)을 줌 — `/calc` 줄 `품목` (sub1 · 검증완료 — 칸 = 키 · 이름 · 규격 · 단위 · 값칸 · 고름 줄도 같음 · 1,354 금액 변화 0) · `/text` 요소조각 글 = 품명 · 참조 = 그 키 (sub2 — `/text` 쪽 검증완료: `master_text_item.py` 새로 · 재료 줄 요소조각 글 = 잡힌 품목 이름 · 참조 MT 키 · 고름 · 검색어 · 대표 모두 · GF000159 결속선 = 어닐링철선(결속선),서울 · MT000209 · 계 `/calc` 와 같음 · `test_m01_text` 39 통과)
- [X] 화면 — 잡힌 품목은 이름으로(`MT000018.거래가격` 금지) · 모달 검색 칸은 검색어 첫 낱말의 괄호 앞(「합판(내수)」 → 「합판」) · 상세 재료 줄 모달은 서버가 준 품목과 검색 규칙으로(「맞는 마스터 줄 없음」 헛돎 금지) · 단위 경고 딱지를 상세 줄에도 (sub3) — 검증완료(GF000160 잡힌 품목 이름 · 검색 칸 「합판」 · 잡힌 줄 칠함 · 계 117,485 / GF000159 결속선 모달 품목 · 단가 · 후보 15 · 칠함 / GC000938 상세 줄 딱지 · 서버 `/calc` 줄 `품목` 은 올 때 그 이름으로 · 옛 자동값은 `prices` 로)
- [X] 검색이 띄어쓰기를 무시 — 자재 이름 「골 함 석」 · 검색 낱말 「함석」이 안 맞아 모달 후보 0(`GC000938`) · 자동값 금액 변화 0 확인 (sub1 · 검증완료 — 목록 길 `_hit` 양쪽 빈칸 뗌 · 검색어 길은 이미 뗌 · 자동값 품목 변화 0)
## 9. 일위대가 조합 — 실무 일위대가표에서 뽑아 만들기 (한 번만 · 승인 대기)
사용자 확정 — 실무 일위대가표에서 품셈 항목 여럿을 한 이름으로 묶은 호표만 골라 **우리 단가산출 로직 목록의 조합**으로 · 새 품셈 · 새 로직은 안 만듦(우리 로직에 없는 줄은 뺌) · 수치로 나뉜 호표(크기별 등)는 하나로 · 이름은 품셈과 다를 수 있어 줄 구성(직종 · 수량 · 기계)으로 로직을 고름 · 한 번 하고 끝.
기준 — 호표를 우리 로직으로 풀었을 때 **서로 다른 로직이 2개 이상**이면 조합(참조 줄 수가 아님 · 예 합판거푸집 6회는 12-4 한 항목이라 아님).
자료 — 거창 엑셀(호표 14 · 묶음 후보 7) · STmate 파일 7개(봉화 · 영월 · 울진대흥 · 계류보전 · 울진소광 3판 · 읽는 길은 `_STC포맷분석.md`) · 보안(DRM) 걸린 4곳은 풀린 사본이 오면 더함.
### 9-1. 호표 뽑기 · 로직 잇기 (sub4 · Opus)
- [X] 거창 일위대가 시트 + STC 7개의 일위대가 전개에서 호표마다 이름 · 규격 · 단위 · 줄(품명 · 규격 · 수량 · 단위 · 참조) — 중간 결과는 `tmp/일위대가_뽑기/`(git 밖) — 끝: STC 는 옆 엑셀 내보내기(일위대가표 · 단가산출근거)로 읽음 · 소광 변경1차의 새 호표 14개는 엑셀이 없고 STC 속 전개가 암호라 이름만(기슭막이 5 · 집수정 2 · 수로관 · 면목 · 파형강관 · 돌쌓기 2 · 돌붙임 2)
- [X] 줄마다 우리 로직 고르기 — 이름으로 후보 → 후보 로직을 입력 바꿔 계산해 줄 구성이 같아지면 확정 · 못 맞추면 「후보 · 없음」으로 남김 — 끝: 품셈 항목 149줄 중 확정 66 · 후보 66 · 없음 17— 철근가공및조립 한 줄 = 현장가공 + 현장조립 두 로직 합으로 맞음 · 후보는 옛 판 품셈 값이라 수가 달라 후보 · 우연히 수만 맞은 헛짝은 이름으로 걸러 냄
- [X] 판정 — 서로 다른 로직 2개 이상인 호표만 · 같은 품명(치수 글 뗀 것) + 같은 로직 목록은 하나로 · 담은 로직이 조금 다른 같은 품명은 합쳐 하나 — 끝: 묶음 호표 87 → 조합 후보 22(9-3) · 확정 로직 1개 이하라 보류 11
### 9-2. 조합 넣기 (sub4)
- [X] 사용자 검토 — 조합 후보 목록(이름 · 담은 로직 · 못 맞춘 줄 · 합친 호표)을 먼저 보여 드리고 확정 뒤 넣음 — 끝: 브레인이 사용자 자리에서 확정(못 맞춘 줄 한 번 더 · 단위 둘이면 나눔 · 보류 11 그대로)
- [X] `일위대가조합.json` 에 넣음 — 이름 · 단위 · 담은 로직(차례 = 실무 줄 차례) · 비고(로직이 아니라 뺀 줄) · `check_master` 조합 0 · 화면에서 몇 개 열어 미리 보기 계산 — 검증완료: 못 맞춘 줄 72줄을 넓힌 후보(거푸집 · 동바리 · 비계 · 타설 갈래 등)로 다시 계산 → 더 맞춘 줄 0(수가 옛 판 값 · 수만 맞은 헛짝 2건은 이름으로 뺌) · 나눈 조합 3(횡단개거 · 기초 콘크리트 · 콘크리트포장 — 횡단개거(m)은 나눈 뒤 로직 1개라 보류) · 넣은 조합 24(`UA000002`~`UA000025`) · 비고 = 못 맞춘 줄 「품명 규격 — 까닭」 + 실무 호표 · `check_master` 조합 0 · 시험 `test_m01_combo.py` 21 통과 · ORCA 미리 보기 BOX 암거 · 돌붙임 · 횡단개거(개소) 멈춤 없음
### 9-4. 브레인 브라우저 확인에서 나온 것
- [X] 못 맞춘 줄 159 중 107 이 「옛 판 값」(실무가 옛 판 품셈 수량을 써서 수만 다름 · 로직은 분명) → **이름 핵심이 맞는 것만** 담은 로직에 더함(강관동바리 ↔ 강관 동바리 · 레미콘타설 ↔ 레디믹스트콘크리트 타설) · 이름이 다른 짝(PE관 부설 ↔ 부단수 할정자관)은 비고에 「이름이 달라 뺌」 · 조합은 수량을 안 담아 수 차이는 상관없음(브레인 판정) (sub4) — 검증완료: 옛 판 값 107줄 → 담은 로직으로 옮김 73줄(조합 21개에 로직 49개 더함 · 이미 담긴 로직은 안 겹침 · 메모 「(실무 수는 옛 판 값)」) · 이름이 달라 뺌 34줄(깬잡석 · 파쇄석 → 막돌 채집 · 고임돌 → 큰돌 채집 · 기계 채집 → 인력 채집 · 막자갈채우기 → 자갈고르기 · PE관 → 부단수 할정자관) · 「우리 로직에 없음」 28줄은 이름 뜻 + 직종·기계 구성으로 다시 찾음 → 더함 0(기초잡석 부설은 덤프 없고 할석공 더 있어 구성 다름) · `check_master` 조합 0 · 시험 `test_m01_combo.py` 21 통과 · ORCA 미리 보기 BOX 암거 7줄 · 관보호공 14줄 · 기슭막이 11줄 멈춤 없음
- [X] 시험 계산 재료 목록의 가격 출처가 `MT000018.거래가격` 로 보임 → 「거래가격」만 (sub3) — 검증완료(GF000160 「합판(내수 12㎜) (거래가격)」)
- [X] 보류 12개(PE관 매설 · 급수및노폭좁은안내판 · 동물이동통로 · 물넘이집수부 · 선떼 · 연결철근 · 측구보호용잡석채움 · 큰돌메쌓기 · 큰돌흙막이 · 파형강관 부설·매설 · 수로형토사개거 · 횡단개거(m))도 **있는 로직만으로** 넣음 — 로직 1개여도 · 0개면 빈 조합 + 비고 · 사용자가 전체를 봄(사용자 지시) (sub4) — 검증완료: 12개 모두 넣음(`UA000026`~`UA000037` · 넣은 24개는 안 건드림) · 로직 1개 2(선떼 · 동물이동통로) · 2개 7 · 3개 2 · 4개 1(물넘이집수부) · 빈 조합 0 · 옛 판 값 줄은 이름 핵심이 맞으면 담음(수로형토사개거 다지기 → 흙 다지기 포함) · `check_master` 조합 0 · 시험 `test_m01_combo.py` 21 통과 · ORCA 미리 보기 선떼 1줄 · 물넘이집수부 4줄 멈춤 없음
### 9-3. 조합 후보 — 끝(24개 넣음 · 아래 표는 넣기 전 22개)
담은 로직 = 계산이 같아진 것만(실무 줄 차례) · 못 맞춘 줄 = 후보 · 없음(자재 줄은 따로 뺌) · 줄별 자세한 것은 `tmp/일위대가_뽑기/후보목록_상세.txt`.
| 이름 | 단위 | 담은 로직 | 못 맞춘 줄 | 합친 호표 |
| ---------------------- | ------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------- | ------------------------------------------------- |
| 취수장 | 개소 | 레미콘타설`GC000198` · 유로폼 `GC000214` · 철근가공 `GC000206` · 철근조립 `GC000207` · 터파기(기계) `GC000088` · 지수판 `GC000224` · PVC관 부설 `GC000393` · 합판거푸집 `GC000211` · 잡철물 `GC000821` | 6 | 3 (봉화 1 · 영월 1 · 거창 1) |
| 관보호공(유입·유출구) | 개소 | 레미콘타설`GC000198` · 유로폼 `GC000214` · 철근가공 `GC000206` · 철근조립 `GC000207` · 찰붙임(장비) `GF000225` · 큰돌 메쌓기 `GF000226` · 모르타르 배합 `GC000677` · 터파기(기계) `GC000088` | 29 | 15 (봉화 7 · 영월 5 · 울진대흥 2 · 울진소광 1) |
| 기슭막이 | m | 찰쌓기(장비)`GF000222` · 유로폼 `GC000214` · 레미콘타설 `GC000198` · 메쌓기(장비) `GF000220` · 모르타르 배합 `GC000677` · 터파기(기계) `GC000088` | 17 | 14 (봉화 4 · 울진대흥 9 · 울진소광 1) |
| 임도차단기 | 개소 | 잡철물`GC000821` · 레미콘타설 `GC000198` · 철근가공 `GC000206` · 철근조립 `GC000207` · 유로폼 `GC000214` · 터파기(기계) `GC000088` | 3 | 1 (봉화 1) |
| L형옹벽 측구 | m | 레미콘타설`GC000198` · 유로폼 `GC000214` · 문양거푸집 `GF000161` · 철근조립 `GC000207` · 터파기(기계) `GC000088` | 3 | 1 (울진소광 1) |
| 돌붙임 | ㎡ | 찰붙임(장비)`GF000225` · 메붙임(장비) `GF000224` · 레미콘타설 `GC000198` · 모르타르 배합 `GC000677` · 터파기(기계) `GC000088` | 13 | 9 (봉화 4 · 울진대흥 4 · 울진소광 1) |
| 횡단개거 | m·개소 | 터파기(기계)`GC000088` · 레미콘타설 `GC000198` · 합판거푸집 `GC000211` · 메붙임(장비) `GF000224` · 절토면 고르기 `GF000124` | 10 | 6 (봉화 3 · 영월 3) |
| BOX 난간 | m | 레미콘타설`GC000198` · 유로폼 `GC000214` · 철근가공 `GC000206` · 철근조립 `GC000207` | 0 | 2 (봉화 1 · 거창 1) |
| BOX 암거 | m | 레미콘타설`GC000198` · 유로폼 `GC000214` · 철근가공 `GC000206` · 철근조립 `GC000207` | 7 | 3 (봉화 1 · 거창 2) |
| 관보호공 안전난간 | 개소 | 레미콘타설`GC000198` · 합판거푸집 `GC000211` · 철근가공 `GC000206` · 철근조립 `GC000207` | 2 | 1 (봉화 1) |
| 돌수로 | m | 찰붙임(장비)`GF000225` · 메붙임(장비) `GF000224` · 모르타르 배합 `GC000677` · 터파기(기계) `GC000088` | 12 | 4 (봉화 1 · 영월 2 · 울진소광 1) |
| 임도 준공표지석 | 개소 | 레미콘타설`GC000198` · 합판거푸집 `GC000211` · 터파기(기계) `GC000088` · 유로폼 `GC000214` | 4 | 2 (봉화 1 · 울진대흥 1) |
| 콘크리트포장 | m·㎡ | 콘크리트 표층 인력포설`GC000297` · 와이어메시 `GC000665` · 콘크리트포장(인력) `GF000162` · 합판거푸집 `GC000211` | 4 | 3 (봉화 1 · 영월 1 · 울진대흥 1) |
| 포장 난간 | m | 레미콘타설`GC000198` · 유로폼 `GC000214` · 철근가공 `GC000206` · 철근조립 `GC000207` | 0 | 1 (봉화 1) |
| 기초 콘크리트 | m·개소 | 레미콘타설`GC000198` · 유로폼 `GC000214` · 터파기(기계) `GC000088` | 2 | 2 (울진소광 2) |
| 날개벽 | 개소 | 유로폼`GC000214` · 철근가공 `GC000206` · 철근조립 `GC000207` | 1 | 2 (거창 2) |
| 국가지점번호판 | 개소 | 레미콘타설`GC000198` · 합판거푸집 `GC000211` | 3 | 1 (영월 1) |
| 도로반사경 설치 | 개소 | 합판거푸집`GC000211` · 도로반사경 `GC000310` | 5 | 1 (영월 1) |
| 돌조공 | m | 메쌓기(장비)`GF000220` · 터파기(기계) `GC000088` | 4 | 1 (울진소광 1) |
| 취수장 안내판 | 개소 | 레미콘타설`GC000198` · 합판거푸집 `GC000211` | 4 | 1 (영월 1) |
| 임도 안전표지판 | 개소 | 레미콘타설`GC000198` · 합판거푸집 `GC000211` | 5 | 1 (영월 1) |
| 자생수종 이식 | ㎡ | 관목 식재`GC000149` · 관목 굴취 `GC000148` | 1 | 1 (계류보전 1) |
보류(확정 로직 1개 이하) — PE관 매설 · 급수및노폭좁은안내판 · 동물이동통로 · 물넘이집수부 · 선떼 · 연결철근 · 측구보호용잡석채움 · 큰돌메쌓기 · 큰돌흙막이 · 파형강관 부설·매설 · 수로형토사개거.
+7
View File
@@ -61,6 +61,9 @@ from B06_Section.B06_Section_Router_HaulPlan import (
from B07_DesignDetail.B07_DesignDetail_Router import router as b07_design_router
from B07_DesignDetail.B07_DesignDetail_Router_Frame import router as b07_frame_router
from M01_MasterData.M01_MasterData_Router import router as m01_master_data_router
from M02_MasterTemplete.M02_MasterTemplete_Router import router as m02_master_template_router
from M02_MasterTemplete.M02_MasterTemplete_Router_Drawing import router as m02_drawing_router
from M02_MasterTemplete.M02_MasterTemplete_Router_Layers import router as m02_layers_router
from common_util.common_util_audit import note_api_call, record_call_burst
from common_util.common_util_auth import (
require_company,
@@ -632,6 +635,10 @@ app.include_router(b07_frame_router, dependencies=protected_with_company)
# 마스터 데이터 — 회사·프로젝트가 아니라 시스템 관리자만 본다.
system_admin_only = [Depends(verify_session), Depends(require_system_admin)]
app.include_router(m01_master_data_router, dependencies=system_admin_only)
# 마스터 템플릿 — 시스템 층은 시스템 관리자만 · 층(회사·개인·프로젝트)·도면 길은 로그인만(권한은 길 안에서).
app.include_router(m02_master_template_router, dependencies=system_admin_only)
app.include_router(m02_layers_router, dependencies=protected)
app.include_router(m02_drawing_router, dependencies=protected)
# 개발 전용 잠금 해제 — 다른 라우터와 **같은 보호**를 받는다(로그인·회사·프로젝트 접근).
# 그 위에 서버가 환경까지 한 번 더 본다.
app.include_router(dev_unlock_router, dependencies=protected_with_company)
+1 -1
View File
@@ -8,7 +8,7 @@
"build": "node ./config/node_modules/typescript/bin/tsc --noEmit && node ./config/node_modules/vite/bin/vite.js build --configLoader runner && npm run build:corridor && npm run build:server-calc && npm run build:formula && npm run build:b07-cad",
"build:corridor": "node ./config/node_modules/vite/bin/vite.js build --configLoader runner --ssr ../B05_Profile/B05_Profile_Corridor_Node.ts --outDir ../config/corridor_node",
"build:server-calc": "node ./config/node_modules/vite/bin/vite.js build --configLoader runner --ssr ../B06_Section/B06_Section_Server_Calc_Node.ts --outDir ../config/server_calc_node",
"build:formula": "node ./config/node_modules/vite/bin/vite.js build --configLoader runner --ssr ../B08_Quantity/B08_Quantity_Formula_Node.ts --outDir ../config/formula_node",
"build:formula": "node ./config/node_modules/vite/bin/vite.js build --configLoader runner --ssr ../common_util/common_util_sheet_recalc_node.ts --outDir ../config/formula_node",
"install:b07-cad": "npm --prefix B07_DesignDetail/openwebcad install",
"build:b07-cad": "npm run install:b07-cad && npm --prefix B07_DesignDetail/openwebcad run build",
"preview": "node ./config/node_modules/vite/bin/vite.js preview --configLoader runner",
+1 -1
View File
@@ -32,6 +32,6 @@
"maplibre-gl": ["config/node_modules/maplibre-gl"],
}
},
"include": ["A00_Common", "A0*", "B0*", "B1*", "Z0*", "ui_template", "config/**/*", "common_util"],
"include": ["A00_Common", "A0*", "B0*", "B1*", "M0*", "Z0*", "ui_template", "config/**/*", "common_util"],
"exclude": ["0_old", "node_modules", "venv", "dist"]
}