Files
Aislo/M02_MasterTemplete/StructOptions/M02_SO_Router.py
T
eomsangdonandClaude Opus 5.5 863abc7766 feat(구조물표): 322-0 안전망 — 42종 전수 표 시험(지금 결과 기록 · ★ 바뀔 칸 표시) · 「기타」 유령 길 막기(지금 · 지난 판 종류 이름 전부) · 종류 캐시 판 확인(보기 열 때 · 탭 다시 보일 때) · 서버 관 기본값 캐시 걷음
- 전수 표 시험 test_322_0_golden + helper_322_0_golden.cjs · 기록 golden_322_structures.json(측점 · 카드 이름 · 형상 열쇠 · 3D 몸체 · 알약 띠 · 고르기 목록 · 물빼기 · ★ 27칸)
- 이관 = 지금 판 + 구조물정의_이력 판_N 종류 이름 측점은 안 옮김(all_type_names)
- GET /api/m02/structure-definition/version · dropStaleStructureTypes · onStaleStructureTypes
- _registry_defaults lru 걷음(정의 읽기가 이미 파일 시각 캐시)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Ji4nuyLVHcxrXWHTdb5nRD
2026-10-14 14:16:27 +09:00

114 lines
4.8 KiB
Python

"""M02 구조물 옵션 보이기 · 그룹 · 정의 길 — 정본 `M02_SO_Definition.py`(PLAN 48-1) 한 벌.
`router` = 고쳐 씀 · 관리 읽기(`main.py` 가 `system_admin_only` 로 붙임) ·
`read_router` = 읽기만(로그인 누구나 · `main.py` 가 `protected` 로 붙임) · 정의 쓰기는 여기서
시스템 관리자만(`access.require(write=True)` · 아니면 403).
"""
from __future__ import annotations
from typing import Any
from fastapi import APIRouter, Depends, HTTPException
from pydantic import BaseModel
from B05_Profile.B05_Profile_Structures_Schema import definition_version
from common_util.common_util_auth import verify_session
from M02_MasterTemplete import M02_Layer_Access as access
from M02_MasterTemplete import M02_MasterTemplete_Store as store
from M02_MasterTemplete.StructOptions import M02_SO_Definition as definition
from M02_MasterTemplete.StructOptions import M02_SO_Groups as groups
from M02_MasterTemplete.StructOptions import M02_SO_Options as options
router = APIRouter(prefix="/api/m02", tags=["M02 MasterTemplete"])
read_router = APIRouter(prefix="/api/m02", tags=["M02 MasterTemplete"])
class OptionsBody(BaseModel):
판: str = "" # 옵션 표시 표 판 — 어긋나면 409
표시: dict[str, Any] # {종류: {옵션 키: 참 · 거짓}} — 거짓만 남김
class GroupsBody(BaseModel):
판: str = "" # 그룹 표 판 — 어긋나면 409
그룹: dict[str, Any] # {종류: [{id, 이름, 옵션[]}]}
class DefinitionBody(BaseModel):
판: int # 읽어 간 정의 판 — 어긋나면 409
정의: dict[str, Any] # 정의 한 벌(틀 = docs/raw/M02_구조물옵션정의/정의_틀.md)
def _call(fn, *args):
with store.at(store.FOLDER):
try:
return fn(*args)
except store.StoreError as e:
raise HTTPException(status_code=e.status, detail=e.detail) from e
@router.get("/structure-options")
def get_structure_options() -> dict:
"""`{판, 표시, 종류}` — 표시 = 숨긴 것만 · 종류 = 옵션 있는 종류와 그 옵션."""
return _call(options.listing)
@router.put("/structure-options")
def put_structure_options(body: OptionsBody) -> dict:
"""고쳐 씀(낡은 판이면 409 · 없는 종류 · 키는 422) — 돌려주는 것 = 새 `{판, 표시, 종류}`."""
return _call(options.save, body.표시, body.판)
@router.get("/structure-option-groups")
def get_structure_option_groups() -> dict:
"""`{판, 그룹, 종류}` — 그룹 = `{type_id: [{id, 이름, 옵션}]}` · 종류 = 레지스트리 전부."""
return _call(groups.listing)
@router.put("/structure-option-groups")
def put_structure_option_groups(body: GroupsBody) -> dict:
"""고쳐 씀(낡은 판 409 · 없는 종류 · 키 · 겹침 422) — 돌려주는 것 = 새 `{판, 그룹, 종류}`."""
return _call(groups.save, body.그룹, body.판)
@read_router.get("/layers/system/structure-options")
def get_structure_options_read(session=Depends(verify_session)) -> dict:
"""구조물 옵션 보이기 읽기 — 로그인 누구나(마스터 한 벌 · 고쳐 씀은 시스템 관리자만)."""
access.require(session, "system", None)
return _call(options.listing)
@read_router.get("/structure-definition")
def get_structure_definition(session=Depends(verify_session)) -> dict:
"""구조물 정의 한 벌(판 · 구조물군 · 동작 · types · 종류 · 표시 · 그룹 · 배치 · 규칙)."""
access.require(session, "system", None)
return _call(definition.read)
@read_router.get("/structure-definition/version")
def get_structure_definition_version(session=Depends(verify_session)) -> dict:
"""지금 정의 판 `{판}` — B05 · B06 종류 캐시가 판을 볼 때(322-0 · 한 벌을 다 받지 않음)."""
access.require(session, "system", None)
return {"판": definition_version()}
@read_router.get("/structure-definition/history")
def get_structure_definition_history(session=Depends(verify_session)) -> list[dict]:
"""지난 판 목록 `[{판, 저장일}]`(새 판부터) — 로그인 누구나(PLAN 48-2)."""
access.require(session, "system", None)
return _call(definition.history)
@read_router.get("/structure-definition/history/{version}")
def get_structure_definition_at(version: int, session=Depends(verify_session)) -> dict:
"""지난 판 한 벌(읽기만) — 없으면 404."""
access.require(session, "system", None)
return _call(definition.read_version, version)
@read_router.put("/structure-definition")
def put_structure_definition(body: DefinitionBody, session=Depends(verify_session)) -> dict:
"""정의 고쳐 씀 — 시스템 관리자만(403) · 낡은 판 409 · 검사 422 · 판 +1 · 앞 판은 이력."""
access.require(session, "system", None, write=True)
return _call(definition.save, body.정의, body.판)