feat(M02): 옮기기 같은 이름 = 「이름(1)」 — 항목 · 폴더 · 여러 개 · 붙여넣기 · 복사 생성 한 벌(86-2)

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MgChuAcyBqUkhHMTXomQC7
This commit is contained in:
2026-10-08 12:06:22 +09:00
co-authored by Claude Sonnet 5.5
parent 245eaa77af
commit cd8a226323
9 changed files with 103 additions and 32 deletions
+21 -5
View File
@@ -14,6 +14,7 @@ from __future__ import annotations
import copy
import re
from collections.abc import Callable
from typing import Any
MIN_LEVELS = 4 # 옛 약속 — 종류 · 분류1 · 분류2 · 분류3
@@ -173,6 +174,14 @@ def _taken_item(doc: dict[str, Any], path: list[str], skip=None) -> None:
raise TreeError(409, f"이미 있는 항목 「{name_of(path)}」")
def unique_path(path: list[str], busy: Callable[[list[str]], bool]) -> list[str]:
"""겹치는 경로면 마지막 이름을 「이름(1)」 「이름(2)」… 로 — 옮기기 · 붙여넣기 · 복사 생성이 한 벌을 씀."""
out, n = path, 1
while busy(out):
out, n = [*path[:-1], f"{path[-1]}({n})"], n + 1
return out
def _set_path(col: dict[str, Any], path: list[str]) -> None:
col["경로"] = path
col["머리"] = list(path) # 머리 줄 수는 저장 맞춤(`normalize_table`)이 채움
@@ -272,21 +281,28 @@ def apply(
to = _path(body.get("새경로"), "새경로")
if key:
col = _find(out, key, ids)
moved = [*to, path_of(col)[-1]]
_taken_item(out, moved, [col])
want = [*to, path_of(col)[-1]]
taken = _item_paths(out, [col])
moved = unique_path(want, lambda p: p in taken) # 같은 폴더 같은 이름 = 「이름(1)」
out["열"] = [c for c in out["열"] if c is not col]
_set_path(col, moved)
_place(out, col)
note["경로"] = moved
if moved != want:
note["바뀐이름"] = [moved[-1]]
else:
_folder(out, where, "옮길")
if _under(to, where):
raise TreeError(422, "폴더를 제 안으로 옮길 수 없음")
moved = [*to, where[-1]]
if moved in folders_of(out) or any(_under(p, moved) for p in _item_paths(out)):
raise TreeError(409, f"이미 있는 폴더 「{name_of(moved)}」")
folders_now, paths_now = folders_of(out), _item_paths(out)
moved = unique_path(
[*to, where[-1]],
lambda p: p != where and (p in folders_now or any(_under(x, p) for x in paths_now)),
)
_move_folder(out, where, moved, replace=True)
note["경로"] = moved
if moved[-1] != where[-1]:
note["바뀐이름"] = [moved[-1]]
else: # delete
if key:
gone = [_find(out, key, ids)]