"""2026-10-20: manual v0.2.14 -> v0.2.15 (검토 요약 확정), planning document v0.1.10 -> v0.1.11 (6.9), OPEN #36. Old files move to backup/.""" import shutil from pathlib import Path R = Path(__file__).resolve().parents[4] DOC = R / "DOC" / "04_실행" SRC = DOC / "실행_T형교각모델링앱사용설명서_2026-10-20_v0.2.14.md" DST = DOC / "실행_T형교각모델링앱사용설명서_2026-10-20_v0.2.15.md" s = SRC.read_text(encoding="utf-8") def rep(a, b): global s assert s.count(a) == 1, a[:70] s = s.replace(a, b) i = s.index("| v0.2.14 | 2026-10-20 |") j = s.index("\n", i) s = s[:j + 1] + "| v0.2.15 | 2026-10-20 | 심영표 | 「검토 요약 확정」 추가(한 화면에서 검토하고 한 번에 확정, 사유 자동 기록): 4 화면 구성, 5.4, 6.1, 8, 9 | 사용자 \"확정 판정에 시간이 너무 걸리고 사용자가 확인하기 어렵다\" → 권고안 진행 |\n" + s[j + 1:] rep("| 일치 묶음 일괄 확정 | 교각 화면의 버튼 |", "| 검토 요약 확정 | 교각 화면의 [검토 요약으로 확정] | 확정이 필요한 묶음을 **한 화면**에 모아 \"바뀐 것 · 앱이 확인한 것 · 앱이 확인하지 못한 것 · 값의 출처\"를 보여 주고, 사용자가 **도면과 대조한 묶음에 체크**한 뒤 이름을 넣어 **한 번에 확정**. 불일치 묶음은 확정 불가, 사유는 앱이 자동 기록 |\n| 일치 묶음 일괄 확정 | 교각 화면의 버튼 |") rep("### 5.4 확정\n\n확정은 **\"내가 이 값을 도면과 대조했다\"는 사람의 기록**입니다. 앱은 확정하지 않고, 확정에 쓸 근거를 모아 줍니다.\n", "### 5.4 확정\n\n확정은 **\"내가 이 값을 도면과 대조했다\"는 사람의 기록**입니다. 앱은 확정하지 않고, 확정에 쓸 근거를 모아 줍니다.\n\n" "**권장: 검토 요약으로 확정 (2026-10-20)** — 교각 화면 2절의 [검토 요약으로 확정]을 누르면 확정이 필요한 묶음이 한 화면에 모입니다.\n" "1. **불일치**(빨간 구역): 확정할 수 없습니다. 값을 고치거나 원인을 해결한 뒤 다시 확인하세요.\n" "2. **주의·근거 없음**: 묶음마다 \"바뀐 것\"(교각을 만들 때 대비 몇 개 값이 어떻게 바뀌었는지), \"앱이 확인하지 못한 것\", \"값의 출처\"(도면에서 읽기·표 밖 치수 후보 반영 이력)가 나옵니다. **도면과 직접 대조한 묶음에만 체크**하세요. 체크하지 않은 묶음은 미확정으로 남습니다.\n" "3. **사람 결정 기록**(예: 계획된 FAIL 목록): 내용을 읽고 체크합니다. 설계자 확인 전 임시 등록은 사유에 그렇게 적혀 있는지 보세요.\n" "4. **앱 확인 일치**: 근거를 훑어보고 맨 아래 \"일치 ○개의 근거를 읽었습니다\"에 한 번 체크합니다.\n" "5. 목록을 **끝까지 내리면** 확정자 이름과 공통 의견(선택)을 넣을 수 있고, [선택한 묶음 확정]을 누르면 체크한 묶음이 한 번에 확정됩니다.\n" "- **사유는 앱이 자동으로 기록합니다**: \"[검토 요약 일괄 확정] 사용자가 도면과 대조했다고 표시함. 앱 확인 근거 없음 — … | 변경: … | 출처: … | 의견: …\". 확정 기록에는 그 시점의 앱 확인 상태가 함께 남아 보고서 8.1장에 올라갑니다.\n" "- 목록이 바뀌었으면(값을 고침) \"끝까지 읽은 뒤에 확정할 수 있습니다\"가 나오므로 화면을 다시 여세요.\n" "- 체크는 사용자의 선언입니다. 앱은 실제로 대조했는지 확인할 수 없으므로, 체크한 묶음은 도면과 직접 대조한 것이어야 합니다.\n\n" "아래는 같은 확정을 다른 방법으로 하는 경우입니다.\n") rep("| `confirm_view.json` | 일치 묶음 일괄 확정에서 근거표를 끝까지 읽었다는 표식 |", "| `confirm_view.json`, `review_view.json` | 일치 묶음 일괄 확정, 검토 요약 확정에서 목록을 끝까지 읽었다는 표식(그때 목록의 해시) |") rep("| \"C3b … 생성 시점 값 그대로\" 주의 |", "| 검토 요약에서 \"끝까지 읽은 뒤에 확정할 수 있습니다\" | 목록을 끝까지 내리지 않았거나 읽은 뒤 값이 바뀌어 목록이 달라짐 | 화면을 다시 열어 끝까지 내림 |\n| 검토 요약에서 \"확정한 묶음이 없습니다\" | 체크한 묶음이 없음(일치 묶음은 맨 아래 \"읽었습니다\" 체크) | 도면과 대조한 묶음에 체크 |\n| \"C3b … 생성 시점 값 그대로\" 주의 |") rep("- **C9의 한계**:", "- **검토 요약 확정의 한계**: 체크는 사용자의 선언이라 앱이 실제 대조 여부를 확인하지 못합니다. 사유는 앱이 아는 사실로 자동 작성되지만 도면과 무엇을 어떻게 대조했는지는 공통 의견에 직접 적어야 남습니다.\n- **C9의 한계**:") DST.write_text(s, encoding="utf-8") shutil.copy2(SRC, DOC / "backup" / SRC.name) SRC.unlink() # ---- planning document + OPEN PO = R / "DOC" / "01_기획" / "기획_입력묶음확인확정개편_2026-10-20_v0.1.10.md" PN = R / "DOC" / "01_기획" / "기획_입력묶음확인확정개편_2026-10-20_v0.1.11.md" shutil.copy2(PO, R / "DOC" / "01_기획" / "backup" / PO.name) t = PO.read_text(encoding="utf-8") row = "| v0.1.10 | 2026-10-20 |" i = t.index(row) j = t.index("\n", i) t = t[:j + 1] + "| v0.1.11 | 2026-10-20 | 심영표 | 검토 요약 확정(한 화면 검토 + 한 번 확정) 6.9절 추가 | 사용자 \"확정 판정이 오래 걸리고 확인하기 어렵다 → 앱이 일괄 처리, 사용자는 일괄 검토\" 제안 → 권고안 진행 |\n" + t[j + 1:] sec = """### 6.9 검토 요약 확정 (2026-10-20) **문제**: 묶음 20~23개를 하나씩 확정하는 데 시간이 오래 걸리고, 사유가 비거나('12', 'asf') 무엇이 바뀌었는지 보기 어려웠다. 사용자 제안: 앱이 일괄 확정하고 사용자는 일괄 검토만 한다. **결정(권고안)**: "앱이 확정"은 확정의 의미(사람이 도면과 대조했다는 기록)를 없애므로 채택하지 않고, **앱이 검토를 준비하고 사람이 한 화면에서 검토·체크해 한 번에 확정**한다(D1 유지). 근거 없음 묶음은 **항목별 체크**(a)를 요구, 기존 개별 확정 화면은 예외 처리용으로 유지. | 요소 | 구현 | | :--- | :--- | | 화면 | `/pier/<이름>/review` (교각 화면 [검토 요약으로 확정]). 확정이 필요한 묶음을 네 구역으로: 불일치(확정 불가), 주의·근거 없음(항목별 체크), 사람 결정 기록(체크), 일치(근거 훑어보기 + 구역 체크 1회) | | 앱이 준비하는 것 | `engine/review.py`: 바뀐 것(교각 생성 시점 값 기록 `origin_values.json` 대비 변경 값 수와 예), 앱이 확인하지 못한 것(근거 없음·주의 검사 항목), 값의 출처(`read_log.json`·`anchor_log.json` 이력), 사유 자동 작성(`auto_reason`) | | 사람이 하는 것 | 도면과 대조한 묶음에 체크, 목록 끝까지 읽기(표식 `review_view.json` = 그때 목록의 해시), 확정자 이름, 공통 의견(선택) | | 기록 | 묶음별 확정 기록에 사유(앱 확인·변경·출처·의견 포함), 확정 당시 앱 확인 상태, 이름. 앱은 체크가 없으면 아무것도 확정하지 않음 | | 안전장치 | 이름·끝까지 읽기·체크 없으면 거절, 값이 바뀌면 표식 무효, 불일치는 요청에 id 가 들어와도 확정하지 않음 | **시험** `tools/test_review.py`(PASS): 화면 조회만으로는 확정 0, 표식·이름 없으면 거절, 체크 없으면 0, 일치 구역은 구역 체크로만, B·D 는 체크한 것만, 불일치는 거절, 기록에 사유·앱 확인 상태·이름, 값이 바뀌면 표식 무효, 불일치를 고치면 모든 필수 묶음이 이 화면으로 확정되어 게이트가 열림. 회귀 fast 19/19. **한계**: 체크는 사용자의 선언이라 실제 대조 여부는 앱이 확인할 수 없다. 사유의 "무엇을 어떻게 대조했는지"는 공통 의견에 적어야 남는다. 앞으로 앱 확인 'C10 도구 읽기 이력'을 근거(출처, 독립 검증 아님)로 연결하면 근거 없음 항목이 줄 수 있다(미구현). --- """ k = t.index("## 7. 리스크·결정 사항") t = t[:k] + sec + t[k:] PN.write_text(t, encoding="utf-8") PO.unlink() OPEN = R / "context-migration" / "OPEN_미해결목록.md" shutil.copy2(OPEN, R / "context-migration" / "backup" / "OPEN_미해결목록_2026-10-20_검토요약전.md") o = OPEN.read_text(encoding="utf-8") row36 = ("| 36 | 입력 묶음 확정에 시간이 오래 걸리고 확인이 어려움(사유 '12'·'asf') — **[해소 2026-10-20]** 「검토 요약 확정」 구현: 앱이 바뀐 것·확인하지 못한 것·값의 출처를 한 화면에 모으고 사람이 도면과 대조한 묶음에 체크해 한 번에 확정, 사유는 앱이 자동 기록(`engine/review.py`, `/pier/<이름>/review`, `tools/test_review.py`). " "'앱이 확정' 방식은 확정의 의미를 없애므로 채택하지 않음. **남은 것**: 체크는 사용자의 선언이라 실제 대조 여부를 앱이 확인하지 못함, 'C10 도구 읽기 이력'(출처 근거) 연결 미구현, 기존 묶음별 개별 확정 화면은 예외용으로 유지 | 2026-10-20 | 2026-10-20 | 해소 | " "[ref: DOC/01_기획/기획_입력묶음확인확정개편_2026-10-20_v0.1.11.md §6.9] |") o = o.rstrip("\n") + "\n" + row36 + "\n" OPEN.write_text(o, encoding="utf-8") print("ok", DST.name, PN.name)