knowledge(마스터): 소요량·계수·로직에 구분·상세구분 — 표·줄마다 칸 · 갈래 목록은 서버가 줌

- 장 파일 137 개의 표 3,028 · 로직 1,351 줄에 구분(원문 + 부문 · 「건설품셈 공통」) · 상세구분(「03장 토공사」) 칸을 직접 둠 · 파일 머리의 부문·차례는 목록 차례로 남김
- 열 차례 — 표는 키 · 원문번호 · 구분 · 상세구분 · 이름 · 기준 · 출처 · 비고 · 조건 · 범위규칙 · 값칸 · 줄 · 주 · 그룹(맨 뒤) · 로직은 소유 다음에 비고
- 서버 — GET /subs?group= 이 구분·상세구분 목록(장 차례대로) · GET /tables 가 파일을 가로질러 구분·상세구분·찾기로 거르고 쪽 나눔 · GET /logics 도 구분·상세구분으로 거름 · 새 줄은 서버가 갈래를 채움 · 죽은 book 칸 걷어냄
- check_master 가 구분·상세구분이 파일 머리·이름과 맞는지 봄 · adopt 가 빌더 줄에 갈래를 찍어 되돌리기 시험 글자까지 같음 · _틀.md · 화면 계약 · 화면 트리 · 시험 같이 고침

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JgUhN55Z3BCYhUJTjwTNfj
This commit is contained in:
2026-09-20 16:30:48 +09:00
co-authored by Claude Opus 5
parent 9de61eb251
commit 10418ccbd4
154 changed files with 8227 additions and 8046 deletions
+52 -4
View File
@@ -125,6 +125,42 @@ MERGED = {
"기계": ("기계.json", "세부분류", {"건설품셈": "건설품셈", "산림품셈": "산림품셈"}),
}
DIVISIONS = ("공통", "토목", "건축", "기계설비", "유지관리")
# 장 파일 줄의 열 차례 — 앞 넷은 한 줄에 · 「그룹」(소요량 파일 안의 계수 표 표시)은 맨 뒤
ROW_ORDER = {
"": (
"",
"원문번호",
"구분",
"상세구분",
"이름",
"기준",
"출처",
"비고",
"조건",
"범위규칙",
"값칸",
"",
"",
"그룹",
),
"로직": (
"",
"원문번호",
"구분",
"상세구분",
"이름",
"결과단위",
"출처",
"소유",
"비고",
"입력",
"중간",
"호표",
"덧줄",
"결과",
"끝수",
),
}
OLD_CHAPTER = re.compile(r"^(소요량|계수|로직)_(산림품셈|건설품셈)_(\D*)(\d+)장\.json$")
CHAPTER = re.compile(r"^(소요량|계수|로직)_(산림품셈|건설품셈|자체)_(\d\d)장_.+\.json$")
_BODY = MASTER.parents[1] / "resources/knowledge/original/원가계산"
@@ -142,6 +178,11 @@ def title(book: str, division: str, number: int) -> str:
return hit.name.split("_", 1)[1]
def detail_of(name: str) -> str:
"""장 파일 이름 → 상세구분 「03장 토공사」."""
return name.removesuffix(".json").split("_", 2)[2].replace("_", " ")
def chapter_file(group: str, book: str, division: str, number: int) -> str:
return f"{group}_{book}_{number:02d}장_{title(book, division, number)}.json"
@@ -230,15 +271,16 @@ def dump_rows(head: dict, rows: list[dict]) -> str:
def keep_text(text: str, old: dict, new: dict) -> str | None:
"""글 모양 그대로 — 「열쇠」 칸 · 바뀐 글 · 머리 부문·차례만 갈음 · 읽어 맞대어 다르면 None."""
"""글 모양 그대로 — 「열쇠」 칸(키·원문번호·갈래) · 바뀐 글 · 머리 부문·차례만 갈음 · 다르면 None."""
rows_old, rows_new = old[_items(old)], new[_items(new)]
spots = list(re.finditer(r'"열쇠": ("(?:[^"\\]|\\.)*"|[-\d.]+)', text))
if len(spots) != len(rows_new):
return None
parts, at = [], 0
for m, row in zip(spots, rows_new):
number = json.dumps(row["원문번호"], ensure_ascii=False)
parts += [text[at : m.start()], f'"": "{row[""]}", "원문번호": {number}']
head = [k for k in ("", "원문번호", "구분", "상세구분") if k in row]
line = ", ".join(f'"{k}": {json.dumps(row[k], ensure_ascii=False)}' for k in head)
parts += [text[at : m.start()], line]
at = m.end()
text = "".join(parts) + text[at:]
swap = {}
@@ -319,8 +361,14 @@ def adopt(folder: Path = MASTER) -> list[str]:
for r in rows
]
data[_items(data)] = rows
# 장 파일 줄은 갈래를 스스로 지님 — 구분 = 원문 + 부문 · 상세구분 = 「NN장 장 제목」
extra = (
{"구분": " ".join(x for x in (src, c[3]) if x), "상세구분": detail_of(target)}
if c
else None
)
stamped = [
_convert(book, r, names) for r in stamp(book, table_id(group, src), rows, target)
_convert(book, r, names) for r in stamp(book, table_id(group, src), rows, target, extra)
]
if group in MERGED:
file, slot, labels = MERGED[group]