feat(M02): 48-1 구조물 정의 한 벌 — 정의 틀 문서 · 판 1 옮김 · 읽기 길
- 정의 틀 = docs/raw/M02_구조물옵션정의/정의_틀.md (담는 것 · 키 규칙 · 꼴 · 배치 · 그룹 형상 · 규칙 · 동작 · 판 이력) - resources/master_template/구조물정의.json 판 1 = 옛 B05 레지스트리(37종 · 옵션 235) + 옵션표시 + 옵션그룹 키 그대로 옮김 - GET /api/m02/structure-definition(로그인) · PUT(시스템 관리자만 · 판 +1 · 이력 판_N) · 검사(꼴 · 키 겹침 · 규칙 대상) - GET /structure-types · B05 구조물 검사가 새 정의를 읽음(응답 꼴 그대로) · 옵션 보이기 · 그룹 저장도 정의 칸으로 - 프로젝트 structures.json 에 저장 때 정의 판 · 정의에 없는 키 값은 남김(오류 없음) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EYJJRCfHfdCGNhmXTjQKV7
This commit is contained in:
@@ -12,7 +12,11 @@ import os
|
||||
import uuid
|
||||
from typing import Any, Iterable
|
||||
|
||||
from B05_Profile.B05_Profile_Structures_Schema import StructureInstance, structure_type_map
|
||||
from B05_Profile.B05_Profile_Structures_Schema import (
|
||||
StructureInstance,
|
||||
definition_version,
|
||||
structure_type_map,
|
||||
)
|
||||
from common_util.common_util_json import atomic_write_json
|
||||
from M02_MasterTemplete.StructOptions.M02_SO_Options import hidden_keys
|
||||
|
||||
@@ -125,6 +129,8 @@ def save_structures(
|
||||
"revision": revision,
|
||||
"structures": [item.model_dump(mode="json") for item in items],
|
||||
"migrated_legacy": sorted(history),
|
||||
# 저장 때 구조물 정의 판(PLAN 48-1) — 뒤에 정의가 바뀌어도 이 값이 어느 정의로 적혔는지 앎
|
||||
"definition_version": definition_version(),
|
||||
}
|
||||
atomic_write_json(structures_file_path(project_root), payload)
|
||||
return revision
|
||||
@@ -192,12 +198,15 @@ def _validate_options(item: StructureInstance, definition, hidden: set[str] = fr
|
||||
for key, value in item.options.items():
|
||||
option = allowed.get(key)
|
||||
if option is None:
|
||||
raise ValueError(f"{definition.name}에 정의되지 않은 옵션입니다: {key}")
|
||||
# 지금 정의에 없는 키 = 지난 정의 값 — 버리지 않고 그대로 남김(PLAN 48-0 ② · 오류 없음)
|
||||
continue
|
||||
if option.input == "number":
|
||||
if isinstance(value, bool) or not isinstance(value, (int, float)):
|
||||
raise ValueError(f"{definition.name}의 {option.label}은(는) 숫자여야 합니다.")
|
||||
if not (value == value and abs(value) != float("inf")) or value < 0:
|
||||
raise ValueError(f"{definition.name}의 {option.label}은(는) 0 이상이어야 합니다.")
|
||||
elif option.input == "bool" and not isinstance(value, bool):
|
||||
raise ValueError(f"{definition.name}의 {option.label}은(는) 예 · 아니오여야 합니다.")
|
||||
elif option.input == "select" and option.choices and str(value) not in option.choices:
|
||||
raise ValueError(f"{definition.name}의 {option.label} 값이 선택지에 없습니다: {value}")
|
||||
for option in definition.options:
|
||||
|
||||
Reference in New Issue
Block a user