Files
Aislo/resources/master_data/_화면_계약.md
T
eomsangdonandClaude Opus 5.5 54ce67ceb8 refactor(M02): 자재 조합(UM) 지움 — 좌측 컨테이너 · 재료산출 옆 판 · 길(material-combos · 갈라 내기 · 키 적기 자재조합) · 저장소 · 틀 검사 · 복사 길의 UM 줄 · 시스템 층 표 · fixture · 시험
- 자재 고르기 창은 M02_Material_Pick.ts 로 옮겨 남김
- storage 층(회사 · 개인 · 프로젝트) 자재조합.json 은 지우지 않음(읽기만 끊음)
- check_master 틀 검사 · _틀.md 11장 · _화면_계약.md 자재 조합 절 정리

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NPJGtfXo6GMbcpiboQC4uK
2026-10-04 17:39:16 +09:00

30 KiB

관리자 화면 계약 (M01)

resources/master_data/ 첫 층 JSON 을 보고 고치는 화면과 서버(M01_MasterData/) 사이의 약속. 파일 모양은 _틀.md.

1. 공통

  • 길 머리 /api/m01 · 시스템 관리자만(아니면 403).
  • 봉투 칸 이름은 영문 · 줄·표·로직 알맹이는 파일 그대로(한글 칸).
  • 수는 JSON 수로 옴.
  • version = 파일 판본(내용 해시). 읽을 때 받아 두고 저장 때 그대로 돌려줌.
  • file = 파일 이름(소요량_건설품셈_07장_위생기구설비공사.json · 인력.json). 밑줄 파일·하위 폴더는 없음.
  • key = 키(LB000123) — 전체에서 하나. 줄의 원문 번호는 원문번호 칸.
  • 없는 파일·키 = 404 · 틀린 요청 = 400.

2. 읽기

길 받음 줌
GET /groups {groups: [{group, files, rows}]} — 그룹 차례는 _틀.md 2장
GET /groups/{group}/files {files: [{file, book, chapter, edition, rows, version, order}]} — 머리 차례 순
GET /subs file 또는 group {file, version, slot, subs: [{name, book, details}]} — 인력 구분 · 기계 세부분류(머리에 등록된 것) · group(소요량 · 계수 · 로직)은 장 파일에서 모음(구분 = 원문 + 부문 · 상세구분 = 장 · 차례대로)
GET /rows file · page(1) · size(50) · q · sub · detail {file, version, total, page, size, rows: [줄…]}
GET /tables file 또는 group · sub · detail · section · q · page(1) · size(30) {file, version, total, page, size, tables: [{file, 키, 원문번호, 구분, 상세구분, 이름, 기준, 출처, 조건, 값칸, count}]} — 파일을 가로지른 한 목록
GET /table file · key {file, version, table: {표 하나 통째}}
GET /table/options file · key {file, key, 이름, 조건, 범위규칙, 값칸, count, 값: {조건 이름: [값…]}} — 표 줄을 통째로 안 받고 조건 칸의 값만
GET /sections book(필수) · division · chapter · q · limit(200 · 1000까지) {total, sections: [{book, division, chapter, chapterNo, section, title, tables, logics}]} — 원문 절 목록
GET /logics sub · detail · q · blocked(0/1) · owner {logics: [{file, 키, 원문번호, 구분, 상세구분, 이름, 결과단위, 출처, 소유, blocked, reasons}]} — 장 차례대로
GET /logic key {file, version, logic: {로직 한 줄 통째}, blocked, reasons, prices: {요소: 요약 | null}}
GET /elements group · q · limit(50 · 200까지) {total, items: [{ref, file, 원문번호, 구분, 상세구분, 이름, 규격, 단위, 값, 값칸}]}
GET /materials sub(구분) · detail · spec · region(자재지역) · limit(50 · 200까지) {total, 기본, items: [{ref, 구분, 상세구분, 이름, 규격, 단위, 값, 관급}]} — 재료 고르기 조건 안 후보 · 기본 = 시험 계산이 쓸 줄
  • rows 는 요소·로직 파일은 줄, 표형 파일(소요량·계수)은 표 를 줄로 봄.
  • q = 찾기 — 키·원문번호·이름·옛이름 에 든 글(대소문자 무시).
  • sub = 인력 구분·기계 세부분류 거름 · detail = 인력 상세구분 거름 · 빈 글 = 전체.
  • chapter = 「부문 NN장 장 제목」(공통 03장 토공사 · 13장 구조물) · 장 파일 아니면 "".
  • blocked = 로직 검사(check_master.py 로직)에 걸림 · reasons = 걸린 까닭 글.
  • prices = 호표 요소 → {ref, 이름, 규격, 단위, 값}(단가 자동 칸) · 없는 요소는 null · {이름} 이 낀 원문번호·하위 로직 줄은 빠짐(계산 때 정해짐). 품셈재료는 값 = 연결을 따라간 낮은 값(시험 계산용) · 출처 = 그 값의 열(<자재품목 키>.<열>) · 자재지역 후보는 값 null(계산 때 정해짐).
  • elements = 요소 찾기 창 — 그룹 전체에서 q 찾기 · ref = 식에 넣는 키 · 표형 그룹은 값칸 이 옴.
  • materials = 재료 고르기 단계 — 로직 재료 줄 요소 가 조건 {구분, 상세구분, 규격} 이면 이 API 로 후보(방식 A·B·C 가 부품 M01_MasterData_UI_Test_Pick.ts 하나를 같이 씀 · 구분 → 상세구분 → 후보 순으로 좁힘). 값 이 비어 있어도 후보로 둠. 옛 재료 줄(품셈재료 키)은 품셈재료 이름(없으면 이름 첫 낱말)으로 pick?kind=price 후보. 후보 글 = 이름 규격 · 값 있는 열 전부(물가자료 · 유통물가 …). 멈춤 까닭 입력 「X」 없음 · 맞는 줄 0개 는 방식 A·B·C 가 쉬운 말로 바꿔 보임(plainReason) · 빈 수 칸은 「값을 넣어 주세요」 안내 글.
  • 소요량·계수 표의 용도({공종, 대상, 로직키}) = 방식 B 원문 표 미리보기 머리에 안내 · 칸이 없으면 안 보임 · /tables 는 usage 로 용도.대상 거름(기계 sub·detail 은 인력과 같이 구분 → 상세구분).
  • 「새로 만들기」 모달(M01_MasterData_UI_Logic_Wizard*.ts) — 원문 절 = /sections · 그 절의 표 = /tables?section=(소요량·계수) · 표 조건 값 = /table/options · 인력 = /pick?kind=job · 재료 = /pick?kind=price(구분·상세구분 조건 묶음으로 넣음) · 기계 = /elements · 다른 로직 = /logics?q. 시험 계산 = /calc 키 "" + row(파일 안 보냄) · 저장 = /logic/new(소유 현장 · 키 GX 는 서버) · 본떠 만들기 = /logic/copy. 끝수는 묶음 {대상: 계, 자리: 0, 방법} 으로 보냄.
  • section = 절 번호 거름 — 그 절과 그 아래 절만(13-4 는 13-4 · 13-4-1 만 · 13-40 은 안 걸림). 「만들기」가 절을 고르면 그 절의 표만 보임.
  • /sections = 만들기 첫 걸음 — 원문 본문의 절 제목 줄에서 모음(book = 산림품셈 · 건설품셈 · division = 건설품셈 부문(공통 · 토목 · 건축 · 기계설비 · 유지관리) · chapter = 장 번호 두 자리 「13」 · q = 절 번호·제목 찾기). chapter = 「부문 NN장 장 제목」 · chapterNo = 「NN」 · tables · logics = 그 절(아래 절 포함)의 마스터 표·로직 수 — 0 이면 아직 안 올린 절.
  • /table/options = 조건 값 고르기 — 고르기 조건은 줄에 나온 값 차례대로(중복 없음) · 범위 조건은 [[아래, 위]…] · count = 줄 수. 표 몸을 통째로 받지 않으려는 자리에만 씀(통째는 /table).
  • owner = 로직 소유 거름(공용 정본 · 현장 자체) · 빈 글 = 전체.
  • pick = 고르기 창 — price = 재료_자재품목.json(값 = 값 열 다섯 가운데 낮은 값 · 관급 = 관급 값 있음) ref 키 · job = 인력.json 값 있는 공표 직종(구분 「미확보」 빼고) ref 키.

3. 시험 계산

POST /calc 받음 {key, inputs: {이름: 값}, row?, file?, 고름?} — 새 로직은 key "" · 고름 은 10장

  • 됨 — {ok: true, lines: [{이름, 단위, 수량, 단가, 금액, 비목: {비목: 금액}, 출처?, 단위경고?}], sums: {노무비, 재료비, 경비, 계}, middle: {이름: 값}} · 출처 = 재료 줄의 단가 칸 · 단위경고 는 10장
  • 돈 아닌 로직 — {ok: true, result, middle}
  • 멈춤 — {ok: false, reason} (200). 까닭 = 엔진 글 그대로(「입력 「돌」 없음」 · 「값 없음 — 관리자가 채울 값」 …).
  • row 없음 = 저장된 파일로 계산 · row 있음 = 그 로직만 고친 줄로 바꿔(없던 로직이면 file 에 더해) 메모리에서 계산 — 파일에 안 씀. 요소 값은 늘 저장된 파일.
  • 저장 안 한 새 초안 = key "" · row 에 로직 한 줄 통째 · file 은 안 보내도 됨(서버가 메모리에만 얹음). 「만들기」 모달의 [시험 계산] 이 이 길을 씀 — 키를 미리 받지 않음.
  • 끝수 가 묶음이면 계산 끝에 붙음(6장) · 글자면 설명일 뿐 계산에 안 붙음.

POST /text — 몸은 /calc 와 같고, 같은 계산을 사람이 읽는 식 줄로 돌려줌(화면은 받은 글을 그대로 찍음).

  • 됨 — {ok: true, groups: [{비목, 줄: [{이름, 글, 이름글, 짝, 금액, 까닭?}], 소계, 끝수}], 계, 별칭: […]} · 멈춤은 /calc 와 같은 {ok: false, reason}.
  • 글 = 호표 줄은 「단가 * 수량식 = 금액」 · 덧줄은 「식 = 금액」. 중간 값 · 요소 · 찾기() · 로직() · 만약() 은 글자로 안 나오고 그 자리에서 나온 수로 · 「… / 100」 은 「… %」 로 · 수는 화면과 같은 자릿수(소수 넷째 자리까지 · 천 단위 쉼표).
  • 이름글 = 같은 줄을 변수 이름으로 적은 것(「석공노임 * 메쌓기인력.석공 * (1 + 증가율 %) = 석공비」) — 화면 왼쪽 칸 · 글 은 오른쪽 칸.
    • 단가 자리 = 「요소 이름 + 노임(인력) · 손료(기계) · 단가(그 밖)」 · 비목이 나뉜 줄은 「이름 + 비목 + 단가」.
    • 금액 자리 = 「이름 + 비」 · 비목이 나뉜 줄은 「이름 + 비목」 · 덧줄·결과는 그 줄 이름.
    • 표 찾기 · 로직 부르기 = 별칭 이름(7장 규칙 그대로 · 값 칸은 .석공 처럼 뒤에 붙음) · 중간 값 · 입력 · 비목 이름은 그대로 · 만약() 은 두 꼴 모두 걸린 쪽만 적어 줄이 어긋나지 않음.
  • 짝 = 1 부터 매긴 줄 번호(답 전체에서 하나씩 · 묶음을 가로질러 차례대로) — 두 칸을 줄 맞춰 놓고 한쪽을 누르면 다른 쪽을 밝히는 데 씀. 두 꼴은 한 줄 안에 나란히 오므로 줄 수와 차례가 늘 같음.
  • 별칭 = 이름글 에 쓰인 표·로직 이름 목록 — 7장 별칭 과 같은 모양({이름, 종류, 참조, 원문, 밑이름, 값칸, 결과단위, 자리}).
  • 비목 = 노무비 · 재료비 · 경비(돈 아닌 로직은 묶음 하나 결과) · 줄이 없는 비목은 빠짐 · 소계 는 끝수까지 붙은 값이고 끝수 는 그 한 마디(「원 미만 버림」 · 없으면 "") — 끝수는 따로 줄로 안 보임.
  • 하위 로직 줄처럼 한 줄이 여러 비목에 걸리면 비목마다 한 줄씩 · 그 비목 몫으로 단가를 되계산해 적음.
  • 까닭 = 단가가 0 이거나 못 구한 줄의 한 마디(「수량 0 — 이 조건에서는 안 쓰는 줄」 · 「단가 0 — 「MP000082」 값이 아직 없음」).

4. 저장

POST /save 받음 {files: [{file, version, changes: [{op, key, row}]}]}

  • op — edit(키 key 줄을 row 로 바꿈 · 키는 못 바꿈) · add(row 더함 · 키는 서버가 _키대장.json 의 다음 번호로 줌) · delete(key 줄 지움).
  • 요소 파일 = 줄 한 줄 · 표형 파일 = 표 하나 · 로직 파일 = 로직 한 줄. row 는 통째(칸 일부만 보내지 않음).
  • 화면은 조작을 캐시에 쌓고 [저장] 한 번에 보냄 — 서버는 이때만 파일에 씀.
  • 순서: 모든 version 대조 → 모두 적용(메모리) → 검사 → 모두 씀. 하나라도 걸리면 아무것도 안 씀.
답 뜻 몸
200 씀 {files: [{file, version}]} — 새 판본
409 낡은 화면 — 그 사이 파일이 바뀜 {detail: {stale: [file…]}} → 다시 읽고 다시 고침
422 검사 걸림 {detail: {errors: [글…]}}
404 없는 파일·키 {detail}
400 틀린 op · 고친 줄의 키를 바꿈 {detail}
  • 검사 = check_master.py 의 틀(고친 파일) + 로직 변수(모든 로직 파일, 고친 뒤 마스터 기준). 고친 뒤 새로 생긴 걸림만 막음 — 원래 있던 걸림은 막지 않음. 인력·재료의 원문번호 겹침도 걸림(표·로직 원문번호는 절 번호라 겹쳐도 됨 · 자재품목은 줄에 원문번호가 없음).
  • 요소를 지워 어떤 로직이 가리키던 것이 사라지면 로직 변수 검사에 걸림(422).
  • 쓰기는 UTF-8 · LF · 들여쓰기 2칸.

5. 자체 로직 (만들기 · 본뜨기 · 고치기 · 지우기)

정본 로직(소유 「공용」 · 로직_산림품셈… · 로직_건설품셈…)은 이 길로 못 고침 — 403. 고치려면 먼저 복제.

  • 자리 = 로직_자체.json 한 파일(원문 장으로 나누지 않음 — 틀이 「자체」 파일에 장 이름을 두지 않음) · 없으면 서버가 머리({"그룹": "로직", "원문": "자체", "판": <올해>, "줄": []})와 함께 만듦.
  • 키 = 서버가 _키대장.json 에서 GX 다음 번호로 줌 — 화면은 키를 만들지 않음. 원문 절이 같아도 줄마다 다른 키.
  • 소유 = 현장(기본) · 공용. 줄의 구분 = 「자체」 · 상세구분 = 「NN장 장 제목」(출처·원문번호 에서 서버가 찾음 · 원문 절이 없으면 빈 글)은 서버가 넣음.
길 받음 줌
POST /logic/new {logic, owner?} {file, version, key, logic}
POST /logic/copy {key, 이름?, owner?} {file, version, key, logic} — 정본·자체 둘 다 본뜰 수 있음
POST /logic/edit {key, version, logic} {file, version, logic}
POST /logic/delete {key, version} {file, version}
  • logic = 로직 한 줄 통째(_틀.md 7장) · 키·구분·상세구분 은 보내도 서버 것이 이김.
  • version = GET /logic 이 준 그 파일 판본 — 다르면 409 {detail: {stale: [file]}}.
  • copy 는 비고 끝에 「<본뜬 키> 를 본뜸」 을 붙이고 시험입력 은 그대로 가져옴 · 이름 을 주면 그 이름으로.
  • 답 — 200 · 400(틀린 몸) · 403(정본 로직) · 404(없는 키·파일) · 409(낡은 판본) · 422 {detail: {errors: […]}}(검사 걸림 — /save 와 같은 검사).
  • 지움은 그 로직을 부르는 다른 로직이 있으면 422.

6. 끝수

로직 줄의 끝수 는 묶음 {대상, 자리, 방법, 출처?, 비고?} — 계산 맨 끝에 붙음.

  • 대상 — 계(돈 로직 · 비목 합 셋을 각각 끊고 계 = 그 셋의 합) · 결과(돈 아닌 로직의 결과 수).
  • 자리 = 소수 자리(0 = 원 미만 · 3 = 소수 넷째 자리에서).
  • 방법 — 버림 · 올림 · 반올림.
  • 옛 줄의 글자 끝수(「손료 원 미만 버림(…)」)는 원문 근거를 적어 둔 설명 — 계산에 안 붙음(그 끊기는 이미 식 안에 있음).

7. 복사해서 만들기 (별칭 꼴 식)

정본 로직을 식 줄로 펴 보이고, 고친 식을 자체 로직(GX)으로 저장하는 길. 규칙은 ref/_설계_식_복사.md · 엔진은 scripts/master_copy.py.

길 받음 줌
GET /logic/formula key {file, version, key, 소유, prices, 로직, 별칭: […], 줄: […]}
POST /logic/formula/save {로직, 별칭, owner?, 이름?, 본뜬키?} /logic/new 와 같음 — {file, version, key, logic}
POST /logic/formula/preview {로직, 별칭} {logic} — 별칭을 원문으로 되돌린 로직 줄만(저장 안 함)
  • 로직 = 로직 한 줄 통째(_틀.md 7장) · 식 칸만 별칭 꼴(찾기(…)·로직(…) 한 덩이가 이름 하나로). 식이 든 칸 = 호표[].수량 · 호표[].요소(글자일 때) · 중간[].식 · 덧줄[].식 · 결과.식.
  • 별칭 = {이름, 종류(찾기·로직), 참조, 원문, 밑이름, 값칸, 결과단위, 자리: […]} — 원문 이 되돌릴 부르기 글 그대로 · 자리 는 그 별칭이 쓰인 자리표 목록.
  • 줄 = 화면에 쌓을 평평한 목록(읽는 차례 중간 → 호표 → 덧줄 → 결과) · {자리, 갈래, 차례, 이름, 단위, 비목, 식, 출처} · 호표 줄은 종류·요소 가 붙음.
  • 별칭 이름 — 표·로직의 이름 에서 낱말 글자만 남김 · 비거나 12자를 넘으면 키를 그대로 · 완전히 같은 부르기는 하나로 합침 · 같은 표를 다른 인자로 부르면 등장 차례로 번호(합판거푸집1…). 입력·중간·비목·함수·표 값 칸 이름과 겹치면 뒤에 번호를 더 붙임.
  • 값 칸(.석공)은 별칭 뒤에 그대로 둠 — 별칭은 부르기 한 덩이까지만.
  • 별칭은 저장하지 않음 — 화면에 보일 때만 씌우는 겉치레. 저장은 별칭을 원문 으로 되돌린 뒤 5장 logic/new 를 그대로 씀(정본은 손대지 않음 · 늘 새 GX 줄).
  • 되돌릴 때 이미 원문으로 적힌 부르기 안 · 작은따옴표 안 · . 뒤 값 칸 이름은 건드리지 않음.
  • 별칭[].원문 은 부르기 하나여야 함 — 아니면 400. 표를 바꾸면 화면이 그 별칭의 원문 을 새 부르기로 바꿔 보냄.
  • 본뜬키 를 주면 비고 끝에 「<키> 를 본뜸」 을 붙임(5장 logic/copy 와 같은 말) · 이름 을 주면 그 이름으로.
  • 답 — 200 · 400(별칭·몸이 틀림) · 404(없는 키) · 422(검사 걸림 — /save 와 같은 검사).
  • 복사본은 원본을 따라가지 않음(값을 그대로 박은 스냅숏) · 식 안 로직(…) 부르기는 참조 그대로라 그 하위 로직은 계속 정본을 봄.
  • formula/preview 는 저장 전 시험 계산용 — 되돌린 로직 줄을 POST /calc·/text 의 row(file 은 GET /logic/formula 가 준 file)로 그대로 넣어 씀(3장과 같은 길).

8. 식으로 만들기

POST /logic/draft 받음 {text, decided, head?, save?, owner?} — 줄로 적은 식을 받아 변수를 뽑고 검사한 뒤 로직 한 줄로 옮김(해석기 scripts/master_draft.py).

  • text = 줄마다 「이름 = 식」 또는 「식 = 이름」(A * B = C) · 한쪽이 값 이름 하나면 그쪽이 이름 · 양쪽이 다 식이면 그 줄의 등호 자리를 짚어 못읽음. 괄호 안 등호(찾기(…, 뒷길이=높이))와 비교 기호(== <= >= !=)는 안 가름. 빈 줄과 # 는 건너뜀 · 마지막 줄의 값 이름이 결과 변수. 식 글자는 _틀.md 8장 범위만.
  • decided = 변수마다 정한 것 {이름: {무엇, 단위, 비목, 요소 | 찾기 | 값, 설명 · 고르기 · 범위}}.
    • 무엇 — 마스터요소(키 또는 재료 고르기 조건을 요소 에 · 비목 도 정함) · 설계입력(입력 칸이 됨) · 고정값(값 을 중간으로) · 표찾기(찾기 = {표, 값칸, 조건} → 찾기(…).값칸 을 중간으로).
    • 단위 — 마스터요소는 그 줄의 단위(「인」 · 「포」)를 적음. 식에서는 단가라 원/단위 로 셈.
    • 단위 없는 맨 수(횟수 · 배율 · 비율)는 단위 칸에 없음(또는 맨수 · - · % · 빈 글)을 골라 무차원으로 둠 — 「전용 4회」 를 「회」 로 두면 원/회 가 남아 덧셈 검사에 걸림. 칸 자체가 없으면 아직 안 정한 것(정할것 에 단위).
    • 비목 합 이름(노무비 · 재료비 · 경비 · 계)은 정하지 않음 — 덧줄에서만 쓰는 이름.
  • head = 로직 머리(이름 · 결과단위 · 원문번호 · 출처 · 비고 · 끝수). 없으면 검사만 함.
  • 줌 {줄, 변수, 결과, 문제, 다됨, logic} — logic = 옮긴 로직 한 줄(head 가 있을 때만 · 저장 전).
    • 변수 = {이름, 처음, 갈래, 정의줄, 쓰임, 무엇, 단위, 비목, 정할것} · 갈래 = 정의됨(식이 있음) · 미정(쓰기만 함) · 비목합 · 정할것 = 아직 안 정한 칸 이름들. 단위 는 그 값이 식에서 가지는 단위(무차원은 빈 글).
    • 문제 = {줄, 자리, 갈래, 말} · 자리 = 그 줄의 글자 자리(모르면 null) · 갈래 = 못읽음 · 이름 · 두번정의 · 돌고돎 · 안쓰임(= 결과가 하나인지) · 단위 · 덜정함 · 항 · 비목 · 비목합.
    • 단위 검사 — 곱셈은 단위를 곱하고 나눗셈은 나눔(같은 단위끼리 나누면 맨 수) · 덧셈·뺄셈과 만약·최소·최대는 단위가 같아야 함 · 비교는 한쪽이 맨 수면 안 따짐(높이 <= 3). 「m * m」 과 「㎡」 는 같게 봄. 모르는 단위는 안 따짐.
    • 덧줄이 될 값(결과 식의 항 가운데 마스터요소가 없는 것)은 막지 않고 그 값의 정할것 에 비목 을 얹음 — 화면은 「비목을 골라 주세요」 로 보임.
  • save = true 면 POST /logic/new 와 같은 자리에 저장(키 GX 는 서버 · 소유 owner) → 답에 {file, version, key, logic} 이 더 옴. 문제가 하나라도 있으면 422 {detail: {errors, 문제}} 로 아무것도 안 씀.
  • 옮기는 법 — 돈 로직(결과단위 가 「원」 으로 시작)은 결과 식을 + 로 갈라 항마다: 마스터요소 변수 하나면 호표 줄(나머지 곱이 수량) · 비목만 정한 변수면 덧줄 · 그 밖은 문제 항. 나머지 정의 줄은 중간(쓰는 차례대로). 돈 아닌 로직은 호표 없이 중간 + 결과 식.
  • 표 찾기는 글자로 치지 않음 — 변수 하나로 두고 무엇 을 표찾기 로 정할 때 모달이 찾기 묶음을 채움.

9. 일위대가 조합

관리자가 이름을 붙이고 단가산출 로직을 골라 담은 묶음. 파일 모양은 _틀.md 10장 · 엔진은 scripts/master_combo.py.

  • 자리 = 일위대가조합.json 한 파일 · 없으면 서버가 머리({"그룹": "일위대가조합", "판": <올해>, "줄": []})와 함께 만듦.
  • 키 = 서버가 _키대장.json 에서 UA 다음 번호로 줌 — 화면은 키를 만들지 않음.
  • 조합은 담은 로직 목록만 지님 — 수량 · 비율 · 계산은 두지 않음(프로젝트 몫 · B08 · B09).
  • 조합은 요소 그룹이 아님 — GET /groups 목록에 끼지 않고 /rows·/groups/{group}/files 로 다루지 않음(줄 모양이 요소와 아주 다름). 아래 제 길로만.
길 받음 줌
GET /combos sub? detail? q? owner? {combos: […]} — 줄마다 count · blocked · reasons
GET /combo key {file, version, combo, 줄: […], blocked, reasons}
GET /logic/combos key {key, combos: […]} — 이 로직을 담은 조합
POST /combo/new {combo, owner?} {file, version, key, combo}
POST /combo/edit {key, version, combo, owner?} {file, version, combo}
POST /combo/delete {key, version} {file, version}
POST /combo/preview {combo, inputs} {키, 이름, 단위, 줄: […], 노무비, 재료비, 경비, 계, 멈춤}
  • 본뜬키 = 본뜬 원본 조합 키(같은 파일의 다른 UA) 또는 null(원본) — 없는 키 · 자기 키는 400 · 목록 · 상세에 그대로 나옴.
  • POST /combo/delete 는 구조물집계표 · 구조물집계표조합 의 「일위대가」 칸으로 쓰는 열이 있으면 409 {detail: {errors: […], users: [구조물 이름…]}} — 지우지 않음.
  • 조합 알약 GET /combo/{키}/inputs = {키, 이름, 물량: [{키 = 「이름|단위」, 이름, 단위, 로직: […], 배?}], 조건: []} — 같은 이름 · 단위 물량은 한 알약.
  • combo = 조합 한 줄 통째(_틀.md 10장) · 키·소유 는 보내도 서버 것이 이김 · 안 준 칸은 null 로 채워 열 한 벌을 맞춤.
  • version = GET /combo 가 준 그 파일 판본 — 다르면 409 {detail: {stale: ["일위대가조합.json"]}}.
  • GET /combo 의 줄 = 담은 로직에 이름을 붙인 목록 {차례, 로직, 메모, ok, 이름, 원문번호, 구분, 상세구분, 결과단위, 출처} — 없는 키는 ok false 와 까닭.
  • GET /logic/combos 의 combos 줄 = {키, 이름, 구분, 상세구분, 단위, 소유, 차례} — 차례 는 그 조합 안 몇 번째인지(여러 번이면 여럿). 로직 줄에 칸으로 박지 않고 물을 때 훑음.
  • preview 는 보기만 — 마스터에 아무것도 쓰지 않음. combo 는 저장된 키(글자)여도 되고 저장 전 조합 줄(묶음)이어도 됨.
    • inputs = {로직 키: {입력 이름: 값}} — 담은 로직마다 그 자리에서 따로 받음(로직마다 하는 일이 달라 수량이 따로 들어감).
    • 줄 = {차례, 로직, 메모, 이름, 원문번호, 결과단위, 구분, 상세구분, 출처, ok, 갈래, 노무비, 재료비, 경비, 계} · 돈이 아닌 로직은 갈래 「결과」 와 결과 수 하나(비목이 없어 합계에 안 얹음).
    • 못 도는 줄은 통째로 멈추지 않고 그 줄만 ok false · 까닭 · 멈춤 에 한 줄 — 나머지 줄의 합계는 그대로 냄.
  • 답 — 200 · 400(틀린 몸 · 이름 없음 · 모르는 소유) · 404(없는 키) · 409(낡은 판본) · 422 {detail: {errors: […]}}(검사 걸림 — 없는 로직 키 · 같은 로직 두 번 · 빈 조합 · 조합을 담음).

10. 재료 · 기계 고르기

재료 줄은 키 대신 기본 검색어로 품목을 찾음 — 파일 모양 · 찾기 규칙 · 자동값 차례 · 단위 환산은 _틀.md 7장.

무엇 모양
고른 품목 /calc · /text 몸에 "고름": {"<호표 줄 차례>": "MT000019"} · 저장 안 함 · 기계는 그 입력값에 원문 분류번호(목록 밖 번호도 기계 마스터에 있으면 받음)
단위 경고 성격이 다르면 계산은 하되 /calc 줄에 "단위경고": "줄 m · 자재 Ton" · 화면은 그 줄에 딱지
모달 검색 재료 = 자재품목 표 · 검색 칸 = 검색어 첫 낱말(예 「합판」) · 잡힌 품목 칠함 / 기계 = 기계 표 · 검색 칸 = 기계 이름(예 「크레인(타이어)」)
  • 고름 이 없거나 그 줄에 없으면 자동값(_틀.md 7장 차례의 첫째).
  • 고르면 다시 계산 · 고른 품목은 파일에 저장하지 않고 계산 요청에만 실음.
  • 드롭다운 고르기는 걷음 — 재료 줄 · 기계 입력의 「품목 고르기」 가 모달을 검색 칸 채워 엶(재료 컨테이너 표 재사용).
  • 인력은 고르지 않음(지정값).