feat(733-3): 서고 중복 찾기 · 합치기 서버 등록 · 지문 모듈 연결 · 시험
- M02_Library_Same_Router — 733-1a 지문(Same 한 벌 · above) 으로 묶음 · 합칠 때 지문 다시 셈(다르면 409) - main.py 에 라우터 등록(로그인만 · 층 쓰기 권한은 길 안에서) - 새 시험 test_733_3_library_same_merge(합치기 참조 옮김 · 금액 같음 · 되돌림 · 지문 · 판 409 · 권한 밖 남김 · 위 층 키 · 일반 사용자 회사 층 403 · SC 수량만 다름) - 새 시험 test_733_3_library_same_screen(부품만 · 날 색 없음 · 나무 메뉴 · 서버 길 짝) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -62,14 +62,6 @@ def _ref(at: refs.Here, key: str) -> refs.Ref:
|
||||
return {"층": at[0], "주인": at[1], "키": key}
|
||||
|
||||
|
||||
def _uppers(at: refs.Here) -> list[refs.Here]:
|
||||
"""이 층이 읽는 위 층 — 개인 → 그 회사 · 마스터 / 회사 → 마스터 / 마스터 → 없음."""
|
||||
layer, owner = at
|
||||
if layer == "personal":
|
||||
return [("company", str(owner).split("/")[0]), ("system", None)]
|
||||
return [("system", None)] if layer == "company" else []
|
||||
|
||||
|
||||
def _docs(at: refs.Here, kind: str) -> list[tuple[str, dict[str, Any]]]:
|
||||
folder = refs.folder_of(*at) / kind
|
||||
out = []
|
||||
@@ -83,12 +75,6 @@ def _docs(at: refs.Here, kind: str) -> list[tuple[str, dict[str, Any]]]:
|
||||
return out
|
||||
|
||||
|
||||
def _finger(at: refs.Here, kind: str, doc: dict[str, Any]) -> str | None:
|
||||
"""문서 내용 지문(733-1 · 빈 문서 None) — 참조는 가리킨 문서 지문(층 넘어 사본도 같음)."""
|
||||
with store.at(refs.folder_of(*at)):
|
||||
return same.finger(kind, doc)
|
||||
|
||||
|
||||
# ── 쓰는 곳 ───────────────────────────────────────────────────────────
|
||||
def _user_index() -> dict[str, list[tuple[Path, str, str]]]:
|
||||
"""모든 층(프로젝트 뺌) 훑기 한 번 — {ref_id: [(파일, 종류, 「어디 이름」)]}."""
|
||||
@@ -177,9 +163,10 @@ def find(folder: Path, kind: str) -> dict[str, Any]:
|
||||
mine = refs.where(folder)
|
||||
index = _user_index()
|
||||
groups: dict[str, list[tuple[refs.Here, str, dict[str, Any]]]] = {}
|
||||
for at in [mine, *_uppers(mine)]:
|
||||
marks = same.Same() # 한 요청 안 참조 지문 메모
|
||||
for at in [mine, *same.above(mine)]:
|
||||
for key, doc in _docs(at, kind):
|
||||
if (mark := _finger(at, kind, doc)) is not None:
|
||||
if (mark := marks.finger(kind, doc)) is not None:
|
||||
groups.setdefault(mark, []).append((at, key, doc))
|
||||
out = []
|
||||
for mark, docs in groups.items():
|
||||
@@ -204,7 +191,7 @@ def merge(session: Session, folder: Path, kind: str, body: MergeBody) -> dict[st
|
||||
raw = body.남김 or {}
|
||||
keep_at: refs.Here = (str(raw.get("층") or ""), raw.get("주인") or None)
|
||||
keep = _ref(keep_at, str(raw.get("키") or ""))
|
||||
if keep_at not in [mine, *_uppers(mine)]:
|
||||
if keep_at not in [mine, *same.above(mine)]:
|
||||
raise _bad(400, "남김은 이 층 또는 위 층 문서")
|
||||
if refs.kind_of(keep["키"]) != kind or (keep_doc := refs.read_ref(keep)) is None:
|
||||
raise _bad(404, f"없는 {refs.TITLE[kind]} 「{keep['키']}」")
|
||||
@@ -218,8 +205,9 @@ def merge(session: Session, folder: Path, kind: str, body: MergeBody) -> dict[st
|
||||
tree_doc, 판 = pre_folders._read(kind)
|
||||
if 판 != body.판:
|
||||
raise _bad(409, {"stale": [pre_folders.file_of(kind)], "판": 판})
|
||||
mark = _finger(keep_at, kind, keep_doc)
|
||||
if mark is None or any(_finger(mine, kind, have[k]) != mark for k in gone):
|
||||
marks = same.Same()
|
||||
mark = marks.finger(kind, keep_doc)
|
||||
if mark is None or any(marks.finger(kind, have[k]) != mark for k in gone):
|
||||
raise _bad(409, "내용이 그새 달라짐 — [중복 찾기]를 다시 누름")
|
||||
|
||||
rids = {refs.ref_id(_ref(mine, k)): k for k in gone}
|
||||
|
||||
Reference in New Issue
Block a user