Files
Aislo/resources/tester/test_743_1_hopyo_forget.py
eomsangdonandClaude Opus 5.5 48848bb287 refactor(785-7): 옛 맞춤 층 Python 지움 · 서버 새 길로 정리 · 낡은 시험 정리
- 지움(git rm) 10 파일 3,374 줄: M02_Hopyo_Finger · Ours · Option · Fit · Combine · Verdict · Line · SkLink · SkPatch · Basis
- Match: 흐름 몫(candidates · name_cands · fix_typo · clause · b_order · _logic_specs · _line_mod · units_of · _state · view · guess · picks · chain) 지움 · 이름 도구 몫 · line_key 남김
- Words: conds · cond_score · close · cosine · jacc 지움 / Shares: sections 지움(trade · eq_key 남김)
- 옮김: Finger.kind_of → Fixed.kind_of · SkLink(sk_line · kept · left · LEFT · WHY) → Sangeun · SkPatch 기계 몫(MACH_IN · MACHINE · SOLO · _mach_logics) → Units.mach_logics
- Sangeun: 옛 /sangeun 몸(build · _sure · Maker.basis · judge · plan · make) 지움 · Kids: first · proposal · order 지움 · Build: build() · unlinked() 지움(모두 고정 Builder · build_all · _order · _origins 남김)
- Router: 옛 길 지움(GET hopyo/{키}/{번} · guess · hopyo-picks · hopyo-build · hopyo-unlinked · hopyo/{키}/sangeun) · GET hopyo/{키} = Judge.view(1차 줄 판정 줄상태 · 만든 · 블록 풀이 셈)
- Marks: 칠 = Judge.judged 만 · Forget: 맞춤 캐시 지움 줄 걷음 · Ledger: Ours.version 판 칸 걷음 · Item: Kids.first 걷음
- Row(덧): 단산 줄 = 장부 짝이 있어도 늘 「2차 필요」(장부 = 1차 후보 힌트만)

시험 정리(까닭 = 지운 길 · 모듈만 시험함):
- 지움 11 파일: test_m02_hopyo_finger · fit · golden · option · ours · basis · seam · flow · draft_calc · test_635 · test_628(지문 · 순위 · 옵션 거꾸로 · 맡은 절 · 옛 확인 흐름)
- 함수 지움: /sangeun · /hopyo-build · /hopyo-unlinked · hopyo-picks · 옛 줄 맞춤 보기를 부르던 것(572 · 718_1 · 729 · 739_1 · 777_1 · 778_5 · 780_1 · labor_national · 705_3 · m02_hopyo_match · 746_1)
- test_621 S2(지문 해시) 지움 · S1 남김 · test_m02_hopyo_build = 장부 길 시험만(PUT 으로 심음)
- 새 길로: 779_2(줄상태 = 1차 판정 · 칠 셈 전 None) · grid · stmate(hopyo-judge 줄 판) · 778_1 · 778_2(Units.mach_logics) · 642_6(Marks 원문) · 642_3 장부 짝 단산 줄 2차 지킴

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-05 01:15:20 +09:00

152 lines
8.0 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""불러오기 엑셀 보관 안 함(PLAN 743-1 · 요구 582-3 · 584-2 · `M02_Hopyo_Forget`).
[끝내기] = 남는 파일 0 · 만든 일위대가 · 단가산출 = 출처(파일 · 때 · 누가)만 · 금액 그대로 ·
엑셀 사본(본뜬 키 · 원본 · 확인 · 품셈 · 줄 메모 「실무 …」) 걷음 ·
실무수량 = 저장 수량과 같을 때만 걷음 · SK 또 = 그 HP 몫만 ·
하루 지난 HP = 목록 숨김 → 올림 때 지움 · 옛 파일 정리 미리 보기(쓰기 0) → 고침.
층 = 임시 폴더.
"""
import json
from datetime import datetime, timedelta, timezone
from M01_MasterData import M01_MasterData_Store as m01
from M02_MasterTemplete import M02_Hopyo_Forget as forget
from M02_MasterTemplete import M02_Hopyo_Store as hs
from M02_MasterTemplete import M02_Labor_Ref as refs
from M02_MasterTemplete import M02_MasterTemplete_Store as store
from M02_MasterTemplete import M02_Template_Layers as layers
from resources.tester.test_m02_hopyo_excel import URL, _post, client # noqa: F401
ALL = "/api/m02/layers/personal/hopyo-build-all"
def _files(folder):
return sorted(p.name for p in (folder / hs.DIRNAME).rglob("HP-*.json"))
def _sums(folder):
"""문서마다 1 단위 기준 계 — 끝내기 전후 같아야 함."""
whole = refs.Expand(m01.loaded()[1])
out = {}
with store.at(folder):
for kind in ("precombo", "sangeun"):
for p in sorted((folder / kind).glob("*.json")):
out[p.stem] = refs.summary(folder, kind, p.stem, whole).get("기준금액")
return out
def _docs(folder, kind):
return {p.stem: json.loads(p.read_bytes()) for p in sorted((folder / kind).glob("*.json"))}
# ── 순수 ──────────────────────────────────────────────────────────────
SURE = {"누가": {"id": 42, "이름": "갑"}, "때": "2026-11-02T00:00:00Z"}
HEAD = {"층": "실무자료", "주인": None, "키": "HP-000003 제2호표", "파일": "가.xls"}
def test_SC_사본_걷음_출처만_실무수량은_저장_수량과_같을_때만():
lines = [
{"로직": "L1", "메모": "실무 0.3㎥ × 1 · 규격", "수량": {"손": 0.3}, "별칭": "엑셀 품"},
{"로직": "L2", "메모": "사용자 메모", "수량": {"손": 2}},
]
doc = {
"이름": "가",
"담은로직": lines,
"자재": [{"코드": "MT1", "수량": {"손": 5}}],
"본뜬": {**HEAD, "원본": ["personal", "7/42"], "확인": SURE, "품셈": [0],
"전국자재": [{"이름": "모래"}], "실무수량": {"줄": {"0": 0.3, "1": 2},
"자재": {"MT1": 5}}},
} # fmt: skip
got = forget.strip_sc(doc)
assert got["본뜬"] == {
"층": "실무자료",
"파일": "가.xls",
"전국자재": [{"이름": "모래"}],
"때": SURE["때"],
"누가": SURE["누가"],
}
assert "메모" not in got["담은로직"][0] and got["담은로직"][1]["메모"] == "사용자 메모"
assert got["담은로직"][0]["별칭"] == "엑셀 품" and got["담은로직"][0]["수량"] == {"손": 0.3}
assert got["자재"] == doc["자재"]
# 742 전 저장본(수량 null) = 실무수량이 셈 근거 → 남김
old = {**doc, "담은로직": [{**x, "수량": None} for x in lines]}
assert forget.strip_sc(old)["본뜬"]["실무수량"] == doc["본뜬"]["실무수량"]
def test_SK_또_그_HP_몫만_걷음():
other = {"키": "HP-000004 단산1", "원본": None, "갈래": "SK", "엑셀품": {}, "이름": "나"}
doc = {"본뜬": {**HEAD, "키": "HP-000003 단산1", "확인": SURE, "갈래": "기초", "엑셀품": {},
"못옮김": [], "또": [other]}} # fmt: skip
got = forget.strip_sk(doc, lambda x: str(x.get("키")).startswith("HP-000003 "))
assert got["본뜬"] == {**{"층": "실무자료", "파일": "가.xls"}, **SURE, "또": [other]}
both = forget.strip_sk(doc, lambda x: True)
assert "또" not in both["본뜬"] and "키" not in both["본뜬"]
# ── 길 ───────────────────────────────────────────────────────────────
def test_끝내기_남는_파일_0_금액_그대로_출처만_다시_올림(client):
folder = layers.personal_dir(7, 42)
assert _post(client).json()["키"] == "HP-000001"
made = client.post(ALL, json={"층": "personal", "키": "HP-000001"}).json()
assert made["만듦"]
before = _sums(folder) # 모두 고정 = 메모 없음(메모 걷음은 순수 시험)
res = client.delete(URL.format("personal") + "/HP-000001")
assert res.status_code == 200
assert _files(folder) == [] # HP · 격자 0
assert _sums(folder) == before # 금액 그대로
for kind in ("precombo", "sangeun"):
for key, doc in _docs(folder, kind).items():
got = doc["본뜬"]
assert got["층"] == "실무자료" and got["파일"] and got["때"], key
assert not {"키", "원본", "확인", "품셈", "갈래", "엑셀품", "못옮김", "또"} & set(got)
lines = doc.get("담은로직") or []
assert not any(str(x.get("메모", "")).startswith("실무 ") for x in lines)
assert hs.done(folder)["지문"] == {} # 끝낸 기록 없음
again = _post(client) # 같은 엑셀 다시 올림 = 새 키(409 없음)
assert again.status_code == 200 and again.json()["키"] == "HP-000002"
def test_하루_지난_HP_목록_숨김_올림_때_지움(client):
folder = layers.personal_dir(7, 42)
assert _post(client).json()["키"] == "HP-000001"
path = folder / hs.DIRNAME / "HP-000001.json"
doc = json.loads(path.read_bytes())
old = datetime.now(timezone.utc) - timedelta(days=1, minutes=1)
doc["올린때"] = old.replace(microsecond=0).isoformat().replace("+00:00", "Z")
path.write_text(json.dumps(doc, ensure_ascii=False), encoding="utf-8")
assert client.get(URL.format("personal")).json()["줄"] == [] # 숨김
assert forget.expired(folder) == ["HP-000001"]
got = _post(client).json() # 같은 엑셀이어도 지난 것 = 지우고 새로(이어서 아님)
assert got["키"] == "HP-000002" and not got.get("이어서")
assert _files(folder) == ["HP-000002.json", "HP-000002.json"] # 이번 것 + 격자
def test_옛_파일_정리_미리_보기_쓰기_0_고침(client):
folder = layers.personal_dir(7, 42)
assert _post(client).json()["키"] == "HP-000001" # 작업 중 — 그대로
home = folder / hs.DIRNAME
(home / "HP-000007.json").write_text(json.dumps({"키": "HP-000007", "호표": []}), "utf-8")
hs._put_done(folder, {"번": 7, "지문": {"ab": {"파일": "옛.xls", "만든": ["SC-000001"]}}})
(folder / "precombo").mkdir(exist_ok=True)
gone = {"이름": "옛", "단위": "개", "담은로직": [{"로직": "L", "메모": "실무 1개 × 1"}],
"본뜬": {**HEAD, "키": "HP-000005 제1호표", "확인": SURE}} # fmt: skip
live = {**gone, "본뜬": {**HEAD, "키": "HP-000001 제1호표", "확인": SURE}}
for key, doc in (("SC-000001", gone), ("SC-000002", live)):
text = json.dumps(doc, ensure_ascii=False)
(folder / "precombo" / f"{key}.json").write_text(text, "utf-8")
snap = {p: p.read_bytes() for p in folder.rglob("*.json")}
rows = forget.tidy(folder)
assert [r["대상"] for r in rows] == ["실무자료/HP-000007", "불러옴.json", "SC-000001"]
assert {p: p.read_bytes() for p in folder.rglob("*.json")} == snap # 미리 보기 = 쓰기 0
assert forget.tidy(folder, apply=True) == rows
assert _files(folder) == ["HP-000001.json", "HP-000001.json"]
assert hs.done(folder) == {"번": 7, "지문": {}}
docs = _docs(folder, "precombo")
assert "키" not in docs["SC-000001"]["본뜬"] and "메모" not in docs["SC-000001"]["담은로직"][0]
assert docs["SC-000002"] == live # 작업 중 HP 것 그대로
assert forget.tidy(folder) == [] # 두 번째 = 할 일 없음