diff --git a/resources/master_data/ref/_설계_로직_만들기.md b/resources/master_data/ref/_설계_로직_만들기.md new file mode 100644 index 00000000..ff7dc1af --- /dev/null +++ b/resources/master_data/ref/_설계_로직_만들기.md @@ -0,0 +1,145 @@ +# 일위대가 로직 만들기 화면 설계 + +품셈을 모르는 설계자가 **빈 화면에서 로직 한 줄을 새로 만드는 길**. 지금 테스트 컨테이너(`M01_MasterData_UI_Test*.ts`)는 이미 있는 로직을 읽고 시험 계산만 해서 이 길을 못 재는 자리를 메움. + +- 만들기 = 방식 A(질문·답 마법사) 확장 · 보기 = 방식 C(흐름 그림). +- 식은 글자로 치지 않음 — 선택지와 블록으로 세움. 글자 식은 「고급」 뒤. +- 저장·계산은 지금 서버 그대로(`POST /calc` · `POST /save`) — 화면만 새로 붙임. + +--- + +## ① 만들기 걸음 + +``` +[1 이름] 무슨 일인지 한 줄 + 결과 단위(원/㎡ · 원/m · 원/개소) + ↓ +[2 원문 절] 책 → 장 → 절 고르기 · 그 절의 표를 용도로 자동 제시 + ↓ +[3 호표 줄] 인력 · 재료 · 기계 · 다른 로직 을 줄로 얹음 · 줄마다 수량 정하기 + ↓ +[4 설계 입력] 표 조건 칸에서 자동 제안 → 받을 값만 남김 · 쉬운 말 설명 달기 + ↓ +[5 덧줄·끝수] 잡재료비 같은 비율 줄 · 원 미만 버림 + ↓ +[6 시험 계산] 견본 값을 넣어 호표와 합계 확인(저장 전) + ↓ +[7 저장] 개인 · 공용 고르기 → 키는 서버가 발급 +``` + +1. **이름** — 「무엇을 얼마만큼 하는 값인지」 한 줄 · 결과 단위는 고르기(`원/㎡` · `원/m` · `원/㎥` · `원/개소` · `원/본` · 그 밖 직접). 단위가 「원」 으로 시작하면 돈 로직(호표) · 아니면 결과 식 하나(`_틀.md` 7장). +2. **원문 절** — 책(산림품셈 · 건설품셈 · 자체) → 장 → 절. 절을 고르면 그 절 번호의 표를 모아 보임 — 「이 절에 쓰는 표」 목록에 표 이름 · 기준(1㎡당) · 용도(`공종` · `대상` = 인력 · 재료 · 기계 · 작업량 조건). 표 하나를 고르면 그 표의 **값 칸이 곧 호표 후보 줄**(석공 · 보통인부 …). +3. **호표 줄** — 줄마다 세 가지를 정함. + - 무엇 — 인력 · 재료 · 기계 · 다른 로직. 인력은 직종 찾기 창(`GET /pick?kind=job`) · 재료는 구분 → 상세구분 → 후보(`GET /materials`) · 기계는 구분 → 기종 · 로직은 로직 목록에서. + - 단위 — 고른 줄의 단위를 그대로 씀(재료 후보는 이 단위로 거름). + - 수량 — 아래 셋 가운데 하나(②). + - 비목은 자동 — 인력 노무비 · 재료 재료비 · 기계 경비(고칠 수 있음). +4. **설계 입력** — 2·3 에서 고른 표의 `조건` 칸을 그대로 입력 후보로 제안. 조건 종류대로 칸 모양이 정해짐 — `고르기`는 표 줄에서 뽑은 목록 · `범위`는 아래·위 · `수`는 수 칸. 설계자에게 물을 것만 남기고 나머지는 붙박이 값으로 접음. 남긴 칸마다 **쉬운 말 한 줄(`설명`)** 과 단위를 받음. +5. **덧줄·끝수** — 「노무비의 몇 %」 같은 줄은 비율 블록으로(비목 고르기 + 퍼센트). 끝수는 고르기(`원 미만 버림` · `원 미만 반올림` · 없음). +6. **시험 계산** — 입력마다 견본 값을 넣고 `POST /calc` 에 `row`(저장 전 줄) · `file` 을 실어 보냄 — 파일에 안 씀. 막히면 까닭을 쉬운 말로(`plainReason`) 보이고 그 걸음으로 되돌림. +7. **저장** — 소유(개인 · 공용) · 파일 고르기 → `POST /save` `op: add`. 검사에 걸리면(422) 아무것도 안 쓰고 까닭을 걸음별로 되짚음. + +## ② 식을 글자로 치지 않는 법 + +수량 한 줄을 세 선택지로 세움 — 고른 것을 화면이 식 글자로 조립. + +``` +[ 직접 값 ] 0.15 → "0.15" +[ 표에서 찾기 ] 표 QF000421 · 값 칸 「석공」 → "찾기(QF000421, 뒷길이=뒷길이, 돌=돌, 쌓기=쌓기).석공" + 조건 칸마다 「설계자에게 물음(입력)」 / 「붙박이 값」 고르기 +[ 다른 로직 ] 로직 GF000220 · 넘길 입력 → "로직(GF000220, 뒷길이=뒷길이)" +``` + +- **곱하기 덧붙임** — 위 셋 뒤에 「× 할증·증가율」 블록을 붙임(`… * (1 + 증가율 / 100)`). 블록은 이름 하나 + 사칙 하나까지 — 더 얽히면 중간 값으로 뺌. +- **조건 나누기** — 「값이 …보다 크면 A, 아니면 B」 블록 → `만약(조건, A, B)`. 블록 겹치기는 두 겹까지 · 그 뒤는 고급. +- **중간 값** — 되풀이되는 식은 이름을 붙여 중간으로 뺌(주③ 증가율 같은 것). 화면은 「이 값은 어디에 쓰나」 로 보임. +- **고급** — 글자 식 칸은 「고급」 을 열 때만. 지금 로직 화면(`M01_MasterData_UI_Logic_Edit.ts`)이 그 자리 — 만들기 화면에서 「고급으로 열기」 한 단추로 넘김. +- 블록이 만든 식은 늘 엔진 문법 그대로라 되읽기도 됨 — 열 때 식을 블록으로 되짚어 보이고, 못 되짚는 식만 글자로 보임. + +## ③ 지금 식 언어·틀·엔진으로 되는 것과 모자란 것 + +되는 것(`_틀.md` 8장 · `scripts/master_formula.py`): + +- `찾기(표, 조건=값).값칸` · `로직(키, 입력=값)` · `만약` · `올림·버림·반올림` · `최소·최대` · 사칙·비교 · 비목 합 이름 · `{입력}` 끼우기 — 위 블록이 쓸 것은 모두 있음. +- 저장 전 계산(`/calc` 의 `row`·`file`) · 새 로직 키 발급(`/save` `op: add`) · 저장 때 전체 검사(422) — 만들기에 필요한 서버 길은 이미 있음. +- 재료 후보 거르기(`/materials` — 구분 · 상세구분 · 규격 · 자재지역 · **호표 줄 단위**) · 표 거르기(`/tables` 의 `usage` = 용도 대상). + +모자란 것(고쳐야 만들기 화면이 섬): + +1. **`끝수` 를 엔진이 안 씀** — 로직 줄의 칸일 뿐, `run()` 이 읽지 않아 계산에 안 붙음. 만들기에서 받으려면 엔진에 한 자리(비목 합·계에 적용) 필요 · 그 전에는 화면에 「적어만 둠」 으로 표시. +2. **TS 타입이 재료 고르기 조건을 못 담음** — `M01_MasterData_UI_Logic_Api.ts` 의 `HoLine.요소: string` · `Logic_Edit.priceCell` 이 `요소.includes(…)` 를 불러 조건 묶음 줄에서 깨짐. `요소: string | 고르기조건` 으로 넓히기 전에는 만들기 화면이 재료 줄을 조건으로 못 세움(키로만 셈). +3. **입력 `설명` 칸이 화면 타입에 없음** — `_틀.md` 7장엔 있고 산림 시험 대상 10개에 채워져 있으나 `LogicInput` 에 없어 마법사가 도움말로 못 씀. +4. **절 목록 API 없음** — 책·장·절과 절 제목은 원문 본문 폴더 이름에 있음(`scripts/master_keys.py` 의 `title`). `GET /sections?book=&chapter=` 한 길 필요. +5. **절로 표 거르기 없음** — 지금은 `/tables?q=13-4` 로 글자 찾기라 `13-40` 까지 걸림. `section=` 한 칸 필요. +6. **표 조건 값 목록이 무거움** — 입력 후보를 뽑으려면 `/table` 로 표를 통째 받아야 함(40줄 표는 괜찮으나 큰 표는 무거움). `/table` 답에 `조건값: {칸: [값…]}` 요약 한 칸 권함. +7. **소유 거름 없음** — `/logics` 에 `owner` 가 없어 개인 로직만 보기가 안 됨. + +## ④ 저장 자리 + +- **소유 칸** — 로직 줄의 `소유` = `공용`(원문 품셈을 옮긴 정본) · `개인`(현장에서 만든 것). 칸은 이미 있음 · 새 로직은 기본 `개인`. +- **파일 가르기** — 정본 장 파일(`로직_산림품셈_13장_구조물.json`)에 개인 줄을 섞지 않음. 자체 로직은 `로직_자체_NN장_<제목>.json` — 파일 이름 규칙(`master_keys.CHAPTER`)이 `자체` 를 이미 받음 · 키는 `GX`(대장 `다음` 에 GX 가 없어 첫 줄이 `GX000001`). +- **키 발급** — 화면은 키를 만들지 않음. `op: add` 로 보내면 서버가 `_키대장.json` 의 다음 번호를 줌. 대장 열쇠는 「절 번호 + 이름」 이라 줄의 절 번호와 겹치지 않음 — 같은 절에 로직을 둘 만들어도 새 키. +- **막는 것** — 저장 전 검사(`check_saved`)를 그대로 받음 · 하나라도 걸리면 아무것도 안 씀. 「값 없는 요소」 처럼 관리자 몫인 까닭은 저장은 되고 계산만 멈춤. +- 프로젝트별·사용자별 자리는 뒤 단계 — 마스터에는 사람 개념이 없음. 지금은 「개인 = 이 설치본의 현장 로직」. + +## ⑤ 기존 로직 본떠 만들기 + +- 로직 목록·시험 컨테이너에서 「이것처럼 새로 만들기」 한 단추 — 고른 로직을 복사해 키 빈 줄로 만들기 걸음 7 번(저장) 직전 상태로 엶. +- 복사할 때 바꾸는 것 — 키 비움 · 소유 `개인` · 파일 자체 파일 · 이름 뒤에 「(수정)」 · 출처는 본뜬 원문 절 그대로 두고 비고에 「<키> 를 본뜸」 한 줄. +- 걸음은 같음 — 이름 → (원문 절은 그대로 두고) 호표 줄 고치기 → 입력 다듬기 → 시험 계산 → 저장. +- 가장 흔한 길 — 원문 품셈 로직에서 재료 한 줄만 현장 자재로 바꾸기 · 덧줄 비율만 바꾸기. +- 본뜬 뒤 원본은 안 바뀜 — 시험 컨테이너의 「바꿔 보기」(`swappedRow`)와 같은 방식으로 복사본에만 씀. + +## ⑥ 화면 구성과 구현 조각 + +``` +로직 화면(관리자) 테스트 컨테이너 +┌───────────────┐ ┌─────────────────────┐ +│ 목록 · 고급 편집기 │◀──「고급」──│ [만들기] A 확장 마법사 │ +└───────────────┘ │ [보기] C 흐름 그림 │ + ▲ └─────────────────────┘ + └─────── 같은 서버 길(/calc · /save) · 같은 부품(Pick) ───────┘ +``` + +- **만들기 = A 확장** — A 는 「입력을 묻고 계산」 · 만들기는 그 앞에 「무엇을 만들지」 걸음을 더한 같은 마법사 틀(한 번에 한 질문 · 뒤로 · 다시). +- **보기 = C** — 저장 직전과 저장 뒤 모두 C 흐름 그림으로 전체를 보임(설계 값 → 표 찾기 → 수량 → × 단가 → 덧줄 → 비목 → 계). `Test_C_Model.ts` 는 순수 함수라 저장 전 줄에도 그대로 씀. + +파일 경계(새로 만들 것 · 한 파일 700줄 아래): + +| 파일 | 몫 | +| --- | --- | +| `M01_MasterData_UI_New.ts` | 걸음 틀 · 만드는 중인 줄 한 벌 · 앞뒤 이동 · 저장 | +| `M01_MasterData_UI_New_Steps.ts` | 걸음별 화면(이름 · 절 · 호표 · 입력 · 덧줄) | +| `M01_MasterData_UI_New_Qty.ts` | 수량 블록(직접 값 · 표에서 찾기 · 다른 로직 · 할증 · 조건) → 식 글자 | +| `M01_MasterData_UI_New_Text.ts` | 화면 글(쉬운 말) | + +그대로 쓰는 것 — `Test_Pick.ts`(재료·기계 고르기) · `Logic_Api.ts`(`fetchLogic` · `runCalc` · `saveFiles` · `fetchMaterials`) · `Test_C*.ts`(보기) · `Logic_Edit.ts`(고급) · `Test_Text.ts`(`plainReason`). + +서버에 더할 것 — `GET /sections`(책·장·절 목록) · `/tables` 의 `section` 거름 · `/table` 답의 `조건값` 요약 · `/logics` 의 `owner` 거름 · `Logic_Api` 타입 셋(`HoLine.요소` 넓히기 · `LogicInput.설명` · `LogicRow.소유`). + +## ⑦ 예 — 산림 13-4-1 메쌓기를 빈 화면에서 + +지금 `GF000219` 와 같은 줄이 나오는 걸음. + +1. **이름** — 「돌쌓기 메쌓기(인력)」 · 결과 단위 `원/㎡` → 돈 로직(호표 모양). +2. **원문 절** — 산림품셈 → 13장 구조물 → `13-4. 돌쌓기` → `13-4-1. 메쌓기(인력)`. + 그 절의 표 둘이 뜸 — `QF000421 메쌓기(인력)`(기준 1㎡ · 용도 인력·작업량 조건 · 값 칸 석공 · 보통인부) · `QF000422 높이에 대한 증가율표`(값 칸 증가율). +3. **호표 줄** — `QF000421` 의 값 칸 둘을 줄로 얹음. + - 석공 — 인력 찾기에서 「석공」(`LB000033`) · 단위 `인` · 수량 = [표에서 찾기] `QF000421` · 값 칸 「석공」 · 조건 셋(뒷길이 · 돌 · 쌓기)을 모두 「설계자에게 물음」 · 뒤에 [× 할증] 블록으로 `증가율` 붙임. + - 보통인부 — 같은 방식(`LB000002` · 값 칸 「보통인부」). + - 비목은 둘 다 노무비 자동. +4. **주(注) 읽기** — 절의 [주]③ 「높이 3m까지 적용 · 넘으면 다음 표」 를 화면이 같이 보임 → [조건 나누기] 블록으로 중간 값 `증가율` 을 세움. + `만약(높이 <= 3, 0, 만약(높이 <= 7.5, 찾기(QF000422, 높이=높이).증가율, 초과증가율))` + — 표 마지막 칸이 범위 값(80∼100)이라 그 자리는 설계자 입력 `초과증가율` 로 받음(`_틀.md` 6장 · 값 칸 범위는 입력으로). +5. **설계 입력** — 3·4 에서 물은 칸이 그대로 입력이 됨. + + | 이름 | 모양 | 설명(쉬운 말) | + | --- | --- | --- | + | 뒷길이 | 고르기 25·30·35·45·55·60·75 (㎝) | 쌓을 돌의 뒤쪽 길이 | + | 돌 | 고르기 견치돌·깬돌·깬잡석·호박돌 및 야면석 | 쌓을 돌 종류 | + | 쌓기 | 고르기 골쌓기·켜쌓기 | 돌을 어긋나게 쌓는지 줄 맞춰 쌓는지 | + | 높이 | 수 (m) | 쌓는 벽 높이 | + | 초과증가율 | 범위 80∼100 (%) | 기준 높이를 넘어 더 드는 품 비율 | + +6. **덧줄·끝수** — 원문에 잡재료·할증 줄이 없어 덧줄 없음 · 끝수 없음. +7. **시험 계산** — 견본으로 뒷길이 35 · 돌 깬잡석 · 쌓기 골쌓기 · 높이 4 · 초과증가율 80 을 넣어 호표 두 줄과 계를 확인. 표에 없는 조합(뒷길이 25 · 견치돌 등)은 「맞는 줄 0개」 로 멈추므로 화면이 「원문 표에 없는 조합」 으로 되짚어 줌. +8. **저장** — 소유 `개인` · 파일 `로직_자체_13장_구조물.json` → 키 `GX……` 발급. 공용 정본으로 올리는 것은 관리자 몫(뒤 단계).