auto: 2026-09-22 03:10 (EOMSANGDON-HOME)

This commit is contained in:
2026-09-22 03:10:31 +09:00
parent 323e1d2c3d
commit 6a2925a9ec
8 changed files with 305 additions and 18 deletions
+32 -10
View File
@@ -24,6 +24,7 @@ import master_copy as mcp # noqa: E402,F401 (`_Store_Make` 가 `store.mcp` 로
import master_keys as mk # noqa: E402
import master_text as mtx # noqa: E402
from M01_MasterData import M01_MasterData_Store_Cache as cache # noqa: E402
from M01_MasterData.M01_MasterData_Store_Shape import dump, keep_shape # noqa: E402
FOLDER: Path = cm.MASTER # 시험은 사본 폴더로 바꿈
@@ -56,6 +57,22 @@ def read(file: str) -> tuple[dict, str]:
return json.loads(raw, parse_float=Decimal, parse_int=Decimal), version_of(raw)
# ── 한 번 읽어 두기(`_Store_Cache`) ────────────────────────────────────
def loaded() -> tuple[dict[str, dict], object]:
"""(파일 묶음, 색인) — **읽기 전용**. 고칠 것이면 `cm.load` 로 새로 읽을 것."""
return cache.loaded(FOLDER)
def blocks() -> dict[str, list[str]]:
"""로직 키마다 막힘 까닭 — 미리 세어 둔 값(목록에서 검사를 돌리지 않음)."""
return cache.blocks(FOLDER)
def warm() -> None:
"""서버가 뜰 때 뒤에서 미리 읽어 둠 — 첫 목록을 기다리지 않게."""
cache.warm(FOLDER)
def items_key(data: dict) -> str:
return "" if data.get("그룹") in cm.mf.TABLE_GROUPS else ""
@@ -318,9 +335,10 @@ def _logic_files(files: dict[str, dict]):
def logics(sub: str, detail: str, q: str, blocked: int | None, owner: str = "") -> list[dict]:
"""로직 목록 — 구분 · 상세구분 · 소유 · 찾기로 거름(장 차례대로 · 파일을 가로지름)."""
files = cm.load(folder=FOLDER)
whole = cm.mf.Master(files)
"""로직 목록 — 구분 · 상세구분 · 소유 · 찾기로 거름(장 차례대로 · 파일을 가로지름).
막힘은 미리 세어 둔 값(`blocks`) — 목록에서 줄마다 검사를 돌리지 않음."""
files, _ = loaded()
why_of = blocks()
out = []
for name, data in sorted(_logic_files(files), key=lambda f: f[1].get("차례") or 0):
for row in data.get("") or []:
@@ -330,7 +348,7 @@ def logics(sub: str, detail: str, q: str, blocked: int | None, owner: str = "")
continue
if not _hit(row, q):
continue
reasons = cm.mf.check_logic(whole, row)[0]
reasons = why_of.get(str(row.get("")), [])
if blocked is not None and bool(reasons) != bool(blocked):
continue
out.append(
@@ -358,11 +376,10 @@ def logics(sub: str, detail: str, q: str, blocked: int | None, owner: str = "")
def logic(key: str) -> dict:
"""로직 하나 — 키는 전체에서 하나."""
files = cm.load(folder=FOLDER)
files, whole = loaded()
for name, data in _logic_files(files):
for row in data.get("") or []:
if str(row.get("")) == key:
whole = cm.mf.Master(files)
reasons = cm.mf.check_logic(whole, row)[0]
_, version = read(name)
return {
@@ -427,7 +444,7 @@ def elements(group: str, q: str, limit: int) -> dict:
if group not in cm.mf.GROUPS:
raise StoreError(404, f"없는 그룹 「{group}")
hits = []
for name, data in cm.load(folder=FOLDER).items():
for name, data in loaded()[0].items():
if data.get("그룹") != group:
continue
for row in data.get(items_key(data)) or []:
@@ -491,7 +508,7 @@ def materials(sub: str, detail: str, spec: str, region: str, unit: str, limit: i
"""재료 고르기 조건 안 후보 목록 — 화면·테스트 컨테이너가 같이 씀.
`unit` = 호표 줄 단위 — 주면 그 단위 줄만(단위가 다르면 다른 물건).
`기본` = 시험 계산이 쓸 줄(대표 줄이 없을 때의 첫 줄) · 그 줄을 `items` 맨 앞에 둠."""
whole = cm.master(folder=FOLDER)
whole = loaded()[1]
cond = {"구분": sub, "상세구분": detail or None, "규격": spec or None}
env = {cm.mf.REGION: region} if region else {}
keys = cm.mf.candidates(whole, cond, env, unit or None)
@@ -648,8 +665,11 @@ def save(batch: list[dict]) -> list[dict]:
for part in batch:
_apply(after[part["file"]], part.get("changes") or [], part["file"], book)
mk.finish(book)
old = set(cm.check_saved(before, names, mk.load_book(book_path)))
new = [x for x in cm.check_saved(after, names, book) if x not in old]
# 저장이 흔드는 줄만 검사(고친 줄 · 그 줄을 부르던 줄 · 그 요소를 보던 줄) —
# 마스터 전체 검사는 `check_master` 몫
narrowed = cache.narrow(FOLDER, batch, before, after)
old = set(cache.check_saved(before, names, mk.load_book(book_path), narrowed))
new = [x for x in cache.check_saved(after, names, book, narrowed) if x not in old]
if new:
raise StoreError(422, {"errors": new})
if book["다음"] != issued:
@@ -664,4 +684,6 @@ def save(batch: list[dict]) -> list[dict]:
tmp.write_text(text, encoding="utf-8", newline="\n")
os.replace(tmp, FOLDER / name)
out.append({"file": name, "version": version_of(text.encode("utf-8"))})
# 저장 뒤에는 그 파일을 바로 다시 읽게 · 흔들린 자리를 알려 줘 그 줄만 다시 세게
cache.stale(dict.fromkeys(names), narrowed[2])
return out