feat(735-1): 서고 나무 지우기 — 쓰는 곳 경고 표 뒤 그 줄째 지움 · 되돌림
- 새 M02_Library_Delete: 쓰는 줄 미리 보기(종류 · 이름 · 키 · 줄 · 층) · 권한 밖 409 막힘 목록 ·
확인 몸이면 쓰는 문서의 그 줄 지움(store.write 정본 다시 셈) 뒤 문서 지움 · _합친것/ 기록
(지운 문서 · 자리 · 고친 문서 앞판) · 되돌림(그새 고친 문서는 건너뜀) · 단가산출 바탕 · 더한줄 열쇠 당김
- 미리 보기 길 POST {kind}-tree/delete-check · undo 길이 지움 기록도 되돌림 · 합친 것 목록에 「지움」
- 나무 고침 몸 확인 칸 · 세션을 나무 고침에 넘김 · 옛 _refuse_used 걷음
- 화면: 지우기 앞 경고 창(쓰는 곳 N · 표 · 프로젝트 사본 영향 없음 · 되돌림 자리) · 부품 상자
확인창에 detail 칸(넓은 판 · 안 스크롤)
- 시험: 새 test_735_1 · test_716_4 의 쓰는 곳 409 시험을 확인 없음 409 + 목록 꼴로 고침
(지움이 막힘에서 경고 뒤 지움으로 바뀜)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -7,7 +7,10 @@ GET /layers/{층}/{kind}-same — 이 층 + 위 층(회사 · 마스터) 같은
|
||||
POST …/merge {남김, 지움[], 판} — 서버가 지문 다시 셈(다르면 409) · 쓰는 곳 참조를 남김으로
|
||||
(쓰기 권한 닿는 곳만 · `store.write` 정본 다시 셈) · 남은 쓰는 곳이 있는 문서 = 안 지움
|
||||
「남김 — 쓰는 곳 N」 · 나머지 = `{층}/_합친것/<키>.json` 으로 옮김 · 나무 자리 걷음
|
||||
POST …/undo {키} — `_합친것/` 에서 되돌림 · 옮긴 참조도 되돌림
|
||||
POST …/undo {키} — `_합친것/` 에서 되돌림 · 옮긴 참조도 되돌림 · 나무 지움 기록(735-1 `지움` 칸)이면
|
||||
`M02_Library_Delete.undo`(문서 · 자리 · 고친 문서 앞판)
|
||||
POST /layers/{층}/{kind}-tree/delete-check {대상} — 나무 지우기 미리 보기(735-1) · 지울 문서 ·
|
||||
쓰는 줄
|
||||
지움 = 이 층 문서만 · 남김 = 이 층 또는 위 층(위 층과 같은 아래 층 문서 = 남김 = 위 층 키) ·
|
||||
판 = 이 층 서고 나무 판(`{종류}_폴더.json`) · 권한 = 그 층 쓰기 · 프로젝트 사본 = 굳힌 값이라
|
||||
안 건드림 · 지문 = `M02_Library_Same`(733-1) 읽기만.
|
||||
@@ -27,7 +30,7 @@ from pydantic import BaseModel
|
||||
from common_util.common_util_auth import verify_session
|
||||
from common_util.common_util_json import atomic_write_json
|
||||
from M02_MasterTemplete import M02_Labor_Ref as refs
|
||||
from M02_MasterTemplete import M02_Layer_Access as access
|
||||
from M02_MasterTemplete import M02_Library_Delete as deleting
|
||||
from M02_MasterTemplete import M02_Library_Same as same
|
||||
from M02_MasterTemplete import M02_MasterTemplete_Store as store
|
||||
from M02_MasterTemplete import M02_Precombo_Folders as pre_folders
|
||||
@@ -37,8 +40,8 @@ from M02_MasterTemplete.M02_MasterTemplete_Router_Items import Layer, Session, _
|
||||
router = APIRouter(prefix="/api/m02", tags=["M02 MasterTemplete Library Same"])
|
||||
|
||||
Kind = Literal["precombo", "sangeun"]
|
||||
GONE = "_합친것"
|
||||
USER_KINDS = (("labor", "구조물 조합"), ("precombo", "일위대가"), ("sangeun", "단가산출"))
|
||||
GONE = deleting.GONE
|
||||
USER_KINDS = deleting.USER_KINDS
|
||||
_ORDER = {"system": 0, "company": 1, "personal": 2}
|
||||
|
||||
|
||||
@@ -54,6 +57,12 @@ class UndoBody(BaseModel):
|
||||
키: str
|
||||
|
||||
|
||||
class CheckBody(BaseModel):
|
||||
"""나무 지우기 미리 보기 — 나무 고침 `대상` 꼴 `[{경로, 키?}]`."""
|
||||
|
||||
대상: list[dict[str, Any]]
|
||||
|
||||
|
||||
def _bad(status: int, text: Any) -> store.StoreError:
|
||||
return store.StoreError(status, text)
|
||||
|
||||
@@ -92,10 +101,7 @@ def _user_index() -> dict[str, list[tuple[Path, str, str]]]:
|
||||
|
||||
|
||||
def _can_write(session: Session, at: refs.Here) -> bool:
|
||||
try:
|
||||
return access.grant(session, at[0], at[1]).write
|
||||
except HTTPException:
|
||||
return False
|
||||
return deleting.can_write(session, at)
|
||||
|
||||
|
||||
def _retarget(doc: dict[str, Any], olds: set[str], new: refs.Ref) -> dict[str, Any]:
|
||||
@@ -144,17 +150,23 @@ def _gone_rows(folder: Path, kind: str) -> list[dict[str, Any]]:
|
||||
rec = json.loads(path.read_bytes())
|
||||
except (OSError, ValueError):
|
||||
continue
|
||||
if rec.get("종류") == kind:
|
||||
if rec.get("종류") != kind:
|
||||
continue
|
||||
if "지움" in rec: # 나무 지움(735-1) — 남김 없음 · 이름 = 지운 문서들
|
||||
names = [(d.get("문서") or {}).get("이름") or d.get("키") for d in rec["지움"]]
|
||||
row = {"이름": " · ".join(map(str, names)), "남김": None, "고친": rec.get("고친곳")}
|
||||
else:
|
||||
doc = rec.get("문서") or {}
|
||||
out.append(
|
||||
{
|
||||
"키": rec.get("키"),
|
||||
"이름": doc.get("이름") or rec.get("키"),
|
||||
"남김": rec.get("남김"),
|
||||
"때": rec.get("때"),
|
||||
"옮긴곳수": len(rec.get("옮긴곳") or []),
|
||||
}
|
||||
)
|
||||
row = {"이름": doc.get("이름") or rec.get("키"), "남김": rec.get("남김"), "고친": None}
|
||||
out.append(
|
||||
{
|
||||
"키": path.stem,
|
||||
"이름": row["이름"],
|
||||
"남김": row["남김"],
|
||||
"때": rec.get("때"),
|
||||
"옮긴곳수": len(row["고친"] or rec.get("옮긴곳") or []),
|
||||
}
|
||||
)
|
||||
return out
|
||||
|
||||
|
||||
@@ -275,6 +287,10 @@ def undo(session: Session, folder: Path, kind: str, key: str) -> dict[str, Any]:
|
||||
raise _bad(404, f"합친 것에 없음 「{key}」") from None
|
||||
if rec.get("종류") != kind:
|
||||
raise _bad(404, f"합친 것에 없음 「{key}」")
|
||||
if "지움" in rec:
|
||||
got = deleting.undo(session, folder, kind, rec)
|
||||
rec_path.unlink()
|
||||
return {"되돌림": key, **got, **find(folder, kind)}
|
||||
path = folder / kind / f"{key}.json"
|
||||
if path.exists():
|
||||
raise _bad(409, f"「{key}」 키를 그새 다른 문서가 씀 — 되돌릴 수 없음")
|
||||
@@ -328,6 +344,32 @@ def library_same_merge(
|
||||
return _run(merge, session, _root(session, layer, owner, write=True), kind, body)
|
||||
|
||||
|
||||
def check(session: Session, folder: Path, kind: str, picks: list[dict[str, Any]]) -> dict:
|
||||
"""나무 지우기 미리 보기 — 나무 고침을 셈만(저장 안 함) → 지울 문서 · 쓰는 줄."""
|
||||
with store.at(folder):
|
||||
tree_doc, _ = pre_folders._read(kind)
|
||||
try:
|
||||
_, note = pre_folders.apply_many(
|
||||
tree_doc, {"op": "delete", "대상": picks}, pre_folders._keys(kind)
|
||||
)
|
||||
except pre_folders.tree.TreeError as e:
|
||||
raise _bad(e.status, e.detail) from e
|
||||
gone = note.get("지운문서") or []
|
||||
return {"문서": gone, "쓰는곳": deleting.users(session, kind, gone)}
|
||||
|
||||
|
||||
@router.post("/layers/{layer}/{kind}-tree/delete-check")
|
||||
def library_delete_check(
|
||||
layer: Layer,
|
||||
kind: Kind,
|
||||
body: CheckBody,
|
||||
owner: str | None = None,
|
||||
session: Session = Depends(verify_session),
|
||||
) -> dict:
|
||||
"""나무 지우기 미리 보기(735-1) — `{문서, 쓰는곳}`(`M02_Library_Delete.users` 줄)."""
|
||||
return _run(check, session, _root(session, layer, owner, write=True), kind, body.대상)
|
||||
|
||||
|
||||
@router.post("/layers/{layer}/{kind}-same/undo")
|
||||
def library_same_undo(
|
||||
layer: Layer,
|
||||
|
||||
Reference in New Issue
Block a user