feat(M02): 48-2 지난 판 목록 · 한 벌 읽기 길 · 정의 화면 시험

- GET /api/m02/structure-definition/history · /history/{판}(로그인 누구나 · 없는 판 404)
- 화면이 만드는 고침 한 벌을 서버가 받음 · 판 +1 · 403 · 422 시험(사본 정의)
- 옛 옵션 보이기 · 그룹 시험의 화면 글 검사를 정의 화면 자리로

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016PSXsvyDxjNmufteN5bqmt
This commit is contained in:
2026-10-05 16:17:00 +09:00
co-authored by Claude Opus 5.5
parent ef6faaaf20
commit 4b79e7f39c
5 changed files with 168 additions and 9 deletions
@@ -7,7 +7,9 @@
from __future__ import annotations
import json
from collections.abc import Callable
from datetime import datetime
from pathlib import Path
from typing import Any
@@ -32,6 +34,26 @@ def history_path(version: int) -> Path:
return Path(schema.DEFINITION_PATH).parent / HISTORY / f"판_{version}.json"
def history() -> list[dict[str, Any]]:
"""지난 판 목록 `[{판, 저장일}]` — 이력 `판_N.json` · 저장일 = 파일 고친 때(분까지)."""
folder = history_path(1).parent
rows = []
for path in folder.glob("판_*.json") if folder.is_dir() else []:
number = path.stem.removeprefix("판_")
if number.isdigit():
when = datetime.fromtimestamp(path.stat().st_mtime).strftime("%Y-%m-%d %H:%M")
rows.append({"판": int(number), "저장일": when})
return sorted(rows, key=lambda r: r["판"], reverse=True)
def read_version(version: int) -> dict[str, Any]:
"""지난 판 한 벌(읽기만) — 없으면 404."""
path = history_path(version)
if not path.is_file():
raise store.StoreError(404, f"판 {version} 이력이 없음")
return json.loads(path.read_text("utf-8"))
def _type_errors(doc: dict[str, Any]) -> tuple[list[str], dict[str, dict[str, Any]]]:
"""(틀린 것 · 종류 → {옵션 키: 옵션}) — 종류 꼴 · 키 겹침 · 구조물군 있음."""
errors: list[str] = []