From 6b34f5d7d3d83fe0cdd709f4d0c59044c6d148e7 Mon Sep 17 00:00:00 2001 From: umsangdon Date: Sat, 19 Sep 2026 18:11:40 +0900 Subject: [PATCH] =?UTF-8?q?docs(master=5Fdata):=20=EA=B4=80=EB=A6=AC?= =?UTF-8?q?=EC=9E=90=20=ED=99=94=EB=A9=B4=20=EA=B3=84=EC=95=BD=20=E2=80=94?= =?UTF-8?q?=20M01=20API=20=EA=B8=B8=C2=B7=EC=9D=91=EB=8B=B5=20=EB=AA=A8?= =?UTF-8?q?=EC=96=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 읽기(그룹·파일·줄·표·로직) · 시험 계산 · 저장(409·422) 약속 Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_01PAdA5ThqmtVSsbzjusk1cJ --- resources/master_data/_화면_계약.md | 59 +++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) create mode 100644 resources/master_data/_화면_계약.md diff --git a/resources/master_data/_화면_계약.md b/resources/master_data/_화면_계약.md new file mode 100644 index 00000000..cc4e524c --- /dev/null +++ b/resources/master_data/_화면_계약.md @@ -0,0 +1,59 @@ +# 관리자 화면 계약 (M01) + +`resources/master_data/` 첫 층 JSON 을 보고 고치는 화면과 서버(`M01_MasterData/`) 사이의 약속. 파일 모양은 `_틀.md`. + +## 1. 공통 + +- 길 머리 `/api/m01` · 시스템 관리자만(아니면 403). +- 봉투 칸 이름은 영문 · 줄·표·로직 알맹이는 파일 그대로(한글 칸). +- 수는 JSON 수로 옴. +- `version` = 파일 판본(내용 해시). 읽을 때 받아 두고 저장 때 그대로 돌려줌. +- `file` = 파일 이름(`소요량_건설품셈_기계설비7장.json`). 밑줄 파일·하위 폴더는 없음. +- 없는 파일·열쇠 = 404 · 틀린 요청 = 400. + +## 2. 읽기 + +| 길 | 받음 | 줌 | +|---|---|---| +| `GET /groups` | | `{groups: [{group, files, rows}]}` — 그룹 차례는 `_틀.md` 2장 | +| `GET /groups/{group}/files` | | `{files: [{file, book, chapter, edition, rows, version}]}` | +| `GET /rows` | `file` · `page`(1) · `size`(50) · `q` | `{file, version, total, page, size, rows: [줄…]}` | +| `GET /tables` | `file` · `q` | `{file, version, tables: [{열쇠, 이름, 기준, 출처, 조건, 값칸, count}]}` | +| `GET /table` | `file` · `key` | `{file, version, table: {표 하나 통째}}` | +| `GET /logics` | `book` · `chapter` · `q` · `blocked`(0/1) | `{logics: [{file, book, chapter, 열쇠, 이름, 결과단위, 출처, blocked, reasons}]}` | +| `GET /logic` | `book` · `key` | `{file, version, logic: {로직 한 줄 통째}, blocked, reasons}` | + +- `rows` 는 요소·로직 파일은 `줄`, 표형 파일(소요량·계수)은 `표` 를 줄로 봄. +- `q` = 이름 찾기 — `열쇠`·`이름` 에 든 글(대소문자 무시). +- `chapter` = 파일 이름의 장(`13장` · `01장`) · 없으면 "". +- `blocked` = 로직 검사(`check_master.py 로직`)에 걸림 · `reasons` = 걸린 까닭 글. + +## 3. 시험 계산 + +`POST /calc` 받음 `{book, key, inputs: {이름: 값}}` + +- 됨 — `{ok: true, lines: [{이름, 단위, 수량, 단가, 금액, 비목: {비목: 금액}}], sums: {노무비, 재료비, 경비, 계}, middle: {이름: 값}}` +- 돈 아닌 로직 — `{ok: true, result, middle}` +- 멈춤 — `{ok: false, reason}` (200). 까닭 = 엔진 글 그대로(「입력 「돌」 없음」 · 「값 없음 — 관리자가 채울 값」 …). +- 계산은 저장된 파일로만 — 화면 캐시의 고친 값은 [저장] 뒤에 반영. + +## 4. 저장 + +`POST /save` 받음 `{files: [{file, version, changes: [{op, key, row}]}]}` + +- `op` — `edit`(열쇠 `key` 줄을 `row` 로 바꿈) · `add`(`row` 더함 · `key` 안 씀) · `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칸.