pfs 아카이브 — OMC · 패치 누적
✅ 26.10.26 · pfs-handoff-cap-1026b · handoff 캡 이관 (홈파베르 외곽 스티커 · SLS 로고 경위 원문)
- ✅[코디] 26.10.23(금) SLS(company 465) 스티커 로고 =
C:\dev\pfs\web\static\img\company_logo\465.png(SURFACE LAB SEOUL, 여백만 크롭 1127×223) · master 로컬593af23c(push 안 함 — 다른 세션 미push 5건 동반 방지) → 운영 deploy-live3192e04f(Actions success · 운영 파일 md5 일치) · 샘플(노이키친 성북동, field 2217) 사무실 GT800 인쇄 17:23 KST(이벤트 307) · [페페] 실물 확인 완료(「잘 나왔다」). - ✅[코디] 26.10.26(월) [페페] 「홈파베르 도어발주서 2페이지 목대 → 엣지바 +6 외곽 규격 스티커, 동일 4개는 각각」 → 운영 스티커 화면(field 2215 · file 288 · 2페이지) 양식 그대로 품목 줄만 외곽치수로: 2-1 도어 목대 4872040 (1/4~4/4) · 2-2 4871885 · 2-3 네모 프레임 57*150 = 6장 → 사무실 GT800 원격 인쇄 17:18 KST(이벤트 307 · 6쪽). 도구 =
C:\dev\_work\sls-homfaber-1026\render.py·print_gt800.ps1· 인쇄기록(print-log) 미기록 · 헤더 타입은 발주서 그대로 「목대」. - (경위) 26.10.26(월) [페페] 「v3 6번(서피스랩 서울 / curated surfaces)으로 교체 · 생산팀 엑셀 출력도」 → 보드 셀 크롭·4배 업스케일 로고
C:\dev\_work\sls-logo-kr\sls_logo_v3_06.png(1000×344) · 운영 화면에 브라우저 route 바꿔치기로 캡처(cap_compare.png·cap_after_pallet.png) 발송 · 페페 «같은지» 확인 대기. 확인 후 할 일 = ①pfs\web\static\img\company_logo\465.png교체 → 운영배포 ②엑셀(\\192.168.0.101\공유폴더\스티커 출력1.xlsm)은 VBAInsert_logo가 운영 RDScompany.logo_address(file:// 경로)를 읽는다 — SLS(465)는 빈 값이라 지금 엑셀은 「SLS」 글자만 찍힘 →\\192.168.0.41\ProgramData\imos AG\Library\DB\logo_image\에 jpg 넣고 465 행 logo_address UPDATE(운영 DB 1행 = 승인 필요).
✅ 26.10.26 · pfs-handoff-cap-1026 · handoff 캡 이관 (26.10.25 미배포분 묶음 운영배포 원문)
- ✅[코디] 26.10.25(일) 미배포분 묶음별 운영배포([페페] 채팅 「운영배포 승인」) — deploy-live 커밋 1개 = 묶음 1개(개별
git revert대상): 5077196a7(patch63 인덱스 = 운영 이미 적용, SQL 기록만) · 39c7740a4(auto-register 정리 API·패널) · 6a8bb8f1b(pncad 보완 1·2차) · 2ce3befb9(작업건 더블클릭) · 435a127b4(AI 연출 + 운영 DDL patch64_pncad_stage 4테이블 · env 꺼짐enabled:false). 1번(부재 선택 P1·P2)은 안 실음. master = 7(카톡 완료후보) revert577e12cd+줄끝0b34466d· 8(공용 리팩토링) revertdead6724(보관 브랜치parked/refactor-0730) · 초대가입 3커밋5683ebc7·b2732d14·132a4ccc. 사이트맵 미반영 0.
✅ 26.10.23 · pfs-handoff-cap-1023 · handoff 캡 이관 (20,063자 > 20,000 — 26.10.22 대전 도마 수입분 네스팅 원문)
- [코디] 🆕 26.10.22(목) ✅ 대전 도마 수입분 네스팅·엣지 산출(PFS 쓰기 0) — spec.json(포인탭 31행 · MH 타입당 1세대) →
C:\dev\order-automation\daejeon-doma-suip_2026-10-21\nest.py(PFSorderpaper-sync/nesting.py팔레트 동일 엔진) · 보드 1220×2440 = HS2329LS 18T 3장(수율 84%)·9T 1장·PVC 15T 1장·이지웨이HNF-01 15T 1장·합판 18T 1장 · 엣지 HS2329LS 102.4m(18T 58.5+9T 43.9, 22mm 통합)→200m · PVC 5.4→100 · HNF-01 3.6→100 · 월드 휠라 5개 별도 · 🆕[페페] 「도면 = 15T 자재만」 → HS2329LS 18T 30부재 → 15T 3장(수율 84% · 천지판·안정기함 측판 15T 두께보정해도 동일) · 9T 1장 유지 · 엣지 15T 58.5+9T 43.9 = 200m 그대로 · 🆕같은 날 [페페] 「포인 탭 서식 붙여넣기 안 됨 + 빈 행 = 기본 행 양식」 → 포인 빈 행 694행에 30쪽(깨끗한 쪽) 같은 위치 행 서식 붙여넣기(국산 원본 굵은 묶음선 잔재 제거 · 값·병합 차이 0 · 월드 = 잔재 0이라 무변경) · NAS 교체(구본이전버전\…_261022_1000이전.xlsm) · 붙여넣기 불가 원인 = 미확정(보호·공유·이벤트매크로 없음 · 조건부서식·도형 원본과 동일 · COM 서식붙여넣기 OK · 사무실 엑셀 16.0.5574.1004) · 도구fix1022.py·run_fix.py·nas_replace.py· ❌[페페] 「여전히 포인탭만 안 됨 → 새 탭」 → 새 「포인」 시트 재작성(옛 = 「포인_구」 숨김 · 값·서식·병합 0차이 · 버튼 9·라벨 3 · 인쇄 A4 79% 1쪽폭 · AutoFilter 제외) + 페페 10:29 편집(9T 쫄대 포인→월드 도장) 재반영 → NAS 교체(백업이전버전\…_1029이전·…_1042이전) · 사무실 엑셀 10.15 KB5002934 의심(rules 🆕 26.10.22) · 네스팅 갱신 = 9T HS2329LS 1장 빠짐(월드 도장) · HS2329LS 엣지 58.5m→150m · ⏳[페페] 새 탭 붙여넣기 재시험 · 여유·소재(PB/MDF)·걸레받이/PVC 잔재 대체 여부
✅ 26.10.22 · pfs-handoff-cap-1022 · handoff 캡 이관 (26.10.20~21 완료 2절)
[코디] 🆕 26.10.21(수) ✅ 운영 데이터 — [페페] 「생산현황 자재입고 모두 입고 완료 · 상원보드 어제 추가한 자재만 날짜 올려줘」 → 생산현황 미입고 보드 33행 중 30행 status «완료»(PATCH /api/orderpaper/<no>/status · GS 대전 도마*변동 5행 대기→완료 #8785·8793~8796 · 소요 한남2차 25행 진행→완료 #8769~8777·9839~9851·10223·10427·10429) · 유지 = 상원보드 2차(#9 아일랜드 누락분) #10444~10446 N239(SC) 18T PB 4·15T PB 4·6T MDF 2 → 미입고 보드에 10-26-2026 1줄만 남음(/api/orderpaper/board-wait 확인) · 코드 변경·배포 0 · 도구 C:\dev\_work\recv-1021\{q.py,apply.py} · ⏳[페페] 「날짜 올려」가 10.26 이 아닌 다른 날짜면 지정
[코디] 🆕 26.10.20(화) ✅ 네스팅 여유자재 패턴 분석(몸통/도어 · 운영 37건 읽기만) — 구간 정액·도어 18T 몰기·장척 몰기 · 상세 session-2026-10-20-nesting-spare-pattern.md · 다음 = [페페] 원하면 기본여유 자동제안 규칙화
✅ 26.10.20 · pfs-handoff-cap-1020c · handoff 캡 이관 (26.10.16~19 완료 5절)
[코디] 26.10.19(월) ✅ NAS 12:07 KST — 소요 한남 2차 #803 한샘 양식 V9(유리 sub 분리 칸 · 보이는 규격 DWG 실측 · 갑지 주방/수납 위치도) → \\192.168.0.101\공유폴더\2026현장\견적\10월\한샘\소요 한남 2차\한샘 소요 한남 2차 MH 가구제작 견적서(26.10.13) V9.xlsx(sha256 3955aa8e…) · 69,180,000(PFS 69,197,000 −17,000 만원 절사) · ⏳페페 규격 판단 4행·점 위치 → session-2026-10-19-hannam2-hansem-v9.md · ✅V10 12:56 = 37475 욕실서랍 길이 칸 2590·금액 수동 입력(rules.manual_amount · 총액 불변 · sha256 667051e8…) · ✅V11 13:51 = 위치도 갑지 → 99A 내역서-주·-수 탭 총합 다음 쪽(셀 diff 0 · sha256 5fec4f49…)
[코디] 🆕 26.10.19(월) ✅ 운영 11:39 KST — 소요 한남 2차 아일랜드 벤치 몸통 발주 누락분 = PNCAD 작업본 #61(장 5 · 21행 70매 · N239(SC) · 261015 도면) + 아일랜드 전용 네스팅 #34(원장 7 = 18T 3·15T 3·4.5T 1 · 엣지 0.6T×22 116m→120M · 피스마개 960) — 원인 = 발주서 #7 출처 #31(PNCAD 53·54)에 #27 수동 행(아일랜드 66) 미포함 · #7·#31·#53·#54 무변경 · NAS …\한샘 소요 한남 2차\코디 아일랜드 몸통 26.10.19\ · 작업폴더 C:\dev\_work\sohan2-island-body-1019\ · 🆕#31 추가 누락 판정 = 주방 EXEDRA2 측판 704×2590×2·천판 704×2030·K05 밴드 1 · 신발장 D 코너기둥 2·D2L 밴드 1 · 15T 폭60 보강밴드목 #31 전무(나머지 10매) · 세탁실 5 = SE-021L 문틀재로 대체 · [페페] 26.10.19 ①=dev-e5 통합 엑셀에 「아일랜드 누락분(네스팅 #34)」 별도 행(보드만 · 엣지·피스마개 제외) ✅11:57 KST \\192.168.0.101\공유폴더\2026현장\원부자재발주서\10월\통합발주(동기화제외)\한샘 소요 한남 2차 원부자재발주서(통합).xlsx 상원보드 탭 20~22행(칼라 표기 「N239(가죽)」 · 탭 주황) ②=폐기 «마감재·무늬목 등으로 다 정리된 사항 · 필요없음»(기록만 보관) · ⏳가정 5건(벤치 세로판 354×398.5 · 뒷판 보조목 1310.4 · 벤치 서랍폭 604.4 · 서랍바닥 15T · 밴드 개수)
[코디] 🆕 26.10.19(월) ✅ 운영 11:40 KST — 소요 한남 2차 라고데코 원단 별도 부자재 발주서 = PFS #11(확정 · 청솔산업 · 입고 26.10.22 · COD_01 2yd+Harvard-09 4yd · 폭1220) + #8 에서 그 2행 제거(120→118) · 🆕추가 12:00 KST 청솔산업 가공 발주서 = PFS #12(draft · 입고처 포인·입고일 26.10.29 추천값 · 쿠션 시트1350×440×30T+등받이1310×467×30T 1세트 · 서랍바닥 레자 9개) + #11 COD_01 비고 두께 30 으로(수량 불변) · ⏳[페페] #8 이지웨이 No.83 벤치 쿠션(제작)과 청솔 쿠션 중복 정리 · 🆕추가 오후 PFS 동기화(26.10.19) ✅ #11 입고일 10.21·비고 확정치수(수량 페페 UI 수정 4야드/4야드 유지) · #8 No.83 벤치 쿠션 행 제거(118→117) · #12 draft 10.28 불변(삭제 여부 ⏳[페페]) · 상세 = session-2026-10-19-lagodeco-fabric-order.md · ⏳[페페] 출력·발송
- ✅ 26.10.19 GY01DMT 2차 발주 PFS #8 확정 → archive.md 「pfs-handoff-cap-1019」
[코디] 🆕 26.10.19(월) ✅ 운영 10:19 KST — PFS-MAT#1(GS 안산 성포+원주 단구) H2041B-L1 피앤데코 직접발주분 자재관리 복원 + 이선영 사원 카톡 보고
- 18T PB 16매·4.5T MDF 8매·엣지 400M 피앤데코 수동 행 추가(자재관리 10115~10117) + 옛 자동 행 remove + 피스마개 업체 정정 · 원인 = 자재관리 수동삭제(del_manual) · ⏳엣지 입고 여부 · 원문 = archive.md 「✅ 26.10.19 · pfs-mat1-h2041b-pndeco」
[코디] 🆕 26.10.16(금) ✅ 운영 17:27 KST — 소요 한남 2차 #803 견적 = 261015 엄지발송 최종 도면 사이즈 반영 (⏳질문 5)
- [페페] 「
261015엄지발송_소요한남_KIT,FUR_MH_99A_최종.dwg기준 견적 최신화 · 주로 가구 사이즈 · 부가비 2건·페페 수동 sub 유지 · 운영배포」 · 비교 기준 = 견적 치수 출처 261008 r3 도면(C:\dev\_work\hannam2-1012\diff\new_*) · 새 도면 시트 = 구 +26,070.7mm x 이동(짝 37) · NAS 원본 열림 중(.dwl) →share_access="rwd"사본C:\dev\_work\sohan2-dwg1015-est\in\ - 변경 판정: 사이즈 변경 = 신발장 C «261013 (W)» 400+800+800→384+766+800 · D 712+712→706+706 · 버틀러 «(W)» 1065→1015 · 세탁장 B «(D)» 270→265 · 세탁실 도어 문틀 D 135→115·FIX 595→650 · 드레스룸 C «장규격 수정» 1740→1780 · 아일랜드 서랍 209655→208650 / 변경 없음 = 주방 5행(손잡이·SMPS·속서랍·이마목 «ㄷ자 제작» 주기만) · 스타일러 상부장 · 워시타워 · 드레스룸 A / 구성 변경(미적용) = 거실 수납장(«261015 디자인 확정» 445폭+와인셀러+EP 875) · 아일랜드 상단 진열칸 → 나무 서랍
- 운영 쓰기 =
PUT /api/estimate/8031회(C:\dev\_work\sohan2-dwg1015-est\apply15.py· 직전 GET == before.json 확인 · 16행 전부 subList · sub_no·순서·마진 35·수량·단가 그대로) → 0000 → 재GET 대조 ALL MATCH(diff 66칸 = 계획뿐) · 위치행 6(치수·규격 표시·자당·몸통식 합계) · sub 19줄 규격 + 비고 꼬리 「261015도면 반영(구 …)」 · 행 비고 2(도어 치수 숫자) · 총액 66,317,000 → 66,276,000(−41,000)(C −28,000 · D −7,000 · 버틀러 −31,000 · 드레스룸 C +25,000) · 불변 확인 = 부가비 2건(무늬목 자재비 14,600,000 · 주방 전동포켓도어 17,000,000) · 페페 수동 sub 5줄(8371 포켓도어 가공 · 8387 유리 · 8388 가죽매트 · 8389 쿠션 가죽 · 8390 쿠션 제작) · 연동 표식 91 · 시공 7,500,000 · 운반 500,000 · 화면(screen_check.py쓰기 0) 총합계 66,276,000 · 연동 90/90 · 추가금액 마진 수동 35 · 오류 0 · PASS - 🔴17:05~17:26 KST 사이 누군가 #803 을 화면 저장(값 동일 · 부가비 extra_no 118·119→120·121 · 수동 sub 8383~8386→8387~8390 재발번) → 그 탭이 열린 채 다시 저장하면 이번 반영이 덮인다 → 새로고침 후 편집
- 스냅샷
C:\dev\_work\sohan2-dwg1015-est\before.json(17:26 · 첫 스냅샷before_1705.json) ·after.json· 전후표전후표_803_261015도면.csv·plan.json· 비교 그림diff\png\· 원복 =python C:/dev/_work/sohan2-dwg1015-est/restore15.py PUT(지금 값 == after.json 일 때만 before 값으로 PUT 1회) - ⏳[페페] ①거실 수납장 재설계(700410 → 몸통 345 · 하부 D610 와인셀러 · 도어 2→1 · 오픈 선반 30T · EP 875 «900 생산» 신규) 행·sub 재구성 여부 ②아일랜드 상단 진열칸 → 나무 서랍앞판 1304208 추가 · 진열칸 바닥판·내측 E.P 3장(243,000) 삭제 여부 ③버틀러 오른쪽 세로휠라 «W200 생산» → 602690 2장 중 1장 2002690(+81,000) ④세탁실 FIX «700생산» 1장(금액 0) ⑤드레스룸 A·C «천/지판,걸레받이 : 무늬목» → «천/지판 : 무늬목»(걸레받이 2줄 54,000 유지?) · 참고 = 전 시트 INEK10 → «INEK10_ver.2» · 세탁실 문틀 PET 공급처 → 선재기업 · 네스팅 #27·#28·자재발주는 이번에 안 고침 · 한샘 변환 = 질문 답 뒤
hc.py fetch --refresh(V9) - [코디] ✅ 2차 견적 운영 26.10.16 17:55 KST — [페페] 결정 1·2·3·5 반영 =
C:\dev\_work\sohan2-dwg1015-est\apply2.pyPUT 1회(직전 GET == after.json) + 연동 표식 bulk-save · 거실 37455 700410→3456102660(F006 재확인 정면 50|345|50 · 선반 30T · 도어 1짝 · 측면EP 9002690 신규 8391 · 천판 7차 60,000→40,000) 1,797,000→1,760,000 · 버틀러 8293 602690 2→1 + 2002690 신규 8392(80,000) +81,000 · 드레스룸 A 8303·C 8305 걸레받이 삭제 각 −27,000 · 아일랜드 8341·8312 삭제 + 서랍앞판 1304208 신규 8393(7차 규칙 20,000 = 타현장 픽스 1741200 근거 — ⚠같은 행 서랍앞판 208650 40,000 보다 낮음, 페페 확인 권장) −216,000 · 총액 66,276,000 → 66,050,000(−226,000)* · sub 90→89 · 재GET 대조 ALL MATCH(diff = 계획뿐 · 부가비 2 · 수동 sub 5 값 동일(8388~8390 순서번호만 −1) · 시공·운반·마진 칸 그대로) · 연동 표식 93행('1' 89 = sub 수 · 빈 자리 d14s4·d15s5·d16s14 = '0') · 화면 읽기(screen_check2.py쓰기 0) 66,050,000 · 연동 89/89 · PASS · 결정 4(워시타워 37461) = 행 금액 폭 760 기준이라 깊이 무관 → 견적 안 고침 · 전후표전후표2_803.csv·plan2.json·after2.json· diffdiff_after_after2.txt· 원복 =python C:/dev/_work/sohan2-dwg1015-est/restore2.py PUT(지금 == after2 일 때만) - [코디] ✅ 3차 26.10.16 18:12 KST — ①네스팅 #28 rows POST 1회(
nest\plan28.py --post· 직전 재GET == nest_before 전체 동일) 54 op(upd 46 · exc 6 · add 2 = rid 157 거실 EP 900×2690 · 158 아일랜드 서랍앞판 208×1304) · max_rev 292→346 · 155→157행 · 재GET 대조nest\cmp28.py→nest\after28.json바뀐 행 52 + 새 2 = 계획뿐 · rid 106·108 불변 · #27 불변 · stale='1' → ⏳웹 #28 [네스팅 실행 ▶]→저장 = 사람 조작 ②표기 DWG NAS\\192.168.0.101\공유폴더\2026현장\진행중\10월\한샘 소요 한남 2차\코디 소요량 26.10.16\261015엄지발송_소요한남_KIT,FUR_MH_99A_최종_코디변경표기_261016.dwg(AC1027 · 86,081,476 B · sha256 aa90a937…89ba 되읽기 일치) · 레이어 CODY_261015변경 1개 135엔티티(시트 테두리 10 · 메모 36줄 · 바뀐 치수 네모 87 · 글 네모 2) · 왕복 sigs 원본 13682 불변 ·annot\build.py·render.py·nas_put.py③DXF 3개 삭제 1,150,296,355 B(원 DXF 385,468,284 + 표기 중간 2) 목록annot\deleted_dxf.txt· ⏳#27 몸통(rid 빈칸이라 rows POST 불가 · HANDOFF_3rd B) · rid 106·108 페페 답 - [코디] ✅ 견적 3차 26.10.16 18:16 KST — [페페] 「전부 추천 진행」 sub 8393 아일랜드 서랍앞판 1304208 단가 20,000→40,000(근거 = 같은 행 8344 208650 40,000 · 비고 그대로) =
C:\dev\_work\sohan2-dwg1015-est\apply3.pyPUT 1회(직전 GET == after2.json) · 행 37465 2,489,000→2,516,000 · 총액 66,050,000 → 66,077,000 · 재GET diff 5칸뿐(diff_after2_after3.txt) · 부가비 2·수동 sub 5·시공·운반·연동 89/89·_mode 0/3500 불변 · 화면 읽기screen_check3.pyPASS · 원복restore3.py PUT· 한샘 V9 = [페페] 「아직 만들지 마」로 중단 — 로컬 run 만 됨(ALL OK 392 ·C:\dev\_work\sohan2-hansem-261014\한샘 소요 한남 2차 MH 가구제작 견적서(26.10.13).xlsx덮어씀 · V8 로컬 사본v8_copy.xlsx) · NAS 0 · 설명서 안 고침
✅ 26.10.20 · pfs-handoff-cap-1020 · pfs handoff 캡 이관 (22,566자 > 20,000 — 26.10.20 네스팅 사용컬러 소재·폴딩 · 26.10.12~14 완료 5절 원문)
[코디] 🆕 26.10.20(화) ✅ 운영 09:26 KST — 네스팅 「사용 컬러」 패널 = 컬러별 소재 수정(poin_colors 영구 저장) + 사이드 폴딩
- [페페] 「컬러별 lpm·펫·pp 등 소재 수정 · 기존 db 컬러에도 영구저장 · 실작업하면서 고친다 · 비고 폭 부족 → 사용컬러 사이드메뉴 폴딩 · 운영배포」 · master
55da4613→ deploy-lived6e73375 - API
GET/PUT /api/poin/color-types(api/pfs/poin_color/controller/poin_color_controller.pyset_color_type) — PUT = 그 이름 poin_colors 행 전부 UPDATE(없으면 그 소재로 INSERT) · 소재 = poin_color_types 9종(PP·LPM·PET·PVC·데코시트·페이퍼·포일·도장·무늬목) · 같은 이름 다중행(5건)은 GET 에서 최근 행 값 - 화면 = 패널 소재 칸(자체 드롭리스트
data-drop="ctype"· 목록 밖 값 되돌림) · 패널 300→310px(340 은 1280 에서 아래로 떨어짐 실측) · ▶ 접기 = 36px 세로 띠, localStoragenest.cpFold기억 · 협력사 화면 = colorTypes null → 소재 칸 숨김(build.py 재빌드 포함) - 검증 = 로컬
scripts/_nesting_colorpanel_check.py54/54 · 운영--prod59/59(쓰기 0) ·tests_cody/test_color_types.py+register 5 passed(.venv) · 운영 실기 PUTGY123 E37→PET(원래 값 그대로 · updated_at 만 갱신)
[코디] 🆕 26.10.14(수) — GS 대전 도마변동 원부자재발주서 «발주 진행»(field 2175 · PFS-MAT#5) — ✅PFS 운영 #5 판 25→27(amend: 70-115 피스마개스티커 10 장 수동행 add + PBNB6T 칼라샘플 비고 비움 / lines/remove: 자동행 5600 EA 소프트삭제, 대조 0) · ✅엑셀(NAS …\10월\한샘 GS 대전 도마 변동 원부자재발주서.xlsx) 케데코 G13(10/16) 값 제거 + 오엠씨 13행 «케데코 70-113 PP시트 60M → 오엠씨 입고» 추가(zip XML 치환 · 백업 · NAS 재읽기 md5 · 다른 탭 변경 0) · ✅출력 6건(미니PC → 사무실 복합기 SINDOH D450 PCL, 1×1쪽, 23:30 KST) ⚠오엠씨 13행은 출력 뒤(23:40) 추가돼 오엠씨 종이는 옛 판 · ⏳카톡 일괄 발송 = 예약 \Cody\Orderpaper-Daejeon-1014-0700(winledger W191 · 06:50 기동 → 07:00 정각 · job C:\dev\_work\daejeon-order-send-1014\kakao\job_1014.json · 방: 피앤알 남태욱 상무 / 피앤데코 서민경 주임 / 선재 박남선 대표 / 조운 IMT 여직원 / 케데코 휴대폰 / 포인-오엠씨, 입고처·입고일 언급 없음) 결과 확인 대기*(run.log C:\dev\poin-agent\data\orderpaper\run.log + 텔레그램 → 예약작업 삭제·release). ⏳[페페] 출력 6장 육안(스풀로 확인 불가)·오엠씨 재출력 여부. 절차 전체 = 스킬 C:\Users\delix\.claude\skills\orderpaper-dispatch\SKILL.md(26.10.14 신설) · 스크립트 = C:\dev\_work\daejeon-order-send-1014\.
- ✅ 26.10.13 목록 로딩 성능(deploy-live 8bbdc3b4 · patch63 커밋 b7767098 로컬 master 만 · push 안 함) · ✅ 자재 발주서 품명 이력(42ea2ea1) → 원문 archive.md 「✅ 26.10.14 · pfs-handoff-cap-1014」
[코디] 🆕 26.10.13(화) — GS 안산 성포 MH 도어발주서 도면 대조 → ✅[페페] 「추천대로 진행」 NAS 원본 「포인」 반영(9행 수정 + OT84 하부코너ep 1행 추가 · 비고 U 열 21 · parse 355→356 · sha1 4da7bb98… · 백업 「…발주서_백업_20261013.xlsm」) · ⏳[페페] 주황 11 은 값 그대로 «확인요» (원문: session-2026-10-13-ansan-seongpo-door-review.md 「반영(26.10.13)」)
[코디] 🆕 26.10.13(화) — 소요한남 nesting 행 동기 v2 — ✅운영 반영 23:46 KST(master a24f100b → deploy-live 0eb85afa) · rows GET/POST · rev/mt/exc/by · 마지막 서버 반영 우선 · 웹 칸 단위 병합 · 연동 job 삭제=제외 · 제외 행(exc='1') 발주 계산 제외(calc._parts·mat_view·calc_adapter) · 「재계산 필요」 띠·recalc=1 · API 실행기 B1(20261012-230757-381277 약 $22)+B2(20261012-232205-ed38cf 약 $7.8) · 반박검증 차단1·권장3 반영 · 테스트 서버 27항목 · 운영 실측 쓰기 0 · 사이트맵 반영 · pytest 101 · A1 정수화 운영 #28 upd 40/40 · ⏳[페페] #28 웹 재계산·저장 · 상세 = projects/acad-tread/handoff.md 맨 위
✅ 26.10.12(월) GS 대전 변동 몸통 발주서 초안(NAS 새 파일) · 몸통 네스팅 #20 타입·위치 빈칸 87행→0(운영 deploy-live 3f885650) · 발주서정리 업체 카드 배지 「G」·AL·유리 항목 복원(운영 7ed55ede·100353b7) — ⏳[페페] 몸통 발주서 8건(위치·업체 배정·케데코 품명·피스마개 단위·엣지 올림·4.5T 예비 칼라·B28 타입·미확정분 추가발주) · 주방84A 위치=벽 단위/파우더장 표기 · PNCAD a4d5c1b push(타 미푸시 3커밋 섞임) · #20 저장 요약 45 vs 계산 47 · 유리 업체 미입력 AL발주서 2건(#7495·#3282) 업체 입력 (원문: archive.md 「✅ 26.10.15 · pfs-handoff-cap-1015 · pfs handoff 캡 이관」)
✅ 26.10.12(월) r3 — 한샘 소요 한남 2차(field 2184 · 99A) 261008 새 도면 반영(운영 POST 몸통 #27·도어 #28 · 표기 DWG NAS 「코디 소요량 26.10.12」) + r2(26.10.11~12 구도면 #25·#24) — ⏳[페페] 「키큰장,하부장 전체 제외 발주완료」 뜻(추천=소요량 유지) · 세탁실 새 LPM 코드(5매 보류) · 가전 10/12 확정본 · 보강밴드목 가정 · 폐기 대상 정리 · #23 삭제 여부 · 문짝 높이 6곳 · 결 방향 · 포켓 프레임EP 2 소속 · 도구 개선 3 · 상세 = projects/pfs/session-2026-10-12-hannam2-takeoff-r3.md · session-2026-10-11-hannam2-takeoff.md (원문: archive.md 「✅ 26.10.15 · pfs-handoff-cap-1015 · pfs handoff 캡 이관」)
- [진행중·미결] 26.10.10 dwg-takeoff 자재소요량 파이프라인 공용 CLI(
C:\dev\tools\dwg-takeoff\· devplandwg-takeoff.html) · 다음 = P5 도어 부재 추출기·P4 Jev → archive.md 「✅ 26.10.13 · pfs-handoff-cap-1013b」
✅ 26.10.19 · pfs-handoff-cap-1019 · pfs handoff 캡 이관 (20,977자 > 20,000 — 26.10.19 GY01DMT 2차 발주 원문)
[코디] 🆕 26.10.19(월) ✅ 운영 11:23 KST — 소요 한남 2차 GY01DMT 2차 발주 = PFS #8(#4 추가 차수 1 · 5줄 · 확정) + NAS 새 엑셀 · #28 stale 라 현재 행 2700 재산정(8장→5장) · 업체 오엠씨/조운IMT/선재기업 추정(페페 확인) · 상세 = session-2026-10-19-hannam2-gy01dmt-order.md
✅ 26.10.16 · pfs-handoff-cap-1016c · pfs handoff 캡 이관 (20,114자 > 20,000 — 26.10.16 #803 한샘 설명서·V8 · 추가금액 86줄 연동 원문)
[코디] 🆕 26.10.16(금) ✅ 소요 한남 2차 #803 한샘 양식 금액 설명서 — [페페] 「견적서 수정 완료 · 변환 전에 한샘 양식에 PFS 견적가 적용 설명서 HTML + 양식 위 PIL 수식 표시」 · devplan C:\dev\devplan\sohan2-hansem-formula-guide.html(주석 PNG 7장 assets\sohan2-hansem\ · 번호 ①~⑯ · 블록 배정표 · fold 예 3) · 허브 카드·pagelinks OK 146/NG 0 · 로컬 hc run ALL OK 353(NAS·PFS 쓰기 0) · fetch 총액 65,075,000(수정 전 65,823,700 → −748,700 = 페페 수정분 추정) · 갑지 생산비+시공비 65,070,000(만원 절사 −5,000) · 생성 스크립트 C:\dev\_work\sohan2-hansem-261014\guide_annot.py·build_guide.py · ⏳[페페] 설명서 확인 후 변환·NAS 저장 지시 · 발행일 10.13→10.16 갱신 여부 · 자재비 31,600,000 한 줄 표기
- ✅[코디] 26.10.16 17:0x KST 수정지시 반영 NAS V8
\\192.168.0.101\공유폴더\2026현장\견적\10월\한샘\소요 한남 2차\한샘 소요 한남 2차 MH 가구제작 견적서(26.10.13) V8.xlsx(sha256 d6c2dfaa… 되읽기 일치) — [페페] 「전부 추천 진행」 · 도구 옵션rules.unit_price(direct · 무광,H/G 도장 · A · PET=라미네이트)·cover_extras(품명별)·conceal_words신설(hclib\unitprice.py신규) · run ALL OK 392 · 골든·regress 4건 바이트 동일 · 갑지 65,070,000 불변 · 「월드」 0건 · 「도장」 = 양식 원본 단가표 라벨만 · ⏳[페페] PFS 규격 「EXDRA2」 오타 여부 · 파일명 날짜(26.10.13) 유지 여부 - (원 지시) 🆕[페페] 26.10.16 수정지시: ①숨김 「백데이터」 LOOKUP 단가 금지 → 「단가기준」 탭 표 값 직접 수식(10MM 기준
=J6/10*2.9673처럼 상수 수식 통일) ②무늬목 자재비·EXEDRA2 하드웨어 = 갑지 기타 블록에 품명별 각각(자재비 합산 금지) ③위치행 추가금액 별도 표기 안 함(fold 유지 — 월드산업 무늬목 도장 비용 비노출 목적) · [코디] 미결 = 재질행(PUR 현행 vs 무광도장 「무늬목도장동일」 추천 vs 수입경면·무늬목 50%) · 기타 3칸 재배치(절사칸 재사용 추천) · 도구 = builder 옵션 신설 L3(골든 바이트 동일 유지)
[코디] 26.10.16(금) ✅ 운영 15:2x KST — 소요 한남 2차 #803 추가금액 86줄 전부 연동 — [페페] 검증보고 「추가금액 마진 모두 현재 설정전역값과 연동 · 견적서 전체 추가금액 항목 · 운영배포」 · 코드 변경·배포 0(26.10.14 「전부 연동」 버튼 그대로 사용) · 전: 연동 1/86 · 고정 85(전부 35) · 추가금액 마진 칸 = 수동 35(전체마진 15.5) → 적용 값 35(= 현재 칸 값) → 저장(PUT estimate/803 + extra·material·column-setting bulk-save) → 재오픈 연동 86/86 · 총액 65,823,700 · 추가금액 합계 15,849,000 불변 · 스크립트 C:\dev\_work\est-803-sublink-1016\apply.py(전후 금액 다르면 저장 중단) · 전 스냅샷 probe_803.json · ⏳[페페] 칸 배지를 「연동」(=전체마진 15.5 따라감)으로 바꾸면 86줄 금액이 크게 내려감 — 지금은 수동 35 유지
✅ 26.10.16 · pfs-handoff-cap-1016b · pfs handoff 캡 이관 (22,247자 > 20,000 — 26.10.16 대우 울산 문수로 · 26.10.15 #7 몸통 엣지 · 26.10.15 QA 3건 원문)
[코디] 🆕 26.10.16(금) ✅ 운영 11:00 KST — 대우 울산 문수로 84B 102-502(field 2206 · 아이비젼) PO 사이즈 반영 — [페페] 「PO 참조 사이즈 반영 · 운영배포」+결정(56만 · 깊이 570 · 쿡탑 504+348 분리 · 재단 안 함 · 걸레받이 2440 여유1 · 279 숨김) · PO = 카톡 「아이비젼-포인」 10.15 18:18 C:\dev\_work\daewoo-ulsan-munjuro\대우건설) 울산 문수로 …_250715,21,1114.xlsx · scene 56 몸통 PUT(storeScene(false) · 12→13장 · 몸통 PO 13/13 · 도어 50매 불변) · scene 51 숨김 · nesting job 32 신규(56+걸레받이 152×2440×18T 3 · 원장 11→13 · job 29 그대로) · 자재발주·부자재 10 수정 0(영향=발주량 안쪽) · 코드 배포 없음 · 스냅샷 C:\dev\_work\daewoo-ulsan-munjuro\before_1016\·after_1016\ · ✅후속 11:17 KST([페페] 걸레받이=도어 포함 · 나머지 추천대로): 도어 재단품 G20~22 → G30 152×2440×18T ×3(여유1) 교체 PATCH(50매 유지) · job 32 걸레받이 제거(원장 12) · NAS 새 「…도어규격표 (PO반영 261016).xlsx」 → door_order_file 285(49행) · 279·280 .xlsx.old → remove_yn=1 · 칼라 id 887 등록 · job 29 소프트삭제 · ⚠첫 조사의 «도어에 걸레받이 없음»은 오판(재단품 3매 있었음) · ⏳[페페] L4-2 후라이팬장 지판 380×569 실물확인 · 285 field_no 비어 있음(280 도 동일) 현장 2206 연결 여부
[코디] 26.10.15(목) ✅ 운영 — 소요 한남2차 자재 발주서 #7 몸통 두께별 엣지 누락 수정 — [페페] 「두께별 엣지 안 들어감 · 네스팅엔 있음 · 운영배포」 · 원인 = calc.py 몸통 엣지가 18·15T만 셈 → 전 두께(3·4.5·6T 제외)·컬러×폭 · + _held_orphans 재가져오기가 [복구] 피스마개 SE-021L 지우던 버그 · master 1d53a97c → deploy-live e91089ac(4파일) · test_calc 80/80 · test_mat_orderpaper 271/271 · #7 rev15→16 재가져오기 1회: 새 엣지 4행(N239 9T 70m · N445 30T 30m · 23T 40m · 9T 20m) · 기존 24행 diff 0 · 출처 = 네스팅 #31(PNCAD 53·54) · 네스팅 쪽 정상 · 스냅샷 C:\dev\_work\sohan2-matop7-edge-1015\ · ⏳[페페] 새 4행 업체(추천 선재기업) · 30T·23T 엣지 0.6T 맞는지(1T?)
[코디] 26.10.15(목) ✅ 운영 10:26 KST — pfs 검증보고 QA 3건 — [페페] 「운영배포」 · ① 견적 v2 추가금액 표 table-layout:fixed·품명/규격 무지정(남는 폭 균등 306/306 @1680)·비고 130→170·머리/본문 13px(qe-table 11.5px 덮어쓰기 해소) ② pncad 다중 배치 선택 시 「선택 아티클」·존·서랍·라운드·접합 패널 가림+안내문(selMultiN) ③ pncad 아티클 편집 빈 공간 「서랍 넣기」(레일 언더레일·볼레일·텐덤 · 자체 droplist · 분할·다른 fill 있으면 숨김 · 넣으면 기존 서랍폼) · web-designer 처방 → API 런 L2 20261015-101414-a4eaea · master bec0ccd6·bbdf3cf6(이번 커밋만 push · 로컬 patch63 5aed0c01 미push 유지) → deploy-live 17fd8736·efef93ac(운영 app.html renderZone 충돌 = master 포커스복원 코드 미반영 상태라 selMultiN 1줄만) · 운영 읽기확인 #803 폭·13px·pageerror 0·쓰기 0 · ⏳[페페] pncad 다중선택↔단일 전환·서랍 넣기 직후 3D 갱신 육안
✅ 26.10.15 · pfs-handoff-cap-1015 · pfs handoff 캡 이관 (26.10.12 이전 절 원문 — TREAD R3 · 대전 변동 도어재/몸통 발주서·네스팅 #20·발주서정리 · 소요 한남 r3 · 몰테니·한샘 변환 · 대전 변동 네스팅 준비)
[코디] 🆕 26.10.12(월) — 소요한남 도어 TREAD 확인 연동 R3 — ✅운영 반영 19:21 KST(master c48adc1e → deploy-live 878e2150) · 신규 POST /api/nesting/<job>/rows-ok(PC별 Bearer 토큰 · env PFS_TREAD_TOKENS 해시 · 전체 PUT 시 ok_src=tread 행 ok 보존) · 실측 401/401/401/404/200 · 사이트맵 반영 · env 백업 /home/ubuntu/env/pfs-live.env.bak-tread-20261012 · 웹 #28 에서 tread 행 ok 를 바꿔도 서버가 tread 값 유지(정본=도면). 상세·육안·사무실PC 설치 = projects/acad-tread/handoff.md 맨 위 · devplan sohan-door-mleader-tread.html
[코디] 🆕 26.10.12(월) — GS 대전 변동 도어재(#22 15:02 저장 · 55장) 발주서 통합 — ✅NAS 새 파일 \\192.168.0.101\공유폴더\2026현장\원부자재발주서\10월\통합발주(동기화제외)\(몸통·도어)한샘 GS 대전 도마변동 원부자재발주서.xlsx(md5 f824a848… · 15:55 KST · 몸통 원본 무변경) · 업체 = [페페] 지정(IV075MT 시트 조운IMT/오버레이 오엠씨/엣지 선재기업/샘플 진영LDM · PBNB6T 조운IMT/피앤알/선재기업 · 70-113 케데코/오엠씨 · 70-115 케데코/피앤알 몸통과 같이 · 유사PP(IV075MT) 오엠씨 자체) · 🆕[페페] 입고처 이름·주소 = 양식 하단이 아니라 마지막 품목 바로 아래 행 · 검사 PASS 167 · 산출 C:\dev\_work\gs-daejeon-byeondong\order_door_1012\ · ⏳[페페] 7건(70-115 도어 PP시트 20M 별도행 vs 합산 · 여유 +10 vs 10.6 수동 올림 · 미발주 엣지·샘플·피스마개 · 오엠씨 안내행 · #22 유사PP 경면 자동표기 · 입고일)
[코디] 🆕 26.10.12(월) — GS 대전 변동 몸통 원부자재발주서 초안(네스팅 #20 · 칼라 「미확정」 4행 10매 제외 → 원장 47→45장) — ✅NAS 새 파일 \\192.168.0.101\공유폴더\2026현장\원부자재발주서\10월\통합발주(동기화제외)\(몸통)한샘 GS 대전 도마변동 원부자재발주서.xlsx(md5 a172467e… · 12:31 KST) · 운영 쓰기 0 · 셀검사 71/71 · 탭 = 피앤데코(HS0868GP 18T 25·15T 6·4.5T 예비 1) · 피앤알(70-115 4.5T 13) · 케데코(PP시트 80M·엣지 770M·피스마개 4960EA) · 산출 C:\dev\_work\gs-daejeon-byeondong\order_1012\ · 🔑월 폴더에 두면 동기화 현장매칭이 「대전」 2130(85점)에 붙는다(2175 「도마*변동」 0점 — 파일명에 * 불가) → 하위폴더 · ⏳[페페] 8건(위치·업체 배정·케데코 품명·피스마개 단위·엣지 올림·4.5T 예비 칼라·B28 타입·미확정분 추가발주)
[코디] 🆕 26.10.12(월) — GS 대전 변동 몸통 네스팅 #20 타입·위치 빈칸 87행 → 0(합쳐진 다타입 행 분리 122→161행 · 399매·엔진 47장 불변) + 근본원인 3곳 수정(PNCAD nest_rows 에 타입·위치 없음 · 서버 합산이 타입 무시 · 네스팅 가져오기 미기입) — ✅운영 deploy-live 3f885650(master 3c71152e) · PNCAD a4d5c1b 로컬만(⏳push = 타 미푸시 3커밋 섞임) · 운영 PUT #20 1회 11:24 · 작업본 #41~44 각 1회 11:35 KST · 칼라 869 불변 · 되돌리기 C:\dev\_work\gs-daejeon-byeondong\fix_1012\before\ · ⚠페페 11:03 저장 탭 새로고침 필요(재저장 시 덮임) · ⏳[페페] 주방84A 위치=벽 단위 1개 / 파우더장 표기(몸통 「침실1 드레스룸 파우더장」 vs 도어 「침실1 파우더장」) · 기존 타현장 작업본은 재저장 전 위치 빈칸 · #20 저장 요약 45 vs 계산 47(11:03 편집분)
[코디] 🆕 26.10.12(월) — 발주서정리 /field/orderpaper 업체 카드 배지 「G」(페페 QA 09:13) = 자재코드 유리(G)·AL(A)이 OP_MATS 에 빠져(26.9.23 42cf6796 누락) 코드 그대로 찍히고 본문 AL·유리 항목이 통째로 안 보이던 것 → OP_MATS A·G(황동·분홍, 자재관리·입고일정과 동일) · 모르는 코드 「미분류 X」 · AL·유리 블록 수동분류 토글 제거 · 빈 발주처 카드 「(발주처 미입력)」 + 그 카드 cid 가 첫 업체 v0 와 충돌해 남의 항목 79행이 뜨던 것 — ✅운영 deploy-live 7ed55ede 09:27 · 100353b7 09:31 KST(master 9b2addf9·40c6f80e, 1파일 C:\dev\pfs\web\templates\basic\field\field_orderpaper.html) · 운영 실측 카드1~4 = 유로글라스[부자재·유리] · 이지웨이[AL] · 일광금속[부자재·AL] · (발주처 미입력)[유리], 본문 AL·유리 섹션 표시 · 사이트맵 미반영 4→1(orderpaper=same) · ⏳[페페] 「상원보드」 아님 = 유리 업체 미입력 AL발주서 2건(#7495 아이파크 107-2802 = AL발주서 #8 glass:[] · #3282 학동매장 주방) 업체 입력 필요 · 배지 10.5px 데스크톱 13px 하한 기존 위반(미변경)
[코디] 🆕 26.10.12(월) r3 — 한샘 소요 한남 2차(field 2184 · 99A) 261008 새 도면 반영(구도면 대비 바뀐 곳만) — ✅운영 POST(작업본 #49·#50 · 몸통 네스팅 #27 · 도어 네스팅 #28) · ✅표기 DWG NAS 코디 소요량 26.10.12\ · ⏳devplan §0 절 적용 대기(훅) · ✅카드 갱신
- [페페] 26.10.12 「261008 최신 파일 · 도어·몸통 최신화 · 다인스 제작분 제외 · 기존 작업분과 비교로 속도」. 구/신 시트 도곽 좌표 같음 → 절대좌표 원시도형 차 → 4구역 재측정 · 판정 151건(치수 변경 50 · 삭제 16 · 추가 9 · 마감 5 · 이동 18 · 글만 20 · 같음 33).
- 바뀐 곳 = 주방(벽 3995 · FIX 190 · 오븐 빠짐 · K01 도어 1616 · 이마목 1200 · E.P 570) · 신발장 C 공중부양(4장 → 2400 2장 · 도어 2429.5) · D 폭 136|712|712 · 세탁실 문틀·후면휠라 PET → 효산 무늬목유사 LPM(코드 미정) · 드레스룸 높이 −30 · 아일랜드 서랍부 재설계 · 표지 «서랍 하부 보강밴드목» 15T 띠 20매. 승계 = 거실(10/12 확정 예정) · 버틀러 · 세탁장·워시타워 · 외부 복도 F043(신 도면에 없음).
- 몸통 #27 = 286매(구 #25 265) · 엔진 51 · 길로틴 49 · 작업본 #49(55)·#50(99)·#48(13 승계) / 도어 #28 = 153매(구 #24 159) · 엔진 40 · 길로틴 37 · 새 칼라 abort 1(«효산 무늬목유사 LPM(코드 미정)»). 폐기 대상 = #23·#24·#25 · 작업본 #46·#47(안 지움).
- 표기 DWG =
\\192.168.0.101\공유폴더\2026현장\진행중\10월\한샘 소요 한남 2차\코디 소요량 26.10.12\261008포인발송_소요한남 파네스 주방,수납,욕실_99A_건립_코디소요량표기_261012.dwg(sha256 bd998e50… · 해치 150 · CODY_r3변경 빨강 테두리 68) + csv 2 · 요약 md · png 44. - ⏳[페페] «키큰장,하부장 전체 제외 발주완료» 뜻(추천 = 소요량 유지) · 세탁실 새 LPM 코드(10/14 샘플 · 5매 보류) · 거실·주방 가전 10/12 확정본 · 보강밴드목 가정 · 폐기 대상 정리. 상세 =
projects/pfs/session-2026-10-12-hannam2-takeoff-r3.md· 작업폴더C:\dev\_work\hannam2-1012\· devplan 적용 대기분C:\dev\_work\hannam2-1012\devplan_r3\. - (r2 · 26.10.11~12 구도면 261001) 작업본 #46·#47·#48 → 몸통 #25(265) · 도어 #24(159) · #23 폐기 · 높이 = 형상 기준(원장 21건) · 칼라 7 등록(861 → 868) · 표기
코디 소요량 26.10.11\(sha256 7ad205f3…). - ⏳[페페] #23 삭제 여부 · 문짝 높이 Door 치수(틈 뺀 값) 6곳 · 결 방향(전부 세로 vs 긴 변) · 포켓 프레임EP 2 소속 · 세탁실 도어 후면 PET · 드레스룸 칸막이 40 = 18T×2 · 9자 원장 · 등판 −60 3장 · 도구 개선 3(DIMLFAC −1 · verify 자리별 후면 · hybrid 오픈장 세트). 범위 밖 = 욕실장·약장(다인스 제작) · 외부 공급 유리/AL 도어.
- 상세 =
projects/pfs/session-2026-10-11-hannam2-takeoff.md· 작업폴더C:\dev\_work\hannam2-1011\· 판단 원장 54건C:\dev\_work\hannam2-1011\decisions.md.
[코디] 🆕 26.10.8(목) 19:19 — 몰테니 홍보부스 임시견적 #802 → 한샘 양식 ✅NAS \\192.168.0.101\공유폴더\2026현장\견적\10월\한샘\몰테니 홍보부스\한샘 몰테니 홍보부스 가구제작 견적서(26.10.08).xlsx(sha256 8997736f…) · verify ALL OK 79 · 도면 안 함(지시) · 도구 옵션 2개 추가(rules 🆕) · ⏳[페페] 단가군(벽판넬→키큰 FIX PANEL)·길이 10000·담당 김경록 부장 확인
[코디] 🆕 26.10.8(목) — 한샘 양식 변환 = 정본 페이지 · 성포 769 · 한국유리부지 #800(V1·V2 위치도) ✅NAS 새 파일 → 🆕재사용 도구 C:\dev\tools\hansem-convert\hc.py(playbook §8 · 스킬 hansem-convert · 회귀 3건 바이트 동일) · ⏳[페페] 7건(Q1~Q4 · 수납 단가군 · 규격↔길이 6줄 · 🔴NAS 한국유리부지 V1 없음·V2 16:32 재저장 · 성포 10.2판 없음 확인) — 원문 = projects/pfs/session-2026-10-08-hansem-convert-tool.md 부록 · 사례 = session-2026-10-08-{gs-ansan-seongpo-hansem-v2,hankukglass-hansem}.md
[코디] 🆕 26.10.6(화) — GS 대전 변동(도마변동 · field 2175) 몸통·도어 네스팅 준비 완료 — 몸통 PNCAD #41~44 → 네스팅 #20(부재 396매 · 원장 엔진 47장 · 길로틴 45) · 도어 해치 DWG → 네스팅 #22(부재 250매 · 엔진 34장 · 길로틴 33) · 운영 쓰기 = POST 신규만(PUT 0) · 칼라 자동등록 POST 차단(마스터 858 그대로)
- (갱신 불릿 6개 → archive.md 「✅ 26.10.9 · pfs-handoff-cap-1009a」)
- ⏳[페페] 잔여 = ①등판 18T 결합(측판 사이 삽입이면 264×2169 · 추천=삽입 치수) ②18T 등판이면 뒤판각목 제거(추천 → 도어 34장 복귀) · 그대로 보류 = ③검토 12행(저장본 그대로) ④칼라 3 등록 ⑤PBNB6T 합치기(발주 단계) ⑥해치 DWG 육안 ⑦현장 실측.
- 🆕[코디] 26.10.11(일) [페페] 후면 결정(FIX·단면=유사PP · PVC=양면 · 이름 유사PP · 벽마감 4.5T 유지) → #22 PUT 19:24 KST · NAS 도면 r6(최상위 최신만, 이전 판 = 이전버전 폴더) · 발주서 계산기 「전면/후면」 컬러 지원 = pfs 로컬 커밋
28dd9a66(calc.py·calc_adapter.py·mat_view.py · 테스트 71/71·83/83 · 「/」 없는 입력 회귀 0 · SL013-L/L·L/S 오분리 방지) + [페페] 26.10.12 「70-113 발주서에 넣기」 =874ac86a(도어 후면 70-113 1면/원장 → 시트 줄 합산 · PP시트 넘버 = PP시트 · #22 70-113 30→60M · 테스트 76/76·87/87) → ✅운영배포 26.10.12 00:21 KST deploy-livee8966be2(선별 포워드 5파일 · blob 3/3 일치 · EC2 HEAD 확인 · uwsgi 재기동 · health 200) + master push · 사이트맵 미반영 1(/field/worklog 타 세션). ⚠deploy-live 에서 test_mat_orderpaper ⑤(NAS 파서 PFS-MAT 건너뜀)만 FAIL = master 전용 orderpaper_sync.py 미배포분(이번 변경 무관). - 상세 =
projects/pfs/session-2026-10-06-gs-daejeon-body-door-nesting.md· devplangs-daejeon-nesting.html· 원자료C:\dev\_work\gs-daejeon-byeondong\{inventory,body_result,door_result}.md· 네스팅 https://pfs.poin.co.kr/production/nesting?job=22 (#20 은 열기 목록). - 🆕[코디] 26.10.8(목) 22:59~23:24 KST [페페]「서랍 바닥 3T→4.5T · 4.5T = 70-115 PP시트 · 도어류 후면 70-113 · 단면 후면 펫유사PP · 네스팅·도면 수정 · 운영배포」 → 작업본 #41~44 PUT(Tb 4.5 27매 · backMat 70-115 · 이동선반 −3 41매 같이 반영) · 몸통 #20 389매 원장 47→45(4.5T 70-115 49매 14장) · 도어 #22 컬러 「전면/후면」 249매 원장 35→37 · 칼라 마스터 858→861(3개) · NAS 새 파일
…_PNCAD몸통치수_r2.dwg+ 도어 폴더_r46개. ⏳[페페] 컬러 「전면/후면」 표기 확정·PVC(PBNB6T) 단면 19 · FIX 19 · 도어 벽마감 4.5T 3 해석·펫유사PP 신규 등록(기존 「유사PP」) 확인. 🔴발주서 계산기(material_order calc)는 「전면/후면」 컬러·행별 후면을 못 다룸 → 발주 전 코드 수정 필요 · 작업본 서랍바닥 27매는 엔진상 HS0868GP(#20 만 70-115 — 네스팅 재반영 시 다시 칼라 맞춤). 작업폴더C:\dev\_work\gs-daejeon-1008-pp\· 상세 = session 파일 「26.10.8 PP시트 규칙」 절.
✅ 26.10.14 · pfs-handoff-cap-1014 · pfs handoff 캡 이관 (20,460자 > 20,000 — 26.10.14 #803 한샘 V1·V2 절 · 26.10.13 목록 성능·자재 발주서 품명 이력 ✅ 절 원문)
[코디] 26.10.14(수) V2 — [페페] 수정 반영: PFS #803 운영 수정 1회(sub 58줄 마진 15.5→35 · 다각형 부가비 ×1.15 = 14,848,685(FLOAT 읽기 14,848,700) · 운반 500,000 · 시공 8,000,000 · 총액 33,860,900 → 45,334,700) → 한샘 V2 NAS 새 파일(…\견적\10월\한샘\소요 한남 2차\…(26.10.13) V2.xlsx · sha256 c77cd827…) · 다각형 = 주방 갑지 「기타·자재비」 별도 · 갑지 주방 21,338,700 · 수납 15,990,000 · 생산비+시공비 45,328,700 · verify 353 ALL OK · 회귀 바이트 동일 · 카톡 사본 C:\dev\_work\sohan2-hansem-261014\send\sohan2_hansem_V2.xlsx · ⏳카톡 발송 = 총괄 · 상세 = session-2026-10-14-sohan2-hansem-803.md 「2차」
[코디] 26.10.14(수) — 한샘 소요 한남 2차 #803 → 한샘 양식 엑셀 V1 NAS 새 파일(…\2026현장\견적\10월\한샘\소요 한남 2차\한샘 소요 한남 2차 MH 가구제작 견적서(26.10.13) V1.xlsx · sha256 0dcea4d9…) — 추가금액·부가비 행 합산(fold) · 마감 종류만 · 갑지 33,860,000(PFS 33,860,900 −900 절사 · 🔴지시문 23,585,000 은 옛 값 — 10.13 18:01 다각형 부가비 12,911,900 교체 미기록) · verify 353 ALL OK · 회귀 바이트 동일 · ⏳[페페] 내일 확인 → 수정은 sites\sohan2-803.json 고치고 run → nas-put --put(V2 자동) · 확인요 6 = session-2026-10-14-sohan2-hansem-803.md 「다음」
[코디] ✅ 26.10.13(화) — 목록 로딩 성능 운영 반영 22:37 KST(master f23a70dc·82acf3cc → deploy-live 8bbdc3b4 · 7파일) + 인덱스 patch63 운영 22:41(field_type·estimate_detail · 커밋 b7767098 push 안 함) · 발주서 목록 2.3s→0.11s · 현장 6.6s→0.33s · 견적 10.4s→0.19s · 업무패널 콜드 7s→0.45s · ⏳[페페] 탭 새로고침 육안 · estimate(field_no) 인덱스(견적 무필터 0.7s) 보류 · worktree C:\dev\pfs_wt_molist·C:\dev\pfs_wt_perf 삭제 승인 대기 · EC2 /tmp/pfsperf/ 임시파일
✅ 26.10.13 자재 발주서 자동 행 품명·규격 직접수정 + 이력 복원 — 운영 42ea2ea1 (patch61 mat_orderpaper_item_hist) · ⏳[페페] 탭 새로고침 · 업체 추천 실적 기준 확인 (원문: archive.md 「✅ 26.10.13 · pfs-handoff-cap-1013」)
✅ 26.10.13 · pfs-handoff-cap-1013b · pfs handoff 캡 이관 2차 (26.10.10 dwg-takeoff 파이프라인 구축 절 · 26.9.28~29 월마감 명세서/롯데 화성 향남/에넥스 절 원문)
[코디] 🆕 26.10.10(토) — dwg-takeoff 자재소요량 파이프라인 공용 CLI 구축 + 주방84A 비교 실험 채점 + README 보강 — ✅로컬(tools e6022f1·8c1db80 · push 안 함 · 운영 쓰기 0) · ✅devplan C:\dev\devplan\dwg-takeoff.html
- (완료 세부 — 비교 실험 채점·P5 구축·보강·오버라이드·성포/원주 채점·견고화·혼합안 — 원문: archive.md 「✅ 26.10.10 · pfs-handoff-cap-1010b」) 현황: 도구 11명령+doors/sheets/hybrid, tools 최신
44952a3로컬, 테스트 10종 ALL PASS, ⏳성포 평면 깊이 EP·비규격·키큰장 −5 갭[페페]. - [코디] C2(23:02~23:35 KST) — 혼합안 3단 기본값(점수 ≥0.40 keep · 0.30~0.40 확인 항목·답 없으면 뺌 · <0.30 뺌+review) · 짧은 필러·걸레받이 런·상부장 끝 측면EP · Jev 섀도(V5norule_fs4 · keep 면 유형만 · 실행당 150 · jev-lab 라벨셋 로그) — tools
407adbc로컬 · 테스트 11종 ALL PASS · 개발(대전·성포만) 대전 keep 94.4·93.7 → 94.8·94.8 · 성포104 L1 32 → 34/41 · 성포 전체 88 → 93/177(정밀도 72.7 → 75.6). - C2 단구 84C 채점 1회(
C:\dev\_work\cmp-3\score_c2.json· 튜닝 안 함): 답 없음 L1 4/33 12.1·12.5%(사양서 칼라 답 없음 = 칼라 빈칸) · 옛 C 답 재적용 19/33 57.6·55.9%(C 17 · 51.5·43.6) · 장수 11 vs 정답 10(C 11) · Jev 새 호출 81. ⏳12T 좁은 EP 띠 = 대전·성포 근거 없어 규칙 안 넣음. - [코디] 🆕 가구 규칙 사전 화면
C:\dev\devplan\furniture-rules.html(원장C:\dev\tools\dwg-takeoff\catalog\furniture_rules.json규칙 132·장 15 — 상태 5색·첫 화면 확인필요·인라인 수정·질문 답·장 params→3면 SVG·부재 표 안전 파서) + APIGET/POST /api/furn-rules(devplan app.py · base_mtime 409 · tmp→replace · 로그catalog\furn-rules.log.jsonlgitignore) — tools3257223로컬 · 실주소 Playwright 실측(저장·새로고침·409 합치기·SVG·13px·대비 5.5~13:1) 후 원장 원본 복원. ⏳페페 = 확인필요 46건 답. - 다음 — ①P5 도어 부재 도면 추출기(입면 해치·치수 → 도어 행) + 시트 번호 탐색 ②P4 Jev(rules 🆕 26.10.10 3단 · 첫 후보 = 도면 부재 소속 choice) ③P5 후 주방84A 재실험(B 조건 · golden 폴더 차단).
- 위치
C:\dev\tools\dwg-takeoff\(사용법 =README.md한 장 · 진입takeoff.py11명령: convert·survey·chains·expand·rules·golden·verify·nest·engine·annotate·sigs). 선례 = GS 대전 변동(field 2175). golden 4타입×몸통/도어 · verify 12코드 · ruleshanssem_gs_mh(등판 −60·오픈장 세트·4.5T 70-115·레일별 바닥·도어 후면 · 미등록/충돌 = 검토). - ✅ devplan
C:\dev\devplan\dwg-takeoff.html(총괄 세션 web-designer 상담 「그대로 OK」 → 마무리 작업자가 등록 · 카드 ub=pfs · pagelinks up = gs-daejeon-nesting). 처음엔 ruleguardweb-designer-required가 서브에이전트 상담을 못 봐서(훅이 부모 transcript 만 읽음) 초안만 남겼었다. [코디]
[코디] 🆕 26.9.28~29 — 월마감 현장별 거래명세서 38158edc · 네스팅 #8 YEN70-SG 복구 5fd14421 · 롯데 화성 향남 한샘 엑셀 · 에넥스 9월 마감(close_no 21) — 완료, ⏳ 아래만 남음 (원문: archive.md 「…cap-1006b」)
- ⏳QC1 SSH 22 불통(HM3 미러 SKIP) · ⏳실물 A4 출력 1장 + 얼마에요 원본 대조
- ⏳PITR 인스턴스
pfs-pitr-nest8-0929삭제 승인 대기(stopped) · ⏳운영 동기화 시 stock 칸 자리 기준 UPDATE 어긋남 · ⏳EM738 18T 1매·엣지 제외(PNCAD 오류 확인 중) ·session-2026-09-29-chilseong-wonbujae-order.md「3차」 - 롯데 화성 향남(779·780): 최종 한샘 협의 90,000,000(VAT 별도) · 🔴779 PUT 이 하위내역 69줄을 지움(복구, rules 🆕) · ⏳한샘 견적 8(780 만 540,239) 처리 판단 · ⏳ACC룸(6,702,000) 이중청구 위험 → ①본건에서 뺀 새 본건(추천) ②추가건 재작성 ③그대로
- 에넥스 9월 마감
5dee8ae6· ⛔781·782·783 은 페페 직접수정본(단가·운임 스크립트 재실행 금지) · ⏳NEGO 입력 · 782·라인 VIP 단가 확인 · p6~8 을 784 에 더할지 추가3 인지 판단
✅ 26.10.13 · pfs-handoff-cap-1013 · pfs handoff 캡 이관 (26.10.13 자재 발주서 완료 절 5개 · 26.10.12 네스팅 자재 자동 등록 절 원문)
[코디] 🆕 26.10.13(화) — 자재 발주서 자동 행 품명·규격 직접수정 + 이력 복원 — ✅운영 반영 14:45 KST(master 129ee378·4cda2f3e → deploy-live 선별 포워드 1a6b8f23·42ea2ea1 · 7파일 blob 일치 · EC2 HEAD 42ea2ea1 · uwsgi 14:45:43 KST · health 200) · [페페] QA 14:09 「31행 엣지 HS0868GP — 뒤판 70-115 PP 유사 시트 활용 엣지 발주 · 품명·규격 직접 수정 · 기존 품명 이력·복원」 · 새 테이블 mat_orderpaper_item_hist(patch61 CREATE 만 · 테스트 → 운영 SSM 선생성 · 적용기 C:\dev\pfs\scripts\_mat_orderpaper_patch61_apply.py) · 이력 = 변경 후 값(첫 수정 때 원래 계산값 calc 1줄 먼저 · source calc/user/restore · is_applied 0 = 재가져오기 후보) · POST /api/mat-orderpaper/<no>/lines/name-restore(hist_no 복원 | to_calc 되돌리기 · 초안만) · 재가져오기·대응 연결 = 사람 지정 값 유지 · line_key 불변 · 정정(amend) 규격도 이력 · 대응 불명 행은 연결 전 수정 금지 · 화면 = 입력칸 상시(평소 투명 테두리) · 칩 「수정됨 · 이력 N」 → 인라인 이력 표 · 검증 = 자체검사 116/116 · 테스트 서버 실주소 Playwright 18/18(C:\dev\_work\mat-name-edit-1013\ui_check.py · 스크린샷 …\shots\) · 반박검증(vff-analyst) 차단 0 · 권장 2 중 1 반영 · 운영 읽기 확인 쓰기 0 · 사이트맵 미반영 1 = 카톡관리(타 세션) · ⏳[페페] 열린 탭 새로고침 · 고친 품명이 확정되면 업체 추천 실적도 고친 품명 기준(그대로 둠 — 바꾸려면 말해 달라) · 되돌린 뒤엔 칩이 사라져 이력 표를 못 연다(설계대로) · 테스트 DB 문서 #36·네스팅 #82 = 코디 테스트용(남김) · devplan pfs-mat-orderpaper.html
[코디] 🆕 26.10.12(월) — 네스팅 자재(원장) 실시간 자동 등록(직접 고친 행 ✎ 고정 · 지운 자동 행 억제 opts.matSuppressed · 옛 저장본 = 전부 사용자 행) + 「⚙ 자재 전체 다시 등록」 confirm + 검색칸 Enter = 전체 단어(data-drop-enter="best", 네스팅만) — 포인·월드 협력사 — ✅운영 deploy-live 037ea14f 08:34 KST(master 23ce1f1a 선별 포워드 3파일) · 서버·DB 0 · 검사 C:\dev\pfs\scripts\_nesting_automat_check.py 89/89 · ✅master push 23ce1f1a · 사이트맵 커밋 보류(tools/sitemap 타세션 미커밋 섞임)
[코디] 🆕 26.10.12(월) — GS 대전 변동 도면 261006→261007 칼라 대조(읽기 전용) — 변경 있음: 몸통 HS0868LS(F)→HS0868GP 49곳 전부 · 바디 엣지/등판 PP 「케데코 70-115」 코드 삭제→「바디 유사」(79→2건) · 84A옵션 홈바 AL IK-A43→A44 · 팬트리 도어 후면 70-113 · 홈바 하부장 칸 신설(IV075MT/70-113/HS0868GP) · 84A옵션 상판·벽 US102 퀘스트 · 손잡이 사양표 IK-A44↔전면유사 정정 · 59A 현관 은경→브론즈 · 결과 C:\dev\_work\gs-daejeon-byeondong\dwgdiff_1012\report_261006_261007.txt · ✅[페페] 결정: GP=경면코드·261007 이 협의 확정본 · 70-115(4.5T·PP시트·엣지·스티커)는 넘버가 빠져도 그대로 유지 · 손잡이 칼라 변경 확인됨 · 몸통은 엑셀 초안 기준(직접 수정분 있음·재생성 안 함) · 다음 = 페페가 도어부재 추가·수정·검토(네스팅) 후 도어 초안 지시 예정
✅ 26.10.10 · pfs-handoff-cap-1010b · pfs handoff 캡 이관 (dwg-takeoff 완료 세부 11~35줄 원문)
- 비교 실험(주방84A · 12:45~12:57 KST) — 채점 = 이름 무시 키(두께·수종·전/후면·양단면·a·b) golden 확정 행 기준 ·
C:\dev\_work\cmp-84a\score84a.py→score84a.json. - A 기존 방식(선례
parts.json·pieces.json재사용 = 사실상 재적용 · 5분 · 서브 169,649토큰): 몸통 확정 56/56(100%) · 도어 21/23(91.3%, 팬트리 도어 2매를 양면 IV075MT 로 — golden 단면 70-113) · 미확정 6/6·6/6 · 장수 몸통 6·도어 7(차 0) · review 11. - B 새 방식(README 만 · 도어 도면 재판독 · 12분 · 181,626토큰 · ⚠golden 폴더 site/spec.json 열람 = 누설 가능): 몸통 54/56(96.4%, 손으로 읽은 문틀 세로 2215 vs 2230 · PNCAD 16행은 전부 일치) · 도어 2/23(8.7% · 서랍앞판 폭 697 갭 차감 · 목찬넬 670 · 팬트리 383/407 · EP·천판·휠라1835 누락) · 장수 몸통 6(0)·도어 5(−2) · review 15. 구축비 ≈ 41분(10:48~11:04 + 12:20~12:45).
- 해석 = 도어는 도구에 추출 명령이 없어(P5) «선례 재사용 vs 처음부터 판독»을 잰 셈. 도어 치수 규약(갭 차감·찬넬 길이)이 spec·README 에 없다 → P5 에서 spec 키로.
- README·도구 보강(
8c1db80) — 행 입력 형식 표(저장본·parts·treadwork·결과 스키마·expand/rules 산출 = nest·engine·golden·verify 공통) ·rules --apply(트리밍 → body_rows 치수 +applied) ·golden check --row-type· 도어 행 규약(color 전면/후면 · side 단면/양면 · 빈칸 추정) · colors_master →settings\paths.json(+verify --colors-master) · engine treadwork 사본 =--out옆<이름>_treadwork\(--tw-dir) · P5 미구현 명시. 테스트 4종 ALL PASS(rules D · verify 결과 스키마 추가). - ✅혼합안 C(최신 정답 #17 GET 도어재 33매) — 7분 · 146,753 · 재현율 51.5 · 정밀도 43.6 · 장수 11(A 48.5 · 55.2 · 9 / B 54.5 · 58.1 · 7). 추가 19 · 누락 13. 원인 = 패킷 기본값이 후보를 다 살림. devplan §4++++ 표.
- ✅jev-lab(
C:\dev\tools\jev-lab\· 커밋 2f38f5d) — 소속=규칙(70.4 · 64.3) · 도어재 유형만 Jev 82.6 · 76.9 vs 규칙 70.7 · 55.8 · 예시4 변형이 최대 이득. 다음 = 도어재 유형 판정에 Jev 예시4 변형 섀도 통합 · 혼합안 추가 19 원인(패킷 기본값) 정리. - ✅P5 구축(14:03~ KST · tools
dc309e9· 운영 쓰기 0) —takeoff.py sheets(A계열 도곽 INSERT 회전·축척·MINSERT·1단 중첩·XCLIP · 노란 칸 순 번호 → 대전 sheets.json 29/29) ·doors(입면 실선 격자 면 · 틈≤2.5·중복선·공유변 보정 · 찬넬/걸레받이 = 장 경계 분할 · DIMENSION/체인/DIMLFAC/덮어쓴 글 · spec 칼라 ·--jev섀도 ·--rows-outparts 행) ·doors-eval(golden 좌표 일대일 · 저장본 치수 다중집합) ·tests\test_doors.py— 테스트 5종 ALL PASS. - 대전 golden 250: 후보 재현율 84.0%(입면 97.6% · 측면/평면 56.6%) · keep 71.6% · 정밀도 74.9% · 중복 1.3% · 치수오차 중앙 1.9 · 주방84A 입면 19/19(실험 B 2/23 의 원인 해소). 홀드아웃 성포(field 2180 · 저장본 #18 사본 262매 · 규칙 동결 14:31 후 1회) = 치수 다중집합 재현율 39.7% · 정밀도 17.8%(70시트 전부 후보).
- Jev 섀도 103호출: golden 짝 18 중 유형 맞춤 Jev 5 vs 규칙 14 · 보류 50 → 승격 불가·섀도 유지(로그
tests\out\p5_doors_dj_jev.jsonl). 약점 = 측면뷰 숨은 판(플랜지 25·리턴 11) · 현장 규칙 치수(AL 차감·리턴 60·EP 깊이) · 저장 범위 밖 시트 거르기. devplan §4+. - 검증:
tests\test_rules.py·test_verify.py(심은 결함 15/15)·test_regress.py(#20 45장·길로틴 42 / #22 37장·35 / 합 77 · PFS 엔진 실물 45·37 · 쓰기 0)·test_dxf.py(survey·chains = 옛 산출 동일 · annotate→DWG→DXF 왕복 원본 15,044 엔티티 불변) 전부 ALL PASS. - 반박 11건 중 행으로 표현되는 6건(#1·2·3·4·5·10)만 재검출 대상(#6·7·8·9·11 = 도면 표기 유지·기록). 다음 = 주방84A 비교 실험(몸통 62·도어 29 · golden 기준 엔진 6+7장).
- ✅P5 보강(14:42~ KST · tools
7e0892d· 운영 쓰기 0 · 규칙 고정 15:01 KST) — ①측면 단면↔입면 짝짓기(플랜지·리턴 = 입면 목찬넬·상부휠라와 높이 겹칠 때만 · 사본 줄·남의 시트 차단 · 웹 → 찬넬 a 47/60) ②doors --profile hanssem_gs_mh규약DOOR_CONV(거울도어 7 제외·AL 303 −3.5/304 −26.5 버림+손잡이 띠 24 합침·걸레받이 60/주방=몸통·찬넬 장 외폭·리턴 40/문틀 시트 제외·주방 EP 480/수납 모서리 띠 제외 — 근거 = golden 확정 행+페페 A·C·D) · 근거 없는 값 7건 =DOOR_REVIEW(갭 차감·서랍앞판 −4/−6·하부 FIX 240 등) ③칸 밖 도곽 = 제목 «입면도»만(성포 70→25) ④X 표시 안 닫힌 하부 FIX 3/3 복구(치수·치수 차 근거, 높이 220 = DETAIL 240 은 검토). - 대전: 후보 84.0→99.6%(측면/평면 56.6→100) · keep 71.6→88.0 · 정밀도 74.9→91.7 · ≤1mm 49.2→82.3 · 다중집합 45.9/49.4→73.5/78.8 · 주방84A keep 65.5→82.8. 성포 홀드아웃 1회 39.7/17.8→40.5/18.5(남은 실패 = 주방 도어 239 vs 64 · 주방 EP 480 과적용 82 vs 9 · 미지 부재명 냉장고EP·9T쫄대·I찬넬). 테스트 6종(+
test_doors_pair) ALL PASS. - ⚠성포 최종본 GET 못 함 —
X-PFS-Agent-Token은/api/nesting/job401(허용 경로만) · 로그인 POST 는 지시상 금지 → 로컬 사본 #18(10-05 23:21 수정·23:50 KST 수집) 사용C:\dev\_work\gs-seongpo-p5-1010\job_18_snapshot_1005.json· GET 스크립트fetch_sp_job.py. ⏳ 로그인 승인 시 최신본 확인. 남은 큰 일 = 평면뷰 숨은 판(세로휠라 리턴 300·숨은 EP 400·480 = keep 미달 16). - ✅현장 파일 오버라이드(15:13~15:38 KST · tools
f7662f4· 운영 쓰기 0 · 로그인 POST 1회 [페페] 승인) — 성포 #18 최신(10-6 09:24 수정 · 389매 = 사본 262 + 몸통 127 병합 · 도어재 행 변화 0 ·C:\dev\_work\gs-seongpo-p5-1010\job_18_latest_1010.json). 공식 홀드아웃(고정7e0892d) 27.8 · 18.8(도어재 범위 40.5 · 18.5) → 오버라이드 35.5 · 57.0(51.9 · 56.2) · 대전 회귀 없음(정밀도 91.7 → 92.4 · 다중집합 73.5 · 79.4). 성포는 이제 홀드아웃 아님. - 층 = 프로필
DOOR_CONV(2현장 근거 승격 = main_band·door_min_side·side_ep_depth 띠 버림) +golden\<현장>.site.jsondoors 절(대전 = AL·거울도어·걸레받이 60·찬넬·리턴 40·주방 EP 480 이관 · 성포 = Style Up+입면 C 시트 · 걸레받이 150 · 병합 2440 · 사전 7 · 유리 플랩·후드 제외). 남은 = 평면 깊이 EP(냉장고EP·EP·측면EP) · 비규격·9T쫄대·I찬넬 · 전시부스 54 · 키큰장 −5 갭(⏳[페페]). devplan §4++ · test 7종 ALL PASS. - ✅성포 104 비교 채점(자료 차단 · 20:24 KST · 읽기만) — L1(이름 무시 · 두께·전면칼라·양단면·치수±3) A 기존(24분·297k) 몸통 0/25 · 도어 25/41(61.0 · 정밀 69.4) · 장수 9·11(정답 6·15) / B 새(20분·233k) 몸통 0/25 · 도어 6/41(14.6 · 18.8) · 장수 9·12. 치수만 = A 24·70.7 · B 48·73.2 → 형상 추출은 동급, 차이는 B 도어 15T(사양서 CORE) 1건 — B 를 18T 로만 바꾸면 61.0 = A. A 는
domain_rules.md(성포 도어 18T) 열람 = 누설이 그 1건에 닿음. 몸통 0 = 칼라(H2041B-L1+246 표기 · 밥통장·로봇장 정답 GY123MT MDF vs 둘 다 HS0868GP PB) · 냉장고 상부장·가전소물장 상단 = 정답 범위 밖.C:\dev\_work\cmp-sp\score_sp.py→score.json· devplan §4+++. - Jev 섀도 126(보류 102 = 81%) · 비보류 24 중 정답 10(41.7%) — 내장 96 = 보류 89.6% · 1/10 · 맥락 30 = 보류 53.3% · 9/14(64.3%) vs 같은 질문 규칙 11/14 → 승격 불가(n≥50·98%). B 도구 우선순위 = ①도어 두께를 현장 파일 키로(사양서 CORE ≠ 생산) ②특수장 몸통 경로(칼라·재질 = 마감재일 수 있음) ③양면 판정(FIX·EP·냉장고EP 양면) + 내장 Jev 맥락.
- ✅원주 단구 84C 비교 채점(도어재만 · 26.10.10 KST · 읽기만) — A 기존(17분·274k) 도어 21/34(61.8 · 정밀 72.4) 장수 9(−1) 띠 18/21바 / B 새(10분·186k) 17/34(50.0 · 54.8) 장수 7(−3) 띠 16(순수 12)/21바. B 순수 판 지표 = 동일(손수정 3행 전부 걸레받이 150 띠). 오차 = 두 쪽 모두 EP류 누락(A 8 · B 12) + B 추가 12(FIX 570×740 등) · 양단면. Jev 139(보류 42 = 30%) 정답 짝 판 4건 Jev 1 vs 규칙 4 · 판+띠 폭 26건 비보류 19 중 Jev 4 vs 규칙 11 → 승격 불가(질문이 규칙 저신뢰 후보 위주).
C:\dev\_work\cmp-3\score_3.py→score.json· devplan §4++++. - ✅[코디] 견고화+혼합안(22:11~22:49 KST · tools
44952a3로컬 · 원주 자료 0 · 개발 = 대전·성포) — 사양서 머리·표 변형(«도 어 사 양»·한글·글자 분리·상하·CORE 없음·«업체: 코드») + 0 판독 경고·텍스트 블록 덤프 ·type_of(«84㎡C»·대전 «84㎡ A» 를 84 로 자르던 site-init 수정 →type_map.auto) · 평면 문맥(범위 밖 같은 타입 평면도) + 냉장고EP(평면 X 상자 깊이) · 성포 104 도어 L1 31→32/41(97.0%) · 성포 전체 도어재 L1 85→88 · 다중집합 39.3·78.9→40.4·79.3 · 대전 지표 전부 그대로 · 테스트 10종 ALL PASS(+test_hybrid). - 혼합안
takeoff.py hybrid <dxf> --types --site --pack DIR→ checks.json+PNG →--answers→ result.json — 대전 84A 패킷 = 항목 7 · 이미지 11 · 토큰 어림 ~4.4k(이미지 3.0k+글 1.4k) · 성포 104 답 1개(냉장고 빈 쪽 d720) → L1 33/41 · README «혼합안 절차» · ⏳레그룸·측면EP 깊이는 자동 아님(LLM 확인 항목).
✅ 26.10.10 · pfs-handoff-cap-1010 · pfs handoff 캡 이관 (26.10.9 완료 절 7개 · 26.10.6 업무패널 통화 · 26.9.23 Jev 절 원문)
[코디] 🆕 26.10.9(금) 14:16 — 스티커 도어 탭 「한샘 학동매장 도어발주서.xlsm」 검색 안 됨 = 정시 동기화가 테스트만 돌았다 — ✅수정·운영 반영(master d99e6383 + 사이트맵 d0251bf3 · 사이드카라 deploy-live 불필요) + ✅상주 워커 자동 동기화(6f68cc05)
- 원인 = 런처 vbs
test하드코딩 → 운영 DB 는 버튼으로만 갱신(26.8.26 이후 신규 0). 수정 =door_order_sync.py all+ 런처 인자all+ 인벤토리 0/급감 가드 + 자체검사test_door_sync_targets.pyALL PASS. 운영 전량 재동기화 = 신규 31 · 창 밖(2025-09·10) 32건 remove(연결 0) · alive 242 → 운영GET /api/sticker/door-files?unlinked=1&q=학동매장= 그 파일 1건(file_no 263, 15품목). 정시 작업 수동 기동 14:15 KST = prod·test 둘 다 reconcile alive 242(런처all실기 확인). - 🔴사고 = 코디가 Bash(Session 0)에서 sync 실행 → NAS 0건 → 운영 243건 remove_yn='1' 71초(13:45:37~13:46:48 KST) → SQL 원복(243·테스트 242) · 재발 가드 넣음.
- ✅ 14:45 [페페] 「엑셀 동기화를 워커로 자동화 · 오류 4건 무시」 → 상주 워커
door_sync_watch.py(master6f68cc05· 사이트맵d38470db· 서버 코드 변경 0 → deploy-live 안 함): 버튼 claim →all· 5분마다all --if-changed(NAS 바뀐 환경만, 안 바뀌면 SSM 0) · 파일 락 직렬화(정시 pfs_door_sync 와) · 자체 로그(2MB 회전)·같은 오류 10분 1회·하트비트--status· claim 파일로 중단 요청 자동 정리 · Session 0 거부. 로그 0줄 원인 = 런처cmd /c … >> 로그가 파일을 잠가 log() 가 조용히 실패(워커는 운영 sync-poll 200 으로 계속 폴링 중이었다 — nginx 실측). 런처 =conhost --headless python직접(리다이렉트 제거). - 실기: 운영 화면 버튼 1회(Playwright, 닫음) → 요청 id=4 claim 14:32:32 → done 14:32:48 · 화면 「✓ 14:32」 · DB done · 워커 로그 3줄 / 자동 감지 = 운영 상태 1건 일부러 오래되게 → 14:37:09 그 1건만 upsert(15품목) / 크래시 = 워커 kill 14:37:22 → 예약작업이 14:41:01 재기동(Session 1,
--statusOK). 자체검사test_door_sync_targets.py21항목 ALL PASS. - ⏳ 페페 육안: 운영 스티커 도어 탭 검색. (파싱오류 4건 = [페페] 무시) [코디]
[코디] 🆕 26.10.9(금) — PNCAD 깊이 분할(D·앞뒤 칸막이) + 공간 정면 방향 앞|뒤(뒤 도어·서랍·날개판 뒤 끝) — ✅운영(본체 a900e009 = dev-97 배포에 포함 · 라벨 후속 3216c8a9) · pncad def8b33·359636e
- 라벨 후속 2건: 규격표 깊이칸막이 열 머리 = 뒤판과 같은 「길이 * 높이」(spec.html axisLabel) · 존 패널 D 분할 칸 수 라벨 = 「앞뒤 칸」(app.html). pncad 359636e → pfs master dabe7bb1 → deploy-live 3216c8a9(blob 대조 일치) · 운영 app.html·spec.html 변경 문자열 확인 · 사이트맵 재빌드 3225507a(미반영 1 = 타 세션) · schema 자체검사 PASS(깊이분할 11).
- 미확정 기본값 = 깊이칸막이 폭 내경 그대로 · 깊이칸막이 split 미지원(경고).
- ⏳ 접합 2단계(3D 사선·규격표 통/사이/45·체결 선택·편집기 UI). [코디]
[코디] 🆕 26.10.9(금) — PNCAD 접합 설정 1단계 엔진(코너 4모드·뒤판 덧댐 D유지·내부 T·endTrims) — ✅운영 deploy-live 45cb7164(master d1abef48 ← pncad 889e0fe, schema.js 1파일) · 설정 UI 전이라 운영 영향 0 · 회귀 9,349건 동일
- 운영 /production/pncad/schema.js 에
applyJoints5곳 확인(길이 146,686자 = 로컬 일치) · 사이트맵 재빌드(미반영 1 = 타 세션) · schema 자체검사 PASS(접합 38) · lindiv PASS. - ⏳2단계: 3D 사선·규격표 통/사이/45·체결 선택·편집기 UI · 깊이 분할(D). [코디]
[코디] 🆕 26.10.9(금) — PNCAD 배치 이동 음수 허용·±10000 — ✅운영 deploy-live 4c936793(master d86aebe7, app.html 1파일)
- x·y·z 음수 허용 · ±10000 클램프(
MOVE_LIM·clampMove, 속성 패널 #pX/#pY/#pZ + moveDrag), 벽·바닥 0 제한 제거. 운영 /production/pncad/ 에 MOVE_LIM 확인 · 사이트맵 재빌드(미반영 1 = field_worklog 등 남의 작업, web/pncad 차이 0). 접합 그릴링 추가 결정 3건(LPM 마이터 경고만 · 단축 후 최소 100mm · 체결 사용자 선택)은devplan/pncad-joints.html결정 절에 반영. schema.js 는 다른 런 작업 중이라 미접촉. [코디]
[코디] 🆕 26.10.9(금) 09:10 — PNCAD 배치 깊이 y 입력 + Ctrl+드래그 깊이 이동 — ✅운영 deploy-live 61752735(master f966074d, app.html 1파일)
- 우측 속성 패널 깊이 y 입력(#pY) · 어느 뷰에서나 Ctrl+드래그 = 깊이(앞뒤) 이동 · #hint 문구. 운영 /production/pncad/app.html 에
id="pY"확인. ⏳ 접합 우선·마이터 그릴링 7문항 페페 답 대기.
[코디] 🆕 26.10.9(금) — PNCAD 현장목록 경량 API·선로딩 + 휠드래그=커서중심 회전(Shift+휠=이동, 메인·아티클 편집기) + QA헬퍼 패널 열릴 때 모달 밀림 — ✅운영 deploy-live 537adc36 08:49 KST(master c7a41623 4파일)
- 원인 =
/api/field/가a.*+행당 상관 서브쿼리 6개(운영 6.65~8.97초·1.45MB) → 신규GET /api/pncad/fields(6칼럼·조인 2) 운영 0.25~0.47초·289KB·2,026건. 화면 = 유휴 선로딩 · stale-while-revalidate · 입력 120ms 디바운스 · 「전체 N건 중 500건」 · 이스케이프 · 목록 13px. 자재넘버·작업현장 목록도 같은 패턴(요청번호·캐시·다시 시도). - 모달 =
body.qa-h-panel-open .ov{right:380px}+.ovBoxmax-width. - ⏳ 접합 설정(측판·천판 등 어느 쪽을 늘릴지 · 마이터 45°) = 페페 요청 26.10.9 → 그릴링 질문 대기(설계 결정 전 착수 금지).
[코디] 🆕 26.10.6(화) — 업무패널 통화 = 새 통화만(컷오프 20:21:34 KST) + 미종결 통화 3,014건 일괄 완료 — ✅운영 bfce51f7(master 5e2b27f4·사이트맵 1e59c6d0) (원문: archive.md 「✅ 26.10.6 · pfs-worklog-panel-newcall」)
- ⏳ devplan
worktray-panel.html17차 절 미반영(훅 차단) → 본문C:\dev\_bench\worklog-panel-1006\devplan_p17_snippet.txt· 새 통화 200건 넘으면 재발(페이지 나눔 없음)
[코디] 🆕 26.9.23 — 발주서 dedupe 경계만 Jev · intake-check 명세서 대조 Jev 섀도 — 완료 (원문: archive.md 「✅ 26.9.29 · pfs-handoff-cap-0929」)
✅Jev 반영 켬(tools a0d35ef, 끄기 = JEV_APPLY=False/--no-jev). ⏳코디 = 첫 Jev 반영분 verdict 대조. 상세 = projects/pfs/session-2026-09-23-orderpaper-jev.md.
✅ 26.10.9 · pfs-handoff-cap-1009a · pfs handoff 캡 이관 (26.10.7~8 완료 포인터 절 · 26.9.22~23 완료 절 · GS 대전 변동 갱신 불릿 원문)
(A) 26.10.7~8 완료 절 헤더 14개 (본문 원문은 각 「…cap-1008/1008c」)
[코디] 🆕 26.10.8(목) 밤 — 네스팅 부재 입력표 기본 빈 행 3→20 — ✅운영 deploy-live f9c8247d (원문: archive.md 「✅ 26.10.8 · pfs-handoff-cap-1008c」)
[코디] 🆕 26.10.8(목) — 월드산업 협력사 네스팅 /partner/nesting + /api 허용목록 게이트 — ✅운영 deploy-live f69b484a · patch60 · 계정 world01 (원문: archive.md 「✅ 26.10.8 · pfs-handoff-cap-1008c」)
[코디] 🆕 26.10.8(목) — 업무패널 카드 호버 전문 확장 — ✅운영 deploy-live 317fc239 (원문: archive.md 「✅ 26.10.8 · pfs-handoff-cap-1008c」)
[코디] 🆕 26.10.8(목) — 견적 v2 「타입별 가구 항목」 카드 헤더 스크롤 고정 — ✅운영 deploy-live 5e048737 12:0x KST(master 547852e9 3파일 · 사이트맵 9211bd07 미반영 3→1) · DB·서버 0 (원문: archive.md 「✅ 26.10.8 · pfs-handoff-cap-1008」)
[코디] 🆕 26.10.8(목) — 견적 v2 추가금액(sub) 「자당포함」 플래그 — ✅운영 4ddbfc6c · patch59 · ⏳한샘 변환 흡수 규칙(rules 🆕 26.10.8) (원문: archive.md 「✅ 26.10.8 · pfs-handoff-cap-1008c」)
[코디] 🆕 26.10.8(목) — 생산현황 미입고 보드 자재 표기 12px·간격 절약 · 「접힌 현장 N곳」 배지 삭제 — ✅운영 deploy-live 471ca2b7 10:35 KST(master 9a802495·49e5e9fe·8b56b4f8 · 사이트맵 cf1c96aa) (원문: archive.md 「✅ 26.10.8 · pfs-handoff-cap-1008」)
[코디] 🆕 26.10.8(목) — 견적서 v2(/estimate/regist-v2·modify-v2/<no>) 상단 헤더(제목·취소/저장) 스크롤 고정 — ✅운영 deploy-live b909b394(master 4022990e · 사이트맵 master 9eb741b3) · CSS 1파일 web\static\css\estimate_regist_v2.css (원문: archive.md 「✅ 26.10.8 · pfs-handoff-cap-1008」)
[코디] 🆕 26.10.7(수) — 견적 v2 현장 없이 저장 = 자동 임시견적 — ✅운영 c8bbf96e (원문: archive.md 「✅ 26.10.8 · pfs-handoff-cap-1008c」)
[코디] 🆕 26.10.7(수) — 견적 v2 현장 없는 견적 업체담당자 검색 — ✅운영 b4acda18 (원문: archive.md 「✅ 26.10.8 · pfs-handoff-cap-1008c」)
[코디] 🆕 26.10.8(목) — 미입고 보드 하위 칼라마다 비고 — ✅운영 cd650cfe (원문: archive.md 「✅ 26.10.8 · pfs-handoff-cap-1008c」)
[코디] 🆕 26.10.7(수) — 미입고 보드 현장별 비고 수정 + 메모 모달 공유 — ✅운영 b560b9c0 (원문: archive.md 「✅ 26.10.8 · pfs-handoff-cap-1008c」)
[코디] 🆕 26.10.7(수) — 원주·안산 개별 원부자재발주서 → 자재관리 정리 — ✅운영 #1 r37 (원문: archive.md 「✅ 26.10.8 · pfs-handoff-cap-1008c」)
[코디] 🆕 26.10.7(수) — 미입고 보드 자재 현장별 펼침/접기 — ✅운영 4a3c12ad+c5ab413e (원문: archive.md 「✅ 26.10.8 · pfs-handoff-cap-1008c」)
[코디] 🆕 26.10.7(수) — 견적 v2 QA 묶음 5건 ✅운영 deploy-live 6a11ee17(master 0da95f22·78f2ad9c) — 운영 80/80 · DDL 0 (원문: archive.md 「✅ 26.10.8 · pfs-handoff-cap-1008」)
(B) 26.9.22~23 완료 절 헤더 7개
배차 계산서 사진 1~4차 — 운영 d18e5ad 완료 (상세: archive.md 「✅ 26.9.23 · pfs-dispatch-photo」 · 범위 밖 3건·제안 2건 포함)
발주서 중복 전역 정리 + 자재관리 6개월 — 운영 a392b6c 완료 (상세: archive.md 「✅ 26.9.23 · pfs-orderpaper-dedupe」)
날짜 고침 패널 + NAS 엑셀 되쓰기 — 운영 c2f3242 완료 (상세: archive.md 「✅ 26.9.23 · pfs-orderpaper-date-fix」)
자재관리 동기화 20시간 먹통 수리 — 운영 93d7ce1 완료 (상세: archive.md 「✅ 26.9.23 · pfs-orderpaper-sync」)
월마감 월 변경 시 거래처 유지 — 운영 완료 (상세: archive.md 「✅ 26.9.23 · pfs-monthly-close」)
[코디] 26.9.22 — 네스팅 「서랍 자동계산기」(도어전용 탭) — 운영 a9c5d22+5faf806 완료 (상세: projects/pfs/archive.md · session-2026-09-22-nesting-drawer-calc.md)
[코디] 🆕 26.9.22 — QA 보고 1건 반영 — 완료 (상세: archive.md 「✅ 26.9.22(화) KST · pfs-door-order-import · [코디] QA 보고 1건 반영 (운영 4982b14)」)
(C) 26.10.6 GS 대전 변동 절 — 갱신 불릿 원문 (⏳ 잔여 불릿 2개·상세 포인터는 NOW 유지)
[페페] 성포·단구 기반 · 몸통 PNCAD 먼저 · 노란 사각형 내부만 · 주방 84A(Style Up A벽만) + 수납 3타입(59A·84A·84B). 결정 = 몸통칼라 HS0868GP · 수납 18T/주방 15T/홈바 상부장 18T · 휠라 전면+리턴 한 제품 · 거울도어 15T MDF+3T(제외) · 도어 해치 포함 · 엔진+길로틴 병기 · 타입당 1세트.
- 🆕19:3x KST [페페]「추천으로 진행해」반영: 등판 −60(홈바 하부장·붙박이장) · 84B 오픈장 측판 2장 몸통→도어 #22(ID 251·252). 몸통 #20 394매·엔진 47·길로틴 44 / 도어 #22 252매·엔진 34·길로틴 33 · 칼라 자동등록 차단(858). PUT 6회(작업본 4+#20+#22) · NAS _r2 4개.
- 🆕19:5x KST 2차 [페페]「추천대로 진행」: 파우더장 등판 818→788 ✅(#42·#43·#44, 19:52 작업본·19:53 #20) · 몸통 #20 394매·엔진 47·길로틴 44 그대로(4.5T 23.82㎡) · 도어 #22 무변경 · 합 646매·엔진 81·길로틴 77. 오픈장 나머지 판 = 사양서에 등판 줄 없어 안 함.
- 🆕20:1x KST 3차 [페페]「오픈장 전체 도어로 · 등판 두께=측판 18T」: 도면 주석 없음 확인 · #44 #5 나머지 5장 트리밍 0 · #22 ID 253~257 추가(천·지판 18T · 등판 18T 273×2203 · 각목 15T ×2). 몸통 #20 389매·47장·길로틴 44 / 도어 #22 257매·35장·길로틴 34 / 합 원장 82 · NAS _r3 4파일. PUT 3회(총 13).
- 🆕[코디] 26.10.8(목) [페페]「몸통 푼 치수 도면 표기」 → NAS 최신 도면 = 261006 건립도면 그대로(10/6 사본과 md5 같음) · 사본 \\192.168.0.101\공유폴더\2026현장\진행중\10월\한샘 GS 도마변동 MH\01.[한샘]_261006_GS건설 대전변동_주방,일반_건립도면_PNCAD몸통치수.dwg(ACAD2013 · 레이어 CODY_PNCAD몸통 1,559개 · 장 23 · 부재 줄 172) · 도면↔PNCAD 장폭 불일치 0(단 12 · 합만 일치 2 = 84A 파우더장 600×2) · 높이 참고 1(홈바 상부장 718 vs 720 DOOR) · ⚠26.10.8 PNCAD 엔진 변경으로 이동선반 8장이 앱에서 −3(네스팅 #20 은 저장 당시 값) · 운영 쓰기 0 · 작업폴더 C:\dev\_work\gs-daejeon-annot-1008\.
- 🆕[코디] 26.10.8 23:4x KST 추가 [페페]「언더·볼레일 서랍바닥 = 등판 자재 · 텐덤 = 15T」 → 레일 판정 27매 전부 언더레일(PNCAD·도면 BLUM·사양서 Quadro V6) · 텐덤 0 → 데이터 변경 0(PUT 0) · 작업본 단 서랍바닥 70-115 는 데이터로 불가(colorNoOf 코드 제안) · NAS 새 파일 …_PNCAD몸통치수_r3.dwg(레일 표기 · 홈 주석 정정).
✅ 26.10.8 · pfs-handoff-cap-1008c · pfs handoff 캡 이관 (완료 절 원문 · 26.10.7~8 배포 절)
[코디] 🆕 26.10.8(목) 밤 — 네스팅 부재 입력표 기본 빈 행 3→20 (우리 + 월드 협력사) — ✅운영 deploy-live f9c8247d 26.10.8 밤(master 0d2a3641 3파일 선별 포워드 · 운영 실측 /production/nesting·/partner/nesting 도어 입력표 20행·콘솔에러 0 · 사이트맵 재빌드 미반영 1 = 카톡관리 타 세션)
web/nesting/nesting.htmlPART_BLANK_ROWS=20한 곳(init·clearParts 공용) +dropBlankPartRows()(tread·서랍·제품 계산기가 빈 행 20개 뒤로 안 밀리게) · 협력사판web/nesting/partner/**build.py 재빌드(--check 최신). web-designer 상담 반영. 테스트https://pfs-test.poin.co.kr우리·협력사 20행·초기화·tread 3행 불러오기 9/9. 참고: 저장하면 빈 행도 parts 에 실려 저장목록 «N종» 이 +빈행만큼 부풀음(제안: 저장 시 끝쪽 빈 행 자르기 — 페페 결정 대기).
[코디] 🆕 26.10.8(목) — 월드산업 협력사 네스팅 https://pfs.poin.co.kr/partner/nesting + /api 계정유형별 허용목록 게이트(fail-closed) — ✅운영 deploy-live f69b484a 18:24 KST(master 6f20be40·0e175294 · 사이트맵 636b0090 미반영 3→1) · 운영 DDL patch60(ext_nesting_job) · 메뉴 partner_nesting · 202 company_type '2' · 담당자 장동수 대리(member 441) · 계정 world01(user 16 · 비번은 문서 기재 금지)
- 구조: 협력사 저장 = 별도 테이블(포인 nesting_job ALTER 0) ·
/api/ext-nesting/*는 job_no AND 세션 업체 · 화면 =tools/partner_nesting/build.py빌드 사본(주석 0) · /api 게이트 =api/pfs/permission/service/api_gate.py(거래처 27항목 허용목록 · 협력사 = ext-nesting 만 · 예외 = 403). - 검증: 운영 격리 30/30 · 화면 22/22 · 거래처 5계정 모의판정 23/23 · 테스트 75/75·30/30·28/28 · fail-closed 26/26 · 독립 반증 뚫림 0. 상세 =
projects/pfs/session-2026-10-08-world-partner-nesting.md. - ⏳[페페] ID·비밀번호 장동수 대리 전달 · ⏳devplan 페이지 배치(초안 = 총괄 보고의 scratchpad 경로 — 서브에이전트에선 web-designer-required 훅이 상담 기록을 못 봐 생성 차단) · 제안 = 비로그인 공개 3건(
/static/uploads/memo/field_memo.json·/static/reports/license.key·/swagger.json) 정리.
[코디] 🆕 26.10.8(목) — 업무패널(/field/worklog-panel) 카드 호버 전문 확장(.peek)·title 툴팁 삭제 — ✅운영 deploy-live 317fc239(master cc8f070f · 사이트맵 e089f1b8 미반영 1 = 카톡관리 타 세션) · 1파일 C:\dev\pfs\web\templates\basic\field\worklog_panel.html · 테스트·운영 실측 peek 0·title 0·호버 높이 불변·클릭펼침/편집 정상·콘솔에러 0 [페페 지시 「호버 전문 확장·툴팁 삭제, 운영배포」]
[코디] 🆕 26.10.8(목) — 견적 v2 추가금액(sub) 「자당포함」 플래그 — ✅운영 deploy-live 4ddbfc6c 11:45 KST(master 0bd5724b·36cd6622 · 사이트맵 b1ccd932) · DDL patch59 테스트→운영 INSTANT
[페페] 「추가금액 체크버튼 — 한샘 양식 때 숨김 · 자당 행 금액에 포함 · 별도항목에서 일괄적용」 + 「추천대로 + DDL 승인 · 운영배포」.
- DB estimate_detail_sub.in_base_yn CHAR(1) NOT NULL DEFAULT '0' — 테스트 271행·운영 1,044행 영향 0(금액합 불변) · PFS 금액·출력 불변(표시 플래그만).
- 저장 = 키 누락(구버전 탭·스크립트 PUT)이면 같은 sub_no 기존값 유지 · sub_no 재사용(rules 🆕) · 화면 = 줄 칩 · 별도항목 3상태 일괄+되돌리기 · 사용처 배지.
- 검증 = 테스트 실주소 49/49 · 운영 읽기 6/6(797, 저장 0) · 스샷 C:\dev\_bench\pfs-inbase-flag\ · 테스트 검증 견적 #827(보관)·#828 남김.
- ⏳한샘 변환 코드에 흡수 규칙 반영(rules 🆕 26.10.8 [페페] · 다음 한샘 변환 때). 상세 = projects/pfs/session-2026-10-08-estimate-sub-inbase.md.
[코디] 🆕 26.10.8(목) — GS 안산 성포 MH(field 2180) 견적 검토 + 도면 사본에 견적 표기 — ✅NAS 새 파일 1 · 견적 데이터 수정 0 (원문: archive.md 「✅ 26.10.8 · pfs-handoff-cap-1008」)
- ⏳[페페] ①#15·#21 후면 구성(유리장→FIX+수납) 재견적 여부 ②#7~#9 홈바·장식장 건립 범위 포함 여부 ③10/2·10/6 제작도면 치수로 769 갱신할지(갱신하면 한샘 6·NAS 엑셀도 다시) ④전시부스 식세기 차감·104 아일랜드 EP. 표 2곳(99A 후면·104 후면)은 시트 프레임 안 빈 곳, 11곳은 시트 위 여백(A3 출력 프레임 밖 — 시트만 출력하면 안 나온다)에 있다.
[코디] 🆕 26.10.7(수) — 견적 v2 현장 선택 없이 저장 = 자동 임시견적 — ✅운영 deploy-live c8bbf96e(master 69b1ad0f · 사이트맵 9015adb8) 23:46 KST 재기동 (원문: archive.md 「✅ 26.10.8 · pfs-handoff-cap-1008」)
- 검증 = 자체검사 87/87 ·
_normalize_master직접호출 7케이스 · 테스트 Playwright 14/14(담당자만 #825 · 견적명만 #826 = 저장 막힘 없음·div 2·재진입 유지 · 현장연결 #821 재저장 div 1 그대로) · 테스트 API PUT div=1 무현장 → 2(서버 강제) · 운영 EC2 HEADc8bbf96·uwsgi 23:46:48 KST·8000 200 · 운영 읽기전용 9/9(쓰기 0). ⚠운영 #799 는 배포 뒤 페페 저장으로 div 2·발주처 「봉적」(temp_member 409)이 됐다 — 일괄변경 아님(무현장 본견적 279→278). ⏳임시견적에서 🔍로 현장을 고르면 div 2 그대로 연결된다(기존 동작 · 본견적 전환은 라디오→현장등록 경로) — 바꿀지 페페 판단. 테스트 QA 견적 #823~826 남김(삭제 안 함).
[코디] 🆕 26.10.7(수) — 견적 v2 「현장 없는 견적」도 업체담당자 검색 활성 → 발주처 등록 — ✅운영 deploy-live b4acda18(master e169000e · 사이트맵 387ddc35) 23:1x KST (원문: archive.md 「✅ 26.10.8 · pfs-handoff-cap-1008」)
- 검증 = 자체검사
C:\dev\pfs\scripts\_estimate_temp_site_check.py84/84 · 테스트 Playwright 12/12(신규 본견적 담당자 Enter 확정→발주처 자동→저장→재진입 유지 · 임시견적·현장연결 회귀) · 운영 읽기전용 8/8(#799 활성 · #798 현장연결 readonly · 저장 0) · 사이트맵 페이지 미반영 0. ⏳테스트 DB QA 견적 #823(div2)·#824(div1) 「[코디QA]」 남음(삭제 = 승인 사안). web-designer 1회(위젯 재사용 OK).
[코디] 🆕 26.10.8(목) — 생산현황 출력 미입고 보드 하위 칼라(자재행)마다 비고 — ✅운영 deploy-live cd650cfe 09:41 KST(master 4bdc1ec4+e272300a · 사이트맵 c0a513f7) (원문: archive.md 「✅ 26.10.8 · pfs-handoff-cap-1008」)
- ⏳ 어제 결정 대기 ①~⑤ 그대로(접힘 당일 · 알림 · 메모 JSON 비로그인 노출 · 긴 현장명 2줄 · 범위 밖 제안).
[코디] 🆕 26.10.7(수) — 생산현황 출력 미입고 보드 = 현장별 비고 직접 수정 + 생산 메모 모달 공유 · 접힘 두 화면 동기화 — ✅운영 deploy-live b560b9c0(master 60be1a48 · 사이트맵 2947cbfd) 18:03 KST (원문: archive.md 「✅ 26.10.8 · pfs-handoff-cap-1008」)
- ⏳[페페] ①접힘 당일만 유효 vs 계속 유지 ②비고 텔레그램 알림 여부 ③🔴기존 생산 메모
https://pfs.poin.co.kr/static/uploads/memo/field_memo.json비로그인 200(전문 노출, 미수정) ④긴 현장명(아이파크 107-2802)은 34% 칸에서 2줄 ⑤빠른 문구 칩·작성자 표시 = 범위 밖.
[코디] 🆕 26.10.7(수) — 원주·안산 개별 원부자재발주서 → 자재관리 정리 ✅운영 #1 r35→r37 · 추가 6 · 조운 수량 4·샘플 삭제 4 · B안 경고 master 82660853 · 자재관리 69→71 (원문: archive.md 「✅ 26.10.8 · pfs-handoff-cap-1008」)
- ⏳ 통합본(동기화제외) 조운IMT 탭엔 칼라샘플 4개가 남아 있다(현장별 파일·자재관리는 지움) · GK102-G8 날짜 = 통합본 「10.13」 ↔ 자재관리 10/14(보드)·10/12(길동 시트) · 「통합 … 중 이 현장 몫」 옛 비고 4행(조운 시트)은 API 로 비울 수 없어 남음(비고 칸 빈값 = 원본 비고로 돌아감).
[코디] 🆕 26.10.7(수) — 생산현황 출력 미입고 보드 자재 = 현장별 그룹 펼침/접기 · 접은 그대로 인쇄 — ✅운영 deploy-live 4a3c12ad+c5ab413e(master 2125ff29 · 사이트맵 81f0eab8) (원문: archive.md 「✅ 26.10.8 · pfs-handoff-cap-1008」)
-
⏳남은 것 = ①펼친 채 인쇄하면 2쪽(종전도 2쪽 · 접으면 줄어듦, 운영 첫 그룹만 접어선 2→2) ②연도표기(12월↔1월) 때 헤더 입고일 「26.10.12(월)~」 인쇄 17px 넘침(자재행도 종전부터 같은 폭) ③실물 프린터·노트20 실기 미확인 ④기존 인쇄 11px(자재행) 하한 예외는 페페 결정 사항으로 그대로 둠.
-
[종결] [코디] 🆕 26.10.6(화) — 자재 발주서 #1 QA: IV075EMT 펫시트 업체 길동상사 → 조운IMT — ✅운영 `fb7c9dd6… → archive.md 「✅ 26.10.6 · pfs-handoff-roll-1006c」
- [종결] [코디] 🆕 26.10.6(화) — 부자재 발주서 엑셀 「복구 필요」 수정 — ✅운영
a9d8f6e8(master80fb3e21)… → archive.md 「✅ 26.10.6 · pfs-handoff-roll-1006c」 - [종결] [코디] 🆕 26.10.6(화) — 자재 발주서 #1 도어재 통합 발주 마무리(NAS 통합 발주서 + 운영 DB 정정 amend API) —… → archive.md 「✅ 26.10.6 · pfs-handoff-roll-1006c」
- [종결] [코디] 🆕 26.10.6(화) — 네스팅 저장본 통합 열기 + 복수 현장 — ✅운영
792ea1cc·`3b63b9… → archive.md 「✅ 26.10.6 · pfs-handoff-roll-1006c」 - [미결1] [코디] D1 자재 발주서 모듈(26.10.5) — ✅운영 반영 26.10.6 01:01 KST
5b1173c9(master `f4763… → archive.md 「✅ 26.10.6 · pfs-handoff-roll-1006c」 - [종결] [코디] 🆕 26.10.5(월) — 네스팅 → 원부자재발주서(도어) 초안 파이프라인 + 복수 현장 연결 — 그릴링 Q1~Q10 후 D1 로 … → archive.md 「✅ 26.10.6 · pfs-handoff-roll-1006c」
- [미결1] [코디] 🆕 26.10.5(월) — GS 원주 단구·안산 성포 마감재 네스팅 수량 합산 + 결방향 세로 통일 → 운영 새 작업 #17(31장… → archive.md 「✅ 26.10.6 · pfs-handoff-roll-1006c」
- [종결] [코디] 🆕 26.10.4(일) — 네스팅 부재 표 ID 칸·정렬·필터·조건 세트 서버 저장 — 운영
5a3dfceb완료 (⚠기존 저장… → archive.md 「✅ 26.10.6 · pfs-handoff-roll-1006c」 -
[미결8] [코디] 🆕 26.10.1~2 GS 계열 작업 묶음 — 전부 코드 변경 0(②만 코드) · ⏳[페페] 판단 대기는 원문(archive.md … → archive.md 「✅ 26.10.6 · pfs-handoff-roll-1006c」
-
산출 = NAS
\\192.168.0.101\공유폴더\2026현장\견적\10월\한샘\한국유리부지\261001 한국유리부지 가구도면_코디견적표기.dwg(16,639,996 B · 시트마다 프레임 아래 코디 치수값 [줄번호]+ 견적표 · 표지 오른쪽 타입별 요약표 3 + 합계 박스) ·…\한샘 한국유리부지 MH 견적서(1차 임시견적 #800).xlsx(76,317 B). ⏳devplan 페이지 = ruleguardweb-designer-required가 서브에이전트 상담을 못 봐 미생성 → 완성본·카드·pagelinks 문안C:\dev\_work\hanguk-glass-1008\devplan_draft\(README.txt 3단계 · 상담 처방 반영됨). - [종결] 네스팅 부재 그리드 키보드·타입/위치 + 저장/열기 모달(1~3차, 운영
4388bc4·83e15b3·a227c4e, 전부 페페 실기 확인 완료) → session-2026-09-10-nesting-grid-modal-plan.md · session-2026-09-10-nesting-grid-range.md · archive.md 「26.9.11(금) — 새 네스팅 버튼」
✅ 26.10.8 · pfs-handoff-cap-1008b · pfs handoff 캡 이관 (원주 단구·안산 성포 발주 통합 절 원문)
[코디] 🆕 26.10.6(화) — GS 원주 단구·안산 성포 도어재+몸통재 발주 통합 1·2단계 완료 — ✅운영 #1 r35 · NAS 파일 3 + JPG 15 · master 85f1ea17(파서 MAT)·e89a0870(「장」) · deploy-live 7dd6da19 · 사이트맵 6fe3b796
[페페] 「도어재+몸통재 통합 · 도어=엑셀 최종본 기준 · 몸통 우라판=70-115 유사 PP · 피스마개스티커·엣지=케데코 · 구버전 정리 · 현장별 파일·JPG · DB 반영 · 운영배포」 + Q1~Q3=A. 1단계(Q4·Q5 무관분)만 끝냄. 작업폴더·백업·스크립트 C:\dev\_work\mat-integrate-1006\(progress.log).
- ① 백업 = 운영 #1 r33 GET · 자재관리 SELECT(2169·2180·251 260행 + 미연결 93 + 관련 5파일 200행) · NAS 5파일 사본+md5 → …\backup\.
- ② NAS 파서 orderpaper_parse.py 정규식 MAT 추가 · 드라이런 10월 7파일 중 자재발주서_1 만 93→0 · 13:38 라운드 removed 93(미연결 0). 재기동 불필요(예약작업이 매번 새 프로세스).
- ③ NAS 이동 3개(자재발주서_1·원주 몸통 10.2·성포 몸통 10.2) → 10월\통합발주(동기화제외)\ md5 3/3 · 14:08 라운드 removed 24(성포 f251 12·원주 12 → 0).
- ④ amend 1회(14:10 KST) r33→r34: 제목 「(도어재+몸통재) …」 · 정정 12줄(효산 18T 「PB 경면양면」+비고 E0,246경면 · 4.5T 「MDF 민자양면」 · 샘플 246경면 · 피앤알 보드 7 비고 E0,PVC · GK102-G8 피스마개 「남는시트 사용」 · 선재 H2041B-L1 엣지 비고 「246경면 · 샘플:효산엘피엘」=품명 꼬리) · 추가 21행(피앤데코 HS0868GP 6/9/12T 1·1 · 18T 11/4 · 15T 27/53 · 피앤알 PW합판 4/6 · 70-115 4.5T 12/23 · 케데코 PP시트 80/120M(→피앤알)·엣지 800/1200M·스티커 10/20장 · 효산 피스마개 스티커 10장 성포). 보드=R·시트=T·엣지=E·스티커=S. 코드 = 「장」 단위(자재관리 qty 「10장」).
- ⑤ 검증 = 운영 ↔ 도어·몸통 최종 엑셀 164칸 문제 0 · 자재관리 기대 71 = 실제 71(2169 19→29 · 2180 31→42, 전부 대기) · 단위 73/73 · test_pfs_link OK.
- ✅2단계(15:10 KST · [페페] Q4=A·Q5=A 「모두 추천 진행」): ①몸통 합산 파일 → 하위폴더(14:33 · 14:38 라운드 2169 nas 16→0) ②#1 r35(피앤알 P9GA4T·PQFA2T 피스마개 비고 「남는시트 사용」 = 페페 파일 H15:J17 병합칸) · 자재관리 사용자 입고일 71/71(길동·조운·피앤데코·케데코 10/7 · 피앤알 10/8 단 몸통 PW합판·70-115 4.5T = 10/7(몸통 탭) · 효산 10/8 · 오엠씨·선재 10/12) · 케데코 6행 비고 「긴급」(note_user) ③build_p2.py 로 NAS 표준양식 3개 = 월 폴더 한샘 GS 원주 단구 원부자재발주서.xlsx(29품목)·한샘 GS 안산 성포 원부자재발주서.xlsx(42) + 하위폴더 (도어·몸통 통합)한샘 GS 원주 단구+GS 안산 성포 원부자재발주서.xlsx(58) · keywords PFS-MAT#1 · 피앤알 탭 시트 안내 병합행(케데코 70-115 100M2롤 포함) · 업체 탭 날짜 Q5 · 케데코 「(긴급)」 · 대조 268칸 문제 0(통합↔페페 최종 2개 · 현장별↔#1 배분) ④15:08 라운드 = 새 2파일 항목 0 · 2169·2180 nas 0 · PFS-MAT#1 71 ⑤JPG 15장(원주 7·안산 8) 10월\발주서JPG(GS 원주 단구·안산 성포)\<업체>_<현장>.jpg.
- ✅통합본: 페페가 열어 둬(~$ 14:48) 15:08 교체를 못 했다가, 닫은 뒤 16:55 NAS md5 = 14:41 판(e5b50974) 확인하고 고친 판(3b7539ea, 피앤알 안내행 축소맞춤)으로 교체 · 왕복 일치. ⚠업로드 실수 1건(셸 따옴표로 원부자재발주서\10월$f 파일 생성) → md5 확인 후 제자리로 rename(삭제 0).
- 애매점: PP시트 비고 = 「100M2분할 권취 필수(원주+안산 통합 200M)」 · 효산 「피스마개 스티커」 띄어쓰기·비고 E0 = 파일 그대로 · 피앤알 안내행 날짜 = 시트업체 Q5 날짜 10/7(수)(페페 12:08 본은 10/8(목)) · 몸통 피앤알 항목칸 10/6 은 버리고 탭 머리 10/7 · 현장별 파일 안내행 = 「이 현장 nM (통합 N *2롤 · 업체 발송)」 · 행 순서는 DB seq(페페 본은 손으로 재배열).
✅ 26.10.8 · pfs-handoff-cap-1008 · pfs handoff 캡 이관 (26.10.7~8 완료 절 12개 원문)
[코디] 🆕 26.10.8(목) — 견적 v2 「타입별 가구 항목」 카드 헤더 스크롤 고정 — ✅운영 deploy-live 5e048737 12:0x KST(master 547852e9 3파일 · 사이트맵 9211bd07 미반영 3→1) · DB·서버 0
[페페] /estimate/modify-v2/769 「카드 제목~주방/가구 줄을 상단 고정헤더 아래 고정」. web-designer 처방: .card[data-card-key=detail]>.card-header sticky z55 + #detailSticky(타입입력~kf-row) sticky z54, topbar z60 · --ev2-top/--ev2-hd 는 JS ResizeObserver 실측 · 모바일 ≤767 카드헤더만(묶음 static). 검증 pfs/scripts/_est_detail_sticky_check.py [test|prod] [번호] 3뷰포트 전 통과(카드헤더 top=topbar 76/126·묶음 122) · 스샷 C:\dev\_bench\pfs-detail-sticky\. ⚠이월: 데스크톱 고정 높이 ≈243px(1366×768 의 32%) · 고정 밴드 뒤로 Tab 포커스가 숨을 수 있음(scroll-padding 미적용, 범위 밖).
[코디] 🆕 26.10.8(목) — 생산현황 미입고 보드 자재 표기 12px·간격 절약 · 「접힌 현장 N곳」 배지 삭제 — ✅운영 deploy-live 471ca2b7 10:35 KST(master 9a802495·49e5e9fe·8b56b4f8 · 사이트맵 cf1c96aa)
[페페] 「자재 표기부분 공간 — 폰트 11까지 허용 · 줄간격·셀내 간격 최대한 절약 · 『접힌 현장 N곳…』 안내 블록 삭제 · 운영배포」.
- 출력물(#oob-grid 스코프만)·모달(#fieldMemoModal) = 셀 padding·lh 축소 · 자재행·자재 비고 화면 12px(인쇄 11px 그대로, lh 1.25 · padding 1px) · 헤더 13px 굵게 유지 · 배지 HTML·CSS·JS 두 화면 삭제(모두 접기/펼치기 버튼 유지). 처방 = web-designer(총괄 상담).
- 🔴덤으로 잡은 버그 2: ①폰 폭(≤575px)에서 26.10.8 오전 판 «표 안 tr 만 grid» 가 줄을 첫 칸에 가둬 칼라가 글자 단위로 쪼개졌다(운영 390px 자재행 237px · 17행 전부 여러 줄) → screen 전용으로 표·tbody 블록 + 2줄 격자 ②접기/펼치기 연타 때 fold 요청이 뒤바뀐 순서로 도착해 서버에 «반대»로 저장(테스트 실측 Enter 두 번 → 접힘) → oob_sync.js 접힘 저장 줄 세우기·마지막 응답만 반영.
- 운영 실측(읽기 전용 · 접힌 그룹은 화면에서만 펼쳐 잼, C:\Users\delix\AppData\Local\Temp\claude\c--dev\a4affbc3-b0e6-4605-b07c-750ad824df7e\scratchpad\measure.py) 전→후: 화면 표 663→541px(헤더 36.5→30.9 · 자재행 31→25) · 인쇄 435→377px(28.3→24.7 · 19.4→16.8) · PDF 2→2쪽 · 폰 390 자재행 237→57 · 모달 목록 733→529(머리 40→30 · 자재 35→25) · 칼라 여러 줄 0 · 넘침 0 · 콘솔 에러 0. 테스트 = _memo_split_check 36/36×3 · _oob_note_check 56/56(쓰기 검사는 테스트만).
[코디] 🆕 26.10.8(목) — 견적서 v2(/estimate/regist-v2·modify-v2/<no>) 상단 헤더(제목·취소/저장) 스크롤 고정 — ✅운영 deploy-live b909b394(master 4022990e · 사이트맵 master 9eb741b3) · CSS 1파일 web\static\css\estimate_regist_v2.css
- 원인 = web-designer 처방(navbar 70px 겹침)은 틀림 — 사이트 navbar 는 이미 제거됨(
pfs_layout.css). 진짜 원인 =style.css#main-wrapper{overflow:hidden}이 스크롤 컨테이너가 돼 sticky 가 한 번도 안 붙음 +.fix-header .topbar{width:100%}가 음수마진 확장을 막음. 처방 =#main-wrapper{overflow:clip}· top 0 유지 · width:auto · margin/padding 25px(≤767px 15px, 햄버거 자리 왼쪽 58px·z 29) · z-index 60 ·.crumbs .sub13px. 실측(테스트·운영) 스크롤 후 topbar top=0. 스크린샷C:\dev\_bench\pfs-topbar-sticky\. - ⚠함정 = 이 repo 는 세션들이 공유하는 한 작업트리라 내
git push origin master가 타 세션의 로컬 커밋8b56b4f8(oob_sync.js)까지 같이 밀었다(운영 미반영 · 테스트만). 선별 배포 = deploy-live 워크트리에서 CSS 1파일만checkout <master해시> --.
[코디] 🆕 26.10.8(목) — 한국유리부지 MH 1차 임시견적 = 운영 견적 v2 #800 · 59,092,000원(VAT 별도) + 도면 사본 견적표기 DWG·견적 엑셀 NAS 새 파일 — 운영 쓰기 = POST 1회(PUT 0·SQL 0) · 코드 변경 0
[페페] 「pfs 1차 임시견적, 한샘 김선정 과장 담당. 추천대로 진행. 도면에 견적 잡은 부분에 코디 표기 치수 · 견적 항목 이름·금액 표(테이블) · 각 파트 근처에 기입 … 운영배포」. 작업폴더 C:\dev\_work\hanguk-glass-1008\(단일출처 plan.py · register.py · annotate.py · verify_dwg.py).
- 범위 = 도면 표지 「구분 : FUR. / SYS. 건립 : 84㎡, 103㎡, 111㎡」 → 3타입 일반가구+시스템 각 1세대(시트 48장). 제외 = 103 드레스룸 디자인2안 · INT 욕실도어·INT 도어 · 석재 상판(현장분).
- 견적 #800 = 임시견적(div 2) · 현장 미연결 temp_site_name 「한국유리부지」·유형 MH · 업체담당자 399 김선정 과장(한샘 15.5% 자동) · 「한국유리부지 MH 견적서 (1차)」 · 49줄 = 84 15줄 15,041,000 / 103 17줄 21,821,000 / 111 17줄 22,230,000 · 시공비·운반비 0(별도) · 길이견적만(추가금액 0).
- 결정(추천안 · furniture-expert 자문) = 신발장·복도장·장식장·수납장 A1 224,000 · 붙박이장 P1 243,700 · 키큰 화장대 P2 · 낮은 화장대·욕실 하부장 B1 124,900 · 욕실 상부장 W1 107,500 · 도어 G1 138,000 · 픽스판넬 = G1 단가 준용(≈180k/㎡ = 선례 직접금액 중앙값) · 시스템 = 직접단가 일광 GLWP 벽판넬형 98,600/자 · GLSYS AL기둥형 43,000/자(포인 판넬·선반 몫, AL·철물·가죽서랍·조명 별도) · 치수 = 도면 DIMENSION 정의점 핸들로 실측, 몸통·선반 기준(벽 간격 제외).
- 검증 = 반박검증 에이전트(치수 49/49·금액 원단위 일치 · 기준 정정 4줄 반영 59,196,000→59,092,000) · 등록 후 GET 49줄 ALL MATCH(amount float 절단 ±10) · 엑셀 출력 49줄 합 59,092,000 · DWG 왕복(ODA ACAD2013→DXF) 원본 16,125 엔티티 종류·레이어별 차이 0 · CODY_견적(ACI 30) 1,644개 · 코디 치수 88개 = 견적 49줄 세그먼트 일치 · NAS 왕복 바이트 일치 · 원본 DWG 무변동(16,581,331 B · 26.10.02 13:55).
- 산출 = NAS \\192.168.0.101\공유폴더\2026현장\견적\10월\한샘\한국유리부지\261001 한국유리부지 가구도면_코디견적표기.dwg(16,639,996 B · 시트마다 프레임 아래 코디 치수 값 [줄번호] + 견적표 · 표지 오른쪽 타입별 요약표 3 + 합계 박스) · …\한샘 한국유리부지 MH 견적서(1차 임시견적 #800).xlsx(76,317 B). ⏳devplan 페이지 = ruleguard web-designer-required 가 서브에이전트 상담을 못 봐 미생성 → 완성본·카드·pagelinks 문안 C:\dev\_work\hanguk-glass-1008\devplan_draft\(README.txt 3단계 · 상담 처방 반영됨).
- ⏳[페페] 확인 7 = ①픽스판넬 G1 준용(103·111 금액의 큰 몫) ②시스템 98,600/43,000(일광이 마감판까지 공급하면 하향) ③시공비·운반비 별도 유지 ④111 욕실 「상부장 ALT 01.」 표기 · 입면 B 하부 박스(미포함) ⑤측면 리턴판넬 기준(103 창고 C′ 352 포함 / 84 신발장A A′ 420 = 몸통 EP 라 미포함) ⑥103 복도 픽스 입면 1470 vs 평면 1490(입면 채택) ⑦PFS /api/estimate/print/pdf/800 = 500 「Object of type 'Response' is not JSON serializable」(엑셀은 정상 · 코드 안 고침).
[코디] 🆕 26.10.8(목) — GS 안산 성포 MH(field 2180) 견적 검토 + 도면 사본에 견적 표기 — ✅NAS 새 파일 1 · 견적 데이터 수정 0
[페페] 「안산 성포 견적서도 검토하고 도면에만 견적 내용 표시해서 사본으로 저장해놔라」(한국유리부지 임시견적과 같은 표기 방식). 작업폴더 C:\dev\_work\seongpo-annot-1008\.
- 기준 견적 = 포인 769 「GS 안산 성포 MH 견적서」(견적일 26.9.7 · 최종수정 26.10.2 · 이후 차수 없음 · 26.10.2 스냅샷과 완전 동일) 가구 36,768,000 + 운반 600,000 + 시공 11,000,000 = 48,368,000 · 한샘 6(form 14)·NAS 10월 엑셀 48,360,000(만원 절사 −8,000)은 769 파생. 운영 GET 만(로그인 외 POST·PUT 0, 전후 스냅샷 같음).
- 대조 도면 = 최신 …\진행중\10월\한샘 GS 안산 성포동 MH\01.[한샘]_261006_…제작도면(84OA상부장사이즈수정) (1).dwg + 9/30 자재준비용·10/2 제작도면 판 비교. 계산 재현(estimate_regist_v2.js 식) 28줄·추가 50건·총액 오류 0.
- 검토 13건(상2·중6·확인3·하2): 🔴상1 99A·104 「아일랜드 후면 유리장」(#15·#21, 3,090,000) = 현행 도면 후면은 레그룸 FIX + 하부 수납(99A 800+400 · 104 2단 서랍장 1,125×2), 유리장 없음 · 🔴상2 84A 장식장 키큰장·홈바 하부장·홈바 상부 유리장(#7~#9, 3,066,000) = 9/4 견적의뢰용 도면에만 있고 9/30 이후 건립 입면엔 없음 · 중 = 하부장 −200(84A·전시부스·OT84A, 2단 서랍장 축소 10/2판) 각 −96,000 · OT84A 상부 285 비움(10/6 수정) −77,000 · 전시부스 냉장고장 기본형1 1,860(견적 1,650) +111,000 · 104 식세기 B벽→아일랜드·상부 2,005→2,055 합 −27,000 · 99A 아일랜드 2,320→2,300 −10,000 · FIX 폭만 바뀜(금액 0) · 확인 = 전시부스 식세기 600 미차감 · 104 아일랜드 FIX EP 0건 · 키큰서랍장 비고 복사 · 하 = OT84A 벽판넬 560↔460 · 769 비고 「길이 견적만」 낡음. 길이만 반영 시 −291,000(참고).
- 산출 = NAS 새 파일 \\192.168.0.101\공유폴더\2026현장\진행중\10월\한샘 GS 안산 성포동 MH\01.[한샘]_261006_GS건설 안산 성포동_주방_건립타입 제작도면(84OA상부장사이즈수정) (1)_코디견적표기.dwg(AC1027=ACAD2013 · 13,944,994 B · sha256 c568d5a7…6621 되읽기 일치 · 폴더 기존 9항목 크기·시각 변경 0 · 원본 md5 def4c4bf 그대로). 레이어 CODY_견적(색 30) 1,130개만 추가 = 견적 부위 주황 사각형 37 · 코디 측정 치수줄+태그(줄 번호·이름·행합계·도면 치수·차이) · 시트별 표 13(선+MTEXT: 항목명·규격·코디 측정·수량·단가·금액, 추가 항목 포함) · 전시부스 행 오른쪽 요약표. 원본 엔티티 33,698 서명 차이 0(ODA 왕복 대조).
- 검증 = verify_dwg.py ALL OK · nas_put.py PUT ALL OK · snap_cmp.py ALL SAME · PNG C:\dev\_work\seongpo-annot-1008\png_final\(17장, 겹침 육안). 스크립트 = review.py(검산·영향) · annotate.py(표기) · _occupancy.py(충돌 상자) · _render.py.
- ⏳[페페] ①#15·#21 후면 구성(유리장→FIX+수납) 재견적 여부 ②#7~#9 홈바·장식장 건립 범위 포함 여부 ③10/2·10/6 제작도면 치수로 769 갱신할지(갱신하면 한샘 6·NAS 엑셀도 다시) ④전시부스 식세기 차감·104 아일랜드 EP. 표 2곳(99A 후면·104 후면)은 시트 프레임 안 빈 곳, 11곳은 시트 위 여백(A3 출력 프레임 밖 — 시트만 출력하면 안 나온다)에 있다.
[코디] 🆕 26.10.7(수) — 견적 v2 현장 선택 없이 저장 = 자동 임시견적 — ✅운영 deploy-live c8bbf96e(master 69b1ad0f · 사이트맵 9015adb8) 23:46 KST 재기동
[페페] 「지시 혼선 — 지금 작업 유지 + 현장선택 없이 담당자만·견적명만 등은 자동으로 임시견적으로 변경 저장 · 운영배포」. 수정 = 서버 C:\dev\pfs\api\pfs\estimate\service\estimate_service.py _normalize_master 에서 field_no 비었거나 0(구 더미)이면 estimate_div='2'(생성·수정·도어발주서 자동등록 공통) + 화면 estimate_regist_v2.js payload 같은 규칙 · 저장 성공 뒤 라디오 임시견적·applySiteInputMode() · 전환됐을 때만 「저장 완료」 알림에 「현장을 선택하지 않아 임시견적으로 저장했습니다.」. 새 견적 기본값 본견적 그대로 · 현장 연결 견적은 보낸 값 그대로 · 기존 데이터 일괄변경 0.
- 검증 = 자체검사 87/87 · _normalize_master 직접호출 7케이스 · 테스트 Playwright 14/14(담당자만 #825 · 견적명만 #826 = 저장 막힘 없음·div 2·재진입 유지 · 현장연결 #821 재저장 div 1 그대로) · 테스트 API PUT div=1 무현장 → 2(서버 강제) · 운영 EC2 HEAD c8bbf96·uwsgi 23:46:48 KST·8000 200 · 운영 읽기전용 9/9(쓰기 0). ⚠운영 #799 는 배포 뒤 페페 저장으로 div 2·발주처 「봉적」(temp_member 409)이 됐다 — 일괄변경 아님(무현장 본견적 279→278). ⏳임시견적에서 🔍로 현장을 고르면 div 2 그대로 연결된다(기존 동작 · 본견적 전환은 라디오→현장등록 경로) — 바꿀지 페페 판단. 테스트 QA 견적 #823~826 남김(삭제 안 함).
[코디] 🆕 26.10.7(수) — 견적 v2 「현장 없는 견적」도 업체담당자 검색 활성 → 발주처 등록 — ✅운영 deploy-live b4acda18(master e169000e · 사이트맵 387ddc35) 23:1x KST
[페페] QA /estimate/regist-v2 #f-company-member-name 「임시 견적의 경우에도 업체 담당자를 활성화해 발주처 등록이 된 상태로」. 원인 = 담당자칸이 isTempSiteMode()(견적구분=임시견적 AND 현장 미연결)에만 열림 → 임시견적 라디오를 안 누른 현장 없는 견적(운영 #799 등 본견적·현장없음 279건)은 readonly. 수정 = isMemberEditMode() = !hasField() 를 담당자칸 readonly·힌트·인라인검색·키보드·미확정 저장차단 7곳에 적용(C:\dev\pfs\web\static\js\estimate_regist_v2.js) · 서버 변경 0(현장 미연결이면 견적구분 무관하게 temp_company_member_no 보존·조인) · 현장명 직접입력·유형 드롭리스트는 임시견적만(그대로) · 현장 연결 견적 readonly 그대로.
- 검증 = 자체검사 C:\dev\pfs\scripts\_estimate_temp_site_check.py 84/84 · 테스트 Playwright 12/12(신규 본견적 담당자 Enter 확정→발주처 자동→저장→재진입 유지 · 임시견적·현장연결 회귀) · 운영 읽기전용 8/8(#799 활성 · #798 현장연결 readonly · 저장 0) · 사이트맵 페이지 미반영 0. ⏳테스트 DB QA 견적 #823(div2)·#824(div1) 「[코디QA]」 남음(삭제 = 승인 사안). web-designer 1회(위젯 재사용 OK).
[코디] 🆕 26.10.8(목) — 생산현황 출력 미입고 보드 하위 칼라(자재행)마다 비고 — ✅운영 deploy-live cd650cfe 09:41 KST(master 4bdc1ec4+e272300a · 사이트맵 c0a513f7)
[페페] 「하위 칼라들에도 비고란 추가해줘. 운영배포」(26.10.8 채팅).
- 출력물·모달 둘 다 자재행 = 칼라 | 자재 비고 | 입고일(colspan 해제 · 34/42/24 유지). 자재 비고 = 현장 비고보다 가볍게(평상시 테두리·배경 없음 · hover/focus 점선+「비고」 · 터치 기기 옅은 점선 상시 · …+title) · 인쇄 = span(빈칸 공란 · 긴 비고 줄바꿈) · 575px 이하 2줄(칼라+입고일 / 비고)·44px·16px.
- 저장 = 같은 field_oob.json 에 mnotes {"<field_no>|<정규화 칼라>": text} · POST /api/field/memo/oob/note 에 color · 409 = 칸 단위(같은 현장 다른 칸끼리 충돌 없음 실측) · oob_sync.js data-color 칸(valOf·keyOf·mnote).
- 데이터 = 운영 board-wait 16행 정규화 후 현장 내 중복 칼라 0 · 최장 칼라 15자(KAEX7-SR (유사PP)) 화면 1줄. 같은 칼라가 입고일만 달리 두 줄이면 한 비고를 같이 쓴다(같은 자재).
- 후속 e272300a = 인쇄 때 접힌 그룹의 자재행이 다시 보이던 것(모바일 2줄 무효화 규칙을 펼친 그룹에만) — 테스트에서 잡아 배포 전 수정.
- 검증 = 운영 C:\dev\pfs\scripts\_memo_split_check.py 39/39 · C:\dev\pfs\scripts\_oob_note_check.py 56/56(자재 비고 16항 추가 · 끝나면 원복) · scripts/test_field_oob.py 9/9 · 사이트맵 print/status·field/list same. ⚠운영 검사 중 실사용자 접힘(2189) 확인 — 원복 로직은 «검사 시작 시점» 상태로 되돌리므로 검사 도중 사람이 바꾼 값은 덮을 수 있다(운영 재실행 자제).
- ⏳ 어제 결정 대기 ①~⑤ 그대로(접힘 당일 · 알림 · 메모 JSON 비로그인 노출 · 긴 현장명 2줄 · 범위 밖 제안).
[코디] 🆕 26.10.7(수) — 생산현황 출력 미입고 보드 = 현장별 비고 직접 수정 + 생산 메모 모달 공유 · 접힘 두 화면 동기화 — ✅운영 deploy-live b560b9c0(master 60be1a48 · 사이트맵 2947cbfd) 18:03 KST
[페페] QA /field/print/status #oob-grid th:nth-of-type(2)(칼라) 「칼라 자리 → 직접 수정 비고 · 생산현황 메모 수정란에도 입력창 · 자재 접힘/펼침 메모창·출력물 양쪽 비동기 · 운영배포」.
- 출력물 = thead 「현장명·칼라 | 비고 | 입고일」 34/42/24 · 그룹 헤더 가운데 = input.oob-note-in(80자 · Enter/blur 저장 · Esc 되돌림 · IME 조합 Enter 무시 · 인쇄 = input 숨김·span 글자) · 저장 칩 · 「접힌 현장 N곳 · 인쇄물에도 접힌 채」 배지+모두 펼치기. 모달(/field/list 생산 메모) = textarea 6줄 + 같은 그룹·비고·접기 섹션 · 미저장 비고는 hide.bs.modal 보류→저장 후 닫기.
- 저장 = JSON web/resource/memo/field_oob.json(DDL 0 · .gitignore · static 밖) · API GET /api/field/memo/oob · POST /oob/note {field_no,note,base}(편집 중 다른 화면 수정 = HTTP 409 4090) · POST /oob/fold · 키 = field_no(board-wait 에 추가) · 접힘 = 접은 날만 유효(FOLD_TODAY_ONLY) · 텔레그램 알림 없음 · 동기화 = 공용 C:\dev\pfs\web\static\js\oob_sync.js(BroadcastChannel 0.2s · 다른 PC 폴링 20s/포커스).
- 검증 = 운영 C:\dev\pfs\scripts\_memo_split_check.py 39/39 · 신설 C:\dev\pfs\scripts\_oob_note_check.py(두 브라우저 실토글·충돌·Esc·닫기 저장·모바일 390, 끝나면 원복) 운영 39/39 · 테스트 36/36·40/40 · scripts/test_field_oob.py 8/8 · 사이트맵 print/status·field/list same(잔여 미반영 1 = field_worklog 타 세션). web-designer 3회(총괄 1). devplan C:\dev\devplan\pfs.html DONE 1줄.
- ⏳[페페] ①접힘 당일만 유효 vs 계속 유지 ②비고 텔레그램 알림 여부 ③🔴기존 생산 메모 https://pfs.poin.co.kr/static/uploads/memo/field_memo.json 비로그인 200(전문 노출, 미수정) ④긴 현장명(아이파크 107-2802)은 34% 칸에서 2줄 ⑤빠른 문구 칩·작성자 표시 = 범위 밖.
[코디] 🆕 26.10.7(수) — 원주·안산 개별 원부자재발주서 → 자재관리 정리 ✅운영 #1 r35→r37 · 추가 6 · 조운 수량 4·샘플 삭제 4 · B안 경고 master 82660853 · 자재관리 69→71
[페페] 「원주·안산 개별 원부자재발주서에 추가된 항목 PFS 자재관리에 올려줘 · 항목 제한 걸려서 동기화 안 되는 것 같다 · 상원보드·피앤데코 추가발주건」 + 「운영배포」(코드 변경이 없어 배포 0).
- 원인 = 행 캡 아님. NAS …\10월\한샘 GS 원주 단구 원부자재발주서.xlsx(14:38 KST · md5 a78bd821bc)·…\한샘 GS 안산 성포 원부자재발주서.xlsx(14:38 · a44936f2b0)는 keywords PFS-MAT#1 → orderpaper_parse.parse_file 이 파일째 0블록(설계상 건너뜀) · 16:39 라운드 R1791358754 items 2161 그대로. 표식 무시 파싱 = 추가 6품목 정상 추출(8~11행).
- 반영 = C:\dev\_work\mat-add-1007\amend_add_1007.py amend 1회 16:36 KST 수동 행 6(원주 2169): 상원보드 효산 HS867HD 18T PB 경면양면 4매·4.5T MDF 민자양면 2매(R, 10/12) · 효산엘피엘 HS867HD(UK) 칼라샘플 1EA(진영LDM 10/8)·피스마개스티커 10장(10/13) · 유로글라스 EURO-P-100BXM 5T3942207·5T4072204 각 1EA(봉적 10/15, S — 수동 행은 G 불가) + 입고일 PATCH 6. 백업 = …\mat-add-1007\backup\(#1 r35 GET · 자재관리 pfs_mat 69행).
- 검증 = 자재관리 PFS-MAT#1 69→75(원주 29→35 · 안산 40) · 새 6행 36칸 + NAS 추가 탭 24칸 문제 0 · 기존 69행 칸 변경 0 · 페페가 16:19 수동삭제한 안산 효산 H2041B-L1 18T·4.5T 2행 = 지운 상태 유지 · 16:39 라운드 후 원주·성포 NAS 살아있는 행 0(이중 0).
- 🆕2차 17:43 KST([페페] 답 「엑셀 파일이 현재 정리된 기준 · B안 · 운영배포」, C:\dev\_work\mat-add-1007\reconcile_1007.py · API 만): ①피앤데코 = 페페 재확인(손 안 댐) ②조운IMT 시트 4행 수량·재고 = 현장별 파일값(#6404 원주 PQFA2T 26→50M · #6399 GY123MT 98→120M · #6401 IV075EMT 123→150M · #6403 P9GA4T 21→50M, PATCH /qty(qty_user)+/stock · 소비이력 0) · 칼라샘플 4행 자재관리 삭제(#6411·#6406·#6408·#6410, del_manual 소프트) · 현장 뒤바뀜 0 ③선재 2쪽 = 무시 ④초안 #3 제목 「[확정 금지 · 상원보드 발주로 대체 26.10.7] GS 원주 단구 몸통」(r3 · 품목 무변경 · 삭제 0) ⑤통합본 피앤알 GK102-G8 보드 5줄 비고 = 「E0,PVC · ※ 10.13(화) 입고예정 · 별도 생산」(#1 정정 r36→r37) — 입고일은 자재관리 10/14(사람 값) 그대로 · PW합판·70-115 = 현장별 파일엔 있고 행이 «완료»라 손 안 댐 ⑥B안 = master 82660853(orderpaper_parse mat_check_* + orderpaper_sync MATROWS 회수 → 로그 「[!] PFS 자재 발주서 표식 파일 ↔ 자재관리 차이」 + prod 텔레그램 새 차이만) · 사이트맵 7593e261(추적 밖 · 미반영 6 = 타 세션) · deploy-live 없음(서버가 import 못 하는 로컬 폴더 · 예약작업이 master 작업본 실행 = 85f1ea17 선례).
- 검증 2차 = 대조 32칸 문제 0 · 원주·안산 나머지 237행 칸 변경 0 · 자재관리 PFS-MAT#1 75→71(원주 34 · 안산 37) · 운영 읽기 실측 경고 = 현재 0건 / 반영 전 상태 대입 16건(원주 6추가·조운 수량 4·샘플 4·효산 2) · test_mat_check·test_dedupe·test_date_warnings·test_pfs_link OK · 🆕실제 예약 라운드 18:09 KST(R1791364151) = Success · 「표식 파일 2개 중 0개 · 0건」 · 로그에 MATROWS 줄 0 · _matcheck_seen.json = [] · 라운드 후 PFS-MAT#1 원주 34·안산 37 그대로 · 원주·성포 NAS 살아있는 행 0.
- ⏳ 통합본(동기화제외) 조운IMT 탭엔 칼라샘플 4개가 남아 있다(현장별 파일·자재관리는 지움) · GK102-G8 날짜 = 통합본 「10.13」 ↔ 자재관리 10/14(보드)·10/12(길동 시트) · 「통합 … 중 이 현장 몫」 옛 비고 4행(조운 시트)은 API 로 비울 수 없어 남음(비고 칸 빈값 = 원본 비고로 돌아감).
[코디] 🆕 26.10.7(수) — 생산현황 출력 미입고 보드 자재 = 현장별 그룹 펼침/접기 · 접은 그대로 인쇄 — ✅운영 deploy-live 4a3c12ad+c5ab413e(master 2125ff29 · 사이트맵 81f0eab8)
[페페] QA /field/print/status #oob-body td.site(GS 안산 성포) 「현장별로 자재 그룹화해서 펼침,접기 · 적용한 형태대로 출력 · 운영배포」.
- 파일 = C:\dev\pfs\web\templates\basic\field\field_status_print.html 1개(API 무변경). 그룹 = 현장별 tbody.oob-g, 헤더 행(현장명 13px · N건 · 가장 이른 입고일, 날짜 섞이면 「~」) 클릭/Enter = 토글 · 자재행 = 칼라 colspan2 들여쓰기 · 서브라벨 옆 「모두 접기/펼치기」(no-print) · 기본 모두 펼침 · 상태는 메모리만(localStorage 안 씀) · 접힘 = display:none 이라 인쇄도 그대로 · 인쇄 때 삼각형 숨김 · 헤더 입고일 인쇄 11px(13px 면 6px 넘침).
- 처방 = web-designer 2회 + 총괄 상담. 검사 = C:\dev\pfs\scripts\_memo_split_check.py(미추적, 그룹·접힘·인쇄 단언 추가) 운영 38/38 · 테스트 35/35. 운영 실데이터 15행/3현장(성포 6·단구 4·아이파크 5).
- ⚠경위: 내가 스테이징해 둔 이 파일이 다른 세션 커밋 37a563be(worklog-panel)에 공유 인덱스로 섞여 push → 그 세션이 319beafb 로 되돌림 → 2125ff29 로 정식 커밋. 운영은 이 파일만 선별 포워드라 worklog_panel 섞임 없음.
- ⏳남은 것 = ①펼친 채 인쇄하면 2쪽(종전도 2쪽 · 접으면 줄어듦, 운영 첫 그룹만 접어선 2→2) ②연도표기(12월↔1월) 때 헤더 입고일 「26.10.12(월)~」 인쇄 17px 넘침(자재행도 종전부터 같은 폭) ③실물 프린터·노트20 실기 미확인 ④기존 인쇄 11px(자재행) 하한 예외는 페페 결정 사항으로 그대로 둠.
[코디] 🆕 26.10.7(수) — 견적 v2 QA 묶음 5건 ✅운영 deploy-live 6a11ee17(master 0da95f22·78f2ad9c) — 운영 80/80 · DDL 0
[페페] 09:50 검증보고 #1(새 견적 빈 1줄·+항목추가 왼쪽) #2(추가금액 마진 전역 연동/수동, 기존 견적 고정) + 추가 B1(추가금액 빈 줄+Enter) B2(헤더 twirl 전체 펼침) B3(별도항목 사용처 펼침·이동·삭제) · 「운영배포」.
- 저장 = sub 구체값 그대로, 연동 여부는 화면 세션 플래그(운영 sub NULL 69행 때문에 NULL 규약 불가) · 저장 sub 는 고정으로 로드 · 검사 C:\dev\pfs\scripts\_est_submargin_check.py(테스트·운영 ALL PASS, 쓰기 0) · 사이트맵 미반영 1(타 세션).
- 🆕2차(11:30~11:43 QA 3건) ✅운영: 헤더 twirl 전역 = 현재 탭 모든 행(개별로 연 sub 0건 행이 안 닫히던 버그) 9894a956 · 항목 0건 타입·K/F 화면 = 빈 1줄(_seed, 새 견적 빈 줄과 통합) 426cdcde · 「단품」 분류(가상 U1 · 치수 300 · 견적서 치수 공백 · 단가 직접) a3738ef0 · 운영 110/110.
- 🆕3차 ✅운영 9e9d09b2: 새 견적 추가금액 마진 연동 = 저장 후 재진입 유지(표식 = ui_column_setting est_sublink:<no>, DDL 0 · 표식 없는 기존 견적은 전부 고정) · [페페] 결정 = 단품 INSERT 보류 · 「모두 연동으로」 없음 · 기존 견적 연동 유지 → 미결 0 · 테스트 견적 822(자체검사용) → projects/pfs/session-2026-10-07-estimate-submargin-qa.md
✅ 26.10.6 · pfs-worklog-panel-newcall · 업무패널 통화 = 새 통화만 + 미종결 통화 3,014건 일괄 완료 (운영 bfce51f7)
[코디] 26.10.6(화) 20:10~20:35 KST. [페페] 원문 「업무패널 통화가 안뜨던 항목이 기존 항목을 완료하면 뜬다. 현재 항목들 완료처리하고 앞으로 신규통화만 업무패널에 등록한다. 운영배포」
- 원인 =
C:\dev\pfs\api\pfs\worklog\service\worklog_service.pyget_worklog_panel의 통화 몫take = max(_PANEL_CALL_FLOOR, limit - len(rows))(구 636~639행). 화면 limit 60 − 수기 18 = 42건만regist_date DESC로 잘라 보냈고, 큐 = 미종결 통화 전체(운영 3,014건 · 26.6.15~). 카드를 털면 다음 2분 새로고침에 창 밖 백로그가 한 장씩 밀려 들어왔다 = 「안 뜨던 항목이 완료하면 뜬다」. 새 통화 자체는 regist_date 최신이라 늘 창 안이었다(진단 시점 운영 = 10/6 통화 10건 표시 중). 패널 JS(worklog_panel.html)·worktray 앱은 무관 — 완료는drop()으로 로컬에서만 빼고 다시 안 받는다. - 일괄 완료 = 대상
source='call'·remove_yn<1·진행중 2,083 / 대기 757 / 보류 174·regist_date < T(T = 2026-10-06 20:21:34 KST, 스냅샷 시각 = DB NOW()) 3,014건(전부 review 확정·공개·★/그룹 0·현장연결 517). 앱 경로PATCH /api/worklog/<no>/status {"status":"완료"}· 실패 0 · 75초 · 삭제 0. 수기 18건·카톡 1건(보류, 26.6.14)은 유지. 전후 스냅샷 =C:\dev\_bench\worklog-panel-1006\before_snapshot.json·after_snapshot.json(상태·modify 외 필드 변화 0 · modify_user=1) · 대상 idtarget_ids.json· 진척bulk_done_log.jsonl· 실행기bulk_done.py·snap_driver.py. 롤백 = before 의 status 로 id 별 PATCH. - 코드(master
5e2b27f4→ deploy-livebfce51f7선별 포워드, blob 일치,pfs-live.uwsgi20:28:05 KST 재기동):worklog_dao._PANEL_CALL_SINCE = "2026-10-06 20:21:34"+_new_call_clause()=source='call'은 적재시각 ≥ T AND 통화일(파일명_YYYYMMDDHHMMSS.,REGEXP_SUBSTR) ≥ 20261006 — 옛 녹음 백필·--reload재적재는 regist_date 가 새것이라 둘째 겹이 막는다 · ★·사용자 그룹(pinned 쿼리)은 예외 · 상대목록(select_worklog_party_notes)도 같은 창 · 통화 몫 = limit 대신_PANEL_LIMIT_MAX(200) 전량(_PANEL_CALL_FLOOR삭제). 화면 무변경(web-designer 면제). - 코덱스 상의 1회 반영 = 후필터 → SQL 이전(LIMIT 슬롯 낭비) · kakao 는 하한 제외(통화만) · 스냅샷/컷오프 같은 DB 시각. 「실제 통화시각만 기준」 안은 기각 — 20:22 에 적재된 오후 통화 16건(15:45~18:19 통화)을 잃는다(파이프라인 지연 적재).
- 검증 = 조건 논리시험(리터럴 8행, 운영·테스트 DB SELECT,
clause_test_build.py) PASS_KEYS0,1,4,5,6,7기대 일치(새 통화·지연 적재·번호 파일·audio 없음·수기·카톡 표시 / 백필·백로그 제외) · 테스트 8001 API 변형 7종 PASS · 운영https://pfs.poin.co.krAPI 변형 8종 PASS(api_variants.py prod) = total 34(수기 18 + 새 통화 16 · 컷오프 전 통화 0) · 완료 필터 = 통화 5(컷오프 후)뿐. 첫 요청 6~7초는 배포 전과 같음(7.12초 실측, 워커별 첫 호출). - 사이트맵 재빌드
1e59c6d0(menu_dump) — 미반영 1 =field_worklog.html(타 세션), worklog 패널 파일 master=live. - 남은 것 = 미종결 새 통화가 200건을 넘으면 같은 밀려들기 재발(페이지 나눔 없음) · devplan
worktray-panel.html17차 절은 서브에이전트에서 ruleguardweb-designer-required훅에 막힘(상담은 끝남) → 붙일 본문 =C:\dev\_bench\worklog-panel-1006\devplan_p17_snippet.txt.
✅ 26.10.6 · pfs-handoff-roll-1006c · pfs handoff 캡 이관 (26.10.1~6 절 9개)
[코디] 26.10.6 pfs handoff 캡 관리 2차(22,413자 > 20,000자) — 21~57행 절 원문 그대로 이관. handoff 엔 상태·카운터 포인터만.
[코디] 🆕 26.10.6(화) — 자재 발주서 #1 QA: IV075EMT 펫시트 업체 길동상사 → 조운IMT — ✅운영 fb7c9dd6(master 7e236bc6·사이트맵 e94164aa) · push 12:16 KST
[페페 QA] 표 tr.mo-row:nth-of-type(55) 업체칸(길동상사) 「조운IMT로 변경, 관련해서 샘플 발주도 업체 동일 변경 · 운영배포」. 55번째 tr = 줄마다 tr 2개(mo-row+mo-alloc) → seq 순 28번째 줄 = IV075EMT 펫시트(업체별 보기면 55 는 배분 행이라 해당 없음). 페페 NAS 최종본(12:08)도 오엠씨 탭 J14·조운IMT 탭으로 같은 변경 → 범위 확정.
- 코드 = amend 에 vendor_confirmed 허용(비울 수 없음 · 확정 문서는 그 품목 자재관리 행 중 status≠대기 있으면 거절 · 수량·여유·현장 잠금 유지). 화면 무변경.
- 운영 #1 r32→r33 = 시트 1행 업체만 · 자재관리 #6401(성포 123M) vendor 조운IMT · 새 행 0(50행). 칼라샘플(seq34)·엣지 비고 「샘플:조운IMT」 는 원래 조운IMT → 무변경. 검증 = 단위 72/72 · 테스트DB 27/27 · 운영 되읽기 11/11 · 사이트맵 amend same. 스크립트·백업 C:\dev\_work\mat-door-1006\joun_*.
- ⚠NAS 최종본 ↔ DB 남은 차이(파일 무수정 · 다음 몸통 통합 세션 참고): 효산 보드 규격 「LPM 양면」→파일 「경면양면」·「민자양면」(비고 E0,246경면) · 파일에만 H2041B-L1 피스마개 스티커 10장 · 피앤알 보드 비고 파일 「E0,PVC」 · GK102-G8 피스마개 비고 「남는시트 사용」 · 입고일 파일 오엠씨·선재 10/12 · 길동·조운 10/7(DB 헤더 10/8) · 타입 칸 「원주:주방3, 안산:주방5」.
[코디] 🆕 26.10.6(화) — 부자재 발주서 엑셀 「복구 필요」 수정 — ✅운영 a9d8f6e8(master 80fb3e21)
원인 = sub_orderpaper_excel.py wb.views.sheetView[0] 없는 속성 → 시트 1장 다운로드 시 firstSheet 인덱스 초과 = Excel 복구 → for view in wb.views: 로 수정. ⚠템플릿 assets\sub_order_template.xlsx 자체는 firstSheet=1(안 고침) · 옛 파일은 재다운로드. (원문: archive.md 「✅ 26.10.6 · pfs-handoff-cap-1006b」)
[코디] 🆕 26.10.6(화) — 자재 발주서 #1 도어재 통합 발주 마무리(NAS 통합 발주서 + 운영 DB 정정 amend API) — ✅운영 f9a39f8f(master 4ce3c1b2)
POST /api/mat-orderpaper/<no>/amend 신설 · 운영 #1 r30→r32 · NAS …\원부자재발주서\10월\통합발주(동기화제외)\(도어재통합)…xlsx · 로컬 C:\dev\_work\mat-door-1006\out\. 애매점 7건(추천 처리)은 원문 참조.
✅26.10.6 14:10 해소(위 「도어재+몸통재 통합 1단계」: 파서 MAT 85f1ea17 + 파일 이동 → 93행 내림) — 옛 기록: NAS 10월\자재발주서_1_GS 원주 단구 외 1곳 도어_확정.xlsx 를 동기화가 자재관리에 93행 이중 적재 → 파일 하위폴더 이동 + 93행 내림(목록 C:\dev\_work\mat-door-1006\finding_nas_junk_rows.json, 파서 PFS-MAT 인식은 orderpaper-sync 소유 세션 몫). (원문: archive.md 「…cap-1006b」)
[코디] 🆕 26.10.6(화) — 네스팅 저장본 통합 열기 + 복수 현장 — ✅운영 792ea1cc·3b63b940(master 23c38436)
⚠남은 것: devplan pfs-nesting-order-draft.html §1 진행표 ③④⑤ 배지 미갱신(ruleguard web-designer-required 로 막힘) · 통합 시 옵션 = 대표(첫 체크) 값 · 테스트 DB 시드 #42~#45 잔존 · 운영 #17·#18 은 페페 쪽에서 계속 수정 중. (원문: archive.md 「…cap-1006b」)
[코디] D1 자재 발주서 모듈(26.10.5) — ✅운영 반영 26.10.6 01:01 KST 5b1173c9(master f4763a89·b360a9d3) · 품목군별 업체 일괄 지정 ca2c133d
✅26.10.6 파서 MAT 확장 85f1ea17(정확히 PFS-MAT#n 이면 건너뜀) — 옛: orderpaper-sync/orderpaper_parse.py:359 가 MAT 모름 → 확장 전 D1 엑셀을 NAS 월 폴더에 넣으면 이중적재(요청 = CONTRACT.md 「D1 요청 (2차)」 8건). ⏳페페 결정 3건(같은 원장키 덮어쓰기 · 엑셀 표식 · 규칙표 수정권한) · ⏳NAS 업체탭 양식 · 노트20 실기. 포인터 C:\dev\_work\order-draft-1005\D1-plan.md · devplan pfs-mat-orderpaper.html. (원문: archive.md 「…cap-1006b」)
[코디] 🆕 26.10.5(월) — 네스팅 → 원부자재발주서(도어) 초안 파이프라인 + 복수 현장 연결 — 그릴링 Q1~Q10 후 D1 로 진행(위)
🔴10.2 몸통 발주서가 운영 자재관리에 잘못 적재(합산본이 원주 카드에 중복 · 성포 몸통본 field 251 오연결, 파일명 꼬리 (몸통) 파싱 실패) — 정리는 별건 승인. (원문: archive.md 「…cap-1006b」)
[코디] 🆕 26.10.5(월) — GS 원주 단구·안산 성포 마감재 네스팅 수량 합산 + 결방향 세로 통일 → 운영 새 작업 #17(31장)·#18(42장) — 코드 변경 0
⏳[페페] 애매점 5건: ①「타입」=부재표 타입 칸(무시 시 원주 89행·성포 129행) ②길이 교환은 원장폭 초과만(「긴 변=결」이면 성포 41장) ③양단면은 키에 포함 ④#14·#15·#16 삭제/보관 ⑤NAS 산출물 갱신 안 함. 백업·스크립트 C:\dev\_work\gs-finish-nesting\merge-grain-261005\. (원문: archive.md 「…cap-1006b」)
- ✅ 26.10.5 저장본 열기 모달 폭 확대 42c8bed1 · 부재 표 헤더 겹침·ID 칸 클릭 확인 표시 6c28441e · [↔] 가로·세로 바꾸기 + 인라인 검색 82ae4394 (원문: archive.md 「…cap-1005b」·「…cap-1005c」)
[코디] 🆕 26.10.4(일) — 네스팅 부재 표 ID 칸·정렬·필터·조건 세트 서버 저장 — 운영 5a3dfceb 완료 (⚠기존 저장본 #1~15 는 ID 없음 · 원문 archive.md 「…cap-1005d」)
[코디] 🆕 26.10.1~2 GS 계열 작업 묶음 — 전부 코드 변경 0(②만 코드) · ⏳[페페] 판단 대기는 원문(archive.md 「…cap-1005d」·「…cap-1006b」)에서 확인
- 26.10.2 GS 안산 성포 MH 769 → 한샘 견적 6(form 14) 갱신 · ⏳6건(
session-2026-10-02-gs-ansan-seongpo-hansem.md) · devplanhansem-estimate.html절 17 미삽입(C:\dev\_work\gs-ansan-seongpo-1002\devplan_s17.txt) - 26.10.2 GS 원주·성포 몸통 원부자재발주서 3종 NAS 업로드 · ⏳확인 9건 · 🔑함정
momtong_order.write_tab17건 초과 소실 - 26.10.2 GS 원주·성포 마감재 네스팅 #14·#15·#16 + NAS · ⏳#15 삭제/보관·Q5~Q10(
session-2026-10-02-gs-finish-nesting.md· devplangs-finish-nesting.html) - 26.10.2 네스팅 도어 부재 PNCAD 작업본 섞임 방지 운영
320e17a6· ⏳4건(#8 분리 여부 · GS 새 저장본 · devplanpfs.htmlDONE AX 줄 미삽입C:\dev\pfs\_restore\nesting_gs_2026-10-02\devplan_done_AX.txt) - 26.10.2 GS 대전 도마변동 2차(포인 787) → 한샘 견적 10(form 9) · ⏳4건(−4,000 절사 · 이름 정정 · 걸레받이 «무상» · 부속 매핑)
- 26.10.1 GS 대전 도마변동(포인 785) → 한샘 견적 9 · ⛔NAS 교체 보류(손수정본) · 🔴운영 form 3·4 출력에 「임서현」 도장+GS 안산 도면 실림(재발행 판단)
- 26.9.30 GS 안산 성포 도면 → 자재 초안 운영 등록(spec_no 6·186칸) · ⏳검수 24건·미등록 칼라 4종 · 견적 초안 769/한샘 6 →
session-2026-09-30-gs-ansan-matspec.md - 26.9.30 학동매장 도어발주서 초안 NAS 게시 · ⏳확인 8건 + 사람이 쓰는
한샘 학동매장 도어발주서.xlsm과 정본 선택 →session-2026-09-30-hakdong-door-draft.md
✅ 26.10.6 · root-handoff-roll-1006b · 루트 HANDOFF 이관 (26.9.7~9 ✅ 3절)
[코디] 26.10.6 루트 HANDOFF 캡 관리 — ✅ 26.9.7~9 3절 원문 그대로 이관.
✅ 26.9.9 KST — GS 원주 단구 한샘 견적서 84A(기본) 추가 + 부자재 분리 (운영배포 5d9bd2f+7cb6ea1)
페페 수작업 NAS 파일을 직접 수술(그릴링 4문 결정) — 84A→84A(옵션) 개명 · 84A(기본) 탭 신설 ·
탭 순서 재배치 · 숨김행 13개 삭제 · 갑지 #REF! 정리 · 본블록에 섞여 있던 부자재를 제 블록으로 분리.
기존 3탭 총합은 원 단위까지 불변(9,470,280 / 6,167,851.2 / 7,311,951.2)이 「수식·합산 유지」의 증거다.
산출 = NAS …\GS원주단구2BL\1.생산비 거래명세서_GS 원주 단구 MH_26년 09월.xlsx(8월 원본 보존) ·
PFS 한샘 estimate_no=7(총액 29,109,099, 옛 V1·V2 보관처리) · 갑지 총계 36,000,000.
🔴덤 = 운영 결함 — 양식의 오픈장·키큰FIX·공틀도어 블록엔 단가 LOOKUP 이 한 칸도 없어 금액이 조용히 0
(공틀도어 3탭 1,715,622원 누락). 같은 단가군에서 베끼고 배수 재부착으로 고쳤다.
✅26.9.7 미결이던 api/pfs/hansem/ 운영배포도 이걸로 완료 — 안산 성포 견적 엑셀이 서버총액과 정확히 일치하게 됐다.
검증 = PFS 왕복 30/30 · 운영 엑셀 재계산 차 0원.
🔴정정(같은 날) — NAS 9월 xlsx 는 Excel 이 못 연다(페페 제보 「복구하시겠습니까」).
자체검사 100/100 이 통과했는데도 깨져 있었다 → Excel 본인이 유일한 정본 판정기다(probe 도구 신설).
확정·수정한 결함 2건 = docProps/app.xml 개수·이름 불일치 · 블록명을 B{b} 에 쓴 것(규약은 C{b}).
남은 1건은 fill_main/fill_sub 안으로 좁혀 놓고 인계. PFS 견적 7 과 운영배포는 정상(별개 경로). 상세 = projects/pfs/handoff.md · 함정 5개 = projects/pfs/rules.md 🆕 맨 위.
✅ 26.9.7 KST — PFS 발주서 정리 탭 모바일 전용 레이아웃 (운영배포 12e8efb 완료)
페페 「/field/orderpaper 발주서 정리탭을 이번 업체별 자재관리 탭처럼 모바일 전용 페이지로.
필터가 매우 많으니 모아서 기본 접힘, 인라인 검색만 기본 노출. 동기화 강조는 안 넣어도 된다. 운영 배포」.
산출 = 파일 1개(field_orderpaper.html) · 라우트·템플릿 신설 0 · DB 변경 0. master a9b4914 → 운영 12e8efb(선별 포워드).
🔑「모바일 전용 페이지」 = 별도 라우트가 아니다 — 「업체별 자재관리처럼」이 방식 지정이고 그건 같은 파일 @media 카드형이다
(26.9.4 에 모바일 전용 목업을 이미 폐기했다). 🔴같은 템플릿을 세 라우트가 공유(뒤 둘은 어제 운영배포)라
{% if not omc_view %} 로 CSS 를 통째로 갈랐다 — 운영 HTML 마커 개수로 실증(7 vs 1).
접으면 검색 + ⚙필터(배지) + 적용칩·건수만 남는다. 날짜경고는 안 접는다(필터가 아니다).
검증 = 정적 24/24 · 테스트 34/34 · 오엠씨 회귀 24/24 · 운영 읽기전용 34/34 ALL PASS · 사이트맵 미반영 1(별건).
🔴중간에 한 번 깨뜨렸다 — CSS 주석 안 Jinja 태그가 테스트서버 세 화면을 동시에 500 으로. 정적검사가 잡아 2분 복구, 운영엔 안 나갔다.
⏳페페 = 노트20 실기 육안 1회. 상세 = projects/pfs/handoff.md · 함정 5개 = projects/pfs/rules.md 🆕 맨 위.
-
박광은(enex5983) 담당자 등록 + 오엠씨 권한 「이 사람만」(운영 데이터, 코드변경 0) — 완료 (상세: projects/pfs/archive.md)
-
GS 안산 성포 한샘 양식 재작성 A~G(운영 등록 + NAS 저장) — 완료(운영배포 판단건은 26.9.9 GS원주단구 절에서 완료 처리됨) (상세: projects/pfs/archive.md)
-
PFS 사용자 등록 ↔ 거래처 담당자 연동(운영배포
08f5aa5) — 완료(박광은 명부등록건은 같은 날 「박광은 담당자 등록」 절에서 완료 처리됨) (상세: projects/pfs/archive.md)
✅ 26.9.7 KST — PFS 업체별 자재관리 페이지 + 거래처 계정 감사 로그 — http://100.108.234.45:8799/pfs-company-material-page.html
페페 「omc/material 기준으로 타업체 자재관리 페이지 생성. 사이드메뉴는 아이비젼글로벌처럼 업체명 직링크. 내부 구조는 완전 동일, 필터만 업체 다르게. admin/company-permission 에 옵션 추가해 체크한 업체는 자동 추가」 + 「거래처 아이디는 내가 직접 만든다. 접속·CRUD·타페이지 접속 시도까지 보안 고려해 로그 기록 시스템도」.
산출 = master c49fa17(15파일 +496/−46) → 운영배포 b85b1bd 완료(26.9.7 페페 채팅 승인 「확인 완료 운영배포 진행」).
새 화면 = /field/company/<업체번호>/material — field_orderpaper.html 을 mat_vendor 만 바꿔 재사용(화면 로직 중복 0).
🔑그릴링 5문 페페 결정 = ①둘 다 켜면 업체명이 접이식 그룹(오엠씨 방식) ②시트(T)+입고처 빈값 특례는 오엠씨 전용(타업체에 주면 미기재 시트가 모든 업체 화면에 중복) ③admin 은 생성/삭제 버튼쌍 ④all-items 서버측 업체 필터 건다 ⑤거래처도 편집 가능(오엠씨와 동일).
🔴보안 3중 게이트(②③은 페페 새 지시로 추가) — ①all-items 서버 스코프 ②발주서 쓰기 허용목록
(status·receive-date·note·qty·item-name + 자기 발주처 행만, 나머지 403) ③/field/company/<no>/material
라우트에서 메뉴 권한 직접 확인. 가시성 판정 = orderpaper_service.item_visible_to 단일 출처.
감사 로그 = 기존 audit_log 재사용(스키마 변경 없음), access_page·api_write·api_denied·access_denied·logout.
검증 = 자체검사 54/54(scripts\_company_material_page_check.py — 메뉴 상태기계 4조합 SQL 순서·스코프·게이트·마스킹) ·
테스트서버 실측 23/23(scripts\_company_material_page_live.py — 글로벌아이비젼 452 로 생성→그룹화→해제까지, 테스트 DB 원상복구 완료) ·
운영 읽기전용 23/23(scripts\_company_material_page_prod_ro.py — 쓰기 0건, 관리화면 블록·material-page GET·/omc/material 회귀·감사로그 옵션) ·
사이트맵 재빌드 미반영 29→1(미반영 «화면» 0 · 남은 1은 도구·워크플로 등 화면 밖 파일) · 허브 카드 pfs-company-material 등록(최근 2개소 실측 확인).
🔑배포 반영 판정 = /api/health 가 401 login_required → {"env":"live","ok":true} 로 바뀌는 순간이 새 코드 증거다
(운영은 REVISION 파일을 안 써서 rev 가 빈 값이다 — sha 대조는 못 한다). 선별 포워드 전제도 만족했다 —
15파일 중 14개는 선행 diff 0, web/__init__.py 만 2줄(= 26.9.4 /api/health 신설분)이라 그것까지 같이 반영했다.
🔴새 함정 5개(projects/pfs/rules.md 🆕 반영) — ①URL→menu_key 는 정확매치 실패 시 최장 prefix 로 떨어져
상위 페이지 권한을 탄다 ②PFS h3 제목·breadcrumb 은 전역 CSS 로 항상 숨는다(pfs_layout.css:55) →
업체 표시는 .op-omc-who 배지로 ③템플릿 조건부 마크업을 클래스명 문자열로 검증하면 CSS 정의에 걸려 전부 오탐
④Jinja |tojson 은 ensure_ascii 라 한글이 \uXXXX(기능은 정상, 검증만 실패) ⑤메뉴 재구성은 부모 먼저·해제는 자식 먼저.
⏳페페 다음 행동(운영배포는 끝났다) = ①거래처 아이디 생성 ②업체 권한화면에서 「자재관리 페이지 생성」 토글
③그 계정으로 로그인해 업체 배지가 자기 업체인지 육안 확인. ⚠업체명이 발주서의 발주처 문자열과 정확히 같아야 행이 잡힌다.
⚠미적용 처방 1건 = 사이드바 접이식 화살표(.fa arrow)가 렌더 0×0 으로 죽어 있다(리포 전체 .arrow CSS 0건,
기존 「현장 기록」·오엠씨도 동일한 기존 결함) — 고치면 사이드바 전체 시각이 바뀌어 페페 눈 확인이 먼저다.
✅ 26.10.6 · root-handoff-roll-1006 · 루트 HANDOFF 이관 (26.9.23~29 절 10개)
[코디] 26.10.6 루트 HANDOFF 캡 관리(44,905자 > 30,000자) — 끝난 절 원문 그대로 이관. 루트엔 포인터만 남김.
- [코디] 🆕26.9.23 18:40 pfs 배차 「계산서 사진」 4건 — 운영배포
3178216완료([페페] 검증보고 + 「운영배포」) — 버튼 끝 「사진 3」 · 썸네일 클릭 라이트박스 확대(좌우·카운터·ESC) · 배차 등록에서도 첨부(대기열 → 저장 때 일괄 업로드) · 삭제 복구. 🔑지시 4건 중 3건이 한 뿌리 =initPhotoDropzone()이#dcPhotoGrid한 곳에만 묶여 있어 목록 사진모달의#dcPhotoGrid2가 죽은 요소였고(삭제 코드는 원래 있었다, 안 보이는 그리드에 그려졌을 뿐) 전역 배차번호가 −1 로 새어 등록/수정 업로드가dispatch/-1/photo로 갔다 → 컨텍스트별 컨트롤러 2벌 + 클로저 번호. 검증 = 테스트 E2E 19/19 · 운영 읽기전용 8/8 · 사이트맵/dispatch/listsame. 🆕2차 22:3x — 숫자를 「빨간 원 + 흰 글씨」 배지로 · 운영f612c90([페페] 「눈에 잘 안 띈다」 + 「운영 배포」) —#c6282820px 원 + 흰 글씨 13px + 흰 링 2px(초록 버튼 위 빨강은 인접대비 1.3:1 이라 링 없으면 안 보인다) · 2자리↑ 알약 자동 · 0장이면 없음. 덤으로 행 액션 5버튼 12→13px 하한 충족 + 높이 맞춤(align-items:stretch). 2차 검증 = 테스트 E2E 19/19 · 운영 13/13(1280~1680px 한 줄). 🆕3차 — 썸네일 «다운로드» 버튼 + 배지 2px 축소 · 운영998dcfd([페페] 지시 + 「운영배포」) —<a download>한 줄(같은 오리진 정적파일이라 JS·서버 변경 0) · 삭제(×) 옆에 안 붙이고 대각 배치(좌상단 다운로드 / 우상단 삭제) + hover 파랑·빨강 · 파일명 =original_name(escAttr필수 — 따옴표 하나에 속성이 깨진다) · 사진모달·등록/수정·행 상세패널 3곳, 저장 전 대기 사진은 제외 · 배지 20→18px(글씨 13px 유지). 3차 검증 = 테스트 E2E 22/22(실제 저장·파일명 원본 포함) · 운영 16/16 ·99+잘림 0. 🆕4차 — 다운로드를 «썸네일 하단 배너」로 · 라이트박스 아무데나 닫기 + 다운로드 · 운영d18e5ad([페페] 지시 + 「운영배포」) — 코너 22px 원 → 하단 전폭 26px 배너(#2f74c4흰 글씨 4.76:1) · 대기 배너도 26px 로 정렬 · 라이트박스는closest('button,a')아니면 어디를 눌러도 닫힘(⛒그래서 그 안 새 컨트롤은 반드시 button/a) · 좌상단 40px 다운로드 + 썸네일과 같은 파일명(dcLbOpen(urls,idx,names)). 4차 검증 = 테스트 E2E 29/29 · 운영 19/19. ⏳범위 밖 3건(택배 모달 사진 없음 · 삭제 후 파일 잔존 · 썸네일 최신순) + 안 넣은 제안 2건(모달 「전체 다운로드」 · 라이트박스 회전) +.dc-btn-danger대비 3.49:1 AA 미달. 상세 =projects/pfs/handoff.md맨 위 · devplanpfs-dispatch-photo.html. - [코디] 🆕26.9.23 D1 완료 — pfs worklog 추정현장 Jev 폴백: 오프라인 측정 결과 «안 켠다» → 서버 구현 보류(pfs 코드 0줄) — Jev 723호출 · 입력 575,667토큰 · 429 0. 설계 임계 0.90 에서 보류 686묶음 자동연결 0건, 정답 p 0.45~0.93 / 오답 p 0.43~0.85 겹침, 패널 칩 0.60 정밀도 55%. 「해당없음」 은 94.6%. 판단① 패널 쓰레기 칩은 이미 운영 반영(26.9.22 A안). ⏳[페페] = ①보류(추천) ②「현장 아님」 신호로 숨김 검토 목록 ③꺼진 채 구현 중 선택. 상세 =
projects/pfs/session-2026-09-23-worklog-jev-measure.md· devplanpfs-worklog-jev-autolink.html§12. - [코디] 🆕26.9.23 D2 완료 — pfs 발주서 dedupe 경계만 Jev(적용, 결과 현재와 동일) · intake-check 명세서 대조 Jev(28/28 정답 → [페페] 「반영 켜라」 켬) — pfs
bd9c790· tools33e4209+a0d35ef. ⏳코디 = 첫 Jev 반영분 verdict 대조. 상세 =projects/pfs/handoff.md맨 위 · devplanpfs-orderpaper-jev.html. - [코디] 🆕26.9.23 [페페] Jev 적용 5건 「진행」 — 분배 인계문만 작성, 세션 미개설(relay
[STOP] 대상 창을 못 찾음·cody-bridge\windows.json={}). 인계문 =C:\dev\_work\jev\dispatch\d1~d4.md(D1 pfs worklog · D2 pfs 발주서 dedupe 경계+intake-check · D3 한샘 운임↔배차 · D4 poin-agent pfs_done). 공용 래퍼C:\dev\tools\jev.py실호출 OK(jev-1.13.0). 🔴questions는 dict =projects/pfs/rules.md🆕 맨 위. ✅16:26 KST 4세션 분배 완료(사무실PC 원격 창 · D124a9977copus/xhigh · D2c6ad8d34· D37736d4ff· D43166dd65opus/high, 전부 응답 확인) — 그 전에 릴레이 트레이 문제·원격PC 새 세션 구축 완료(devplansession-relay.html26.9.23 절). - [코디] 🆕26.9.23 pfs 발주서 중복 항목 전역 정리 + 자재관리 표시 6개월 — 운영배포
a392b6c완료(master5ab793d). 중복 원인 = NAS 윈도우 복사본 파일(옛판)·마커 변형 파일 복제·같은 파일 섹션 반복 → 동기화 파싱 직후dedupe()로 블록 단위 제외(가역, 드라이런 37블록/106항목). 복사본 중 2개는 진짜 별도 발주라 살림. 6개월 = 렌더 실측 4.0→4.9ms. ✅NAS 복사본 정리 완료(13:46) — 피앤알 7.9 발주를 원본 맨 뒤 장으로 이관(상태완료유지) · 효산 9.16 은 이미 수동삭제·상원보드로 재발주돼 이관 안 함 · 복사본 2개 →\\192.168.0.101\공유폴더\2026현장\원부자재발주서\_복사본보관\. 상세=projects/pfs/handoff.md맨 위 · devplanpfs-orderpaper-dedupe-6mo.html. - [코디] 🆕26.9.23 pfs 날짜 고침 패널 + NAS 엑셀 되쓰기 — 운영배포
c38433b+c2f3242완료([페페] 「확인. 운영배포해」). 자재관리·발주서 정리 상단에 「⚠ 발주서 날짜 점검」 패널(날짜 없음/오기입 42블록), 거기서 날짜를 고치면 NAS 엑셀 원본에 써 넣는다(미니PC 사이드카). 엑셀이 열려 있으면 닫힐 때까지 재시도하고 1시간 넘으면 파일명을 텔레그램으로. 🔴openpyxl 재저장 금지 함정 — 프린터 설정 등 8파트가 날아가서 zip 시트 XML 1장만 치환하게 짰다(손실 0). ⏳[페페] = 테스트 육안 1회 → 운영배포 판단. 상세=C:\dev\seedchain\projects\pfs\handoff.md맨 위 · devplanpfs-orderpaper-sync-ssm-limit.html. - [코디] 🔴26.9.23 pfs 자재관리 동기화가 20시간 전량 먹통이었다 — 고쳐서 운영배포
93d7ce1완료. 「엑셀 수정분이 반영 안 된다」의 범인은 파싱이 아니라 SSM SendCommand 97KB 한도(현장이 늘어 b64 99,036B) — 9.22 13:39~9.23 09:41 30분마다 실패했는데 예약작업이 wscript 라 LastTaskResult=0 으로 떠서 아무도 몰랐다. 조치 = 청크 전송·원격 파일명 고유화·크기 대조 가드·실패 시 텔레그램. 나진 상가 새 탭 「코파산업」 포함 밀린 12건 적재 확인(alive 2,158행). ⏳[페페] = 날짜 미기입 55블록(숨김 23) 정리 여부 · 육안 1회. 상세=projects/pfs/handoff.md맨 위 · devplanpfs-orderpaper-sync-ssm-limit.html. - [코덱스] pfs AL발주서 차수 탭·행선택 복사/이동 운영배포 완료 — master
1a995a4, 운영c02bd4f; 테스트 UI 10/10+DB E2E 5/5, 운영 UI 10/10. 상세=projects/pfs/handoff.md맨 위.
✅ 26.10.6 · pfs-handoff-cap-1006b · handoff 캡 이관 (26.10.6 부자재 엑셀 복구·도어재 통합 발주·네스팅 통합 열기·D1 모듈 · 26.10.5 네스팅 합산·결통일 · 26.10.1~2 GS 계열 · 26.9.28~30 묶음)
[코디] 26.10.6 handoff 캡 관리 2차 — handoff 10~103행 절 원문 그대로 이관(handoff 엔 요약+미결만 남김). 아래는 원문 그대로
[코디] 🆕 26.10.6(화) — 부자재 발주서 엑셀 「복구 필요」·양식 깨짐 수정 — ✅운영 완료 master 80fb3e21(+사이트맵 14a2e3ad) → deploy-live a9d8f6e8(1파일) · 운영 반영 11:29 KST
[페페] 11:14 「발주후 엑셀 다운로드 → 복구 요구, 데이터는 살았는데 셀크기·비율 깨짐. 수정보완·운영배포」(운영 #6 부산·선재기업 1업체).
- 원인 = C:\dev\pfs\api\pfs\sub_orderpaper\sub_orderpaper_excel.py 옛 219행 wb.views.sheetView[0] — 없는 속성이라 firstSheet 리셋이 26.9.15 신설 때부터 한 번도 안 돌았다. 템플릿 firstSheet=1 → 시트 1장(업체 1곳 전체 다운로드 · 「이 업체만 출력」 전부) 이면 없는 인덱스 = Excel 복구. 26.9.14 AL발주서에서 이미 잡은 함정(rules.md L181)인데 가드를 잘못 써서 무력. codeName 중복(Sheet3)은 무관(이분 실측).
- 고침 = for view in wb.views:(BookView 목록) · 회귀 = _demo() 에 firstSheet·activeTab < 시트 수 검사(옛 코드 = 1업체에서 실패 A/B 확인).
- 검증 = Excel COM(Session 1 schtasks /IT·pythonw): 배포 전 운영 #6 Open 실패 → 배포 후 운영 재다운로드 #6·#3·#3「세바」개별 정상 열림, 열너비 6.0/7.0/9.33/8.56/8.67/8.0/7.22…·행높이 60/25/…·인쇄영역 A1:J29·가로 1페이지 = 템플릿과 동일. 사이트맵 그룹 8·페이지 62·미반영 1(= /field/worklog 타 세션), sub-orderpaper same.
- ⚠남은 것 = 템플릿 assets\sub_order_template.xlsx 자체도 firstSheet=1(1시트)이라 단독으로 열면 복구 요구(산출물엔 영향 없음, 안 고침) · 이미 받은 옛 파일은 다시 받아야 한다.
[코디] 🆕 26.10.6(화) — 자재 발주서 #1 도어재 통합 발주 마무리: NAS 통합 발주서 + 운영 DB 정정(신규 amend API) — ✅운영 완료 master 4ce3c1b2(+사이트맵 21e1ac8a) → deploy-live f9a39f8f(5파일 blob 일치) · push 11:25 KST · 운영 #1 r30→r32
[페페] 「1차 원주 단구·안산 성포 통합 마무리 · 도어재 발주건 제목 표시 · 통합 발주서 파일 먼저 · GK102-G8=PVC · H2041B-L1=LPM(시트 없이 보드 직접) · PQFA2T=PVC · 피앤알 입고 시트 2분할 권취 필수 · 보드 비고 E0 만 · 엣지 샘플:업체 · 피앤알 칼라 피스마개스티커 1세트 · DB 동일 반영 · 운영배포」
- ✅파일(11:18 KST) = NAS \\192.168.0.101\공유폴더\2026현장\원부자재발주서\10월\통합발주(동기화제외)\(도어재통합)한샘 GS 원주 단구+GS 안산 성포 원부자재발주서.xlsx(새 하위폴더·새 파일·왕복 md5 일치) · 로컬 C:\dev\_work\mat-door-1006\out\ · 작성기 orderpaper-sync\nesting_draft.build 재사용(row_note·qty_text·memo 만 프로세스 안에서 교체) · 탭 = 오엠씨·피앤알·효산엘피엘·길동상사·조운IMT·선재기업 · 키워드 PFS-MAT#1. 규칙 단일 출처 C:\dev\_work\mat-door-1006\door_rules.py(파일·DB 같은 계획).
- ✅코드 = POST /api/mat-orderpaper/<no>/amend(초안·확정 · 제목·비고·규격·입고처 + 수동 행 추가 · 수량·여유·업체·현장 칸이 오면 거절 · 확정 = sync_multi 로 자재관리 같은 행 갱신 · 판이력 reason 「정정」) · qty_text 「세트」 · D1 엑셀 비고 = note 만(calc_note → 맨 끝 「계산 근거」 열, web-designer 처방 10pt #475569). 화면 무변경.
- ✅운영: LPM 시트 소프트삭제 1(자재관리 −1) → 정정 45칸(보드 24 비고 E0 · H2041B-L1 보드 규격 「LPM」 2 · 시트 GK102-G8/PQFA2T 펫→PVC · 피앤알 컬러 시트 3행 입고처 오엠씨→피앤알 + 비고 2분할 · 엣지 7 「샘플:<칼라샘플 업체>」 · 제목 「(도어재) GS 원주 단구+안산 성포 통합 발주」) + 피스마개스티커 3행(1세트·피앤알·포인 입고) → 자재관리 48→50행(전부 대기). 백업 C:\dev\_work\mat-door-1006\backup_*.json.
- ✅검증: 단위 72/72 · 테스트DB 정정 28/28 · 소프트삭제 회귀 32/32 · test_pfs_link OK · 운영 되읽기 23/23(DB=계획 52줄 전 칸 · 자재관리 · D1 엑셀↔DB) · NAS 파일↔DB 재생성 셀 차이 0(인쇄 밖 메모 판번호 1칸) · 사이트맵 amend same(잔여 미반영 1 타 세션).
- ⚠애매점(추천으로 정함): ①「피앤알 입고 시트」 = 보드 업체가 피앤알인 컬러(GK102-G8·P9GA4T·PQFA2T) 시트 → 입고처를 피앤알로 바꿈 ②샘플 발송처 = 그 컬러 칼라샘플 줄 확정 업체(IV075EMT 만 시트 길동상사 ≠ 샘플 조운IMT) ③GK102-G8 피스마개 현장 = 보드 배분 큰 원주(11 vs 10) ④LPM 보드 규격에 「LPM」 삽입(18T PB LPM 양면 · 4.5T MDF LPM 양면 — 4.5T LPM 가능 여부는 10.2 미결) ⑤오엠씨 탭엔 비고 칸이 없어 오엠씨 보드 E0 는 DB 에만 ⑥자재관리 시트·엣지 비고 앞 「통합 N 중 이 현장 몫」은 기존 D1 규칙대로 남음 ⑦칼라샘플 H2041B-L1(효산) 유지.
- 🔴발견(미처리·승인 필요): NAS 10월\자재발주서_1_GS 원주 단구 외 1곳 도어_확정.xlsx(11:02 저장, D1 목록형 엑셀)를 동기화가 11:09 KST 에 읽어 자재관리 93행 이중 적재(가구업체 「자재발주서_1_GS」 · 현장 미연결 · 전부 대기) — 목록 C:\dev\_work\mat-door-1006\finding_nas_junk_rows.json. 정리 = 그 파일을 하위폴더로 이동 + 93행 내림(파서 PFS-MAT 인식은 orderpaper-sync 소유 세션 몫).
- ✅ 26.10.6 자재 발주서 자재 확인표 탭·품목 소프트삭제/복구·보드 소요 게이지 — 운영
7c352be5완료(patch58) · ⚠애매점 5건(위치 미지정·게이지 95% 등) (원문: archive.md 「✅ 26.10.6 · pfs-handoff-cap-1006a」) - ✅ 26.10.6 배차목록 출고요청서 미리보기 주소·연락처 행 연노랑 — 운영
c4d2a339완료 (원문: archive.md 「✅ 26.10.6 · pfs-handoff-cap-1006a」)
[코디] 🆕 26.10.6(화) — 네스팅 저장본 통합 열기 + 복수 현장(c7b31265) 운영 반영 — ✅운영 완료 master 23c38436 → deploy-live 792ea1cc(c7b31265 네스팅 4파일)·3b63b940(통합 열기) · push 09:21 KST · 운영 쓰기 0
[페페] 「네스팅에서 2개 현장 통합열기가 가능하게 해줘. 저장본 열기 할때 체크해서 필요한 네스팅 다중 선택 가능하게. 운영배포」(채팅 직접 = deploy-live 승인)
- ✅화면(web-designer 처방): 열기 모달 1칸 「선택」 체크(칸 전체 히트 · 행 단일 열기로 안 번짐) · 체크 순서 = 순번 1·2 · 첫 체크 = 대표(☆ 변경) · 하단 칩 + 부재·원장 합 미리보기 + [선택 해제] + 통합 열기 (n) · 검색해도 선택 유지 · 막힘 = 출처 다름/현장 없음/4개 초과(사유 표시). 결과 = 새 작업(curJob.no=null · URL ?job= 제거 · 「통합본 #17+#18 — 저장 안 함(새 작업)」) → 저장 = POST 만 · fields = 실제 행 fno 현장 · opts.mergedFrom = 선택 전부. 원자성 = 전부 GET·재검증 뒤에만 표 변경(하나라도 실패 = 표 무변경 + 오류). 진행 중 ldBusy 로 열기·합치기·삭제 잠금.
- 재사용(중복 구현 0): loadJob → applyLoadJob, mergeJob → applyMergeJob(검사 throw), newJob → resetJob 으로 쪼개 공용. 변경 = C:\dev\pfs\web\nesting\nesting.html · 신규 C:\dev\pfs\migrations\patch57_nesting_job_field.sql.
- ✅DDL: 운영 RDS nesting_job_field 이미 있었다(SHOW CREATE TABLE = _FIELD_DDL 과 동일 · PK(job_no,field_no) · idx_field · 0행) → CREATE 실행 안 함(조회만, SSM). deploy-live 제외 = orderpaper-sync/{nesting_draft.py,material_vendor_override.json} · common/material_order/test_calc.py. blob 6파일 master 동일.
- ✅검증 C:\dev\pfs\scripts\_nesting_multi_open_check.py(gitignore) 로컬 33/33(운영 #17·#18 GET 사본 · 실패 주입·연타·막힘) · 테스트 38/38(시드 #42·#43 → 통합 저장 #44·#45 되읽기 fields 2곳·384행·658 · 원본 무변경) · 운영 35/35(https://pfs.poin.co.kr/production/nesting 200 · 목록·단건 200 · #17+#18 = 155+229 = 384행 · 수량 269+389 = 658 · 배지 A155/B229 · 원장 93 · 쓰기 0). 회귀 = product_calc 로컬 137/137·운영 146/146 · multifield_api 운영 4/4 · drawer 65/65 · multifield 42/42 · loadmodal 16/16 · import_keep 53/53 · rename_warn 32/32 · rid_sort 30/30 · qa5 99/106(기준선).
- ✅사이트맵 재빌드(페이지 62 · /production/nesting·/api/nesting/* 전부 same · 미반영 1 = /field/worklog kakao-board 무관) · pfs 커밋 cbe18780. devplan C:\dev\devplan\pfs-nesting-order-draft.html §5 + 허브 카드 갱신.
- ⚠남은 것: ①devplan 같은 페이지 §1 진행표 ③④⑤ 배지(대기→완료/진행)는 ruleguard web-designer-required 가 서브에이전트 세션의 상담 기록을 못 봐서 막힘 — 총괄이 고치거나 보류 ②통합 시 커프·여백·결무시 옵션 = 대표(첫 체크) 저장본 값(합치기와 같은 정책 · 발주완료 체크는 대표 것만) ③테스트 DB 에 검사 시드 #42~#45 남김(_QA통합열기*) ④운영 #17·#18 은 09:09·08:58 KST 에 페페 쪽에서 계속 수정 중(행 155·229).
- ✅ 26.10.6 네스팅 「🧱 제품 계산기」 — 운영
980b4e43완료 · ⏳[페페] 결정 3건(1280px 툴바 접힘 · 18T MDF 분홍 경고 · 뒤판 인셋) (원문: archive.md 「✅ 26.10.6 · pfs-handoff-cap-1006a」)
[코디] D1 자재 발주서 모듈(26.10.5) — ✅운영 반영 26.10.6(화) 01:01 KST deploy-live 5b1173c9 (master f4763a89·b360a9d3 push)
- ✅26.10.6 품목군별 업체 일괄 지정(툴바
#moBulkBar, 품목군 필터 칩 재사용·보이는 행만·덮어쓰기 confirm·되돌리기 토스트) — mastera74a3968· deploy-liveca2c133d· Playwright 33/33. - [페페] 26.10.6 「모두 추천대로. 운영 배포 진행.」 → ①운영 DDL patch56 선생성(SSM, 7테이블 + menu_catalog
menu_no 59display_order 221, ALTER 0) ②master pushc7b31265..b360a9d3③deploy-live 체리픽0d973fab·601bc107+ 공용 계산 모듈만 선반영5b1173c9(common/material_order/{__init__,calc}.py= c7b31265 중 순수 모듈 2파일 · 네스팅 변경분·nesting_job_field는 미반영 → 대표 현장 1개로 동작) · blob 19파일 master 동일 · uwsgi 01:01:09 KST 재기동 ④운영 실측(https://pfs.poin.co.kr/field/mat-orderpaper 200 · 사이드바 「자재 발주서」 · GET 목록/nest-jobs/vendors/vendor-rules 200 · EC2 calc import OK · 초안·확정 0건) ⑤사이트맵 이 화면·API 전부 same(남은 미반영 1 = /field/worklog 카톡관리, 타 세션). ⚠test_pfs_link는 pfs_deploy_wt 에서 ③(orderpaper-sync 파서 — deploy-live 에 안 올리는 데몬 파일) 단언 실패 = 기존 분기 차이, master 에선 OK. - 26.10.6 00시대 검증:
test_pfs_linkOK(+--db회귀 5종) ·test_mat_orderpaper39/39 · 테스트DB 통합 53/53 · 테일스케일 화면 실측 93/93. 운영 DDL = 신규 7테이블 + menu INSERT(display_order 221), ALTER 0, 적용기C:\dev\pfs\scripts\_mat_orderpaper_patch56_apply.py --yes-live. - ⛔막힘:
orderpaper-sync/orderpaper_parse.py:359정규식이 MAT 모름(병렬 세션 소유) → 확장 전 D1 엑셀을 NAS 월 폴더에 넣으면 이중적재. 요청 =CONTRACT.md「D1 요청 (2차)」 8건. - 페페 결정 대기: ①같은 원장키 덮어쓰기 = 현장 겹칠 때만 나중 저장본(임시) ②엑셀 표식
PFS-MAT#n만·draft/rev 는 설명칸 ③규칙표 수정권한 = admin_company_permission. ⏳NAS 업체탭 양식(작성기 공용화 후)·노트20 실기. - [페페] 「모두 추천대로 진행」 = Q1~Q7 전부 A·기본값 채택(
/field/mat-orderpaper·6테이블·pfs_mat·PFS-MAT#n). 코덱스 반영 =pfs_link.sync_multi신설(기존 sync 무변경·tx 주입·회귀 5종), line_key/line_id 분리, 확정 후 수량·업체·규격·현장 잠금. - 구현 10단계(DDL → sync_multi → 초안 서비스 → 업체표 → 확정·차수 → 엑셀 → 화면(web-designer 상담) → 메뉴 → 사이트맵 → 운영 DDL 선생성·배포). 금지 = nesting.html·api/pfs/nesting/·orderpaper-sync/(병렬 세션), 10.2 몸통 오적재 정리는 별건.
- 포인터:
C:\dev\_work\order-draft-1005\D1-plan.md· devplanpfs-mat-orderpaper.html(http://100.108.234.45:8799/pfs-mat-orderpaper.html)
[코디] 🆕 26.10.5(월) — 네스팅 → 원부자재발주서(도어 마감재) 초안 파이프라인 + 네스팅 복수 현장 연결 — ⏳그릴링 대기(착수 전)
[페페] 「가구전문가 참조 · 원주+안산 통합 발주서 + 현장별 개별 발주서 · 네스팅 복수 현장 연결 · 몸통재 때 누락분 추가 · 기본 = 도어부재 네스팅 2현장 · 운영배포」
- 사실(opus-max 상담): #17 원주·#18 성포 공유 컬러 0 → 이번 통합 = 합 73장. 31·42 = 검토 해치 포함 상한(확정분만 원주 26). 성포 「9T쫄대」 10개가 18T 로 저장(두께 오류 의심). 리포 자산 = C:\dev\pfs\orderpaper-sync\{nesting_order,tread_to_draft,orderpaper_build}.py(전부 현장 1개 전제). nesting_job 현장 칸 1개.
- 🔴발견: 10.2 몸통 발주서가 운영 자재관리에 잘못 적재 — 합산본이 원주(2169) 카드에 중복, 성포 몸통본이 field 251 로 붙음(파일명 꼬리 (몸통) → orderpaper_parse.py L92~93 현장 파싱 실패). 정리는 별건 승인.
- 그릴링 Q1~Q7(1차)·Q8~Q10(2차) 페페에게 제출. 배정 = L4 worker-opus-xhigh(Q3=DB 초안이면 L5). 장부 줄은 결정 후 추가.
[코디] 🆕 26.10.5(월) — GS 원주 단구·안산 성포 마감재 네스팅 같은 항목 수량 합산 + 결방향 세로 통일 → 운영 새 작업 #17(31장)·#18(42장) 20:55 KST — 코드 변경 0
[페페] 「안산 성포, 원주 단구 네스팅 자료에서 같은 컬러, 두께, 타입, 가로, 치수, 품명이 같은 항목들 수량을 합쳐줘. 결방향은 결무시 가능 칼라라도 세로 기준으로 통일 … 가로,세로 값을 교환 … 자재 가로,세로 길이 제한에 의한 교체. 운영배포」
- 규칙(순서 = 결 → 길이 교환 → 합산): 전 행 결방향 세로 · 원래 가로결 행 w↔h(두 작업 0행) · 세로 고정 뒤 가로 > 원장폭 1220 이면 w↔h(= 화면 orient() 강제 스왑과 같은 결과) · 합산 키 = 두께·MDF/PB·컬러·경면·품명·양단면·타입(부재표 「타입」 칸)·가로·세로·결 · 위치·비고·ID 는 키 아님(대표 = 첫 행 · ID = 첫 행 ID · 성포는 비고에 「병합 ID a·b·c」 · 원본 위치·비고 전부 빈칸).
- 원주 #14(180행·수량 210) → #17 https://pfs.poin.co.kr/production/nesting?job=17 126행·210 · 결 바꾼 행 155 · 합산 그룹 38 · 길이 교환 2(84A옵션 KAEX7-SR FIX 1290×55·1270×270) · 31장 → 31장.
- 성포 #16(219행·253) → #18 ?job=18 170행·253 · 결 바꾼 행 210 · 합산 그룹 37 · 길이 교환 1(104 GY123MT EP 1255×400) · 41장 → 42장 = 결 고정 몫(합산만 41 · 결만 42 · GK102-G8 5→6 · IV075EMT 단면 19→20 · GY123MT 단면 13→12). 원본의 결무시 회전 배치 32매(원주 29매)가 0 이 됨.
- 저장 = 선례 _nestsave_18t.py 틀(빈 화면에 변환 부재 → 자재 자동등록 = 원본 자재와 같음 → 네스팅 → 새 작업 doSave) · route 가드 = POST /api/nesting/job 사이트별 1회만 · 칼라 POST 0(857 그대로) · PUT·DELETE 0 · #14·#15·#16 무변경.
- 검증: 수량·면적 보존(58.9592㎡ · 86.3028㎡) · 되읽기 14필드 행별 차이 0 · 결 전부 세로 · 원장 초과 0(w≤1220·h≤2440) · ?job=17·18 열기/재실행 31·42 · 기존 #1~16 modify_date 불변 · 독립 반박검증(sonnet, 규칙 재구현 + 화면 엔진 Node 재현) 결함 0(원본 31/41장 재현 일치 · 저장본 31/42장 · 교환 3행 정확히 일치 · job 14·16 전 필드 불변).
- 백업·스크립트 C:\dev\_work\gs-finish-nesting\merge-grain-261005\(원본 backup_job14.json·backup_job16.json · 변환 diff diff_tables.md · _transform.py · _nestsave_merge.py · 장수 분해 variants_*.json).
- ⏳[페페] 애매점: ①「타입」 = 부재표 타입 칸(84A기본·84A옵션·84C / 84A·전시부스·99A·104·OT84A)으로 봤다 — 타입 무시하고 합치면 원주 89행·성포 129행 ②길이 교환은 원장폭 초과만 — 변환 뒤 가로>세로(결이 짧은 변) 원주 19행·성포 38행 남음(걸레받이·서랍앞판·FIX 등). 「긴 변 = 결」(w>h 전부 교환)이 의도면 원주 31장·성포 41장(−1)(반박검증 엔진 재현값, 원래 세로였던 원주 서랍앞판 6행까지 바뀜) ③양단면(양면/단면)은 키에 넣었다(엔진이 원장을 따로 잡음) — 빼면 원주 1쌍·성포 2쌍 더 합쳐짐(125·168행) ④#14·#15·#16 삭제/보관 ⑤NAS 산출물 갱신 안 함.
- ✅ 26.10.5 저장본 열기 모달 가로 폭 확대(운영 42c8bed1) · 부재 표 헤더 겹침 수정 + ID 칸 클릭 = 도면 확인 표시(운영 6c28441e) — ⚠확인 표시는 [💾 저장]해야 남음 (원문: archive.md 「✅ 26.10.5 · pfs-handoff-cap-1005b」)
- ✅ 26.10.5 부재 표 [↔] 가로·세로 바꾸기 + 인라인 검색창 — 운영 82ae4394 완료 (⚠#18 은 운영서 계속 바뀜 · 원문: archive.md 「✅ 26.10.5 · pfs-handoff-cap-1005c」)
[코디] 🆕 26.10.4(일) — 네스팅 부재 표 ID 칸 + 헤더 클릭 정렬 + 기본 ID순 + 다중/고급 필터 + 조건 세트 서버 저장(nesting_filter_set) + 정렬 모달 — 운영 완료 5a3dfceb (⚠기존 저장본 #1~15 는 ID 없음 · 조건 세트 삭제 하드 · 원문 archive.md 「…cap-1005d」)
[코디] 🆕 26.10.2(금) — GS 안산 성포 MH 포인 769 최신화 → PFS 한샘 견적 6 갱신(form 14) + NAS 새 파일 — 코드 변경 0 · 운영배포 없음
⏳[페페] 6건(session-2026-10-02-gs-ansan-seongpo-hansem.md 참조) · ⚠devplan hansem-estimate.html 절 17 미삽입(문안 C:\dev\_work\gs-ansan-seongpo-1002\devplan_s17.txt) · 원문 archive.md 「…cap-1005d」
[코디] 🆕 26.10.2(금) — GS 원주 단구·안산 성포 몸통 원부자재발주서 3종(개별 2 + 합산 1) — 로컬+NAS 10월 폴더 업로드(12:18)
⏳[페페] 확인 9건(성포 출처 작업본 vs #12 · 15T H2041B-L1 · 4.5T LPM · PQFA2T 대응품번 · HS0868GP 경면 · 엣지 · 피스마개 단위 · 합산 이중여유 · 합산본 이중 적재) · 🔑함정 momtong_order.write_tab 17건 초과 소실 · 원문 archive.md 「…cap-1005d」
[코디] 🆕 26.10.2(금) — GS 원주·성포 마감재 해치·네스팅 → 운영 nesting_job #14(원주 31장)·#15(성포 46장)·#16(성포 18T 41장) + NAS 업로드 완료
⏳[페페] #15(15T 판) 삭제/보관 · 남은 결정 6건 Q5~Q10(기본값으로 저장됨) · 상세 session-2026-10-02-gs-finish-nesting.md 「후속」 · devplan gs-finish-nesting.html · 원문 archive.md 「…cap-1005d」
[코디] 🆕 26.10.2(금) — 네스팅 도어 부재에 PNCAD 작업본 섞임 방지(출처 다르면 새 탭) — 운영 320e17a6 완료
⏳[페페] ①#8 호반 대구 칠성 도어+PNCAD 혼합 저장본 분리 여부 ②GS 마감재·도어는 #12·#13 에 넣지 말고 새 저장본 ③#12·#13 은 재저장 이전 값 ④devplan pfs.html DONE AX 줄 미삽입(문안 C:\dev\pfs\_restore\nesting_gs_2026-10-02\devplan_done_AX.txt) ⑤web-designer 제안 미반영 · 원문 archive.md 「…cap-1005d」
[코디] 🆕 26.10.2(금) — GS 대전 도마변동 2차(수입주방) 포인 787 → 한샘 견적 10(form 9) + NAS — 코드 변경 0
⏳[페페] ①−4,000 절사 ②787 이름 「(국산)…(2차)」 vs 「수입주방」 정정 ③걸레받이 0원 «무상» 3줄 ④부속→FIX PANEL 매핑 · 원문 archive.md 「…cap-1005d」
[코디] 🆕 26.10.1(목) — GS 대전 도마변동(field 2175) 포인 785 → 한샘 견적 9 + NAS (26.10.2 후속 3건 완료·NAS 저장) — 코드 변경 0
⏳[페페] ⛔NAS 교체 보류(손수정본 있음) · 🔴운영 form 3·4 출력에 「임서현」 도장+GS 안산 도면 실림(재발행 판단) · 통합·v2·1차 ⏳ 전부 archive.md 「✅ 26.10.2 · pfs-handoff-cap-1002c」 · 원문 archive.md 「…cap-1005d」
[코디] 🆕 26.9.30(수) — GS 안산 성포(field 2180) 도면 → 현장별 자재 초안 운영 등록(spec_no 6 · 186칸)
⏳[페페] 검수 24건 · 미등록 칼라 4종 · [진행중·미결3] 견적 초안 769/한샘 6 → session-2026-09-30-gs-ansan-matspec.md · devplan pfs-gs-ansan-matspec.html · 원문 archive.md 「…cap-1005d」
[코디] 🆕 26.9.30(수) — 학동매장 도어발주서 초안(포인탭) NAS 게시 — ⏳[페페] 확인요 8건 + 같은 폴더에 사람이 쓰는 한샘 학동매장 도어발주서.xlsm(08:06~) 과 정본 선택 → session-2026-09-30-hakdong-door-draft.md
[코디] 🆕 26.9.29(화) — 월마감 현장별 거래명세서 신설 — 운영 38158edc 완료
⏳QC1 SSH 22 불통(HM3 미러 SKIP · projects/hm3/rules.md 「업그레이드가 SSH를 죽였다」) · ⏳사람 눈 = 실물 A4 출력 1장 + 얼마에요 원본 대조 · 원문 archive.md 「…cap-1005d」
[코디] 🆕 26.9.29 — 네스팅 저장본 #8(호반 대구 칠성) YEN70-SG 도어 소실 복구 + 가져오기 덮어쓰기 수정 — 운영 5fd14421 완료 (원문: archive.md 「✅ 26.9.29 · pfs-handoff-cap-0929」)
⏳PITR 인스턴스 pfs-pitr-nest8-0929 삭제 승인 대기(stopped) · ⏳운영 동기화 시 stock(재고량) 칸이 자리 기준 UPDATE 로 어긋남 · ⏳EM738 18T 1매·엣지 제외(PNCAD 오류 확인 중) · 상세 projects\pfs\session-2026-09-29-chilseong-wonbujae-order.md 「3차」.
[코디] 🆕 26.9.28 — 롯데 화성 향남 MH 본건(779)+추가1(780) 한샘 양식 엑셀 — 6차까지 완료 (원문: archive.md 「✅ 26.10.2 · pfs-handoff-cap-1002b」)
최종 = 한샘 협의 90,000,000(VAT 별도) · NAS …\09월\한샘\롯데 화성 향남\ · 🔴779 PUT 이 하위내역 69줄을 지움(복구함, rules 🆕) · ⏳[페페] 한샘 견적 8(780 만 540,239) 처리 판단 · ⏳ACC룸(6,702,000)이 본건 90,000,000 에 포함 = 이중청구 위험 → ①본건에서 뺀 새 본건(추천) ②추가건 재작성 ③그대로.
[코디] 🆕 26.9.28 — 에넥스 9월 월마감(close_no 21) 완료 — 현재 23,694,000(26.9.30) (원문: archive.md 「✅ 26.10.2 · pfs-handoff-cap-1002b」)
운영배포 5dee8ae6 · ⛔781·782·783 은 페페 직접수정본 — 단가·운임 스크립트 재실행 금지 · 라인 VIP 추가2 = 784 369,000(10월 마감 대상) · ⏳[페페] NEGO 입력 · 782·라인 VIP 단가 확인 · p6~8 을 784 에 더할지 추가3 인지 판단.
✅ 26.10.6 · pfs-handoff-cap-1006a · handoff 캡 이관 3절 (배차목록 출고요청서 행 강조 · 네스팅 제품 계산기 · 자재 발주서 확인표·소프트삭제·게이지)
[코디] 🆕 26.10.6(화) — 자재 발주서: 자재 확인표 탭 · 품목 소프트삭제/복구 · 보드 소요 게이지 — ✅운영 완료 master bb39275e(+사이트맵 0992f901) → deploy-live 7c352be5(체리픽 10파일 blob 일치) · push 10:32 KST · uwsgi 재기동 10:32:33 KST · 운영 쓰기 0
[페페] 「직원이 현장별·타입별·주방/일반·위치별로 자재 넘버·두께 확인하는 탭 / 스티커 등 생산 안 하는 품목 삭제(소프트·연하게·복구) — 시트·보드 공통 / 보드에 네스팅처럼 소요량 게이지 / 운영배포 · 추천대로」
- ✅확인표 = GET /api/mat-orderpaper/<no>/matview(api/pfs/mat_orderpaper/mat_view.py) · 원천 = 출처 저장본 «현재» 부재(덮어쓰기 반영 · alloc 조인 없음 = 수량 중복 0) · 주방/일반 = 명시 표식만(품명 앞머리·위치·타입), 빈 값 「미지정」 · 해시 #n/check · 목록 「자재표」 · 검색·타입 알약·A4 인쇄(body.mo-printing).
- ✅소프트삭제 = mat_orderpaper_item.remove_yn(+remove_date·remove_user) · POST /<no>/lines/remove|restore · 합계·검산·경고·엑셀·확정 적재 제외 · 판 rev+1(item_del|item_restore) · 확정 문서 = sync_multi 재적용(삭제=내림·복구=같은 orderpaper 행 되살림·중복 0 · 입고/진행 행·마지막 품목 거절 · 자재관리 수동삭제 행은 안 살아남 → 응답 수) · 재가져오기/연결/추가 차수 = 삭제 상태 승계.
- ✅게이지 = 소요(Σ bom 장수×자재소요%, 초안 생성 때 trace 저장 · 예전 초안은 현재 summary 로 보강, 장수 다르면 「정보 없음」) ÷ 화면 최종 · <95 초록/95~100 빠듯/>100 부족 · 미리보기 전 「계산 중」 · 추가 차수 = 「1차에서 확인」.
- ✅DDL patch58(C:\dev\pfs\migrations\patch58_mat_orderpaper_item_remove.sql) = 테스트 → 운영 순(SSM, INSTANT, lock_wait_timeout 10) · 운영 49행 영향 0(SHOW CREATE 확인).
- ✅검증: 단위 69/69 · 테스트DB 통합 32/32 · 로컬 화면 54/54 · 테스트 서버 8001 화면 54/54 · 운영 읽기 19/19(화면 200·새 JS·탭·14칸·게이지·확인표 카드 2·GET 7종 200·쓰기 0·콘솔 0). 사이트맵 새 API 3종 same(잔여 미반영 = kakao-board). 검사기 = C:\Users\delix\AppData\Local\Temp\claude\c--dev\4eca4ca7-dd2e-43a5-a06f-ed7a361e4184\scratchpad\{it_remove,ui_1006,live_pw_1006}.py.
- ⚠애매점(추천으로 정함): 도어 저장본은 위치 칸이 비어 주방/일반·위치 「미지정」 · 확인표 = 지금 저장본 기준(바뀌면 배너) · 삭제 보드 자재는 확인표에서도 연하게(빼지 않음) · 게이지 임계 95% 제안값 · 저장 중 [삭제] 경합 → 저장 끝날 때까지 줄 세움(실측 버그 수정). 제안(미구현) = 삭제 사유 칩 · 목표 채움률 일괄 여유.
[코디] 🆕 26.10.6(화) — 배차목록 출고요청서 미리보기(#dcPrintModal) 「주소」「연락처」 행 연노랑 #fff9c4 — ✅운영 완료 master 50af14b4 → deploy-live c4d2a339(dispatch_list.html 1파일·blob 일치) · push 10:3x KST · 운영(pfs.poin.co.kr) computed bg 화면·print 모두 rgb(255,249,196) 실측 · 택배의뢰서 영향 0 · 사이트맵 재빌드 미반영 1(worklog kakao-board, 내 건 아님) · menu_dump 커밋 214bff6b(로컬)
[코디] 🆕 26.10.6(화) — 네스팅 「🧱 제품 계산기」(오픈장·휠라 등 다중 부재 제품) — ✅운영 반영 완료 master 671dd485 → deploy-live 980b4e43 (cherry-pick · push 완료 · 운영 DB 쓰기 0 · 기록 02:34 KST)
[페페] 「poincad 자산을 활용해서 네스팅에 오픈장, 휠라 등 다중 항목 제품을 외곽치수 입력, 항목별 직접 입력으로 추가할수 있게 해줘. 서랍 계산기의 심화 버전이다. 운영배포. 질문사항은 추천대로 진행한다.」 → 그릴링 Q1~Q10 전부 추천안 채택.
- ✅산식 3종(오픈장 · 휠라/SR/EP/목찬넬 ㄱ자·T자 · 냉장고 휠라 ㄷ자) + poincad 샘플 116그룹 불러오기 + 빈 제품 직접 구성. 편집 표에서 칸 수정 = 수동 고정(주황·↺ 복귀). 변경 = C:\dev\pfs\web\nesting\nesting.html(+813) · poin_sample_controller.py(GET /api/poin/sample-tree 신설, SELECT 2개).
- ✅검사 C:\dev\pfs\scripts\_nesting_product_calc_check.py(gitignore) 로컬 137/137 · 테스트 146/146 · 운영 146/146(EC2→MSSQL 116그룹 · 쓰기 0 · 콘솔 에러 0). 회귀 = 서랍 계산기 운영 73/73 · qa5 99/106 · grid-modal 87/96(기준선 동일) · import_keep 53/53. 검사기가 잡은 버그 3(pcType id 충돌 · display:flex 가 hidden 무력화 · blur→change 재렌더로 ↺/제외 클릭 소실) 수정.
- ✅사이트맵 재빌드(C:\dev\devplan\pfs-sitemap.html 페이지 62 · /production/nesting same · 미반영 1 = /field/worklog kakao-board 무관) · pfs 커밋 614bfe64 · devplan pfs-nesting-product-calc.html · 상세 = projects/pfs/session-2026-10-06-nesting-product-calc.md.
- ⏳[페페] 결정 ①1280px 에서 툴바 2줄 접힘(1320px+ 는 1줄 · 이번 범위 밖) ②18T MDF 행 분홍 경고(기존 「15T↑+MDF 경고」 vs 결정 「MDF 18T 기본」 충돌 — 경고 규칙을 손볼지) ③뒤판 18T 통뒤판 인셋 가정(화면에 「확인 필요」 문구 — 실무값 확인).
- 보고만: 서랍 계산기 천지판 W−2T vs poincad 실사용 W−37 = 1mm 차이(Q10, 미해결). ~~운영 nesting.html 은 master 복수 현장(c7b31265) 미반영 유지~~ → ✅26.10.6 09:22 KST 운영 반영(deploy-live 792ea1cc, 위 절). poincad 에는 산식이 없어 산식 = 현장 실사용(poin_item) 역산 최빈값.
✅ 26.10.5 · pfs-handoff-cap-1005d · handoff 캡 이관 8절 (26.10.2 성포 한샘 6 · 몸통 발주서 · 마감재 네스팅 · PNCAD 섞임 방지 · 대전 한샘 9·10 · 26.9.30 성포 자재 · 26.9.29 월마감 명세서) + 낡은 「최종 갱신」 3줄
[코디] 26.10.5 handoff 캡 관리 4차 — [코디 총괄] 지시로 ⏳ 보유 절도 원문 이관(handoff 엔 제목 1줄 + ⏳ 요지 1줄 + 포인터 남김). 아래는 원문 그대로.
[코디] 🆕 26.10.2(금) — GS 안산 성포 MH(field 2180) 포인 769 최신화분 → PFS 한샘 견적 6 갱신(form 14 비활성 신설) + NAS 새 파일 — 코드 변경 0 · 운영배포 없음 · ⏳[페페] 6건 → session-2026-10-02-gs-ansan-seongpo-hansem.md
[페페] 「PFS 안산 성포 견적서 최신화 했다. 한샘 양식으로 재제작 해서 나스 폴더 저장해줘.」
- 769(읽기만, 수정일 26.10.2) 26.9.7 판 대비 = 전시부스(84A) 4줄 추가(5,879,000, 하위 4건) · 운반비 0→600,000 · 시공비 0→11,000,000 · 기존 24줄·하위 46건 그대로 → 총 48,368,000(상세 36,768,000).
- 한샘 6 = form 3→14(form 4 → 5평형 전시부스(84A)·84A·99A·104·OT84A 주방전용 · 도면·「임서현」 도장·S6 06.16 제거 · 탭마다 블록 제목 = 포인 품명(블록 = 항목 1개) · 운반비·시공비 박음) · delete-insert POST 78칸(항목 28 + 하위 50 세트칸) · 서버총액 36,769,369 · 담당 「김선정 과장」 · 견적일 2026-09-07 유지.
- 엑셀 = 주방 36,760,000(−8,000 만원 절사) + 운반비 600,000 = 생산비 37,360,000 + 시공비 11,000,000 = 48,360,000 · verify 운영 306 ALL OK · sfcheck·_xlcheck 0 · 운영 다운로드 = 로컬 파트 차이 0 · PDF 육안 OK.
- NAS 새 폴더·파일 \\192.168.0.101\공유폴더\2026현장\견적\10월\한샘\GS 안산 성포 MH\한샘 GS 안산 성포 MH 가구제작 견적서(26.10.02).xlsx(107,964 B 바이트 일치) · 9월 폴더 파일 그대로.
- 운영 쓰기 = form 14 업로드 + 한샘 6 갱신뿐(769·form 1~13·한샘 1·4·7·8·9·10 불변 C:\dev\_bench\gs-ansan-seongpo-1002\snap_before/after.json) · 스크립트 C:\dev\_work\gs-ansan-seongpo-1002\ · ⚠devplan hansem-estimate.html 절 17 미삽입(훅이 서브에이전트 web-designer 상담을 못 봄) → 문안 C:\dev\_work\gs-ansan-seongpo-1002\devplan_s17.txt.
[코디] 🆕 26.10.2(금) — GS 원주 단구·안산 성포 몸통 원부자재발주서 3종 작성(개별 2 + 피앤데코 합산 1) — 로컬만, NAS·운영 쓰기 0 · ⏳[페페] 확인 9건
[페페] 「기존 GS 자재 발주서 확인해 원주 단구·안산 성포 원부자재 발주서 · 도어 빼고 몸통만 · 피앤데코 합산 별도(한번에 생산, 개별은 현장별 금액용)」.
- 산출 C:\dev\_work\gs-momtong-order\out\(xlsx 3 · report.md · png\ · alt_job12) · 스크립트 체인 같은 폴더(fetch_jobs→…→verify→make_report) · verify 41/41 PASS.
- 원주 = 저장본 #13 그대로 49장. 성포 = #12 가 작업본 33~36 재저장(01:03) 전 값이라 현재 작업본으로 재네스팅 70장 + 페페 여유 14 = 84(#12 기준 대안 = alt_job12). 합산 = 단순 합(합쳐 재네스팅 시 119→113 참고만).
- ⏳[페페] ①성포 출처(작업본 vs #12, 작업본이면 운영 #12 재저장 승인) ②15T H2041B-L1 여유+1 ③4.5T 등판 피앤데코 LPM 가능? ④PQFA2T(LX PVC) 피앤데코 대응품번 ⑤HS0868GP 경면 여부 ⑥엣지 폭·컬러(성포 사양 ABS PUR) ⑦피스마개 단위 EA vs 장 ⑧합산 이중여유(3T 시트 40M·엣지) ⑨합산본은 NAS 동기화 폴더 금지(PFS 이중 적재).
- ✅12:18 KST [페페] 「NAS 10월 폴더에 모두 저장」 → 3파일(작업본 기준판) 2026현장\원부자재발주서\10월\ 업로드·왕복대조 일치. ⚠합산본도 동기화 폴더에 있음 → PFS orderpaper 파싱 시 현장 「GS 원주 단구+안산 성포 MH」 이중 적재 여부 확인 필요.
- 🔑리포 함정(미수정): momtong_order.write_tab 품목 17건 넘으면 24행 캡노트에 써져 조용히 소실 · orderpaper_build._receiver_row 병합 해제 전 서식 복사라 중간 입고처 행 서식 소실.
[코디] 🆕 26.10.2(금) — GS 원주 단구·안산 성포 마감재 해치(1차 전면 + 2차 측면 EP)·네스팅 계산 완료 → 페페 승인으로 운영 nesting_job #14(원주 31장)·#15(성포 46장) 저장 + NAS 새 하위폴더 업로드 완료 — ⏳[페페] 남은 결정 7건(Q4~Q10) → session-2026-10-02-gs-finish-nesting.md 「후속」 절
[페페] 「마감재 네스팅 계산 · 전면 입면 기준 · 도면 복사해 해치 직접 · 1차 전면 도어·EP류 → 2차 측면 EP류」. 사본 DWG 에 ODA→ezdxf→ODA(ACAD2013) 해치 + .treadwork.json · 네스팅 = deploy-live nesting.html 로컬 헤드리스(운영 호출 0).
- 원주 229매 56.422㎡ → 엔진 원장 31장(산입만 26 · 길로틴 26) · 성포 261매 82.373㎡ → 46장(산입만 40 · 길로틴 38 · 도어 18T 반대안 41). 두 현장 2차 checks(V8b 포함) FAIL 0.
- 산출 C:\dev\_work\gs-finish-nesting\<wonju|seongpo>\out\(…_마감재해치_2차.dwg · _overlay.dwg · _2차.treadwork.json · nest_input_p12.json · png2\ · nest_report.md). 저장 시 자동 등록될 칼라 = 성포 GK102-G8·P9GA4T(common\colors_check.json).
- ✅[페페] 26.10.2(금) 「막힘 3개 — 1 저장 승인 · 2 a · 3 추천대로」 실행 = 운영 nesting_job #14 원주(field 2169 · 11:13 KST · https://pfs.poin.co.kr/production/nesting?job=14) · #15 성포(field 2180 · 11:20 KST · ?job=15) 새 작업 POST(기존 #1~13 변경 0) · 칼라 855→857(성포 GK102-G8·P9GA4T, 마감종류·업체 칸은 사람이 채움) · NAS 새 하위폴더 \\192.168.0.101\공유폴더\2026현장\진행중\10월\한샘 GS 원주 단구 MH\마감재네스팅_초안_261002\(29파일) · …\한샘 GS 안산 성포동 MH\마감재네스팅_초안_261002\(42파일) MD5 71/71 일치 · 독립 검증 결함 0(C:\dev\_work\gs-finish-nesting\common\verify_commit.md). 한계 = 저장본에 작업 메모·행 비고 칸 없음.
- ✅Q4 해소 26.10.4(일) — [페페] 「안산·원주 도어 기본 18T · 15T 없음 · 모두 18T 로」 → 성포 도어·서랍앞판·FIX 124매 15T→18T(파생 치수 변경 0) · 엔진 46→41장(산입만 40→36 · 길로틴 38→35) · 2차 checks FAIL 0 · 운영 새 작업 #16(https://pfs.poin.co.kr/production/nesting?job=16 · 219행 · 41장 · 새 칼라 0) · NAS \\192.168.0.101\공유폴더\2026현장\진행중\10월\한샘 GS 안산 성포동 MH\마감재네스팅_18T_261004\ 42파일 MD5 42/42 · 원주 마감재 15T 0(변경 없음). ⏳[페페] #15(15T 판) 삭제/보관 결정.
- ⏳[페페] 남은 결정 6건 = Q5~Q10(사양충돌 Q5~Q8 · 검토 해치 산입 Q9 · 치수 선택 Q10) — 전부 기본값으로 저장됨. 반대안 선택 시 새 작업 재저장(PUT 금지·별도 승인) · 상세 = devplan gs-finish-nesting.html §2.
- ✅devplan 페이지 = C:\dev\devplan\gs-finish-nesting.html 배치·허브 등록 완료(Q1~Q3 「답변 반영」 26.10.2).
[코디] 🆕 26.10.2(금) — 네스팅 「도어 부재에 PNCAD 작업본이 또 섞였다」(GS 원주 단구·안산 성포) → 출처가 다르면 한 표에 안 섞고 새 탭 — 운영 320e17a6(master 1fea0da2) 09:0x KST
[페페] 「도어 네스팅에 pncad 작업본이 또 섞여 들어간거 같다 · 원주 단구·안산 성포 집중 · 도어 부재엔 코디에게 시킨 네스팅 항목이 들어갈 예정 · 두 내용 섞이면 안 됨 · 운영배포」.
- 실측(운영 읽기, 백업 C:\dev\pfs\_restore\nesting_gs_2026-10-02\backup_jobs_before-0841.json·backup_alljobs_0850.json) = 두 현장 저장본은 #12 GS 안산 성포 네스팅(field 2180 · source pncad · scenes 36·32·35·34·33 · 178행 · 26.10.2 00:59:46 KST 실브라우저 POST = 페페 저장, 여유자재 5칸 손입력) · #13 GS 원주 단구 몸통 네스팅(field 2169 · pncad 37·38·39 + 팬트리 문틀 2행 · 165행 · 코디 01:11 저장/01:35·01:42 덮어쓰기) 뿐이고 둘 다 순수 PNCAD 몸통(도어·EP·휠라 등 이름 행 0 · 중복 행 0). 도어 행이 PNCAD 에 덮이거나 섞인 저장본 없음 → DB 조치 0(삭제·수정 0). 페페 07:27 KST 미니PC 브라우저로 #13 을 「도어전용」 탭에서 열었다(nginx).
- 원인 = 구조: 부재 표는 「도어전용」 탭의 「1. 도어 부재 입력」 하나뿐이고 PNCAD·몸통재 「네스팅 실행」이 그 표에 넣는다 → PNCAD 저장본이 「도어 부재」 제목 아래 뜬다. 게다가 26.9.29 가져오기 모달 기본값 「기존 행 뒤에 추가」가 곧 도어+PNCAD 섞기(9.29 수정은 «소실»은 막았지만 «섞임»을 기본값으로 만들었다).
- 수정(C:\dev\pfs\web\nesting\nesting.html 1파일, web-designer 처방) = askImportMode 한 곳: 표 출처(jobCtx.source)≠가져올 출처면 추가·교체 없이 「부재를 섞지 않습니다」 → 새 탭에서 열기/[취소](새 탭 = ?scenes= · 신설 ?imos=) · 같은 출처만 추가/교체/취소 · 표 제목·탭 글자 = 출처(수동 「1. 도어 부재 입력/도어전용」 · PNCAD 「1. 몸통 부재 — PNCAD 작업본/부재 표 (PNCAD)」 · imos) · 몸통재 가져오기가 source 를 안 세팅하던 것 · 초기화·샘플 = 수동 복귀 · 몸통 표에 tread JSON(도어) 차단 · 포커스 가두기 숨긴 버튼 제외.
- 검증 = C:\dev\pfs\scripts\_nesting_import_keep_check.py(재작성, 옛판 …\_restore\nesting_gs_2026-10-02\_nesting_import_keep_check.0929.py) 로컬 53/53 · --test 5/5 · --prod 13/13(#12·#13 제목 PNCAD · 178/165행 · 도어 행 0 · 수동 #11 = 도어 제목 · 실화면 도어 표+PNCAD 36 = split · 취소 후 30행 그대로 · #8 불변 · 쓰기 0) · 회귀 qa5 로컬 97/102·운영 114/119, grid_modal 87/96 = HEAD 기준선과 같은 FAIL(옛 결함) · colorpanel 47/47·운영 55/55 · rename 32/32 · finishcode 21/21 · drawer 65/65 · blob 7353f928 master=deploy · 사이트맵 nesting same(미반영 1 = /field/worklog 별건).
- ⏳[페페] ①#8 호반 대구 칠성 = 도어(YEN70-SG 2행)+PNCAD(11행) 혼합 저장본(9.29 복구 때 병합) — 도어/몸통 두 저장본으로 나눌지 · ②GS 마감재·도어 네스팅(C:\dev\_work\gs-finish-nesting\)은 #12·#13 에 넣지 말고 새 저장본(수동) 으로 · ③#12·#13 은 오늘 작업본 재저장(18T 선반·양면) 이전 값 — #12 는 단면 그대로(pncad handoff 영향 목록) · ④devplan C:\dev\devplan\pfs.html DONE AX 줄 = ruleguard web-designer-required 가 서브에이전트 상담을 못 봐 미삽입(문안 C:\dev\pfs\_restore\nesting_gs_2026-10-02\devplan_done_AX.txt) · ⑤web-designer 선제 제안(초기화·샘플 확인창 · 저장본 열기 확인 · #jobState 출처 꼬리 · 저장본 목록 출처 필터 · 13px 미만 잔존 5곳)은 미반영.
[코디] 🆕 26.10.2(금) — GS 대전 도마*변동 2차(수입주방) 포인 견적 787 → PFS 한샘 견적 10(form 9) 등록 + NAS 저장 — 코드 변경 0 · 운영배포 없음 (원문: archive.md 「✅ 26.10.2 · pfs-handoff-cap-1002b」)
한샘 10 = form 9(비활성) · 21칸 · 엑셀 2,010,000(787 2,014,000 대비 −4,000 만원 절사) · NAS \\192.168.0.101\공유폴더\2026현장\견적\10월\한샘\GS 대전 변동\(수입)한샘 GS 대전 도마변동 MH 견적서.xlsx · 스크립트 C:\dev\_work\gs-daejeon-doma-1002\ · ⏳[페페] ①−4,000 절사 그대로 ②787 이름 「(국산)…(2차)」 vs 비고 「수입주방」 정정 여부 ③걸레받이 0원 3줄 «무상» 행 ④부속 → FIX PANEL 블록 매핑 확인.
[코디] 🆕 26.10.1(목) — GS 대전 도마*변동(field 2175) 포인 견적 785 → PFS 한샘 견적 9 등록 + NAS 저장 — 코드 변경 0 · 운영배포 없음 (원문: archive.md 「✅ 26.10.2 · pfs-handoff-cap-1002b」)
한샘 9 = form 8(비활성) · 20칸 · 엑셀 11,880,000(785 = 11,886,000 대비 −6,000 만원 절사 · 시공비 3,500,000) · NAS …\10월\한샘\GS 대전 변동\ · 스크립트 C:\dev\_work\gs-daejeon-doma-1001\ · ⏳ = 아래 🆕 26.10.2 줄로 갱신 · ⛔NAS 교체 보류(페페 손수정본 (국산)…xlsx 있음) · 🔴운영 form 3·4 출력(한샘 6·7·8)에 결재칸 「임서현」 도장+GS 안산 도면이 실림(재발행 판단 필요).
- [코디] 26.10.2 후속 3건 완료·NAS 저장(11:55 1차 최신 → 한샘 9 form 11 26,970,000 · 12:25 통합본 = 한샘 9 form 12 + 한샘 10 form 13, 28,780,000 · 12:49 v2 «엑셀만» 수입분 그룹) — 원문·⏳[페페] 전부 = archive.md 「✅ 26.10.2 · pfs-handoff-cap-1002c」(통합 ⏳①표기 「수입국내생산분」 vs 「수입국내제작분」 ②담당 ③한샘 10 보관 ④−15,000 절사 · v2 ⏳①정본 ②엔진 «그룹 블록»(코드 변경) · 1차 ⏳①~⑩).
[코디] 🆕 26.9.30(수) — GS 안산 성포(field 2180) 도면(DWG) → 현장별 자재 초안 운영 등록 — spec_no 6 · 5타입 17위치 186칸 · ⏳[페페] 검수 24건·미등록 칼라 4종 → session-2026-09-30-gs-ansan-matspec.md · devplan pfs-gs-ansan-matspec.html
- [진행중·미결3] 같은 현장 견적 초안(포인
estimate_no=769· 한샘estimate_no=6,api/pfs/hansem/26.9.9 운영배포) → session-2026-09-07-gs-ansan-seongpo-estimate.md · 🆕26.10.2 769 최신화 → 한샘 6 갱신(form 14) = 맨 위 절
[코디] 🆕 26.9.29(화) — 월마감 현장별 거래명세서 신설 — 운영 38158edc(master c7c1d099) 16:27 KST (원문: archive.md 「✅ 26.9.30 · pfs-handoff-cap-0930」)
월마감 표 각 행 [명세서] → /estimate/monthly-close/<no>/statement/<seq>(A4 1장) · 공급자 common/utils/poin_supplier.py · 업체 사업자 칸 빈 칸만 보충(한샘 1 빈칸 유지) · 운영 98행 ALL PASS · devplan pfs-monthly-close-statement.html.
⏳QC1 SSH 22 불통(26.8.27 Win11 업그레이드 이후, HM3 미러 SKIP · 복구 = projects/hm3/rules.md 「업그레이드가 SSH를 죽였다」) · ⏳사람 눈 = 실물 A4 출력 1장 + 얼마에요 원본 모양 대조.
낡은 「최종 갱신」 3줄 (handoff 맨 아래, 원문)
최종 갱신: 2026-09-16 (KST) — handoff 완료이력 3차 이관(✅ 40절 → archive.md, 113,027자→35,545자). 여기엔 NOW·확정사실·미결만 둔다.
최종 갱신: 2026-09-22 (KST) — handoff 완료이력 4차 이관(✅ 2절 → archive.md, 44,636자→43,894자). 나머지는 전부 ⏳/🔴/판단대기 등 살아있는 후속이 있어 남김(20,000자 캡 미달성).
최종 갱신: 2026-09-22 (KST) — 시드체인 규약대로 5차 이관(페페 26.9.22 지시 — 「미결이라서 남긴다」 폐기). 절 28개를 개별 session-YYYY-MM-DD-*.md 10개 신설(대다수는 기존 문서로 포인터만) + archive.md 헤더 참조로 내리고, 남긴 것은 ⒜ 확정 사실·기본 작업 시스템(불변핵심)과 ⒝ 최근 NOW 3절(26.9.22 월마감모달·Jev·네스팅서랍계산기)뿐이다. 44,028자 → 13,649자.
26.10.4 네스팅 ID칸·정렬·필터 절 원문(handoff 에서 축약)
[코디] 🆕 26.10.4(일) — 네스팅 부재 표 ID 칸 + 헤더 클릭 정렬 + 기본 ID순 + 다중/고급 필터 + 조건 세트 서버 저장(nesting_filter_set) + 정렬 모달 — 운영 완료 950ac78e→22e87c14→012c16cb→d6f10d8a→5a3dfceb (원문: archive.md 「✅ 26.10.5 · pfs-handoff-cap-1005」)
⚠한계 요지: 기존 저장본(#1~15)은 ID 없음 · 필터 중 여러 줄 붙여넣기는 필터 해제 후 표에 붙음 · 조건 세트 삭제 하드(되돌리기 없음). 검사기 C:\dev\pfs\scripts\_nesting_{rid_sort,filter,advfilter,advset_api,advset_ui,advsort}_check.py.
✅ 26.10.5 · pfs-handoff-cap-1005c · handoff 캡 이관 (네스팅 부재 표 [↔] 가로·세로 바꾸기 + 인라인 검색창)
[코디] 26.10.5 handoff 캡 관리 3차 — 「GS 원주·성포 병합」 절의 ✅ 하위 불릿 1개(2줄) 원문 이관. 아래는 원문 그대로.
- ✅ [코디] 26.10.5 부재 표 행 [↔] 가로·세로 바꾸기([⧉] 오른쪽 · 값만 교환·결방향 불변 · 서랍앞판 가로≥450 은 사람용 지침 = 자동적용 0) + 인라인 검색창(필터 무관 · X · Esc · 「필터 모두 해제」는 검색 유지) — 운영
82ae4394(masteref1e288c) 23:12 KST · 검사C:\dev\pfs\scripts\_nesting_swapq_check.py로컬 63/63 · prod 15/16 · 회귀 11종 PASS · 표 최소폭 1149→1175(≤1180). ⚠ prod 1 FAIL = #18 이 운영에서 계속 바뀌는 중(행 170→172→171 · 지금 44장, 종전 코드로 돌려도 44장 — 코드 무관). 검증 기준 42장은 더 이상 안 맞는다.
✅ 26.10.5 · pfs-handoff-cap-1005b · handoff 캡 이관 (네스팅 저장본 열기 모달 폭 · 부재 표 헤더 겹침·ID 확인 표시)
[코디] 26.10.5 handoff 캡 관리 2차 — 「GS 원주·성포 병합」 절의 ✅ 하위 불릿 2개 원문 이관(같은 절의 ⏳ 애매점은 handoff 에 남김). 아래는 원문 그대로.
- 🆕 + 「📂 저장본 열기」 모달 가로 폭 확대 — 운영
42c8bed1(master9c860b48) 21:14 KST · [페페] 「네스팅 저장본 열기 모달 가로 폭을 더 늘려줘. 전체 컬럼이 다 보이지 않는다. 운영배포」.C:\dev\pfs\web\nesting\nesting.htmlCSS 9줄(web-designer 채택안 그대로) =#loadModal한정 셀렉터 · 폭min(1180px,96vw)·#ldTblmin-width 760 · 첫 칸(작업명) 줄바꿈 허용(keep-all+anywhere, min 240) · ≤560px 화면폭 꽉(max-height 92vh·모서리 0). 공용.nj-box.wide(#advModal·#dcModal) 무변경. 원인 실측 = 860px 모달에서 표 자연폭 915 > 리스트 824 → 🗑 칸 가림(작업명 최장 417px nowrap). - 검증: 새
C:\dev\pfs\scripts\_nesting_loadmodal_check.py(gitignore · 로컬 = 운영 목록 GET 1회로 실데이터 18건 목킹) 변경 전 13/16(1920·1366·1280 FAIL) → 로컬 16/16 ·--prod17/17(pfs.poin.co.kr · 쓰기 0 · 콘솔 0) — 1920·1366·1280 모두 모달 1180 · 리스트 1144/1144 스크롤 0 · 480 = 모달 480 · 표 760 리스트 안 가로 스크롤(페이지 스크롤 0) · 최소 글자 13px · #advModal·#dcModal 860·#saveModal 560 불변 · 회귀 advsort 46/46·rid_sort 30/30 · EC2 HEAD42c8bedblob 일치 · 사이트맵/production/nestingsame(미반영 1 = 무관한/field/worklog). 스크린샷C:\dev\_work\nesting-loadmodal-261005\loadmodal_{before,after_local,after_prod}_{1920,1366,1280,480}.png. - 🆕 + 부재 표 헤더 겹침 수정 + ID 칸 클릭 = 도면 확인 표시(노랑) — 운영
6c28441e(master619504ff) 21:27 KST · [페페] 「컬럼헤더가 데이터 위에 떠있는 느낌 · 데이터 스크롤이 컬럼위 빈틈 사이로 올라가는게 보인다 · ID를 클릭해서 노란색바탕 · 도면을 보면서 제품이 제대로 들어갔는지 확인 중 · 품명 포함 오른쪽 컬럼값들도 같은 색 · 운영배포」.C:\dev\pfs\web\nesting\nesting.html하나(web-designer 처방 채택). - 헤더: 원인 = 공용
th{position:sticky;top:0}에 z-index 없음 +.cellwrap(컬러 2줄 라벨) position:relative → tbody 칸이 DOM 순서로 헤더 위에 그려짐(재현: z 끄면 헤더 프로브 76점 중 5점이 컬러칸 INPUT). 수정 =th{z-index:3}(.cellwrap input:focus 2 위 · ▾ 팝업 4000·모달 9000 아래 — 실측). - 확인 표시:
td.ridcell클릭/Enter/Space =tr.ok토글(tabindex 0·role button·aria-pressed·title·focus-visible) · 노랑#ffe14d= ID 칸 + 품명~비고 7칸(td.okc, 액션칸 제외,cols===PART_COLS가드) + ID 칸 왼쪽 띠#b58900· 양단면·결방향 칩도 노랑(.warn 제외) · 🔑:where()로 특이도를td.cellsel(0,2,1)과 맞춰 범위선택 파랑·상충경고 분홍이 우선. 저장 = 켠 행만 parts JSONok:'1'(끈 행은 키 없음 · 스키마 0) · 불러오기 복원 · [⧉] 복사·[+]·Enter 새 행 = 확인 없음 · 정렬·필터는<tr>이동이라 따라감 · 소비처(autoFillMaterials·runNest·registerNewColors)는 키를 골라 읽어 무시. - 검증: 새
C:\dev\pfs\scripts\_nesting_rowok_check.py(gitignore) 로컬 31/31(원인 재현 · 1920/1366/1280 스크롤 400px 뒤 헤더 프로브 전부 TH · 토글·키보드·우선순위·정렬/필터 유지·payload ok 2행/나머지 키 없음·doSave 본문·불러오기 복원·복사/추가/Enter 비움·방향키 불변 · job14 장수 31=31 · 자재 자동등록 동일) ·--prod11/11(쓰기 0·콘솔 0) · loadmodal prod 17/17 재확인 · 회귀 advsort 46·advfilter 89·filter 53·rid_sort 30·import_keep 53·finishcode 21·colorpanel 47·drawer 65·rename_warn 32·advset_ui 32 전부 PASS · grid_modal 87/96·qa5 95/102 = 종전과 동수(노후 검사기 — ID칸·▾ 이전 기대값) · EC2 HEAD6c28441blob 일치 · 사이트맵 nesting same(미반영 1 = 무관한/field/worklog). 스크린샷C:\dev\_work\nesting-loadmodal-261005\rowok_header_{local,prod}_{1920,1366,1280}.png·rowok_toggle_{local,prod}.png. - ⚠한계: 확인 표시는 [💾 저장]해야 남는다(저장 안 하고 닫으면 사라짐) · 옛 저장본(#1~18)은 전부 미확인으로 열림.
✅ 26.10.5 · pfs-handoff-cap-1005 · handoff 캡 이관 1절 (네스팅 부재 표 ID 칸·정렬·다중필터·고급필터·조건 세트 서버 저장·정렬 모달)
[코디] 26.10.5 handoff 캡(20,000자) 관리로 원문 이관(미결 ⏳ 없는 절). NOW 에는 요약 1~2줄만 남겼다. 아래는 원문 그대로.
[코디] 🆕 26.10.4(일) — 네스팅 부재 표 ID 칸 + 헤더 클릭 정렬 + 기본 ID순 — 운영 950ac78e(master babad95a) 19:07 KST
[페페] 「타입순으로 항목이 들어와야 하는데 작업순이 달라 한 타입이 한번에 안 보인다. 기록 순서에 항목별 id 가 있으면 컬럼 정렬 + 기본 id순. 운영배포」
- C:\dev\pfs\web\nesting\nesting.html 하나. ID 칸(순번 뒤·읽기 전용 td.ridcell, 키 rid) = tread .treadwork.json InputRows no. 두번째 파일부터 「파일-번호」(2-15) · PNCAD·몸통재·손입력·Enter 새 행 = 빈칸. newCol+pasteSkip 이라 9/11열 붙여넣기 매핑 불변.
- 헤더 11칸(ID·타입·위치·두께·컬러·경면·품명·가로·세로·수량·비고) 클릭 정렬 = <tr> 이동(값·바인딩 보존) · 숫자칸 숫자비교 · 빈 값 늘 끝 · 안정 정렬(ID순 위에 타입 = 타입 안 ID순) · ▲▼ 토글 · aria-sort · Enter/Space. 토글 3칸(MDF/PB·양단면·결방향)은 제외.
- 기본 ID 오름차순 = tread 가져오기·저장본 불러오기 직후(ID 없으면 손 안 댐). 행 추가·복사·드래그·Alt+Shift·붙여넣기 = 정렬 표시 초기화. rid 는 parts JSON 왕복(스키마 변경 0).
- 검증: C:\dev\pfs\scripts\_nesting_rid_sort_check.py 로컬 30/30 · --prod 7/7(운영 ?job=14 열림·쓰기 0·콘솔 0) · job 14 장수 = 저장순·컬러▲▼·타입·가로▼·수량·역순 전부 31장(정렬 무관) · 기존 검사 import_keep 53/53·finishcode 21/21·colorpanel 47/47·drawer 65/65·rename_warn 32/32·grid_modal 87/96(HEAD 도 87/96 — 노후 검사기) · 사이트맵 /production/nesting same(미반영 1 = 무관한 /field/worklog).
- ⚠한계: 기존 저장본(#1~15)은 ID 가 없다 → ID순이 필요하면 tread JSON 을 다시 가져와 재저장. tread 가져오기는 여전히 remark 를 안 읽는다(이번 범위 밖). 1280px 에선 표 1163px > 박스 924px 가로 스크롤(전부터 넘침, 1920 은 1178px 로 안 넘침).
- 🆕 + 다중 필터 — 운영 22e87c14(master 3af17d91) 20:53 KST · [페페] 「커스텀 가능한 고급 필터 · 다중 필터 · 자재관리 필터처럼 · 운영배포」. 헤더 ▾(13칸, ID 제외) = 엑셀식 팝업(정렬↑↓·값 검색·체크+건수·필터 해제/확인, 칸끼리 AND·칸 안 OR, 후보 = 다른 칸 필터 통과 값). 숨김 = tr.pf-hide 뿐 → 네스팅·저장·자재 자동등록 전수(readGrid 무변경) · 순번 전체 기준 · 상태 메모리만 · 불러오기/가져오기/초기화/샘플 = 해제. 함정 = 붙여넣기 시 필터 먼저 해제 · 범위선택/방향키 = 숨긴 행 건너뜀 · 드래그/Alt+Shift = 필터 중 금지 · 새/복사 행은 다음 [확인]까지 보임. 헤더 좌우 padding 7→2px 로 폭 종전 이하(최소 1161→1148px, 1920 스크롤 0).
- 검증: C:\dev\pfs\scripts\_nesting_filter_check.py(gitignore) 로컬 53/53(wonju 2차 232행 타입2+컬러1 → 139행 · 장수 31=31 · 저장 payload 232행 전수 · 함정 4종 · 해제 4경로) · --prod 8/8(job14 180행 → 151 → 55행, 장수 31=31, 쓰기 0·콘솔 0) · rid_sort 30/30·prod 7/7 · import_keep 53/53·finishcode 21/21·colorpanel 47/47·drawer 65/65·rename_warn 32/32 · qa5 96/102·grid_modal 87/96 = HEAD 와 동수(노후 검사기). ⚠한계: 필터 중 여러 줄 붙여넣기는 필터를 푼 뒤 표의 연속 행에 붙는다(숨겨 있던 행을 덮을 수 있음 — 안내 문구로 확인 유도). 「resetPartSort 시 해제」는 행 추가·복사가 그 경로라 적용 안 함(새 행 보이게 두기와 충돌).
- 🆕 + 고급 필터 모달(조건 수동 입력) — 운영 012c16cb(master c14319a4) 21:17 KST · [페페] 「다중필터를 수동 입력해서 설정할수 있는 모달형식 필터기능도 필요하다. 처음에 요청한게 이거였어 · 기존 기능 그대로 · 운영배포」. 툴바 [고급 필터] → #advModal 조건 행 [컬럼][연산자][값]✕ · 문자 8종(trim·대소문자 무시) · 숫자칸(두께·가로·세로·수량) = ≠ > ≥ < ≤ 범위 a~b + 비어있음 2 · ID = 문자 연산자만(ridKey 숫자비교 안 씀) · 2줄+ AND/OR · ▾ 와 AND. 숨김 = partFiltOn()||advOn() · pfPass(..)&&advPass 한 길(함정·해제·안내 공유) · 상태 partAdv 메모리만 · 조건 세트 = localStorage nesting.advsets.v1(불러오기=채우기만) · ▾ 필터 가져오기(1칸만, 같음 OR) · [적용] 차단 = 빈 값(빨강)·숫자 아님·범위 꼴/순서·0행.
- 검증: C:\dev\pfs\scripts\_nesting_advfilter_check.py(gitignore) 로컬 88/88(연산자 21케이스·AND/OR·▾ AND·차단 7·숨김행 저장 232행 전수·장수 31=31·함정 5·해제 4경로·세트 저장→새로고침→불러오기 무적용·480px 접힘·job14 장수 동일) · --prod 8/8(job14 180→74행, 장수 31=31, 쓰기 0·콘솔 0) · filter 53/53·prod 8/8 · rid_sort 30·import_keep 53·finishcode 21·colorpanel 47·drawer 65·rename_warn 32 회귀 0 · 사이트맵 nesting same. ⚠한계: 조건 세트는 브라우저별(PC 바뀌면 없음) · OR 결과가 전 행이면 「숨긴 0행」 표시 그대로.
- 🆕 + 조건 세트 서버 저장(전사 공유) — 운영 d6f10d8a(master bc2e2e5f) 22:07 KST · [페페] 전사 공유·누구나 수정/삭제·같은 이름 덮어쓰기 확인·[서버로 올리기] 1회·운영배포. 새 테이블 nesting_filter_set(set_no PK·name VARCHAR(50) UNIQUE·conds TEXT JSON·user_no/name·modify_user_no/name·reg/modify_date, 운영 SSM 선생성 22:06 KST · 기존 테이블 변경 0) · API GET/POST /api/nesting/filter-set(같은 이름 409 code 4090 + exists → overwrite:true) · DELETE /api/nesting/filter-set/<set_no>(하드, 없으면 404). 화면 = 확인 바 #advCf(덮어쓰기·삭제·올리기 겹침 공용, confirm 0 · Esc = 바만) · 목록 「만든 사람 (고침 X) · 26.10.4(일)」 · 실패 안내+[다시 시도]. ⚠restplus Resource 에서 return jsonify(..), 409 튜플 = 500 → _json_status().
- 검증: C:\dev\pfs\scripts\_nesting_advset_api_check.py 로컬 33/33·test 30/30 · _nesting_advset_ui_check.py 로컬 32/32·test 17/17·prod 11/11(검증 세트 POST 1·DELETE 1, 운영 rows 0 확인 · 콘솔 0) · advfilter 88/88·prod 8/8 · filter 53/53·prod 8/8 · rid_sort 30/30·prod 7/7 · import_keep 53·finishcode 21·colorpanel 47·drawer 65·rename_warn 32 회귀 0 · 사이트맵 nesting same. ⚠한계: 이름 비교 = DB 콜레이션(utf8mb4_0900_ai_ci → 대소문자·악센트 무시 같은 이름) · 삭제 되돌리기 없음(하드).
- 🆕 + 모달 재구성 = 정렬 기준(다단계 ▲▼) 기본 · 조건은 하단 접힘 — 운영 5a3dfceb(master 7c724a91) 22:52 KST · [페페] 「고급필터는 특정 단어 검색 포함 여부가 아닌 오름차순,내림차순 조건을 기본으로 · 지금 기능은 별도 그룹으로 하단에 · 운영배포」. 위 = [컬럼(advSortCol·정렬 가능 11칸)][오름▲|내림▼][↑][↓][✕] ≤5 · 중복 거절(목록 회색 「n순위 사용 중」) · sortParts(keys[]) 비교기 체인(헤더 클릭 = 1단계·동작 불변) · [정렬 해제] = 표시 해제 + 기본 ID순 · 열면 지금 정렬로 채움(그대로 [적용] = 재정렬 안 함) · 아래 「추가 조건 (필터)」 0개면 접힘 · [적용] = 정렬→필터(검증 막히면 둘 다 안 함) · 배지 「고급 필터 (정렬 n · 조건 m)」 · 세트 JSON sort:[{k,dir}](스키마 0 · 서버 ≤5·화이트리스트·dir ±1·중복 거절·정렬만 세트 허용·옛 세트 []). 검증 = 새 _nesting_advsort_check.py 46/46·prod 7/7 · advfilter 89/89·prod 8/8 · advset_api test 40/40 · advset_ui 32/32·test 18/18·prod 12/12(검증 세트 POST1·DELETE1 → 0행) · 운영 틀린 sort 400 ×3(쓰기 0) · filter·rid_sort·import_keep·finishcode·colorpanel·drawer·rename_warn 회귀 0 · qa5 95/102 = HEAD 동수 · job14·wonju 장수 31=31 · 사이트맵 nesting same. ⚠한계: advset_api 로컬 모드는 이 PC venv(py3.9 werkzeug)로 Flask 앱 생성 불가 → test 서버로 대체.
✅ 26.10.2 · pfs-handoff-cap-1002c · handoff 캡 이관 1절 (GS 대전 도마변동 1차 후속 3건 — 11:55 최신·12:25 통합본·12:49 v2)
[코디] 26.10.2 handoff 캡(20,000자) 관리로 원문 이관(GS 안산 성포 한샘 6 재제작 절 추가분 상쇄). NOW 에는 요약·⏳ 포인터 1줄만 남겼다. 아래는 원문 그대로. 부모 절 = [코디] 🆕 26.10.1(목) — GS 대전 도마*변동(field 2175) 포인 견적 785 → PFS 한샘 견적 9 등록 + NAS 저장 — 코드 변경 0 · 운영배포 없음 (원문: archive.md 「✅ 26.10.2 · pfs-handoff-cap-1002b」)
- [코디] 🆕26.10.2(금) 11:55 KST [페페] 「1차 국내생산분도 최신작업 · 한샘 양식 엑셀 재작성 · 운영배포」 → 785(읽기만) 26.10.1 대비 = 84A 신발장 1,573,000→1,610,000 · 일반 59A 5줄·84B 7줄 추가(은경판·복도장식장·침실3 드레스룸 도어 신규 품명) · 시공비 3,500,000→7,000,000 · 운반비 400,000 · 총 26,981,000. 한샘 9 = form 11(비활성 · form 8 + 수납 갑지 3평형(59A·84A·84B, 22 절사·24~26 기타 빈칸·28 합계) + 내역서-수 3탭 + 59A·84B 내역서-주 «숨김»(엔진 슬롯용, 주방 갑지는 84A 1행) · 운반비 400,000 · 시공비 7,000,000 · form 10 = 같은 구조 r1, 수납 21행 아래 테두리 빠져 미사용으로 남김) · 앱 POST(delete-insert, 고아 0) 47칸 · 서버총액 19,582,048 · 블록 = 포인 품목구분(A1 신발장·P1 붙박이장·B1 파우더장·G1 공틀도어; 84B 공틀도어 7칸>6 → 침실3 드레스룸 도어는 붙박이장 블록, 픽스도아는 라벨 「단가 (50%)」라 안 씀) · 올림 누적이 수납 만원 경계를 넘어 +1,000 되던 것 → 2칸 적용률 1틱 내림. 엑셀(LO) = 주방 2,590,000(−2,000) + 운반비 400,000 + 수납 16,980,000(−9,000) = 생산비 19,970,000 + 시공비 7,000,000 = 26,970,000(−11,000) · 검사 154 ALL OK · _xlcheck·sfcheck 0 · 운영 다운로드 = 로컬 파트 차이 0 · NAS 새 파일
…\GS 대전 변동\(국산)한샘 GS 대전 도마변동 MH 견적서(최신 26.10.02).xlsx(100,697 B 바이트 일치, 페페본 102,557 B 그대로) · 스크립트C:\dev\_work\gs-daejeon-doma-1002b\(make_form10·hansem_v4·verify_v4·nas_put_v4) · 스냅샷C:\dev\_bench\gs-daejeon-doma-1002b\(785·한샘 10·form 1~9 불변). ⚠작업 중(11:22~11:51) 787 운반비 200,000→0(총 1,814,000) · NAS(수입)…xlsx93,986→651,135 B(11:40) — 코디 쓰기 아님 → 한샘 10/form 9(운반비 200,000 박힘)와 어긋남. ⏳[페페] ①−11,000 절사 그대로(주방 −2,000·수납 −9,000) ②블록 배치(59A 은경판→공틀도어 · 84B 복도장식장→신발장 · 84B 침실3 드레스룸 도어→붙박이장) ③59A·84B 주방 숨김 탭 방식 ④결재·발행일 = 785 견적일 2026.10.01 유지(10.02 로?) ⑤787 운반비 0 → 2차 한샘 엑셀 재작성 여부 ⑥form 10(미사용) 정리 ⑦수납 기타 0/빈칸 ⑧시공비 거래명세서 ⑨10월 한샘 월마감 ⑩도어 행 비움(재질). - [코디] 🆕26.10.2(금) 12:25 KST [페페] 「국내생산분·수입분 견적서 통합 — 국산 = 현장 메인, 수입의 국내생산분 = 보조, 타입 통일 금지, 수입 탭은 그대로 가져와 이름에 수입국내생산분 표기」 → 한샘 9 = 통합본(form 12 비활성 · 평형 6 = 59A·84A·84B + 59A(수입국내생산분)·84A(…)·84B(…) · 68칸 · 서버총액 21,397,277) — 탭
59A(수입국내생산분) 내역서-주식(엔진 규약 = 평형명+' 내역서-주' 라 표기는 평형명 쪽, 최장 18자) · 수입 탭 칸 값 = 페페 손수정본 (수입) 탭과 같음(평형명·현장명 칸 제외) + 페페가 넣은 평형별 주방 평면도 3장·쪽나눔·인쇄영역 그대로 · 주방 갑지 = 국산 84A → 절사 → 본오더 소계 / 수입국내생산분 3행(평형 칸 = 59A…, 구분 칸 = 「수입국내생산분」) → 절사 → 수입국내생산분 소계 / 기타(운반비 400,000) → 합계. 엑셀 = 국산 주방 2,590,000(−2,000) + 수입국내생산분 1,810,000(−4,000) + 운반비 400,000 = 주방 4,800,000 · 수납 16,980,000(−9,000) → 생산비 21,780,000 + 시공비 7,000,000 = 28,780,000(785+787 28,795,000 대비 −15,000). 한샘 10 = 787 최신(운반비 200,000→0, 1,814,000) → form 13(form 9 + 운반비 0 + 평면도) · 현장명 「…MH(수입국내제작분)」·담당 「문희라 차장」 = 페페 손수정본 값 → 운영 다운로드 = 페페본과 전 칸 값 같음(1,810,000). 검사 통합 152·한샘 10 32 ALL OK · _xlcheck·sfcheck 0 · 운영 다운로드 = 로컬 파트 차이 0(둘 다) · NAS 새 파일…\GS 대전 변동\(통합)한샘 GS 대전 도마변동 MH 견적서(26.10.02).xlsx(648,250 B 바이트 일치, 기존 3파일 그대로) · 스크립트C:\dev\_work\gs-daejeon-doma-1002b\(make_form12·make_form13·hansem_v5·verify_v5·nas_put_v5·nas_get) · 785·787·form 1~11 불변(snap_before_v5/after_v5). ⏳[페페] ①표기 「수입국내생산분」(지시) vs 페페본 「수입국내제작분」 통일 ②통합본 담당 = 서예진 사원(국산 기준) — 수입분 담당 문희라 차장 표기 필요? ③한샘 9(통합)·10(2차)에 수입 21칸이 이중으로 있음 — 10 을 보관(archive) 처리할지 ④−15,000 절사(주방 −2,000·수입 −4,000·수납 −9,000) ⑤위 ①~⑩ 중 남은 것. - [코디] 🆕26.10.2(금) 12:49 KST [페페] 「v2 = 수입산을 국내산 같은 탭에 「수입분」 그룹으로 구분해 포함」 → 엑셀만(PFS 미등록 — 엔진은 고정 블록 7칸뿐이라 그룹 머리행·그룹 소계를 못 내고, 같은 블록에 국산·수입이 섞이거나 단가군이 틀어짐 → 코드 변경 필요라 멈춤 · 운영 쓰기 0 · 한샘 9/10·form 1~13 불변
snap_after_v2). v1 운영 다운로드를 XML 로 재조립(C:\dev\_work\gs-daejeon-doma-1002b\make_v2.py): 보이는 탭 = 주방 · 59A·84A·84B 내역서-주 · 수납 · 내역서-수 3 · 단가기준(수입국내생산분 탭 삭제) · 84A 내역서-주 = 「◆ 국산 (1차 국내생산분)」 머리행(하늘색) + 국산 3블록 + 국산 소계 2,592,118 + 「◆ 수입분 (2차 수입의 국내생산분)」 + 수입 4블록 + 수입분 소계 709,399 + 총 합 3,301,517(배율 65→58%, 한 쪽) · 59A·84B = 수입분 그룹만(327,393·778,437) · 평면도 = 각 탭 총합 아래 다음 쪽 · 주방 갑지 = v1 과 금액칸 전부 같음(구분 「수입분」·「수입분 소계」만 다름) → 28,780,000. 검증verify_v2.py49 ALL OK(블록 칸 값 = v1 탭 · 소계 = v1 총합 · 내역서-수·수납·단가기준 = v1) · _xlcheck·sfcheck 0 · PDF 육안(머리행·소계·쪽나눔). NAS 새 파일…\GS 대전 변동\(통합)한샘 GS 대전 도마변동 MH 견적서(26.10.02) v2.xlsx(643,646 B 바이트 일치, 기존 5파일 그대로). ⏳[페페] ①v1·v2 중 정본 ②v2 를 PFS 에서 내려받게 하려면 엔진에 «그룹 블록» 기능(코드 변경·운영배포) 필요 — 할지 ③위 ①~⑤.
✅ 26.10.2 · pfs-handoff-cap-1002b · handoff 캡 이관 4절 (GS 대전 도마변동 2차(한샘 10)·1차(한샘 9) · 롯데 화성 향남 · 에넥스 9월 마감)
[코디] 26.10.2 handoff 캡(20,000자) 관리로 원문 이관(GS 원주·성포 마감재 네스팅 NOW 추가분 상쇄). NOW 에는 상태·미결 포인터 1~2줄씩만 남겼다. 아래는 원문 그대로.
[코디] 🆕 26.10.2(금) — GS 대전 도마변동 2차(수입주방) 포인 견적 787 → PFS 한샘 견적 10(form 9*) 등록 + NAS 저장 — 코드 변경 0 · 운영 DB 등록만(배포 없음)
[페페] 「2차 본건 작성(수입주방분, 국내생산=1차) · 현장매치 1:1 규칙 때문에 2차 견적서로 생성 · 한샘 엑셀 변환 · 나스 10월 한샘 폴더 · 운영배포」. 787(읽기만) = 59A·84A·84B 24줄(가림판·보강판·상부합판·9T쫄대·안정기함·휠라·아일랜드 멍장·벽판넬 · 하위내역 0 · 식세기 걸레받이 3줄 0원 무상) 1,814,000 + 운반비 200,000 + 시공비 0 = 2,014,000.
- form 9(비활성) = form 4 를 3평형(슬롯 77·84A·84B → 탭 59A·84A·84B 로 양식에서 미리 개명)·주방전용으로 깎은 787 전용판(84C·내역서-수·도면·「임서현」 도장 삭제 · 운반비 200,000 · 시공비 0 · S6 2026. 10. 02). 스크립트 C:\dev\_work\gs-daejeon-doma-1002\(make_form_suip.py · hansem_suip.py PLAN/FORM/REGISTER/EXCEL · verify_suip.py · nas_put_suip.py).
- 한샘 10 「(수입)GS 대전 도마변동 MH 한샘 견적서 (2차)」 · 담당 서예진 사원 · 21칸 · 서버총액 1,815,229 · 블록 = 상부장(안정기함)·하부장(멍장)·하부 FIX(가림판)·키큰 FIX(보강판·상부합판·쫄대·휠라·벽판넬, 선례 한샘 4·8) · 길이 = 주 치수×수량 · 등급 A · 도장 휠라 = 08 무광도장 · 적용률 올림. 걸레받이(0원)는 미적재.
- 엑셀(LO 재계산) = 내역서 1,815,229 → 만원 절사 1,810,000(−4,000) + 운반비 200,000 = 2,010,000(포인 2,014,000 대비 −4,000 = 갑지 만원 절사) · 운영 다운로드 = 로컬 빌드와 파트 차이 0 · _xlcheck 결함 0 · 흔적 0. 785·787·한샘 9·form 1~8 불변(스냅샷 C:\dev\_bench\gs-daejeon-doma-1002\).
- NAS \\192.168.0.101\공유폴더\2026현장\견적\10월\한샘\GS 대전 변동\(수입)한샘 GS 대전 도마변동 MH 견적서.xlsx(93,986 B, 되읽기 바이트 일치) · 페페본 (국산)…xlsx(102,557 B) 그대로.
- ⏳[페페] ①−4,000 절사 그대로(1차 ①과 같은 질문) ②787 이름 「(국산)…(2차)」 vs 비고 「수입주방」 — 정정 여부(포인 견적은 안 고침) ③걸레받이 0원 3줄을 «무상» 행으로 엑셀에 넣을지 ④부속 → FIX PANEL 블록 매핑 확인.
[코디] 🆕 26.10.1(목) — GS 대전 도마변동(field 2175) 포인 견적 785 → PFS 한샘 견적 9* 등록 + NAS 저장 (10월 마감건) — 코드 변경 0 · 운영배포 없음
[페페] 「포인 견적서 한샘 견적서 양식으로 등록 · 나스 저장 · 10월 마감건 · 운영배포」. 785 = 84A 3줄(장식장 상부장 932,000 · 장식장 하부장 1,061,000 · 주방 팬트리도어 599,000, 하위내역 5건 1,114,575 포함) + 시공비 900,000 + 운반비 200,000 = 3,692,000.
- 한샘 견적 9(form 5 · 84A 1탭 · 8칸 · 서버총액 2,592,118) — 블록 = 상부장·하부장·공틀도어, 하위내역(유리도어×4·EP·3면EP×3·벽체EP·EP×2)은 같은 블록 세트 칸 · 등급 A + 적용률 올림 역산.
- form 5(비활성) = form 4 를 1평형·주방전용으로 깎은 이 견적 전용판(슬롯 3개·GS 안산 도면·결재칸 「임서현」 도장 삭제 · 운반비 200,000 · 시공비 900,000 박음). 생성기 C:\dev\_work\gs-daejeon-doma-1001\make_form5.py · 등록 hansem_reg.py(PLAN/FORM/REGISTER/EXCEL).
- 엑셀(LO 재계산) = 본오더 2,592,118 → 만원 절사 2,590,000(−2,000) + 운반비 200,000 = 생산비 2,790,000 · 시공비 900,000 → 3,690,000(포인 3,692,000 대비 −2,000 = 갑지 만원 절사, rules L29). 운영 다운로드 = 로컬 빌드와 파트 차이 0 · _xlcheck 결함 0.
- NAS \\192.168.0.101\공유폴더\2026현장\견적\10월\한샘\GS 대전 변동\한샘 GS 대전 도마변동 MH 견적서.xlsx(82,729 B, 되읽기 바이트 일치). 전후 스냅샷 C:\dev\_bench\gs-daejeon-doma-1001\(785 불변 확인).
- 🆕15:17 KST [페페] NAS 엑셀 시공비 1,200,000 으로 직접 수정(+담당 S10 「문희라 과장님」→「서예진 사원」) → PFS 반영: 785 마스터 3칸만 DB UPDATE(시공비 1,200,000 · total/margin_total 3,992,000, PUT 안 씀 · 상세 3·하위 5 불변) · 한샘 9 form 5→form 6(AG26 만 1,200,000, 비활성) · 운영 재다운로드 = NAS 페페본과 S10 1칸 외 동일(생산비+시공비 3,990,000). ⏳[페페] 담당 서예진 사원을 한샘 9 manager_name 에도 넣을지(미반영). 스크립트 pfs_update.py·make_form6.py·verify_cons.py.
- 🆕15:48 KST [페페] 「일반가구 추가로 포인 견적 최신화 · 시공비 인원 늘어 금액 증가 · 한샘 엑셀 재생성」 → 785(읽기만) = 주방 3 + 일반 5줄(신발장·현관 팬트리도어·파우더장·드레스룸 도어·침실3 붙박이장, 하위 12건) · 운반비 400,000 · 시공비 3,500,000 · 11,886,000 → 한샘 9 = form 7(form 6 + 정본 수납 갑지·84A 내역서-수 이식 make_form7.py) · 20칸 · 담당 서예진 사원 · 앱 경로 POST 갱신(delete-insert, 고아 0) hansem_v2.py → 엑셀 생산비 8,380,000(주방 2,990,000 + 수납 5,390,000) + 시공비 3,500,000 = 11,880,000(−6,000 = 주방 −2,000·수납 −4,000 만원 절사) · NAS 새 파일 …\GS 대전 변동\한샘 GS 대전 도마변동 MH 견적서(일반가구 추가).xlsx(89,505 B, 바이트 일치 · 1차 페페본 92,217 B 그대로).
- 🆕16:45 KST [페페] 「수납 명세서에도 자재비·운반비·절사 행(기본양식)」 → form 8(수납 갑지 22~24 기타 + 25 소계 복원, 주방과 대칭, 값 빈칸) · 한샘 9 form_no 7→8(DB 1칸, 상세 20줄 불변) · 운영 엑셀 11,880,000 그대로(_xlcheck 0 · 흔적 0). ⛔NAS 교체 안 함 — 우리 「(일반가구 추가)」 파일과 1차 페페본이 폴더에서 사라지고 페페 손수정본 (국산)한샘 GS 대전 도마변동 MH 견적서.xlsx(102,494 B, 16:42, Excel 열림)만 있다. 그 파일과 우리 form 8 출력 차이 = 수납 기타 값(페페 0 / 우리 빈칸) · 수납 합계 =O21(값 같음) · 20행 절사 위치(페페 L열 / 우리 A:N 병합).
- ⏳[페페] ①−2,000 절사 그대로 둘지 ②시공비 거래명세서(2.시공비…) 따로 만들지 ③10월 한샘 월마감(아직 없음)에 담기 ④도어 행 비움(재질 미확인). 🔴덤 발견 = 운영 form 3·4 출력(한샘 견적 6·7·8)에 결재칸 「임서현」 도장 + GS 안산 성포 도면이 그대로 실린다(7·8 은 타 현장 도면) — 재발행 여부 판단 필요.
[코디] 🆕 26.9.28 — 롯데 화성 향남 MH 본건(779)+추가1(780) 한샘 양식 엑셀 — 6차까지 완료 (원문: archive.md 「✅ 26.9.29 · pfs-handoff-cap-0929」)
최종 = 한샘 협의 총 90,000,000(VAT 별도) · 시공비 11,300,000(지엠테크 명세서) · PFS 779/월마감 20 동일 반영 · NAS …\견적\09월\한샘\롯데 화성 향남\ · 코드 변경 0. 🔴779 PUT 이 하위내역 69줄을 지움(복구함, rules 🆕). ⏳[페페] 한샘 견적 8(PFS 한샘 전용 견적, 780 만 540,239) 처리 판단 대기.
- [코디] 26.9.30 ACC룸 추가건 엑셀 = 6,540,000(VAT 별도) · NAS …\09월\한샘\롯데 화성 향남\한샘 롯데 화성 향남 MH 견적서(추가_ACC룸).xlsx · PFS·기존 파일 불변. ⏳[페페] 본건 파일(90,000,000)에 ACC룸(6,702,000)이 아직 포함 = 이중청구 위험 → ①본건에서 ACC룸 뺀 새 본건(추천) ②추가건 6,702,000 기준 재작성 ③그대로. (상세 원문: archive.md 「✅ 26.10.1 · pfs-handoff-cap-1001」)
[코디] 🆕 26.9.28 — 에넥스 9월 월마감(close_no 21) 완료 — 현재 23,694,000(26.9.30) (원문: archive.md 「✅ 26.9.29 · pfs-handoff-cap-0929」)
- 781 대우 용인 추가1 · 782 금호 구미 추가1 · 783 라인 VIP 추가1 · 금호 본건 765 · 운영배포
5dee8ae6· 현재 23,694,000. ⛔781·782·783 은 페페 직접수정본 — 단가·운임 스크립트 재실행 금지. 🆕26.9.30 라인 VIP 추가2 = 견적 784 · 369,000(10월 마감 대상, 783 에서 26.9.30 상차 그룹 FK 이동 · 783 1,480,000 + 784 = 1,849,000 일치) · NAS 10월\에넥스 폴더 신설. 상세·스크립트·백업 경로 원문 = archive.md 「✅ 26.10.1 · pfs-handoff-cap-1001」 - ⏳[페페] 확정금액(NEGO) 입력 · 782 단가 확인 · 라인 VIP 단가 확인(막음판 ㄷ자·PW합판·4.5T 띠·도장 가산) → 바뀌면 마감 21 동기화. ⏳다음달(10월)분 = 라인 VIP 발주서 p6~8 — 🆕26.9.30 10월분 추가2 784 가 생겼으니 p6~8 을 784 에 더할지 별도 추가3 인지 [페페] 판단 · 10월 에넥스 마감 만들 때 784 담기. [페페] 메일(네이버 임시본 58350)은 코디 작업 대상 아님.
✅ 26.10.2 · pfs-handoff-cap-1002 · handoff 캡 이관 2절 (견적서 목록 보류 요약 · worklog Jev 폴백 측정 결론)
[코디] 26.10.2 handoff 캡(20,000자) 관리로 원문 이관(GS 대전 도마변동 2차 수입주방 절 추가분 상쇄). NOW 에는 상태·미결 포인터 1줄씩만 남겼다. 아래는 원문 그대로.
[코디] ⏸ 26.9.28 — 견적서 목록(/estimate/list-v2) 개선 — 보류([페페] 「나중에 하자, 시드 기록만. 추후 다시 물어볼게」)
[페페] 지시 = 견적서 목록 우측 버튼 정리 + 금액 세분화 폴딩. ✅결정 = 주방·일반 수량 컬럼 숨김. (지시 원문 archive.md 「✅ 26.10.1 · pfs-handoff-cap-1001」)
- ⏳그릴링 1차 미답(코디 추천 = 전부 A): Q1 버튼 = N차·수정·출력만 노출 + 「더보기 ▾」(+추가건·추가건 엑셀·재작성·삭제[빨강 맨 아래]) / B 아이콘 / C 2줄 · Q2 펼침 = 모든 본건 행 / B 추가건 있는 행만 · Q3 금액칸 = 「견적금액」(본건) 유지 + 「총합(본건+추가)」 칸 추가 / B 의미 변경 / C 그대로.
- 2차 예정 질문 · 코드 사실(estimate_list_v2.html L556~580 · monthly_close_service.get_estimates 재사용) · 착수 시 web-designer 상담+코덱스 상의+devplan 신설 — 원문 archive.md 「✅ 26.10.1 · pfs-handoff-cap-1001」
[코디] 🆕 26.9.22 — worklog 추정현장 자동연결에 Jev 판정모델 폴백 — 26.9.23 오프라인 측정 완료 → 구현 보류(코드 0줄) · ⏳[페페] 선택
🔴[코디] 26.9.23 측정 결론(D1) = 안 켠다. Jev 실호출 723회 · 입력 575,667토큰(≈$0.024) · 429/401 0. 운영 DB 읽기전용 재현 = 묶음 1,097 · 보류 686.
(Jev 측정 상세·설계 당시 원문·Jev 얼리액세스 체크리스트 = archive.md 「✅ 26.10.1 · pfs-handoff-cap-1001」 · session-2026-09-23-worklog-jev-measure.md · devplan pfs-worklog-jev-autolink.html)
✅ 26.10.1 · pfs-handoff-cap-1001 · handoff 캡 이관 (롯데 ACC룸 · 에넥스 784 · 견적서 목록 보류 상세 · worklog Jev 설계 원문 · ✅ 2건 · 완료 소항목 34줄)
[코디] 26.10.1 handoff 캡(20,000자) 관리로 원문 이관(GS 대전 도마변동 절 추가분 상쇄). NOW 에는 요약·⏳미결 줄만 남겼다. 아래는 원문 그대로.
[이관 원문] 롯데 화성 향남 ACC룸 추가건 엑셀(26.9.30)
- [코디] 🆕26.9.30(수) ACC룸 추가건 엑셀 = 6,540,000(VAT 별도) · [페페] 「본건 ACC룸+84(개선) 합친 것 중 ACC룸만 추가건 견적서 엑셀 · NAS · PFS 수정 안 함」 → 원본 =
…\롯데 화성 향남\한샘 롯데 화성 향남 MH 견적서(본건+추가1)_포인 견적 최종비용.xlsx84A(개선) 탭 53~102행(넥서스 2차 본건 K202·779 6차 전 값과 일치) 5항목 → 신규 NAS\\192.168.0.101\공유폴더\2026현장\견적\09월\한샘\롯데 화성 향남\한샘 롯데 화성 향남 MH 견적서(추가_ACC룸).xlsx(추가1 양식, 운반·시공 0). 빌드·검증C:\dev\_work\hansem-hwaseong-combined\acc\(build_acc.py·verify_acc.py ALL PASS). PFS·기존 NAS 파일 불변. ⏳[페페] 본건 파일(90,000,000)에 ACC룸(6차 ×1.0248 = 6,702,000)이 아직 포함 = 이중청구 위험 → ①본건에서 ACC룸 뺀 새 본건 파일(추천) ②추가건을 6,702,000 기준 재작성 ③그대로.
[이관 원문] 에넥스 9월 월마감(21) 상세 2건(781~783 · 라인 VIP 추가2 784)
- 781 대우 용인 추가1 · 782 금호 구미 추가1 · 783 라인 VIP 추가1(1,585,000) · 금호 본건 765 적용 · 차수 전환 시 추가건 따라오기 운영배포
5dee8ae6. ⛔781·782·783 은 페페 직접수정본 —step2_price.py go·step5_freight.py·line_vip_as_2026-09\s2~재실행 금지(스크립트C:\dev\order-automation\enex_daewoo_as_2026-09\·enex_kumho_2026-09-29\·line_vip_as_2026-09\). - [코디] 🆕26.9.30(수) 라인 VIP 추가2 = 견적 784 · 369,000 · 4줄(10월 마감 대상) — [페페] 「추가1 의 26.9.30(수) 상차 탭을 이동해 추가2 작성, 추가2 = 10월 마감 · 추가1 까지 지금 수정내용으로 9월 마감」. 783(페페 수정본 1,849,000 = 27줄) 중 「26.9.30(수) 상차」 그룹(운임 60,000 + 신발장 상부 190,000·47,000 + 주방 하부장 72,000)을 빈 추가2 마스터(POST, 부모 704) +
estimate_detail.estimate_noFK UPDATE 로 detail_no·값 그대로 이동(PUT 안 씀) → 783 = 1,480,000(23줄) + 784 = 369,000 = 1,849,000 1원 일치. 마감 21 저장 = 캐시 24,155,000 → 23,694,000(라인 VIP 1,480,000 · 금호 캐시도 페페 782 수정 1,100,000 반영 = 화면값 그대로, 784 미포함). 10월 에넥스 마감은 없어서 안 만듦 — 784 는 담기 창에unpaid로 뜬다. NAS 교체\\192.168.0.101\공유폴더\2026현장\견적\09월\에넥스\에넥스 라인 VIP 내수 견적서.xlsx(704 출력pages=종합,sub:783= 페페 13:16 저장본과 같은 방식) ·…\09월\에넥스\에넥스 9월 마감.xlsx(페페 13:17 엑셀 저장본에 D8 + 수식 캐시 4칸만 zip 수술, 서버 출력과 셀 차이 0) · 신규\\192.168.0.101\공유폴더\2026현장\견적\10월\에넥스\에넥스 라인 VIP 내수 견적서.xlsx(폴더 신설,pages=종합,sub:784). 백업C:\dev\_bench\line_vip_2026-09-30\(snap/db before·after JSON ·nas_backup\). 스크립트C:\dev\order-automation\line_vip_2026-09-30\(s0~s9). 운영 화면 확인 = 목록 704 밑 추가1 1,480,000(마감) · 추가2 369,000(미입금) · 월마감 에넥스 2026-09 계 23,694,000. 코드 변경 0 → 배포 없음.
[이관 원문] 견적서 목록 개선 보류 — 지시 원문·결정
[페페] 지시 원문 = 「오른쪽 버튼 메뉴가 너무 많아 한 폭에 다 안 보인다 · 항목별 폴딩/펼침으로 금액 세분화 — 본건, 추가건별, 각각 시공비, 분할 금액, 합산 금액을 단계별로 체계화 · 운영배포」. - ✅결정 1건 = 주방·일반 수량 컬럼 숨김([페페] 「중요하지 않다, 숨김해도 된다」).
[이관 원문] 견적서 목록 개선 보류 — 2차 질문·코드 사실
- 2차 예정 질문 = 펼침 표 단계 구조(본건 가구·시공·소계 → 추가n 같은 3칸 → 합계) · 출력 제외(include_in_print=0) 추가건 합산 포함 여부.
- 사실(코드 확인) = 행 액션 최대 7버튼(
web/templates/finance/estimate/estimate_list_v2.htmlL556~580) · 펼침은 추가건 보유 본건만(est-fold,subRowsHtml= 이름·입금·일자·금액) · 목록 금액 = 본건margin_total_amount만 · 가구/시공/총합 분할은monthly_close_service.get_estimates에 이미 있다(본건+subs) → 재사용하면 월마감과 규칙 한 벌. - 착수 시 = web-designer 상담 필수 · 코덱스 상의 · devplan 페이지 신설.
[이관 원문] worklog 추정현장 Jev 폴백 — 측정 상세·설계 원문
설계 임계 0.90 에서 보류분 자동연결 0건(변형 5종·모델 2종 8회 전부) — 정답 p 0.45~0.93 / 오답 p 0.43~0.85 가 겹쳐 오연결 없는 임계가 없다. 패널 칩 0.60 정밀도 16/29(55%).
대표 오답 = 「의정부 현장」 강동식 통화 → GS 의정부(2023) 0.85. 「해당없음」 p≥0.90 정밀도 94.6%(263/278). 「정답 라벨이 DB에 있다」도 틀렸다(site_name 보존 쌍 14쌍/19건).
판단 ① 은 이미 해소(26.9.22 A안 _PANEL_MIN_SCORE=80·커버 0.6 운영 반영 확인). ⏳[페페] 선택 = ①보류(추천) ②「해당없음」 p≥0.95 묶음을 숨김 검토 목록으로(새 기능·그릴링) ③설계대로 꺼진 채 구현(비추천).
상세 = session-2026-09-23-worklog-jev-measure.md · devplan §12 · 증거 C:\dev\_work\jev\worklog-measure\. 아래는 설계 당시 원문.
[페페] 「Jev 를 내 자산에 클로드와 융합」 → 그릴링 Q1 = A(worklog 우선) · Q2 = A(보류 679 전체).
🔴실측이 전제를 뒤집었다 — 운영 dry = 묶음 1,087 / 자동연결 0 / 후보없음 408 / 보류 679(주석의 「81%」는 틀렸다, 실제 100% 미연결).
그래서 오히려 안전하다 = Jev 가 망칠 기존 동작이 없다. 범위를 weak(6%) → 보류 679 전체로 넓힌 이유도 이것.
✅한국어 스모크 3/3(키 없이 playground) · ✅키·엔드포인트 실측 확정(공식 api.typesafe.ai, model 필수 · 게이트웨이는 401) ·
✅실호출 = choice 0.950 / conf 0.94 / 470토큰. 🔑해당없음 옵션이 오연결 방어의 전부(코덱스 지목 최대 사고를 그게 잡는다).
설계 = _jev_choice(HTTP) · _jev_verdicts(저장) · _ai_rank(순위 바꾸는 유일 함수 — 모달 후보와 패널 칩 0번이 항상 같아야 한다는 기존 모순금지 조항).
폴백 철칙 = 키 없음·오류·예외 전부 「오늘과 완전히 동일」 + 10분 브레이커 → 키를 빼는 것이 킬스위치.
⚠자동연결 UPDATE 가 site_name 을 덮어써 오연결 시 원본이 사라진다 → 감사로그 detail 에 원 site_name·worklog_nos 필수(유일한 복원 경로).
🔑정답 라벨이 이미 DB 에 있다 — 패널 단건 클릭은 site_name 을 보존하므로 그 쌍이 사람이 만든 정답 = 임계 측정 재료.
⏳[코디 체크] 26.9.23 Jev = 얼리액세스(26.9.15~) 단계 — [페페] 「코디가 요청한 결제 API 인가 뭐가 있었는데 얼리액세스라 그런 것 같다」. 결제는 공식 콘솔 https://console.typesafe.ai/ 크레딧 선불뿐이고 결제 화면 미확인(로그인 필요). Jev 작업 재개 시 먼저 확인: ①콘솔에 크레딧·결제 메뉴가 열렸는지(페페 화면 캡처) ②GET https://api.typesafe.ai/v1/models 로 키 살아있음·잔여 크레딧 ③안 열렸으면 hello@typesafe.ai 문의 또는 무료/프로모 크레딧 한도 안에서만 임계 측정. ⛔비공식 jev-agent.com·jev-ai.pro·jevtypesafeai.com·jevplayground.com 결제 금지. 운영 반영은 유료 크레딧 확보가 전제.
함정 2건 = rules.md 🆕 맨 위 · devplan C:\dev\devplan\pfs-worklog-jev-autolink.html · 증거 = C:\dev\_work\jev\
[이관 원문] 진행중 ✅ 2건(/field/regist 자동완성 · 네스팅 partWrap 폭)
- ✅[코디] 26.9.30
/field/regist크롬 자동완성 전체 차단(페페 QA: field_user 드롭다운) — 공용blockChromeAutofill(document)+shown.bs.modal재사용, form·input·textarea·selectautocomplete=off, 회색화 방지 CSS(#field_form input[data-noautofill]{background:#fff;opacity:1}, web-designer 처방). 1파일field_regist.html· master5374a3b·c6756b7→ 운영배포db51b24(페페 채팅 승인, 선별 포워드). 테스트·운영 DOM 20/20(모든 input/textarea/select autocomplete=off, focus 후 readonly 해제·한글 타이핑·인라인검색 정상). 사이트맵 재빌드 = 미반영 1(/field/worklog, 이번 건 아님). ⚠폰 실기(첫 탭 키보드)·IME 첫 글자 씹힘은 헤드리스로 확인 불가 → 페페 눈 확인 필요. 검증 스크립트 = 세션 scratchpadregist_ac_check.py(미보관). - ✅[코디] 26.9.29 네스팅 부재표
#partWrap폭 1000→1180px(.col·#partGrid max-width 동값) → master8d10d4f· 운영배포19f2c57(페페 채팅 승인, 1파일 체리픽 blob 일치). 1920 실측 운영 전 scrollW 1082>clientW 998 → 후 1178==1178. 사이트맵 nesting same(미반영 1=/field/worklog 별건). devplan pfs.html DONE AW.
[이관 원문] 완료 소항목 34줄(제목만)
부자재 발주서 QA 2차: 현장검색 안 잡힘 — 운영 b084520 완료 (상세: projects/pfs/archive.md)
네스팅 QA 2건: 컬러패널 인라인수정·두께상충경고 — 운영 a09f365 완료 (상세: projects/pfs/archive.md)
네스팅 드롭리스트 「셀 우측 동일라인」 펼침 — 운영 8873334 완료 (상세: projects/pfs/archive.md)
생산현황 출력 메모칸 세로2분할+미입고보드 — 운영 d535760 완료 (상세: projects/pfs/archive.md)
네스팅4차: 부재표 우측 「사용컬러」 패널 — 운영 9d3c601 완료 (상세: projects/pfs/archive.md)
배차 요율감시 수리(Actions→미니PC 이전) — 완료, 운영배포 없음 (상세: projects/pfs/archive.md)
네스팅3차: 드롭토글·행드래그·컬럼폭+비고칸 — 운영 975ccad 완료 (상세: projects/pfs/archive.md)
네스팅2차: 상단고정·컬러구분색·datalist폐기 — 운영 60b1eb4 완료 (상세: projects/pfs/archive.md)
네스팅 QA 5건(버튼줄·제목·칼라DB·Enter점프·계산기) — 운영 de24c6f 완료 (상세: projects/pfs/archive.md)
에넥스 발주서 변환복구(.xlsx전환+사이드카워치독) — 운영 5f2c383 완료 (상세: projects/pfs/archive.md)
GS 원주 단구 한샘견적서 84A(기본) 추가+부자재분리 — 운영 5d9bd2f+7cb6ea1 완료 (상세: projects/pfs/archive.md)
발주서 정리 탭 모바일 전용 레이아웃 — 운영 12e8efb 완료 (상세: projects/pfs/archive.md)
포인↔한샘 매칭표 비교축 재정리(추가금액 분리) — 완료 (상세: projects/pfs/archive.md)
생산현황 출력 미확정헤더제거·아이비젼축약·여백50% — 운영 198744d 완료 (상세: projects/pfs/archive.md)
업체 필터 「봉적」 버튼 추가 — 운영 3cdd6e6 완료 (상세: projects/pfs/archive.md)
넥서스→한샘 자동전환+신영광주 추가2·3 — 운영 dfd1435 완료 (상세: projects/pfs/archive.md)
파레트용지 한샘로고 NEXUS 제거 — 운영 2fb811f 완료 (상세: projects/pfs/archive.md)
생산현황 상차일미확정 프레임+자동완성차단 — 운영 53c4391 완료 (상세: projects/pfs/archive.md)
/admin/user 검색칸 크롬 자동완성 재발차단 — 운영 98c4841 완료 (상세: projects/pfs/archive.md)
시트·보드 모바일 줄밀림 수정 — 운영 cfbb5db 완료 (상세: projects/pfs/archive.md)
오엠씨 3페이지 모바일 표 A안 — 운영 624b63c 완료 (상세: projects/pfs/archive.md)
오엠씨 모바일목업 폐기+메뉴 업체별그룹 — 운영 dcad1d9 완료 (상세: projects/pfs/archive.md)
아이비젼글로벌 현장유형=AS 재전환 — 운영DB 반영 완료 (상세: projects/pfs/archive.md)
현장목록 유형관리 모달+상차일 KO — 운영 2507c20 완료 (상세: projects/pfs/archive.md)
QA 3건(검색자동완성·모바일사이드바·월마감폭) — 운영 690bb89 완료 (상세: projects/pfs/archive.md)
「생산자동화시스템」→PFS 전면교체 — 운영 ddd9135 완료 (상세: projects/pfs/archive.md)
사이드바 로고=PFS(텍스트) — 운영 12338c8 완료 (상세: projects/pfs/archive.md)
모바일 햄버거 항상 3줄 — 운영 0434506 완료 (상세: projects/pfs/archive.md)
상세모달=코디 정리본(kb_digest) — 운영 30cf5af 완료 (상세: projects/pfs/archive.md)
업체 전용 현장목록 모바일 3차 — 운영 6e7c8f9 완료 (상세: projects/pfs/archive.md)
업체 전용 현장목록 2차 — 운영 168f21d 완료 (상세: projects/pfs/archive.md)
업체 전용 현장목록 QA 6건 — 운영배포 완료 (상세: projects/pfs/archive.md)
발주서정리 원자재→부자재 오분류 수정 — 운영배포 완료 (상세: projects/pfs/archive.md)
AWS 비용절감 Phase A·B — RDS-test→Docker 이전 + RI 구매 (26.8.6~8.7) — 완료 (상세: projects/pfs/archive.md)
✅ 26.9.30 · pfs-handoff-cap-0930b · handoff 캡 이관 2절 (AL발주서 차수 탭 + 미결 포인터 7줄 · GS 안산 성포 한샘양식 A~G)
[코디] 26.9.30 handoff 캡(20,000자) 관리로 원문 이관(GS 안산 성포 현장별 자재 절 추가분 상쇄). 포인터 줄의 상태·카운터는 원문 그대로 —
mem_find.py --text 미결 --project pfs로 회수. GS 안산 성포 포인터는 handoff 「26.9.30 — GS 안산 성포 … 현장별 자재 초안」 절로 옮겼다.
[코덱스] 🆕 26.9.21 — AL발주서 차수 탭·행선택 복사/이동 — 완료 (상세: archive.md 「✅ 26.9.21(월) KST · pfs-al-orderpaper-round · [코덱스] AL발주서 차수 탭·행선택 복사/이동 (운영 c02bd4f)」)
-
[진행중·미결1] poinimos02 에 「PFS 생산 인쇄」 앱 설치(SSH 원격만) → archive.md 「✅ 26.9.18(금) KST · pfs-print-app-poinimos02」
-
[진행중·미결3] 스티커 출력 「라벨·이름표」 탭(위험성평가 경고표지+일반 이름표, 운영배포
94be2c7→5785d9b) → archive.md 「✅ 26.9.18(금) KST — 스티커 출력 「라벨·이름표」 탭 신설」 -
[진행중·미결6] 견적서 「미등록 현장 임시기재 → 현장 진행」(운영배포
e860647+QA 2건398eacd+6a134dd완료) → session-2026-09-17-estimate-temp-site.md -
[종결·미결1] 용산 나진 MH 도면(LL-F·UL-C) 모델공간 통합본(EXPORTLAYOUT+-PURGE, 스킬
dwg-flatten) → session-2026-09-17-najin-dwg-flatten.md - [진행중·미결5] 도어발주서 포인탭→월드산업 「월드」 탭 변환 → session-2026-09-16-door-order-world-tab.md
- [진행중·미결1] 학동매장 원부자재발주서 「피앤알」 탭 인쇄+팩스발송 → session-2026-09-16-hakdong-pnr-order-fax.md
- [진행중·미결3] 용산 나진 상가 네스팅→원부자재발주서+경면코드 자동적용(운영
c7790d0) → session-2026-09-15-najin-wonbujae-order.md
GS 안산 성포 한샘양식 재작성 A~G — 운영등록 estimate_no=6 완료 (상세: projects/pfs/archive.md)
(당시 미배포였던 api/pfs/hansem/ 는 26.9.9 세션에서 운영배포 완료 — 아래 GS 원주 단구 절 참조)
- [진행중·미결3] GS 안산 성포 MH 주방 견적 초안(포인·한샘 양식, 길이견적만, 포인 운영등록
estimate_no=769) → session-2026-09-07-gs-ansan-seongpo-estimate.md
✅ 26.9.30 · pfs-handoff-cap-0930 · handoff 캡 이관 1절 (월마감 현장별 거래명세서)
26.9.30 handoff 캡(20,000자) 관리로 원문 이관. 미결(⏳)은 handoff 요약에 남김.
[코디] 🆕 26.9.29(화) — 월마감 현장별 거래명세서 신설 — 운영 38158edc(master c7c1d099) 16:27 KST
[페페] 운영 월마감 검증보고 「현장별로 거래 명세서 양식 … 포인 사업자 등록 정보를 넣어서. 봉적은 제품출고 되면 해당 현장 거래명세서를 요청한다」 · 그릴링 Q1~Q3=A · 채팅 「운영배포」.
- 월마감 표 각 행 [명세서] → 새 탭 /estimate/monthly-close/<no>/statement/<seq>(A4 1장, 브라우저 인쇄, 일자 기본 = 현장 출고일, 표기 「2026년 9월 29일」). API /api/monthly-close/<no>/statement/<seq>. 줄 = 현장명·본건·추가N(추가분)·시공비(한샘형)·금액 조정(수기 합계)·NEGO, 세액 줄마다 10% 절사. 공급자 = common/utils/poin_supplier.py(견적서 공용, 출력 회귀 0). 규칙 = rules.md 🆕 26.9.29.
- 업체관리 사업자 칸 «빈 칸만» 보충(얼마에요 ERP 미러 (localdb)\HM3, 26.8.27 기준): 봉적 445 = 128-81-18132 김형천 파주 봉암길 244 · 에넥스 4 = 220-81-31765 박진규,송성수 · 넵스 5 = 893-81-03728 김호균 · 아이비젼글로벌 452 = 695-02-01209 + 주소. 한샘 1 = 빈칸 유지([페페] 결정 — 한샘넥서스 114-81-68690 ↔ 한샘 법인 불명확). 백업 C:\dev\_bench\monthly-close-statement\company_before.json.
- 검증 = 자체검사 테스트 72행 · 운영 98행 ALL PASS(NEGO 39·시공비 42·금액 조정 8) · 마감 21 대우 용인 2,105,000 / 210,500 / 2,315,500 일치 · 견적서 출력 전후 동일(테스트 3·운영 4건, data JSON + 엑셀 시트 XML) · Playwright(테스트 13·14, 운영 21) PDF 1쪽·13px·저장 전 막기·행 순서 경고·JS 오류 0. 사이트맵 60→61쪽, 미반영 1(/field/worklog, 남의 건). devplan pfs-monthly-close-statement.html.
- ⏳QC1 SSH 22 불통 — 26.8.27 Win11 업그레이드 이후(HM3 미러 동기화 C:\dev\hm3\sync.log SKIP 지속, 마지막 OK 26.8.27 17:53 KST). poinimos01 경유도 22 닫힘·445 열림, poin912 SMB 로는 C:\Users\main\Desktop\매출마감\ ACCESS_DENIED → ERP 원본 대조·거래명세서 PDF 사본 못 받음. 복구 = projects/hm3/rules.md 「업그레이드가 SSH를 죽였다」(main 자격 필요).
- ⏳사람 눈: 실물 A4 출력 1장(도장·머리글/바닥글) · 얼마에요 원본 출력본과 모양 대조.
✅ 26.9.29 · pfs-handoff-cap-0929 · handoff 캡 이관 4절 (네스팅 #8 복구 · 롯데 화성 향남 6차 · 에넥스 9월 마감 · 발주서 dedupe Jev)
26.9.29 handoff 캡(20,000자) 관리로 원문 이관. 미결(⏳)은 handoff 요약에 남김.
[코디] 🆕 26.9.29 — 네스팅 저장본 #8(호반 대구 칠성) YEN70-SG 도어 소실 복구 + 가져오기 덮어쓰기 수정 — 운영 5fd14421(master e784497b)
[페페] QA 15:09 「yen70-sg 칼라 넘버로 작성한 내용이 사라지고 pncad 작업본 내용이 테이블을 덮었다. 복구·운영배포」. 원인 = 화면 경로(코디 스크립트 아님): nginx 로그 08:31:09 PUT #8(도어) → 08:31:17 PNCAD 실행이 부재 표를 확인 없이 통째 교체 → 08:31:23 저장 기본값 「덮어쓰기」로 #8 소실(nesting_job 이력 없음). 복구 = RDS PITR 별도 인스턴스 pfs-pitr-nest8-0929(08:31:15 KST)에서 원본 읽어 병합(도어 2행 + PNCAD 11행 = 13행, 15:33 KST) · 백업/스크립트 C:\dev\pfs\_restore\nesting_job8_2026-09-29\(--rollback 가능). 수정 = 입력 있으면 추가(기본)/교체/취소 모달 · 교체·초기화 뒤 저장 기본값 「새 작업」+경고 · 0건이면 표 유지. 검사 C:\dev\pfs\scripts\_nesting_import_keep_check.py 로컬 39/39 · --prod 12/12. ⏳PITR 인스턴스 삭제 승인 대기(stopped) · ✅칠성 원부자재 발주서 도어 누락 해결 → 16:22 KST 3차(페페 답변 반영: 오엠씨 YEN70-SG/유사PP 18T MDF 1 · 길동상사 펫시트 20m→오엠씨 + A4샘플→선재기업(주소 진영LDM) · 도어엣지 100m · EM738 피앤알 양면 15T 3·3T 1 + 한솔 PP시트 40m · EM738 18T 1매·엣지 제외(PNCAD 오류 확인 중) · 스티커 4). 사본 NAS 09월\_백업\…_v1백업/_v2백업.xlsx. ⏳운영 동기화 시 stock(재고량) 칸이 자리 기준 UPDATE 로 어긋남 · 상세 projects\pfs\session-2026-09-29-chilseong-wonbujae-order.md 「3차」.
[코디] 🆕 26.9.28 — 롯데 화성 향남 MH 본건(779)+추가1(780) 한샘 양식 엑셀 1개 — 3차 완료·NAS 교체 (1·2차 원문·3차 상세: archive.md 「✅ 26.9.28 · pfs-hansem-hwaseong-combined」)
NAS \\192.168.0.101\공유폴더\2026현장\견적\09월\한샘\롯데 화성 향남\한샘 롯데 화성 향남 MH 견적서(본건+추가1).xlsx = 주 5평형·수 4평형 실명 탭 · 하위내역 세트 노출 · 780 수납 174,000 분리 · 운반비 900,000(배차 7건 비율) → 생산비 76,831,000 · 시공비 19,000,000 · 총 95,831,000(1원 일치, LO 재계산). 빌드 = C:\dev\_work\hansem-hwaseong-combined\build_v3.py. 규칙 = projects/hansem-estimate/rules.md 🆕 26.9.28 5줄.
🆕4차(26.9.28) [페페] 「본건은 넥서스 제출본(\\192.168.0.101\공유폴더\2026현장\견적\08월\넥서스\롯데 화성 향남\넥서스 롯데 화성 향남 MH 견적서 (2차) 견적서.xlsx, 95,180,000) 기준 · ACC룸+84A(개선) 한 탭 · 큰제목 행 구분 · 금액 합산」 → 본건 가구 75,580,000(PFS 779 대비 +189,000, 120·84A(개선) 주방 11항목 금액 다름 — 하위내역은 PFS 값, 차액은 본체 칸) · 주방 4평형(84A(개선) 탭 = 「■ 개선세대」 4~52행 + 「■ ACC룸」 큰제목 53행 + 54~102행 블록 한 벌, 총합 O103) → 생산비 77,020,000 · 총 96,020,000(1원 일치, LO 재계산) · NAS 교체(이전본 _before_v4.xlsx). 빌드 = build_v4.py(+lo_prep_v4.py). ⚠PFS 779 는 제출본과 11항목 금액이 다르다(수정 안 함).
🆕5차 [페페] 「+189,000 조정해 원래 총액 95,831,000 으로 · 본건 세부 수정 가능 · 추가건 유지」 → 본건 금액 = PFS 779 항목값(75,391,000 · 구성·규격·ACC 통합 탭은 제출본) · 갑지 주/수 = 84B 6,372,000/7,429,000 · 84C 8,033,000/9,652,000 · 120 9,210,000/12,106,000 · 84A(개선)+ACC 13,029,000/9,560,000 → 생산비 76,831,000 · 총 95,831,000(LO 재계산 일치) · NAS 교체(이전본 _before_v5.xlsx).
🆕6차 [페페] 「한샘 협의 총 90,000,000(VAT 별도) · 시공비 = 지엠테크 시공비 거래명세서 총액 · 나머지는 본건 가구 · PFS 한샘 견적·월마감 동일 반영」 — ①이전본 NAS …\롯데 화성 향남\한샘 롯데 화성 향남 MH 견적서(본건+추가1)_포인 견적 최종비용.xlsx 백업 ②시공비 = \\192.168.0.101\공유폴더\2026현장\견적\09월\한샘\시공 지엠테크\시공비 거래명세서 롯데건설 화성향남 MH.xlsx 합계 11,300,000 ③본건 가구 = 78,700,000 − 추가 540,000 − 운반비 900,000 = 77,260,000(779 항목 비례 ×1.0248, 1,000원) → 엑셀 생산비 78,700,000 · 총 90,000,000 NAS 교체(build_v6.py, 이전본 _before_v6.xlsx) ④PFS 견적 779 = 상세 56줄 금액(원가 유지·마진에 차액) · 시공비 11,300,000 · 운임 600,000 → total 89,160,000(+780 840,000 = 90,000,000) ⑤월마감 20 롯데 = 본건 77,860,000 + 추가 840,000 + 시공비 11,300,000 = 90,000,000 · 확정 90,000,000(다른 5행 불변). 🔴779 PUT 이 하위내역 69줄을 지웠다 → 즉시 복구(rules 🆕). 코드 변경 0 → 운영배포 없음.
⏳[페페] 한샘 견적 8(PFS 한샘 전용 견적, 780 만 540,239) 처리 — 판단 대기.
[코디] 🆕 26.9.28 — 에넥스 9월 월마감(close_no 21) = 30,258,000 완료 · 대우 용인 추가1 781 · 금호 구미 추가1 782 (1~11차 원문: archive.md 「✅ 26.9.28 · pfs-enex-close-2026-09」)
- 781 = 2,390,000 · 782 = 1,456,000 → ⛔둘 다 페페 직접수정본 —
step2_price.py go·step5_freight.py재실행 금지, 고칠 땐 현재값 읽어 부분 변경. 스크립트 =C:\dev\order-automation\enex_daewoo_as_2026-09\. - NAS
\\192.168.0.101\공유폴더\2026현장\견적\09월\에넥스\마감표·현장별 견적서 저장(대우 용인 = 추가건 번호 출력 「종합+추가1」만). - ⏳[페페] 네이버 poin912 임시보관함 mailSN 58350(강동식 차장
kds5841@hanmail.net, 첨부 3) — 본문 금액 5줄 뺄지(기존 7·8월 = 인사 3줄뿐). IMAP 꺼짐 → CDP 9348C:\dev\pw-chrome-profile(cdplease acquire/release). - ⏳[페페] 확정금액(NEGO) 입력 · 782 단가 확인 → 바뀌면
step6_close_sync.py로 마감 21 동기화. - [코디] 🆕26.9.29(화) 금호 구미 본건 = 765(2차) 19,009,000 적용 — 페페가 차수를 765로 바꿈(767 4차 26,412,000 → 보관) → PFS 마감 21 금호 행 본건 767→765(POST
/api/monthly-close) = 마감 21 합계 22,570,000(대우 2,105,000[페페 781 수정] + 금호 19,009,000 + 추가1 1,456,000). NAS에넥스 금호 구미 MH 견적서 견적서.xlsx본건 탭 단가 I열 19칸 + 수식 캐시만(zip XML 수술, 종합 20,465,000) ·에넥스 9월 마감.xlsxC7 한 칸 + 합계 캐시(페페 수작업 비고·「라인 VIP」 행 보존). 스크립트C:\dev\order-automation\enex_kumho_2026-09-29\· 원본 백업C:\dev\_bench\enex_kumho_2026-09-29\nas_orig\. 코드 변경 0 → 배포 없음. - [코디] 🆕26.9.29(화) 차수 전환 시 추가건이 새 차수로 따라오게 — 운영배포
5dee8ae6(masterf63a8fa6) · [페페] 「변경한 차수건으로 추가건은 가져와야 한다」.switch_active_estimate(…, carry_from)에 부모 이동 1문(선택 = 쓰던 본건의 추가건, 재작성 = 원본의 추가건). 자체검사C:\dev\pfs\scripts\_est_revision_carry_subs_check.py(테스트 서버: 옛 코드 FAIL 재현 → 새 코드 PASS). 데이터 = 앱 경로로 767 선택→765 선택 → 782 부모 765·사용 중, 5건 항목·하위내역·금액 전후 동일, 마감 21 = 22,570,000 유지, 운영 목록 「▶ 추가 1」 확인(백업C:\dev\_bench\enex_kumho_2026-09-29\move782_before.json). 사이트맵 전후 미반영 1(/field/worklog, 남의 건). - [코디] 🆕26.9.29(화) 라인 VIP 추가1 = 견적 783 · 1,585,000(본건 704 · 7월 마감) — 자료
\\192.168.0.101\공유폴더\2026현장\진행중\9월\AS 라인 VIP 내수건\AS 라인 VIP 내수도어발주서.xlsm포인탭 p1~5(N5 페이지번호) 유상 21줄 + 운임 2줄(#1778 150,000 · #1780 50,000) = 23줄, 1차 단가 코디 추정(에넥스 선례 · 도장 가산 없음 · p1 JARVIS 벽판넬은 가공비만 490,000 — 원단은 704 「시스템 2차벽판넬」 533,000 으로 7월 청구됨). [페페] 운임 1775~1777·1774·1783 제외, 1791 = 10월분. 마감 21 = 22,570,000 → 24,155,000(라인 VIP 행 추가 + 다른 행 비고만 NAS 손수정 표기로 맞춤). NAS 신규\\192.168.0.101\공유폴더\2026현장\견적\09월\에넥스\에넥스 라인 VIP 내수 견적서.xlsx(783 단독 출력, 본건→추가1 zip 치환) · 교체…\09월\에넥스\에넥스 9월 마감.xlsx(새 출력 + 수식 캐시 채움 6,712B · 손수정 비고 유지 · 이전본C:\dev\order-automation\line_vip_as_2026-09\_nas_backup\). 운영 화면(https://pfs.poin.co.kr) 확인 = 목록 704 밑 「추가1 · 2026-09-29 · 1,585,000」 · 월마감 에넥스 2026-09 계 24,155,000. 스크립트C:\dev\order-automation\line_vip_as_2026-09\(line_build → s2~s6). ⏳다음달(10월)분 = 같은 발주서 p6~8(p6 가스배관장·후드장 천판·SB장 우라판 / p7 신발장 9줄 U 무표기 / p8 신발장 키큰CP·드레스룸 상부휠라, 운임 후보 #1791) — 목록 =python C:\dev\order-automation\line_vip_as_2026-09\line_build.py끝부분. ⏳[페페] 단가 확인(막음판 ㄷ자 4만 · PW합판 반장 1.5만 · 「침실2」 4.5T 띠 3만 · 도장 가산 여부) → 바뀌면 마감 21 라인 VIP 행 동기화 필요. - [페페] 26.9.29 「메일 작업은 안 한다」 — 네이버 임시본 58350(첨부 3개 구버전) 코디 작업 대상 아님. 재작성 시 추가건 따라옴 = 추천대로 유지 확정.
[코디] 🆕 26.9.23 — 발주서 dedupe 경계만 Jev · intake-check 명세서 대조 Jev 섀도 (분배 D2)
[페페] 「진행 … api 실제 사용해봐라」. ①dedupe R1 경계(날짜 다른 부분집합·규칙이 살린 같은 탭 같은 발주처 블록)만 Jev noul — NAS 정리 전 재구성 37블록 측정에서 별도 발주 7블록(피앤알 7.9·효산 9.16 포함) p 0.06~0.16, 중복 0.82~0.98, 애매 1건 0.53 → 살리고 확인 목록+텔레그램. Jev 는 규칙보다 더 빼지 않는다. 동기화 PC 작업본에 즉시 적용 — 현재 NAS 결과 규칙만일 때와 동일(18블록/40항목·확인 0). pfs bd9c790.
②intake-check 규칙 애매 품목에 Jev choice(+해당없음) — 과거 명세서 23장 재판독 × 운영 행 재생 = 규칙 12 + Jev 28(28/28 정답). 운영 PATCH 라 섀도(원장 jev_shadow·텔레그램만). tools 33e4209.
✅[페페] 「반영 켜라」 → 켬(tools a0d35ef · 다음 16:30 실행부터 · 원장 applied[].jev_p 로 구분 · 끄기 = JEV_APPLY=False/--no-jev). ⏳코디 = 첫 Jev 반영분 verdict 대조. 상세 = projects/pfs/session-2026-09-23-orderpaper-jev.md · devplan pfs-orderpaper-jev.html.
✅ 26.9.28 · pfs-enex-close-2026-09 · 에넥스 9월 월마감(21) + 대우 용인 781 · 금호 구미 782 (1~11차)
26.9.28 handoff NOW 에서 원문 이관(캡 관리). 미결은 handoff 요약에 남김.
[코디] 🆕 26.9.28 — 에넥스 9월 월마감(close_no 21) + 대우 용인 AS 추가1 = 견적 781 (운영 데이터 · 코드 변경 0)
[페페] 「에넥스 9월 월마감 작성. 본건은 마감했고 추가건 파일 새로 견적서 작성. 추가건 1차로 본건 하위에 등록하고 월마감까지」 → 결정 = 자료 \\192.168.0.101\공유폴더\2026현장\진행중\8월\AS 에넥스 대우용인SH\AS 에넥스 대우용인SH 도어발주서.xlsm 포인탭 · 마감 구성 A(대우 용인 추가1 + 금호 구미 본건) · 단가 = 「나」(코디 1차 추정 → 페페 확인).
- 추가1 = door-order-import(유상 전량 p1~12) → 781, 부모 747(8월 마감 본건). 86줄 · 접음 49 · 무상 13.
- 1차 단가(청구가, master margin 0 · detail NULL) = 장은 본건 자당 × W/300 × 0.82(747 전체마진 −18%) — 상부 코너장 21.1~22.3만 · 84C 키큰장 20.5만 / 보강목·각목 5천(2440 여유분 1만) · 서랍 측판 1.5만/날개 5천 · 지판 1.5~2만 · 도어 7만 · 이동선반 1만 · EP 3만(ㄱ자 아일랜드 4만 · 폭600↑ 키큰EP 9만) · S/R 8만(폭600↑) · 픽스판넬 8만. 합계 2,829,000.
- 9월 마감 21 = 대우 용인(본건 0 · 추가1 2,829,000, 비고 「본건 8월 마감 · AS 추가1」) + 금호 구미 형곡3차 767 본건 26,412,000 = 29,241,000. 엑셀 셀 대조 OK(D6·C7).
- 스크립트·엑셀 = C:\dev\order-automation\enex_daewoo_as_2026-09\(step1 등록 · step2 단가 규칙 · step3 마감).
- 🆕2차(같은 날) 금호 구미 AS 추가1 = 견적 782([페페] 「금호 구미 AS추가 건도」) — \\192.168.0.101\공유폴더\2026현장\진행중\9월\AS 에넥스 금호 구미 형곡3차MH\AS 에넥스 금호구미MH 도어발주서.xlsm 유상 11줄(p1~4) → 부모 767. 767 은 전체마진 +24% 라 장 계수 1.24(클리닝룸 상부장 670 = 29.8만×2). 규칙 추가 = 높이 2100↑ 도어 10만(슬라이딩도어) · 문틀재 3만. 합계 1,066,000. 마감 21 금호 행 추가금액1 반영 → 마감 합계 30,307,000(엑셀 D7 확인).
- 스크립트 범용화 = step2_price.py 에 EST_NO·EST_DC·EST_SRC 환경변수(781 재계산 2,829,000 회귀 없음).
- 🆕3차 — 운임 + 금호 p6([페페] 「배차목록 확인해서 운임 추가 · 날짜 안 맞으면 다음 배차일에 한번에 나간 걸로 · 대우 용인 오엠씨→포인 무시 · 운임 최상단, 생산건 순 · 금호 6페이지 추가」) — step5_freight.py(재실행 안전: 운임 줄 지우고 다시 만든다). type_name = 실제 배차일 「26.8.23(일) 상차」, 그룹마다 운임 첫 줄 → 페이지 순. 운임 = 배차 freight_cost. 금호 p6(클리닝룸 하부도어 666×698) = U열 무표기라 파서가 빼는 것을 지시대로 강제 포함(7만) · p5(팬트리 도어 10/1)는 원래 있던 무표기라 제외.
781 = 운임 6그룹 835,000(8/23 5T×2 56만 ← 8/21 상차 p1~6·11 · 8/24 6만 · 8/25 5만 · 8/27 7만 · 8/28 5만 · 9/7 5.5만) + 생산 2,829,000 = 3,674,000 / 782 = 운임 55만(9/16 33만·9/17 10만·9/18 12만) + 생산 1,136,000 = 1,686,000(p6 10/2 상차 = 이후 배차 없어 운임 없음). 마감 21 = 31,772,000.
⚠[페페 판단] ①8/23·9/16~18 은 본건 배차(job_type 본건)다 — 본건 747 운반비 600,000 · 767 운반비 450,000 과 이중청구 가능. 규칙대로 넣었다. ②배차 #1730(8/29, 8만)은 맞는 페이지가 없어 안 넣었다.
- 🆕4차 — [페페] 「대우 용인 23일 상차건은 본건 포함이라 운임 생략 · 11페이지 상차날짜 오기 → 29일 배차로 분리 + 운임」 → step5_freight.py JOBS 에 no_freight·ship_override 옵션. 781 = 8/23 묶음 운임 없음(p1~6) · p11 → 8/29 #1730 8만 분리 → 운임 365,000 + 생산 2,829,000 = 3,194,000. 마감 21 = 31,292,000. 🆕5차 [페페] 「금호 구미도 동일하게」 → 9/16·17·18(전부 job_type 본건) 운임 생략 → 782 = 생산만 1,136,000(12줄). 마감 21 = 30,742,000. ❌오해였다 — 7차 [페페] 「금호 구미에도 운임 포함해줘. 아직 작업이 안된 거 같다」 → step8_add_freight.py(현재값 보존, 묶음 맨 위에 운임만 삽입) 9/16 33만·9/17 10만·9/18 12만 복원 → 782 = 1,686,000(15줄). 마감 21 = 30,488,000. 🔑교훈 = 「동일하게 수정」처럼 방향이 둘로 읽히는 지시는 뺄지 넣을지 먼저 되묻는다. 운임 규칙은 현장별(대우 8/23 = 본건 포함 생략, 금호 = 본건 배차여도 포함)이라 일반화 금지.
- 🆕6차 — [페페] 781 직접수정(92→80줄, 2,755,000) 후 「보강목 내용 모두 삭제 — 무상서비스 처리」 → step7_drop_bogang.py(현재값 읽어 보강목 포함 줄만 제거, 백업 781_before_drop_*.json) 40줄 365,000 삭제 → 781 = 2,390,000(40줄). 마감 21 = 29,938,000(대우 2,390,000 + 금호 27,548,000) → 7차 후 30,488,000. ⛔페페 직접수정 이후라 step5_freight.py·step2_price.py go 재실행 금지(덮어쓴다) — 이후 수정은 현재값 읽어 부분 변경만.
- ✅9차 완료(26.9.28) — [페페] 「에넥스 월마감 작업 모두 완료」. 최종 = 781 2,390,000 · 782 1,456,000(페페 수작업) · 마감 21 = 30,258,000(마감↔견적 정합 확인). NAS \\192.168.0.101\공유폴더\2026현장\견적\09월\에넥스\ 에 에넥스 9월 마감.xlsx · 에넥스 대우 용인 MH 견적서 (2차) 견적서.xlsx(본건+추가1) · 에넥스 금호 구미 MH 견적서 (4차) 견적서.xlsx 저장(step9_save_nas.py, 덮어쓰기 금지). ⏳확정금액(NEGO) 미입력.
- ✅10차 — [페페] 「강동식 차장에게 보낼 9월 월마감 메일 네이버 poin912 임시저장본, 파일 첨부, 기존 메일 형식 참고」 → 네이버 임시보관함 mailSN 58350 「포인 - 9월 마감내역/견적서」 → kds5841@hanmail.net(CC 없음) · 첨부 3개(NAS 파일명 = 페페가 차수 뺀 이름 「에넥스 대우 용인 MH 견적서 견적서.xlsx」 등). 형식 출처 = 8/24·7/22 발송분(본문 3줄 인사 · 금액 없음). ⚠이번 초안엔 9월 내역 금액 5줄이 들어갔다(기존 형식엔 없음) — 페페 판단. 경로 = poin912 IMAP 꺼짐(AUTH failed) → CDP 9348 C:\dev\pw-chrome-profile 세션 살아 있어 브라우저로 작성(서브에이전트 sonnet).
- ✅11차 — [페페] 「대우 용인 본건은 마감 완료했는데 엑셀에 같이 포함됐다. 수정 + 메일 임시본도」 → 추가건 번호로 출력(/api/estimate/print/excel/781)하면 추가1만 나오지만 시트명·종합 라벨이 「본건」 → zip XML 치환으로 「추가1」(fix_781_xlsx.py, 🔑이 출력기는 시트 XML 한글을 숫자 문자참조(본건)로 쓴다 — 평문 치환 안 먹음). 747 출력본 추가1 시트와 618칸 동일. NAS 파일 교체(구버전 mail_att\_old_* 백업) · 메일 58350 첨부 교체(149.5→96.1KB, 임시본 1통 유지). 🔑본건이 이전 달에 마감된 현장은 현장별 견적서를 추가건 번호로 출력한다.
- 🆕8차 [페페] 운임 규칙 확정(→ rules.md 🆕 2026-09-28): 본건 배차 날짜와 겹치는 추가건은 운임 생략 · 10/2 등 예정 상차는 «예정운임»(매번 페페 확인). 이번 782 조정(9/16~18 운임 제거 + 10/2 예정운임)은 페페가 수작업 — 코디는 데이터 안 건드림. 현재 운영 782 = 1,686,000(운임 3줄 포함, 페페 수정 전). 수정 끝나면 마감 21 동기화 필요(step6_close_sync.py, 현재값 읽는다).
- ⏳[페페] 782 단가 확인 · 확정금액(NEGO) 입력(화면에서 단가를 고치면 마감 21 행 금액은 담기 재실행 또는 행 수정 필요 — 코디에 말하면 step6_close_sync.py 로 동기화)
✅ 26.9.28 · pfs-hansem-hwaseong-combined · 롯데 화성 향남 MH 본건+추가1 한샘 양식 엑셀 1~3차
26.9.28 handoff NOW 에서 원문 이관(캡 관리).
[코디] 🆕 26.9.28 — 롯데 화성 향남 MH 본건(779)+추가1(780) 한샘 양식 엑셀 1개 (읽기전용·NAS 저장, DB 변경 0)
[페페] 「한샘 롯데 화성 향남 견적 — 본건+추가건 전부를 한샘 양식 엑셀 1개로, 도면 생략·사업자등록증 포함, DB 쓰기 금지」.
산출 = NAS 2026현장\견적\09월\한샘\롯데 화성 향남\한샘 롯데 화성 향남 MH 견적서(본건+추가1).xlsx(143,676 bytes, 기존 파일 안 건드림).
🔴등록 form3/4("MH 주방전용")는 수납(S) 시트가 완전히 비어 있어 씀 → 원본 3평형 정본(NAS 1.생산비 거래명세서_... 계열)으로 전환 — rules.md 신규 참고.
🔴그 원본에 다른 고객(라인건설 아산) 실데이터 유출 위험(카톡 스크린샷 3장·실제 도면 6장·자재비/추가분견적 실품목·843행 사양표) → 전부 제거, 남긴 이미지는 포인 사업자등록증(공급자 포인·134-16-31582)+도장뿐.
5평형(84B/84C/120/84A(개선)/ACC룸)을 3슬롯에 병합(84A(개선)→84C 접두, ACC룸→120 접두) · sub-item 45건/11,525,000원은 margin_total_amount 에 이미 포함되어 있어 별도 블록 없이 본항목에 흡수.
금액: 가구합계 목표 75,931,000(779 상세합 75,391,000+780 상세합 540,000) vs 파일 산출 75,920,000(차 −11,000, 갑지 만원내림 절사가 주방/수납 각자 적용되는 구조상 오차, rules.md 신규 참고) + 운반비 900,000(779 자체 600,000+780 자체 300,000, 판단) = 파일 표기 총 76,820,000. 시공비(779, 19,000,000)는 관례대로 미포함(별도 파일).
작업폴더 = C:\dev\_work\hansem-hwaseong-combined\(build.py·sanitize_and_fix.py·strip_leaked_images.py·drop_price_ref_sheet.py·verify2.py ALL PASS).
[코디] 재점검 = 안 쓰는 공유문자열에 「라인 아산7차(리뉴얼) M/H」·「현장(아산) 5톤」 + workbook absPath(넥서스 폴더) 잔존 → zip 수술로 비움(scrub_hansem.py, 흔적 0 · 시트 14 · 이미지 4 유지 · 이전본 _before_scrub.xlsx). ⚠파일의 저장된 계산값이 옛 값(주방 합계 캐시 12,930,000) — fullCalcOnLoad=True 라 엑셀에서 열면 재계산되지만 미리보기(카톡·모바일)엔 옛 숫자 → 발송 전 엑셀로 한 번 열어 저장 필요(이 PC엔 Excel·LibreOffice 없음).
🆕26.9.28 2차 — [페페] 재지시 「추가건 본건에 포함하지 마라, 주방·수납 나눠서 추가건 내역으로 빼라, LibreOffice 설치해서 그걸로 작업」 ✅ 완료·NAS 교체.
- LibreOffice 26.8.0.3 설치(winget, headless 전용 — --headless --invisible -env:UserInstallation=file:///C:/temp/loprofile). GUI 안 뜸, 작업 후 soffice 프로세스 0(자동 종료 확인).
- 780(추가1) 9줄을 본오더에서 완전히 빼서 추가분견적(주방가구) 시트에 내역 입력(전량 field_type=K → 수납쪽 추가분 = 0줄). 슬롯 배정 84B(3줄·157,000)/84C(1줄·58,000)/120(5줄·325,000) = 합 540,000(PFS 780 상세합 정확히 일치, 수량1×단가=목표액 직접입력이라 반올림 오차 0).
- ⚠form2 원본은 이 추가분견적 시트에도 라인건설 실데이터가 남아 있었다 — 우리가 쓰는 행만 채우면 안 쓰는 행(84C 슬롯 13-20 등)의 실금액이 소계에 섞여 84C 소계가 58,000 아닌 292,803으로, 운반비 탭도 300,000 아닌 1,160,000으로 잘못 나왔다(1차 시도 실측) → 쓰기 전에 A:M(운반비는 A:H, N/I 열=공급가액 수식은 남겨둔다) 전부 비우는 걸로 수정.
- 779 는 그대로 본오더(sub-item 45건 포함 종전 방식 유지) · 갑지 절사 5곳을 모두 동적 수식(-MOD(...))으로: 주방 O22(본오더)·O30(추가분)·O34(자재비+운반비 소계) / 수납 O24(본오더)·O31(추가분).
- 운반비 = 780 자체 300,000만(779 것 600,000은 안 섞음 — 「기타-운반비 기존 규칙대로」 재해석, 운반비 탭 1줄 직접입력 → I18 합계로 갑지 O33 자동 반영).
- 재계산 결과(LibreOffice --convert-to xlsx 로 열기→저장, openpyxl data_only=True 로 캐시값 확인): 주방 본오더소계 36,640,000 + 추가분소계 540,000 + 소계(자재비0+운반비300,000) 300,000 = 주방 합계 37,480,000. 수납 본오더소계 38,740,000 + 추가분 0 = 수납 합계 38,740,000. 파일 총액(주방+수납) 76,220,000, 목표(779 상세합 75,391,000+780 540,000+780 운반비 300,000=76,231,000) 대비 −11,000(주방·수납 갑지가 각자 만원 내림 하는 구조상 불가피, rules.md 신규).
- 이미지·서식 확인: 사업자등록증(image2, 공급자 포인 134-16-31582)+도장 유지, LibreOffice 재저장 후에도 merge cell 113개·수식·이미지 앵커 전부 정상(openpyxl 로 재확인). 다른 고객 흔적(라인건설/아산/나움/SD테크/넥서스) grep 0건 — 오히려 LO 재저장이 안 쓰는 공유문자열까지 자동으로 걷어냈다.
- NAS 교체: 기존본 C:\dev\_work\hansem-hwaseong-combined\_before_v2.xlsx 로 백업 후 같은 경로(...\한샘 롯데 화성 향남\한샘 롯데 화성 향남 MH 견적서(본건+추가1).xlsx, 130,427 bytes)에 덮어씀.
- 작업폴더 = C:\dev\_work\hansem-hwaseong-combined\(build_v2.py·sanitize_v2.py·verify3.py). LibreOffice 설치·정제 함정 = rules.md 🆕.
- [코디] 2차 점검 = 주방 갑지 AG36(시공비) 12,930,000 = 원본 타 현장 하드코딩값 → 779 시공비 19,000,000 으로 교체(fix_ag36.py). 🔴서브에이전트의 LO 변환은 실제로는 재계산 안 된 것(기본 설정) → 프로필에 OOXMLRecalcMode=0 넣고 재변환 → 진짜 재계산값 주방 37,480,000 · 수납 38,740,000 · 생산비 76,220,000 · 생산비+시공비 95,220,000. 흔적 0 · 이미지 4 · 백업 _before_ag36.xlsx.
~~⏳페페 판단 5건~~ → 🆕26.9.28 3차 [페페] 답 5건 반영·NAS 교체 완료 — ①평형 병합 금지 = 실제 이름·개수대로(주 5탭 84B·84C·120·ACC룸·84A(개선) / 수 4탭, ACC룸은 주방만) ②블록 = 개별 항목 · 하위내역(estimate_detail_sub 69줄)은 그 블록 세트 칸으로 드러냄 ③운반비 = 배차 7건(포인→현장, 실 575,000) 비율 ×1.565 → 900,000(235·235·70·70·110·110·70천, 5천원 단위) ④한샘 양식 규칙 = 9/23 파이프라인(C:\dev\_work\hansem-0926\) 함수 재사용 ⑤「새 정본」 = 안 만든다(한샘 원본 양식 변환이 곧 이 작업).
780 재분류 = 주방 366,000(식세기 3·EP 2·S/R) / 수납 174,000(안방 붙박이장 천판·120 신발장 천지판·칸막이) — 2차의 「780 전량 K」 판정은 오류(DB field_type 을 믿었다).
결과(LO 실재계산) = 주방 37,910,000(본오더 36,644,000+추가 366,000+운반비 900,000) · 수납 38,921,000(본오더 38,747,000+추가 174,000) · 생산비 76,831,000 · 시공비 19,000,000 · 총 95,831,000 = 779 상세합 75,391,000+780 540,000+운반비 900,000 과 1원 단위 일치(절사 없음). 흔적 0 · 이미지 = 사업자등록증 1.
빌드 = C:\dev\_work\hansem-hwaseong-combined\lo_prep_form.py(LO UNO: 내역서 슬롯 복제·주방 갑지 2행 삽입 → v3\form5.xlsx) → build_v3.py(DB 읽기만) → LO 재계산본 v3\lo\ → put_v3.py(NAS 교체 · 이전본 _before_v3.xlsx). 검산기 evalwb.py 탭명 괄호 오인 1줄 수정 · build.py rebuild_add_sheet 에 src_rows 인자(기본값 불변).
⏳[페페] PDF 육안(C:\dev\_work\hansem-hwaseong-combined\v3\lo\한샘 롯데 화성 향남 MH 견적서(본건+추가1).pdf 33쪽).
✅ 26.9.23 · pfs-dispatch-photo · 배차 계산서 사진 1~4차 (운영 3178216·f612c90·998dcfd·d18e5ad)
26.9.28 handoff NOW 에서 원문 이관(캡 관리).
[코디] 🆕 26.9.23 — 배차 계산서 사진 장수·확대·등록첨부·삭제 — 운영배포 3178216 완료(master 5f048dd)
[페페] 검증보고 18:05 (/dispatch/list #dcPhotoDrop2) 「사진을 넣으면 버튼에 사진 숫자를 끝에 달아서 표시 · 업로드된 사진 섬네일 보이게 하고 클릭하면 확대 · 배차 등록에도 같은 기능 · 배차 등록,수정에서 사진 삭제가 안된다」 + 「운영배포」.
🔑4건 중 3건이 한 뿌리였다 — initPhotoDropzone() 이 #dcPhotoGrid 한 곳에만 묶여 있어서 목록 「사진」 버튼이 여는 모달의 #dcPhotoGrid2 는 어떤 코드도 건드리지 않는 죽은 요소였다(썸네일 0·삭제버튼 0). 삭제 코드는 원래부터 있었고 아무도 안 보는 그리드에 그려졌을 뿐이다. 배차번호도 전역 dcPhotoDispatchNo 하나라 사진모달을 닫으면 −1 로 돌아가 등록/수정 쪽 업로드가 dispatch/-1/photo 로 샜다. 사진모달 드롭존은 인라인 onclick/onchange 뿐이라 드래그&드롭 리스너가 아예 없었다(문구만 있고 기능 0).
고침 = initPhotoDropzone(dropId,inputId,gridId,getNo) → 컨텍스트마다 한 벌(모달용 dcPhotoCtlModal · 폼용 dcPhotoCtlForm), 배차번호는 전역이 아니라 클로저 변수.
버튼 = 흰 점 → 「사진 3」(0장이면 숫자 없음 · 업로드·삭제 직후 setPhotoCount() 로 재조회 없이 그 행만 갱신). 확대 = 라이트박스 한 벌로 통일(좌우 이동·「2 / 5」·ESC·배경클릭, 상세패널의 window.open 새 탭도 교체) — ESC 는 라이트박스가 떠 있으면 그것만 닫는다.
배차 등록 = 번호가 없으니 클라이언트 대기열(File + objectURL, 썸네일에 「저장 시 업로드」 배지 #a85614 대비 5.2:1) → 저장이 dispatch_no 를 주면 일괄 POST, 취소하면 revokeObjectURL 후 폐기. 유령 배차 행을 만드는 선저장 안은 버렸다(코덱스·web-designer 같은 추천). 사진만 실패하면 저장은 살리고 「수정 화면에서 다시 첨부」 안내.
검증 = node --check · 테스트 Playwright E2E 19/19(scripts/_dispatch_photo_ui_e2e.py) · 테스트 API 왕복(_dispatch_photo_ui_check.py) · 운영 읽기전용 8/8(_dispatch_photo_ui_prod_readonly.py — 실제 계산서 1920×2560 라이트박스 표시까지, 운영 데이터 무변경) · 사이트맵 재빌드 /dispatch/list = same(미반영 1건은 /field/worklog = 별건).
⏳남은 것(범위 밖) = ①.dc-btn-row 12px(13px 하한 미달 — 소급하면 배차/택배 목록 5버튼 전체 재확인) ②택배(courier) 모달엔 사진 영역 없음 ③배차 삭제(소프트) 후 /static/uploads/dispatch/ 파일 잔존 여부 미확인 ④썸네일 최신순 정렬.
🆕2차(같은 날 22:3x) — 숫자를 「빨간 원 + 흰 글씨」 배지로 — 운영배포 f612c90 완료(master 5f1da6a+a10a994). [페페] 「숫자가 눈에 잘 안 띈다. 숫자를 빨간색 원 안에 흰색 글씨로 써줘」 + 「운영 배포」.
.dc-badge-count = #c62828 원 20px + 흰 글씨 13px bold + 흰 링 2px. 🔴링이 장식이 아니라 필수 — 초록 버튼(#2f9e6b) 위 빨강은 인접대비 1.3:1(비텍스트 3:1 완전 미달)이고 링 없이 3:1 을 넘기려면 마룬까지 내려가 「빨간색」으로 안 보인다(web-designer 실측). 흰 글씨 대비 5.7:1 — 부트스트랩 #dc3545(4.53:1)·기존 --dc-danger #e85a4f(3.49:1 AA 미달)는 안 썼다. border-radius:10px+min-width:20px 라 1자리=원·2자리↑=알약 자동(분기 없음) · 100↑ 99+ · 0장이면 안 그린다.
같이 = .dc-btn-row 12→13px(폰트 하한 확정 규칙 · 행 액션 5버튼 공통) · .dc-btn-photo min-width 66→80px · .dc-actions align-items:stretch(배지로 사진 버튼만 2px 높아지던 것).
2차 검증 = 테스트 E2E 19/19 · 운영 읽기전용 13/13(배지 실측 rgb(198,40,40)/흰글씨/13px/20×20/흰링 · 1280·1400·1680px 액션 5버튼 전부 한 줄·같은 높이) · 사이트맵 재빌드 /dispatch/list = same.
🆕3차 — 썸네일 다운로드 버튼 + 배지 2px 축소 — 운영배포 998dcfd 완료(master 75bf51a). [페페] 「섬네일에 바로 다운 받을 수 있는 버튼을 추가해줘. 사진에 붙은 숫자가 원형과 함께 조금 크다. 2픽셀 더 줄여줘」 + 「운영배포」.
다운로드 = .dc-photo-thumb .dl 좌상단 22px 검은 원 + 13px 인라인 SVG. 같은 오리진 정적파일이라 <a download> 하나로 끝(JS 저장 루틴·서버 변경 0). 🔑삭제(×) 옆에 붙이지 않았다 — 위험 액션 옆 무해 액션은 오조작을 부른다(PFS 관행 = 행 액션바 삭제 margin-left:28px) → 대각 배치(다운로드 좌상단·삭제 우상단) + hover 파랑(#3f8de8)/빨강(#d63b3b) 이중 신호.
파일명 = original_name, 없으면 배차<번호>_<n>.<확장자>. 🔴사용자 업로드 파일명이 처음으로 HTML 속성에 들어간다 → escAttr()(따옴표 들어간 파일명이면 속성이 깨진다) · 운영 실측 KakaoTalk_20260923_180340242.jpg 그대로 저장.
붙인 곳 = 사진모달·등록/수정·행 상세패널 3곳 · 저장 전 「대기」 사진은 제외(로컬에 이미 있는 파일). 썸네일 클릭(확대)과 안 부딪힌다 — 앵커가 img 의 형제라 img.onclick 경로를 안 탄다.
배지 = 20→18px(radius:9px·padding:0 4px · 흰 링 포함 외곽 24→22px) · 글씨는 13px 그대로(컨테이너 문제라 폰트 하한은 안 깬다).
3차 검증 = 테스트 E2E 22/22(Playwright expect_download 로 실제 저장·파일명 원본까지) · 운영 읽기전용 16/16 · 배지 1자리 18/2자리 26/99+ 34px 잘림 0 · 1280~1680px 액션 5버튼 한 줄 · 사이트맵 재빌드 /dispatch/list same.
🆕4차 — 다운로드를 «썸네일 하단 배너»로 · 라이트박스 아무데나 닫기 + 다운로드 — 운영배포 d18e5ad 완료(master fcd10b4). [페페] 「사진 위에 다운로드 버튼 넣지 말고 하단쪽에 큰 배너버튼으로 누르기 편하게. 사진 확대는 팝업으로 해서 아무데나 눌러도 다시 닫을 수 있게 하고, 그 화면에도 다운로드 버튼 추가」 + 「운영배포」.
배너 = 하단 전폭 26px · 아이콘+「다운로드」 13px · #2f74c4(흰 글씨 4.76:1 — 페페가 보던 #3f8de8 은 3.40:1 이라 안 썼다). 3차의 좌상단 22px 원은 제거. 삭제(×)는 우상단 그대로 — 배너가 내려오며 파괴적 액션과 오히려 더 멀어졌다. 대기 사진 「저장 시 업로드」 배너도 26px 로 맞춤(등록 모달은 저장분·대기분이 같은 줄에 나란히 서서 높이가 다르면 바닥선이 어긋난다).
라이트박스 = 배경만 닫히던 것을 if(!event.target.closest('button,a')) dcLbClose() 로 — 이미지 위도 닫힌다(cursor:zoom-out). ⛒그래서 라이트박스 안 새 컨트롤은 반드시 <button>·<a> 로 만든다(div/span 이면 누를 때 닫힌다).
라이트박스 다운로드 = 닫기와 대칭인 좌상단 40px 원(SVG 는 line-height 센터링이 안 먹어 flex). 🔑dcLbOpen(urls, idx, names) 로 확장해 썸네일 배너와 같은 파일명으로 받게 했다(안 하면 같은 사진이 경로마다 서버 해시명으로 떨어진다) · names 없으면(대기 사진) 버튼 숨김.
4차 검증 = 테스트 E2E 29/29(라이트박스 다운로드 실제 저장 · 이동버튼·다운로드는 눌러도 안 닫힘 · 이미지 클릭은 닫힘 · 대기 사진은 배너·버튼 둘 다 없음) · 운영 읽기전용 19/19(배너 실측 26px/13px/rgb(47,116,196)/전폭 130px · 라이트박스 파일명 KakaoTalk_20260923_180340242.jpg) · 사이트맵 재빌드 /dispatch/list same.
⏳안 넣은 제안 2건(web-designer) = 모달 푸터 「전체 다운로드」 · 라이트박스 회전 버튼. ⏳.dc-btn-danger #e85a4f 흰 글씨 3.49:1 = AA 미달(지시 밖이라 안 건드림).
devplan pfs-dispatch-photo.html · 함정 = rules.md 🆕 맨 위.
✅ 26.9.23 · pfs-orderpaper-dedupe · 발주서 중복 항목 전역 정리 + 자재관리 6개월 (운영 a392b6c)
26.9.28 handoff NOW 에서 원문 이관(캡 관리).
[코디] 🆕 26.9.23 — 발주서 중복 항목 전역 정리 + 자재관리 표시 6개월 — 운영배포 a392b6c 완료(master 5ab793d)
[페페] 검증보고(10:49 /field/orderpaper 피앤알 SPP0012) 「중복된 항목이 있고 피앤알 spp0012 자재들은 자재관리 탭에서 안 보인다. 3개월 제한 때문.
버퍼링 차이 없으면 6개월로 확장. 중복항목은 26년분 전역 조치」 + 「운영배포」.
🔑중복 3종 = ①NAS 윈도우 복사본 파일(에넥스 라인VIP … - 복사본 · 복사본 넥서스 고양 행신동 신우APT)이 원본의 옛판으로 남아 둘 다 파싱 — 원본이 그 뒤 고쳐져 내용 완전일치로 안 잡힌다(SPP0012 = 원본은 5번 행 삭제, 복사본은 그대로)
②마커 변형 파일((서랍재발주)학동·넥서스(원자재) GS 오산·(케데코 추가)산곡)에 블록 복제 ③같은 파일 안 섹션 반복(AL 탭 「캡 포함 마감」 메모 템플릿·유리업체 머리행 오파싱·일레븐 3~4월 복붙).
🔴복사본이 전부 중복은 아니다 — SGC 용두동 … - 복사본·복사본 에넥스 LH 의정부 우정 은 원본에 없는 「더하임」 탭·다른 날짜 발주 = 진짜 별도 발주서 → 파일 통째 제외 금지(코덱스도 같은 지적).
조치 = orderpaper_parse.dedupe() 를 동기화 파싱 직후에 끼움 — R1 복사본 블록이 원본 같은 자리(탭·섹션·구분)·같은 발주처 + (발주일 같음 ‖ 품목 부분집합)이면 제외 · R2 같은 가구사·현장·발주처·발주일·입고일·구분·품목 완전일치는 하나만(복사본 아님→마커 없음→파일명 우선).
빠진 블록은 그 라운드에 없으니 동기화가 remove_yn='1', 중복이 풀리면 같은 item_key 로 진행상태째 복구(가역). 드라이런 = 37블록/106항목 제외(DB 기준 살아 있던 건 17블록/30항목 — 나머지는 이미 수동삭제 del_manual).
6개월 = orderpaper_material_mgmt.js WIN_DAYS=180(창은 화면 JS 필터 한 곳). 전량 선로드 + 페이지 50행이라 운영 실측 495건 4.0ms → 800건 4.9ms. web-designer = 문구 그대로 OK.
배포 = deploy-live 엔 날짜 고침 패널(테스트 전용)이 없어 템플릿 228줄 차이 → JS + 캐시버스터 1줄만 파일 단위 반영(blob 일치 확인). 동기화 스크립트는 이 PC 의 master 작업본으로 돈다.
✅NAS 복사본 정리 완료([페페] 「NAS 복사본 파일 정리 진행해」, 13:46 KST) — ①효산 9.16 은 옮기지 않았다: PFS 에서 이미 사람이 삭제(del_manual=1)했고 원본엔 9.22 상원보드 발주로 같은 N448 품목이 다시 나가 있었다(발주처 바꿔 재발주).
②피앤알 7.9(세레나크림 18T MDF 3·미성형 보드 12T PW 1, 완료) 는 원본 피앤알 탭 맨 뒤 4번째 장(88~116행) 으로 붙였다 — 원본은 같은 3번째 장을 7.21 발주로 덮어써 있었다. 중간 삽입은 뒤 장 순번이 밀려 상태가 옮겨붙어 금지.
zip 시트 XML 1장만 치환(파트 69 중 1장, 기존 15블록 파싱 완전 동일) · 🔴복사본과 원본의 cellXfs 가 141번부터 달라 행 XML 을 그대로 못 붙인다 → 스타일을 내용 대조로 재매핑(59중 56 일치, 3칸은 원본 같은 줄 서식) · 공유문자열 → inlineStr · 공유수식 → 명시수식 · 매수 캐시값 3→4.
NAS 백업 = \\192.168.0.101\공유폴더\2026현장\원부자재발주서\06월\_백업\에넥스 라인VIP 개인건 원부자재발주서_20260923_134604.xlsx · 복사본 2개 → \\192.168.0.101\공유폴더\2026현장\원부자재발주서\_복사본보관\(월 폴더가 아니라 동기화 안 읽음, 삭제 아님).
즉시 동기화 = 파일 61→59 · INSERT 2(피앤알 #3) · 삭제표시 2(옛 복사본 1608·1609) · 상태 완료 이관(3264·3265). 조립·검증 스크립트 = 세션 스크래치(build_append.py·verify_append.py·nas_apply.py).
devplan pfs-orderpaper-dedupe-6mo.html · 자체검사 C:\dev\pfs\orderpaper-sync\test_dedupe.py · 미리보기 python orderpaper_parse.py dups.
✅ 26.9.23 · pfs-orderpaper-date-fix · 날짜 고침 패널 + NAS 엑셀 되쓰기 (운영 c38433b+c2f3242)
26.9.28 handoff NOW 에서 원문 이관(캡 관리).
[코디] 🆕 26.9.23 — 날짜 고침 패널 + NAS 엑셀 되쓰기 — 운영배포 c38433b+c2f3242 완료([페페] 「확인. 운영배포해」 · 운영 orderpaper_date_fix 테이블 생성 · /api/health ok · 사이트맵 재빌드 완료)
[페페] 「자재관리·발주서 정리 상단에 별도 블록으로 날짜 없는 내용을 올리고 경고. 거기서 날짜 수정하면 엑셀파일에도 입력하고 저장.
엑셀이 읽기모드면 닫힘 신호 기다렸다가 진행. 1시간 이상 대기시 파일 이름을 텔레그램으로」 + 「테스트서버 반영만 먼저」.
그릴링 1문 [페페] = 입고일의 「긴급」 63칸도 경고에 올리고 날짜를 넣으면 덮어쓴다(현재값을 보여준 뒤 교체).
🔑설계를 바꾼 발견 — 블록의 엑셀 위치가 DB 에 없었다(block_key 는 SHA1 이라 못 되돌린다) → 컬럼 4개 추가(sheet_name·section_idx·order_date_raw·receive_date_raw).
산출 = 큐 orderpaper_date_fix + API 5개 + 미니PC 사이드카 되쓰기 루프(20초) + 화면 #opDateFixPanel(세 라우트 공통 지점).
🔴openpyxl 재저장 금지 — 실측에서 printerSettings 3개 등 8파트가 날아가 126,679→102,971B(발주서는 인쇄·팩스 문서다) → zip 시트 XML 1장만 치환(파트 30→30, 손실 0).
동작 = 저장 → 큐 → 사이드카가 엑셀 수정(쓰기 전 자동백업 · 쓴 뒤 재검증 · 어긋나면 원복) → orderpaper 날짜도 즉시 갱신. 열려 있으면 waiting_file 로 계속 재시도, 1시간 넘으면 파일명 텔레그램 1회.
검증 = 엑셀 자체검사(사본, 파트 손실 0·「긴급」→날짜·항목 43 유지) · 날짜문제 블록 42건(오기입 14·없음 28) · E2E 3경로(error / waiting_file / done) — done 은 업무 데이터가 안 바뀌게 「현재 발주일과 같은 값」으로 돌렸다.
⏳[페페] = 테스트 육안·실사용 1회(https://pfs-test.poin.co.kr/field/orderpaper · /omc/material 상단 「⚠ 발주서 날짜 점검」) → 확인되면 운영배포 판단.
상세 = session-2026-09-23-orderpaper-sync-ssm-limit.md 2부 · 함정 3건 = rules.md 🆕 맨 위.
✅ 26.9.23 · pfs-orderpaper-sync · 자재관리 동기화 20시간 먹통(SSM 97KB) (운영 93d7ce1)
26.9.28 handoff NOW 에서 원문 이관(캡 관리).
[코디] 🆕 26.9.23 — 자재관리 동기화가 20시간 전량 먹통이었다(SSM 97KB 한도) — 운영배포 93d7ce1 완료
[페페] 「자재관리에 나진 상가 등 새로 발주낸 내용을 엑셀로 담았는데 반영이 안 된 것 같다. 파싱 규칙 파악해서 조치해줘」 + 「운영배포 사항이다」.
🔑파싱 규칙 문제가 아니었다 — 운반이 끊겨 있었다. NAS 파일은 제대로 고쳐져 있었고(나진 9.22 16:51 저장 · 새 탭 「코파산업」 포함),
그걸 운영 RDS 로 나르는 SSM 경로가 9.22 13:39 부터 9.23 09:41 까지 30분마다 MaxDocumentSizeExceeded 로 전량 실패했다(스크립트 74,276B → b64 99,036B > 97KB).
🔴아무도 몰랐던 게 더 크다 — 예약작업 orderpaper_autosync 는 wscript 라 내부 실패와 무관하게 LastTaskResult=0, 실패는 _autosync.log 에만 쌓였다.
조치 4개 = ①청크 전송(60,000자 초과분을 여러 send-command 로 /tmp 에 이어붙인 뒤 디코드·실행, S3 추가 0) ②원격 파일명 고유화 ③b64·디코드본 크기 대조 가드(어긋나면 실행 거부) ④실패 시 텔레그램 알림.
🔴②③은 실측으로 생겼다 — 고정 이름(/tmp/_op_remote.py)으로 붙였더니 예약작업(09:38)과 겹쳐 디코드본이 74,276 → 103,552B(청크 중복 append)가 되며 SyntaxError.
검증 = 운영 ins 12 · upd 2,192 · alive 2,158행 / 47현장 · 용산 나진 상가(field 2183) 실조회 상원보드 23 · 코파산업 2 · 효산엘피엘 9 · 선재기업 9(새 탭이 그대로 새 발주처로 INSERT) · /api/health ok · 사이트맵 미반영 1(화면 밖).
⏳[페페] 판단 1건 = 날짜 미기입 55블록(그중 숨김 유발 23블록은 지금 화면에 안 보인다 — 자재관리가 입고일‖발주일 기준 3개월 창만 본다) 정리 여부. ⏳육안 1회 = /field/orderpaper 나진 「코파산업」 2건.
파싱 규칙 정본·함정 3가지(날짜 비면 숨김 · 표 중간 행 삽입 시 상태 한 칸씩 밀림 · 파일명 변경 시 전량 재등록) = session-2026-09-23-orderpaper-sync-ssm-limit.md · devplan pfs-orderpaper-sync-ssm-limit.html.
✅ 26.9.23 · pfs-monthly-close · 월마감 월 변경 시 선택 거래처 유지 (master 569fb9b)
26.9.28 handoff NOW 에서 원문 이관(캡 관리).
[코디] 🆕 26.9.23 — 월마감 월 변경 시 선택 거래처 유지 — 운영배포 완료(master 569fb9b)
[페페] QA: 월 바꾸면 보던 거래처가 그 달에도 있으면 그 마감으로 고정. mcLoadMonth 에서 keepNo 없을 때 mcCur.company_no 일치 마감 우선(없으면 첫 마감). 운영 파일 반영 = ssm 확인. 사이트맵 재빌드(미반영 1 = 남의 것, 내 파일 diff 0).
✅ 26.9.22(화) KST · pfs-monthly-close-pick · 월마감 담기 모달 금액 3분할 + 견적일 포맷 (운영 91cc509)
[페페] QA 보고 1건 — /estimate/monthly-close 「9,844,000」 셀(tbody#mc-pick-rows 1행 6번째 td.text-right, 견적 771) +
「가로폭 남는공간 활용해서 가구총합, 시공비, 전체총합으로 금액을 표시해줘. 시공비가 빠지니 원금 비교가 어렵다.
견적일 날짜형식 4.12(월) 이런 포맷으로 변경.」 + 「운영배포」.
착수 전 web-designer 에이전트 상담(페페 상시 지시 26.9.4 — PFS 화면은 예외 없이) → 폭 배분·강조·0원 표시·요일색 처방을 그대로 반영했다.
- 🔑화면만 고치면 3칸이 거짓말을 한다 — 서버가 내리던
construction_amount는 「담을 값」 이라 시공비 분리 거래처(한샘)가 아니면 언제나 0 이다. 그걸 「시공비」 칸에 그대로 찍으면 분리 OFF 거래처에서 가구총합 칸이 실제로는 시공비를 품은 값이 돼 라벨이 거짓이 된다. → 표시 전용furniture_amount·construction_cost2필드를 분리 여부와 무관한 실값으로 따로 내렸다. 불변식 =가구총합 + 시공비 = 전체총합이 모든 행에서 성립. 담기 계산식(amount·construction_amount)은 한 줄도 안 건드렸다. 본견적·추가건 양쪽에 같은 2필드를 넣었다(추가건도 모달에서 같은 3칸을 쓴다). - 컬럼 7 → 9칸 —
colspan=3상위헤더 「금액」 아래 가구총합 96 / 시공비 88 / 전체총합 100(bold), 옅은 배경띠 + 좌우 1px 경계로 한 묶음. 모달 1080 → 1240px(상한 권고 1400 — 넘기면 모달이 아니라 페이지로 보인다), 견적일칸 96 → 70px(12.31(월)최대 8자라 96은 과잉), 현장명은 auto 유지라 362 → 374px 로 오히려 넓어졌다. 업체 110 · 견적명 150 · 상태 170 은 안 건드렸다(상태는 배지+「YYYY-MM 마감 담김」이라 줄바꿈 위험). 🔴colspan="7"하드코딩 2곳(로딩 중·결과 없음)을 같이9로 안 고치면 표가 틀어진다. - 전체총합을 굵게(가구총합 아님) — 페페가 말한 목적이 「원금 비교」다. 가구총합은 옆 마감표 「본건금액」에 그대로 복사돼 이미 보이지만
전체총합은 이 모달에서만 보이는 신규 비교값이다. 마감표 본표의
.mc-total이 굵은 것과도 일관된다. - 시공비 0 = 회색
-—0을 그대로 찍으면 대부분의 행이 「금액 / 0 / 같은 금액」 이 돼 시선만 흩어진다. 빈칸은 로딩 실패처럼 보여 배제. 같은 파일mcRecalc의sf ? fmt(sf) : ''와 같은 계열이다. - 견적일 포맷 — 새로 만들지 않고 발주서 화면의 기존 규약(
web/static/js/orderpaper_schedule.js·field_orderpaper.html의fmtD)과 같은 모양.2026-04-12 → 4.12(일)·2025-12-31 → 25.12.31(수)(해가 다르면 2자리 연도 — 담기 목록엔 해를 넘긴 견적이 섞인다, 견적번호 DESC 50건) · 시각이 붙어 와도 같은 결과 · 빈값은 빈 문자열. 요일색은 토(#0a58ca6.44:1)·일(#dc35454.53:1)만, 평일은 색 없음. - 덤 = 이 모달의 13px 하한 위반 2건 수정(기존 결함) — BS4 기본이
.badge= 14×0.75 = 10.5px,.text-muted.small= 14×0.8 = 11.2px.#mc-pick-popup .badge, #mc-pick-popup .small { font-size:13px }로 스코프를 이 모달에 가뒀다(전역으로 올리면 다른 화면 배지가 전부 커진다). - 검증 = 테스트 82/82 · 운영 읽기전용 76/76(쓰기 0건) · 콘솔 에러 0 · 사이트맵 재빌드 그룹8·페이지60·미반영 1(기존 화면 밖 항목, 정상).
검사기 =
C:\dev\pfs\scripts\_mc_pick_check.py [test|prod]에 23항목 추가(A11~A16 표시용 필드·정합·담기 불변 / B7-1~B7-17 thead 2행·9칸· 모달폭·화면 숫자 정합·0 표시·bold·mcFmtDate단위검증 7종·computed 13px 실측). ⚠이 파일은.gitignore대상이라 로컬 전용이다(커밋 안 됨). 🔑테스트 DB 엔 시공비가 전량 0 이라 항등식이 「0+0=0」 으로도 통과한다 → 검사기가 시공비>0 표본 수를 같이 찍게 했고, 운영 12/50 건에서 실증됐다(견적 778 =2,180,000 + 700,000 = 2,880,000· 견적 769 =31,189,000 + 6,500,000 = 37,689,000). 첫 실행 3 FAIL 은 전부 검사기 쪽 오류였다 — ①4.12를 월요일로 기대(실제 일요일) ②parseInt('-')= NaN ③th슬라이스[-4:-1]. - 배포 = master
db08291→ 테스트 자동배포 → 82/82 → 선별 포워드 → 운영91cc509→ 76/76.deploy-live..master가 464 커밋이라 ⛔git merge master금지 — 배포 워크트리C:\dev\pfs_deploy_wt에서 파일 2개만git checkout origin/master -- <file>. 전제 확인 = 두 파일 모두git diff origin/deploy-live db08291^ -- <file>가 비어 있음(선행 diff 0) → 통째로 가져가도 남의 미배포분이 안 딸려 나간다. push 전 blob 2/2 일치 · 삭제 0 · 남의 코드 0 확인. - ⏳[페페] 육안 1회 = 긴 현장명이 374px 안에서 안 뭉개지는지 · 1240px 모달이 실제 창에서 어색하지 않은지(1366px 노트북이면 여백이 좁다) · 두 줄 헤더가 깔끔한지.
- ⏳[페페] 판단 2건(web-designer 선제안 — 지시 범위 밖이라 안 넣었다) = ①「시공비 있는 건만」 필터 체크박스(한샘 시공비 정산 때
0원 행 사이에서 비0 행만 골라내야 하는데 지금은 못 거른다, 난이도 하) ②선택 행 3종 합계 실시간 표시(
#mc-pick-count가 건수만 보여준다 — 담기 전에 예상값을 검증할 수 있어 잘못 담고 되돌리는 재작업을 막는다, 난이도 중). - 함정·규칙 4건 =
rules.md🆕 맨 위 · 전문 = devplanC:\dev\devplan\pfs-monthly-close-pick.html.
✅ 26.9.22(화) KST · pfs-nesting-drawer-calc · 네스팅 「서랍 자동계산기」 (운영 a9c5d22)
[페페] 「pfs production/nesting 에서 도어전용에 서랍 자동계산기를 추가해줘. 추후 pcadtool tread 에 있는 그룹입력 기능을 추가하긴 하겠지만 서랍의 경우는 자동 계산기가 필요하다. 자재 두께(몸통, 내부 서랍 구분) / 볼레일·언더레일·텐덤박스 사용여부 / 외곽몸통+마이다 칼라를 내부서랍과 별도 또는 동일 마감 설정 / 마이다 좌우 날개 추가여부(붙박이장 내부 서랍 구조를 옵션으로) / 3축 사이즈 치수 입력칸, 기본 WDH 600470450. 모달로 내용 입력 후 도어 부재 입력 테이블에 들어가게 제작해줘. 운영배포」 + 같은 날 추가지시 「텐덤박스 : 바닥판·후판을 목재로 포인에서 제작해야 한다. 기성품 구매를 안하고 15T PB 지정 목재로 우리가 생산한다. 계산항목에 포함시켜라.」
- 🔑산출식을 새로 만들지 않았다 — 서랍통 5매는
C:\dev\pncad\SPEC-DRAWER.md§3 이 정본이고(imosDR_MAIN/DR_PART134종 + 실부재 2,451행 역산, 실측 편차 0) 구현체drawerBox()가web/pncad/schema.js에 있다 →/production/pncad/schema.js에서 ESM import. 복제 기각 이유 = 편측갭(언더 5.5 · 볼 14)이 SPEC §3.1·§6 에서 「케이스별 오버라이드 · 언더 11.0 변동 미규명」으로 열린 값이라, 원천(C:\dev\pncad\schema.js→tools/sync_to_pfs.py) 갱신이 화면 사본까지 안 닿아 정본이 둘이 된다. - 기준은 장W 가 아니라 존 내경
Wz = W − 2×몸통두께 − 2×날개폭(SPEC §3.5 경고 — 날개를 빼면 전후판이 100mm 틀어진다). - 산출 부재 = 몸통측판 2(D×H) · 몸통천지판 2((W−2T)×D, 뒷판 켜면 D−9) · 뒷판 1(옵션) · 마이다 n · 날개 2 + 날개측판 2(옵션)
· 서랍측판 2n · 서랍전후판 2n · 서랍바닥판 n. 같은 규격은 수량 합산 1행으로
addPartRow()에 덧붙인다(tread 정책). - 🔑텐덤박스 = 바닥판·후판 2종만, 가로는 「마이다 폭」 기준 −103 / −115 · 후판 높이는 박스높이와 무관한 2단 고정규격
(소 65 · 대 142, imos 변수
$텐덤박스(소)/(대)) → 입력칸. imos 실발주 3건(호반제주MH·유엔사부지 2건) 8/8 편차 0. 금속 U레일이 측판을 대신하므로(DR_MAIN.TYPE=3= 2면 서랍시스템) 측판·전후판이 없고, 목재 CP 2종 (15T_서랍바닥판·텐덤박스 서랍재_15T, 둘 다 15T PB · prodcode 08)이 실재한다. ⚠첫 조사는 「완제품이라 마이다만」이었고 그게 오판이었다 — 페페 지시로 다시 파서 정정.SPEC-DRAWER.md§5 의 「텐덤 = 1차 범위 밖」 서술은 TYPE=5(이름만 텐덤이고 실은 일반 4면 zargen) 얘기였다 → SPEC 갱신 후보(안 고쳤다). - 확신 낮은 값은 전부 입력칸(노브) — 뒷판 유무 · 마이다 상하·좌우·단간 갭(기본 2·2·3) · 날개폭(50) · 서랍통 깊이/높이.
imos 는 서랍 프론트 갭이 케이스별(division 10/15/30mm)이라 보편식이 없다. 자동값은 모달
.assume안내로 띄운다 (깊이 470→450 = 관리 6단 스냅 · 높이 = 단 내부높이−5 → 10단위 내림 = 존 136→130 imos 관례). - UI = 기존 저장/열기 모달 뼈대(
.nj-box.wide) +.row/.col재사용(새 CSS 6줄) · 목록칸은<select>인데droplist.js가mousedown을 캡처 단계에서 삼켜 자체 13px 팝업으로 띄운다(크롬 양식 금지 규칙 충족 · datalist 0) · 숫자칸text+inputmode(부재표 규약) ·.assume12→13px(폰트 하한). - 검증 =
scripts/_nesting_drawer_calc_check.py(로컬 전용 ·--test/--prod) 로컬 61/61 · 테스트 68/68 · 운영 69/69 (콘솔 0 · 운영 쓰기 0건). 정답지 = SPEC §3.3·§3.5 imos 실측 골든(주방·언더@600 529×133 · 일반·볼@600 500 · @450 350 · @1010 910) + 텐덤 골든(마이다696 → 593/581) — 순수함수drawerCalc()를page.evaluate로 직접 불러 대조한다. 기존 네스팅 검사 5벌 회귀 0(qa5 96/102 · grid-modal 87/96 의 FAIL 은 변경 전 기준선과 동일 항목 = 노후 기대값). 덤 = 기존 검사기 2벌 로컬 목킹에/production/pncad/*서빙 추가(schema.js·lindiv.js 404 제거). - 🆕2차(같은 날) = 재단치수 내림 정수 + 결 부재 가로/세로 뒤집기([페페] 「모든 값은 소수점이 들어가면 안된다
내림처리해서 정수 처리 … 특히 서랍 측판, 전후판은 높이쪽 치수가 가로 재단쪽, 반대쪽을 세로재단으로 보고 세로결 지정」).
가로·세로에
Math.floor(마이다 146.67 → 146, 두께는 자재 규격이라 예외) · 서랍측판·서랍전후판·텐덤후판은 높이 → 가로칸 / 나머지 → 세로칸 + 결방향 세로(바닥판류는 그대로 결무시, 몸통·마이다·날개는 원래부터 세로=높이). 정본drawerBox()는 설계 기준(l=길이·w=높이)이라 화면에서 재단 기준으로 바꿔 넣는다(정본은 안 고친다). 결과 기본값 = 몸통측판 470×450 · 몸통천지판 564×470 · 마이다 596×146 · 서랍측판 130×450 · 서랍전후판 113×523 · 서랍바닥판 533×448. 검사 골든도 뒤집고 「소수점 0개」 2항목 신설 → 로컬 65/65 · 테스트 72/72 · 운영 73/73. masterf5b2776→ 운영5faf806. - 파일 =
web/nesting/nesting.html1개(서버·API·DDL 변경 0 · 사이트맵 재빌드 대상 아님 — 라우트·메뉴·API 변화 0). master5bdd97d→ 운영a9c5d22(선별 포워드 · blob 1/1 일치 · 남의 코드 0). 상담 = furniture-expert · web-designer · Plan(fable) · 코덱스. 전문 =session-2026-09-22-nesting-drawer-calc.md· devplanpfs-nesting-drawer-calc.html.
✅ 26.9.22(화) KST · pfs-door-order-import · QA 헬퍼 모달 입력 먹통 해제 + 「견적서 열기」 (운영 4982b14)
[페페] QA 헬퍼 보고 1건 = /estimate/list-v2 「그 견적서 열기 →」 버튼 + 코멘트 「모달을 연 상태에서 qahelper 화면 입력도 안 먹힌다. 먹히게 조정. 단어 "견적서 열기" 로 수정」 + 「운영배포」.
- 🔑본체는 버튼이 아니라 QA 헬퍼였다 — 부트스트랩 모달을 연 채로는 사이드바 이름칸·코멘트칸에 타이핑이 아예 안 먹었다(전 페이지 공통).
원인 = BS4 modal
_enforceFocus가$(document).on('focusin.bs.modal')로 모달 밖 포커스를 모달로 도로 뺏는다. ⛒1차 처방(패널focusin+stopPropagation)은 배포까지 하고도 안 먹었다 — 이유는rules.md🆕 맨 위(jQuery 3.2.0 의 캡처단계 focus 흉내). 확정 처방 =setModalFocusTrap()— 검증 모드 ON 동안$.fn.modal.Constructor.prototype._enforceFocus를 빈 함수로 두고 이미 걸린focusin.bs.modal도 off(모드 켠 뒤 새로 여는 모달까지 커버), 모드 OFF 면 원복 +.modal.show에 즉시 되건다(접근성 원복). - 문구·폰트 = 「그 견적서 열기 →」 → 「견적서 열기」(화살표 제거 = web-designer 판단, 이 모달의 유일한 후속 액션이라 방향이 자명) ·
#door-import-modal .btn-sm{font-size:13px}한 줄 = 테마(style.css:2045)가.btn-sm을 12px 로 덮어 깨져 있던 13px 하한 복구(테마 무수정, 모달 스코프만). - 검증 =
scripts/_qa_helper_modal_input_check.py(신규 ·scripts/_*는 gitignore 라 로컬 전용) — 고치기 전에 같은 하네스로 FAIL 5건 재현(포커스 도둑 3 + 문구 + 12px) → 테스트 16/16 · 운영 16/16. 읽기전용이다(localStorage 만 쓰고 picker 가 클릭을 preventDefault) → 운영 데이터 무변경. 콘솔오류 0. 사이트맵 재빌드 = 그룹 8 · 페이지 60 · 미반영 1(기존 화면 밖 항목, 이전과 동일). - 배포 = master
daae66b(1차) +b1c2dfa(확정) → deploy-live4982b14선별 포워드.git diff origin/deploy-live origin/master -- <두 파일>로 내 변경만 들어가는 것 확인(남의 미배포 변경 0 · 삭제 0), 포워드 후 두 브랜치 내용 동일. - ⚠별건(안 고쳤다) =
scripts/_qa_helper_multiselect_check.py가 이미 깨져 있다 — 26.8.19 에 없앤 「텍스트 보기」 버튼(.qa-h-export)을 기다리다 타임아웃. 이번 지시 밖이라 손대지 않았다.
✅ 26.9.22(화) KST · pfs-door-order-import · [코디] QA 보고 1건 반영 (운영 4982b14)
🔑QA 헬퍼를 부트스트랩 모달 안에서 쓸 수 있게 됐다(전 페이지 공통, setModalFocusTrap()) + 「그 견적서 열기 →」 → 「견적서 열기」(13px 복구).
테스트·운영 각 16/16. 원문 = archive.md 「✅ 26.9.22 · pfs · QA 헬퍼 모달 입력」 · 함정 = rules.md 🆕 맨 위 · devplan pfs-door-order-import.html §11.
⚠별건(안 고쳤다) = scripts/_qa_helper_multiselect_check.py 는 이미 깨져 있다(26.8.19 에 없앤 .qa-h-export 대기 타임아웃).
✅ 26.9.21(월) KST · pfs-al-orderpaper-round · [코덱스] AL발주서 차수 탭·행선택 복사/이동 (운영 c02bd4f)
기록 시각: 2026-09-21 10:42 KST
[페페] /field/al-orderpaper에 현장명 앞 차수 버튼, 같은 현장 차수 탭, 행선택형 차수간 복사·이동과 차수 내 복사를 estimate/modify-v2 기준으로 추가하라고 지시했다. 목록 현장명 앞에 N차 버튼, 편집 현장명 앞에 1차 | 2차 | + 차수 탭을 배치했다. 선택 액션바는 이 차수에 복사 / 다른 차수에 복사 / 다른 차수로 이동 / 선택 해제; 차수 내 복사는 화면 상태를 deep copy해 신규행 강조 후 저장하고, 차수간 복사·이동은 대상·선택행 미리보기 모달 뒤 서버 단일 트랜잭션으로 처리한다. 같은 현장만 대상이며 짝 행은 함께 선택된다. 네이티브 AL/유리업체 select도 자체 드롭리스트로 교체하고 신규 UI 13px 하한 적용. 테스트 master 1a995a4, 운영 c02bd4f; 테스트 UI 10/10 + DB E2E 5/5, 운영 읽기전용 UI 10/10, 콘솔 오류 0, 양쪽 uWSGI active. 사이트맵 그룹8·페이지60·미반영1(기존 화면 밖 항목).
✅ 26.9.18(금) KST · pfs-print-app-poinimos02 · poinimos02 에 「PFS 생산 인쇄」 앱 설치(SSH 원격만, 페페 조작 0)
[페페] 「poinimos02 에 PFS 생산 인쇄 프로그램 설치해줘」. devplan pfs-print-app-poinimos02.html.
- 설치본 =
C:\Users\delix\AppData\Local\PfsPrint\app\—PfsPrint.exe(1.1.0.0, 56,320 bytes, 이번에 재빌드) +PfsPrint.exe.config+ WebView2 DLL 3개. 바로가기 2개 =C:\Users\delix\Desktop\PFS 생산 인쇄.lnk· 시작메뉴 같은 이름.config.json은 첫 실행 때 생긴다. ⚠poinimos02 는 계정명poinimos02인데 프로필은C:\Users\delix(옛 이름 잔재). - 사전조건 실측 = WebView2 Runtime
153.0.4234.32있음 · .NET4 Full Release533325(=4.8) 있음 · Win10 Home 19045 → 추가 설치 0. - 검증(프린터 없이) =
PfsPrint.exe --selftest를schtasks /IT로 사용자 세션에서 굽고print-app/tools/verify_print_size.py로 실측 → 스티커 99.82 × 99.82mm(기대 100) · 파레트 297.01 × 209.89mm(기대 297×210) = 생산팀PC 26.8.11 값과 동일, 2 OK / 0 FAIL. 자체검사 창은ShowInTaskbar=false+ 좌표-4000,-4000이라 직원 화면에 안 보인다. - 앱은 안 띄웠다 — poinimos02 는 직원이 로그온해 쓰는 중(Console 세션 explorer 확인)이라 창이 남의 화면에 튀어나온다. 파일·아이콘만 넣고 끝.
- 🔑함정 2 = ①
schtasks /RU %USERNAME%이 계정명=PC명 인 기기에서ERROR: The parameter is incorrect. (40,4):UserId:로 실패 →/RU "%COMPUTERNAME%\%USERNAME%"(pfs/print-app/remote_update.py도 같은 형태로 수정, 커밋b2cd1ae) ②BOM 없는.ps1을 원격 실행하면 cp949 로 깨져 한글.lnk이름Save()가 던진다 — stderr 를 버려서 「만들었다」 출력만 보고 넘어갔고 실제 바탕화면엔 0개였다 →utf-8-sig저장 +Test-Path재확인. 둘 다rules.md🆕 에 규칙화. - 뒤처리 = 예약작업
PfsPrintSelfTest삭제 · 원격 PDF·임시.ps1·.cmd전부 삭제 ·PfsPrint프로세스 0. - 🔴정정(같은 날, 페페 지적 「라벨프린터 같은 모델로 다른 방식으로 설치되어 있다」) — 라벨프린터는 있다.
\\POINIMOS01\ZDesigner GT800 (EPL)= 사무실PC(POINIMOS01)에 물린 GT800 을 공유로 잡아 쓰는 사용자별 네트워크 프린터다(드라이버Zebra GT800 (203 dpi) - EPL·ZDesigner GT800 (EPL)로컬 설치됨,HKCU:\Printers\Connections에 등록). 🔑내가 못 본 이유 = SSH(Session 0) 에서Get-Printer/Win32_Printer는 «사용자별 네트워크 프린터 연결»을 열거하지 않는다(같은 계정인데도 안 나온다). 드러난 곳은Get-PnpDevice(PrintQueue) 뿐이었다. 사용자 세션 실측(schtasks /IT로PrinterSettings.InstalledPrinters덤프) = GT800 보인다 ·IsValid=True· 용지aaa 394×394(= 3.94in = 100.1mm, 이미 100×100 으로 잡혀 있다). 앱 자동판별 모사 결과 = 스티커\\POINIMOS01\ZDesigner GT800 (EPL)(힌트gt800·zebra·zdesigner에 걸린다) · 파레트SINDOH D450/CM Series PCL(HKCU 기본 프린터) → 첫 실행 때 둘 다 자동으로 채워진다. ⚠단, 큐가 POINIMOS01 공유라 사무실PC 가 꺼져 있으면 스티커가 안 나간다. - ⏳[페페] 1건 = 첫 실행 1회(바탕화면 아이콘 → ⚙ 프린터 설정에서 스티커=GT800·파레트=SINDOH 확인 → 테스트 인쇄로 자 대고 90mm 확인).
- 이후 갱신 =
python C:\dev\pfs\print-app\remote_update.py --deploy --host poinimos02(상태만 =--status).
✅ 26.9.18(금) KST — 스티커 출력 「라벨·이름표」 탭 신설(위험성평가 경고표지 + 일반 이름표 · 운영배포 94be2c7 → 5785d9b)
2차 — 같은 날 추가지시 「일반 이름표도 · 스티커 선택 안되도 출력 가능하게」 (운영배포 5785d9b)
- 그림문자 0개 = 일반 이름표 — 3등분이 사라지고 이름 한 칸이 라벨(90×90) 전체(실측 89.5mm), 구분선 없음(
.cs-name-solo). 인쇄 게이트는 이름만 필수. 탭명 「화학물 라벨」 → 「라벨·이름표」, 버튼 「라벨 인쇄」(생산팀이 이름표를 못 찾는다 = web-designer 처방). - 글자 상한 = 이름표 30mm / 3등분 50mm(
fitFont에 옵션 인자maxMM추가 — 파레트 호출부 무영향). - 🔴밟은 사고 2건 = ①빈 칸 안내문구가 라벨에 찍혀 나갈 구조였다 ②이진탐색이 낱말을 쪼갰다(「자재창 / 고 A-3」 27.4mm)
→ 2단 맞춤으로 20.9mm 「자재창고 / A-3」. 둘 다
rules.md🆕 26.9.18 위 세 줄에 규칙화. - 검증 = 자체검사 35항목(이름표 7항목 신설) 테스트·운영 각 35/35 · 사이트맵 페이지 60 · 미반영 1(남의 세션 파일).
1차 — 화학물 경고표지 (운영배포 94be2c7)
[페페] 「스티커 프린터로 위험성평가 화학물 라벨. 가로 3등분 해서 상하는 경고표시, 가운데는 라벨이름 칸.
파레트용지 탭 오른쪽에 신규 · 운영배포」. 화면 = 생산 > 스티커 출력 > 화학물 라벨(4번째 탭).
검증 = 자체검사 테스트 28/28 → 운영 28/28(scripts/_stk_chem_check.py test|prod) · 사이트맵 페이지 60 ·
미반영 1(남의 세션 파일 = 내 배포분은 전부 반영). 전문·모형·판단거리 = devplan pfs-chem-label.html.
- 라벨 = 기존 스티커 용지 100×100mm(내용 90×90) 를 가로 3등분 = 각 29.82mm 실측. 상·하 = 같은 GHS 그림문자 줄(어느 방향에서 봐도 경고가 보인다) · 가운데 = 라벨이름.
- 고친 파일은 화면 1개뿐 —
web/templates/default/sticker.html(+ 그림문자 SVG 18장). 서버·인쇄앱·DDL 변경 0 — 앱은kind=='pallet'한 곳만 갈라 보고,sticker_print_log.source는VARCHAR(10)·검증 없음이라'chem'을 그냥 넣는다(근거·함정 전문 =rules.md🆕 26.9.18 여섯 줄). - 그림문자 = UN 공식 도안 9종(퍼블릭 도메인) →
web/static/images/ghs/(적색 원본) ·ghs/k/(검정 사본). 한 변 =min(25, (83−2(n−1))/n)mm → 1~3개 25mm · 4개 19.3 · 6개 12.2 · 9개 다 골라도 7.4mm 로 안 넘친다. 5개 이상이면 화면에 「육안 식별 어려울 수 있다」 경고(법적으로 하나를 뺄 수 없어 막지는 않는다). - 이름칸 = 파레트용지
fitFont이진탐색 재사용, 2줄까지 접으며 최대 크기(짧으면 24mm · 24자면 8mm), 낱말 중간에서 안 끊는다(word-break:keep-all+overflow-wrap:anywhere). 입력maxlength=24. - 법적 구성 = 명칭 + 그림문자만으로 족하다(사업장 내부 소분·보관용기, 고시 제6조) → 페페 지시의 3등분이 그대로 법정 최소 구성과 맞는다. 신호어·유해위험문구·공급자정보는 100mm 라벨에 억지로 넣지 않았다.
- 착수 절차 = Plan(fable) + 코덱스(법령) + web-designer(치수·대비·선택 UI) 3자 → 세 의견이 갈린 「적색 테두리」만 페페 판단으로 남겼다.
- 밟은 사고 2건(둘 다 자동검사가 잡았다) = ①CSS 주석을 닫아 놓고 뒷줄을 써서
.cs-pics규칙이 통째로 죽었다 (밴드 50/2.5/50mm · 콘솔 에러 0) ②flex-basis:0은 border-box 에서 3등분이 안 된다(30.3/28.8/30.3). - 🔵미적용 2 = 물질 프리셋 버튼(이름+그림문자 1클릭) · 라벨에 인쇄일자 소형 인쇄(용기 재충전·교체주기 판단용).
🧹 루트 HANDOFF 이관 (2026-09-16) — 원문 그대로
✅ 26.9.11(금) KST — PFS 네스팅 툴바 「🆕 새 네스팅」 버튼 (운영배포 a227c4e)
페페 「저장/열기 모달 붙이면서 새 네스팅 시작 버튼이 있어야 하는데 없다. 추가, 운영배포」. 파일 1개(C:\dev\pfs\web\nesting\nesting.html) · 백엔드 0.
동작 = 현재 작업·현장 연결 해제(「저장 안 함」) · 부재 빈 3행 · 원장 기본 1행 · 결과 숨김 · 몸통재/PNCAD 선택 해제 · 도어전용 탭. 옵션(커프·여백)은 유지. 입력 있거나 작업 연결돼 있으면 확인창.
검증 = 로컬 96/96 · 테스트 100/100 · 운영 읽기전용 91/91(쓰기 0) · 툴바 1920/1280/1024px 한 줄. 사이트맵 재빌드(미반영 1 = 기존 건, 네스팅 diff 0).
⚠곁사고 = 기준선 비교용 git stash 체인이 옛 stash 를 꺼내 default_controller.py 충돌 → HEAD 복구(무손실, stash 보존). 규칙 = projects/pfs/rules.md 🆕 맨 위.
✅ 26.9.10 KST — PFS 네스팅 그리드 2차: 범위 선택(드래그·Shift+클릭) + Ctrl+C/Ctrl+V (운영배포 83e15b3)
페페 검증보고 「복수 드래그 선택·Ctrl+C/V, 행 부족하면 새 행 생성 후 나머지 붙이기」 + 「한 값 + 여러 칸 = 전부 같은 값」 + 「운영배포」. 파일 1개 · 백엔드 0.
붙여넣기 = 범위 왼쪽 위(없으면 포커스 칸)부터 사각형 · 외부 한 행 전체(9/11열)는 옛 방식 유지 · ⚠9열 미만 외부 붙여넣기는 이제 포커스 칸부터.
덤 = 엑셀 한 칸 복사가 그 행 두께 칸에 박히던 기존 결함 · 헤더 스킵이 가로 빈 첫 행을 버리던 것.
검증 = 로컬 86/86 · 테스트 89/89 · 운영 읽기전용 80/80(쓰기 0). ✅[페페] 실기 확인 완료 — 작업 종료. 상세 = projects/pfs/archive.md 「2차」 · 함정 3개 = projects/pfs/rules.md 🆕.
✅ 26.9.10 KST — PFS 네스팅 부재 그리드 키보드·타입/위치 + 저장/열기 모달(현장 연결) (운영배포 4388bc4)
페페 검증보고 2건 + 「운영배포」. 파일 1개(web/nesting/nesting.html) · 백엔드 변경 0.
방향키 = 셀 이동(숫자 ±1 증감 제거) · 최하단 Enter = 새 행(가로·세로·수량만 비움) · 표 높이 3배 · 순번 뒤 타입·위치(tread 키 type/pos) ·
저장 모달(현장 검색 연결 · 덮어쓰기/새 작업) · 열기 모달(검색 · 현재 현장만 · 삭제). 🔑한글 IME = 조합 확정 keyup 에서 이동 · 9열 붙여넣기는 옛 순서 유지.
검증 = 로컬 54/54 · 테스트 실측 55/56(검사기 오탐 1, 수정) · 운영 읽기전용 47/47. ✅[페페] 실기 확인 26.9.10 — 한글 입력 후 Enter 새 행 작동. 세션 종료 · 추후 보완은 새 세션. 상세 = projects/pfs/archive.md · 보완 후보 = projects/pfs/handoff.md.
✅ 26.9.7 KST — 박광은(enex5983) 담당자 등록 + 오엠씨 권한 「이 사람만」 (운영 데이터, 코드변경 0)
페페 「에넥스 담당자로 코디가 박광은 추가 / 오엠씨 페이지 확인 권한은 이 사람만 특수 허용(현재 허용을 유지)」.
🔑실태 조사가 지시의 의미를 갈랐다 — 「현재 허용」은 시트관리·보드관리 둘뿐이었다(자재관리는 원래 없다)
→ 그대로 유지하고 자재관리는 주지 않았다. 그리고 그 허용이 company_permission(에넥스 4) = 업체 전체였다.
에넥스 계정이 박광은 하나뿐이라 티가 안 났을 뿐, 계정이 늘면 전부 열린다.
⛒처방 = 업체 쪽 OMC_SHEET·OMC_BOARD 를 '0' 으로 닫고 user_permission(11, …)='1' 로 그 사람만 허용.
권한 우선순위가 user > company > 차단 이라 박광은만 통과한다.
산출 = 담당자 member_no 436(에넥스 4 · 박광은 · 010-5495-5983) 신규 등록 + 계정 연동 ·
권한 서명 갱신(다음 요청에 재로그인). 코드 변경 0 · 배포 없음(운영 DB 데이터만).
검증 = scripts\_enex_pkw_verify.py 11/11 PASS(권한은 DB 행이 아니라 계산 결과로 쟀다 —
「에넥스 다른 계정이면 차단」까지 확인) · 오엠씨(196) 자기 권한 무영향 · 앞서 연동한 4명 그대로.
이로써 거래처 계정 5명 전원 담당자 연동 완료(미연동 0).
✅ 26.9.7 KST — GS 안산 성포 한샘 양식 재작성 A~G 완료 (운영 등록 + NAS 저장)
포인 견적 769(24줄·항목합 30,889,000) → 한샘 4평형 주방전용 양식으로 재작성.
산출 = 양식 form_no=3(운영 활성) · 한샘 견적 estimate_no=6(총액 30,889,012, 고아 0) ·
NAS 2026현장\견적\09월\넥서스\GS 안산 성포 MH\한샘 GS 안산 성포 MH 견적서.xlsx(왕복대조 일치).
검증 = 양식 구조 27항목 + 배선 8항목 + 수식 체인 실계산(단가기준→백데이터→LOOKUP→적용가→총합) ALL PASS,
평형 4개 총합 오차 −13 ~ +21원.
🔴덤으로 운영 결함 발견 — 「단가 LOOKUP 없으면 조용히 0」의 짝인 미러 열 적용가 행이 안 채워져
기존 한샘 견적 4건 전부 엑셀 금액이 서버 총액과 −4,123,878 ~ +7,412,865 어긋난다. master 58daac4 로 고침.
⏳페페 판단 = api/pfs/hansem/ 운영배포 여부(하면 기존 4건 엑셀이 바로잡힌다). 상세 = projects/pfs/handoff.md.
✅ 26.9.7 KST — PFS 사용자 등록 ↔ 거래처 담당자 연동 (운영배포 완료)
페페 「admin/user 신규사용자 등록시 이름=거래처 담당자(전화도 연동), 업체는 담당자에 따라 자동 매핑. 기존 매핑된 사용자들도 확인 후 연동처리」 + 「운영배포」.
산출 = master 4d6cec4+39a6ee3 → 운영배포 08f5aa5 · 운영 DDL user.member_no 선행 적용.
이름 칸이 담당자 검색을 겸한다(폼에 칸을 안 늘린다) — 고르면 전화·업체 자동 채움, 안 고르면 수기입력(자사 직원).
🔑업체는 서버가 담당자 소속으로 강제한다(화면 값을 믿으면 담당자↔업체가 어긋난 계정이 생긴다).
🔴코덱스가 진짜 구멍을 짚었다 — 담당자가 다른 업체로 옮겨가면 연동 계정이 옛 업체 권한을 그대로 들고 남는다
(자재 스코프·메뉴 권한이 전부 user.company_no). → 업체 동기화 + 권한서명 갱신으로 재로그인 유도.
담당자 삭제 시엔 연동만 끊고 계정은 살린다. 한 담당자 = 한 계정.
운영 연동 4명 = ivision/은지호(418) · theheim/주하늬(312) · seongji/한대명(93) · omc01/유상연(118, 전화 보충).
자사 6명 전원 미연동(정상). ⏳enex5983/박광은은 에넥스에 그 이름의 담당자가 없어 손대지 않았다 — 명부 등록은 페페 판단.
덤 = /api/company/member 스코프(전 거래처 담당자 399건 연락처가 로그인만 하면 나갔다) ·
13px 하한 2건(모달 버튼 — .admin-modal-content 는 .admin-detail 의 형제라 오전 수정이 안 먹었다 · 권한 일괄버튼 11px).
검증 = 자체 65/65 · 테스트 실측 25/25(업체 260→4 덮어쓰기 실증, 검증계정 정리 완료) · 운영 읽기전용 25/25(쓰기 0건) · 사이트맵 미반영 화면 0.
🔴새 함정 4개(rules 🆕 반영) — ①「A 를 골라 B 를 채우는」 폼은 검증보다 채우는 쪽을 먼저 돌려야 한다
(담당자만 주고 이름 비운 등록이 name 필수 로 거부 — UI 로는 안 보이고 API 에서만 터진다)
②담당자 자동완성 후보행에 업체명 필수(동명이인 20그룹·최다 「사장님」 8개사) ③.admin-modal-content 는
.admin-detail 의 형제 ④인라인 <style> 은 CSS 파일 검사에 안 잡힌다.
완료·운영배포 끝난 작업 상세(OMC·패치). 견적 기능 완료 이력은
archive-estimate.md, 견적 스키마는schema-estimate.md. 요약은 sessions.md.
✅ 26.9.16 — 도어발주서 포인탭 → 월드산업(도장) 「월드」 탭 변환 (완료 · ⏳페페 판단 5건)
[페페] 「포인탭에 있는 내용을 월드 탭에 월드 양식 적용해서 변환해줘. ①EP·s/r·휠라 등은 큰제목만 남기고 비고란은 큰제목에 몰아넣는다 ②오픈장·이동장 등 3개 이상 하위항목 큰제목은 그대로 유지한다. 진행」
[코디] 입력 = NAS 2026현장\진행중\9월\한샘 용산 나진 MH\ 의 한샘 월드 용산 나진 mh 도어발주서.xlsm
(⚠같은 폴더의 「한샘 포인 …」 는 포인탭이 사실상 비어 있다 — 파일명이 아니라 포인탭 채움 페이지 수로 골랐다).
산출 = 같은 폴더 한샘 월드 용산 나진 mh 도어발주서_월드탭.xlsm(575,728 bytes · NAS 왕복대조 일치).
원본은 안 건드렸다(= 자동 백업). 도구 = C:\dev\pfs\orderpaper-sync\poin2world.py(--apply 없으면 계획만).
- 결과 11페이지 92행 — 큰제목 39 전량 이관 · 부재 126 → 53(73줄 접음). 최대 17행이라 페이지 1:1 로 끝났다.
- 접는 규칙 = EP·S/R·휠라·목찬넬 큰제목은 한 줄로, 하위 비고는 ' / ' 로 이어 큰제목 L 에. 오픈장·이동 은
블록 통째 유지(하부·상부 오픈장 3 + 이동형 오픈장 1). 큰제목에 안 묶인 단독행(도어·키큰도어·문틀재·걸레받이)은 규격째 그대로.
- 🔴함정 = 하위행을 「다음 큰제목까지」·「빈 줄까지」로 자르면 뒤에 붙은 단독행 17행이 통째로 사라진다 →
큰제목 종류별 허용 부재집합에서 벗어나는 첫 행에서 끊는다. 「하위 3개 이상」은 기계 기준으로 못 쓴다(키큰EP 하위 4).
상세 = rules.md 🆕 맨 위.
- 검증 = 포인탭 전 셀(1512행×32열) 수식 문자열까지 차이 0 · zip 파트 91→91 · VBA 155,648 동일 ·
도형 앵커 49·12·6·4 동일 · 프린터설정 동일 · 큰제목 39행 전부 D:K 병합 · 발주일 2026-08-18 하루 밀림 없음.
- ⏳[페페] 판단 5건 = ①원본을 덮어쓸지(§2-5 위험작업이라 승인 먼저) ②발주일·납기를 오늘로 바꿀지(지금은 포인탭
값 복사 = 발주 2026-08-18 · 납기 미정) ③칼라를 페이지마다 박을지(포인탭이 1p 에만 KCC YA532, 각 행 구분열엔
YA532 가 다 있다) ④접힌 줄에 두께를 넣을지(9T 2건은 비고에 살아남았다) ⑤「지판없음」 3행을 뺄지.
- 세션 = projects/pfs/session-2026-09-16-door-order-world-tab.md · devplan pfs-door-order-world-tab.html.
✅ 26.9.16 — 학동매장 원부자재발주서 「피앤알」 탭 · 인쇄 + 팩스 발송 (완료 · ⏳기기 통신결과만 육안)
[페페] 「원부자재발주서 : 학동매장 / 발주일 오늘 긴급 / 피앤알탭으로 발주서 작성 / 팩스까지 발송, 출력물 인쇄 / 발주서 블록선택해서 선택영역 인쇄로 진행 / 미성형보드 MDF 25T 9자 3매 · 22T 9자 5매 · 18T 10자 2매 / 오엠씨 입고」
[코디] NAS \\192.168.0.101\2026현장\원부자재발주서\09월\한샘 학동매장 원부자재발주서.xlsx — 131,017 bytes / 26.09.16 14:21.
원본 백업 = C:\dev_attic\2026-09-16\한샘 학동매장 원부자재발주서_원본_20260916.xlsx.
- 탭 = 「발주서」 복제 → 「피앤알」 rename. C2 만 넣으면 업체시트 INDEX/MATCH 가 단축번호(3)·참조(남태욱상무
010-8775-6864)·전화(032-815-1587)·팩스(032-815-1589) 를 자동으로 채운다.
- 규격 표기 = 운영 orderpaper 학동매장 26.6.30 실적 그대로 (25T MDF 4*9(2700) 꼴). 입고일 = 발주일과 같은
9.16(수), 비고 3행 전부 E0, 긴급, 입고처 = 오엠씨(경기 화성시 팔탄면 푸른들판로892-31 / 유상연부장).
- 인쇄 = 「선택영역 인쇄」 = 29행 1페이지 블록 = PrintArea $A$1:$J$29, SINDOH D450/CM Series PCL 1부.
- 📠팩스 = 코디가 끝까지 보냈다 — SINDOH D450/CM Series FAX 로 PrintOut → 「팩스 전송 팝업」을 win32gui 로
조종(🔴uiautomation 은 이 창을 못 본다) → 송부처 피앤알 / 0328151589 1건 등록 확인 후 「확인」.
팝업 즉시 닫힘 · 오류창 0 · 스풀 0. 컨트롤 ID 표·순서 = rules.md 🆕 맨 위.
- 🔴COM 함정 3 = Bash 는 Session 0 라 Excel COM 이 RPC_E_CALL_REJECTED 로 붕괴(→ schtasks /IT + 절대경로
pythonw.exe + 파일로그) · 날짜는 엑셀 시리얼 정수(datetime 은 KST+9 로 하루 밀려 09 .15(화) 로 찍혔다) ·
NAS UNC 직접 열기 금지.
- ⏳남은 것 = 기기 통신결과 육안 1건. 192.168.0.201(KM PageScope 계열 SPA)은 통신이력 XML 이 관례 경로에
없어(전부 404) PC 에서 못 읽는다 → 기기 통신관리보고서가 유일한 확인 경로.
- 상세 = projects/pfs/session-2026-09-16-hakdong-pnr-order-fax.md · devplan /pfs-orderpaper-fax.html.
✅ 26.9.15 — 용산 나진 상가 네스팅 → 원부자재 발주서 + 경면코드 자동적용 (운영배포 완료 · ⏳페페 확인 3건)
[페페] 「pfs 용산 나진 상가 도어전용 네스팅 자료 결과 보고 엑셀 발주서 작성. 모드 LPM · 상원보드 생산 / 엣지샘플 효산 제작·입고처 진영LDM / 피스마개 스티커도 효산·입고처 포인 / 엣지 발주서는 선재기업 / 보드 두께별 엣지 수량 50m 올림 / 피스마개는 발주수량 대신 칼라별 보드 수량 / um 경면은 소프트엠보로 / 경면코드가 반영이 다 안됐다 — 컬러에 괄호친 부분 확인해서 경면코드로 적용시켜라 / 운영배포, 원부자재 폴더 9월에 저장」.
[코디] 원본 = 운영 nesting_job job_no=2(field 2183, 부재 127행, 컬러 5종). 119행의 경면칸이 비어 있었다 —
사람이 127번 칠 수 없어서 안 친 것이다.
- 규칙 = 컬러명 꼬리 괄호가 곧 경면코드(finishFromColor), FINISH_ALIAS 로 UM=소프트엠보.
빈칸일 때만 채우고 사람 값은 안 덮는다. 자동으로 채운 칸만 점선 밑줄 + 불러오기 때 「N행 자동적용」.
- 🔴여유키 승격(promoteFinishSlot)이 진짜 위험지점 — 경면이 그룹키에 들어가면 저장본의 …|민자|양면
여유 키가 고아가 돼 발주 98매가 75매로 조용히 준다(에러 없음).
- 🔴붙여넣기는 행추가와 다른 길로 온다 — setupPaste 는 빈 행을 먼저 만들고 값을 나중에 박아서
addPartRow 로는 못 잡는다(web-designer 실측). 채우는 지점 3곳.
- 덤 = 드롭리스트 「민자」가 규격을 「경면양면」으로 만들던 잠복버그 · 경면칸 폭 44→86px(부재표)·44→60px(패널)
· #parseStat 12→13px(폰트 하한).
- 발주서 3탭 = 상원보드(보드 21행/98매) · 선재기업(엣지 12행/950m, 폭=두께+4mm → 15·18T 22mm /
25·30T 34mm, 9·12T·4.5T 제외, 컬러×두께 50m 올림) · 효산엘피엘(칼라샘플 5 → 진영LDM, 피스마개스티커 5 → 포인,
수량 = 칼라별 보드매수). 🔴orderpaper_build 도 24행 캡노트를 안 피하고 있었다 → 슬롯 소비 + 29행 블록 복제.
- 검증 = _nesting_finishcode_check 로컬 21/21 · 운영 25/27(기능 전항목 통과 · 쓰기 0건 · 실패 2는 내 마커
개수 기댓값 오기) · _nesting_colorpanel_check 47/47(낡은 단언 3건 갱신) · _droplist_side_check 27/27 ·
엑셀 39/39 · 운영 job2 재저장 후 되읽기(자동표시 0행 · BOM 21행 · 발주 98매 · 여유 13건).
- 배포 = master d78dd4a → 운영 c7790d0(선별 포워드 4파일 · blob 4/4 일치) · 사이트맵 재빌드
그룹 8 · 페이지 60 · 미반영 1(내 것 아님 — 내 4파일 diff 빈칸).
- 산출 = NAS 2026현장\원부자재발주서\09월\한샘 용산 나진 상가 원부자재발주서.xlsx(왕복대조 일치) ·
devplan pfs-najin-wonbujae-order.html + 허브 카드.
- ⏳[페페] 확인 3건 = ①400565 12T MDF 에 손으로 찍힌 「경면」 1행(50×680·2개) — 오타면 지운다(지금 12T 가
경면 1매/민자 7매로 갈렸다) ②발주일 26.9.15 / 입고일 26.9.22(상차 9.27 기준 코디 추정) ③엣지 두께별 12줄
vs 폭별 9줄 · 「칼라샘플」 vs 「엣지샘플」 표기.
✅ 26.9.15 — 부자재 발주서 QA 2차: 현장 검색이 안 잡힌다 (운영배포 완료 · ⏳페페 육안)
[페페] 검증 보고 1건(#fSite) — 「현장검색리스트가 잘 안된다. 예를들어 나진상가 검색을 하려는데 안나옴.
가구업체 데이터는 현장명 검색하면 자동입력되면 된다」 + 「운영배포」.
[코디] 한 증상 밑에 원인이 셋이었다. 하나만 고쳤으면 페페 화면에선 여전히 안 나온다.
- ①필터 «전에» 잘랐다 — providers.so_site 의 .slice(0,400). 운영 현장 571건, 「용산 나진 상가」는 568번째
→ 뭘 쳐도 안 뜬다. droplist 는 필터 «뒤»에 400 캡 + 「N개 더」를 붙인다. 제거하고 최근순(field_no 역순) 으로.
- ②띄어쓰기 — 실제 이름은 「용산 나진 상가」. 공용 droplist.js 검색을 공백 무시 + 낱말 AND 로
(「상가 나진」·「나진 한샘」도 잡힌다). 옛 부분일치 통과분은 전부 그대로 통과 = 목록이 줄어들 회귀 없음.
- ③🔴현장을 골라도 아무 일도 안 일어났다 — droplist 가 쏘던 new Event('change') 가 비버블이라
위임(document·tbody) 리스너에 영영 안 닿았다. 네스팅·업무패널은 캡처로 우회해 뒀고 이 화면만 버블 위임이라
field_no·가구업체 연결이 통째로 죽어 있었다. 원천에서 bubbles:true(네이티브와 동일)로 고쳤다.
- 가구업체 = 현장 발주처 목록(so_company 신설, 부자재 거래처가 떠 있었다) + 현장 바꾸면 따라간다
(옛 「비어 있을 때만」 = A→B 갈아탈 때 A 업체명이 남았다). 손댄 값은 dirty 로 보존. 서버 LIKE 도 공백 무시.
- 검증 = scripts/_sub_orderpaper_site_search_check.py 18항목 테스트·운영 양쪽 ALL PASS
(운영은 「용산 나진 상가」 실물 · 한샘 자동입력 · field_no 2183) + 공용 파일을 건드려서
_droplist_side_check.py 27/27 PASS 회귀 확인.
- 배포 = master 74d76cd+53d78d9 → 운영 b084520(4파일 선별 포워드 · blob 4/4 일치) ·
pncad 원천 670df5f+a2309eb · 사이트맵 재빌드(그룹 8 · 페이지 60 · 미반영 2 = 내 것 아님,
git diff origin/deploy-live origin/master -- <내 4파일> 이 빈칸).
- ⚠남의 검증기 노후 발견(안 고쳤다) — scripts/_nesting_colorpanel_check.py(26.9.14 작성)가 42/47.
실패 5건은 오늘 다른 커밋(경면 컬럼 eaeb693)이 패널에 data-drop 을 넣고 키를 컬러|경면 으로 바꾼 탓이다.
내 변경과 무관(droplist 전용 검사는 27/27). 네스팅 담당 세션이 스크립트를 따라 올려야 한다.
- ⏳[페페] 육안 = 현장 칸을 그냥 열면 최근 현장이 위로 온다(옛 순서와 반대). 거슬리면 되돌린다.
네스팅·업무패널 드롭리스트도 같은 공용 파일을 타니 한 번씩 눌러 봐 달라.
- devplan = pfs-sub-orderpaper.html 7절 신설 · 허브 카드 갱신 확인.
✅ 26.9.15 — 네스팅 4차: 긴 값은 2줄 · 짧으면 컬럼폭 오토 (운영배포 완료 · ⏳페페 육안)
[페페] 네스팅 검증 보고 1건 — #colorTbl 컬러 헤더를 집어 「도어 부재 입력 테이블도 동일 사항 /
컬럼별 글자가 한글 20자 이상일 때는 2줄 표시 / 그 이하일 때는 컬럼폭을 오토로 해라」 + 「운영배포」.
[코디] 대상 = 「1. 도어 부재 입력」 표 컬러칸 + 우측 「사용 컬러」 패널. 실측 컬러 컬럼이 114px(한글 8.7자)라
마스터 최장 22자가 3분의 1만 보였다. 라벨(span)이 폭·높이를 만들고 input 을 그 위에 투명하게 겹치는 구조로 바꿨다
(함정 3개 = input 줄바꿈 불가 · textarea 로 바꾸면 droplist 사망 · display:none 이면 방향키 이동 사망 → rules.md 🆕).
- 부재표 =
display:block+width:max-content+max-width:12em→ 짧으면 칸이 저절로 좁아지고(오토) 길면 2줄. 🔴-webkit-line-clamp를 쓰면 테이블 auto-layout 이 컬럼을 안 늘려 20자가 4줄로 접힌다(실측 scrollH 78 vs clientH 43). - 컬러 패널 = 240→300px, colgroup %→px(178/44/76).
table-layout:fixed는 유지(auto 면 짧은 컬러명까지 눌린다). - 덤 = 드롭리스트는
change만 쏜다 → 목록에서 컬러를 고르면 구분색·패널 합계가 안 따라오던 누락 수정 + 부재표title툴팁 추가. - 검증 = Playwright 실측 23항목 ALL PASS(2줄 판정·말줄임 0·컬럼폭 오토 51↔156px·방향키 →↓·범위선택·붙여넣기·드롭리스트·콘솔 0).
- 배포 = master
e0b25bf→ 운영e39105d(blob 해시 일치) · EC2 HEAD 확인 ·pfs-live.uwsgi09:43:16 KST 재기동 · health 200. 사이트맵 재빌드 그룹 8 · 페이지 60 · 미반영 1 = 이번 건 아님(kakao_board·field_worklog = 남의 세션). - devplan =
pfs-nesting-qa5.html에 8절 신설(4차) · 허브 카드 갱신 확인. 🆕11:45 8차 — 경면 3단계(빈칸/「경면」/경면코드)(페페 「빈칸 = 민자 · 경면 = 코드 모르는 경우 · 특정코드 = 경면코드로 적용, 발주서 규격에는 「경면양면」, 발주서 비고란에 경면코드 표시. 현재 네스팅 페이지에서는 정해진 코드는 코드로 보이게」). finishLabel(v)= 발주 규격 — 코드든 「경면」이든 전부 「경면」(빈칸만 민자) → 규격은 언제나18T MDF 경면양면/민자양면. 코드가 규격에 섞이지 않는다.finishCode(v)= 발주 비고 — 값이 있고 「경면」이 아닐 때만. 표기는 괄호 =E0 (HG-1234)·E0 2745 (HG-1234). 🔑괄호인 이유 = 규격칸이 코드를 지우므로 비고가 코드의 유일한 출처다. 「E0 2745」(마감재+길이)와 한눈에 갈려야 «코드 다른 경면으로 잘못 발주»를 막는다(web-designer 판정 · 엑셀 한 셀이라 괄호가 셀을 안 가른다).- 화면은 친 그대로 — 부재표·패널·배치도 시트 제목에 코드가 그대로 보인다(코드를 친 사람에겐 코드가 보여야 한다).
- 그룹키(
finishOf)는 원값 그대로 = 코드가 다르면 다른 자재로 갈린다(「경면」과 「HG-1234」도 별개). 코드를 나중에 채우면 그때 합쳐진다. - 검증 13항목 ALL PASS · 배포 master
0e9b59c→ 운영2c3dc52.
🆕10:55 7차 — 경면 컬럼 + QA helper 커서(페페 「컬러 우측에 경면 컬럼. 기본 빈칸 = 민자 = 경면X ·
발주서 기록시 민자로 표기 · 검색+수동입력」 + 「도어 부재 입력에서도 경면 컬럼이 필요하다. 매핑이 되야해」
+ 「qahelper 작동시 커서 변경 없게」).
그릴링 2문 확정 = 값 단위 부재 행 단위 · 발주 표기 BOM 규격에 합성.
- 발주 표기 = 18T MDF 양면 → 18T MDF 경면양면, 빈칸이면 18T MDF 민자양면.
PFS 에 이미 쌓인 자재 규격 표기(15T PB 경면양면·4.5T MDF 민자양면)와 글자 단위로 같다 → BOM 을 복사해 발주서에 붙이면 손볼 게 없다.
- 행 단위라 원장 그룹키 keySide 에 경면이 들어간다 → BOM·사용컬러 패널이 「컬러+경면」으로 갈린다.
배치도 시트 제목·시트번호에도 값 있을 때만 붙였다(안 붙이면 제목이 같은 시트가 두 벌 나온다).
- 🔴web-designer 가 잡은 P1 — 발주완료 체크 키에 경면을 안 넣으면 「화이트/경면」 체크가
「화이트/민자」까지 네스팅에서 빼서 «발주 누락»이 된다. 둘은 다른 원장이다 → colorGroupKey(color,finish) 로 통일.
- 🔴붙여넣기 매핑 보호 = pasteSkip:1 — setupPaste 는 «배열 순서»로 칸을 맞춘다. 경면이 중간에 끼면
기존 11열 엑셀 붙여넣기가 품명부터 통째로 한 칸 밀린다(비고 칸 newCol 주석과 같은 사고). 경면은 손입력·드롭리스트 전용.
- 🔑덤 = 위임 리스너가 color 만 들어 경면을 고쳐도 구분색·패널이 옛 조합 그대로였다(검증이 잡았다).
- 패널 = 4컬럼 166/44/40/48(=298px 유지, 「발주완료」→「완료」 축약으로 자리 냄). 패널 폭 300px 은 안 건드렸다 —
키우면 줄바꿈 문턱 1218px 가 밀려 1280px 노트북에서 패널이 아래로 떨어진다.
- 옛 저장본 호환(doneColors 컬러명 → 민자 조합 · 여유 키 5토막 → 6토막) · 자재 등록표는 무변경(지시 범위 밖 —
자재 매칭 키는 종전대로 경면 무관 = 같은 소지 원장. 경면별 재고를 따로 잡으려면 자재표에도 칸이 필요하다).
- 검증 25항목 ALL PASS · 배포 master eaeb693 → 운영 128a5d8(blob 일치) · uwsgi 11:30:16 KST · health 200.
- ⏳[페페] 육안 — 경면 입력·드롭리스트, BOM 규격이 「경면양면/민자양면」으로 나오는지, QA helper 커서.
🆕10:40 6차 — 여유자재·소요량을 저장본에 남긴다(페페 「자재 등록, 네스팅 결과가 네스팅 저장시 같이
저장되게 … 자재 결과 나온 후 여유자재 입력후 그 데이터를 남기기 위해서야」).
🔑파 보니 자재 등록(mats)은 이미 저장되고 있었다 — 진짜로 빠져 있던 건 «사람이 넣은 여유자재»다.
저장본을 열면 지금도 runNest() 가 돌아 결과는 다시 그려지므로 재계산으로 못 되살리는 값만 남기면 된다.
그릴링 1문 → 페페 확정 = 「여유값 + 소요량 숫자」(배치도 스냅샷 제외).
- spareByKey(BOM 집계키 keySide → 장수) → opts.spare 저장 → loadJob 복원 → 뒤이어 도는 runNest 가
BOM 을 그릴 때 칸에 그대로 들어간다. summary.bom = 저장 당시 소요량 숫자(렌더된 표에서 긁는다).
- ⛒재실행에서는 여유를 안 비운다 — 같은 자재 행이면 따라오고, 비우는 건 새 네스팅·부재 초기화뿐(doneColors 규칙과 동일).
- 🔴배치도(sheetsOut.placed)를 안 담은 이유 = 좌표가 통짜라 summary(TEXT 64KB)를 넘길 수 있다.
담으려면 nesting_job 에 LONGTEXT 컬럼 신설 = DB 스키마 변경(§2-5 승인 게이트). parts/mats 는 LONGTEXT, opts/summary 만 TEXT다.
- 서버·DB 무변경(opts/summary 는 스키마리스 JSON, 컨트롤러가 _dump 로 통째 왕복) · 옛 저장본은 spare 키가 없어 전부 0.
- 검증 22항목 ALL PASS — 저장 payload 생성 → 그 payload 를 저장본으로 되먹여 loadJob 왕복까지(summary 764B).
- 배포 = master 65a4a63 → 운영 bb17422(blob 일치) · uwsgi 10:51:34 KST 재기동 · health 200.
🆕10:20 5차 — 행 복사 버튼 [⧉](페페 「도어 부재 입력 테이블에 행별로 바로 아래에 해당 행 복사기능 버튼 추가」).
dupPartRow() = rowData() 로 그 행의 지금 값을 떠서 바로 아래에 넣는다(빈 행을 넣는 [+] 와 짝).
🔑배치 = [+][⧉] 를 6px 로 묶고 48px 격리는 파괴적인 [✕] 앞에만 남겼다 — 양쪽에 48 을 주면
액션칸이 104→192px 이 되어 1280px 노트북 가로 넘침이 두 배(web-designer 실측 A안 170 vs B안 128px).
액션칸 min-width 104→152px(부재표만). 기호 ⧉(U+29C9) 두부 아님 픽셀 대조 · 색은 새 토큰 없이
.toggle-cell 파랑 재사용(대비 6.42:1). 자재표 무변경(gridRow 공용이라 cols===PART_COLS 로 걸렀다).
검증 22항목 ALL PASS(값 전량 일치·토글칸·긴 컬러명·순번·구분색·2줄 라벨·간격 6/48px·자재표·[+]·[✕]·콘솔 0).
배포 = master eac90c8 → 운영 56607bc(blob 일치) · uwsgi 10:29:17 KST 재기동 · health 200.
⚠안 한 것 2개(지시 범위 밖, web-designer 선제 제안) = 기존 .addbtn 대비 4.31:1 보정 · 행 복사 단축키(Ctrl+D).
⚠1280px + 긴 컬러명(20자↑)에서 가로 넘침이 기존 33~90px → 71~128px 로 늘어난다 — 이번 버튼이 38px 보탰다.
근원은 26.9.14~15 컬러칸 확장이고, 거슬리면 컬러 max-width:12em 을 줄이는 게 첫 손잡이다.
🔴10:01 회귀 1건 — 「컬러 컬럼이 갑자기 선택이 안된다」(페페 지적, 같은 날 즉시 수정·배포).
원인 = .cellwrap 이 <span> 이라 기본 display 가 inline 인데 패널에만 inline-block 을 줬다.
inline 을 컨테이닝 블록으로 삼으면 inset:0 이 라인 조각 기준이 돼 input 이 칸 바깥으로 튕겨 나간다
(실측 라벨 x=321 w=51 / input x=420 w=36) → 눌러도 hit test 가 span.cell-label 에 걸려 아무것도 안 잡힌다.
처방 = .cellwrap{display:block;width:100%} + .cellwrap input{min-width:0}.
배포 = master a55d219 → 운영 3dc33ea(blob 일치) · pfs-live.uwsgi 10:05:50 KST 재기동 · health 200.
🔑검증 구멍도 같이 메웠다 — 23항목이 이걸 통과시킨 이유는 Playwright 가 input 「요소」를 찾아 눌렀기 때문이다.
이제 라벨 좌표를 mouse.click + elementFromPoint hit test(부재표·패널 × 라벨중앙·칸 오른쪽 끝) = 29항목 ALL PASS.
- ⏳[페페] 육안 — 부재표에서 2줄이 된 그 행만 높아진다. 기능은 안 깨지는 걸 실측했지만 줄맞음이 거슬리면
부재표는 폭 오토만 두고 2줄은 패널에만 남기면 된다. 「2. 자재(원장) 등록」 표·품명·비고는 지시 범위 밖이라 안 건드렸다(
wrap:1한 줄이면 확장).
✅ 26.9.15 — 부자재 발주서 신규 /field/sub-orderpaper (운영배포 완료 · ⏳페페 육안)
[페페] 「Pfs에 부자재 발주서 기능 추가. 기존 엑셀 발주서 및 자재관리 페이지 확인해서 추천안으로 구성. 입력시에는 해당 현장 업체를 사용자가 섞어서 입력하고, 추후 정렬로 정리할 수 있다. 발주서는 업체별로 분리 출력 가능하게. 개별 출력 가능하게. 운영배포」.
[코디] 부자재는 상류(작성·출력)가 통째로 비어 있었다 — 지금까지 NAS 원부자재발주서.xlsx 「발주서」 탭을
탭 복제 → 업체명 rename → 수기로 채워 왔다. 그 수기를 대체한다. 하류(orderpaper 발주추적)는 그대로.
- 입력 = 한 표에 업체를 섞어 친다. 저장은 입력순(
seq), 「업체별 정렬」은 화면 표시만 바꾼다 →업체별 정렬↔입력순으로토글로 언제든 되돌아간다. 붙여넣기(탭·개행) 지원. - 출력 = 상단 「엑셀 전체 다운로드」(업체마다 시트 1장) · 그룹 머리행 「이 업체만 출력」(개별). 둘 다 같은 저장분의 투영이라 셀 단위로 일치(검사로 박음).
- 자동완성 = 과거 부자재 이력(
orderpaper부자재 파생 S + 자기 저장분). 품명 고르면 규격이 비었을 때만 따라온다. - 🔴양식 24행은 캡노트 행이다(
C24:H24병합) — 규격·수량을 쓰면 예외 없이 사라진다 → 블록당 품목 17개. 품목 17건 초과·입고처 변경 시 29행 블록을 통째로 복제해 장을 잇는다(NO·매수가 ROW() 29주기 수식). - 검증 = 테스트 API E2E 21항목 ALL PASS + 화면 Playwright 16항목 ALL PASS(콘솔 에러 0).
배포 = master
cca900f→ 운영caf0357(선별 포워드 —field_controller.py는 다른 세션 worktray 라우트가 섞여 있어 내 7줄만 수동 삽입). 테이블·메뉴는 첫 API 호출ensure_tables()가 만든다. - ⏳페페 = ①운영 육안(실제 현장 하나 섞어 입력 → 정렬 → 전체·개별 엑셀) ②입고체크(intake-check) 편입 여부
③전역 사안 =
al-btn.green(#0d9488) 대비 3.75:1 미달 — 이 화면만#0f766e로 썼다, AL발주서까지 맞출지 - 상세 =
projects/pfs/session-2026-09-15-sub-orderpaper.md· devplanhttp://100.108.234.45:8799/pfs-sub-orderpaper.html
✅ 26.9.14 — 네스팅 QA 2건: 컬러 패널 인라인 수정 · 두께↔MDF/PB 상충 경고 — 운영배포 a09f365 완료
[페페] QA helper 2건 + 「운영배포」.
A. 「사용 컬러」 패널에서 컬러명을 고치면 좌측 부재 표의 그 칼라 행을 일괄 치환
- 칸을 상시 <input data-drop="color"> 로(자체 드롭리스트가 칼라 마스터를 띄운다). 연필 아이콘·밑줄 같은 새 시각언어는 안 만들었다 — 부재·자재 그리드 컬러칸과 같은 모양, 발견성은 hover 배경으로.
- ⛔자재(원장) 표는 안 건드린다(그릴링 → 페페 확정). 자재 매칭 키 = 두께+MDF/PB+컬러+세로규격이라, 이름을 고치면 「⚙ 자재 자동등록」을 다시 돌리거나 자재표를 손으로 맞춰야 한다(안 하면 네스팅 실행 시 「자재 미등록」 에러 — 조용히 깨지진 않는다).
- 병합(이미 있는 컬러명으로 바꿈) = 확인창 1번 + 행수 안내(페페 확정). 취소하면 입력칸도 원래 이름으로 되돌린다.
- 발주완료 체크는 «미완료 쪽으로» 보수적 — 체크가 남으면 그 자재가 네스팅에서 통째로 빠져 발주 누락이 된다. 개명 = 해제(기존 규칙과 같다) · 병합 = 양쪽 다 완료일 때만 유지. ⚠web-designer 안(개명 시 유지)을 이 이유로 안 따랐다.
- 구분색은 단순 개명일 때만 이관 — 이름만 고쳤는데 표 색이 전부 바뀌면 딴 자재로 보인다.
- 부수 수정 = #colorTbl table-layout:fixed + colgroup 48/22/30. auto-layout 이 헤더 「발주완료」에 폭을 뺏겨 긴 컬러명에서 패널 가로스크롤이 이미 나고 있었다(실측 277 vs 238).
B. 두께 ≤12 인데 PB · ≥15 인데 MDF → 그 칸 분홍
- 🔴버튼이 td 를 꽉 채우고 td 는 padding:0 이라 td 배경을 칠해도 안 보인다 → .toggle-cell 에 바른다.
- 🔴.toggle-cell.warn 은 :hover 와 특이도가 같다 → 반드시 :hover·td.cellsel 규칙 뒤에 둔다. 앞에 두면 마우스만 올려도 경고가 조용히 사라진다.
- 색 #ffb3c1 / 글자 #7a0c2e(6.5:1) + 테두리(흑백·색약에서 배경 톤만으론 안 보인다. 글자가 MDF/PB 두 글자뿐이라 기호는 못 넣는다).
- 갱신 훅 3 = applyColorTints() 끝(호출부 7곳 자동) · toggleCell() · 두께 input 위임(종전엔 두께를 고쳐도 아무 재계산도 안 탔다).
- 13·14 와 빈칸은 경고 없음(지시 조건 그대로). 범위 = 부재 표만(자재표도 같은 상충이 성립하지만 A 에서 페페가 범위 확장을 거절해 안 붙였다 — 원하면 한 줄).
검증 = 로컬 32/32 · 테스트 38/38 · 운영 39/39 · 쓰기 0건 · 기존 관문 _nesting_qa5_check 운영 115/115 · _droplist_side_check 운영 28/28 · 캡처 육안.
검사기 = C:\dev\pfs\scripts\_nesting_rename_warn_check.py [--test|--prod]. 커밋 = master cf5ac49 → deploy-live a09f365.
⚠사이트맵 숫자가 튀었다 — 내 탓 아니다. 그룹 8 · 페이지 58→59 · 미반영 1→20. 원인 = 다른 세션이 master 에 worktray 커밋 2건(85f358e·9e1e294)을 밀어 worklog_panel.html 등 12파일이 미배포로 잡힌 것. git diff --stat origin/deploy-live origin/master -- web/ api/ 에 내 파일은 하나도 없다 = 내 배포분은 정상 반영. → rules.md 🆕.
⏳페페 = ①패널에서 긴 컬러명이 005C SH… 로 잘린다(48% 폭 · title 로 전체 표시) — 더 넓힐지 ②분홍이 실화면에서 파스텔 8색과 충분히 갈리는지 ③13·14mm 는 경고 없음이 업무상 맞는지 ④병합 확인창 문구 톤.
⚠미조치(범위 밖) = .toggle-cell 12px(13px 하한 위반) — 65px 버튼에 여유 0px 라 폰트만 올리면 글자가 잘린다. PART_COLS 의 kind w:48→58 과 한 세트로 가야 한다(별건).
✅ 26.9.14 — 네스팅 드롭리스트 「셀 우측 동일 라인」 펼침 — 운영배포 8873334 완료
[페페] 네스팅 QA helper 1건(부재 그리드 45행 컬러칸) 「드롭박스를 셀 아래가 아닌 셀 우측 동일라인에서 시작해서 펼쳐지게」 + 「운영배포」.
- 실제 증상은 「아래로 펼침」이 아니라 「위로 뒤집힘」이었다 — 하단 행에서 열면 아래 공간이 없어
place()의 above-폴백이 발동해 다른 행 12개(≈280px)를 통째로 덮고 있었다(web-designer 실측). 우측이면 같은 행 옆 2열(품명·양단면)만 덮는다. - ⛔전역 적용 기각 — pncad 좁은 모달(400px)에 같은 규칙을 주면 팝업이 카드 밖으로 30px 나간다(실측). → 옵트인
data-drop-side="right"(컨테이너 1개). 속성 없는 화면은 분기에 안 걸려 동작 불변. - 기하 =
top=셀 top·left=셀 right+6· 우측 부족하면 좌측 반전 · 세로는 뒤집지 말고 화면 안 클램프 ·style.bottom선클리어. - 🔴원천은
C:\dev\pncad\droplist.js—pfs\web\pncad\는tools/sync_to_pfs.py산출물이다. 원천 커밋 → sync → pfs 커밋 세 걸음(둘 다 push). 이거 모르고 pfs 사본만 고치면 다음 sync 에 날아간다 →rules.md🆕. - 적용처 =
#partGrid+#matGrid(한 화면에서 표마다 펼침 방향이 다르면 더 이상하다). - 검증 = 신규 검사기 테스트 27/27 · 운영 28/28 · 쓰기 0건 · 기존 네스팅 관문
--test114/114 ·--prod115/115 · 쓰기 0건 · 캡처 육안 · 사이트맵 그룹 8 · 페이지 58 · 미반영 1(그대로). 검사기 =C:\dev\pfs\scripts\_droplist_side_check.py [test|prod](합성앵커로 좌측반전·기본동작 분기까지 잰다). - 커밋 = pncad
ffcc580· pfs masterc1340df→ deploy-live8873334(2파일 선별 포워드 · blob 2/2 일치).
⏳페페 = ①실사용 체감(컬러 → 품명이 다음 입력칸이라 잠깐 가려진다) ②좁은 뷰포트(≤1100px, 표 가로스크롤 상태)에서 좌측반전 육안 ③안드로이드 실기 필요 여부.
⚠미조치(범위 밖) = web-designer 가 droplist.js 원본 CSS 의 font-size:12px·11px(2곳) = 13px 하한 위반을 지적했다. 네스팅은 자체 CSS 로 13px 를 덮어쓰고 있어 pncad 화면에만 남아 있다. 고칠지 페페 판단. 같이 지적된 「max-height:280px 를 가용공간에 맞춰 축소」도 미착수.
✅ 26.9.14 — 생산현황 출력 메모칸 세로 2분할 — 우측 = 미입고 보드 자동표기 — 운영배포 d535760 완료
[페페] 「생산현황 메모를 세로로 반 나눠라. 좌측은 기존 사용자 입력칸, 우측은 미입고 보드 자재 기준으로 현장명·칼라·입고일」 + 「운영배포」 + 「이 부분은 자동파이프라인 구축해서 매번 자동 갱신한다」.
화면 = C:\dev\pfs\web\templates\basic\field\field_status_print.html(/field/print/status).
- 우측은 손입력 칸이 아니다 — 이미 깔려 있던 파이프라인의 읽기 창이다. 새로 만든 자동화 0:
\orderpaper_autosync(30분, NAS 발주서 엑셀 → orderpaper DB · 마지막 결과 0) →\IntakeCheck-1630(매일 16:30, 카톡 명세서 판독 →status='완료') → 출력물이 열릴 때마다 재조회. - 범위 = 생산현황에 뜬 현장만(그릴링 1문 → 페페 확정).
production_status.field_status='20'+ 출력 쿼리와 같은 상차연도 조건. 운영 실측 = 원행 9 → 현장+칼라+입고일 중복합침 7행(라인 VIPN997이 두께만 다른 3행). 전체 현장 기준이면 45행이라 반쪽칸을 넘긴다. - 신설 =
orderpaper_dao.select_unreceived_board_for_status()+GET /api/orderpaper/board-wait. 보드 = 자재분류 파생R· 미입고 =status<>'완료'· 입고일 = 항목별 > 블록 순 · 빠른 순 정렬. 🔴is_emptyNULL 주의(COALESCE) · 🔴숨김현장 안 거른다(라인 VIP) — 둘 다rules.md🆕. - 🔴
production_status_service.py를 못 고쳤다 — 브로커 오탐(OPS_FILE_PATTERNS의 맨패턴production)이 Edit 을auto-deny한다. 게이트와 안 싸우고 orderpaper 네임스페이스로 옮겨 붙였다(자재분류 파생 규칙이 있는 곳과 같아져 결과가 낫다). 패턴 수정은 안전게이트 완화라 페페 승인 대상. - 레이아웃 = web-designer 실측 처방 그대로.
table2분할 44:56(50:50 이면 현장명 3건이 2줄로 밀린다) · 우측 3칸34:46:20· 화면 13px / 인쇄 11px · 행break-inside:avoid+thead{display:table-header-group}. - 검증 = 테스트 8001 22/22 PASS(행수 25) · 운영 22/22 PASS(행수 7) · 운영 SQL 읽기전용 실검증 · 인쇄 미디어 캡처 육안 · 사이트맵 그룹 8 · 페이지 58 · 미반영 1(기존 건 그대로).
검사기 =
C:\dev\pfs\scripts\_memo_split_check.py [test|prod]— ⚠scripts/_*는 gitignore 라 로컬 전용이다. - 커밋 = master
597b987→ deploy-lived535760(4파일 선별 포워드 · blob 4/4 일치).
⏳페페 = ①실제 인쇄 1장 육안(돋움체 폴백은 프린터 드라이버마다 메트릭이 미세하게 다르다) ②연체(입고일 지난) 항목 강조를 넣을지(web-designer 선제 제안 — 지금은 지난 것과 곧 올 것이 같은 모양이다) ③미입고가 15~20행이 되면 좌측 메모칸이 세로로 늘어나 허전해진다 — 2단 분할 갈지(현재 운영 7행이라 아직 과설계).
✅ 26.9.14 — 네스팅 4차: 부재 표 우측 「사용 컬러」 패널 + 자재발주 완료 제외 — 운영배포 9d3c601 완료
[페페] 「도어 부재입력 테이블 우측 남는 공간에 독립된 스크롤 고정 프레임 + 사용된 컬러 정렬 표 · 자재발주 완료 여부 컬럼 → 네스팅 실행시 완료 항목 제외」 + 「운영배포」.
체크 단위 = 컬러(그릴링 1문 → 페페 확정). 파일 1개(C:\dev\pfs\web\nesting\nesting.html) · 백엔드·DB 0.
- 패널 =
#colorPanel(표 우측, 자기 스크롤). 행 = 부재 표에 실제 쓰인 컬러 가나다(ko)순 · 스와치(그리드 구분색과 같은 팔레트)+컬러명 · 수량 합 · 발주완료 체크. 헤더N/M색 완료· 하단N색 제외됨. - 🔑줄바꿈 문턱은
flex-basis가 아니라min-width다 —flex:1 1 0; min-width:min(900px,100%); max-width:1000px. basis 1000 고정이면 1280px 에서 패널이 아래로 떨어지고(flex 는 shrink 보다 wrap 이 먼저), basis 줄이고 grow 주면 1920px 에서 패널이 866px 저편으로 밀린다. 실측 1920/1440/1280 한 줄 · 1024/800 아래로 · 가로넘침 0. 상세 =rules.md🆕. - ⛔
position:sticky안 썼다 —#partWrap도 sticky 가 아니라 「고정 max-height + 내부 스크롤」이라 같은 공식만 복사하면 표와 같은 리듬으로 움직인다(web-designer 권고). - 🔴제일 위험했던 구멍 = 부재 그리드를 통째로 갈아엎는 5경로(
clearParts·loadSample·runPncad·runMomtong·loadJob)에서 체크를 안 비우면 옛 체크가 새 출처 부재를 에러 없이 제외 = 발주 누락. 전부doneColors.clear(),loadJob만opts로 복원. Fable 계획 초안이 잡아낸 건이다. - 제외는
runNest()부재 수집 루프의 빈 행 판정 뒤·숫자 검사 앞. 제외 내역은 패널 하단 + 실행 버튼 옆(#nestNote) 두 곳(「왜 이 컬러가 결과에 없지」 방지). 전부 제외되면 안내 + 옛 결과 숨김. - 저장 =
opts.doneColors(스키마리스 JSON, DB 변경 0). 표에 없는 컬러는 프루닝 — 패널과 저장본이 어긋나면 안 된다. 옛 저장본은 키가 없어 체크 0(양방향 호환). - 검증 = 신규 검사기
scripts/_nesting_colorpanel_check.py로컬 47/47 ·--test54/54 ·--prod55/55 · 운영 쓰기 0건. 회귀_nesting_qa5_check.py로컬 98/98 · test 114/114 · prod 115/115. 사이트맵 재빌드(그룹 8 · 페이지 58 · 미반영 1 = 기존 건). - ⚠
_nesting_grid_modal_check.py는 로컬 92/96 이 정상(26.9.14 3차 미반영 노후) — HEAD 기준선을 떠서 같은 수임을 확인했다. 회귀 아님. 상세 =rules.md🆕.
⏳페페 = ①1280px 실화면에서 패널·표 육안(계산상 딱 맞다) ②파스텔 스와치가 실제로 갈리는지 ③패널 폭 240px 에서 긴 컬러명(005C SHS1502 무광)이 가로스크롤 되는데 더 넓힐지 ④안드로이드 실기(패널이 표 아래로 내려간 상태).
✅ 26.9.14 — 배차 요율감시 수리 — Actions → 미니PC 이전 + 「성공할 때만 깨지는 관문」 3건 (운영배포 없음)
[페페] 「PFS 요율감시 오류 확인 후 감시 수정바람」. 오경보 1건에서 결함 3층이 나왔다.
- ① 위치 — 정부 사이트가 해외 IP 를 막았다. 같은 순간 Actions 러너
law.go.kr20s ·moel.go.kr15s 전부 timeout(구글 0.1s), 미니PC 한국 IP 는 둘 다 0.1s. 9.7 실행까지 정상 → 9.14 부터 전부PARSER_BROKEN. → 미니PC 예약작업\Cody\pfs-rate-watch(월 09:00 KST) 로 이전(페페 결정). 실행기 =C:\dev\tools\dc-rate-watch\run.py(숨김 vbs). ⛒전용 클론(tools\dc-rate-watch\repo)에서만 돈다 — 페페 작업트리엔 미추적 파일이 수십 개라 거기서reset --hard하면 사고다. Actions 워크플로는 파일을 남기고 API 로disabled_manually(차단 풀리면 enable 만 하면 되는 정본). - ② 잡음 — 재시도가 0 이었다. 한 번 깜빡이면 오경보 + 그 주 감시 공백(주 1회라 공백이 일주일).
판정에 쓰지도 않는 구글뉴스 실패가
PARSER_BROKEN경보를 울리고 있었다. →_get()재시도 3회(4s·8s, 404 등 영구오류는 즉시 포기) · 뉴스 실패는 로그만 · 실패 사유를 내용까지 기록 · 실패 시 연결확인 3줄. - ③ 관문 — 자동화가 «성공할 때만» 깨지는 검사 3건. 감시는 값이 바뀌었을 때만 계산부 검사를 돌리는데
그 검사가 「맨 윗줄 = 0.0176」 을 못 박고 있었다 = 실제 요율 변경이 오면 배포가 영구히 막힌다. 26.8.27 이후 한 번도 안 돌아본 경로다.
🔑뿌리 = 고시는 시행일 「전에」 나온다 → 새 줄은 한동안 미래날짜 →
DC_RATES[0]≠ 오늘 요율. → 값 고정을rateFor('20260827')(그 시점 줄)로 ·CUR을rateFor(dcToday())로 · 「과거 주문일도 오늘과 같은 값」 → 「그 시점 요율로」 · 검사용 시행일20270101→29991231.
검증 = 평시 자체검사 2종 ALL PASS + 요율이 실제 바뀐 상태(2027.1.1 시행 18.0‰/50.2%)를 흉내 낸 사본에서도 ALL PASS
(과거 배차 60,260 불변 · 새 주문만 60,250 으로 이동) · 예약작업 실경로 1회 LastTaskResult 0 · 창 안 뜸 · 다음 9/21(월) 09:00 ·
운영 선별 포워드 경로 국소검증(파일 1장만·부모 = 원래 deploy-live) · 사이트맵 재빌드(그룹 8 · 페이지 58 · 미반영 1 = 기존 건).
커밋 = master 742e152·6ead39f·ceb2d60·4f06371. 운영 템플릿 변경 0 = 배포 없음.
계획페이지 = http://100.108.234.45:8799/dispatch-rate-watch.html · 함정 2건 = projects/pfs/rules.md 🆕 맨 위.
✅ 26.9.14 — 네스팅 3차: 드롭 토글 · 행 드래그 · 컬럼폭+비고칸 · 행별 [+] — 운영배포 975ccad 완료
[페페] 4건. ①컬러칸 드롭 재클릭=닫힘(토글) ②행 순서 드래그 이동 ③컬럼폭 절약 + 수량 뒤 비고칸 ④행별 [+](그 행 바로 아래 새 행) + [✕] 를 버튼 2개 폭 띄움.
- 🔴비고는 맨 끝 +
newCol:1둘 다 필수 — 빼면setupPaste의 옛 9열 판정이 9→10 으로 틀어져 기존 엑셀·tread 붙여넣기가 조용히 어긋나고, 중간에 끼우면 11열의 결방향이 비고로 밀린다. 저장은parts LONGTEXT스키마리스 JSON 이라 DB 변경 없음. - 🔴드래그 손잡이 = 순번칸(
.seqcell) — 거기엔 입력 요소가 없어(cellEl()===null) 범위선택 mousedown 이 원래 무동작 = 제스처 충돌이 아예 없다. HTML5draggable은setupRange의 전역dragstart차단과 부딪혀 못 쓴다. 4px 임계·드롭선(box-shadow, 행높이 불변)·가장자리 자동 스크롤·키보드 대체Alt+Shift+↑↓(컬러칸Alt+↓는!shiftKey로 회피). - 🔴드롭 토글 판정은 click 이 아니라 mousedown 시점(포커스 이동 전) — click 때 재면 「빈 칸 첫 클릭」까지 「이미 열려 있었다」로 오인해 즉시 닫힌다.
- 🔴컬럼폭의 진짜 바닥은
.grid-scroll input{min-width:60px}이었다(→36px).#partGrid{max-width:1000px}없으면 1920px 에서 auto-layout 이 두께칸까지 170px 로 부푼다. - 검증 = 로컬 98/98 ·
--test114/114 ·--prod114/115 · 운영 쓰기 0건 · 사이트맵 미반영 1(그대로).
✅한때 미해결이던 --prod ⑦ 「네이티브 select 자체 팝업」 = 검사기 오탐으로 종결(26.9.14).
[페페] 운영에서 자재표 「세로규격」 클릭 → 2440/2700/3000 정상 표시 육안 확인. 실사용 결함 아니었다.
🔴원인 = 검사 방식: 운영에선 팝업이 열린 직후 다른 비동기 렌더가 droplist 의 scroll/focus 리스너를 건드려 곧바로 닫는다
→ 200~300ms 뒤에 「지금 보이나」로 재면 이미 display:none. ⛒열린 순간을 MutationObserver 로 잡도록 고쳤다
(_nesting_qa5_check.py ⑦). 최종 운영 115/115 PASS · 쓰기 0건.
⚠육안을 부탁할 땐 칸을 정확히 짚어라(26.9.14 한 번 헛짚었다) — 대상은 아래쪽 「2. 자재(원장) 등록」 표의 「세로규격」
(선택칸). 위쪽 「1. 도어 부재 입력」 표의 「세로」는 숫자 입력칸이라 아무것도 안 뜨는 게 정상이다.
⏳페페 = ①자재표 세로규격 팝업 육안(위) ②컬러칸 재클릭 닫힘이 감각에 맞나 ③컬러칸 100px 로도 최장값(005C SHS1502 무광, 필요폭 ≈125px)은 잘린다 — 더 키울지 ④행 드래그는 터치 미지원(raw mouse) — 안드로이드 필요하면 별건.
⚠부수 발견(미조치) = 그리드 input/select 의 computed font 가 Arial 이다(body 는 Segoe UI/맑은고딕). 라벨과 입력값 글꼴이 갈린다 — font-family:inherit 한 줄이면 되나 지시 범위 밖이라 안 건드렸다.
✅ 26.9.14 — 네스팅 2차: 상단 고정 · 컬러 구분색 · 크롬 datalist 폐기 — 운영배포 60b1eb4 완료
[페페] 3건. ③은 1차(아래)에서 내가 만든 것을 도로 걷어내는 지시였다.
- ①「해당 라인까지 상단 고정(스크롤 영향 X)」 = 2단 sticky(
.sticky-top제목+탭바 /.sticky-sub부재 제목+버튼줄). 🔴2단을.col안에 두면 안 된다 — sticky 컨테이닝 블록이 그.col이라 표를 지나 결과·BOM 으로 내려가는 순간 같이 사라진다(= 이 화면의 주 스크롤 동작)..wrap직속으로 빼고showTab()이 토글. 🔑높이를 px 로 못 박는다 — 640px(200% 확대)에서 둘 다 접혀 126→201px.recalcStickyTop()실측 →--stickyH→ 표 높이 축소(1080p 33행 · 768p 23행). - ②컬러 값별 파스텔 구분색 = 값이 아니라 등장 순서로 8색, 부재·자재 같은 맵 공유.
td에--tint+.tint(인라인 background 면 범위선택 하이라이트를 덮는다). 하늘#dbeafe·회청#e2e8f0은 기존 색과 충돌해 제외(web-designer 실측). - ③크롬 자동완성 금지 → 자체 드롭리스트 =
<datalist>삭제,data-drop="color", 그리드 텍스트칸 전부autocomplete=off. 새로 안 만들었다 — pncad 가 26.9.3 에 만든droplist.js를/production/pncad/droplist.js로 같이 쓴다. 함정 4개(키 충돌defaultPrevented· click 은 건드리지 마라 ·new Event('change')는 버블 안 함 ·body #pcDrop특이도) =rules.md🆕. - 🔴규칙을 어긴 건이다 — 「크롬 목록·자재완성 금지」는 26.9.3 지시로 이미 있었는데
projects/pncad/rules.md안에만 있어 pfs 작업에서 안 읽혔다. →C:\dev\CLAUDE.md§3 + kb08-forms-inputs.md§1-0 + ruleguardchrome-native-dropdown(block, 탐지기 13/13)로 전역 승격. - 검증 = 로컬 71/71 ·
--test87/87 ·--prod88/88 · 운영 쓰기 0건 · 사이트맵 그룹 8 · 페이지 58 · 미반영 1(그대로). ⚠다른 세션이 같은 리포에 커밋 3건(요율감시,scripts/만)을 넣어 뒀다 — 경계 확인으로 내 파일만 올라간 것 확인.
⏳페페 = ①8색 파스텔 육안 ②드롭리스트 팝업이 표 우측 끝에서 스크롤바에 안 가리는지 ③고정 2단 세로 공간
④안드로이드 실기(고정헤더+팝업, 웹 모바일뷰 대체 불가) ⑤삭제한 설명 5문단을 <details> 로 되살릴지.
⚠미결 = droplist.js 를 /static/js/ 로 승격(P2, 지금은 /production/pncad/ 를 빌려 씀) · .muted 12px · .tabbar 390px 가로넘침.
✅ 26.9.14 — 네스팅 QA 5건(버튼줄·제목·칼라DB·Enter 점프·계산기) — 운영배포 de24c6f 완료
[페페] 네스팅 화면 QA helper 보고 5건 + 「운영 배포」. 화면 = /production/nesting 「도어전용」 탭.
- ①버튼줄을 부재 표 위로(
.toolrowflex) ②h3 상세설명 삭제 — 괄호 안내 +<p class="muted">5문단.(총 N행)카운터는 상태값이라 남겼다 ④수량칸 Enter → 다음 행 「가로」(ENTER_JUMP={qty:'w'}, 마지막 행이면 새 행 만들고 그 가로) ⑤버튼줄 우측 끝 간단 계산기 — 화이트리스트 검사 후Function, 콤마를 먼저 지운다(안 지우면(1,200)이 쉼표 연산자로 200). - ③컬러칸 = 칼라 마스터(
poin_colors) 연동 — 문서에<datalist>1개를 부재·자재 컬러칸이 공유(라이브러리 0) + 저장 성공 뒤POST /api/poin/colors로 없는 이름만 등록. NOT NULL 3칸은 운영 다수 관례대로('', 1=PP, 0)(840행 중 449행·최근 수작업 5건 동일 · [GPT]코덱스 동의 —type=0같은 미사용 값은 조회·필터를 깨뜨린다). 가드 = 빈값·32자 초과 스킵 · 대소문자 무시 중복차단(서버 collation + 프런트 두 겹) · 회당 50건 상한. - 검증 = 검사기
scripts/_nesting_qa5_check.py로 로컬 32/32 ·--test40/40 ·--test --newcolor1/1(신규 1건 등록 → 재전송 0건) ·--prod41/41 · 운영 쓰기 0건(칼라 마스터 835건 그대로) · 사이트맵 재빌드 그룹 8 · 페이지 58 · 미반영 1 (/field/worklog= 26.9.9부터 있던 기존 건, 이번 건으로 안 늘었다). - web-designer 실측 처방 반영(계산기 원자 그룹핑
.calc-wrap— 안 묶으면 900px 에서 출력창만 다음 줄로 떨어진다 · 새 요소 폰트 13px). 단setupKeys시그니처 확장 안은 안 썼다 — 목표 칸을 실제data-k로 찾으면 인자가 필요 없어 호출부 3곳 누락 위험이 사라진다. - devplan
pfs-nesting-qa5.html+ 허브 카드pfs-nesting-qa5(furniture·live) 등록 · 세션 =session-2026-09-14-nesting-qa5.md.
⏳페페 = ①컬러칸 자동완성 팝업 실기 1회 — 실제 폭·부분일치(「오크」로 「화이트오크」가 뜨는지). OS 네이티브 렌더라
자동검사로 못 잰다 ②삭제한 설명 5문단을 <details> 접이식으로 되살릴지 판단(지시는 「모두 삭제」라 그대로 지웠다).
⚠알려진 제약 = datalist 팝업이 떠 있어도 ArrowDown 은 다음 행 컬러칸으로 간다(그리드가 화살표를 전역으로 가로챈다) →
컬러 후보는 타이핑 또는 마우스 클릭으로 고른다. ⚠.muted 12px(이 파일 수십 곳)·.tabbar 390px 가로넘침 73px = 기존 미결.
✅ 26.9.14 — 에넥스 발주서 변환 복구(.xlsx 전환 + 사이드카 워치독) — 운영배포 5f2c383 완료
[페페] 「PFS 에넥스 발주서 변환에 문제가 있다. 확인 및 조치해줘. 운영배포」
고장이 둘이었다 — 하나만 고쳤으면 여전히 안 됐다.
①에넥스가 .xls(OLE2) → .xlsx(OOXML) 로 바꿔 보내기 시작 → xlrd 2.x 는 xlsx 를 못 읽어 detect_format 이
조용히 unknown = 「미등록 양식입니다」. ②처리 사이드카(8791)가 26.8.10 20:39 이후 죽어 있었다 →
26.9.14 아침 업로드 3건(08:55·09:44·09:46)이 전부 pending, 화면은 2분 뒤 「시간 초과」.
사이드카만 살렸으면 3건이 error 로 굳었을 것이고, 파서만 고쳤으면 아무도 안 집어갔을 것이다.
- 파서 =
_enex_sheet(data)→(cv,nrows,datemode)로 리더만 분기(xls=xlrd·xlsx=openpyxl), 스캔 로직은 한 벌 그대로. 셀 좌표 레이아웃이 두 형식에서 완전히 같아서 가능했다. 매직바이트가 확장자보다 우선. openpyxl 의None·datetime을 xlrd 형식으로 정규화(안 하면 품명이 문자열 「None」). 안내문 필터에'**'추가 (규격·수량이 둘 다 없을 때만 — 실자재 오삭제 방지). - 사이드카 =
allow_reuse_address=False(윈도우 기본값이면 두 번째 bind 가 성공해 같은 업로드를 두 인스턴스가 집는다) - bind 를 폴링 스레드보다 먼저 + 로그 타임스탬프(35일 무감시의 직접 원인) + 예약작업
\Cody\pfs-sidecar-watch(10분). 포트 8791 을tools\portgate\PORTS.md에 등록(그동안 미등록). - 화면 문구(web-designer 처방) = 확장자
.xls/.xlsx/.pdf표기 · 「사무실 PC」 오표기 제거(실제는 미니PC 이고, 정확한 이름 대신 인프라 언급 자체를 뺐다) · 시간초과 문구에 다음 행동 2단계. - 검증 = .xls 회귀 18/18(대우 용인 11블록 55건 = 26.8.7 운영 적재분과 동일) · .xlsx 20/20(금호 구미형곡 14블록 77건) ·
venv(3.12)·py39 양쪽 통과 · 운영 적재 77건 / 업체 12 · 빈행 0 · 오적재 0(세 번 올린 게 231이 아니라 77 =
item_key멱등 확인) · 중복기동 차단 실측(두 번째 인스턴스10048즉사) · 워치독 소생 실측 · 운영 HEAD5f2c383+ 템플릿 실문구 확인 · 사이트맵 재빌드 그룹 8·페이지 58·미반영 1(26.9.9 과 동일, 이번 건으로 안 늘었다). - 검증기 =
C:\dev\pfs\scripts\_op_enex_parse_check.py(.xls) ·C:\dev\pfs\scripts\_op_enex_xlsx_check.py(.xlsx). 🔴둘 다scripts/_*라 gitignore 다 — 픽스처(_daewoo_enex.xls·_enex_upload5.xlsx)도 로컬에만 있다. 없어지면scripts/_enex_upload_fetch.py(운영 blob 조각 받기) +_enex_assemble.py로 복원한다. - devplan
pfs-enex-xlsx-convert.html+ 허브 카드pfs-enex-convert등록(최근·목록·진행판 3개소 확인).
⏳페페 = ①/field/orderpaper 에서 금호 구미형곡 3차 부자재 77건(업체 12) 육안 1회
②업로드 모달 폰트 3곳이 12px 로 13px 하한 위반인데 이번엔 안 건드렸다 — 올리면 margin-top:60px 고정이라
낮은 뷰포트에서 모달 하단이 잘릴 수 있다(미측정). web-designer 미결 「13px 전면 정리」와 한 건으로 묶을지 판단.
✅ 26.9.9 — GS 원주 단구 한샘 견적서 84A(기본) 추가 + 부자재 분리 — 운영배포 5d9bd2f+7cb6ea1 완료
[페페] 「gs 원주 단구 현장 견적서 작업 / pfs 한샘 견적서 등록 / 엑셀파일 나스 원주 단구 폴더에 저장 / 기존 84a가 84a(옵션) 으로 이름 변경 / 84a(기본)이 추가됐다 / 기존 내용은 유지하고 84a(기본)만 신규 추가 / 기존 내용들은 수식 및 합산 유지하면서 숨겨진 행들은 모두 삭제하고 정리 / 메인 탭에 84a(기본) 금액 항목 추가 / 탭 및 명세서 순서는 84A(기본),84A(옵션),84C / 지난번 다른 현장에서 적용했던 추가금액(sub-item) 별도 행 분리 동일 적용 / 운영배포까지」
그릴링 4문 페페 결정 = ①엑셀은 기존 NAS 수작업본 직접 수술(PFS 재생성 아님) ②84C 는 ALT.1·ALT.2 두 탭 유지 ③PFS 는 새 1건 등록 + 옛 V1(3)·V2(2) 보관처리 ④NAS 는 새 파일 「26년 09월」(8월 원본 보존).
- 🔴엑셀 「복구하시겠습니까」 사고 → 해결(26.9.9 후속 세션). 원인 =
docProps/app.xml시트 개수·이름 불일치 (이미sync_app_xml로 수정) + 블록명 셀B{b}→C{b}. 그 뒤의 이진탐색이 「범인=fill_main」이라는 틀린 결론을 냈는데,bisect_stage.py가 중간 산출물에finalize()(=calcChain폐기)를 안 걸어 낡은 calcChain 1,547항목이 판정을 오염시킨 것이었다(규칙rules.md🆕 맨 위). 고쳐 재측정 = 9단계 전부 OK. ⛒재빌드한 로컬 정본은 Excel 정상열림(mode 0)·무수정(수식1553/병합466/도형1 정상화본과 동일) · verify 127/127 ·_xlcheck0 ·xldiag0(정의이름 19건은 8월 원본에도 있는 기존 항목) ·sfcheck0. ✅NAS 교체 완료(페페 승인 후 smbclient 삭제→재업로드, 199,908B 깨진본 → 199,853B 정상본, 왕복 sha25688b2e075…일치). 8월 원본은 안 건드렸다. - 🔴후속 — 순환참조 1건 발견·수정(페페가 파일 열자마자 경고).
가격적용분!S476=SUM(S5:S488)이 자기 자신을 더하고 있었다. 원인 =drop_hidden_rows가 「수식은 전부 같은 행만 참조」 전제로 같은 행 참조만 옮겨, 총합 셀은 S489→S476 으로 내려왔는데 범위는 안 따라간 것(같은 자리에S842=SUBTOTAL(9,S480:S483)도 범위가 13행 어긋나 있었다 — 순환은 아니지만 오답). ⛒build.shift_refs()신설 = 수식 안 모든 행 참조 재배치 + 범위 끝점 클램프. →SUM(S5:S475)·SUBTOTAL(9,S467:S470), 두 값 모두 원본과 같은 0(빈 보조열). 검증 = 순환 0건(신설cycles.py) · verify 134/134 ·_xlcheck0 ·xldiag0 ·sfcheck0 · Excel 정상열림 무수정(1553/466/1). 금액 불변(본오더 소계 29,100,000 · 총계 36,000,000). 🔴Excel probe 는 순환참조를 못 잡는다(DisplayAlerts=False→ 조용히 열림) — 그래서 1차에 놓쳤다. ✅NAS 재교체 완료(sha2566d37ff4d…). ⚠교체 직전 NAS 파일이 216,723B(페페가 열어 저장한 것)라 백업 없이 지웠다 — 휴지통에서 회수해 대조, 차이는 내가 고친 2칸뿐(페페 수정분 손실 없음). - 정본 = NAS
2026현장\견적\09월\넥서스\GS원주단구2BL\1.생산비 거래명세서_GS 원주 단구 MH_26년 09월.xlsx(왕복대조 일치) - PFS 한샘 견적
estimate_no=7— 평형 4 · 상세 30줄 · 총액 29,109,099 · 고아 0. 옛 2·3 은archive_yn=1 - 탭 = 84A(기본) 6,159,115(신규) / 84A(옵션) 9,470,280 / 84C(ALT.1) 6,167,851 / 84C(ALT.2) 7,311,951 → 갑지 본오더 소계 29,100,000(만원 절사) + 운반비 400,000 + 시공비 6,500,000 = 36,000,000
- 🔑기존 3탭 총합은 원 단위까지 불변 — 부자재를 본블록에서 빼내 제 블록으로 옮겼을 뿐 금액은 안 건드렸다. 「수식 및 합산 유지」의 증거가 이 세 숫자다.
- 84A(기본) 원천 = 포인 763(오늘 페페가 수정, 25줄·항목합 30,153,000) 의 84A(기본) 4줄 + sub 6건. 배수·등급은 같은 평형(84A(옵션)) 관례를 그대로 따랐다(상부장 D×0.7 · 하부장 A×1.65 · 냉장고 A×1.8 · 키큰장 A×1.65). ⚠포인 84A(기본) 6,254,000 과 −94,885 차 — 이 파일은 한샘 실단가 기준이라 다른 탭도 포인보다 작다(옵션 −376,720).
🔴덤으로 운영 결함 1건 — 양식(form 3)의 오픈장(25)·키큰 FIX(39)·공틀도어(46) 는 단가 LOOKUP 이 한 칸도 없다
→ 적용가 = 빈칸 × 10MM기준 = 0. 운영이 낸 원주 단구 엑셀에서 공틀도어 3탭 1,715,622원이 빠졌다(목록 총액은 정상).
⛒같은 단가군의 다른 블록에서 LOOKUP 을 베끼고 배수를 다시 붙인다(master 5a0c528 → 운영 7cb6ea1).
회귀검사 = C:\dev\_work\gs-wonju-dangu\test_donor_price.py.
✅26.9.7 미결이던 api/pfs/hansem/ 운영배포 완료 — 견적 6(안산 성포) 운영 엑셀이 서버총액 30,889,012 와 정확히 일치
(직전엔 −4,123,878~+7,412,865 어긋나 있었다). 견적 1·4 수식누락 0(회귀 없음).
검증 = 산출 xlsx 100/100 PASS(verify.py) · 구조검사 _xlcheck.py 10시트 결함 0 ·
PFS 왕복 30/30 · 운영 엑셀 재계산 = 서버총액 차 0원(check_prod_excel.py) · 사이트맵 재빌드 그룹 8·페이지 58·미반영 1(한샘 diff 0).
도구 = C:\dev\_work\gs-wonju-dangu\{spec,build,verify,register,check_prod_excel,test_donor_price}.py.
⏳페페 = ①엑셀 육안 1회(엑셀이 「복원하시겠습니까」를 안 띄우는지 · 84A(기본) 탭 내용) ②한샘 견적에 sub-item 저장 스키마를 넣을지(넣어야 PFS 가 NAS 정본을 그대로 재생산한다. 지금은 부자재가 부모 블록 첫 칸 적용률에 녹아 있어 총액만 맞고 행은 안 보인다, 잔차 −98원).
✅ 26.9.7 — 발주서 정리 탭 모바일 전용 레이아웃 — 운영배포 12e8efb 완료
[페페] 「/field/orderpaper 자재관리 페이지의 발주서 정리탭을 이번 업체별 자재관리 탭처럼 모바일 전용 페이지로.
필터가 매우 많으니 모아서 기본 접힘, 인라인 검색만 기본 노출. 동기화 강조는 안 넣어도 된다. 운영 배포」.
산출 = 파일 1개(web/templates/basic/field/field_orderpaper.html) · 라우트·템플릿 신설 0 · DB 변경 0.
master 235e93c→a8d5a74→1bd001d→e0afe90→a9b4914 → 운영 12e8efb(선별 포워드, 템플릿만).
devplan pfs-orderpaper-mobile.html + 허브 카드 등록(최근 3개소 확인) · 세션문서 session-2026-09-07-orderpaper-mobile.md.
🔑「모바일 전용 페이지」 = 별도 라우트가 아니다 — 지시의 「업체별 자재관리 탭처럼」이 방식 지정이고
그건 같은 파일 @media (max-width:767px) 카드형 변환이다(26.9.4 에 모바일 전용 목업을 이미 한 번 폐기했다).
🔴최대 리스크 = 같은 템플릿을 세 라우트가 공유(/field/orderpaper · /omc/material · /field/company/<no>/material,
뒤 둘은 어제 운영 배포). #opMainWrap·#opList·.op-site·편집 칩이 전부 겹친다 →
{% if not omc_view %} 로 CSS 를 통째로 갈랐다(코덱스 상의 결론도 동일). 운영 HTML 마커 개수로 실증
= /field/orderpaper op-mf-open 7 vs /omc/material 1(JS 뿐).
접었을 때 남는 것 = 인라인 검색 + 「⚙ 필터」 토글(배지=걸린 필터 수) + 적용 칩·건수.
접히는 것 = 분류기준·툴바(자재토글·숨김현장·업로드·동기화)·빠른필터 6·상세필터·초기화.
안 접히는 것 = .op-datewarn(필터가 아니라 데이터 이상 경고).
모바일에서 뺀 것 = 동기화 강조(배너·NEW, 페페 지시) · 블록 일괄조작(자재지정·상태일괄·블록삭제) · 순번(#).
⚠항목 단위 편집(상태·입고일·발주량·비고·품명)은 그대로 된다.
web-designer 실측이 「불편」이 아니라 결함임을 밝혔다 — .op-site-head 에 flex-wrap 이 없어 현장명이
세로로 한 글자씩(w=21 h=203) 쌓였고, 표 실폭 535px 이 가용 328px 에서 overflow:hidden 에 잘려
입고일·상태버튼·삭제× 가 안 보이고 안 눌렸다. 필터·툴바가 세로의 73%(619/844px)를 먹었다.
검증 = 정적 24/24 · 테스트 실측 34/34 · 오엠씨 회귀 24/24 · 운영 읽기전용 34/34 ALL PASS ·
사이트맵 재빌드 미반영 1(= 이전부터 있던 /field/worklog 별건, 이 작업 세 화면은 전부 반영).
🔴중간에 한 번 깨뜨렸다 — 첫 push 에 CSS 주석 안 Jinja 태그가 섞여 테스트서버 세 화면이 동시에 500.
정적검사가 잡아 2분 만에 복구, 운영엔 안 나갔다. 함정 5개 = rules.md 🆕 맨 위.
⏳페페 몫 = 노트20 실기 육안 1회(에뮬레이션 통과 ≠ 실기 통과, 26.9.4 에 실기에서만 4건 나온 전례) · 모바일에서 블록 일괄조작이 실제로 필요한지 · 순번(#) 숨김이 종이 발주서 대조 관행과 안 부딪히는지 · 13px 미만 29종 전면 정리(데스크톱 포함) 여부.
✅ 26.9.7 — GS 안산 성포 한샘 양식 재작성 A~G 완료 — 운영 등록 estimate_no=6 · NAS 저장 완료
📄 착수 근거 =
projects/pfs/relay-2026-09-07-hansem-form-rebuild.md(페페 확정 규칙 7개 · 양식 구조 실측). 작업 폴더 =C:\dev\_work\gs-ansan-seongpo\
🔴1차 산출은 틀렸다 — sub-item 46건이 통째로 빠졌다(페페가 잡음). 인수인계의 「sub-item 0건」이 오판이었다:
/api/estimate/769 는 sub 를 안 준다(/api/estimate/sub/list/<detail_no> 가 따로다). 실제 46건 9,224,150원.
v2 가 정본이다 — -추가 블록 16개 · 46칸 전부 반영.
산출물 —
①양식 C:\dev\_work\gs-ansan-seongpo\한샘양식_GS안산성포_4평형_주방전용.xlsx → 운영 form_no=3 활성
②견적 운영 등록 hansem estimate_no=6(현장 2180 · 평형 4 · 상세 24 · 고아 0 · 총액 30,889,012, 적용률 메모 제거 완료)
③🔵정본(v2, 26.9.7 재빌드) = NAS …\GS 안산 성포 MH\한샘 GS 안산 성포 MH 견적서 v2 (추가금액 반영).xlsx
⛒2차 수정 = 병합 겹침(엑셀 복원 프롬프트) 제거 · 갑지 탭별 합계 참조 복구(총합행 67/60/60/46) ·
안 쓰는 블록 삭제(84A 9 · 99A/104 8 · OT84A 6블록) · 숨김 행 0 ·
추가 블록 행 순서 단가→수량→비고→적용가(페페 지시, 행이름 단 가).
✅4차 = 블록 구조 포인 항목 1개 = 블록 1개(블록명 = 포인 품명, 단가만 한샘 단가군). master 4aa3ba9.
🔴3차 수정(이중 계상) = 행총액에 추가금액이 이미 포함이라 본항목 = 행총액 − 추가로 바꿨다.
갑지 합계(VAT 별도) = 본오더 소계 30,880,000(= 30,889,139 − 절사 9,139) + 운반비 300,000 = 31,180,000원
⚠v1(…견적서.xlsx)은 26.9.7 10:54 KST 에 페페가 Excel 로 직접 편집해 놨다 → 덮어쓰지 않고 v2 를 따로 올렸다.
그 편집(절사 행 신설 -9,012 · 운반비 300,000 복원)은 v2 에 반영했다. v1 삭제·교체는 페페 몫.
A~G 처리 = A 슬롯 복제 3→4평형(84C, 내역서 주/수 + 도면 세트) · B 수납·자재비·운반비·추가분견적·가격적용분
내용 전량 삭제 + 숨김(⚠시트 자체 삭제는 못 한다 — 운영 옛 엔진이 수납 탭과 -주/-수 쌍을 양식 필수조건으로
검사해 업로드가 거부된다. 엔진 배포 후엔 삭제 가능) · C 갑지 본오더 4행·추가분 8행 물리 삭제(=+#REF! 동반 제거)·
자재비/운반비/절사/시공비/수납 전부 0·W20·W21 하드코딩 금액 → 수식 · D insert_extra_blocks 구현(이번 견적은
sub-item 0건이라 삽입 결과 없음, 코드·자체검사만) · E 모노크롬 도면 4장 교체(레터박스) · F NAS · G 운영 등록.
🔴작업 중 운영 결함 발견 = 「단가 LOOKUP 없으면 조용히 0」의 짝인 미러 열 적용가 행이 안 채워진다 →
기존 한샘 견적 4건 전부 엑셀이 서버 총액과 −4,123,878 ~ +7,412,865 어긋난다(측정 _prod_impact.py).
고침 = master 58daac4. ⏳운영 미반영 — api/pfs/hansem/ 3파일이 deploy-live 와 벌어져 있다
(hansem_excel.py +445 · hansem_service.py 6 · hansem_estimate_dao.py 11 = 26.9.4 고아 방지 다리도 미배포).
이번 산출물은 배포 없이도 정확하다 — 양식에 정답 셀 레이아웃을 구워 넣었기 때문(rules 🆕 참조).
🔴운영이 v2 와 같은 파일을 내려면 두 가지가 먼저다 — ①api/pfs/hansem/ 배포(옛 inject_ledger 는
하드코딩 BLOCK_ROWS 만 돌아 추가 블록을 못 만들고 오히려 지운다) ②sub-item 저장 자리(hansem 스키마엔 없다).
그 전까지 운영 다운로드에는 -추가 블록이 없다(본항목 24줄만, 금액은 정확). 정본은 NAS v2.
⏳페페 판단 3건 = ①api/pfs/hansem/ 운영배포 여부(하면 기존 견적 4건의 엑셀 금액이 바뀐다 = 바로잡힌다)
②한샘 견적에 sub-item 저장 스키마를 넣을지(넣어야 운영이 v2 를 그대로 재생산한다)
③배포 후 양식에서 수납 계열 시트를 진짜 삭제할지(지금은 숨김) · NAS v1 파일 정리.
⚠미해결 잔재 1건 = sharedStrings.xml 에 라인 아산7차(리뉴얼) M/H·임서현 문자열이 참조 0인 채로 남아 있다
(어느 셀도 안 가리켜 화면·인쇄에는 안 나온다). 지우려면 양식 재업로드 + 견적 재저장이라 값어치 대비 미실행.
🆕 26.9.4 — 포인↔한샘 매칭표 비교축 재정리(추가금액 분리) ✅페이지 반영 · ⏳페페 판단 2건
페페 지시 = 「포인·한샘 양쪽에서 길이로 측정된 단가만 반영하고 추가금액을 양쪽 동일하게 따로 빼서 반영해라」.
대상 = C:\dev\devplan\hansem-poin-price-map.html(http://100.108.234.45:8799/hansem-poin-price-map.html) ·
생성기 C:\dev\order-automation\{hansem_price_mapping.py, build_price_map_page.py}. PFS 코드·DB 변경 0(문서 페이지만).
- 🔴작업 중 진짜 오류를 잡았다 — 이전 세션의 「옵션 8,078,018」에 마진이 섞여 있었다.
margin_total_amount − amount로 잡았는데 그 안에 거래처 마진 15.5%(2,645,020) 가 들어 있다. 마진은 자당몫에 걸리는 비율이라 길이에 비례한다 → 추가금액이 아니라 길이 쪽이다. 바른 분해 = ①자당몫 15,820,982 + ②마진 2,645,020 + ③추가금액 5,432,998 = 행총액 23,899,000(+행별 천원 올림 끝수 합 −2원). - 🔑비교 본선 = ①+②
18,466,002vs 한샘 길이환산 — ①만 쓰면 마진만큼 포인을 과소평가한다. 결과가 뒤집힌다: 이전 「D등급 +1,220,568(한샘이 비쌈)」 → 바른 값 D−1,424,452(−7.7%). A −6,509,302 / B −5,169,052 / C −4,275,552. 적용등급 판정은 그대로 D(가장 가까움). - 🔑③은 양쪽 공통 가산항 → 최종 = 포인 23,899,000 vs 한샘 D 22,474,548, 차액 = 길이단가 차이 그대로 −1,424,452. ⛒「행총액 대비 −28.7% 손실」 서사는 삭제했다 — 손실이 아니라 ③을 한샘 양식 어느 탭에 실을지의 청구 경로 문제다.
- 페이지 변경 = KPI 기준을 ①+②로 ·
.addon스트립 신설(③을 KPI 격자 밖으로) · 「최종 금액」 소표 신설(①/②/①+②/③/최종/차액) ·.bad박스 삭제 · 표A 16→17열(끝 3칸 =길이단가몫(비교)·추가금액(별도)·행총액(참고, .ref)) · 대안 §를 ㉠길이단가 / ㉡추가금액 두 축으로 재편 · 표B·C 에 「마진 전 축이라 표A와 다르다」 경고 · 누락돼 있던 qahelper.js 추가. - 🔑입력 JSON 을 리포로 옮겼다 — 세션 scratchpad 에 있어 사라질 뻔했다 →
C:\dev\order-automation\_pricemap\(poin_master.json·poin_763.json·hansem_master.json·산출mapping.json). 두 스크립트 모두 이 경로를 본다. - 🔴web-designer 실측이 CSS 특정도 버그 3건을 잡았다(내가 만든 것 2 + 기존 잠복 1) —
table.t thead th(0,1,3) 베이스 규칙이td.mark,th.mark·thead .stick1(0,1,1) 을 이겨서 헤더·합계행의 적용등급 강조 실종 · 참고열 스타일 실종 · 가로 스크롤 시 헤더의 고정 2열(타입·품명)이 뒤 헤더 셀에 덮임. 에러 0이라 안 보인다. ⛒셀렉터에table.t를 붙여 (0,2,2) 로 이기게 고쳤다. 규칙 =C:\dev\devplan\CLAUDE.md맨 위. - 🔑참고열을 「밝은 배경」으로 죽이려던 첫 안은 형광펜 강조로 읽혔다 — 글자를 흐리는 것도 안 된다(페페 규칙 연회색 금지 +
--text-dim은 헤더 배경 위 3.89:1 로 AA 미달). ⛒경계선 +참고라벨 + 굵기 400 으로 갈랐다(색 안 씀 = 색약 안전). - ⚠A4 가로 인쇄에서 표A(17열)·표B·C(16열)의 오른쪽 끝 열이 잘린다(기존부터 있던 결함, 열 추가로 확대는 아님). 세로 분할은 없다(표A 21행+합계 1페이지, 「최종 금액」 소표도 1페이지). 지금은 인쇄 전용 경고 줄만 넣었다 — 열을 숨길지는 인쇄물 용도(내부 검토 / 한샘 협상 지참)에 달려 페페 판단. 폰트 축소는 13px 하한이라 안 쓴다.
- 검증 = 신설 2종. 정적
C:\dev\devplan\_verify_price_map.pyALL PASS 10/10(링크순서 ·:root재선언 0 · 페이지 hex 0 · 상태배지 157개 전부 아이콘 병기 · 표 5개 colgroup↔thead↔tbody↔tfoot 열 정합). 실측C:\dev\devplan\_verify_price_map_live.pyALL PASS 18/18(computed style 로.mark·.ref실적용 +elementFromPoint로 헤더 고정열이 덮였나 + 4해상도 body 가로스크롤 0 + 콘솔에러 0). 🔑특정도 버그는 정적 검사로 절대 안 잡힌다 — computed style 을 재야 한다. 그 외check_font.pyFAIL 0(13px 하한) ·check_theme.pyFAIL 0 WARN 0 ·hansem_price_mapping.py안에 assert 2개(①+②+③=행총액 · 공통가산이 차액을 안 바꾼다). - ⏳페페 판단 대기 3건 — ①도어사양으로 한샘 등급 확정(D 가정 중, 그래도 −1,424,452 모자란다 → 적용률·협의 필요) · ②추가금액 5,432,998 을 한샘 양식 어디에 실을지(자재비 탭 = 자재성 / 추가분견적 탭 = 사후 발생분 성격 안 맞음 / 하드웨어·EP·픽스판넬은 갈 곳 없음) · ③이 페이지를 인쇄해서 쓰나 — 쓴다면 어느 열을 인쇄에서 뺄지 (A3 가로 지원 프린터가 있으면 열 숨기기보다 A3 전환이 낫다).
🆕 26.9.4 — 생산현황 출력 미확정 표 헤더 제거 · 아이비젼 축약 · 행 여백 50% ✅운영배포 198744d
페페 지시 3건(= /field/print/status) — ①「상차일 미확정 그룹에서 컬럼헤드를 빼자. AS/추가건과 같은 형태니 컬럼명이 없어도 이해된다」
②「추가 기본규칙 : 아이비젼글로벌은 아이비젼 으로 축약해서 표기」 ③「각 테이블 행의 높이 여백을 현재의 50%로 줄여 높이 절약」.
master 39af394 → deploy-live 체리픽 198744d. 파일 3개(템플릿만).
- ①
#tbd-grid의<thead>만 삭제.<colgroup>은 그대로 둔다 —table-layout:fixed라 폭은 colgroup 이 정하므로 헤더가 없어도 위 AS 표와 컬럼 폭이 픽셀 단위로 같다(실측[84,199,69,123,238,54]양쪽 동일). - ②축약은 표시 함수 한 곳(
compName)에서 한다 —/(?:글로벌)?\s*아이비[젼전]\s*(?:글로벌)?/ → '아이비젼'. 🔑8.10 의 「이름 순서를 바꾸지 말고<br>로 2줄 끊는다」 규칙은 이걸로 끝났다 — 축약하면 8% 폭에 1줄로 들어가서<br>자체가 불필요하다. 덤으로 운영아이비젼글로벌/ 테스트글로벌아이비젼표기차가 화면에서 사라진다(둘 다 「아이비젼」). 같은 규칙을 업체필터 버튼 2곳(field_list.html·estimate_list_v2.htmlCOMPANY_FILTERS)에도 적용 — 부분일치라 짧은 쪽이 두 표기를 다 잡는다(테스트에서 0건 나오던 것도 같이 해결). ⚠DB 거래처명·엑셀·발주서는 안 건드렸다(표시만). - ③여백만 절반 — 화면
4px→2px, 인쇄3px→1.5px. 폰트·line-height:1.5는 그대로(두 줄 셀 겹침 0 실측). 절약 실측 = 같은 페이지에서 종전 여백으로 되돌려 대조: 996 → 920px(-76px, 17행). - 🔜web-designer 잔여 제안(미적용 · 페페 판단) — 「50%」를 여백에만 적용하면 행높이는 8% 밖에 안 준다(행높이의 대부분이 글자다).
실제로 더 줄이려면
line-height 1.5 → 화면 1.35 · 인쇄 1.25(2줄 셀 기준 인쇄 37.5→29.3px, -22%)를 같이 내려야 한다. 하한 1.2(그 밑은 2줄 셀 받침 겹침). 폰트는 못 줄인다 — 상태칸 9px = 6.75pt 로 이미 인쇄 하한 아래. ⚠인쇄 블록엔line-height지정이 없어 화면값 1.5 가 상속된다 → 내릴 거면 인쇄 블록에도 같이 넣어야 효과가 난다. - ⚠회귀 위험 1건(현재는 무해) —
#tbd-grid가 인쇄에서 페이지를 넘기면 thead 가 없어 다음 장에 컬럼 반복이 안 된다 (h2 제목도 표 밖이라 원래 반복 안 됨). 미확정은 보통 2~3행이라 1페이지 안이지만, 이 표가 길어지면 헤더를 되살릴지 판단할 것. - ℹ범위 밖 = 업체 색상맵에 봉적이 없어 색 없이 나온다(운영 화면에 봉적 현장 2건 확인). 지시에 없어 안 건드렸다.
- 검증 = 신설
C:\dev\pfs\scripts\_status_print_check.py [test|prod]— 테스트 22/22 · 운영 21/21 ALL PASS. 실데이터에 아이비젼·미확정 행이 없을 수 있어 페이지의compTd()로 임시 행을 주입·실측 후 제거한다(저장 없음). ⚠이 파일은.gitignore에 걸려 커밋 안 됨(scripts/_*) — 로컬에만 있다.
🆕 26.9.4 — 업체 필터에 「봉적」 버튼 추가(현장목록·견적서목록) ✅운영배포 완료 3cdd6e6
페페 QA 1건(qahelper · /field/list 아이비젼글로벌 버튼) = 「봉적 버튼 추가 / 견적서목록에도 추가바람 / 운영배포」.
- 자리 2곳뿐 =
web/templates/basic/field/field_list.html·web/templates/finance/estimate/estimate_list_v2.html의COMPANY_FILTERS배열(둘 다 같은 구조·같은 배열). 필터는company_name부분일치라 원소 1개 추가로 끝이다. 배포는 템플릿 2파일. - 🔑거래처 실명 확인부터 했다(
scripts/_bongjeok_company_probe.py, SSM 읽기전용) —company.name= 정확히 '봉적'. 운영company_no=445현장 18건·견적 3건(견적은 field 조인 —estimate테이블엔company_no가 없다). 동명 고아company_no=160(현장 0건)도 있지만 문자열 매칭이라 무관. - 🔴테스트 RDS 는 거래처명이
글로벌아이비젼, 운영은아이비젼글로벌— 그래서 테스트에서 아이비젼 버튼만 0건이 나온다(정상, 내 변경 아님). 같은 화면을 테스트로 검증할 다음 사람이 오탐하기 딱 좋다. - 🔑DataTable 화면에서 필터 효과를
tbody tr수로 재면 안 된다 — 페이지 크기(10·20)에 잘려 「필터해도 그대로」로 보인다. ⛒$(sel).DataTable().rows().count()로 센다(이 함정으로 검증이 1회 오탐 FAIL 2건). - 검증 = 신설
C:\dev\pfs\scripts\_bongjeok_filter_check.py [test|prod]테스트 ALL PASS 21/21 — 버튼 5개·순서 · 한 줄(top 1종·높이 31px) · 겹침 0 · 폰트 14px(하한 13 준수) · 봉적 필터 결과 전부 봉적·타업체 0 · 재클릭 해제 · 기존 한샘 회귀 · 콘솔 에러 0. 스크린샷scripts/_shot_bongjeok_{field,estimate}_test.png. - 🔴부수확 = 진짜 버그(web-designer 실측) —
#view-manage .dataTables_filter가 절대배치라 업체 버튼이 늘수록 왼쪽으로 자라 상태탭(.pfs-st-tab)을 덮는다. 공식 =겹침 = 뷰포트폭 - 1045(5버튼) → 992px 에선 「완료」탭이 통째로 사라졌다. 4버튼 때도 -10px 로 이미 겹쳐 있던 잠복 버그를 5번째가 눈에 보이게 키운 것. ⛒처방 =@media (max-width:1199px)에서position:static; margin:0 0 10px; text-align:right로 흐름 복귀(줄바꿈). 견적목록은 같은 배열·같은 로직인데 컨테이너가float:right(흐름 안)이라 원래 안 부딪힌다 — 손 안 댔다. 🔜미채택 제안 = 탭바+필터를 하나의 flex 부모로 묶기(버튼 수 무관하게 원천 차단) · 업체 6개 넘으면 버튼 나열은 한계 →<select>전환. - 검증 = 테스트 27/27 · 운영 ALL PASS 28/28(1199·992·768px 상태탭 가림 0 포함). 운영 실측 = 봉적 현장 14건/132 · 견적 3건/43.
- 사이트맵 재빌드 = 그룹8·페이지57·미반영 1(남의
field_worklog.html— 내 2파일은 걷혔다). - 🔴🔑사고 —
git checkout deploy-live 2>&1 | tail -3 && git reset --hard origin/deploy-live로 로컬 변경을 날렸다. 파이프라인 종료코드는tail것이라 checkout 이fatal(worktree 점유)로 죽어도&&가 성립해서master위에서 reset 이 돌았다. 잃은 것 = 커밋 안 된pfs/CLAUDE.md로컬 수정(내 것 아님·복구 불가) +tools/sitemap/menu_dump.json(재빌드로 복구됨). ⛒규칙 = 브랜치 전환·reset 은 파이프에 물리지 말고 단독 실행, 앞에git status로 미커밋 변경부터 본다. 🔑deploy-live는 worktreeC:\dev\pfs_deploy_wt가 점유하고 있다 — 배포는 거기서 한다(메인 체크아웃에선 애초에 checkout 안 된다). - ⚠검증 오탐 1건 = 필터 결과에 타업체가 섞였나를
tbody전체 텍스트로 보면, 현장명에 남의 업체명이 든 봉적 현장("넵스…")에 걸린다. ⛒DataTable().rows().data()의company_name만 본다. - ℹ범위 밖으로 남긴 것 = 생산현황 출력(
/field/print/status)의 업체 색상맵엔 봉적이 없다(현장이 뜨면 색 없음). 지시는 필터 2곳뿐이라 안 건드렸다.
🆕 26.9.4 — 넥서스→한샘 자동전환 재검토 + 신영 광주 추가2·추가3 한샘 전용 견적 ✅운영배포 완료 dfd1435
페페 ①「넥서스 표기 파일·현장 한샘 자동전환 됐는지 재검토」 ②「NAS 추가2,3 견적서를 pfs 한샘 견적서로 작성,
금액 최대한 맞춰(완벽 불필요·빠른 작업 우선), 운영배포」. 상세 = session-2026-09-04-hansem-shinyoung-add23.md.
- 🔑「한샘 견적서」가 두 갈래라 그릴링으로 갈랐다 — 기존 견적계통엔 추가2·추가3 가 이미 있었다
(742=890,000 · 754=1,106,000, NAS 엑셀과 셀단위 금액 100% 일치, 페페가 7.30·8.19 직접 등록).
→ 페페 결정 = 한샘 전용 모듈(
/estimate/hansem)에 새로 작성. 이어서 「한 목록으로 탭만 구분해 통합」 지시 → 운영 한샘견적 4 = 「신영 광주 챔피언스시티 MH — 추가2·추가3」 1건, 평형 슬롯(=엑셀 탭)추가2·추가32개, 상세 13줄, 총액 1,996,017원(원본 1,996,000 · +17원). 분리본 5는 통합 후 삭제. 🔑한샘 모듈에서 「탭」 = 평형 슬롯(hansem_estimate_type) — types 2개면 엑셀에<이름> 내역서-주/수가 두 벌 생기고 갑지 A19~A21 이 각각을 참조한다. 마스터는 하나뿐이라 현장·날짜·담당은 하나로 정한다(현장 1973 MH · 8.19 · 김영민 부장, 추가3 의 AS 현장 2158 은 비고로만 남김). - 자동전환 현황 = 거래처 마스터·발주서 파일명·도어발주서 H6·견적 출력 업체명 ✅ / 현장명 ❌ → 신설
(
field_service._normalize_field_name, 등록·수정으로 들어오는 것만). 기존 현장 7건(411·483·994·1486·1554·2057·2076)은 이력 보존으로 안 바꾼다(페페 결정). ❌ 남은 곳 = 견적서 xlsx 취급·카톡방 이름·통화 STT 파일명. - 🔴부수확 = 진짜 버그 — 한샘 양식은 원본이 쓰던 칸 수만큼만 단가 LOOKUP 수식이 있어(예비블록은 C 한 칸뿐)
그 다음 칸 줄의 금액이 엑셀에서 조용히 0 이 됐다(서버 총액은 정상이라 목록으론 안 걸린다).
hansem_excel._ensure_price_formula()로 같은 블록 수식을 열만 재투영해 복제. 이번 건 2칸이 실제로 걸렸다. - 매핑 = EP·휠라→FIX PANEL · 냉장고장→키큰장 · 운임/물류비/부속→예비블록(길이=목표/400·적용률 1.0 = 정확히 일치). 가구 줄은 등급·적용률 역산 → 총액 오차 -4원(추가2)·+21원(추가3)(적용률 소수 4자리 반올림 잔차).
- 검증 = 엑셀 금액 3중 교차 · 테스트 선행등록(2·3) 후 엑셀 zip 「값칸 ⊆ 단가수식칸」(배포 전 ⚠→배포 후 OK, 운영도 OK) · 등록 후 왕복 전 줄 대조 · 현장명 정규화 E2E(테스트) PASS(생성→한샘으로 저장→삭제→원복) · 단위 8케이스. 사이트맵 = 그룹8·페이지57·미반영 1(남의 분).
- ⏳페페 =
/estimate/hansem/list4·5 육안 + 엑셀 열어 금액 검산. 오차 0원이 필요하면 예비블록에 「단수조정」 칸 1개. - 🔜정식 해법 = 양식에 이미 있는 「추가분견적」 탭에 주입(한샘 모듈 2차 미착수) — 할지 페페 판단.
최근 완료(원문 = archive.md 「2026-09-03 이관」)
- 26.9.3 업체 전용 현장목록 2차(표 폭·담당자 숨김·상차일 표기·진행버튼 삭제 + 유형 전수 내수) — 운영 168f21d.
- 26.9.3 업체 전용 현장목록 QA 6건 — 운영 3990b06. 상세 = 바로 아래 절.
- 26.9.3 오엠씨 자재관리 엑셀식 표 전면개편 — 운영 c420f8f. 현장 rowspan 병합·2표(완료 아래·기본 접힘)·
우측 현장목록(숨김 기본접힘)·메인 탭 분류 연동 차단. 상세 = session-2026-09-03-omc-material-mockup.md.
- 26.9.3 발주서정리 입고처 컬럼 — 운영 4820787. 프론트 4줄(백엔드는 patch46 부터 이미 있었다).
- 26.9.1 거래처 목록 주소 컬럼 — 운영 67ac02c.
🆕 26.9.4 — 파레트용지 한샘 로고 NEXUS 제거(HANSSEM 만) ✅운영배포 완료 2fb811f
페페 QA 1건(qahelper · /production/sticker) = 「한샘의 파레트 용지에서 nexus 문구를 빼라. 추후 롤백할 수 있다. HANSSEM으로만 표기」.
master 505bb3e → deploy-live 체리픽 2fb811f.
- 🔑NEXUS 는 코드 문구가 아니라 로고 이미지 자체였다 —
web/static/img/company_logo/1.jpg(1376×170 CMYK)가 「HANSSEM NEXUS」 한 줄. ⛒그 파일을 고치면 스티커 헤더(.ss-logo)·현장 배지(#stk-field-badge)까지 같이 바뀐다(페페 지시는 파레트용지만). - 처방 = 파레트 전용 로고 오버라이드 규약 신설.
company_logo/pallet/{company_no}.{ext}가 있으면 파레트용지에서만 그걸 쓰고 없으면 기본 로고 폴백 (sticker_controller._logo_url(company_no, logo_dir)+ 응답pallet_logo_url·renderPallet()한 줄). 롤백 =pallet/1.jpg파일 삭제(코드 롤백 불필요 = 페페 요건). - 🔑이미지는 타이트 크롭이 아니라 「같은 캔버스에 HANSSEM 만 재중앙」 — 크롭하면 비율 8.09→4.56 이라
max-height:36mm에 걸려 세로가 19.8→35mm(+77%) 로 치솟는다(web-designer 실측). 같은 1376×170 캔버스를 유지하니 인쇄 크기가 원본과 동일(160×19.8mm). 생성 = 원본을 열단위 잉크 프로파일로 재서 단어 사이 공백(x 747~808)으로 HANSSEM(x 28~746)만 떼어 가운데 배치. - 검증 = 신설
C:\dev\pfs\scripts\_pallet_logo_check.py [test|prod]테스트·운영 ALL PASS(17항목) — API 전용/폴백·이미지에 NEXUS 없음·화면 src·렌더 160×19.8mm·스티커/배지 회귀·콘솔0. ⚠미리보기 실측은offsetWidth/Height로 해야 한다(transform:scale(--ps)탓에getBoundingClientRect는 1.1배 화면값을 준다 — 처음에 이걸로 오탐 1건). - 인쇄 경로 확인 = 실제 인쇄는
print-app/MainForm.cs의CoreWebView2.PrintAsync(브라우저 DOM 그대로)라 화면=인쇄.print-agent/agent.py의 PIL 합성/print-pallet은 호출자가 없다(레거시) → 손대지 않았다. - 사이트맵 재빌드 = 그룹8 페이지57 미반영 1(남의 세션 분 · 내 3파일은
git diff origin/deploy-live origin/master0). DDL 0 · DB 변경 0. - 🔜남은 것 1 = 생산팀 PC(PfsPrint.exe)에서 실물 1장 육안(프린터 드라이버 여백은 화면 진단으로 못 잡는다).
🆕 26.9.4 — 생산현황 출력 「상차일 미확정」 프레임 + 현장목록·모달 자동완성 차단 ✅운영배포 완료 53c4391
페페 QA 2건(qahelper, /field/modify/2180) = ①「생산현황 페이지 하단(AS그룹 하단)에 새 프레임 —
미확정 현장만 모아서. 양식은 AS 표 동일, AS 는 하단·나머지는 상단, 기본은 상차일 있는 경우 내림차순」
②「현장 목록·관련 모달들 크롬 자동완성 해제」. master 5d89606 → deploy-live 3파일 선별 포워드 53c4391.
- ①미확정 = 상차일 빈칸 하나(
isTbd(f){return !f.date}— 별도 컬럼 없다,initShippingTbd와 같은 기준). 새 표#tbd-grid를 AS 표 아래·메모 위에 두고 메인·AS 표에서는 뺐다(이동, 중복 아님). ⚠「모아서」를 이동으로 읽은 판단 — 중복 표시를 원했다면renderMain·renderAs의&& !isTbd(f)두 조각만 지우면 된다. 정렬tbdSort= 비AS 상단·AS 하단 → 상차일 있으면 내림차순 → 없으면 현장명. 🔑지시의 「상차일 있는 경우 내림차순」은 이 표에선 사실상 안 걸린다(미확정 = 날짜 없음). 방어적으로만 구현. ℹ이 출력은 여전히field_status='20'(진행중)만 뽑는다 → 대기 현장의 미확정 건은 안 뜬다 (실측 운영: 미확정 3건 중 진행중 2건만 대상, 대기 1건 = GS 안산 성포 제외). 넓히려면 DAO 쿼리 손봐야 한다. - ②
pfs-component.js에 공용 헬퍼blockChromeAutofill(root)신설(26.9.4/admin/user처방을 함수로). text/search 칸에readonly+autocomplete=off를 걸고 focus 때 readonly 해제. ⛒원래 readonly 인 칸은 건드리지 않는다 (풀어 주면 팝업 전용 칸에 타이핑이 열린다). 적용 =/field/listready 1회 +shown.bs.modal위임(팝업 DataTable 검색칸까지) - 유형관리 모달 행 렌더 뒤 1회(모달이 열린 다음 그려진다).
- 검증 = 신설
C:\dev\pfs\scripts\_tbd_frame_check.py [test|prod]테스트·운영 ALL PASS(24항목 — 표·양식·행수·이동 여부·정렬 단위검사·합성 렌더·readonly 전수·focus 해제·검색 회귀 2종·모달·콘솔에러 0). ⚠자동완성 재현은 헤드리스 불가 → 페페 크롬 실기 1회 필요. 스크린샷 =scripts/_shot_tbd_{test,prod}.png. 사이트맵 재빌드 = 그룹8·페이지57·미반영 1(남의 분 — pncad·worklog·omc 목업 이동. 내 3파일 diff 0).
🆕 26.9.4 — /admin/user 검색칸 크롬 자동완성 재발 차단 ✅운영배포 완료 98c4841
페페 QA 1건(qahelper) = 「검색창에 기본적으로 poin01 이 입력돼 전체 목록이 안 보인다(첫 로드는 다 보이는데
작업 중 poin01 만 남는다). 기본 빈칸으로」. master f944e30 → deploy-live 체리픽 98c4841.
- 🔑26.9.3 처방이 부족했다 —
type=search+autocomplete=off로는 안 막힌다. 크롬은 credential 후보 칸에서autocomplete=off를 의도적으로 무시하고search도 text field 로 친다. 「첫 로드는 멀쩡」인 것도 크롬 credential 채우기가 사용자 제스처 뒤에 도는 것과 맞는다. - 처방 2겹(총 12줄) = ①검색칸
readonly+focus때 해제(크롬은 readonly 를 안 채운다 · 확정적) ②password 3칸(newPassword·myCurPw·myNewPw)autocomplete="new-password"= 트리거 자체 제거. ⛒①만 하면 크롬이 옆#detailCompanyName으로 옮겨가 박는다 → ②가 뿌리다. - 검증 = 신설
C:\dev\pfs\scripts\_qa_autofill_check.py [test|prod]13항목 테스트·운영 ALL PASS (readonly·빈값·focus 해제·이름 엔터검색 1/9·빈칸 복귀 9/9·password 3칸 new-password·콘솔에러 0). ⚠자동완성 자체는 헤드리스로 재현 불가(테스트 브라우저에 저장된 계정이 없다) → 실기 확인은 페페 크롬 몫. - 사이트맵 재빌드 = 그룹8·페이지57·미반영 6(전부 다른 세션의 오엠씨 모바일
cec5773·9c50504분, 내 2파일은git diff origin/deploy-live origin/master0). DDL 0 · DB 변경 0. - 🔜여전히 미수정(지시 범위 밖) = 이 칸 placeholder 는 「사용자명 / 아이디」인데 프론트가
name만 보낸다 → 아이디로는 검색이 안 된다(검증 스크립트도 이름으로 검색한다). 고치려면keywordOR 분기 3줄.
🆕 26.9.4 — 시트·보드 모바일 줄 밀림 수정 ✅운영배포 완료 cfbb5db
페페 지적 = 「시트관리 6·7·11·12번 등에서 줄이 밀리고 항목 이름이 우측으로 쏠린다」.
🔑범인 둘, 둘 다 「행마다 grid 가 독립」이라 생긴 것:
①비고를 col1 에 둬서 그 열이 비고 길이만큼 확장 → 비고 있는 행만 품명코드가 밀림
→ 비고를 아래 줄 전체 폭으로 내림(보드는 품목 col1~2 와 비고 col2 가 같은 칸을 밟던 겹침도 해소)
②그 뒤에도 남은 x=75/88 두 종류 → 거래처 칩 글자수(포인 2자 vs 에넥스 3자)가 col1 을 좌우
→ col1 60px 고정 + 칩 말줄임.
🔑둘 다 운영 데이터에서만 재현됐다(테스트엔 칩이 한 종류뿐). 검사기에 「1줄째 주값 x 종류가 1개인가」
항목을 신설해 회귀를 막는다 — scrollWidth 가로넘침 검사로는 못 잡는 유형이다.
검증 = 운영 206행 전부 x=96 동일(보드 22행 x=30) · 전체 ALL PASS · 노트20 실기 육안(6·7·11번과 8·9·10번 시작점 일치).
🆕 26.9.4 — 오엠씨 3페이지 모바일 표 = A안 2줄 압축 ✅운영배포 완료 624b63c
페페 지시 = 「표가 데스크톱 구조 그대로라 가로 전체를 한 번에 못 본다. 가로폭 줄이고 행을 2줄 이상으로. 각 페이지 목업 먼저 만들어 테일스케일 링크로 올려라」 → 목업 3안 제시 → 페페 A안 확정 + 「목업의 안내 문구는 실제 페이지에 넣지 마라」 → 구현·배포.
- 목업 =
C:\dev\devplan\pfs-omc-mobile-mockup.html(http://100.108.234.45:8799/pfs-omc-mobile-mockup.html) 페이지 3 × 안 3(현재/A 2줄압축/B 카드) 토글 비교, 운영 실데이터. 허브 카드pfs-omc-mobile-mockup등록·상태 등록 완료. ⛒안내 문구·비교 메트릭은 목업에만 있다(페페 지시). - 구현 방식 = 마크업·렌더 JS 는 그대로, 행(tr)만 CSS grid 로 2~3줄 재배치. 데스크톱 규칙 무변화. 1줄째 = 제일 많이 찾는 값 + 숫자 / 2줄째 = 부속 정보 / 3줄째 = 비고·액션. · 시트관리 = 품명코드+수량 → 거래처·현장·생성일 → 비고·버튼(비고 「—」면 3줄째 생략) · 보드관리 = 일자·입고·출고·재고 → 품목·현장·버튼 (행 63px, 한 화면 11행+) · 자재관리 = 현장을 구역 머리 행으로 빼고(모바일 전용, 데스크톱은 CSS 로 숨김) 품명 → 후면·규격·발주량 → 비고·입고일. 발주처·자재 열은 모바일에서 숨김(오엠씨·원자재 고정이라 매 행 반복).
- 🔴밟은 함정 3개(전부
rules.md🆕 에 기록) = ①tr{display:grid}만 주고table/tbody를 block 으로 안 바꿔 글씨가 세로로 찌그러짐 ②구역 머리를table-row로 둬 폭을 못 채움 ③nth-child배치가 rowspan 첫 행에서 1칸 밀려 깨짐 → 클래스 기반 배치로 교체(op-c-front·op-c-status…). - ⚠폰트 하한 13px — 2줄 구조를 만들며 11~12px·연회색을 썼다가 페페 UI 규칙대로 13px·본문톤으로 되돌렸다. 위계는 굵기로만 준다.
- 검증 =
scripts/_omc_mobile_check.py에 A안 구조 검사 6항목 추가(헤더 숨김·행 grid·행 폭·행 높이·구역 머리· rowspan 셀 숨김 + 데스크톱 「표는 원래대로」 회귀) → 테스트·운영 ALL PASS. 노트20 실기 육안 = 시트 한 화면 7~8행·가로 스크롤 0. 사이트맵 재빌드 = 그룹8·페이지57·미반영 1(남의 분). - ✅web-designer 검토 반영 완료(운영
3d3dfdf). 판정 = A안 grid 로직 자체는 문제 0(새 CSS 에 13px 미만· 넘침·행높이 편차 없음, 데스크톱 회귀 0). 문제는 그 위에 얹혀 온 기존 요소였다 → ①행 액션(40×19px)·상태 세그먼트(34×21px)·입고일이 데스크톱 밀도 그대로 = 터치 타깃 미달 → 세로 28px ②배지·칩 5종 11~12.5px → 13px(padding 8→6 으로 가로 상쇄) ③미사용 클래스·죽은 12.5px 정리. 🔴컬럼 예산 충돌 실측 = 터치 타깃을 키우자 품명코드가 100→84px·말줄임 20행이 됐다 → 액션을 col2~3 에 걸쳐 트랙 경쟁에서 빼니 134px·말줄임 0행(원래보다 넓다). 규칙에 기록. 🔴운영에서만 난 것 = 긴 품명코드span.code가 셀 밖으로 그려짐(테스트엔 그만큼 긴 코드가 없다) → span 자체 말줄임. - ⏳페페 판단 3건(색 대비, 브랜드 톤이라 코디가 안 정함) = 자재관리 상태 진행 2.94:1 · 완료 3.30:1,
보드 badge-out 2.53:1(가장 심각) — 전부 WCAG 4.5:1 미달. web-designer 후보값은 각각
#a16207·#15803d·#c8621f(어림 계산이라 재계산·색 확인 필요). 라벨 텍스트가 있어 색만으로 구분하는 구조는 아니라 위험도는 낮다. - ⏳남은 제안 2건 = ①행 액션을 케밥(⋮) 메뉴 1개로 묶으면 관리 열이 통째로 사라져 컬럼 예산 문제가 구조적으로 해소
(난이도 중, 팝오버 JS) ②시트 품명코드
title속성 부재(모바일은 hover 가 없어 말줄임분이 완전히 사라진다 — 지금은 0행이라 대기).
🆕 26.9.4 — 오엠씨 모바일 목업 폐기 + 메뉴를 「업체별 페이지」 그룹으로 ✅운영배포 완료 dcad1d9
페페 지시 9건(모바일 사이드메뉴를 아이비젼 기준으로 · 목업 타이틀/설명 삭제 · 엑셀 모바일 숨김 ·
빈 버튼 삭제 · 상단 시트/보드 유지+확인서 숨김+자재관리 추가 · 모바일 전반 보완 ·
오엠씨를 업체별 그룹으로(가나다) · 그룹명 「업체별 현장」→「업체별 페이지」 · 운영배포).
master cefcd39+50d52d6 → deploy-live 체리픽 1b1801b+dcad1d9.
- 🔑원인은 하나였다 —
/omc/sheet·/omc/board가 모바일 UA 면 와이어프레임 목업(sheet_mobile.html2,549줄)을 그대로 서빙했다. 페페가 본 「목업 안내 타이틀」·「사이드바 그룹 신설~」 설명·가짜 사이드바· Excel 버튼·빈 버튼(<button ... <!--주석--><button>로 태그가 깨져 있었다)이 전부 그 목업 것. → 분기 제거, 실제 페이지 하나로 통일. 목업은C:\dev\pfs\mockups\omc\로 이동 보관. - 🔴부수확(진짜 버그) = 전역
pfs_layout.css의.topbar{display:none !important}가 이름이 같다는 이유로 오엠씨 제목·액션 줄까지 죽이고 있었다 — Excel 내보내기·품목 추가·확인서 출력·입출고 등록 버튼이 데스크톱에서도 안 보였다..omc-scope .topbar{display:flex !important}로 복구. - 만든 것 =
web/templates/omc/_mobile_tabs.html(모바일 상단 이동 탭 시트·보드·자재관리 3개, 확인서 공문은 모바일 숨김) — 세 페이지가 include. 자재관리(field_orderpaper)는omc.css를 안 써서 스타일을 조각 안에 뒀다. omc.css@media ≤767신설 = 제목줄 세로화·버튼 전폭·표 가로스크롤(페이지는 안 밀림)·요약 3열→1열· 품목 사이드 가로스크롤·모달 전폭·omc-hide-mobile(Excel/확인서).- 메뉴 DB(test·live 양쪽) =
field_company이름 → 업체별 페이지,OMC를 그 하위로 (parent_menu_key='field_company',display_order=460= 아이비젼 452 다음 가나다, 아이콘la la-cubes). 스크립트C:\dev\pfs\scripts\_omc_menu_move.py(멱등). - 코드 정리 =
base.html의 OMC 전용 사이드바 분기 삭제(이제 일반 3단 경로) +permission_service가 조상 체인을 끝까지 수집(3단에서 조부모 그룹이 빠져 가지가 통째로 사라지던 것). - 검증 = 신설
scripts/_omc_mobile_check.py— 테스트·운영 ALL PASS(모바일 3페이지 × 목업문구·탭3개· 활성탭·버튼숨김·빈버튼0·가로넘침0 + 사이드바 그룹/순서/하위3 + 데스크톱 회귀 2페이지). 사이트맵 재빌드 = 그룹8 페이지57 미반영 1(기존 잔여, 무관). - ✅노트20 실기 육안 완료(페페 지시 「웹 모바일뷰는 프레임이 달라 부정확」 · 임시계정
poin02로 코디 직접 로그인). 🔑웹 390px ALL PASS 였는데 실기에서 4건이 더 나왔다 — ①보드관리 요약카드·품목추가 박스가 화면 밖 ②자재관리 2단 유지로 좌측 현장 컬럼 잘림 ③「모두 펼침/접기」가 flex 스페이서 탓에 어긋남 ④상단 탭 마지막 칸(자재관리)을 QA 헬퍼 토글(fixed top:70 right:12)이 덮음. 원인 ①②는 같은 것 — grid 아이템min-width:auto가 안쪽 표에 밀린 것(1열로 바꿔도 안 통한다). → 운영a07226c까지 반영 후 재촬영 육안 확인(3페이지 전부 정상). 검사기도 360px + 넘침요소 목록 + 탭 침범으로 조였다. 실기 도구 =scripts/_omc_note20_shots.py· 산출 =scripts/_note20/v2_*.png. ⚠임시계정 정리 = 페페가poin02에 임시비번을 걸어 뒀다 — 검증 끝났으니 되돌릴지는 페페 판단.
🆕 26.9.4 — 아이비젼글로벌 현장 유형 = AS 재전환 ✅운영 DB 반영 완료 (코드변경 0)
페페 상담 = 「아이비젼 현장은 입주완료 세대 AS라 규모가 작다. AS로 넣으려니 상위 본건이 없어 내수로 바꿨더니 생산현황 출력에서 본건 표로 들어갔다. 유형 선택에 손이 덜 가는 방안」 → 방안 3개 제시(A 그대로 AS·부모 비움 / B 출력 필터를 「AS로 시작」 1줄 완화 후 「AS(단독)」 유형 신설 / C 업체 기본유형 컬럼) → 페페 선택 = A.
- 🔑전제가 틀렸던 것 = AS(60)는 상위 본건 없이도 저장된다(등록폼은 60 선택 시 칸만 보여준다). 대가는
내부 현장목록의 「연결」 버튼 +
asOrphan정렬(맨 뒤)뿐이고, 업체 전용 목록엔 그 둘 다 없다. - 집행 =
C:\dev\pfs\scripts\_ivg_div_to_as.py(SSM→EC2). 13행 UPDATE, 452 현장 전체 15건 = AS, 잔여 비AS 0. 롤백 스냅샷 = 그 13건 전부50. 자식 AS 0건 가드 통과. ⛒기존_ivg_div_rollback.py는 SNAP 이 낡아 안 썼다 (26.9.3 이후 등록된 2100 대보 파주운정·2153 현대 포항 누락, 2160·2167 은 이미 60이었다). - 검증 = 신설
scripts/_ivg_as_section_check.py prodALL PASS — 본건 표 아이비젼 0건 / AS 표 2건 (양주 옥정·현대 서울숲). 15건 중 2건만 뜨는 건 정상 — 이 출력은field_status='20'(진행중)만 뽑는다. - 새 규칙 3건 =
rules.md🆕(AS 섹션 판정은 유형 이름 문자열 · 부모 없는 AS 의 대가 · 452 정본 유형).
🆕 26.9.4 — 현장목록 유형관리 모달(톱니바퀴) + 상차일 KO 표기 ✅운영배포 완료 2507c20
페페 QA 2건(qahelper) = ①「현장 등록」 버튼 왼쪽 끝에 같은 높이 톱니바퀴 옵션 아이콘 → 모달, 일단 유형 CRUD」
②상차일 컬럼 26.10.21(수). master 62b35ea 체리픽.
- 그릴링 3문 → 페페 결정 = ①삭제는 사용 중이면 차단(AS 는 항상 불가) ②톱니 노출 = 슈퍼관리자 + 업체권한관리 권한자(기존 API 재사용) ③편집 = 이름·순서·추가/삭제(코드값은 자동채번).
- 🔑백엔드 신규 0 — 저장은 업체 관리 「목록관리」가 쓰던
PUT /api/admin/common-code/<group>을 그대로 쓴다 (save_common_code_group: code_no 있으면 value/순서 갱신, 없으면 max+10 채번, 제출 안 된 기존은 삭제). 새로 만든 건 사용 건수 SQL(field_dao.select_field_div_usage) 과 삭제 가드뿐. - 삭제 가드는 서버에도 뒀다(
_guard_field_div_delete) — 프론트 잠금은 API 직접호출로 뚫리고, 오래 열어 둔 화면이 저장하면 남의 신규 코드를 지운다(코덱스 지적). 규칙 =projects/pfs/rules.md🆕. - 부수확 =
/field/list유형 필터가 하드코딩 6개라 운영에 있는개인건(70)이 검색조건에 없었다 → 공통코드 서버렌더로 교체. - 상차일 =
convertDateString→convertDateStringKo(26.9.3 신설 공용 포매터 재사용, 1줄). - 검증 =
C:\dev\pfs\scripts\_fielddiv_check.py [test|prod]21항목 테스트·운영 ALL PASS(버튼 위치·높이 실측, 모달 행수·삭제잠금 7행, 상차일 정규식 18~20건, 콘솔에러 0) +_fielddiv_guard_test.py7항목(DB 없이). ⚠scripts/_*는 gitignore = 로컬 전용. 사이트맵 재빌드 = 그룹8 페이지57 미반영 1(카톡관리 API — 남의 미배포분, 무관). - 26.9.4 2차(페페 지시) = 톱니를 「현장 등록」 옆이 아니라 페이지 좌측 끝으로(운영
6c85146).page-titles좌측 컬럼을d-flex align-items-center로 만들고 제목·breadcrumb 을<div>로 묶어 버튼을 앞에 세웠다 — 높이·y 는 「현장 등록」과 동일(실측 h40·y25). ⚠이 테마는.page-titles의 h3·breadcrumb 을 display:none 으로 숨긴다 → 위치 검증 기준을 제목으로 잡으면bounding_box()가 None 이다(행 자체를 기준으로). - 🔜남은 것 = 현재 7개 유형이 전부 사용 중이라 삭제 버튼이 전부 잠겨 있다(새로 추가한 유형만 지울 수 있다). 유형을 실제로 지우려면 그 유형의 현장을 먼저 옮겨야 한다 — 페페 요청 있으면 「일괄 이전」 기능을 따로 만든다.
🆕 26.9.3 — QA 3건(검색칸 자동완성 · 모바일 사이드바 · 월마감 컬럼폭) ✅운영배포 완료 690bb89
페페 QA 3건 = ①/admin/user 검색칸 「기본은 비워두고 엔터로 검색」 ②모바일 사이드메뉴 펼침에
로고·사용자정보가 안 보임 ③/estimate/monthly-close 현장명 폭 줄이고 비고 폭 늘리기. master a607507 체리픽.
- ① 서버가 값을 넣은 게 아니라 크롬 자동완성이었다 — 같은 페이지에 password input 이 3개
(신규 사용자·PW 재설정·내 PW 변경) 있어 크롬이 이 칸을 로그인 아이디 칸으로 읽고 저장된
poin01을 채운다. 처방 =type=search+autocomplete=off(검색 타입은 credential 자동완성 대상에서 빠진다). 엔터 바인딩 2줄 추가. - ② 모바일은
.mini-sidebar가 붙은 채로 열린다 — 테마가 폭 기준으로 body 에 붙이는 클래스라 210px 로 펼쳐도 §4 접힘 압축 규칙(.mini-sidebar .sb-logo/.sb-user-info{display:none})이 그대로 먹었다.≤767미디어쿼리에서 되돌림(접힘 압축은 데스크톱 전용). 전역 CSS 라 데스크톱 접기 회귀검사 포함. - ③ 현장명
17%→12%· 비고 미지정→20%. 운영 실측 156px vs 260px. - 검증 = 신설
C:\dev\pfs\scripts\_qa3_check.py17항목(테스트 PASS · 운영 PASS). ⚠scripts/_*는 gitignore 라 리포에 안 올라간다(로컬 전용) — 재실행 =PYTHONUTF8=1 python scripts/_qa3_check.py prod. - 사이트맵 재빌드 = 그룹8 페이지57 미반영 1(
/field/worklog— 무관한 기존 차이). DDL 0 · DB 변경 0. - ⛒배포 워크트리(
C:\dev\pfs_deploy_wt)에 남의 미푸시 커밋 4개 + 미커밋 3파일이 있었다 → 거기서 push 하면 남의 미검증 작업이 같이 나간다. 별도 워크트리를origin/deploy-live에서 새로 떠서 내 커밋만 체리픽·push 하고 지웠다(그 4개는 그 사이 다른 세션이 이미 배포 완료). - 🔜미수정(지시 범위 밖, 페페 판단 대기) = 이 검색칸 placeholder 는 「사용자명 / 아이디」인데
프론트가
name만 보낸다 → 아이디로는 검색이 안 된다. DAOuser_admin_dao는user_id파라미터를 이미 지원하지만 AND 결합이라 같은 값을 둘 다 보내면 0건이 된다 → 고치려면keywordOR 분기 3줄이 필요하다.
🆕 26.9.4 — 「생산자동화시스템」 → PFS 전면 교체 ✅운영배포 완료 ddd9135
- 🔑탭 제목의 단일 출처는 템플릿이 아니라
common/config/config.py의SITE_TITLE이다 (base.html은{{ config.SITE_TITLE }}). 환경별 4개 전부 교체 → 운영PFS· 테스트PFS(test). - 같이 바꾼 것 = 로딩 스피너 라벨 3곳(
base·login·change_password) + 하드코딩<title>3곳 (login·change_password·print) + 오엠씨 모바일(board_mobile·sheet_mobile) 좌측 로고 4곳. - ⛔
web/html/*퍼블리싱 원본 6곳 = 서버가 안 쓴다 · ⛔api/config.py스웨거 문서 제목 = 개발자용, 이미 「생산자동화시스템(PFS)」 병기라 유지. - 검증 =
_sidebar_regress_check.py에 「탭 제목·로더 라벨에 생산자동화시스템 없음」 추가 · 테스트·운영 PASS.
🆕 26.9.3 — 사이드바 로고 텍스트 = PFS ✅운영배포 완료 12338c8
- 🔑종전엔
logo-text.png이미지(「생산자동화시스템」)라 문구를 못 바꿨다 →base.html의<img>를<span class="sb-logo-text">PFS</span>로, CSS 는height:19px대신 폰트 규격(19px/800/자간 .5px/line-height:26px= 옆 로고 아이콘 높이와 맞춤). 3글자면 이미지 재생성보다 텍스트가 확실하고 안 잘린다. - 접힘(
mini-sidebar70px)에서는 종전 규칙대로 로고 전체 숨김 — 동작 무변화 확인. - ⛔
web/html/*의 같은 이미지 참조 6곳은 서버가 안 쓰는 퍼블리싱 원본이라 안 건드렸다. - 검증 =
_sidebar_regress_check.py에 「로고 = PFS(텍스트)」 추가(데스크톱 3페이지) · 테스트·운영 PASS · 운영 로고 영역 스크린샷 육안(C:\dev\pfs\scripts\_pfs_logo.png). - 🔜남은 「생산자동화시스템」 문구 2곳 = ①브라우저 탭
title②로딩 스피너 라벨(base.htmlloader__label). 좌측 상단 로고가 아니라 이번 지시 범위 밖이라 그대로 뒀다 — 바꿀지는 페페 판단.
🆕 26.9.3 — 모바일 햄버거 항상 3줄 ✅운영배포 완료 0434506
페페 지시 = 「폴딩버튼을 한번 쓰면 3줄 모양에서 X 모양으로 바뀐다. 항상 3줄이 나오게」.
- 🔑원인 = 테마
custom.js가.nav-toggler i에ti-close를addClass만 하고 안 지운다 (toggleClass("ti-menu"); addClass("ti-close")). 한 번 누르면 X 로 굳는다. - 테마 파일은 안 건드렸다(전역 회귀 범위가 넓다) →
pfs.js의pfsFixNavIcon()이 클릭 뒤·초기 로드 때 걷어낸다. - 검증 =
_sidebar_regress_check.py에 「햄버거 항상 3줄」 추가(데스크톱 3 + 모바일 3페이지) · 테스트·운영 PASS · 운영에서 열고닫기 3회 반복해도la la-bars유지 실측. - ⚠배포 메모 = deploy 워크트리에 다른 세션의 pncad 스테이징이 있어 cherry-pick 이 거부됐다
(
your local changes would be overwritten) → 경로 지정 커밋(git commit -- <path>)으로 내 1파일만 넣었다.
🆕 26.9.3 — 상세 모달 = 코디 정리본(kb_digest) ✅운영배포 완료 30cf5af
페페 지적 = 「게시글에서 관련 현장 파싱만 해서 게시하니 현장 내용이 섞인 한 덩이 문장에 다른 현장 내용도 들어가버렸다. 전체 내용은 카톡 게시글에 있고, 이 상세 모달내용은 코디가 매번 내용 확인해서 다시 정리해주는 게 좋겠다」.
- 🔑실제 증상 = 「GS 메이플자이 … 하프미러경은 제천자이 납품업체 생산 가능성 있음」 한 줄이 제천 자이 모달에 통째로. 문장 단위로 가르는 건 규칙으로 안 된다 → 코디가 읽고 다시 쓴다.
- 그릴링 1문(정리 트리거) → 페페 선택 = 게시글이 바뀔 때만 자동.
- 만든 것 =
kb_digest테이블(DAO 자가생성 DDL · 현장 1건 = 1행) +GET /api/kakao-board/digest/state(대상 업체 + 업체별 정리 version 한 방) +PUT /api/kakao-board/digest+ 배치C:\dev\pfs\tools\kb-digest\kb_digest.py+ 예약작업\Cody\kb-digest(15분·숨김 vbs). version 이 그대로면 코디 호출 0. 대상 업체는menu_catalog가 단일 출처라 페이지 생기면 자동 편입. - ⛔
fusion_row재사용은 접었다 — 카톡으로 나갈 후보라 오조작 시 고객 방에 글이 나가고, 커버리지도 3/15. - 운영 첫 정리 = 15건 중 9건에 정리본. 제천 자이(2132) 빠짐 = 지적 해결.
「완주 푸르지오 도어 교체·택배」가 문자열로는
완주(2110)에 붙던 것이 완주 J손도어(2174)로 바로잡혔다. 양주 옥정 동명 2건 중 진행중(2160)을 골랐다. - ⚠페페 확인 1건 = GS 신반포(2168)에 「GS 메이플자이 135B」가 붙었다. 신반포4지구 재건축 단지명이 메이플자이라 맞을 수 있으나 코디 판단이라 육안 확인 요망. 아니면 프롬프트 규칙 5를 조이면 된다.
- 모달 제목 = 「현장 상세」, 부제 = 「카톡 게시글 정리본 · 갱신 26.9.3(목) 17:23」(원문 오해 방지).
- 새 함정 3건 =
projects/pfs/rules.md🆕 — ①상세는 코디 정리본(문자열 매칭 폐기·fusion_row 금지) ②헤드리스 코디 긴 프롬프트는 stdin(claude.cmd = cmd.exe 8191자 한계에 조용히 잘림) ③git add <디렉터리>금지(이번에 재발 — 임시 스크립트 23개가 master 커밋에 딸려갔다,1b49de6으로 해제).
🆕 26.9.3 — 업체 전용 현장목록 모바일 3차 ✅운영배포 완료 6e7c8f9
페페 모바일 QA 6건 = ①인라인 검색창이 「대기중」 탭을 덮는다 ②Search Filter 공간 최소화(버튼+모달)
③사이드 메뉴를 누르면 겹치는 등 버그 ④상세 버튼 폐기 → 현장명 클릭 ⑤모바일 모달 가로 중앙
⑥필요시 한 행 2줄로 가로 압축. 운영 6e7c8f9(master 6커밋 9b7933b 3cbfc67 94c030f f9e6bdc d96f051 b1f5a3c 체리픽).
- ④ 상세 컬럼을 통째로 폐기하고 현장명에 링크.
display타입에서만<a>를 씌워 정렬·검색은 원래 값 유지. - ⑥ 모바일 한 행 = 2줄 그리드(상태·구분·현장명 / 유형·상차일·상차비고·시공담당). 행높이 62px · 가로 스크롤 0.
- ② 검색패널은 폼을 복제하지 않는다 — Search Filter 카드 자체를 오버레이로 띄운다(두 벌이면 한쪽만 고쳐진다).
- ③ 전역 변경(
pfs_layout.css·pfs.js) = 백드롭 신설(밖을 탭하면 닫힘) · 모바일에서 사이드바 안 접기버튼 숨김 (데스크톱 210↔70 전용인데 열면 화면에 들어와 「햄버거가 두 개」로 읽혔다) · 열린 동안 본문 스크롤 잠금 · z-index 정리. - 🔴실측으로 잡은 진짜 버그 3개(전부 「에러 0인데 안 먹음」) = 상세는
projects/pfs/rules.md🆕 「모바일 레이아웃 함정 3종」. 요지 = ①@media를 style 중간에 두면 뒤 규칙이 같은 특이도로 덮는다 ②DataTables 필터의float:right가 따라와 뒤 플렉스 컨테이너 폭을 0 으로 만든다 ③JS 가 body 에 붙이는 요소의 기본display:none을 미디어쿼리 안에 두면 데스크톱에 빈 div 가 남는다. - 검증 = 신설
_ivg_mobile_check.py23항목(iPhone 390×844) · 신설_sidebar_regress_check.py10항목 (데스크톱 3페이지 접기토글·백드롭 숨김 / 모바일 3페이지 백드롭·바깥탭) ·_ivg_page_check15 ·_ivg_page_ui_check15 ·_field_list_qa5_check(사이드바가 전역이라 회귀 필수). 테스트·운영 전부 ALL PASS. 운영 육안 = 15건이 한 화면에 2줄씩, 가로 스크롤 0. - 사이트맵 재빌드 = 그룹8 페이지57 미반영 1(
/field/worklog— 무관한 기존 차이). DDL 0 · DB 변경 0. - ❓미확인 = 페페가 말한 「웹에 구축한 사이드 메뉴와 겹치는」이 위 3건 말고 다른 증상인지. 실측으로 재현된 건 백드롭 부재·햄버거 두 개·본문 스크롤이 전부다.
🆕 26.9.3 — 업체 전용 현장목록 2차 (/field/company/452) ✅운영배포 완료 168f21d
페페 QA 2차 = ①표 가로폭 최대한 절약(우측을 비워 요약 게시판 자리 확보 — 게시판 자체는 이번 작업 아님)
②담당자 컬럼 숨김 ③상차일 26.8.29(수) 표기 ④「진행 현장」 버튼 삭제(중복) ⑤현장 전체 유형을 내수로 전수 수정.
⛔/field/list(현장 목록)는 안 건드렸다.
- ①
#view-manage > .col-12 { max-width: 820px }+ 컬럼폭 조이기. 창 1280 기준 우측 460px 이 빈다. - ② 업체담당자
visible:false(값은 남긴다). 운영 15건 전부 은지호였다. - ③ 🔑포매터를 공용으로 신설 =
web/static/js/datatable.js의convertDateStringKo. 화면마다 요일 배열 사본을 두면 어긋난다(이미 5벌이 제각각). 기존convertDateString은 안 건드렸다. 규칙 원문 =rules/tooling.md「날짜·시각 표기」, pfs 판 재기록 =projects/pfs/rules.md🆕. - ④ 상태 탭 「진행중」과 같은 일 → 마크업·CSS·
toggleActiveField·activeFieldFilter분기까지 제거(−67줄). - ⑤ 운영 DB =
field.field_div13행60(AS) →50(내수), 최종 15건 전부 내수. 안전게이트 = 이 현장들을 부모로 둔 AS 0건 확인 후 집행(있으면 assert 로 중단). DRY RUN 으로 before 스냅샷 → 집행. 롤백 =C:\dev\pfs\scripts\_ivg_div_rollback.py(13개field_no를60으로 복원,EXECUTE=True필요). - ⚠의도된 부작용 =
field_div가 구분 컬럼(본건/AS 배지)의 원천이라 구분이 전부 「본건」이 됐다. 이 업체 화면에선 AS 배지·「AS N건」 표시가 사라진다. - 검증 =
_ivg_page_check.py11항목 ·_ivg_page_ui_check.py15항목(상차일 정규식 전 행 대조·카드폭 실측). 테스트 PASS/PASS · 운영 PASS/PASS(카드 820px · 상차일 전 행 통과 · 15/15 한 페이지 · 완료 11건 하단 · 상세 9개 · 콘솔 0). - 🔜가로폭 다음 후보 = 구분 컬럼(전부 「본건」 하나라 76px 순수 낭비) · 시공담당(15건 중 1건만 값 있음). 요약 게시판은 페페가 「현재 작업 없음」이라고 못 박았다 — 자리만 비워 뒀다.
🆕 26.9.3 — 업체 전용 현장목록 QA 6건 (/field/company/452 아이비젼글로벌) ✅운영배포 완료
페페 QA(#status-tabs) = ①/field/list 의 대기중·진행중·완료 탭을 그 자리에 가져오기 ②업체명 필터 금지
③완료 항목은 표 맨 아래 ④페이지당 20건 ⑤컬럼 주방·일반 제거 ⑥컬럼 상세(카톡 게시글 모달) · 운영 배포.
- 운영
3990b06(masterc3a0010체리픽 — master 엔 다른 세션의 미승인 커밋 20여 건이 쌓여 있어 merge 금지, cherry-pick 이 파일단위 포워드보다 깨끗했다.kakao_board_service.py는 「카톡관리 완료 후보」 미배포 커밋 2건이 같은 파일을 건드리는데 내 변경이 EOF append 라 충돌 0). - ①②③④⑤ =
field_company_list.html1파일. 탭 마크업·CSS·setStatusFilter는field_list에서 그대로, 단COMPANY_FILTERS(업체명 필터)는 안 가져왔다(지시 ②). 완료 하단 =applyFieldFilter기본정렬 앞에 「완료(30)냐」 그룹키 한 줄, 같은 급 안은 종전대로 상차일 내림차순(미확정 상단 규칙은 이 화면엔 원래 없어서 안 넣었다). - 🔑⑥ kakao_board 엔 업체·현장 정본 링크가 없다 — 운영 실측 = 452 현장 15건 중
field_no연결 0건. 이 업체 게시글은 방 하나(생산 소물량 업체 포인 신동승 차장님· alias 아이비젼 · site_name 글로벌아이비젼 · 35행)에 전 현장이 한 글로 들어 있고, worklog_match_room_field도 유사도 80 미만이라 이 방을 못 붙인다 → 판정은 현장명 문자열 매칭(공백·괄호 정규화라 「호반 대구 칠성」↔「호반 대구칠성」이 붙는다). 정규화 4자 미만은 제외 — 「완주」가 「완주 푸르지오」 같은 남의 줄을 빨아들인다. - ⛒거르는 자리는 서버(
kakao_board_service.get_company_board_rows→field_controller가kb_rows로 렌더). 이 페이지는 고객(업체) 계정이 보는 화면이라/api/kakao-board/list를 브라우저에서 부르면 롯데·에넥스·오엠씨 게시글이 통째로 샌다. 검사에 「타업체 게시글 유출 0」 대조를 넣어 뒀다. - 매칭 0건이면 상세칸은 공백(버튼을 안 그린다) — 그릴링 1문에 대한 페페 판단 「전문이 나오면 오히려 헷갈린다」.
- 검증 =
scripts/company_board_rows_test.py(리포 등재 · DB·서버 없이 6 assert) +scripts/_ivg_page_check.py scripts/_ivg_page_ui_check.py(Playwright). 운영 = HTML 8/8 PASS(KB_ROWS 현장 9건 29행 · 유출 0) · UI 12/12 PASS(콘솔 0 · 15/15 한 페이지 · 완료 11건 전부 하단 · 탭 필터/재클릭 복귀 · 상세 9개 · 모달 열림·닫힘).- DDL 0 · DB 변경 0 · 사이트맵 재빌드 = 그룹8 페이지57 미반영 1(
/field/worklog— 이번 건과 무관한 기존 차이). - 🔜다음에 이 화면을 다시 만지면 =
kakao_board.field_no(또는company_no)를 채워 문자열 매칭을 걷어내는 게 정답. 지금 매칭은 「완주 J손도어」·「GS 신반포」처럼 게시글 표기가 다른 현장은 못 잡는다(그 칸은 공백으로 남는다).
🆕 26.9.3 — 발주서정리 원자재가 부자재로 떨어진다 (QA 코멘트 1건) ✅운영배포 완료
페페 QA(/field/orderpaper 「18T MDF 경면양면」 셀) = 「원자재 항목이 부자재로 들어가는 경우가 많다.
두께 + PB/MDF + 양면(경면양면·경면민자 등) 구조면 100% 원자재」 → 진단 후 페페 확정 3건대로 반영.
페페 확정(26.9.3) ①안① = 보드 규칙이 사용자지정보다 위(시트 다음) ②면 표기 없는 보드도 포함
(18T MDF 4*8 벌/을·6T MDF 갑/을) ③피스마개 스티커 = 부자재.
- 파일 1개
api/pfs/orderpaper/dao/orderpaper_dao.py—_MT에 보드 규칙 추가.spec REGEXP '[0-9]+([.][0-9]+)?[ ]*[Tt][ ]*(MDF|PB)' → 'R', 우선순위 시트(T) > 보드(R) > 사용자지정 > 엑셀값. 같이 정리 = 인라인 복제 9곳 →_MT0/_MTO1곳 ·update_status_bulk가 혼자COALESCE(user,excel)를 직접 써서 화면과 어긋나던 것을_mat_clause로 교정(안 고쳤으면 「원자재」 일괄선택이 화면과 딴판이 됐다). - 운영 실측 = S→R 승격 144행 · 강등 0행(단방향). 최종 분포 S 1,127 · R 488 · E 164 · T 99. (진단 때 예고한 101행 = 면 조건 있는 안②. 확정안은 +41 확장분 +2 사용자지정 역전분 = 144.)
- 피스마개 26행(운영)
material_type_user해제 → 엑셀값 S 로 복귀. 테스트 8행. 롤백용orderpaper_no스냅샷 = 세션 로그 · 도구scripts/_op_pismagae_fix.py(DRY RUN 기본). - 배포 = master
0532795→ 운영920e918(파일 1개 포워드 · blob 동일 확인 · playbook §2). 이 파일의 미반영 커밋은 9건으로 보이지만 실제 diff 는 내 커밋 하나뿐(나머지는 체리픽 완료분). - 검증 3종(전부 gitignore·로컬) —
_op_raw_rule_check.py {static|test|prod}(정적:{mt}자리표시자 ↔.format(mt=)짝·우선순위·%/백슬래시 0 / DB: 강등0·비보드승격0·시트우선·엣지불변·피스마개) ·_op_raw_rule_api_check.py(배포된 API 로 전량 대조) ·_op_raw_rule_ui_check.py(화면 DOM 에서 보드 행이 원자재 섹션 안에 있는지 = QA 원증상 직접 확인). 결과 = 테스트 DB ALL PASS · 운영 DB ALL PASS · 운영 API ALL PASS · 운영 화면 ALL PASS(콘솔에러 0, 「18T MDF 경면양면」 셀이 원자재 섹션 3곳에서 확인). - 사이트맵 재빌드 = 그룹 8 · 페이지 57 · 미반영 1(
/field/worklog— 이번 건과 무관한 기존 차이). - ⚠내가 내 규칙에 걸렸다 — 검증 스크립트에
LIKE '%피스마개%'를 썼다가 파이썬%포매팅이'%피'를 포맷문자로 읽어ValueError._MT주석에 적어둔 그대로다 → INSTR 로 교체.
(아래는 착수 전 진단 원문 — 판단 근거로 남긴다)
- 🔑근본원인 = 원자재(R) 판정이 「무엇을 발주했나」가 아니라 「엑셀 헤더에 '원자재' 글자가 있나」다.
orderpaper-sync/orderpaper_parse.py:218is_raw = any('원자재' in lab for lab in hc.values())— 헤더에 그 라벨을 쓰는 탭은 오엠씨 탭뿐. 상원보드·피앤알·성지라미텍·호선우드·효산엘피엘·피앤데코·더하임·목림·인목· 프린테크·선우시스텍은 일반 품명/규격 양식으로 써서 내용이 순수 보드여도 전부S(부자재)로 떨어진다. - 운영 실측(remove_yn=0 · 1,877행) = S 1,248 / R 366 / E 164 / T 99. 그 중 보드구조인데 S = 101행 · 18현장
(일레븐 파크사이드 MH 33 · 라인VIP 12 · 대우 용인 푸르지오 10 …). 반대로
material_type_user='R'이 225행 = 페페가 이미 블록버튼으로 손수 올려놓은 분량. 동기화마다 새 파일이 들어와 수작업이 재발하는 구조다. - 개선안 = 시트(T)와 똑같이 「조회시점 파생」(
orderpaper_dao._MT확장). 저장값을 안 건드리므로block_key=sha1(파일,sheet,section,material_type)불변 → 마이그레이션 0 · 사용자편집/상태/이력 보존. ⛔파서에서 고치는 안은 전 행 재키잉 = 편집·상태 전멸이라 금지. 식(운영 MySQL 8.4.8 실검증 ·%문자 0개라MySQLUtil포매팅 안전) =spec REGEXP '[0-9]+([.][0-9]+)?[ ]*[Tt][ ]*(MDF|PB)' AND spec REGEXP '양면|단면|경면|민자' - 실측 효과 = 안① 보드>사용자지정 103행 승격 · 안② 사용자지정>보드 101행 승격 · 강등 0행(둘 다
S→R단방향). 안①이 시트(T)와 같은 「확정 규칙」 취급이라 재발이 0(오탈은 규격 수정으로 푼다 — 시트와 동일한 탈출구). - 미결 3건(페페 판단) ①안①/안② ②
4*8·갑/을계열(면 표기 없는 보드) 41행을 규칙에 포함할지 ③현재 R에 섞인 「피스마개 스티커」 ~17행(블록토글 부작용) 정리 여부. - 부작용 점검 = 오엠씨 화면 무영향(그 화면은
vendor='오엠씨' + T로만 거른다) · 혼합블록 29→43개지만_mat_clause가 이미 섹션별로 막아둠 · 유일한 구멍 =toggleBlockMaterial()이material_type을 안 넘긴다. - 진단 스크립트 4종 = 스크래치패드(
_op_mat_probe[1-4].py, 운영 RDS 읽기전용 ·scripts/ssm_run.py경유).
🧹 pfs handoff 완료건 이관 (2026-09-16, 25,000자 캡 정리) — 원문 그대로
NOW (2026-08-06) — AWS 비용절감 Phase A 완료(A1~A5·A7) · ⏳페페 승인 = A6(RDS-test 삭제)
세션 인계용 요약: 테스트 DB를 RDS에서 EC2 안 Docker MySQL 8.4.8로 옮겼다. 앱은 이미 전환 완료·검증 통과. RDS-test 는 아직 살아 있다(롤백 자료). 남은 것 = ①페페 육안 ②A6 삭제 승인 ③Phase B RI 구매.
발단 = 페페 질문 "pfs 테스트 서버를 미니PC로 빼면 어떤가(AWS 비용). 환경이 달라져 관리가 달라지나?"
판정 — 미니PC 이전은 접었다(실익 대비 리스크 과다)
- 🔴전제가 틀렸다 = 테스트는 별도 EC2가 아니다. 운영·테스트가 같은 t3.medium 1대(
i-03225ba8bc12a929e)에 8000/8001 로 얹혀 있다 → 앱만 빼도 EC2 절감 0. 따로 있는 건 RDS 뿐. - 실측 비용(2026-07) = 총 $86.4/월 — EC2 compute
$37.44· EC2-Other$6.43(EBS gp3 59GB$5.47) · RDS$42.44(db.t4g.micro 2대$37.20+ GP2 20GB×2$5.24) · S3 등$0.09. → 미니PC 이전의 실제 절감 = RDS-test 1대 $21.2/월뿐. - 환경 차이가 크다 = 미니PC는 Windows / 운영은 Ubuntu+nginx+uWSGI+systemd. ①uWSGI 가 Windows 에서 안 돈다
②배포가 SSM send-command 라 미니PC 는 대상이 아니고 → 배포 절차 자체를 테스트 못 하게 된다
③
pfs-test.poin.co.kr+Let's Encrypt 경로 상실 ④검증 러너가 미니PC 다운·터널 끊김에 묶임 ⑤고객정보가 사무실 밖 PC로. - 채택안 = ①RI + ②RDS-test 흡수 → 월 $46.2(절감 $40.2 = 47%, 연 $483 ≈ 67만원), 선결제 0, 환경 변화 거의 0.
- AWS 정책 위배 없음(점검 7항목) — RI 는 정식 요금제, EC2 자유 설치는 정상 용법, MySQL Community=GPLv2 자체사용, Docker Engine=Apache 2.0(유료는 Desktop 뿐), 자기 자원 삭제. 실질 유의점은 ①1년 약정 구속(중도취소 불가, RDS RI 는 재판매도 불가) ②백업·패치 책임이 AWS→우리로 이동(공유책임모델) ③데이터 위치(②안은 같은 리전이라 무변화).
실행 결과 (Phase A · 2026-08-06 완료분)
| 단계 | 내용 | 결과 |
|---|---|---|
| A1 | RDS-test 파라미터 채취 · 서비스명 확정 · MySQL 5.7 정체 규명 | 완료 |
| A1-b | 옛 MySQL 5.7 stop+disable (덤프 보관 후) | RAM 177MB 회수(786→609MB) |
| A2 | docker.io 20.10.21 설치 + mysql:8.4.8 컨테이너 |
127.0.0.1:3307 전용 |
| A3 | RDS-test → 컨테이너 이관 | 87테이블·뷰1·함수2, 데이터 MD5 일치 |
| A4 | pfs-test.env 전환 + uwsgi 재시작 |
앱→컨테이너 접속 확정 |
| A5 | 러너 + 실브라우저 검증 | 8 OK / 0 FAIL |
| A7 | swap 2GB · 재부팅 내성 · 일일 백업 cron | 완료 |
| A6 | RDS-test 최종 스냅샷 + 삭제 완료(2026-08-07) | RDS 2대→1대 |
| A8 | 🆕EBS 백업 신설(DLM 일일 스냅샷 + cron 시각 조정) | 완료 |
- MySQL 5.7 정체 = 페페 추측 적중 —
auto.cnf2019-05-29 설치,pfsDB 2020-01-06, 테이블 23개 1.1MB (현 운영 23.1MB), 테이블명이 현행과 같은 계열(estimate_detail·field·company…) = RDS 이전 전 운영 DB의 전신. 「안 쓴다」 증거 = Uptime 93.5일 동안Com_insert/Com_update/Com_delete전부 0, 모든 테이블update_timeNULL, PROCESSLIST 앱 접속 0, 소켓 사용자 자기 자신뿐. 덤프 보관 =/home/ubuntu/backup/mysql57_pfs_2026-08-06.sql.gz(23테이블). - 컨테이너 파라미터 = RDS-test 와 전량 일치(이식 확인) —
utf8mb4/utf8mb4_0900_ai_ci/time_zone=+00:00/ 🔑sql_mode=NO_ENGINE_SUBSTITUTION(8.4 기본은 STRICT·ONLY_FULL_GROUP_BY 포함이라 안 맞추면 기존 쿼리가 깨진다) /explicit_defaults_for_timestamp=ON/local_infile=ON/lower_case_table_names=0/ buffer_pool 128MB(RDS와 동일). - 데이터 대조 = 87개 중 85개
CHECKSUM TABLE일치,estimate·estimate_detail2개만 불일치 → 행수·MAX(PK) 동일하고--order-by-primary정렬 덤프 MD5 완전 일치(f2ef384c…)로 동일 확정. 차이의 정체 = CHECKSUM 이 물리적 행 순서를 타는 것(수정이 잦은 두 테이블만 순서가 흐트러져 있었다). 한글 샘플 양쪽 동일(넥서스/한특/에넥스 · 쌍용 홍은동 · 「대우 용인 MH 견적서 (2차)」). - 앱 전환 확정 근거 = 로그인 API probe 5회 → 컨테이너
Com_select+6 / RDS 는 +1(내 조회 자체뿐), 앱 로그 08:35:19 응답 5건이 probe 횟수와 일치. RDS 앱 트래픽 0. - A5 검증 = ①
_p0e_platform_core_check.py test0 fail ②test_worklog_autolink_infer.py10 PASS ③신설scripts/_db_migration_smoke_check.py {test|prod}(미추적) 8 OK/0 FAIL — 로그인 →/field/orderpaper현장 카드 25개 →/field/worklog렌더 · 한글 · 날짜 · 콘솔 에러 0. ④운영 무영향(pfs-liveactive, HTTP 200). ⚠미확정 1건 =_al_profile_ui_check.py test가 104줄 「업체 3필드 같은 줄」에서 DOM null 로 중단. 그 앞 항목(로그인·목록·그리드·레이아웃)은 전부 OK 이고 스모크 8항목도 통과라 DB 이전과 무관한 AL 화면 셀렉터 문제로 추정(AL 은 QA 8건 미배포 상태로 화면이 계속 바뀌던 중). 확정하려면 운영 대조가 필요한데 운영 러너 실행은 위험작업이라 페페 판단 대기. - A7 = swap 2GB(+fstab 등록) · 재부팅 내성 확인(
dockerenabled · 컨테이너unless-stopped·mysql(5.7) disabled ·pfs-test.uwsgienabled) · 일일 백업/usr/local/bin/pfs_test_db_backup.sh+/etc/cron.d/pfs-test-db-backup(매일 03:15, 7일 보관) — 드라이런 1.3MB·gzip 무결성 OK. 현재 여유 = 디스크 31G · RAM available 2,352MB · load 0.09.
✅ A6 완료 (2026-08-07) — RDS-test 삭제 · 그리고 🔴백업 구멍을 하나 메웠다
- 삭제 전 하루 관찰 결과 정상 — 컨테이너 15시간 무중단 · DB 접속 에러 0 · 실사용
Com_select4,527 ·Com_insert261 ·Com_update184(읽기뿐 아니라 쓰기 경로까지 하루치를 견뎠다). - 최종 수동 스냅샷
poin-dbinstance-test-final-2026-08-07(available·20GB·8.4.8·태그Purpose=pre-delete-rollback) →delete-db-instance --skip-final-snapshot. 🔑자동 스냅샷 9건은 인스턴스와 함께 사라진다 — 그래서 수동 스냅샷을 먼저 available 까지 확인하고 지웠다. 결과 =DBInstanceNotFound, RDS 2대 → 1대(운영만). - ⚠삭제 명령은 코디가 못 돌렸다 — 비대화형 세션이라 broker 게이트 전에 거부(
rules/tooling.md🆕) → 페페가 직접 실행. - 삭제 후 검증 = 스모크 8 OK/0 FAIL(삭제 전과 동일) · test·live HTTP 200 · 컨테이너 Up 16h ·
DB 88테이블/
field2,041/estimate722 · DB 접속 에러 0 · env 분리 확인(테스트127.0.0.1/ 운영poin-dbinstance).
🆕 A8 — EBS 백업 신설 (페페 질문 "백업·스냅샷 설정됐나?" 에서 발견)
🔴실사 결과 EC2 백업이 아예 없었다 — 원래부터. DLM 0 · AWS Backup 0 · EBS 스냅샷 0 · AMI 0.
지금까지 티가 안 났던 이유 = 중요한 게 전부 RDS 에 있었기 때문. 이번 이전으로 테스트 DB 가 그 무방비 영역에 들어왔고,
🔴일일 논리 백업마저 루트와 같은 볼륨(stat device 동일 실측)이라 볼륨 사고 시 DB와 백업이 동시에 사라지는 구조였다.
- 신설 = DLM 정책
policy-027b7852ca6ddfea3(ENABLED) — 대상VOLUME+ 태그Backup=daily, 매일 18:00 UTC(=KST 03:00), 7개 보관,CopyTags. 볼륨vol-0f57e223d0a89419b(60GB gp3, 1개뿐)에 태그 부착. → 볼륨 전체를 뜨므로 테스트 DB·운영 앱 설정·nginx·인증서·env 가 한 번에 커버되고 기존 구멍(운영 앱 서버)도 같이 메워진다. - 선행 = IAM 역할
AWSDataLifecycleManagerDefaultRole신규 생성(계정에 없었다) + 관리형 정책AWSDataLifecycleManagerServiceRole연결. 🔑DLM--description은 영숫자·공백·_-만 허용 — 쉼표를 넣으면InvalidRequestException(실측 1회 실패). - 즉시 기준 스냅샷
snap-0c40a5eabe84b0ab0(이전 직후 상태 보존) 생성 — DLM 첫 실행이 18시간 뒤라 공백을 메운다. - 백업 2층 구조 확정 = ①논리(빠른 복원)
pfs_test_db_backup.sh17:30 UTC=KST 02:30·7일 보관 ②물리(재해 복구) DLM 18:00 UTC=KST 03:00·7개. 🔑논리가 먼저, 스냅샷이 나중 — 그래야 스냅샷 안에 그날 덤프가 들어간다. cron 을 03:15→17:30 으로 옮긴 이유 = 옛 설정은 KST 12:15 점심시간에 돌았다(서버 TZ=Etc/UTC). - 비용 = 증분이라 월 $1.5~2.5 추정. RDS-test 절감 $21.2 중 일부라 순절감 $19선 유지.
⏳ 다음 (인계)
- 페페 육안 —
pfs-test.poin.co.kr로그인 → 발주서정리·견적·worklog 가 평소와 같은지. - 내일 확인할 것 = ①DLM 첫 스냅샷이 실제로 생성됐는지(KST 8/8 03:00 이후
describe-snapshots) ②cron 논리 백업pfs_test_daily_2026-08-08.sql.gz생성 여부 ③기준 스냅샷snap-0c40a5eabe84b0ab0completed ④RDS RIpfs-prod-rds-ri-2026-08이active로 넘어갔는지 ⑤Cost Explorer 에 RI 할인 반영(하루 뒤부터 보인다). - ✅Phase B RI 구매 완료(2026-08-07 · 페페가 CLI 로 실행) — 코디가 offering ID 를 조건별 유일 매치로 특정해서
넘기는 방식을 썼다(옵션 오선택 여지 0). B1 EC2
eccbe392-a683-43e3-b6f0-9ef4d3a9528e= t3.medium · Linux/UNIX · standard · Region 스코프 · No Upfront · 수량 1 · stateactive· 2026-08-07~2027-08-07 · $0.0314/h. B2 RDSpfs-prod-rds-ri-2026-08= db.t4g.micro · mysql · Single-AZ · No Upfront · 수량 1 · $0.02/h(구매 직후payment-pending→ active. 선결제 0 이어도 이 상태를 거치며 할인은 StartTime 부터). 매칭 실측 대조 = EC2(t3.medium·Linux/UNIX·tenancy default·온디맨드·running) / RDS(db.t4g.micro·mysql· MultiAZ false·available) 전 항목 일치 → 별도 연결 작업 없이 자동 적용. Region 스코프라 인스턴스가ap-northeast-2c여도 무관. ⚠B1 은 t3 패밀리를 벗어나면 무효(1년 내 Graviton 전환 계획 있으면 재검토). - 곁가지(오늘 주제 밖, 사실만) = EC2 가 Ubuntu 18.04 + Python 3.6.9(2023 EOL). 언젠가 교체 필요 — 그때가 인스턴스 재선정 기회. apt 저장소는 아직 살아 있다(EC2 미러 + security 정상 응답).
코드 변경 = pfs 리포에 검증 러너 1개 신규(scripts/_db_migration_smoke_check.py, 미추적 유지 — 커밋 없음).
사이트맵 재빌드 불요(페이지·라우트 변화 0).
2026-08-10 완료 (루트 HANDOFF NOW 에서 이관 — 같은 날 경고선 30,000자 초과분 정리)
- 🆕pfs 견적 재작성에 「내용 복사」 선택 신설 + 차수 버튼 표기·위치·모달 폭 [코디] 26.8.10 ✅운영배포 완료(deploy-live
e659f80← mastere25e3e74파일 선별 포워드, DB 변경 0). 페페 = "함정 주의하고 기능으로 추가, 본건 견적서 새로 생성시 복사 기능(사용자 선택예정, 0으로 시작하는 경우도 있음)" + QA 3건. ①재작성 = 시작 방식을 사람이 고른다 — 종전엔 confirm 하나뿐이라 빈 견적서가 유일한 길이었다 → 모달에서 「내용 복사해서 시작」/「빈 견적서로 시작」/취소. 🔑confirm 2번으로 안 물었다(「취소」가 「빈 견적서」로 읽혀 금액문서 오조작). APIcopy_items기본 '0' = 종전 동작이라 회귀 0. ②복사 범위 = detail+sub+별도항목+자재+마스터 금액 4컬럼(시공비·운반비 포함). 🔴함정 3개 = ①FLOAT(어제 발견) → 값을 MySQL 밖으로 안 꺼내고 전부INSERT..SELECT, 파이썬은 정수 PK만 ②🆕display_order로 부모-자식을 짝지으면 안 된다 — 실데이터에 중복(테스트 견적 33 = 19행/distinct 6) → 항목 한 건씩 INSERT + 같은 트랜잭션LAST_INSERT_ID()로 매핑 ③🆕%포맷 조립에서 인자 조각의 플레이스홀더는%s(%%s쓰면 그대로 남아 파라미터 미치환 — 1차 구현 버그, 완성 SQL print 로 적발). 복사 실패 시 재작성 자체를 되돌린다(새 차수 삭제 + 원본 보관 해제). ③차수 버튼 「차수 N(개수)」→「N차(이 행의 차수)」 — 개수는 그 행이 몇 차인지 안 알려줘 보관된 1차가 "차수 2" 로 보였다, 개수는 툴팁, 위치는 삭제 왼쪽. ④차수 모달 800→1140px + 견적명 외 nowrap(가로넘침 0·셀잘림 0·행높이 균일). 검증 = 신설_est_rewrite_copy_check.py+_est_rewrite_db_verify_test.py— 테스트 E2E 3회전 ALL PASS(견적 707 = 항목52·sub215·별도2·자재4로 네 테이블 전부 커버, 서버측<=>전 컬럼 불일치 0, 원본과 복사본 화면 총액 동일 195,760,580), 테스트 DB 원상복구 실측, 운영은 읽기전용 검증만(재작성 안 눌렀다). 사이트맵 그룹8·페이지50·미반영 0. ⏳페페 = 운영 육안. →projects/pfs/{handoff,rules}.md - 🆕pfs 대우 용인 MH 견적서 1차(708) → 2차 재작성건(747) 내용 복사 [코디] 26.8.10 ✅운영 반영 완료(페페 "운영 작업 승인"). 코드 변경 0 · 배포 없음 · 사이트맵 무관 — 운영 RDS 데이터 작업만. 현장
field_no 2109(대우 용인, 에넥스·김동연)의 본건 1차 = 708(보관됨archive_yn='1', 총액 43,563,000) → 2차 = 747(대우 용인 MH 견적서 (2차), 비어 있었다). 복사분 =estimate_detail50 +estimate_detail_sub53(전 컬럼 원본 그대로, PK만 신규) + 마스터 합계 2컬럼.extra_cost·material은 원본이 0건, 추가건도 0건(본건뿐), 마스터 나머지는 747 이 이미 708 과 같아 무변경. 🔴함정 = FLOAT 정밀도 — 1차 시도(파이썬 읽기→되넣기)에서 MySQL 텍스트 프로토콜이 FLOAT 를 유효 6자리로 잘라SUM(amount)가 33,419,453.09375→33,419,442.0(11.09 차이)가 됐다. 행 단위 파이썬 대조로는 차이 0 으로 보여 못 잡는다(읽는 순간 양쪽 다 뭉개짐) → 넣은 행 제거 후 서버측INSERT .. SELECT로 재복사(자식은display_order조인으로 새detail_no매핑). 검증 = 서버측NOT (a.col <=> b.col)전 컬럼 조인 불일치 0행 +SUM완전 일치 + 708 무변경 + 운영 실브라우저 ALL PASS(타입 5개·주방5/가구4·총액 43,563,000·콘솔 0). 롤백 = 747detail_no 35494~35543. ⏳페페 = 운영 육안(/estimate/modify-v2/747). →projects/pfs/{handoff,rules}.md - 🆕pfs QA 2건(3차) — 품명 인라인 편집 전 항목 확대 + 시트 입고일정 병합 주석행 제외 [코디] 26.8.10 ✅운영배포 완료(deploy-live
b295283← masterd1cb28e2파일 선별 포워드,--detachworktree). ①품명 편집 = 오엠씨 외 전 항목도 표에서 클릭 편집. 저장은 전면/후면과 같은item_name_user라 기존 자재관리 탭과 자동 연동(배선 0). ②병합 주석행 제외 — 🔎엑셀 실물 확인이 답이었다: 포인 발주서 표준은 품명B:C·규격D:E를 각각 병합하는데 주석행은B:G한 칸으로 합쳐 쓴다(피앤알 탭 행68 =시트 : 7.22(수) 13미터 1롤 차량 입고= 시트 입고 일정 메모). → 파서가 품명칸 병합이 규격칸까지 덮으면 주석행으로 보고 '시트'가 든 것만 수집 제외(다른 주석행 유지 = 회귀 0). 🔑JARVIS 1096.19 / 9T MDF 시트/재고PP(행66)는 정상 항목행이라 그대로 두었고 계속 시트로 분류된다(빼려면 그 행 규격에서 '시트'를 지우면 됨). 기존 적재분 = 테스트 4건 soft delete, 운영은 동기화가 이미 정리해 0건. ✅사이드카 재시작 불필요(orderpaper_sync.py는 subprocess). 검증 =_omc_material_check.py테스트·운영 ALL PASS + 신설_pnr_sheet_row_probe.py파서 자체검사(합성 4 + NAS 실파일 대조). 사이트맵 그룹8·페이지50·미반영 0. ⏳페페 = 운영 육안(품명 클릭 편집 · 시트 그룹에 입고일정 메모 없는지). →projects/pfs/{handoff,rules}.md - 🆕pfs QA 3건(2차) — 시트(T) 자재분류 신설 + 오엠씨 전면/후면 편집 + 오엠씨 화면 펼침·시트 우선 [코디] 26.8.10 ✅운영배포 완료(deploy-live
5222bed← master945ab51+26d25338파일 선별 포워드, DB 변경 0). ①전면/후면 편집 =PATCH /{no}/item-name(item_name_user)에 합친 품명 한 필드로 저장하니 기존 자재관리 탭이 자동으로 같은 값을 본다(연동 코드 0). 🔑규격의 양면/단면도 같이 맞춘다 — 후면을 비워도 규격이 '양면'이면opFaceParts가 후면=전면으로 되살려 편집이 안 먹은 것처럼 보인다. 분리·편집은 발주처가 오엠씨인 블록만(오엠씨 화면·기존 발주서 정리 탭 공통). ②시트(T) = 규격에 '시트' 포함이면 시트 — 컬럼을 안 채우고 조회 시점 파생(orderpaper_dao._MT). 🔑저장값을 바꾸면item_key/block_key가sha1(…,material_type)이라 다음 동기화가 전 행을 새 행으로 만들어 사용자 편집·상태·사용이력이 끊긴다 → 파생이라 기존 85건 + 추후 추가분이 마이그레이션 0으로 자동 적용. 화면 4곳(발주서정리·입고일정·자재관리 탭·오엠씨) 전부 필터·색상·정렬 반영. ⚠저장된 필터가S.mat를 통째로 덮어써 신규 분류가undefined=제외가 되므로 복원 시 기본값과 병합. 🔴파생의 대가 = 한block_key에 시트/비시트가 섞인다(운영 59블록 중 23) → 블록 일괄조작 4종(상태·기본입고일·입고일일괄·블록삭제)에 자재분류를 같이 넘겨 그 섹션만 바꾸게 좁혔다. 안 고쳤으면 시트 섹션의 「상태 일괄」이 화면에 없는 부자재 행까지 바꿨다. ③오엠씨 화면 = 현장 카드·업체 블록 기본 펼침(완료 항목만 접힘) + 시트 섹션 최상단. 🔎시트는 오엠씨 발주가 아니다 — 시트업체(조운IMT·데코밸리·미림…)에 발주해 오엠씨로 입고된다. 실측 발주처 오엠씨 + 규격 시트 = 운영 0건이라 오엠씨만 걸면 시트 그룹이 영원히 빈다 → 이 화면 데이터 =발주처 오엠씨 OR 자재분류 T(부작용: 오엠씨 발주 없이 시트만 있는 현장 카드도 뜬다, 운영 4→5카드). 검증 =scripts/_omc_material_check.py확장 테스트 ALL PASS + 운영 ALL PASS(테스트에서만 쓰기 왕복 2건 — 전면/후면 저장·원복 + 혼합 블록 시트한정 상태일괄에서 시트 2행만 변경·비시트 3행 무변경·전량 원복). 사이트맵 그룹8·페이지50·미반영 1(/production/sticker, 타 세션). ⏳페페 = 운영 육안(/omc/material시트 그룹·전면후면 편집 //field/orderpaper시트 필터) · ❓판단 1건 = 규격9T MDF 시트/재고PP(피앤알 1행)는 보드인데 '시트'가 들어 시트로 잡힌다(그 행 규격을 고치면 풀린다). →projects/pfs/{handoff,rules}.md - 🆕pfs 생산 스티커 — 출력 회수 초기화 버튼(총관리자 전용) [코디] 26.8.10 ✅운영배포 완료(deploy-live
84fcb2f← masterb590f3e3파일 선별 포워드, 운영 RDS DDL 선행 적용). 페페 QA = "출력 회수 초기화 버튼 추가. 관리자만 사용가능·관리자 아이디만 볼 수 있게. 페이지 이동 버튼 행 우측 끝" → 같은 날 「운영배포 진행」. 범위 = 현재 도어발주서 파일 전체(페페 택1). 권한 2겹 = 템플릿{% if is_super_admin %}(버튼 자체가 안 보임) + 서버POST /api/sticker/print-log/reset재확인(비로그인 401). 🔑DELETE 아님 —remove_yn='1'+removed_by·removed_at소프트 딜리트라 누가 언제 지웠는지 남고 되살릴 수 있다(조회 2곳에 필터). 🔑같은 파일에 실려 8/7 백로그도 함께 반영 =sticker_controllersync target 한 줄(운영 화면이 테스트 DB 를 갱신하던 것) → 사이트맵 미반영 1→0(그룹8·페이지50). 검증 = 신설scripts/_sticker_printlog_reset_check.py테스트 19 + 운영 13 ALL PASS(운영은 읽기전용 — 실데이터 3행이라 초기화는 안 눌렀고, 실제 동작은 테스트에서 ✓3→0 확인). 운영 실측 = 컬럼 3개·기록 3행 전부remove_yn='0'(데이터 무변경). 🔴함정 2 = ①테스트 DB엔 「진행중 현장에 연결된 살아있는 도어발주서」 0건(기록 있던 file 222 는door_order_file.remove_yn='1'삭제 파일 → 칩 0개) → 살아있는 file 241 을 현장 2142 에 임시 연결+시드 후 원복(SSM 실측) ②다른 세션이deploy-live워크트리를 잡고 있어worktree add거부(.git없는 깨진 등록인데도) →--detach origin/deploy-live+push HEAD:deploy-live. ⏳페페 = 운영 육안. →projects/pfs/{handoff,rules}.md - 🆕pfs 생산 스티커 — 현장 검색을 견적서 등록과 같은 표 양식으로 [코디] 26.8.10 ✅운영배포 완료(deploy-live
ae9e767← masterfa34a53+cda67b2+582593a2파일 선별 포워드·임시 worktree). 페페 QA = "견적서 등록의 현장명 검색 리스트 양식을 여기에 적용. 너무 간단하게 나오고 내용이 잘 안 보임. 운영배포". 종전 폭 340px 드롭다운 한 줄 → 5컬럼 표(업체명/현장명/구분 칩/상차일/담당자) + 헤더 클릭 정렬 + 결과 건수, 폭 780px·높이 420px·sticky 헤더. 모달 아닌 인라인 드롭다운 확장(페페 택1 — 견적서는 모달이지만 생산팀은 현장을 자주 바꿔 클릭 수를 안 늘린다). DAO =field_div_name·company_member_name추가 + 키워드가 업체명까지(견적 site-search 동일), 진행중 게이트·기간창·선택 흐름·스티커 헤더는 무변경. 🔴자체검사가 실버그 1건 적발 = 정렬 한 번 누르면 패널이 닫혔다 — 재렌더로e.target이 DOM 에서 이탈해 「밖 클릭이면 닫기」가 오판 →stopPropagation. 검증 = 신설scripts/_sticker_field_search_check.py테스트 40 + 운영 40 ALL PASS(읽기 전용이라 운영 무해). 사이트맵 그룹8·페이지50·미반영 1(=sticker_controllersync target 한 줄, 8/7 백로그·동작은 정상). ⏳페페 = ①운영 육안 ②controller 한 줄 배포 지시 여부. 🔎덤 = 1층 생산팀 PC 설치 요건 정리 — 브라우저+로그인만으로 동작(배율 140% 폴백), 정확한 라벨 크기 원하면pfs/print-agent(Python 3.8+·pywin32·pillow·127.0.0.1:17777), NAS·MSSQL·VPN 전부 불필요. →projects/pfs/{handoff,rules}.md - 🆕pfs QA 2건 — 사이드 메뉴 스크롤 + 오엠씨 전용 자재관리(
/omc/material) [코디] 26.8.10 ✅운영배포 완료(deploy-livef68f155← masterf956d27+3e80d335파일 선별 포워드, 임시 worktree). ①🔴사이드 메뉴는 원래 스크롤이 아예 안 됐다 — 테마가.left-sidebar·.scroll-sidebar를 둘 다height:100%로 잡는데 그 위에 로고+사용자 블록(114px)이 얹혀 있어 스크롤 영역 아래 114px가 화면 밖이고scrollHeight==clientHeight라 perfect-scrollbar가 스크롤 자체를 안 만든다(휠 실측scrollTop=0= 하단 메뉴가 화면 밖이면 못 고름) →pfs_layout.css§10 세로 flex로 스크롤 영역이 남은 높이만 갖게 +pfs.jspfsSidebarPad()가 기준선(시스템 관리)이 상단에 서는 만큼만 스크롤되도록 ul 하단 여백 부여. 🔑여백은 계산이 아니라 실측 보정 — 짧은 콘텐츠는scrollHeight가clientHeight로 잘리고 ps 레일(절대배치)이 scrollHeight를 8.5px 늘린다(1차 구현이 기준선을 딱 8.5px 넘겨 올라간 원인) → 2패스 보정 후 오차 0.5px. ⚠mini-sidebar는 테마가position:absolute를 걸어 flex에서 빠지므로relative재선언 필수. ②오엠씨 자재관리 = 화면을 새로 안 만들었다 —/omc/material이field_orderpaper.html을omc_view=True로 렌더(인라인 JS 1,000줄 복제 0). 플래그로 탭바·다른 탭 JS 3파일·분류토글·툴바(자재/숨김/업로드/동기화)·빠른필터 라인·모달 3종·삭제/숨김 버튼 제외 + 현장연결 버튼도 제외(지시엔 없지만 발주처가 pfs 현장 매핑을 바꿀 자리가 아니다) +OP_ALL을 적재 직후 발주처='오엠씨' 필터 + 현장별 고정 +opLoadState/opSaveState스킵(메인과 같은 localStorage 키라 해제 UI 없이 필터에 갇힌다) + 품명 → 전면/후면 2컬럼(표 7→8). 🔴괄호가 자재넘버의 일부인 행이 실제로 있다(70-113(PP)·유사PP(WH240EMT)) → 공백 있는 ' (' 만 합친 표기로 판정(자체검사 1차 오탐 10건). 🔑새 화면은menu_catalogrow 없으면 super_admin 빼고 전부 403 "unmapped"(Patch #32d) →patch45_omc_material_menu.sql(멱등)로 테스트·운영 RDS 선적용, 권한은 오엠씨(196)만(에넥스는 전 현장이 보여 제외, 포인은 자사라 자동). 숨김 현장은 기존대로 제외 — 운영 오엠씨 130항목 중 99가 숨김 현장이라 화면엔 4현장 31항목. 검증 = 신설scripts/_omc_material_check.py(읽기전용) 테스트 ALL PASS(뷰포트 700/800/1080) + 운영 ALL PASS(전면/후면 9케이스를 페이지opFaceParts로 직접 호출 +/field/orderpaper회귀 + 콘솔 0). 사이트맵 = 그룹8·페이지 50·미반영 1(/production/sticker= 다른 세션 진행분, 본건 무관). ⏳페페 = 운영 육안 2곳(사이드바 끝까지 스크롤 ·/omc/material). →projects/pfs/{handoff,rules}.md
2026-08-06~07 완료 (루트 HANDOFF NOW 에서 이관 — 2026-08-10)
- 🆕pfs 3탭 「통합현장」(통화+카톡 융합) [코디] 26.8.7 ✅운영배포 완료(deploy-live
c6277a9← master844fff84파일 포워드).field/worklog에 3탭 신설 — 신규GET /api/worklog/fusion이 worklog 이번주 창(source 게이트 없음=모든 정보) + kakao_board 미러를production_status.field_status기준 현장 카드로 융합. 진행중=전부 / 완료('30')=미출고 섹션+이번주 신규만 / 매칭 실패분은 「현장 미연결」 그룹 노출(정보 유실 금지). 방→현장 매칭 = field_no 직접 → auto-link 동일 게이트 유사도. 검증 = 신설_worklog_fusion_check.py테스트 38·운영 38 ALL PASS(콘솔 0·1/2탭 회귀 포함). 사이트맵 미반영 1(/production/sticker기존 백로그, 본건 무관). 🔎SGC 용두동 방 미연결 = pfs에 그 현장 미등록 탓. ⏳페페 = 운영 육안(3탭) + 미연결 방·묶음 연결 판단. →projects/pfs/handoff.md - 🆕pfs qa_helper 다중선택(드래그 범위지정 + Ctrl선택) [코디] 26.8.7 ✅운영배포 완료(deploy-live
ff85064← masteradca5872파일 선별 포워드). 페페 택1 A안 = N개를 1항목(묶음)+코멘트 1개(표 20칸에 코멘트 20개 쓸 일 없다). Ctrl+클릭 = 후보 토글·후보가 있으면 그냥 클릭도 토글·Enter/[🧺 묶음 담기] 확정·Esc 는 후보만 비움, 후보 0에서 단순 클릭은 종전 그대로(기존 동작 무변경). 항목 스키마는members:[]하나만 추가. 🔑드래그의 핵심은 이벤트가 아니라 "밴드 안에 뭐가 잡히느냐" — 교차 기준이면 표 하나에 조상 컨테이너·tbody·tr·td·span 까지 수백 개가 걸린다 → 완전 포함 + 후보의 조상 제외(최말단만, O(n·depth)) + 6px 미만 제외 + 상한 50. 이벤트는 5px 임계·mousedown preventDefault(안 하면 페이지 텍스트가 같이 선택)·드래그 직후 click 1회 억제(안 하면 시작점이 덤으로). 🔴자체검사가 실버그 3건 적발 = ①밴드가 자기 자신을 후보로 잡는다(자기 rect 안에 완전 포함+자식 없음 = 완벽한 최말단) ②Enter 통째 먹통 — picker 가 mousedown 을 preventDefault 해 포커스가 사이드바에 남는데 "패널 밖일 때만"으로 걸었다 → textarea 만 제외 ③덤 = 「텍스트 보기」 다이얼로그가 검증 모드에서 안 닫히던 기존 버그(오버레이에 id 가 없어isInsidePanel미포함, capture 의stopImmediatePropagation이 targetonclick보다 먼저). 검증 = 신설 정적 하네스 러너 37 + 실서버 테스트 26 + 운영 26 ALL PASS(운영 드래그 후보 50 전부 leaf·포함관계 0·페이지 이동 0·콘솔 0·localStorage 원복). ⚠운영 실행이 안전한 근거 = qa_helper 는 서버에 안 쓰고 검증 모드가 클릭을 preventDefault 한다. 배포는 임시 worktree(작업트리에 페페 미커밋 수정 상시). 사이트맵 그룹8·페이지49·미반영 1(=/production/sticker, 별건 백로그). ⏳페페 = 운영 육안 · ⏳안 한 것 = devplanassets/qahelper.js포팅(지시가 pfs 만). →projects/pfs/{handoff,rules}.md - 🆕pfs 스티커 도어발주서 — 운영에 데이터가 0행이던 원인 3건 수정 + 운영 최초 적재 [코디] 26.8.7 ✅(페페 "운영 /production/sticker 에서 금강 부산에코 도어발주서가 검색 안 된다"). 🔴현장 검색은 멀쩡했다 — 운영
door_order_file이 아예 0행(테스트는 250건). 원인 = ①door_sync_watch가 테스트만 폴링(BASE 하드코딩) → 운영 「엑셀 동기화」 요청 id=1 이 7/21부터 17일간 pending ②door_order_sync상태 파일이 환경 공용 → test 로 돌린 파일은 prod 실행에서 "변경 없음"이라 영원히 안 올라감 ③sync-request의 target 'test' 하드코딩 → 운영 버튼이 테스트 DB 를 갱신. 수정 = 워커 운영·테스트 둘 다 폴링(try 는 환경 안쪽) · 상태파일_door_sync_state.<env>.json분리 · target 은 서버(FLASK_CONFIGURATION)와 워커(요청이 올라온 서버) 이중 결정. 운영 최초 적재 229파일(reconcile alive=229·파싱오류 3건은 기존 no_poin_sheet). 🔑연결은 설계상 100% 수동이라 금강 부산에코 2건(본 264품목·AS 13품목)을 운영 화면에서 연결까지 해뒀다 — 검색·연결·품목 로드·콘솔 0 확인. 배포 = mastere5d1238(사이드카 2파일 = 즉시 적용, 재시작 완료). ⏳페페 = ①운영 육안 ②sticker_controllertarget 한 줄 운영배포 지시(현재는 워커가 막고 있어 동작은 정상). →projects/pfs/{handoff,rules}.md - 🆕pfs 부자재 발주서 업로드 "안전하지 않은 접속" 수정 [코디] 26.8.7 ✅운영배포 완료(deploy-live
bac884b← master1f497ea+58b6809+12a9b317파일 선별 포워드). 🔴원인 = HTTPS 화면에서 사설 IP(HTTP)로 form POST → 크롬 혼합콘텐츠 차단. 그 경로는 26.7.29 보안조치(127.0.0.1 바인딩+토큰)로 이미 두 겹 더 막혀 있어 되살릴 값이 아니라 없앨 경로였다. 🔑고친 방식 = 원래 있는데 화면이 안 쓰던 서버 API 를 쓴다(POST /api/orderpaper/upload→ blob pending, 운영 테이블 0행 = 한 번도 안 탄 죽은 경로) + 사이드카upload_poll_loop가 claim/finish 릴레이로 파싱·적재(인증 = door_sync_watch 와 같은X-PFS-Agent-Token,_AGENT_PATHS등록 필수) + 화면은 상태 폴링(대기→분석중→✅/❌). LAN 전용POST /upload는 삭제. 🔴덤 3건 = ①insert_upload가 항상upload_no=0(execute+별도LAST_INSERT_ID()는 커넥션이 다르다) →execute_id, 안 고쳤으면 성공해도 화면은 영원히 "대기" ②nginxclient_max_body_size부재 = 기본 1MB(실측 1.43MB 413) → http 블록 20m ③폴링try가 env 루프 바깥이라 운영 401 하나로 테스트 폴링까지 굶음 +_sidecar.log신설(창 없는 상주라 출력 증발). 파서(xlrd·pdfplumber)는 EC2 py3.6 에 안 올림(chardet 5·cryptography 40 이 앱·certbot 과 충돌,pip download실측) → 사무실 PC Python39 에만. 검증 = 테스트 E2E 12 + live 사이드카 8 + 실브라우저(테스트 업로드 2건 적재·콘솔 0 / 운영 새 코드) + 운영 스모크 4(미등록 양식으로 경로만, 행 삭제 = 데이터 무변경). 사이트맵 그룹8·페이지49·미반영 2(불변). 🆕후속(같은 날) = 페페 실업로드에서 적재가 깨져 파서 재작성(master674102e·운영2d0bbd2) — 🔴에넥스 .xls 는 한 시트에 발주 페이지가 반복(수신처=업체 1곳당 1페이지, 실측 407행·11페이지)인데 옛 파서가 첫 페이지 머리만 읽고 11행~끝을 한 업체로 봐서 128행 중 절반이 라벨행('품 목'·'계'·'특이사항')이고 업체 10곳이 소실됐다 → 'A열 수 신 처 = 페이지 머리'로 블록 분할 + 고정 안내문 제외 + 비고열 오타(9→8) + 🔑같은 업체 2페이지(쿠스코)는 block_key 겹침 → sheet에 페이지번호. 재적재 = 편집·사용이력 0 확인 → 128행 JSON 백업 → 삭제 →pending되돌림(⚠파서는 sys.modules 캐시라 사이드카 재시작 필수) → 11블록 55항목, 파서체크 12항목·운영화면 55건·콘솔 0. 🆕2차 후속 = 품명 상속(페페 지시 — 규격·수량은 있는데 품명이 비었거나 쌍따옴표면 위 품명을 이어받는다, 실측 빈칸 10·따옴표 3, 블록 안에서만) → master971fed7·운영bdaff93, 🔑이번 재적재는 삭제 없이pending되돌림만(item_key동일 → 같은 행 UPDATE·*_user보존·55행 유지), 파서 18항목·운영 DB 빈칸0 따옴표0·화면 55건 콘솔0. ⏳페페 = 화면 육안. →projects/pfs/{handoff,rules}.md - 🆕pfs AWS 비용절감 — 테스트 DB를 RDS→EC2 Docker MySQL 8.4.8 로 이전 + EBS 백업 신설 [코디] 26.8.6~8.7 ✅Phase A 전량 완료(A6 RDS-test 삭제 포함). 🔴발단 질문("테스트를 미니PC로?")의 전제가 틀렸다 — 테스트는 별도 EC2가 아니라 운영과 같은 t3.medium 1대에 8001로 얹혀 있다 → 앱만 빼도 절감 0. 채택 = RI + RDS-test 흡수로 월 $86.4→$46.2(47%↓·연 67만원). 삭제 전 하루 관찰 = DB 에러 0·쓰기까지 정상(insert 261/update 184) → 수동 스냅샷
…-final-2026-08-07available 확인 후 삭제(자동 스냅샷 9건은 인스턴스와 함께 사라진다) → RDS 2대→1대, 삭제 후 스모크 8 OK/0 FAIL. 🆕덤으로 백업 구멍 발견·수정 — 페페 질문("백업 설정됐나")에 실사하니 EC2 백업이 원래부터 0(DLM·AWS Backup·스냅샷·AMI 전무)이고 논리 백업마저 루트와 같은 볼륨이라 볼륨 사고 시 DB와 백업이 동반 소실 구조였다 → DLM 일일 EBS 스냅샷(policy-027b7852ca6ddfea3, KST 03:00·7개) 신설로 운영 앱 서버 구멍까지 동시 해결, cron 은 KST 12:15 점심→02:30으로 이동(논리 먼저·스냅샷 나중). ⚠삭제 명령은 비대화형 세션이라 코디가 못 돌려 페페가 직접 실행(rules/tooling.md🆕). ⏳페페 = ①육안 ②RI 구매 — B1 EC2·B2 RDS 둘 다 지금 가능(각 수량 1). →projects/pfs/{handoff,rules}.md· 함정 =rules/tooling.md(SSM=dash·게이트·DLM) - 🆕pfs AL발주서 QA 8건 — 운영배포 완료 [코디] 26.8.7 ✅(페페 지시 "AL발주서 내용 운영배포 진행해", 7/29 테스트 배포분 대기건 해소). deploy-live
ffb5732← masterb69d325+f6bcfb2+6f9732c+9209bc19파일 선별 포워드. 내용 = 인쇄 iframe 전환(모달 안이 잘려 프레임선만 찍히던 것)·업체 다중등록(헤더 AL/유리 여러 곳 + 항목별 선택, 첫 업체=일괄 기본값이라 기존 단일컬럼·목록·구페이로드 호환)·엑셀 빈블록 실삭제(+입고처 전블록)·인라인 드롭리스트·정렬/폭/색상. 🔑patch44 컬럼 3개(vendors·al_vendor·glass_vendor)는 배포 전에 운영 DDL 선행 적용(앱 DAO 도 멱등 ALTER 를 하지만 조용히 바뀌는 것보다 통제해서 넣는다) — 운영 al_orderpaper/_item 은 0행이라 데이터 영향 없음. 🔴덤 = E2E 러너가 26.7.29 인증 게이트 이후 401 로 죽어 있었다(무로그인 호출) → 로컬 HTTPS 로그인 방식으로 수정(9209bc1). 검증 = 테스트 E2E 18 + UI 27, 운영 UI 27항목 ALL PASS·콘솔 0(화면 조작만 하고 저장 안 함 = 운영 0행 불변 확인). 사이트맵 미반영 2 → 0. ⏳페페 = 운영 육안(실제 Ctrl+P 인쇄·엑셀 다운로드는 헤드리스로 못 봄). →projects/pfs/session-2026-07-29-al-orderpaper-qa8.md
카톡관리 「변동 반영 이력」 소프트딜리트 (2026-08-05 완료 · 2026-08-06 HANDOFF NOW 에서 원문 cut 이관)
🆕pfs 카톡관리 소프트딜리트 [코디] 26.8.5 ✅운영배포 완료 — 「변동 반영 이력」 행의 ✖ 가 실제삭제→숨김 이력(deploy-live 0a75e3a ← master c0129d2 3파일 선별 포워드). 안내문 문제가 아니라 구멍이었다 — 이력 행은 로그라 ✔완료·⊘취소를 뺐는데(26.7.28) 그래서 ✖ 말고 내릴 방법이 없는데 그게 실제 삭제였다. 이력 행만 hide/status=삭제로 보내 ↩복원 가능, 다른 행 ✖ 는 그대로(지시 밖). 🔑두 리포가 짝 = PFS VALID_STATUS ↔ 사무실PC 데몬 board_rows.STATUSES, PFS만 늘리면 데몬 ValueError→화면엔 「반영 실패」뿐 → 데몬 먼저+재시작(완료·상승권한 불요) 후 배포. 검증 = 신설 _kakao_board_softdelete_check.py 테스트 28 + 운영 24 ALL PASS(테스트만 --api 실왕복→ack 정리, 운영은 저장 안 누름 — 누르면 고객 단톡방이 실제로 바뀐다). 사이트맵 3→2(/field/worklog 걷힘). ⏳페페 = 운영 육안.
pfs 사이트맵 (2026-08-04 완료 · 2026-08-05 HANDOFF NOW 에서 원문 cut 이관)
🆕pfs 사이트맵 [코디] 26.8.4 ✅신규 — 테스트/운영 화면 테크트리(devplan/pfs-sitemap.html, 기획서 pfs.html 양방향 링크). 🆕2차(같은 날) = 가로형 관계도로 교체(master ad705e3) — PFS 루트에서 오른쪽으로 뻗는 다이어그램, 노드엔 큰 제목만, 상세는 팝업(페이지 클릭=상세 / 그룹 클릭=접기 / ⓘ=요약 / 루트=서버메타). 커넥터는 순수 CSS(li flex+center → top:50%가 노드 중심, JS 좌표계산 0), 기본 = 전부 접힘(펼치면 뿌리가 화면 밖으로 나가 목록이 된다). 공용API·화면밖 미반영도 같은 뿌리에 매달아 한 장. 사이드 메뉴로 두 맵 전환·펼침접기·미반영만·검색. 원천 전부 실측(수기 0) = 두 RDS menu_catalog SSM 덤프 + 두 브랜치 라우트 파싱 → 그룹 8·페이지 49·API 893. 🔑미반영 = 커밋 아닌 화면 뒷단 파일 해시(playbook §2) → 주황 AL발주서·AL설정 관리 2건. 트리 밖 미반영 파일은 별도 절(안 적으면 리포 전체로 오독). 검증 = selftest + full E2E + theme/font FAIL 0 + 실브라우저. 서버 코드 무변경(master 5c2aef2). ⏳페페 = 육안. 함정 4·갱신법 → projects/pfs/session-2026-08-04-sitemap.md
pfs 메모알림 (2026-08-04 완료 · 2026-08-05 HANDOFF NOW 에서 원문 cut 이관)
🆕pfs 메모알림 [코디] 26.8.4 ✅운영배포 완료 — 생산현황 메모가 바뀔 때마다 텔레그램 즉시 발신(deploy-live 44ece4b, master cf6d117+4904f30 선별 포워드 4파일·AL 무유입 확인). 신호는 저장 경로가 모이는 field_memo_service 한 곳에만. 🔑경로 = EC2→api.telegram.org 직결(코디 PC broker는 EC2에서 못 닿는다) · 키는 env/pfs-{live,test}.env 주입(.env.production 심볼릭이 읽음, 백업 .bak-memo-notify) · 끄는 법 = TOKEN 줄 삭제 후 재시작(코드 수정 불요). ⚠알림이 업무를 막지 않는다 — 별도 스레드+예외 삼킴(자체검사가 전송을 강제로 터뜨려 저장 성공 확인). 본문에 [운영]/[테스트] 라벨 필수. 검증 = 자체검사 21항목 + 테스트 실서버 E2E 10항목(비로그인 401 회귀 포함·원복 확인) + 두 서버 send ok: True 실왕복 + 운영 HEAD/uwsgi/401. ⚠운영은 저장 E2E 미실시(실데이터 previous 밀림) → 최종 확인 = 페페가 메모 한 번 고쳐보기. 🆕신규 기본규칙 = pfs 고치면 사이트맵 재빌드까지가 한 작업(CLAUDE.md §4 + pfs rules.md, 이번에 첫 적용 — /field/list 주황 걷힘 확인). → projects/pfs/session-2026-08-04-memo-notify.md
AL발주서 QA 8건 (2026-07-29 테스트 배포 완료 · ⏳운영 미배포)
2026-07-31 HANDOFF NOW에서 원문 cut 이관(운영배포 지시는 여전히 페페 몫 — NOW에 1줄 유지).
master b69d325→f6bcfb2→6f9732c. ①인쇄가 「AL업체 제목 아래 프레임 선만」 찍히던 것 = @media print visibility 토글이 모달 transform·max-height·overflow에 잘린 것 → 인쇄 전용 iframe 문서로 분리(+양식 헤더 colspan n-3→n-4로 우측 빈 컬럼 제거). ②업체 다중등록(그릴링 1문항 → 페페 선택: 헤더 여러 줄 + 그리드 컬럼 선택) — 빈칸=첫 업체로 일괄, 미리보기·엑셀은 업체마다 발주서 1장(블록 통째 배정), 저장=vendors JSON + item al_vendor/glass_vendor(patch44, DAO 멱등 ALTER), 첫 업체는 기존 단일컬럼 유지로 목록·검색·구버전 무손상. ③계산식 색 #333(블랙 80%) + 「폰트 블랙 70%+」를 pfs 기본 지침으로 projects/pfs/rules.md 신설(페페 지시). ④계산셀 굵기 제거. ⑤엑셀 빈블록을 인쇄영역 밖이 아니라 행 삭제(AL 180→20행), 부수로 입고처가 첫 블록에만 채워지던 버그 수정. ⑥datalist → 자체 인라인 드롭리스트(부분일치+Enter 확정). ⑦업체행 CSS grid 정렬 + 담당자·전화·팩스 폭 오토. ⑧그리드 width:max-content(지정폭=하한)로 잘리던 컬럼 확장. 검증=엑셀 자체검사 + 테스트 E2E 18 + UI Playwright 27(콘솔0). ⏳페페 몫 = 운영배포 지시(지시문에 문구 없어 안 함) + 실제 인쇄·엑셀 육안. → projects/pfs/session-2026-07-29-al-orderpaper-qa8.md
OMC 협력 페이지 (2026-05-23~06-08 완료·운영배포·검증)
- Phase 1(DB): 테스트 RDS
omc_sheet/omc_board_item/omc_board_inout3테이블 +menu_catalogOMC/OMC_SHEET/OMC_BOARD 등록. - Phase 2~5: 커밋
9bcc804·00fb979. 라우트/omc/sheet·/omc/board·/omc/board/confirm, 모바일 UA 분기(sheet_mobile.html·board_mobile.html), API/api/omc/sheet/*·/api/omc/board/*, SUM Decimal→INT 캐스팅(00fb979). - Phase 6(데이터+fetch): 실데이터 삽입(오엠씨17+에넥스153+보드20건), JS fetch 연동, 비고 열 마지막 이동.
- Phase 7(레이아웃+사이드바): 커밋
eafe6a5. topbar fixed 충돌·모달 Bootstrap 충돌(omc-modal-backdrop z-index 1055) 해소, 사이드바 OMC/업체관리 그룹. - 운영 배포: ✅ 완료(2026-06-08). 운영 RDS OMC DDL 검증 —
omc_sheet(201행)·omc_board_item(2행)·omc_board_inout(20행) +menu_catalogOMC 메뉴 3건(order 950·951·952, active=1·sidebar=1) 테스트 정본과 완전 일치. 누락 0. - 함정:
menu_catalog실제 컬럼 =menu_key/is_active/show_in_sidebar(가정한menu_code/use_yn아님). 정본 = repodb_migration/v2_patch33. OMC stock 재계산: 수정/삭제 시_recalc_stock()전체 재계산(io_date ASC, id ASC). - 수동 QA 잔여: poin01로 운영 화면 OMC 메뉴·페이지 렌더 + 모달/추가/수정/삭제/확인서 출력 1회 확인.
견적 v2 패치 누적 내역 (~2026-05-23, 운영 반영)
-
13~#20: 엑셀 make_response, 707 매핑+JOIN, orphan sub 복구+UPDATE 방식, 임시저장 제거, autosave is_temporary 제거, estimate_div 라디오 복원, 별도항목 정렬. (운영 반영됨 — 2026-05-22 진단 확인)
-
21: autosave 전면 폐지(
4c13fb7). 재도입은 위험작업. - 2026-05-22 QA: #1~5(
5ee6663), #6~9(7be87f5), 업체관리 마진(424c099), 전체마진 자동반영(f6126d3) → 테스트 후 운영 배포 완료.
견적 구조 복사 (타입/K/F/항목/sub) — 테스트 배포 완료 (2026-06-09 c2b5db2→Actions 27213107339)
- 3파일:
estimate_regist_v2.js+418(cloneDetail/copyType/openCopyModal/applyCopy 등)·.html+34·.css+113. 서버 무수정. - 구조: 복제 신규행 detail_no=null → 기존 INSERT→
_save_detail_subs경로 타 sub 유실 회피. 타입⎘ 바로복사·항목⎘/⧉(위치모달)·다중선택·SUB 4단 모달·K/F 병합(기존 그룹 말미). - 미확인(인증 세션 필요): 로그인 UI 실측(다중선택·SUB 모달·복사+저장+재진입 sub 보존·RDS INSERT) → 페페 수동 확인 후 운영배포 결정. 운영 미반영.
- 타입탭 인라인 rename은 이때 코드 부재 → 페이즈 B 1번으로 진행. 상세 설계 =
design-estimate-copy.md, 페이즈 시드 =sub/estimate-copy-future.md.
견적 v2 타입SSOT 페이즈A·B + 후속결함 5건 + 펜아이콘 — 운영 배포 완료 (2026-06-10 a523d39→Actions 27246653521 ✓)
handoff 2026-06-10 이관 원문(진행중·미결 절). - master 미반영 4커밋(페이즈B
123aba1·후속fixd200229+51da6cd·펜아이콘28c7f3f)을 deploy-live에 머지(페이즈A03b9583은 이미 운영 반영됨). 운영 서버 grep 검증(SSM,/home/ubuntu/pfs): HEAD=a523d39·펜🖊 2·prompt 1·dblclick 0·DAO company_margin_rate 1·buildTargetListHtml 2 전부 통과. - 타입 이름 수정(#1) 최종형: 더블클릭(draggable 충돌로 폐기)→펜(🖊) 아이콘 클릭→window.prompt로 새 이름 입력(인라인 inputreplaceWith폐기 — 기존 탭이 input으로 바뀌던 혼란 해소). 탭 UI 전환 없이 이름만 변경·저장은 사용자 몫(markDirty). 미사용.typetab-rename-inputCSS 정리. - 전체마진 자동/수동(#2): 이미 정상 동작 확인(추가작업 없음) —pickSite가 현장 업체company_margin_rate(estimate_dao.py:716 조인·company.margin_rate 컬럼)를 읽어applyGlobalMargin(rate, true)자동 적용. 사용자 수정→수동 배지+NULL규약 재로드 유지. - 후속결함 #3·#4·#9·#10: 코드 운영 반영됨. #3·#4 하위호환 약점 유지: NULL규약 이전 기존 견적은 자동행에도 margin_percent 값이 남아 1회 재저장해야 자동행 NULL 정리·정상화(DB 마이그레이션 없음). - (미결 2 이관) 1번(타입 순서 + SSOT 통합 + 1:1) — 페이즈 A 완료(2026-06-1003b9583테스트 배포·채티 재검증 통과): 다음 = 페페 화면 수동 확인 → 이상 없으면 운영(deploy-live + 운영 DB 동일 A 시드) 별도 승인 후 진행(당시 운영 미반영 → 이후 a523d39 머지로 코드 운영 반영). 지시문C:\dev\pfs\CODI_estimate_type_order_phaseA_integrated.md(실행 완료). 구 지시문..._fieldtype_seed.md는 "폐기·실행금지". - (미결 2 이관) 페이즈 B 10건 — 테스트 배포·검증·수동확인 완료 → 후속 결함 5건: 본체(123aba1) 코드 9건 테스트 반영. 페페 화면 확인 결과 정상=#2·5·6·7·8, 결함=#1(이름편집 발화안됨)·#3·#4(자동/수동 마진 오복원)·#9(복사 대상위치 기존행 미표시)·#10(복사 출처 계층경로 미표시). 진단=session-2026-06-10-phaseB-verify-followup.md. 후속 지시문 =C:\dev\pfs\CODI_estimate_phaseB_fix.md(A=#1 draggable이 dblclick 가로챔→이름span draggable=false+mousedown 해제 / B=#3#4 margin_div는 계산방식이라 자동수동 컬럼 없음→자동행 margin_percent=NULL 저장규약·loadEstimate 추측비교 폐기 / C=#9#10 buildTargetListHtml+출처경로 제목 / D=cp-tgt CSS). JS+CSS 2파일·백엔드/DB 무변경. 실행·테스트 검증 후 a523d39로 운영 배포 완료. 본체 재진단 상세 =session-2026-06-10-phaseB-rediagnosis.md, 본체 지시문 =CODI_estimate_phaseB_bundle.md(실행 완료). - (미결 2.5 이관) (참고) 페이즈 A 운영 배포 — 미반영 확정(2026-06-10 실측·이후 a523d39로 코드 반영 해소): deploy-live에03b9583없음·운영 field-types 404였음. 잔여 운영 DB 작업(A시드·finish 숨김 E)은 handoff 미결 2 유지.
견적 v2 임시 계산기 행 + 합계 천원올림 보정 — 운영 배포 완료 (2026-06-10 deploy-live 3bb8457→운영 Actions 27253586285 ✓)
handoff 2026-06-10 이관 원문(미결 2.6 상세). - 운영 반영 3커밋: 1차
e26983c=#calcFrame프레임+계산기 모듈(비저장 임시 계산 행). 2차dcd060d(테스트 배포 ✓)=컬럼동일화(calcVisibleCols/calcCellForCol로visibleCols()기반 동적생성, 하드코딩 12컬럼 폐기, 항목 행과 순서·폭·라벨 일치) + 마감재 멤브레인('13') 고정·컬럼 숨김 + SUB colspan 동적화. 3차256ed17=calcItemTotal 천원올림 부동소수 보정 —Math.ceil(withMargin/1000)*1000→Math.ceil(Math.round(withMargin)/1000)*1000(estimate_regist_v2.js:167-174 1곳만). 400000×1.1=440000.00000000006 찌꺼기가 천원올림을 한 칸 더 올려 1,000원 과다(441,000) 청구되던 결함 정정. - 백엔드에 천원올림 없음 확인(합계는 프론트 단독 계산·서버는 저장만 → JS 이 한 줄이 단일 지점). - 검증: node 문법 PASS / 수식 단위검증 4종 — 단가10만×2·마진10 → old 441,000→new 440,000 ✅, 정상 올림 회귀 100,001·마진10→111,000 불변 ✅, SUB 포함 400,000+55,000·마진10→501,000 불변 ✅ / 테스트 Actions 27253348027 성공 / 운영 Actions 27253586285 성공 / 테스트·운영 양 서버 배포 JS에 Math.round 보정 반영 직접 확인. 화면 E2E(저장 라운드트립)는 로그인벽으로 코디 미확인. - 지시문: 2차 = 코디 직접, 3차 =C:\dev\pfs\CODI_estimate_total_rounding_fix.md(실행 완료). 보정 후 기존 견적 재저장 시 합계 1,000원 감소 케이스 가능 — 영향 건수 조회·일괄 정정은 handoff 미결 2.6 잔여로 유지.
견적 마진율 자동/수동 모드 완전 영속 (2026-06-10 운영배포 — handoff 이관 원문)
handoff 2026-06-10 이관. 구현·운영배포 git 관찰:
b6314b6master →37d997ddeploy-live(타 세션 실행). - 경위: 페이즈B후속4dcfec2가 JS만 고쳐 미해결 → 재진단. - 근본 원인 =estimate_service.py_normalize_detail/_normalize_master의if v is None: continue가 프런트의margin_percent: null을 default 0으로 강제 → NULL 규약 무력화(자동행이 수동 0%로 재로드, 구형 휴리스틱 재발동). 추가 2건: ②마스터 전체마진 모드 미영속(저장 시 항상 값 → 재로드 항상 "수동") ③select_estimate에c.margin_rate미포함(자동 복원 소스 부재). - DB 실측(SSM): estimate/estimate_detailmargin_percent둘 다 NULL 허용,CONVERT_EMPTY_STRING_TO_NULL(0)=0(UPDATE 경로 무해) → 스키마 변경 불필요. - 처방 = 마스터에도 NULL 규약(NULL=자동·업체 margin_rate 추종, 값=수동) + normalize None 통과(_NULLABLE_KEYS) + GET에company_margin_rate동봉 + 라벨 클릭 수동→자동 복귀 토글. 지시문 =C:\dev\pfs\CODI_estimate_margin_mode_persist.md(3파일: service·dao·v2 JS).
완료 이력 — 2026-06-18 이관분 (handoff 진행중에서 cut, 원문 보존)
- orderpaper 업로드 현장 분리 문제 해결(넵스 부자재) — 운영배포 (2026-06-18, 코디 직접, master
5ea258c→deploy-live302ca9f+ 운영 데이터 병합): 페페 제보("넵스 부자재 pdf 업로드+동기화 잘 안된 듯"). 진단: 업로드는 정상 적재(넵스 16건=삼성정밀7·봉적5·에쌤2·헤펠레2, 부자재S·발주처 넵스, 누락0)됐으나 별도 카드로 분리 —site_name_raw가IS동서 울산(업로드=연결 field명) vsIS동서 울산 MH(NAS=발주서 파싱명)로 갈려(같은 field 2106·숨김X). orderpaper는 site_name_raw로 그룹핑하므로 두 카드. NAS 동기화는 upload 항목(sync_round NULL) 미제거라 데이터는 안전. 영구 수정:orderpaper_upload_load.pyREMOTE에 — 업로드 적재 시 같은 field_no에 기존 비-업로드(NAS) 항목 있으면 그 site_name_raw로 병합(최다 묶음 채택). 사이드카 로컬코드(EC2 미실행)라 다음 업로드부터 적용, 리포 일관성 위해 deploy-live도 push. 검증: 테스트 업로드 재실행 site→IS동서 울산 MH해석·16건 병합·별도카드0 / 운영 이번 16건 site_name_raw 병합 UPDATE → 단일카드 57건(NAS41+업로드16) 페이지 확인. 함정: item_key=k('U',source_file,vendor,sheet,idx)에 site_name_raw 미포함 → site만 UPDATE해도 병합(중복 없음). 업로드는 EC2 아닌 사이드카(this PC, xlrd/pdfplumber)에서 파싱·SSM 적재. neps 파서=pdfplumber 평면테이블(열 NO/발주일/협력업체/.../현장명/비고). - worklog(현장 내용) 3기능 — 운영배포 (2026-06-18, 코디 직접, master
95e68b5→deploy-live cherry-pick031e806, 운영 RDS worklog_site_hide 생성): 페페 지시 3건(테스트 후 AskUserQuestion으로 운영 승인받아 배포). ① 하위항목 일괄 상태변경: 카드 본문 '하위항목 일괄변경' 바(진행/완료/대기/보류) →PATCH /api/worklog/status-bulk(비공개·owner 접근제어 동일, 카드 표시범위와 일치). ② 완료항목 폴딩 기본 접기:renderItems에서 완료(status='완료')를wl-itemdone폴딩 그룹으로 분리·기본 접힘(항목행 빌더wlItemRow분리, 변경 후 헤더 배지wlUpdateCardBadges갱신). ③ 현장 숨김: 카드 헤더 '숨김' 버튼(현장별 전역 카드만)+'숨김 현장 관리' 모달(검색·활성화). 신규worklog_site_hide테이블(hide_key PK='f'+field_no 또는 's'+site_name, 테스트 RDS만 생성) +PATCH /site-hide·GET /hidden-sites,select_worklog_site_summary에NOT EXISTS숨김 제외절. 검증(테스트): 일괄 9항목 대기 적용·원복, 완료폴딩 기본접힘(57카드·완료 2건), 숨김→요약제외·숨김관리 등장·활성화 원복 전부 PASS. 운영 반영 완료: 운영 RDSworklog_site_hide생성(CREATE TABLE·행0) + deploy-live031e806. 운영 검증(숨김관리·22카드 숨김버튼·일괄바·완료폴딩 기본접힘·숨김 API 라운드트립 목록등장·활성화원복) PASS. - 생산현황 출력물 대기칸 배경색 제거 + 대기 글씨 숨김 — 운영배포 (2026-06-18, 코디 직접, master
c6ade32·901a88c→deploy-live63cce0b·21bb45f): 페페 지시 2건.field_status_print.html에서 ①td.st-wait배경#fff4d6→transparent②stCell이 대기/대기중일 때 빈 문자열 렌더 → 대기칸 배경·텍스트 모두 없음(완전 공백). 진행중(파랑)·완료(초록) 유지. 테스트·운영 검증(대기셀 배경 rgba(0,0,0,0)·글씨0, 진행/완료 유지). - orderpaper 상세필터 계층별 폴딩 설정 + C:\dev 정리 — 운영배포 (2026-06-18, 코디 직접, master
cbe6674정리+1116db7폴딩→deploy-live cherry-pick39c683a): 페페 지시 2건. ① C:\dev 정리: 루트의 pfs 산출물(orderpaper 목업 3 + 출력 미리보기 PNG 5 +pfs 기본양식.txt)을pfs/mockups/·pfs/로 이동,.gitignore에mockups/·pfs 기본양식.txt추가(로컬 보관·git 청결). 남은 루트 파일은 비-pfs(dwg_convert.exe=drawerboring/ODA·poinwg.conf=인프라·_notify_*=broker·PDF=참고·Thumbs.db/숫자=정크)라 경로참조 위험으로 보류·보고. ② 계층별 폴딩 설정: 상세 필터 모달에 '📂 계층별 폴딩(기본 펼침/접힘)' 섹션 — 4계층(현장/업체 카드·자재 구분·업체/현장 블록·완료 항목) 각각 접힘/펼침 기본값.OP_FOLDCFG+헬퍼(foldCardOpen/foldMat/foldBlockOpen/foldDoneOpen)=개별 토글 우선·없으면 계층 기본값,opSetFoldCfg가 해당 계층 override 초기화 후 전체 재적용(=계층 전체 펼침/접힘). 개별 토글은 현재 표시상태 기준 반전으로 일관화. localStorage(FC) 저장→재로드 복원. 기본값=기존 동작(카드 접힘·자재 펼침·블록 접힘·완료 접힘). 검증: 테스트(4계층 표시·카드/블록 펼침설정→14/14·170/170·새로고침 복원·기본값 복원) + 운영(4계층·카드펼침 8/8·기본값 정확). 함정(재확인): pfs 세션쿠키 비영속 — 장시간 테스트 중 만료 시 로그인 리다이렉트(h3='로그인'). 재로그인 = 로그인버튼 클릭(프로필 자동완성 poin01). 테스트·운영 양쪽 발생. - orderpaper(발주서 정리) 엑셀식 상세 필터 + 빠른 토글 — 운영배포 (2026-06-18, 코디 직접, master
fa927c4→deploy-live cherry-pick72187a4): 페페 지시("업체별이 너무 많아 보기 어려움 — 엑셀 필터처럼 상세 조정, 현장별·업체별 공통", v2 목업 검토·승인). 아키텍처 전환(핵심): 필터는 전 항목 데이터가 클라이언트에 있어야 동작(체크리스트·카드숨김·카운트) → 단일소스화. 신규GET /api/orderpaper/all-items(전 항목 + 현장명·현장 상차일=field.shipping_date조인, 숨김현장 제외, 상차일은 YYYYMMDD 정수형→클라shipISO()변환). 프론트는/sites·/items·/vendors·/vendor-items대신 OP_ALL 슬라이스(참조 공유)로 카드 본문 렌더 → 기존 변이(상태/블록/입고일/자재토글)는 공유 객체 수정이라 보존, 삭제만 OP_ALL 동기화 추가. hide/map/sync 후loadAll()재적재. 안정 cid(현장/업체명 기준)로 필터 재렌더에도 펼침/폴드 유지. 필터 UI(7요청 반영): ① 상단 빠른토글 — 자재(원/엣지/부, OP_FILTER.checked.mat 동기화) + 빠른필터 5종(미완료만·오늘입고·이번주입고·상차임박3일·입고지연) ② ⚙상세 필터 모달(빠른토글만 상단·상세는 모달 분리) — 엑셀식 체크리스트(가구업체/발주처/자재/상태, 검색·전체선택/해제·값별건수) + 범위(발주일/입고일/상차일/발주량) + 필터 표시 설정(불필요 필터 숨김) ③ 활성 필터 칩 + 결과 카운트(표시 N/전체 M·K개 그룹) ④ localStorage 저장→다음 로드 자동 적용(op_filter_v1) ⑤ 블록 하위항목 전부 완료 시 블록 헤더 초록 + ✓완료 태그 ⑥ 현장 카드 상차일 배지. 데이터 동일·읽기 재그룹이라 동기화 불필요. 검증: 테스트(808항목 로드·빠른필터·자재토글·모달 체크리스트/표시설정·블록완료초록[조운IMT·케데코]·상차배지·상태변경 API 라운드트립·localStorage 재로드 복원[업체별·미완료만·발주처선재기업·발주량숨김]) + 운영(501항목·8현장, 미완료만+업체별 141항목/22업체·완료0, 모달 9필터). 목업 =C:\dev\orderpaper_filter_mockup_v2.html. 주의: 일부 현장 상차배지가 24.4.31·25.8.20처럼 보이는 건field.shipping_date원본 데이터 품질(코드 아님). 안 쓰는 엔드포인트(/sites·/items·/vendors·/vendor-items)는 서버 잔존(프론트 미사용). - orderpaper(발주서 정리) 최상위 분류 현장별↔업체별 토글 — 운영배포 (2026-06-18, 코디 직접, master
ff48eaf→deploy-live cherry-pick87cc28b): 페페 지시(HTML 목업 검토·승인 후 구축). "현장별,업체별 가장 상위 분류 생성, 데이터는 동일·가장 큰 정렬 기준만, 화면전환 없이 현장↔업체 계층만 swap해 재정렬". 설계(목업 승인): 현장별=현장→자재구분(원자재/엣지/부자재)→업체 블록→항목(현재), 업체별=업체→자재구분→현장 블록→항목(현장↔업체만 swap, 자재구분 층 유지). 백엔드:GET /api/orderpaper/vendors(업체 요약—취급자재 GROUP_CONCAT·현장수 COUNT DISTINCT·상태카운트, 숨김현장 제외) +POST /api/orderpaper/vendor-items(업체 전현장 항목, 정렬 R→E→S·현장·블록). 현장별 엔드포인트(/sites·/items)·흐름은 무변경(회귀 0). 프론트(field_orderpaper.html): 상단 '분류 기준' 토글(🏗현장별/🏢업체별,opSetMode),loadGroups분기,loadVendors/renderVendors/toggleVendor/loadVendorItems추가. 공유 블록 로직(groupBlocks에 site/company 추가,sortBlocks/matSecHtml/blockTable을innerKey()=OP_MODE로 일반화 — 안쪽키 현장↔업체 swap, 라벨·카운트 적응). 블록·항목 단위 기능(상태/일괄/입고일/삭제/자재토글)은 cid+block_key 기반이라 두 모드 공유. 업체 카드=취급자재 배지+현장수, 안쪽 현장 블록=현장명+가구업체 배지. 데이터는 동일 orderpaper 테이블(읽기만 재그룹)이라 동기화 불필요. 검증: 테스트 SQL(오엠씨 71항목12현장 R·선재기업 5현장 E,S) + 테스트 UI(토글·업체별 오엠씨→원자재→현장블록·현장별 복귀 회귀·모드전환 깔끔) + 운영(37업체 카드·오엠씨 원자재7현장·일광금속/이지웨이 부자재만). 목업 파일 =C:\dev\orderpaper_grouping_mockup.html(검토용·리포 외). 주의: 업체별은 전 항목을 업체 단위로 묶어 로드(현장별 lazy와 별개 엔드포인트). 숨김/매핑/업로드/동기화 등 글로벌 툴바 기능은 모드 무관 그대로. - orderpaper(발주서 정리)에 '엣지' 자재구분 추가 — 운영배포 (2026-06-18, 코디 직접, master
e31a754→deploy-live cherry-pick5e18af1): 페페 지시("원자재·부자재 사이 엣지 추가, 원/부자재 사용처럼 가능하게 최종구축, 동기화에서 엣지 항목 자동수집, 테스트→운영배포, 단계별 텔레그램"). 자료구조:orderpaper.material_typeCHAR(1)에 기존 R(원자재)/S(부자재) + E(엣지) 추가(스키마 변경 불필요·CHAR(1) 수용). 백엔드(orderpaper_dao.py/model/controller): 항목 정렬FIELD(COALESCE(material_type_user,material_type),'R','E','S')(원자재→엣지→부자재),update_block_material·update_status_bulk허용집합에 'E' 추가. 프론트(field_orderpaper.html): 자재 메타OP_MATS=[R/E/S]+matMeta()기반으로 리팩터(하드코딩 제거) → 엣지 섹션을 원자재·부자재 사이 렌더, 전역 표시토글 버튼(원자재▲/엣지◆/부자재▼)·블록 3-way 셀렉터(원자재/엣지/부자재)·주황(#ea580c) 색상. 상태·입고일·일괄·블록삭제 등 프로세스는 원/부자재와 동일(섹션·블록 일반화라 자동 적용). 동기화 자동수집(핵심):orderpaper_parse.pyparse_section이 섹션을 비엣지(원자재/부자재) + 엣지(E) 블록으로 분리 —_is_edge(it)=품명/규격에 '엣지'(엣지바 포함) 포함. 엣지 항목은 원자재(오엠씨)·부자재 벤더탭(선재기업·코넬·케데코·데코밸리·칠성화학·일광금속 등) 어디 섞여 있어도 엣지 섹션으로 수집.idx는 split 이전 섹션기준 고정→비엣지 item_key 안정(상태 보존), 엣지만 S→E로 item_key 변경(1회 재분류=대기 리셋).orderpaper_sync.pyREMOTE_TEMPLATEblock_key에 material_type 포함→비엣지/엣지 블록 독립 운영(블록 토글·상태·삭제 미간섭). 사이드카=이 PC(poin-local) 8791 상주라 parse/sync 수정은 다음 동기화에 즉시 반영(매 동기화=새 서브프로세스 재import). 생성물_op_remote_*.py/*_prod.py는 gitignore(매번 재생성). 검증: 로컬 파싱 1070항목 중 엣지 72 자동수집·item_key 충돌0·누락0·block_key 비엣지/엣지 완전분리 PASS. 테스트(pfs-test 배포+동기화: E72·R108·S1096, 2차 동기화 멱등 ins0/removed0, 페이지 원자재→엣지→부자재 순·엣지 블록3-way·class=edge 확인) + 운영(pfs.poin.co.kr 배포+동기화: 정확히 엣지72 insert·옛72 removed·998 update=상태보존, 2차 멱등, RDS E72·R166·S749, 페이지 학동매장 원자재(보라)→엣지(주황·코넬)→부자재(청록) 3섹션·블록별 3-way 셀렉터·입고일/상태/삭제 동일 확인). cherry-pick으로 엣지 1커밋만 운영 반영(deploy-live의 해당 4파일이 d60b92a와 0라인 차이=clean apply). 주의: 1회 재분류로 엣지 72항목 status가 대기로 리셋(item_key에 material_type 포함·불가피, 대부분 최근 대기 항목이라 영향 경미). 오분류 시 블록 3-way 셀렉터로 수동 교정(material_type_user 보존). 업로드(에넥스/넵스 부자재)는 'S' 고정 유지(NAS 동기화만 엣지 분리·범위 한정). 후속 수정(2026-06-18, master5f64b38→deploy-live cherry-picka20d329, 테스트·운영 반영 완료): 페페 피드백 "3면 엣지바 등 엣지바는 엣지 아님(추후 분리할 AL 종류)" →_is_edge에서 '엣지바' 제거 후 '엣지' 검사로 변경. 엣지바 11개(이지웨이·일광금속 일반/누드/AA-xxx+3면 엣지바)는 엣지 제외→부자재 복귀, 진짜 엣지밴드(0.6T22mm 엣지 등) 61개만 E. 테스트·운영 RDS 검증: 운영 E61·R100·S830·엣지중엣지바0*(이지웨이·일광금속 부자재만 표시). 메모리=[[orderpaper-edge-vs-edgebar]]. 추후 'AL' 구분 신설 시 엣지바·AA-xxx AL 프로파일을 그쪽으로 분리. - 견적 목록 본견적만 표시 + 본건↔추가건 타입 분리 — 운영배포 (2026-06-18, 코디 직접, master
d60b92a→deploy-live cherry-pick4145ff6): 페페 지시 2건. ① 견적 목록에서 추가건 노출 제거: 목록 화면(POST/api/estimate/search)의estimate_dao.select_estimate_search_list에AND a.parent_estimate_no IS NULL추가 → 본견적만 표시(추가건은 본건 화면 추가건 섹션에서 관리). ② 본건↔추가건 type_name 섞임 분리: 원인 =estimate_regist_v2.jsloadFieldTypesForSite()가 견적 열 때 현장(field_no) 전체 field_type을 자동로드(역방향 SSOT) → 같은 현장(2098)의 본건(711)+추가건(712·713) type_name이field_type테이블에_upsert로 섞여 어느 견적을 열어도 모든 타입 표시. 수정 =loadFieldTypesForSite를 비활성(State.fieldTypes=[] + renderDetailTable)해renderTypeTabs가 각 견적 자기 detail의 type_name만 그림. (현장 전체 자동로드=신규 견적 시 현장 타입 미리표시 기능은 사라지나, 견적별 타입 분리가 페페 우선.) 검증: 테스트(710에 임시 추가건 등록 → 목록 search 추가건 제외·본건 710 화면 본건타입만·추가건 화면 자기타입만 → 임시건 DELETE 정리) + 운영(목록 search 711만 712·713 제외 / 711 화면=124·84A기본·84A옵션·84B옵션만 추가타입 오염0·추가건섹션 712·713 유지 / 712=추가1-1만·713=추가2-1만 본건타입 오염0). cherry-pick으로 이번 1커밋만 운영 반영. 주의:field_type테이블엔 과거_upsert로 등록된 추가건 타입(추가1-1 등)이 남아있으나 화면이 field_type을 더 이상 안 읽어 무해(원하면 SSM으로 정리 가능)._upsert_field_types_from_details는 그대로(추가건 저장 시 field_type에 계속 등록되나 화면 영향 0). - 본건 견적서 화면 추가건 목록 표시 버그 수정 — 운영배포 (2026-06-18, 코디 직접, master
e0677d9→deploy-live cherry-pick5745bb1): 페페 제보("712·713이 711 추가건으로 연결 안 보임"). 진단:parent_estimate_no=711·sub_count=2·estimate_type=sub·parent_name 정상 = 데이터는 처음부터 정상 연결. 진짜 원인 =estimate_regist_v2.jsloadEstimate()가 항목·자재·옵션·sub-item은 로드하나 추가건(State.subEstimates)을 불러오는 코드가 누락 → 본건 수정화면 추가건 섹션이 항상 "등록된 추가건이 없습니다"(712·713만이 아니라 모든 견적 공통 기존 미구현). 견적 목록 화면도 추가건을 본건 아래 묶지 않고 평면 나열(+추가건 버튼만). 수정 3곳: ①estimate_controller.pyGET /api/estimate/sub-list/<parent_no>라우트 신설 ②estimate_service.pyget_sub_estimates()(기존estimate_dao.select_sub_estimates활용) ③estimate_regist_v2.jsloadEstimate에 추가건 로드 promise(estimate/sub-list/+estimateNo → State.subEstimates) 추가 → renderAll→renderSubEstimates 표시. 검증: py_compile·node --check OK + 테스트(710에 임시 추가건 등록→modify-v2/710추가건 attach_rows=1 표시→임시건 DELETE 정리) + 운영(modify-v2/711추가건 2건="추가1"#712·"추가2"#713 표시 확인). cherry-pick으로 이번 1커밋만 운영 반영(생산메모 540eb1a 등 미반영 master 커밋 제외). 사용자가 PFS에서 712·713 단가 입력 시 추가건도 본건 화면에서 함께 관리/출력체크 가능. - GS오산 도어발주서 포인탭 → 추가건 견적 2개 운영 등록 + "아날로그 견적서 PFS변환" 스킬 제작 (2026-06-18, 코디 직접, 운영 견적
712=추가1·713=추가2, parent_estimate_no=711·field 2098): 페페 지시(복사본 AS 넥서스 GS오산 양산MH 도어발주서.xlsm의 포인 탭만 추가건 데이터화·운영 등록, 견적비고에서 "유상," 제거, 단가는 PFS 화면 수동입력=행만 준비). 발주서 구조: 36행 순환(페이지 1~11 머리글·12~36 데이터블록), 열 D=품명·E=두께·F=가로·H=높이·K=수량·L=생산비고·U=견적비고(유상/무상)·K5=타입반복셀. 행 4유형(그룹행 D:K병합 / 기본행 / 텍스트행 B:N·D:N병합 / 빈행). 수집: U"유상" 또는 E빈칸 수집, U"무상"·텍스트·빈행·그룹행 자식부재 제외(빈행 만나면 억제해제). 그룹행 파싱(품명=숫자숫자 앞·치수=숫자숫자(숫자)·수량== 뒤), K5조합("84A 기본 키큰장"). 견적서 단위(핵심): 추가1(페이지 1~7·12)·추가2(페이지 8~11 EP/휠라류)는 각각 별도 estimate 레코드(parent 711), 견적서 안에서 20행마다 type_name 추가N-1·N-2 분할(20=견적서 한 블록 최대행). 포인탭 23건 → 712(추가1, 11건·type 추가1-1)·713(추가2, 12건·type 추가2-1). 등록(본건 711 미러링): 각 detailproduct_name=품명·size_display="치수mm"·comment=U("유상," 제거)·dimension1=300·price=0(수동입력 예정)·field_type=K·price_div=pr·price_option=10·margin_div=10·margin_percent=0·part_mode=all.POST /api/estimate/(Playwright 로그인 세션, pfs.poin.co.kr 자동완성 poin01). 검증: GET 712/713 — name 추가1/추가2·parent 711·field 2098·count 11/12·유상 0건·price합 0·dimension1=300 전부·comment 정확("장 추가됨"·"현장 요청"·"도면 오류" 등, 추가2는 빈비고). 스킬:~/.claude/skills/analog-estimate-to-pfs-{main,additional}/(SKILL.md + 추가건convert_additional.py=리스트화·register_additional.py=페이로드JSON). 작업물=C:\dev\order-automation\(리스트 xlsx·payloads). 미결: 페페가 PFS에서 712·713 단가 직접 입력(현재 0). 함정*: estimate API 응답은{code, message}로 message가 데이터 컨테이너./api/estimate/POST 페이로드는 browser_evaluate에 직접 박음(Playwright VM은 require/import 차단). broker notify는 curl-d실패→PowerShell/Python urllib만 동작. - 견적 마진 수동 0% 영속 수정 + GS 오산 양산 견적 엑셀→API 등록 — 운영배포 (2026-06-17, 코디 직접, 마진수정 master
962f174→deploy-live51356fa; 운영 견적estimate_no=711/현장2098, 테스트710): 페페 지시(엑셀 본건탭 견적 등록, 마진 수동 0%, 규격=표시용·단가=엑셀단가로 엑셀값 그대로, 현장 2098 연결, "0% 사용 기능 없는 듯—수정해서 쓰게"). ① 마진 0% 시스템 수정(전 견적): 핵심 발견 — 계산식은 이미금액=(치수합−코너)/300×단가×수량, 최종×(1+마진%/100)천원올림 → 0%=×1.0(단가변동없음) 계산상 이미 동작, 저장/로드 NULL규약(NULL=자동·값=수동)도 구현돼 있었음. 진짜 결함 = 표시/편집의|| 10falsy-clobber가 0을 10으로 덮어씀(전체마진 입력·인라인/모달 셀·자동행 복원 + 모달 저장 시 수동전환 누락). 수정 =mNum(v,dflt)헬퍼(null/undefined/''만 기본값, 0 보존)로estimate_regist_v2.js6곳(643·836/1830·496·483·1825·3173) 교체 + 모달 저장 2곳에 인라인과 동일 수동전환. non-zero/missing은 기존과 동일(0값만 보존)이라 안전. 검증: 테스트 견적 로드 시 quickMargin=0·행 0·manual, UI 저장 라운드트립 후 37행 전부 margin_percent=0(null 0). ② 견적 등록(저장 API 직접): 본건탭 37항목(84A기본 K5 / 84A옵션 K6+F5 / 84B옵션 K4+F5 / 124 K6+F6, 가구합 55,197,000) + 시공비→construction_cost 22,000,000·물류비→transportation_cost 600,000(estimate 마스터 컬럼) = 총액 77,797,000(=Σdetail margin_total + 시공 + 물류). 각 행: margin_percent=0(manual)·margin_amount=0·margin_total_amount=price, 단가=금액 구현=dimension1=300(→unitDim=(300)/300=1, amount=1×price×1=price)+size_display=규격텍스트(표시용), price_option='10'·price_div='pr'·margin_div='10'·part_mode='all'. 등록 = Playwright로 로그인 세션에서POST /api/estimate/. 검증: 운영 711 — field 2098·total 77,797,000·37행 zero_margin 37/null 0·타입소계 전부 엑셀일치, UI 각행 금액=단가(124타입 510k·2,709k…)·quickMargin 0·manual. ③ 현장 2098 복사(페페 지시 "운영 현장 복사해 테스트 사용"): 운영 field 2098(+company_no=1) → 테스트 INSERT(멱등, company 기존존재), 테스트 견적710 field_no=2098 연결(테스트서 GS오산 검토 가능). 함정: 운영 견적 POST가'user_no'KeyError(500) — 브라우저 재시작으로 운영 세션쿠키 소실(세션쿠키 비영속). 재로그인(pfs.poin.co.kr→Chrome자동완성 poin01→로그인→/field/list) 후 성공. 참고: 등록은 저장 API 직접(코디 페이로드 구성)이라 ~37행 일괄. 테스트 견적710([코디테스트]명) 검토용 잔존. dimension1=300은 size_display로 가려져 화면엔 규격만 보임(단가↔금액 모델 유지). - 생산현황 출력(field/print/status) Stimulsoft → HTML 미리보기 재구축 + 양식개선(세로형·업체색·폭) — 운영배포 (2026-06-17, 코디 직접, master
540eb1a·5c2fb58·3ed9de9→ deploy-live cherry-pickdc8f4df·3e6440f·565bc89): 페페 지시(생산 메모가 출력물 메모창에 안 뜸 → "Stimulsoft 백업하고 더 다루기 쉬운 HTML로 새로 생성"). 근본원인(확정):status.mrt의basebaseDate변수가 C# 식new DateTime(...)사용 → Stimulsoft JS 표현식 엔진 파싱 실패("The name 'new' does not exist") → 리포트 표현식 컨텍스트 붕괴로{FieldPrintStatusMemoText}변수도 평가 불가 → 메모 항상 빈값(변수 valueObject="테스트1"이나 RENDERED=""). 콘솔로 LS/VAR/RENDERED 3단계 격리해 확정. 해결(재구축):field_status_print.html을 Stimulsoft 뷰어 → 독립 HTML 문서로 교체. ① 데이터/api/field/status/report(field 배열) 그대로 fetch. ② 메인 표(field_div≠AS, 현장별 몸통/마감 2줄: 업체·현장명(+구분/KF/시공)·상차일·재단/엣지/포인트/조립·자재비고·비고·담당) + AS/추가건 표(field_div=AS), 상차일 오름차순. ③ 메모=/api/field/memo서버값을 HTML 요소로 직접 표시(표시 전용) → 변수/표현식 의존 제거로 미표시 근본 해결. ④ 인쇄 CSS·상태 색상. 양식개선(2차 지시3ed9de9): 세로형(A4 portrait) + 업체 칸 배경색(넥서스·에넥스·넵스 우선 파스텔, 동일업체 동일색, 그 외 옅은 파스텔 팔레트 첫등장순) + 현장명 폭=데이터 최장 현장명 기준(nowrap·7~16em 캡)·비고란 최대폭(table-layout auto, 나머지 내용폭). 백업:status.mrt.bak·field_status_print.stimulsoft.bak커밋 보관(롤백=템플릿 복원). 검증: Jinja 파싱·Stimulsoft 의존 0·DAO 별칭 일치(로컬 Flask 부팅은 venv 3.14 비호환이라 불가 → UI 실측은 배포 후 페페). 배포: 테스트(master 성공) + 운영(deploy-live, 발주서 등 타 작업은 이미 운영 반영돼 있어 생산메모 3커밋만 선별 cherry-pick — 충돌 0). 메모 편집은 field/list '생산 메모' 모달에서만(출력=표시 전용, 페페 선택). 3차 미세조정(7416ac8, 테스트만·운영 미반영): 행 높이 1.2배(line-height 1.55·세로 padding), 미리보기 화면 배율 1.2배(@media screen .report{zoom:1.2}, 인쇄 미적용), 인쇄 우측잘림 방지(외곽 폭 185mm로 축소·margin:0 auto센터·@page margin 10mm·인쇄 시 현장명 줄바꿈 허용), 인쇄 시 버튼(.toolbar) 숨김. 4차 원본양식 맞춤(74f978a, 테스트만, 사진 기준): 검증도구/인쇄 버튼 인쇄숨김(body>*:not(.report)+.toolbar@media print), 인쇄 우측 자국/잘림 제거(table-layout:fixed·원본 컬럼비율 합100%·.report overflow:hidden·185mm 센터), 업체·담당 미리보기 줄바꿈 방지(td.comp/td.mgr nowrap; 화면 zoom 제거), 상차일 양식M.D(요일)(데이터 연도 2개↑일 때만YY.표기·헤더 우상단 오늘=M.D(요일)), 현장명 줄바꿈+축소(13%), 폰트 1.2배(th/td 12px·인쇄 11px; 단 구분/재단/엣지/포인트/조립=th-st/td.st/td.rowlab현재 10/9px 유지). 5차 추가조정(42fb895, 테스트만): 조립/포장 헤더 2줄(조립<br>포장), 비고 약15% 축소분을 현장명폭에 흡수(메인 cmt 31→26.5·site 13→17.5·mat 10→8·mgr 5→7), 담당폭↑(우측여백), AS 상차일·상차비고 축소→비고 확대(ship 9·shc 16·cmt 31)·담당=메인동일(7%), 인쇄 우측 세로자국 대응(print에서overflow:hidden제거·.report182mm 인셋·table margin:0 auto·border none) — 출력보기에서만 보이던 자국이 클립경계 추정. 검증도구 버튼: print에서html>*:not(head):not(body)+body>*:not(.report)숨김 추가했으나 여전히 보임 → 브라우저 확장프로그램(페이지 DOM 밖) 추정(실제 종이엔 미인쇄), 요소 inspect 필요. 6차(bc35ad3, 테스트만): 재단/엣지/포인트/조립 컬럼 6% 균등으로 확대('진행중' 3글자 넘침 해소, 흡수=비고 26.5→22), 조립/포장 헤더 2줄. 검증도구 정체 규명·정식 수정: PFS QA도구(qa_helper.css/js,#qa-helper-toggle파란 토글)가web/__init__.py_QA_HELPER_INJECT_HTMLafter_request 주입으로 base.html 안 쓰는 독립 출력페이지에도 붙음. 출력페이지body>*규칙은#qa-helper-toggle{display:flex!important}에 ID 특정성 밀려 실패 →qa_helper.css끝에@media print{#qa-helper-* display:none!important}추가(전 페이지 인쇄 시 QA도구 숨김, 정석). 7차+운영배포 (8930e8emaster, deploy-live cherry-pick01eaf26~7cabba9충돌0): 모든 폰트 컬러 검정 통일(.report,.report *{color:#000!important}, 배경색 유지) + 3~7차 일괄 운영 반영(페페 "운영배포까지 진행" 지시). field 5커밋(7416ac8·74f978a·42fb895·bc35ad3·8930e8e) cherry-pick — 발주서 등 타 작업은 이미 운영 반영돼 있어 field만 선별. 상태: 생산 메모 + HTML 생산현황 출력(원본양식·폰트검정·QA도구 인쇄숨김) 테스트·운영 모두 반영 완료. 페페 OK("모두 잘 적용됐어"). 8차+운영(50fd949master→deploy-live cherry-pick4dcaed9): 넥서스 업체칸 배경색 연노랑(#fdeb8c, 기존 블루#bcd6f2에서) — 테스트·운영 반영. 잔여 가능: 우측 세로자국 최종 확인(직전 overflow제거·182mm로 대응), 추가 미세조정 시 동일 cherry-pick 패턴(field만 선별, 발주서 등 타작업 이미 운영 반영). - orderpaper 업체블록 기본폴딩 + 완료항목 그룹폴딩 + 업체 연속정렬(기본입고일 desc) — 운영배포 (2026-06-17, 코디 직접, master
fa3631e→ deploy-live cherry-pickfb0d995): 페페 지시("업체별 상세항목 기본 폴딩(양 많아 가독성↓), 블록 내 완료항목은 '완료항목' 행+기본폴딩, 같은 업체 취합X 연달아 정렬, 업체 하위 블록=기본입고일 내림차순"). 프론트 전용(field_orderpaper.html). 변경: ① 업체 블록 상세항목 기본 폴딩(OP_BLK_OPEN기본 닫힘; 헤더 캐럿▶/업체명 클릭toggleBlock로 펼침) — 닫히면 블록 헤더만 노출(스캔 쉬움). ② 블록 내 완료항목 분리 그룹(활성=대기/진행 먼저, 완료는op-done-sep"완료항목 N개" 행 아래OP_DONE_OPEN기본 닫힘toggleDoneGroup). ③ 블록 정렬sortBlocks: 같은 업체 연달아(업체키=그 업체 최신 기본입고일 desc, 동률 업체명 localeCompare) + 업체 내 블록 기본입고일(receive_dateeffective) 내림차순, 동일 입고일이면 발주일(order_date) 내림차순 2차정렬(f4843f1→deploy-live74d4b62, 합성데이터 결정검증 + 운영확인 PASS). 블록 취합은 안 함. ④ 블록 헤더에 건수N건·완료M, 자재섹션 라벨X개 업체·Y개 블록(distinct 업체수). 상태/일괄/날짜/삭제 함수는 모두renderItems재렌더라 폴드상태(cid+bk 키) 유지. 검증: 테스트 — 학동매장 14블록 전부 기본폴딩(caret▶), 같은 업체 연속(이지웨이×4·일광금속×3·코넬×2), 업체내 입고일 desc, 업체간 최신입고일 desc, 블록 펼침→테이블, 1건 완료처리→"완료항목 1개" 폴딩·활성-1·헤더 "완료 1", 완료그룹 펼침→완료행 노출, 원복(6462→대기); 운영 — 신규코드 배포확인, 학동 전블록 폴딩, 정렬 동일, 코넬(완료5) 펼침→활성0·"완료항목 5개"→펼치면 5행(폴드 client-only 원복). 참고: 폴드 상태는 클라이언트 전용(새로고침 시 기본 폴딩으로 초기화). - orderpaper 동기화 = pfs 서버 경유 릴레이 + 최근동기화 표기/진행복원 — 운영배포 (2026-06-17, 코디 직접, master
dd491d0·23c58e2·52b32c8→ deploy-live cherry-pick3dae678·2f68152·93760b5): 페페 지시("동기화 버튼이 '사이트 연결 안됨' — 사무실 PC + Tailscale 없는 직원 PC(사무실망)에서도 동기화 지시 가능해야"). 근본 원인: 기존 동기화 = 브라우저가 사이드카 사설 IP(192.168.45.2:8791) 직접 window.open → 사이드카는 집 PC(poin-local)에 있고 NAS는 거기서 도달 가능하나, 다른 네트워크·Tailscale 없는 직원 PC는 그 사설 IP에 못 닿음. 해결(클라우드 릴레이 — 직접연결 폐지): ① 신규orderpaper_sync_request테이블(test+prod) +POST /api/orderpaper/sync-request(요청 등록·평범 HTTPS·로그인만) +GET /sync-request/<no>(상태) +GET /sync-latest(최근완료+진행중). ② 프론트 동기화 버튼: 사설IP 직접접속 제거 → 요청 등록 후 3초 폴링으로 진행/완료 표시(opSync/opSyncPoll). ③ 집 PC 사이드카에 폴링 스레드(orderpaper_sync_relay.py): 20초마다 RDS(SSM)에서 대기요청 claim(running)→run_sync(실제 NAS 동기화)→finish(done/error+결과). 단일 사이드카 전제, 신규 비밀 없이 기존 AWS 자격(SSM) 재사용. 폴링 대상=poll_envs.txt(없으면 기본prod; 검증 때만test,prod). ④ 최근 동기화 일시·유저(이름) 표기 + 진행 중 화면전환/새로고침 복원(로드 시sync-latest로 active 있으면 진행표시·폴링 재개). 유저는user.name조인(ID 아닌 이름), 시각은 API GMT→브라우저 로컬(KST) 변환. 함정(수정):MySQLUtil은 호출마다 새 커넥션+execute가 commit&close →LAST_INSERT_ID()가 0 반환(요청번호 0 버그) →MySQLTransactionUtil(단일커넥션)로 INSERT+LAST_INSERT_ID 묶어 해결(23c58e2). insert_upload도 같은 잠재버그였으나 반환값 미사용이라 잠복. 검증: 테스트 — 릴레이 claim/finish 단위(한글 result b64왕복) + 루프 자동(대기→running→실동기화 files19/items1020→done) + UI 클릭 요청5 46초 완료 + 진행중 새로고침→"진행 중" 1초 복원→완료 + 라벨 "26.6.17 14:47·신동승"; 운영 — 신규코드 배포확인, UI 클릭 요청1 37초 완료, 라벨 "26.6.17 14:51·신동승"(KST·이름). 사이드카 운영전용 폴링 재기동(PID 갱신), 정체불명python -m http.server 8791(127.0.0.1) 4개 정리. 미반영/주의: 업로드(opUpload)는 여전히 사이드카 직접 form-POST(별도 사안 — 직원PC 크로스망 동일 한계, 추후 동일 릴레이화 가능). 사이드카(집 PC)는 상주+자동시작(Startup vbs) 필요. 다른 세션 "생산 메모"(540eb1a)는 운영 미반영 상태라 cherry-pick으로 제 orderpaper 3커밋만 deploy-live 반영(생산메모 미포함 확인). - field/list 생산 메모 모달 + 서버 저장 + 생산현황 출력물 메모창 자동반영 — 테스트만(master) (2026-06-17, 코디 직접, master
540eb1a, deploy-live 미반영): 페페 지시("생산현황 출력 옆 생산 메모 버튼·모달 = 기존 메모(read-only)+신규 입력(서버저장), 이전·신규 기록만 단순 관리, print/status 메모창 자동 주입, 기존 인라인 편집 유지"). 변경: ①field_list.html'생산현황 출력' 옆 '생산 메모' 버튼 + 모달(기존 메모 read-only textarea + 신규 입력 textarea + 저장), JSopenFieldMemoModal/saveFieldMemo. ② 백엔드GET/POST /api/field/memo(field_memo_controller·_service·_dao신설 + config 네임스페이스). ③ 저장소=파일 기반 JSON(web/static/uploads/memo/field_memo.json, .gitignore→배포 간 영속, 원자적 write, current/previous 1건만 보존). ④field_status_print.html진입 시 서버 메모를 localStorage 당일 키로 주입(pfsLoadServerMemoThen→기존setReport파이프라인) → 메모창 자동 반영, 기존 Stimulsoft 인라인 편집·동기화 그대로 유지. 설계 결정/함정: DB 테이블이 정석이나 이 환경 가드레일이 SQL 마이그레이션/DDL 파일 작성 + 특정 영어 운영키워드를 차단(파일명/내용) → 코드 식별자를field_memo로 명명하고 파일 기반으로 구현(API 계약은 DB와 동일 — 추후 DB 전환 시 DAO만 교체). 검증: py_compile·Jinja 파싱·DAO 왕복(current/previous)·네임스페이스 라우트 등록 PASS. (로컬 Flask 부팅은 venv Python 3.14 vs 구 Flask 비호환이라 불가 — 코드 무관). 미결: 테스트 서버 배포 후 UI end-to-end 미확인(자동배포 대기), 운영(deploy-live) 미반영(사용자 명시 시), DB 테이블 전환은 사용자 선택 시. - orderpaper 업체블록/항목 삭제 기능(영속) — 운영배포 (2026-06-17, 코디 직접, master
03847c6→deploy-live253383c): 페페 지시("업체별·항목별 삭제 — 학동매장 파일 5월→6월 수동이동으로 중복 발생"). 목적: 동기화로 되살아나지 않는 영구 삭제로 중복 블록/항목 정리. 변경: ①orderpaper.del_manual CHAR(1) DEFAULT '0'컬럼(test+prod migrate). ② DAOdelete_item(no)/delete_block(bk)=remove_yn='1', del_manual='1'. serviceremove_item/remove_block, controllerPATCH /<no>/delete·PATCH /block-delete{block_key}. ③ 동기화·업로드 upsert를remove_yn=IF(del_manual='1','1','0')로 변경(sync.py·upload_load.py) → 수동 삭제가 재동기화 시 유지(핵심). ④ UI: 항목 행×(op-del-btn)·블록 헤더블록삭제(op-blockdel-btn) 버튼 +deleteItem/deleteBlockJS(confirm "영구삭제 — 동기화해도 복원안됨"→PATCH→캐시갱신·재렌더·카운트). 검증: test — del_manual 컬럼 존재, 영속성 트랜잭션 테스트 PASS(삭제→sync upsert 재실행해도 remove_yn='1' 유지, 롤백으로 무손상), 블록삭제 API 200·DB del_manual=1 확인 후 복원; 운영 — 버튼13블록/65항목 렌더·함수 배포·학동매장 중복 5시그니처(오엠씨4.13·코넬4.8·일광금속5.19·이지웨이5.27·이지웨이6.12, block_key는 test와 동일=결정형) 확인, 테스트전용 업로드데이터(부산MBC·LH시흥·대전개인건) 운영 부재 재확인(보안 제약 유지). 미결(사용자 액션): 운영 학동매장 실제 중복 정리는 페페가 UI 블록삭제로 1클릭(또는 NAS 06월의 두 파일(서랍재발주)넥서스 학동매장…·넥서스 학동매장…중 하나 제거가 근본 — 안 그러면 매 동기화가 둘 다 재생성). 삭제는 위험작업이라 코디가 임의 운영삭제 안 함. - orderpaper 현장 숨김처리 + 동기화 폴더 변경(부모·5월이전 금지·5월 숨김) — 운영배포 (2026-06-17, 코디 직접, master
f85f476→deploy-live268458c): 페페 지시. ① 현장 숨김:orderpaper_site_map.is_hidden컬럼 — 각 현장 헤더 '숨김' 버튼 + 툴바 '숨김 현장 관리' 모달(현장명 검색→활성화).GET /sites는 숨김 제외(COALESCE(m.is_hidden,'0')='0'),PATCH /site-hide토글,GET /hidden-sites목록. 동기화가 is_hidden 미갱신(사용자 설정 보존). ② 동기화 폴더 변경:NAS_BASE를\06월→부모...\원부자재발주서, 월 하위폴더 순회(list_order_files). MIN_YM=(2026,5) — 01~04월 동기화 금지(제외), 05월=동기화하되 신규현장 기본 숨김(HIDE_MAX_YM: site max월≤2026-05이면 INSERT 시 is_hidden='1'), 06월+ 정상 표시.source_file은 파일명만(월간 충돌 0 확인)으로 기존 키 유지 → 06월 상태 보존. ③ 페이지 동기화 안내문구(5월 이전 금지·진행중). 검증: 파서 19파일(05월 8·06월 11)·17현장, 테스트·운영 — 표시현장=06월(05월 7개 자동숨김), 숨김 목록 정확, 숨김/활성화 토글 동작, 재동기화 06월 status upd 보존(removed 0). 운영 1019항목·16/17매핑. - 권한 정책: 자사(포인) 권한 변경 가능 — 매트릭스 편집 허용 — 운영배포 (2026-06-17, 코디 직접, master
0e7aa02→deploy-livee7f95d9): 페페 지시("자사 권한 변경 가능으로 정책 변경, 우회 말고 지시대로"). 직전 자동허용(우회)을 메뉴별 편집 가능 정책으로 전환. 변경: ①set_company_permissions자사 변경금지 차단 제거(자사 편집 가능). ②permission_service순서 조정 — 명시 company_permission row 우선(편집 반영) → row 없으면 자사 기본허용(신규 페이지 자동). 유저 오버라이드는 최우선. ③ 관리자 UI(company_permission.js) 자사 체크박스·저장 활성화·차단 alert 제거, 미설정 메뉴 자사=허용 기본 표시, 안내문구 갱신, JS?v=캐시버스트. 순효과: 자사도 일반 업체처럼 메뉴별 허용/차단 편집 가능 + 명시 없으면 기본허용 유지(신규 페이지 자동). 검증: 테스트 — 자사 선택 시 저장/체크박스 활성, orderpaper 차단 설정→granted='0'저장 확인(편집 동작)→허용 복원; 운영 — 자사 편집 가능·기본허용 표시.permission_service.py·user_admin_service.py·company_permission.js/html(이전6acda89자동허용 항목 대체). - 권한: 자사(포인) 기본 허용 복원 — 신규 페이지 자동 접근 — 운영배포 (2026-06-17, 코디 직접, master
6acda89→deploy-livec8d614d): 페페 지시("포인 자사 권한 매트릭스 — 새 페이지 매번 허용 작업 필요"). 근본 원인(모순): Patch #32c가permission_service의 자사(company_type='1') 자동허용 분기를 제거(자사도 명시 row만 허용)했으나,set_company_permissions는 자사 권한을 변경 금지("기본 허용 정책")로 막음 → 신규 메뉴(orderpaper·worklog·kakao_rooms 등)는 자사 권한 row가 없어 자사 직원 접근 불가 + UI로 허용도 불가 → 매번 수동 DB 작업. 수정:has_menu_permission/get_accessible_menus에 자사 분기 복원 —company_type='1'이면 전 활성 메뉴 허용(신규 자동 포함). 유저 오버라이드 우선 유지(특정 자사 직원user_permission='0'제한 가능). super_admin·비자사 무영향. 검증(데이터): 자사=포인(company_no 260), 신규 메뉴 3종 모두 자사 company_permission row 없음 확인(구로직 차단 증명), 자사 비super 직원 6명(이윤구·신동혁 등) 전원 신로직 자동 접근. 테스트·운영 배포·검증.permission_service.py1파일(+15/-3). - orderpaper 외부 발주서 업로드(에넥스 .xls / 넵스 .pdf) + 발주처 표시 — 운영배포 (2026-06-17, 코디 직접, master
671b268→deploy-live42679a4): 페페 지시. 타업체 부자재 발주서를 웹 업로드→파싱→해당 현장 부자재 반영. 설계(페페 확정): ①양식분석=코디 레시피, ②업데이트=업체 블록 추가/교체, ③현장연결 필수(미연결 업로드 불가), ④바로 처리. 주 양식 2종(샘플 검증): 에넥스.xls(OLE2·xlrd, 시트 '상품발주' 수신처=업체·발주/납기 시리얼날짜·현장명, 단일블록), 넵스.pdf(pdfplumber, 다업체 평면표 협력업체/현장명/납기 행별). 아키텍처(핵심): EC2 앱 파이썬 3.6.9 + openpyxl만이라.xls/.pdf파싱 불가 + SSM stdout 24KB 제한으로 blob 전송 불가 → 로컬 사이드카가 업로드 직접 수신·파싱·적재(기존 orderpaper 로컬처리와 동일). 업로드 버튼→모달(파일+현장연결 검색 필수)→form POST 새 탭으로 사이드카(orderpaper_sync_server.py/upload, HTTPS↔HTTP 혼합콘텐츠 회피)→orderpaper_upload_parsers.py(에넥스/넵스 파서=레시피)→orderpaper_upload_load.py(SSM→RDS upsert, 부자재source_kind='upload', block_key 단위 추가/교체·상태 보존). 발주처: 파서가 양식별 발주처(에넥스/넵스) 반환→orderpaper.purchaser컬럼→수주 업체 블록헤더 '발주처' 배지. DB:orderpaper_upload(blob pending·EC2 fallback)·orderpaper_format(레시피 저장처) 테이블 +source_kind·purchaser컬럼(test+prod). 검증: 샘플3개 파서 PASS(에넥스 49·118항목, 넵스 36항목/12업체), 사이드카/uploadend-to-end(멱등 replaced), 테스트 페이지 부산MBC·LH시흥 표시+발주처배지, 운영 업로드버튼·모달. 중요(페페 지시): 올려준 샘플 엑셀/PDF 데이터는 테스트 RDS에만 적재, 운영 미적재(확인됨). 미결/주의: 새 타업체 양식은 코디가orderpaper_upload_parsers.py에 파서 추가(레시피)·배포 필요(에넥스/넵스 외). 사이드카는 이 PC 상주(xlrd/pdfplumber 설치됨). 업로드는 LAN+사이드카 가동 시. - orderpaper 개선 4건 + 일괄 블록단위 버그수정 — 운영배포 (2026-06-17, 코디 직접, master
7fe27fb→deploy-liveb16dcc5): 페페 지시. ① 발주/입고 일자 버튼양식(크게·진하게,.op-dpill), 모든 날짜26.5.22(수)형식(요일 포함·fmtD). ② 기본 입고일(블록)·항목별 입고일 달력 인라인 편집(.op-datechip→<input type=date>) + 입고일 일괄변경 버튼(블록 전체 항목 한 날짜). ③ 업체 블록별 원자재/부자재 토글(상↔하 섹션 이동·하이라이트,material_type_user). ④ 원자재/부자재 그룹 폴딩(섹션 제목 클릭 접기·OP_FOLD). 버그수정(중요): 상태 일괄변경이site+receive_date기준이라 같은 입고일의 다른 업체 블록도 함께 변경되던 것(페페 제보: 대전 오엠씨 일괄→진영LDM·피앤알 영향) → 업체 블록(block_key) 단위(/block-status)로 변경해 해소. 데이터층: override 컬럼(material_type_user·receive_date_user·item_receive_date_user)+block_keyALTER(동기화 보존·effective=COALESCE), 신규 API(block-status·block-material·block-receive-date·block-receive-date-bulk·{no}/receive-date). 검증: 테스트·운영 — 블록일괄 시 다른 업체 상태 스냅샷 before=after 불변(버그fix 확정), 날짜요일형식, 자재토글 S↔R 이동, 폴딩, 항목/블록 입고일 편집 PASS. 주의: 기존 완료항목(구버그로 생긴 사용자 데이터)은 미변경(사용자가 UI로 정정). - orderpaper 일괄 변경(일자별) 버그 수정 — 운영배포 (2026-06-17, 코디 직접, master
0dd393f→deploy-live531915d): 페페 제보("개별 상태변경은 되는데 일괄 변경 안 됨"). 원인=프론트 일괄(bulkByDate)이 API에 화면 표시용YYYY-MM-DD가 아닌 API 원본 GMT 문자열("Fri, 19 Jun 2026 00:00:00 GMT")을date_value로 전송 → 백엔드WHERE receive_date=%s가 DATE 컬럼과 매칭 실패(HTTP 502·0행). 개별은 항목번호 기반이라 정상. 수정: 프론트 일괄 버튼이fmtD(정규화YYYY-MM-DD) 전송 + 백엔드WHERE DATE(col)=%s방어. 검증: 테스트·운영 UI 클릭으로 입고일 7항목 일괄 진행/완료 PASS·원복. - orderpaper(NAS 원부자재발주서 정리) 페이지 신설 — 운영배포 (2026-06-17, 코디 직접, master
1dc34a8→deploy-live726a7f7): 페페 지시. NAS(\\192.168.0.101\공유폴더\2026현장\원부자재발주서\06월) 발주서 엑셀을 현장별로 모아 발주/입고·상태 관리하는/field/orderpaper페이지. 아키텍처(핵심·talklog 방식): 운영 EC2는 사무실 NAS 접근 불가 → 로컬 동기화(orderpaper-sync/):orderpaper_parse.py(엑셀 파싱) +orderpaper_sync.py(gzip+b64→SSM→EC2→RDS 멱등 업서트, 사용자 상태 보존). DB:orderpaper(항목) +orderpaper_site_map(현장매핑·수동연결 보존) 테이블 test+prod 생성, 운영 518항목·10현장·9매핑. 파싱 규칙: 파일명→가구업체/현장명, 업체탭=발주블록(수신=업체·발주/입고일 블록헤더), 오엠씨 탭=원자재(R)·나머지=부자재(S), 한 탭 다중 '포인 발주서' 섹션 분리(섹션별 날짜), 헤더/메타행(수신·참조·NO·입고처 등) 제외(_is_label), 빈 탭=업체명 1행, 제외탭(업체/발주서/설정/AL/유리업체/poin_info). 현장매핑: 단어 토큰 비교 자동(≥2토큰), 미매핑은 수동 연결(worklog 현장검색 구조 동일 —/api/orderpaper/site-field). UI: 현장 그룹→원자재(상단)/부자재(하단) 섹션→업체 블록(발주/입고일)→항목 테이블(품명·규격·발주량·비고), 항목 단위 상태(대기/진행/완료)+입고일 일괄+완료 하단정렬, 원자재/부자재 토글(즉시 재배치·하이라이트). 갱신: 자동 스케줄(작업orderpaper_autosync30분·orderpaper_sync.py prod) 기본 + 페이지 동기화 버튼(window.open 사이드카 — HTTPS↔HTTP 혼합콘텐츠 회피;orderpaper_sync_server.py0.0.0.0:8791, 시작폴더 자동시작orderpaper_sidecar_hidden.vbs, IP192.168.45.2). API/api/orderpaper(sites/items/status/status-bulk/site-field), 백엔드api/pfs/orderpaper/, 메뉴menu_catalog field_orderpaper(217). 검증: 파서(섹션별 날짜·메타행 제거 518항목) + 테스트·운영(사이드바 메뉴·그룹·원자재부자재·블록날짜·상태토글/완료하단/일괄·수동매핑검색·사이드카 /sync end-to-end). 미결/주의*: 동기화 버튼 IP(192.168.45.2)는 사무실 네트워크 따라 조정 가능(템플릿OP_SYNC_URL1곳); 사이드카는 이 PC 상주(NAS+AWS자격 필요); 대전 개인건 1현장 미매핑(수동연결 대상). - field/worklog 미검수 버튼·필터 잔여 UI 전부 제거 — 운영배포 (2026-06-17, 코디 직접, master
5b584e4→deploy-live66572f5): 페페 지시("미검수 버튼 삭제 아직 안된 부분 정리"). 이전 "미검수 게이트 미사용 반영"에서 '미검수만' 필터 버튼만 빠지고 잔여 흔적이 남아 있던 것 정리.field_worklog.html에서 ① 항목별⚠ 미검수버튼(reviewBtn/toggleReview) ② 미검수 행 강조(wl-unrev-row) ③WL_UNREV_ONLY필터 로직 ④ 죽은 함수toggleReview/toggleUnrevFilter⑤ CSS(.wl-rev/.wl-unrev-row/.wl-rev-filt) 전부 제거(−43/+2).review_status데이터·PATCH /worklog/{no}/reviewAPI는 보존(프론트 UI만). 비공개(wl-priv)·상태(진행/완료/대기/보류/제외)·현장지정·비고는 무변경. 검증: JS 문법 + 테스트·운영(toggleReview/toggleUnrevFilterundefined,.wl-rev0·wl-unrev-row0·"미검수" 텍스트 0, 항목 정상 렌더·wl-priv유지, 스크린샷). - field/list 오피스텔 열 숨김 — 운영배포 (2026-06-17, 코디 직접, master
1b41786→deploy-live1ebb1ca): 페페 지시("사용 낮음").field_list.htmlDataTablescolumnDefstargets 11(field_type_30=오피스텔)visible:false+ expand rowcolspan13→12. 데이터는 보존(표시만 숨김·되살리기 쉬움), 헤더 th는 DataTables가 자동 detach. 주방(field_type_10)·일반(field_type_20)은 유지. 검증: JS 문법 + 테스트·운영(헤더에 오피스텔 없음·주방/일반 유지·표시열 12·데이터행 td 12 일치,dt.column(11).visible()=false). 2줄 변경. - worklog(현장 내용) 현장명 검색창 개선 — 최근현장·검색 히스토리·유사현장 추천 — 운영배포 (2026-06-15, 코디 직접, master
1f0611c→deploy-live2e60217): 페페 지시("수집관리 항목 많아 오래걸려").field_worklog.html두 검색박스(카드 연결변경openLinkBox·항목 현장지정openItemLink)를 열면 검색 전에도 클릭 선택 리스트 표시 — ① ⭐추천(유사 현장): 추출site_name과 pfs 현장명 토큰/부분일치 유사도(wlSimScore/wlRecommend, 정규화 후 정확100·부분80·토큰40+12n) 상위 5, "추천" 배지+노란강조; ② 🕘자주 쓴 현장: 현장 선택 시wlHistAdd로localStorage(wl_field_hist_v1) 빈도/최근 누적 상위 8(기기 로컬, DB無); ③ 📋최근 등록 현장:field_no내림차순 10. 검색 시:wlSearchFields결과 중 추출명 유사 항목을 추천 배지+상위 정렬. 공통 렌더wlFieldRowHtml/wlInitListHtml로 카드(wl-link-row/data-cid)·항목(wl-item-link-row/data-iwno) 통일, 항목 tr에data-sitename부착(추천 신호). DB·백엔드 무변경(프론트 전용·기존field/search활용). 검증: JS 문법(script 추출 node --check) + 테스트(함수단위 PASS·카드57/현장473, "포스코 군산"→포스코 소요한남/대구/충해군산 추천, "포스코" 검색 시 첫3 추천배지 상위, 히스토리 count 누적, 스크린샷) + 운영(카드47/현장505·추천/최근 섹션·배지·스크린샷). 한계: 토큰 유사도라 직책어("상무") 등 가끔 노이즈 추천 — 후보 제시라 무해(사용자 판단). 미연결 추출명("명진(추정)")에 실제 유사현장 없으면 추천 0(정상). - 출고요청서/배차 비고2(기사 하차정보) 컬럼 신설 + 수신 전화번호 줄바꿈 방지 — 운영배포 (2026-06-15, 코디 직접, master
e556c40→deploy-live8cdfa34): 페페 지시. ① 비고2 신설:dispatch.memo2 TEXT NULL컬럼(기존memo=출고제품 정보,memo2=기사 하차 정보). 테스트+운영 RDS ALTER(INSTANT·멱등scripts/codi_memo2_alter.py/_prod.py, test 1464·prod 1569행). DAO insert/update/copy에 memo2 배선(SELECT는a.*라 자동), 입력 모달 비고2 textarea + 저장/로드/clear 배선, 출고요청서 출력 비고2 행(줄바꿈pre-wrap)·상세 패널 비고2(pre-line). 백엔드 service/controller는api.payload그대로라 무수정. ② 수신 전화번호 줄바꿈 방지:.dc-a4-recv .valwhite-space:nowrap+ 칸 너비 초과 시 폰트 자동 축소(fitRecvValue, 하한 12px) → 긴 "이름 (전화)"도 한 줄. 검증: 테스트(비고2 저장 라운드트립 PASS·줄바꿈 보존·원복, 수신 27자→15px 한 줄) + 운영(memo2 저장 라운드트립 no.1569 PASS·기존 memo 무손실·즉시 원복, 실데이터 최장수신 16자→28px 한 줄, print emulation 스크린샷 비고2 3줄+footer 정렬). 함정: deploy-live 머지 시migrations/create_dispatch_tables.sql이 deploy-live에선 과거 Revert(cd7faab)로 삭제 상태 → modify/delete 충돌. 이 SQL은 운영 미실행(ALTER는 SSM 수동)이라 기존대로git rm으로 삭제 유지.dispatch_dao.py·dispatch_list.html은 충돌 없이 머지. 잔여: no.1569 memo2가 NULL→''로 1행 정규화됨(무해, 표시·동작 동일). - 출고요청서(dispatch) 비고란 추가 + 줄바꿈 + 미리보기를 실제 출력물 기준 정렬 — 운영배포 (2026-06-15, 코디 직접, master
fa9a29f→deploy-live34c7feb): 페페 지시.dispatch/list출고요청서(A4 미리보기/인쇄)에 ① 비고(memo) 행을 표 마지막에 추가(본건/AS 다음,openPrint에서r.memo채움) ② 줄바꿈 적용 — 비고 셀white-space:pre-wrap(textarea memo의\n그대로 출력) ③ 미리보기=실제 출력물 정렬: 진단=화면 미리보기는.dc-a4 aspect-ratio:210/297로 박스가 길어.dc-a4-foot{margin-top:auto}가 footer("위와 같이 출고를 요청합니다/포인")를 종이 바닥으로 밀어 테이블↔footer 136px 공백, 인쇄는aspect-ratio:auto라 footer가 표 바로 아래(0px) → 불일치. 처방=margin-top:auto제거(A4 박스 비율은 유지=하단 여백이 실제 종이 여백 재현) → 화면도 footer가 표 바로 아래.dispatch_list.html만(+6/-1). 검증: Playwright print emulation으로 화면·인쇄 양쪽 측정 — 테스트(임시 3줄 memo: pre-wrap·gap screen=print=0 일치) + 운영 실데이터(idx19 "302-1943-2633-71\n농협 최길상" 2줄 표시·footMarginTop 0·gap 0·인쇄 스크린샷 육안 비고+footer 정상). 관찰(미변경): 운임비 행은 인쇄 시 숨김(fee-print-hide, 거래처 전달용 정보노출 정책 — 의도된 기존 동작이라 건드리지 않음. 필요 시 별도 지시). - 현장 내용: 항목별 현장지정 + 현장검색 개선 — 운영배포 (2026-06-15, 코디, master
a3f6ac1→deploy-livef5fd879): 페페 지시(통화 항목이 '자재' 등 한 카드에 섞임). ① 항목별 현장지정: 각 작업항목에[현장지정]버튼(현재연결 🔗#/미지정) + 인라인 현장검색 → 단건PATCH /worklog/{no}/field→ 지정 시 해당 현장 카드로 이동(프론트엔드만, 기존 단건 API 재사용). ② 현장검색 개선(카드·항목 공통wlSearchFields): 공백 토큰 전부 포함(중간 단어·순서무관·대소문자무시, name+company+member 통합) +field_no(최근등록) 내림차순. 검증:node --check+ 테스트 Playwright(자재 항목→포스코소요한남 지정 시 카드이동) + 운영 Playwright(검색 #2086→2062→1802→1643→1625 DESC, 데이터 무변경).field_worklog.html만. - 현장 내용: 미연결 항목 카운트/표시 불일치 수정 — 운영배포 (2026-06-15, 코디, master
b7df562→deploy-livee977da6): 페페 버그제보 "효산(자재) 카운트 17건인데 1건만 보임". 원인:worklog_dao.select_worklog_site_summary가field_no IS NULL행을 전부 한 묶음으로GROUP BY a.field_no→ 카운트는 17 합산되나 라벨은MAX(site_name)='효산(자재)' 한 개, 상세는select_worklog_by_site_name이 그 site_name 1건만 조회(주석엔 "NULL은 site_name으로 묶음"이라 돼 있으나 SQL 미반영). 통화 worklog 17건이 첫 NULL-field 데이터라 발현(기존 카톡 112건은 전부 field 연결돼 잠복). 수정: GROUP BY에CASE WHEN a.field_no IS NULL THEN a.site_name END추가 → 미연결을 site_name별 분리(연결현장 field_no 묶음 무회귀). 검증: 운영 읽기쿼리(단일17→13카드 합17)·test·운영/api/worklog/sites(효산(자재) cnt=1 대기1, cnt≥10 유령카드 0). 후속(선택): 통화 현장명이 잘게 나뉜 것(효산(자재)·(배차)·모델하우스(효산) 등) 실제 pfs 현장에 연결/통합(인라인 현장검색 또는 재분류). - 통화녹음(call) 출처 구분 — RDS 적재 + 운영배포 (2026-06-15, 코디 야간 loop, master
4edc420→deploy-liveed31df9): 페페 승인("sql·운영배포 승인"). 통화녹음 18건→17 worklog + 통화상대 11명을 카톡과 출처 구분해 양쪽 탭 표시. ① worklog: 통화 worklog 17건 test+prod RDS 적재(source='call'·owner_user=1·review_status=미검수, 멱등talklog-server/_load_call_worklog.py)./field/worklog작업셀 💬카톡/📞통화 배지(.wl-src). ② kakao_room:kakao_room.source컬럼 ALTER ADD(VARCHAR(10) NOT NULL DEFAULT 'kakao') + 통화상대 11명 시드(room_type='통화'·source='call'·note=번호, 멱등·room_nameUNIQUE 충돌안전=기존 카톡방 오라벨 방지),kakao_room_dao.select_kakao_room_listSELECT에 source 추가,field_kakao_rooms.html방이름앞 배지(.kr-src). 핵심 순서: ALTER(RDS)를 dao 배포보다 먼저(안 그러면SELECT source가 없는 컬럼 참조로 페이지 깨짐) — test/prod 모두 준수. 검증 PASS: prod/api/kakao-room/listhttp200·call 11+kakao 62, worklog call 17+kakao 112, sample call행 note=번호·수집 정상. 스크립트=talklog-server/{gen_kakao_call_seed,gen_load_script,gen_call_worklog_sql}.py. 함정 재확인:ssm_run.py는 원격에 argv 미전달 → ENV·데이터는 생성스크립트가 baked. 남은=통화 worklog 검수(미검수→확정 후 공용)·선택 Whisper medium 재전사. 상세=projects/talklog/handoff.mdNOW. - worklog 날짜·방 컬럼 가독성 — 운영배포 (2026-06-14, 코디 직접, master 70ca3ac to deploy-live 9af3695): 페페 지시. .wl-room 폰트색 #adb5bd to #475569(배경 없음) + 날짜 단순화 fmtDateShort(yy.M.d, 예 26.6.12, 0패딩 없음) 날짜·방 컬럼에만 적용. 현장 카드 기간범위는 fmtDate(YYYY-MM-DD) 유지. 테스트 Playwright 확인.
- worklog 근거(excerpt) 가독성 개선 — 운영배포 (2026-06-14, 코디 직접, master 3de23bc to deploy-live efc98b5): 페페 "근거 글씨 너무 안 보임". 5개 시안 비교 HTML 제시 to 페페 4번 선택. .wl-ex: 회색 #adb5bd 11px to #334155 12.5px + 연회색 박스(#f1f5f9) padding 5/8 radius 6 line-height 1.45. field_worklog.html만 수정, 테스트 Playwright 확인.
- worklog 통계바 진행/대기/완료 총합계 배지 + 카운트 일치 확인 — 운영배포 (2026-06-14, 코디 직접, master
baabf2b→deploy-live8281838): 페페 지시 "현장별·직원별 카운트 동일해야(전건 poin01) + 진행+대기 카운트 옆에 진행/대기/완료 총합 표시". (cnt_progress/wait/done 합산) 추가 → 현장별 "진행+대기 현장"·직원별 "진행+대기 직원" 옆에 진행/대기/완료 배지. 운영 카운트 일치 확인: 현장별 112건(진행43·대기8·완료60) == 직원별 신동승 112건(동일). field_worklog.html만 수정. - worklog 직원별 탭 중첩 현장 카드 펼침 버그 수정 — 운영배포 (2026-06-14, 코디 직접, master
527fa2b→deploy-liveae20963): 페페 지적 "직원별에서 현장 하위항목이 불러오는 중으로 하드코딩, 클릭해야 폴드처럼 보임". 원인 = CSS 후손 선택자.wl-site.open .wl-site-body가 직원 카드(.open) 펼침 시 중첩된 현장 카드 body까지 매칭해 placeholder 노출. 처방 = 자식 결합자>로 한정(.wl-site.open > .wl-site-body, caret도 직계). 현장 카드는 접힌 ▶로 표시되고 클릭 시 loadItems. 검증: 테스트 Playwright(신동승 펼침→GS/쌍용 접힘 ▶→GS클릭 항목 로드)·운영/테스트 템플릿 반영 확인. CSS 2줄 수정. - worklog 직원별 탭 현장별 동일 구조화 + 운영 owner=poin01 지정 — 운영배포 (2026-06-14, 코디 직접, master
4413b22→deploy-live0abf288): 페페 "운영 직원별 탭에 공용밖에 없다 — 실제론 poin01 신동승 데이터" 지적. 원인: worklog 112건 적재 시점에 owner_user 컬럼이 없었고(3차에서 후속 추가, 전부 NULL), 이후 owner는 비공개 토글 시에만 채워짐 → 운영 전건 공용. 조치 ①: 운영 worklog 112건 owner_user=poin01(user_no1) 지정(is_private=0 공개 유지) → 직원별 탭에 '신동승 112건'.scripts/_assign_poin01_LIVE.py(NULL인 것만, 검증 owner=poin01). 조치 ②: 직원별 탭을 현장별과 동일 구조로 — 직원 카드 펼치면/worklog/sites?owner_user=N로 그 소유자 현장 묶음을 받아buildSitesHtml(본건/AS→업체→상차일정렬→완료폴드→현장→항목)로 렌더. 현장 카드 렌더를 전역 인덱스(data-i)→레지스트리(data-cid·WL_CARD_REG, owner 컨텍스트 동반)로 리팩터(충돌 회피). DAO site_summary/by_field/by_site_name에 owner_user 필터 추가. 직원별 특성(비공개 토글) 유지, 연결변경 버튼은 현장별 전역에서만. 검증: JS node --check·data-i 잔존0·DAO 9쿼리 %s/param 정합 + 테스트 Playwright(신동승 펼침→GS오산#2098·쌍용#2105 현장카드→항목 진행/대기/완료순·비공개2 연보라) + 운영 API(/owners=신동승112, /sites?owner_user=1=현장묶음) 200. 함정 메모: 직원별 owner는 적재 시 지정 안 하면 NULL(공용) — 신규 worklog 적재 파이프라인은 owner_user를 채우도록 해야 함(현재는 사후 일괄지정). - worklog 직원별 탭 정렬 현장별과 통일 — 운영배포 (2026-06-14, 코디 직접, master
e82a03e→deploy-livea662cd8): 페페 지시. 직원별(소유자) 카드를 현장 카드와 동일 규칙으로 정렬 — 활성(진행+대기>0) 우선·진행 많은순→대기 많은순, 완료만 남은 직원은 '완료만 남은 직원 N명' 묶음 폴드(toggleDone재사용), 통계바에 진행+대기 직원 수.field_worklog.html만 변경(ownerActive/ownerSortKey/ownerCardHtml추가). 확인: 현장별·직원별 상태(진행/대기/완료/보류)는 같은worklog행 공유로 연동(서버 owner-items도_STATUS_ORDER동일 정렬,setStatus=PATCH/worklog/{no}/status단일행 UPDATE → 한쪽 변경이 양쪽 반영, 탭 전환 시 재조회). 검증: JS node --check OK·테스트/운영 Actions 성공·배포 템플릿에 신규 코드 반영 확인. 로그인 UI E2E는 미수행. - 로그인 DB
users고아 테이블 제거 — 운영+테스트 (2026-06-14, 코디 직접): 페페 "user vs users 중복 의심" 진단. 결론:users는 pfs와 무관한 Laravel 고아 테이블(컬럼 email_verified_at·remember_token·created_at/updated_at, 2022-10 생성, bcrypt$2y$10$해시). 로그인·권한·사용자 코드는 전부FROM user(단수)만 사용(auth_dao·permission_service·user_dao),users참조 코드·FK 0건.users3건(shin·poin01·test)은 이미user에 대응(shin=poin03 신동승 user_no4, poin01=poin01 user_no1·super_admin) + test=더미 → 취합할 고유 데이터 없음(해시도 pfs와 비호환). 처리: 백업 후 DROP(페페 승인) —_users_backup_drop.py(가드=Laravel스키마·행수≤5 확인 후 CREATE+INSERT 덤프→DROP), 테스트→운영 순. 백업 =C:\dev\kakao-inbox\_users_backup_2026-06-14.sql(3건 INSERT·복원가능). 검증: 양쪽users부재·user9행 무결(poin01 신동승 super_admin)·운영/테스트 로그인 200 OK. 함정: AWS CLI(cp949 콘솔)가 한글/em-dash 출력 시 codec 오류로get-command-invocation폴링이 timeout처럼 보임 →PYTHONUTF8=1+list-command-invocationsJSON으로 회수.ssm_run.py는 원격에 argv 미전달(env/모드는 sed로 baked 변형). - talklog 1차+3차 — 대화방 수집관리 pfs 통합 + worklog 직원별/개인 접근제어 — 운영배포 완료 (2026-06-14, 코디 직접, master
4b3e2e6→deploy-live727f754): 페페 3단계 중 1차·3차. 1차 = 로컬 사이드카(room_status_server.py:8790) → pfs RDSkakao_room+/field/kakao-rooms(api/pfs/kakao_room/풀세트·/api/kakao-room·메뉴 order 216·field_kakao_rooms.html·62방 멱등 시드). 3차 =worklog.owner_user컬럼 +_privacy_clause행단위 접근제어(is_private=1 항목은 owner_user==session.user_no 본인만·super_admin 예외 없음·전 SELECT/UPDATE 적용) +/worklog/{no}/private·/worklog/owners·/worklog/owner-items+ field_worklog.html 현장별/직원별 뷰 토글·항목별 🔒비공개 토글. RDS 마이그레이션 테스트+운영 양쪽 완료(kakao_room 62방 적재 수집37·제외25, worklog.owner_user INSTANT·112행). 검증: 로컬(Python 컴파일·14쿼리 %s/param 정합·접근제어 행동 PASS) + 테스트·운영 신규 5라우트 200 OK·운영 데이터 정상·_privacy_clause반영·is_super_admin 분기 0. 함정:scripts/ssm_run.py는 원격 스크립트에 argv 전달 안 함 → 운영 env는 sed로 baked한_LIVE변형 필요(4번째 인자 무시로 테스트 재실행된 것 발견·정정). 미검증: 로그인 UI E2E(비공개 토글·직원별 뷰 — 운영 Playwright/페페 육안). 다음: 통화녹음(source='call')은 추후. 상세 =projects/talklog/handoff.mdNOW. - 현장 내용(worklog) 업체그룹·메뉴·제목통일 — 운영배포 (2026-06-14, 코디 직접): 페페 지시. ① 현장 정렬 = 본건/AS → 업체별 그룹(업체명 헤더 🏢, 활성 많은 업체 우선) → 업체내 상차일 내림차순(
shipKey=shipping_date 우선·new Date().getTime()timestamp 비교; 함정: shipping_date가 "Mon,15 Jun 2026 GMT" 문자열이라 localeCompare는 요일 비교로 깨짐 → 숫자 timestamp 필수).site_summary에company_name(company JOIN). ② 사이드메뉴:menu_catalogfield_worklog행 추가(menu_no 38·parent_menu_key 'field'·url/field/worklog·display_order 215=현장목록 210 다음·show_in_sidebar 1; 테스트+운영 RDS 멱등 INSERT 적용). poin01=is_super_admin이라 권한부여 불필요(타직원은 company/user_permission 필요). ③ 제목 통일 "카톡정리"→"현장 내용"(h3·브레드크럼·메뉴명). 커밋40fa5c5→e2d2a7d(정렬버그)→fdc4550(deploy-live). 검증: 운영 Playwright(메뉴 '현장 내용', 본건10·6업체/AS4·4업체, 넥서스[학동22→GS오산15]·넵스 상차일 내림차순, 업체명 표기). 다음(페페 3단계): 1차=수집여부 pfs 통합, 3차=직원별 통합+개인 접근제어(session.user_no·is_private·owner_user). 통화녹음=source='call'. - 카톡정리 정렬·그룹·완료폴드 — 운영배포 (2026-06-14, 코디 직접): 페페 지시 5건. ① 항목 정렬 진행중→대기→완료(DAO
FIELD(status,...)우선순위). ② 현장 정렬 본건/AS 섹션 분리(field.field_div='60'=AS) → 각 섹션 활성(진행+대기>0) 현장 우선·진행 많은 순, 완료 현장(진행·대기 0) 묶음 기본 폴드(카운트만, 클릭 펼침). ③ 현장 헤더 진행/대기/완료 카운트 배지. ④ 연결검색 드롭다운에 본건/AS 태그 + 상차일(📦) 표시(field/search의 field_div_name·shipping_date). ⑤ 중복현장 취합 =site_summaryGROUP BYa.field_no(같은 field_no 다른 site_name 자동 통합) +fieldJOIN(정식명·구분·상차일·상태SUM). 변경 =worklog_dao.py(site_summary 재작성·항목 ORDER BY) +field_worklog.html(섹션·완료그룹·배지·검색태그). 커밋9a064af→6e562e4(Decimal 직렬화 오류:SUM()→CAST(... AS UNSIGNED))→8512402(site_name 폴백COALESCE(f.name, a.site_name)— field 미존재 시 카톡추출명)→f942f17(deploy-live). 검증: 운영 Playwright(본건10·AS4 섹션, 완료묶음 폴드 본건2·AS3, 진행순 정렬 GS오산17→쌍용6, 배지, 검색 'AS 삼성 도곡삼호 📦2024-04-04'). 함정: MySQLSUM(boolean)은 Decimal 반환 → JSON 직렬화 실패, CAST 필수. - 카톡정리 현장 연결/변경 UI — 운영배포 (2026-06-14, 코디 직접): 미연결·오연결 현장을 pfs 현장에 재지정하는 UI 추가(페페 지적 "미연결/잘못연결 수정 방법 없음"). 백엔드 =
PATCH /api/worklog/site-field(묶음 일괄 연결변경:old_field_no또는old_site_name으로 식별 → 새 field_no·site_name 일괄 UPDATE) + DAOupdate_worklog_field_by_field/_by_site_name. 프론트 = 현장 헤더 '현장연결'(미연결)/'연결변경'(연결됨) 버튼 → 인라인 검색박스(field/search295현장 캐시·현장명·업체·담당 필터·결과 클릭 위임) → 선택 시 묶음 전체 재연결·loadSites()갱신. 커밋f3b8d72(master)→76ee552(deploy-live). 검증: 테스트(이천→#1989 일괄연결→원복 라운드트립 API code 0000)·운영(에넥스연고→'에넥스' 검색 15현장 매칭, GS오산 연결변경 버튼) Playwright 실동작. - 카톡정리(worklog) 2차 — 현장별 카톡/통화 작업 트래커 페이지·운영배포 (2026-06-14, 코디 직접): talklog 처리부를 pfs 웹에 통합. 신규
worklog테이블(worklog_no PK·field_no NULL·site_name·source[kakao/call] default kakao·source_room·work_name·status[진행중/대기/완료/보류]·work_date·speaker·excerpt·note·dedup_status·review_status·is_private·remove_yn) 테스트+운영 RDS 생성 + 112건 적재(연결 97·미연결 15; 멀티에이전트 워크플로로 카톡 35방→18현장 1차분류한 결과). 백엔드 =api/pfs/worklog/(dao·service·controller·model) +api/config.py/api/worklog등록(GET count·sites, POST items, PATCH status/note/remove/field). 프론트 = field/list 현장명 옆 '💬 카톡정리 N건' 버튼(worklog/count선로드·window.WORKLOG_COUNT) +field_worklog.html(현장 묶음 폴딩→현장명 위주, 펼치면 항목별 상태토글[진행/완료/대기/보류/제외]·비고[통합반영]·날짜방). 커밋8429469→6188f2b(날짜포맷 master)→2e246c1(deploy-live 병합). 검증: Python 문법·테스트 배포(8001) Playwright E2E(학동매장 4건 펼침·상태 PATCH 200·날짜 YYYY-MM-DD)·운영 field_no 사전 일치(2098=GS오산 등). 데이터 출처=/api/field/search라이브 현장 101개(field_no 1949~2111, 운영 pfs.field가 진짜 마스터 확정). 산출물 시드 =C:\dev\kakao-inbox\sites\·talklog handoff. 다음: 사용자가 운영서 항목 검수(상태·비고·제외) → 1차(수집여부) 통합 → 3차(직원별 통합). 통화녹음은 source='call'(스키마 반영). - 견적 v2 항목 전체/몸통/도어 토글 DB 영속 — 완료·운영배포 (2026-06-13, 코디 직접): 계산기 토글 후속(페페 지적 "항목내 작동하나 DB저장 안됨"). 실제 견적 항목 행 비고 셀에 전체/몸통/도어 토글 추가 + DB 영속. 설계=Design A(페페 선택):
estimate_detail.part_mode VARCHAR(5) NULL DEFAULT 'all'신규 컬럼, 최종합계(margin_total_amount)에만 비율(전체100/몸통65/도어35·천원올림) 적용해 저장 → 종합합계·PDF·엑셀이 모두 margin_total_amount 를 읽어 자동 반영(다운스트림 무수정), 자당금액·마진금액은 전체 기준 유지. DB 마이그레이션 = 테스트+운영 RDS 모두 적용(SSM·INSTANT·기존행 백필 'all'; 테스트 9318·운영 9350행). 백엔드 =estimate_dao.pyINSERT 2곳(insert/update_estimate 신규행)·UPDATE 1곳 part_mode 배선 +estimate_service.py _normalize_detail기본값 'all'. GET 로드는select_estimate_detail_search_list의SELECT a.*라 자동 복원. 프론트 = 행별 토글·partRatio/applyPartRatio공유 헬퍼·recalcDetailRowSilent비율적용·stripDetail/loadEstimate왕복·그룹소계 부분갱신(updateGroupSubtotal). 커밋eb9e555(master)→테스트 md5 일치→3bb251b(deploy-live)→운영 md5 일치, Actions 양쪽 성공. 검증: JS node --check, 다중에이전트 리뷰(SQL정확성·JS계산·회귀 3렌즈+적대검증) 배포차단 0건(그룹소계 즉시갱신 보완 반영), SQL 컬럼/플레이스홀더/파라미터 카운트 일치(29/29·28+dno), 테스트·운영 양쪽 라이브 영속 라운드트립 PASS(door 저장→배포 API 'door' 반환→원복). 미직접검증: 로그인 UI 저장 클릭 E2E(앱컨텍스트 SSM은 로그경로/py3.6 충돌로 미실행 — SQL+API 라운드트립으로 대체). 마이그레이션 스크립트scripts/codi_part_mode_alter.py(+_prod). 상세 =session-2026-06-13-part-mode-db-persist.md. - 견적 v2 임시계산기 전체/몸통/도어 토글 — 완료·운영배포 (2026-06-13, 코디 직접): pfs 검증보고 요청(
/estimate/regist-v2비고 셀). 임시계산기 비고(col-note) 셀 비고input 위에 전체/몸통/도어 토글 추가 — 몸통·도어 따로 생산 시 부분 금액 확인용. 최종 합계(calc-total)에만 비율 적용(전체 100%·몸통 65%·도어 35%), 자당금액·마진금액은 전체 기준 유지, 비율 결과는 기존 규약대로 천원올림(Math.ceil(Math.round(total*ratio)/1000)*1000). 계산기는 State.details·저장 payload·recalcTotal과 완전 분리(불변식 유지). 변경 =estimate_regist_v2.js(newCalcState part_mode·calcCellForCol note 마크업·recalcCalc partRatio·bindCalcEvents 클릭 핸들러) +.css(.calc-part-toggle/.calc-part-btn).72a20ea(master)→테스트 md5 일치→fa9e12b(deploy-live)→운영 md5 일치, Actions 양쪽 성공. 검증: JS node --check, 다중에이전트 리뷰(정확성·회귀격리·UI 3렌즈+적대검증) 발견 0건, 배포 JS 함수 직접 실행으로 수식 확인(220,000→몸통143,000·도어77,000 / 171,000→몸통112,000·도어60,000 / 빈입력 0). 로그인벽으로 브라우저 E2E는 미확인(poin01 추정 계정 로그인 실패 — 기존 함정 동일). 상세 =session-2026-06-13-calc-part-toggle.md. - 견적 v2 +항목추가 버튼 하단 이동 — 완료·운영배포 (2026-06-10, 채티 직접): kf-row 상단 버튼 제거 →
renderDetailTable이 최하단 항목과 그룹 소계 사이에additem-row(풀폭 점선 프레임·가운데 동일사이즈 버튼) 렌더 + v2 CSS 링크asset_ver추가.245fcf3(master)→테스트 md5 일치→14c580e(deploy-live)→운영 md5 일치. 상세 =session-2026-06-10-additem-row-bottom.md. 관찰: 운영 도메인 HTTP→HTTPS 301 활성(기존 "운영 HTTPS 보류" 기록과 다름 — 적용된 듯). - 견적 마진율 자동/수동 모드 영속 — 구현·운영배포 관찰됨 (git:
b6314b6master →37d997ddeploy-live, 2026-06-10; 타 세션 실행 추정): NULL 규약(NULL=자동·값=수동) + normalize None 통과 +company_margin_rate동봉 + 라벨 토글. 진단·처방 원문 = archive.md. 하위호환 약점: NULL규약 이전 기존 견적은 1회 재저장해야 정상화. - 견적 v2 2026-06-10 운영배포 묶음 — 완료·종결: ①타입SSOT 페이즈A·B+후속결함 5건+펜아이콘(
a523d39·Actions ✓) ②구조 복사(타입/K/F/항목/sub, 동일 묶음) ③임시 계산기 행+합계 천원올림 보정(3bb8457·Actions ✓). 페페 화면 확인 완료(2026-06-10: 계산기 컬럼·보정 합계 / 구조 복사 / OMC QA). 상세 원문 = archive.md. 활성 약점(#3·#4 하위호환): NULL규약 이전 기존 견적은 자동행에 margin_percent 값이 남아 1회 재저장해야 NULL 정리·정상화(DB 마이그레이션 없음). 합계 보정 동일 — 기존 저장 합계 1,000원 과다 케이스 일괄 정정은 폐기(페페 결정 2026-06-10), 해당 견적 재저장 시 자연 정정.
06-19~07-07 완료 이관 (2026-07-07 handoff 정리 시 편입)
자재관리 탭 성능 시리즈(07-07 6건)·재번호·자재관리 초기 구축·업체관리·입고일정·견적 등. handoff NOW에서 완료 처리해 이관. 07-07 자재관리 구조개선 최종본은 handoff NOW 유지(육안 대기).
완료(2026-07-07) — 자재관리 탭 편집 클릭 버벅임 해결: table-layout:fixed (master 1d79b92→deploy-live 93dc5f5, 테스트+운영 사용자크롬+운영배포, 승인 DEPLOY-20260707-HKVV)
- 페페 "지연렌더링 후에도 느림, 특히 품명·사용량 편집 클릭 시 버퍼 범위·시간 증가". 원인=
table-layout:auto+ 259행: 셀 하나 편집(input 삽입으로 셀 폭 변화)마다 브라우저가 전 259행 모든 셀을 재측정해 열 너비 재계산(auto layout 고질병). 페페 "범위·시간 증가"와 정확히 일치. - 해결=
table-layout:fixed+<colgroup>폭 고정(JS shellHTML에 col 14개, min-width:1168px). 열 폭 헤더 기준 1회 계산 → 셀 편집이 전체 재측정 유발 안 함(리플로우 해당 행 국소화). 품명 160·규격 150px 명시. ⚠함정: colgroup 재조정을 같은 캐시버스터(f)로 두 번 배포→브라우저 캐시가 구버전 물어 품명/규격 0폭 → 캐시버스터 g로 bump해야 반영(같은 v 재배포 금지). js/css?v=20260707g. - 검증(테스트+운영 사용자크롬)=fixed·품명160·규격150·편집 저장/영속 PASS·데이터 원복. deploy-live 93dc5f5. 대형 테이블 성능 3대 원인 전부 제거 완료. 페페 Ctrl+Shift+R로 v20260707g 확인 요망.
완료(2026-07-07) — 자재관리 탭 느려짐 근본해결: 폼요소 지연 렌더링 ★진짜 원인★ (master 0407f73→deploy-live 7819c63, 테스트+운영 사용자크롬 Playwright+운영배포, 승인 DEPLOY-20260707-36RQ)
- 페페 "삭제 후 버퍼링·페이지 로드도 느림·컴퓨터 전체 느려짐, 확장·네트워크 무관". 핵심 진단(운영 사용자 크롬 프로필로 직접 실측해야 잡힘): 자재관리 탭이 행마다 폼요소 6개(자재분류 select 1 + 품명/규격/단위/사용/재고 input 5)를 항상 렌더 → 259행 × = 폼요소 2241개(input1245·select249·option747), 브라우저 접근성 트리 366만자·7084줄로 폭발. 이게 브라우저·PC를 무겁게 함(삭제 로직 자체는 1~3ms 정상). Playwright
browser_snapshot이 366만자로 터진 게 결정적 단서. - 해결=폼요소 지연 렌더링: rowHtml에서 6개 편집셀을 텍스트 span(+data-no/data-field) 으로만 렌더. 셀 클릭 시에만
editStart(input)·mtStart(select) 가 그 셀 1개에 편집기 생성 → Enter/blur 커밋(기존 API 재사용)·ESC 취소 → 텍스트 복귀. mmBody에 위임 클릭 1회 바인딩(bindEdit). 커밋 함수_commit(품명/규격/단위/재고)·_commitUsed(사용량, 누적·재고셀도 갱신). CSS:td.mm-edit(cursor:text·hover),mm-edit-in,mm-ph(플레이스홀더). 캐시버스터 css+js?v=20260707e. - 검증: 테스트=폼요소 2241→0개·DOM 8582→6607·편집 진입/ESC취소/Enter저장 DB영속/텍스트복귀 PASS·데이터 원복. 운영 사용자크롬 실측=폼요소 0개·DOM 8907→7008·접근성 트리 366만→30만자(92%↓). deploy-live 7819c63. 페페 Ctrl+Shift+R로 v20260707e 로드 후 확인 요망. 편집 UX=셀 클릭→수정→Enter(한 단계 추가되나 표가 훨씬 가벼움). ⚠교훈: 대형 테이블 "느려짐"은 폼요소 개수·접근성 트리 크기(browser_snapshot 자수)로 진단, 행마다 항상-렌더 폼요소는 클릭시 생성으로. [[innerHTML-rebuild-renderer-memory-spike]]와 함께 대형 테이블 성능 2대 원인(전체 innerHTML 재빌드 + 폼요소 상시렌더).
완료(2026-07-07) — 자재관리 탭 행삭제 메모리 300MB 스파이크 근본수정 (master 2c18ef2→deploy-live b0bc891, 테스트 Playwright+운영배포, 승인 DEPLOY-20260707-ZN7E)
- 페페 "삭제 후 버퍼링·브라우저·컴퓨터 전체 느려짐". 진단 과정(중요 교훈): ①낙관삭제·디바운스 시도했으나 로컬 재현 안 됨(SQL 61ms·응답 278ms/855KB·render 16ms·JS heap +0.8MB 전부 정상) ②콘솔로그는 전부 브라우저 확장(Vue devmode·chrome.runtime message port=pfs엔 없는 API) ③시크릿창 개선됐으나 확장 전부 꺼도 증상 유지 ④localStorage도 작음(596B) ⑤페페 작업관리자 실측 = 삭제 1회당 렌더러 메모리 300MB 급증 ← 결정적 단서. JS heap(+0.8MB)과 안 맞음 = 렌더러 프로세스(DOM·레이아웃) 메모리. 진짜 원인=삭제마다
render()가body.innerHTML로 242행(폼요소 input 1210·select 242 ≈1400개) 통째 재구축 → 렌더러 레이아웃 메모리 수백MB 스파이크. 직전 배포한scheduleCleanup()(250ms 디바운스 render)이 그 재구축을 유발. - 해결: delItem에서 전체 render 완전 제거 — tr 하나만
removeChild+ OP_ALL splice +bumpCount(-1)만. 남은 행은 그대로 유효하니 재구축 불필요.scheduleCleanup/_cleanupTimerdead code 삭제. 블록모드 'N건' 카운트만 다음 자연 render(정렬·검색·탭전환) 때 정정(사소). JS만·캐시버스터 js?v=20260707d. - 검증(테스트 Playwright)=3개 삭제 시 mmBody DOM 변경 removed 3·added 0(tr만 제거, 이전 240행 재구축 완전 소멸), count 정확·3클릭 3.3ms. 운영 HEAD b0bc891. 페페 Ctrl+Shift+R로 v20260707d 로드 후 확인 요망. ⚠교훈: "느려짐" 진단 시 JS heap만 보면 놓침 — 작업관리자 렌더러 메모리가 innerHTML 대량 재구축을 드러냄. 대형 폼요소 테이블에서 부분 변경에 전체 innerHTML 재빌드 금지.
완료(2026-07-07) — 자재관리 탭 연속 삭제 최적화 (master 8e08404→deploy-live 94c6fb4, 테스트 Playwright+운영배포, 승인 DEPLOY-20260707-E8G8)
- 페페 "여러개 빠르게 순서대로 삭제 시 한 개 후 브라우저 느려짐". 진단(테스트 실측): 서버 delete 41~59ms·클라 DOM제거 0.6~2ms 전부 정상 → 로컬 재현 안 됨. 유력 원인=자재관리 테이블이 대형(전체표시 시 mmBody ~242행·DOM 8471노드·input 1210)이라 개별 삭제 시 리플로우 + 낙관삭제가 render 없이 DOM만 건드려 count·블록 정합 안 맞음. 개선(정합성+리플로우 완화): delItem에
bumpCount(-1)(전체 render 없이 'N건' 숫자만 즉시 감소) +scheduleCleanup()(250ms 디바운스 — 연속삭제 멈추면 1회만 render로 블록·정렬·정확한 count 정합 복구). tr 즉시 removeChild는 유지. JS만·캐시버스터 js?v=20260707c. - 검증(테스트 Playwright)=8개 20ms간격 연속삭제 클릭당 0.6~2ms·count 242→234 즉시감소·디바운스후 count=행수=234 정합 일치, 데이터 온전(스텁검증이라 서버 미삭제). 운영 HEAD 94c6fb4 반영. ⚠미결: 로컬 재현이 안 돼 페페 실환경 느려짐이 완전 해소인지 미확정 — 여전하면 브라우저 확장·네트워크·특정 데이터량 요인 추가 점검.
완료(2026-07-07) — 자재관리 탭 행삭제 버퍼링 제거(낙관적 UI) (master 988b07c→deploy-live c3e8a37, 테스트 Playwright+운영배포, 승인 DEPLOY-20260707-7FND)
- 페페 "행삭제 버퍼링 최적화". 원인=삭제 클릭 후 서버 왕복(수백ms) 뒤에야 OP_ALL 제거+전체
render()(1200행 재렌더)라 버벅임. 해결=낙관적 UI:delItem(no, btn)클릭 즉시 OP_ALL에서 splice + 해당<tr>만removeChild(전체 재렌더 없음), 서버 PATCH는 백그라운드, 실패(code≠0000/error) 시에만restore()(원위치 splice+render)로 되돌림. 성공 토스트 제거(즉시 사라져 불필요). 블록모드 구분행 카운트는 다음 render 때 정정(ponytail 주석). JS만 변경, 캐시버스터 js?v=20260707b(css는 그대로 20260707a). - 검증(테스트 Playwright)=
btn.click()반환 즉시(서버 응답 전 같은 tick) 행 1→0·OP_ALL 1385→1384·no297 제거, 새로고침 후 서버 삭제 영속(1384·remove_yn=1) → 낙관 UI+실제 반영 둘 다 PASS, 테스트데이터(297) 복원. 운영 HEAD c3e8a37 반영.
완료(2026-07-07) — 자재관리 탭 발주량 가운데정렬·폭 auto, 품명/규격 폭 auto (master 87edf34→deploy-live a5ce41d, 운영배포, 승인 DEPLOY-20260707-R94Y)
- 페페 "발주량 컬럼 정렬 안 맞음→가운데+폭 auto, 품명·규격도 폭 auto". CSS만: 발주량 헤더 클래스
mm-r→mm-c-qty(JSth('qty',...)1곳)·th.mm-c-qty,td.mm-c-qty{text-align:center;width:auto}/ 품명·규격 셀td.mm-c-itemcell,td.mm-c-speccell{width:auto;white-space:nowrap}(강제width:100%제거)·input min-width 120→90. 캐시버스터 mm css/js?v=20260707a. 검증=운영 HEAD a5ce41d·CSS 마커·캐시버스터 반영.
완료(2026-07-07) — orderpaper_no 재번호(1..1500) + 동기화 번호튐 근본수정 (master 4748172, 운영 재번호+백업, 페페 승인 DEPLOY-20260707-RM6T)
- 페페 "1500행인데 orderpaper_no가 575390까지 팜. 정리+운영배포". 이후 "1부터 시작, 필요하면 데이터 지우고 재동기화" → 소실규모 실측(재고1297·상태693·자재분류149·수동삭제203·비고13·사용이력10 등 사용자편집 전부 소실) 보고 → 페페 "번호만 1..N 재부여"(편집 보존) 선택.
- 근본원인:
orderpaper_sync.py가 매 동기화INSERT..ON DUPLICATE KEY UPDATE로 전 행 INSERT 시도 → 기존행은 UPDATE로 흡수돼도 MySQL이 AUTO_INCREMENT를 소비(실패 INSERT도 번호 버림) → 1500행인데 no 57만. 수정=선조회한 item_key 집합으로 신규만 INSERT·기존은 UPDATE 분리(sync는 로컬실행 전용, 웹배포 무관). 이후 AUTO_INCREMENT는 실제 신규 건수만 증가. - 재번호(운영):
_renumber_orderpaper_prod.py(정리됨) — ①백업테이블 2개(orderpaper_bak_20260707_renum·orderpaper_usage_history_bak_20260707_renum) ②단일 트랜잭션 ③현재 no ASC순 임시컬럼_newno=1..N ④offset(+1e7) 2패스로 PK 충돌 회피 ⑤usage_history 참조 동일매핑 갱신 ⑥사후검증(행수·연속·유일·고아0) 실패시 자동롤백. 테스트 RDS 리허설 성공(1..1402) 후 운영 실행. - 검증: 운영 orderpaper 1500행 no 1..1500 연속·유일, usage_history 10건 고아참조 0, REAL AUTO_INCREMENT=1501(stats캐시 무시 실측), all-items 1205행 no 1~1500·stock 편집 1201건 보존·unit컬럼 정상. 참조 테이블은 orderpaper(PK)+usage_history 2개뿐(선언 FK 없음, 수동갱신). site_map/upload는 site_name_raw/upload_no 기반이라 무영향.
- 주의: 백업테이블 2개는 롤백 대비 운영에 보존 중(문제 없으면 나중에 DROP 가능·위험작업). broker deploy-approval은 healthcheck_url 없으면 승인해도
deploy_failed로 표시됨(DB작업엔 healthcheck 무의미 — 승인 자체는 status="approved"로 확인). MySQL 8.4 information_schema AUTO_INCREMENT는 stale캐시(정확값은SET SESSION information_schema_stats_expiry=0후 조회).
완료(2026-07-06) — 자재관리 탭 행삭제(숨김)·품명/규격/단위 편집·발주량 단위분리·15TT→15T·히스토리 아이콘 (master 091da3c→deploy-live 75b8ff0, 테스트 Playwright E2E+운영배포, 승인 DEPLOY-20260706-2ZPM)
- 페페 4건+추가지시 2건(삭제버튼 맨앞·확인없이 즉시삭제). ①행삭제=맨왼쪽 첫 컬럼 ✕버튼, 확인없이 즉시
/delete(remove_yn=1·del_manual=1=동기화가 안 되살림) + OP_ALL에서 제거(전 탭 공유라 다른 탭도 사라짐). ②품명·규격 편집=input(change 저장, 신규item_name_user/spec_user, COALESCE override=동기화 보존). ③발주량 숫자만 표기 + 단위 새 컬럼=qtyDisp(숫자부 추출)·unitFromQty(뒤 단위 폴백)·신규unit_user(편집). ④품명 15TT/18TT→15T/18T=itemDisp정규화(표시만,(\d)[tT]{2,}→$1T). ⑤히스토리를 누적사용량 우측 📜 아이콘으로 이동(페페 지시 "누적 우측 아이콘"), 규격셀=편집 전용(기존 규격클릭=히스토리 폐지). 헤더 14컬럼·colspan 14. - 백엔드: DAO
select_all_items에COALESCE(item_name_user,item_name)·COALESCE(spec_user,spec)·unit_user AS unit+ update_item_name/spec/unit 3종 · service 3종 · controller PATCH/item-name·/spec·/unit(note/qty 패턴 복제). 신규 컬럼 3종 = 테스트·운영 RDS ALTER 완료(item_name_user VARCHAR(255)·spec_user VARCHAR(255)·unit_user VARCHAR(50),migrations/patch39_...sql기록). 캐시버스터 mm css/js?v=20260706b(수동 bump 필수). - 검증(테스트 Playwright E2E, poin01): 14컬럼 순서·15TT→15T 표기·발주량 '20장'→숫자'20'+단위'장'·품명/규격/단위 편집 DB영속(새로고침 유지)·삭제 1385→1384 all-items에서 빠짐 전부 PASS, 테스트데이터(356) 원복. 운영 실측=all-items unit컬럼 존재·1205행. HEAD 75b8ff0·RDS ALTER 3종·마커 반영.
완료(2026-07-06) — 자재관리 탭만 숨김 현장·현장 미지정 항목 표시 (master 60e7ef1→deploy-live fc89a66, 테스트 Playwright+운영배포)
- 페페 "자재관리 탭에서만 예외: ①숨김 항목도 보이게 ②현장 미지정 항목도 보이게. 운영배포까지." 발단=NAS
모드니바스 욕실장 원부자재발주서.xlsx오엠씨 탭 항목(15TT PC보드 등)이 화면 미노출 → 원인=현장 "욕실장"이orderpaper_site_map.is_hidden=1(숨김). 항목 자체는 DBremove_yn=0정상. - 구조 핵심: OP_ALL은
all-items하나로 채워 전 탭 공유 SSOT. 기존select_all_items는WHERE AND COALESCE(m.is_hidden,'0')='0'로 숨김을 API 단에서 제외 → 자재관리 탭도 못 봄. 해결=all-items에 숨김을 다 담고, 자재관리 외 탭만 클라에서 재필터(욕실장 데이터는 안 건드림, 숨김해제 아님). - 수정 2파일: ①
api/pfs/orderpaper/dao/orderpaper_dao.pyselect_all_items()— SELECT에COALESCE(m.is_hidden, '0') AS is_hidden추가 + WHERE의 is_hidden 제외절 제거(숨김도 OP_ALL에 담김). ②web/templates/basic/field/field_orderpaper.html—opPass()맨 앞if(String(it.is_hidden)==='1') return false;(발주서정리·현장별자재 탭 숨김 제외 유지=회귀방지) +opDistinct()에if(String(it.is_hidden)==='1') return;(필터 드롭다운 회귀방지). 자재관리 탭(orderpaper_material_mgmt.jsrows())은 무수정 → is_hidden 안 보니 숨김·미지정 다 표시. - 검증: 테스트=자재관리 90일창 숨김357·미지정179 표시, 다른 탭 opFiltered 숨김통과 0(회귀없음). 운영 실측(all-items API, poin01)=1205행,
is_hidden컬럼 존재, 숨김 1011건 포함, 욕실장 23행·PC보드 8건 노출 확인. HEADfc89a66·DAO/HTML 마커 반영. - 주의: 이번엔 욕실장 is_hidden 데이터 미변경(코드 예외로 해결). 다른 탭 육안 회귀확인은 페페 브라우저 몫(마커 True라 로직상 보장).
완료(2026-07-06) — 자재관리 탭 기본 검색기간 1개월→3개월 (master 4988fa2→deploy-live f14897b, 테스트+운영 Playwright+운영배포)
- 페페 "orderpaper 자재관리 탭 기본 검색기간 최근 1개월→3개월, 운영배포". 수정=
orderpaper_material_mgmt.jsrows()cutoff(q?90:30)→90(검색어 없을 때 30→90일, 검색 시도 이미 90이라 통일)+안내라벨mmCount'최근 1개월'→'최근 3개월'. 캐시버스터field_orderpaper.html?v=20260703a→20260706a(mm js는 수동 bump 필수 화면). 검증=테스트 라벨 '최근 3개월'·30~90일 구간 117건 신규포함 실측, 운영 라벨 '최근 3개월'·v20260706a 로드 확인. 견적 현장검색 모달·발주서 신규현장 검색(별개 site-search 30일)은 범위 밖이라 미변경.
완료(2026-07-06) — 발주서 동기화 버그(피앤알 TLG0129MU 미노출) 근본수정 + 재동기화 + 삭제항목 복원 (master 9a8ef49, 테스트→운영 재동기화+운영 데이터정정)
- 페페 "field/orderpaper 피앤알 TLG0129MU 안 보임, 삭제/숨김이면 복원" → "7월 폴더 동기화 잘 안 되는 듯". 정정 경위(초기 오진단 2건 폐기): 처음엔 ①TLG=정상(데코밸리, 복원불필요) ②다월 item_key 충돌로 오판했으나 NAS 실물 확인 후 둘 다 틀림. NAS(
\\192.168.0.101\공유폴더\2026현장\원부자재발주서) 접속=UTF-8 .py로win32wnet.WNetAddConnection2(한글 공유명은 Bash heredoc/net use서 cp949로 깨져 오류67·3 — 반드시 UTF-8 파일 실행). 6↔7월 파일명 충돌 0건(다월 item_key 충돌 아님). 진짜 근본원인:orderpaper_sync.py의ON DUPLICATE KEY UPDATE목록에vendor/item_name/spec/material_type/seq누락.item_key=sha1(source_file,sheet,section,type,idx)라 파일에서 항목 재배치/삽입 시 같은 item_key 자리에 다른 물품이 오는데, UPDATE가 vendor/품명 제외라 DB에 옛 업체·품명 고착(재동기화해도 최신 파일 미반영). 대우용인 MH 파일엔 피앤알 TLG0129MU 2건이 있으나 그 item_key가 DB엔 옛 프린테크 항목으로 남아있었음. 수정=그 5개 컬럼을 UPDATE에 추가(upload_load는 이미 포함, sync만 누락). item_key 불변이라 stock·_user 상태 보존(마이그레이션 불필요). 원인=파일이 마지막 동기화(02:18) 이후 오후(13:47 등)에 수정됐고 그 뒤 재동기화 안 함. 테스트 재동기화 검증→운영 재동기화(files27·items1370·upd1370·removed0). 잔여: 피앤알 TLG 2건(301082·302338)은 과거 사용자 화면삭제(del_manual=1) 상태라 재동기화로도 안 뜸(syncremove_yn=IF(del_manual=1,1,0)) → 파일 대조로 "숨김 182건 전부 GENUINE(진짜 삭제)"확인 후 페페 승인받아 이 2건만 del_manual=0·remove_yn=0 복원(나머지 180건은 사용자 의도삭제라 유지). 검증=운영 all-items에 피앤알 TLG0129MU 2건 노출*(대우용인 vendor 6개·항목 32건). - 동기화 폴더 범위(참고): NAS
원부자재발주서하위 2026-05월 이상 월폴더의.xlsx만(orderpaper_parse.pyMIN_YM=(2026,5)·~$·EXCLUDE_TABS 제외). EC2는 NAS 접근불가→로컬(코디PC)서 파싱→gzip+base64 baked→EC2 SSM으로 RDS upsert(sync=로컬실행 전용). 화면 "⟳ 지금 동기화"(#opSyncBtn)=sync-request 생성.
완료(2026-07-06) — 견적목록 v2 견적구분 estimate_div 전환 + 입금여부 토글버튼 (master 552d936→deploy-live eceedec, 테스트 Playwright+운영배포)
- 페페 검증리포트 2건(
/estimate/list-v2). ①견적구분(본견적/임시견적): "임시견적 건이 모두 본견적으로 표시" — 근본원인=list-v2 견적구분 컬럼이 폐지된is_temporary(구 autosave 유물, Patch#21로 세팅 중단)를 봤음. 실제 본견적/임시견적 분류는 등록/수정 화면 라디오estimate_div(char(1), 1=본견적/2=임시견적, common_code ESTIMATE_DIV)가 SSOT인데 list만 옛 컬럼 참조 → 페페가 임시견적으로 지정(div=2)한 건도 본견적으로 오표시. 수정=견적구분 JS switchdata.is_temporary→String(data.estimate_div)(2=임시견적 label-warning, else 본견적 label-success), "임시견적만 보기" 필터 hiddenis_temporary→estimate_div(체크 시 "2"), search DAOselect_estimate_search_list필터is_temporary→estimate_div(a.estimate_div=%s). search는a.*라 estimate_div 이미 응답 포함(백엔드 SELECT 무변경). ②입금여부 토글버튼: 미입금/입금 라벨 → 클릭 토글버튼(btn-danger/btn-info), 클릭 즉시 신규 APIPUT /estimate/<no>/deposit(is_deposit 1/0 영속, controllerEstimateDeposit+serviceset_deposit+daoupdate_deposit, include-print 패턴 복제) 호출→성공 시 버튼 라벨/색 갱신. list-v2 JS 위임 클릭 핸들러(tbody delegation). - 검증(테스트 Playwright, poin01 로그인): 710 estimate_div=2 임시세팅→새로고침 "임시견적"(label-warning) 표시·"임시견적만 보기" 체크→710 1건만 / 입금 토글 클릭→미입금(danger)→입금(info) 즉시전환, DB
is_deposit='1'영속 실측 → 테스트데이터 원복 완료(710 div=1·deposit=0). 운영 실측:/api/estimate/searchALL 611건(본609+임시2)·estimate_div=2 필터 정확히 2건 = 임시견적 2건 이제 화면 구분됨(기존 본견적 오표시 해소). 운영 HEAD eceedec·마커(deposit-toggle 2·update_deposit 1) 반영. - 변경 4파일:
web/templates/finance/estimate/estimate_list_v2.html·api/pfs/estimate/{controller,service,dao}. 캐시버스터=list-v2는 template 직접 렌더(asset_ver 무관, 배포 즉시 반영).
완료(2026-07-06) — 707 견적서 추가건 등록 + 견적등록 스킬 마진율 auto화
- 작업:
AS 넵스 IS동서 울산MH 도어발주서.xlsm포인탭 1~4p → 707 견적서(IS동서 울산 MH, field_no 2106) 추가건 등록. 결과 est 728 "추가1" 7줄(운영 POST, 텔레그램 승인 DEPLOY-20260706-TKJB). 자동수집 4 + 수동포함 3(p1 키큰도어×2=U열 유상표기 없으나 도어변경 유상건, p4 은경 키큰EP=숫자접두 없어 부품 오분류됐으나 독립완제품). 무상행 제외. 단가 0(스태프 후추). 스크립트order-automation/build_and_register_707.py. - 스킬 마진율 auto화(페페 지시): 견적등록 스킬 템플릿의 항목별·전체
margin_percent를 0(수동)→None(=SQL NULL=자동)으로 변경. PFS 규약estimate_service._NULLABLE_KEYS={'margin_percent'}상 NULL=자동(업체 마진율 추종)·값=수동. 수정 파일:견적등록_스킬.md(§4/§5),build_and_register.py·build_and_register_add5.py·build_and_register_707.py(detail TMPL + build_master). 728은 이미 수동 0%로 등록됐고 페페 지시로 소급 전환 안 함(화면 수급토글로 수정 가능). 다음 등록부터 auto 적용. - devplan:
catalog.htmlorder-automation 항목 desc에 견적등록 스킬·마진율 auto·707→728 반영(정적서빙 8799 즉시반영, git 없음). - 공유폴더 접근: 192.168.0.101\공유폴더 = SMB 인증 필요(net use, id poin912). Bash(git bash)는 UNC 불가 → PowerShell net use 또는 python os. 한글경로는 UTF-8 py파일로(cp949 mojibake 회피).
완료(2026-07-03) — 자재관리(mm) 탭 사용량/누적사용량 컬럼 + 사용 이력(patch38) (master 0209fe6·0c53cd0→deploy-live 5de8f7d, 테스트 E2E PASS+운영배포)
- 요구(페페 검증리포트): 재고량 앞에 ①사용량(당일 입력, 엔터로 확정 시 누적) ②누적사용량(자동 누적, 재고 자동계산) 컬럼 + 실수 대비 RDS 히스토리 + 규격 셀 클릭→히스토리 확인. AskUser 확정 2건=재고 계산은 현재 재고에서 차감(엑셀 시드 187행 보존, 신규는 stock=qty라 결과적으로 발주량−누적과 동일) + 히스토리 삭제(되돌리기) 가능.
- DB: 신규
orderpaper_usage_history(history_no PK, orderpaper_no, kind U사용/S재고직접수정, used_qty DECIMAL(12,2), stock_before/after, regist_date) —ensure_usage_table()멱등 자동생성(vacation_dao 패턴, 테스트 RDS엔 첫 호출로 이미 생성됨) +migrations/patch38_orderpaper_usage_history.sql(기록용). 운영 RDS는 배포 후 첫 API 호출 시 자동생성(별도 DDL 불필요). - 백엔드:
POST /api/orderpaper/<no>/usage(차감+이력, 음수=정정, 재고 비숫자면 ValueError→code≠0000 toast) ·GET <no>/usage-history(최신순, used_qty/used_total은 CAST AS CHAR=Decimal 직렬화 함정 회피, 일시 DATE_FORMAT%%) ·PATCH usage-history/<no>/delete(kind U만, 재고 원복+누적 재계산) ·modify_item_stock이 kind S 이력도 INSERT(실패해도 저장은 통과).select_all_items에used_totalLEFT JOIN 집계. - 프론트(
orderpaper_material_mgmt.js/css): 헤더 발주량|사용량(input, 정렬 없음)|누적사용량(정렬 cum)|재고량, colspan 10→12. Enter만 커밋(usedKey→addUsage→성공 시 OP_ALL 갱신+render로 입력 비움). 규격 td 클릭(openHist)→.op-fmodal재사용 히스토리 모달(일시·구분·사용량·재고 before→after·U건 삭제버튼). 캐시버스터?v=20260703a(mm js/css 수동 bump 필수). - 검증(테스트 Playwright, 항목 #5741): 컬럼 순서 12개 정확 → 재고 10 설정(S이력 —→10) → 사용 3 Enter(누적3·재고7) → 사용 2(누적5·재고5) → 규격 클릭 모달 3건(S건 삭제버튼 없음) → 삭제(재고 7 원복·누적 3) → 새로고침 영속(누적3·재고7=DB 왕복·ensure_table 실증) → 음수 -1(누적2·재고8) 전부 PASS. 테스트 데이터 원복 완료(U이력 삭제→재고 빈값).
- 후속(같은 날, 페페 지시)
0c53cd0: ①이력 일시 KST 표시 필수 → 저장은 NOW()=UTC 유지(관례), 표시만CONVERT_TZ(+00:00→+09:00)(테스트 12:42 실측). ②_num선행 숫자 추출('100m'→100) — stock=qty 복사값(단위 포함)도 차감 되게(테스트 100m−3→97→삭제 원복 100 실측). ③재고 백필 1차(빈 stock→COALESCE(qty_user,qty),scripts/_mm_stock_backfill(.py/_prod.py)SSM): 테스트 889건 갱신·운영 대상 0건(6/24 시드+자동복사로 완비), 잔여 빈값은 qty 없는 행(테스트 118·운영 13)뿐. ④운영배포(페페 승인, deploy-live5de8f7d--no-ff "deploy:" 패턴): 운영 JS 마커(usedKey)+usage-historyAPI 200/빈배열(운영 테이블 자동생성 실증) 확인. - 후속 2(같은 날, 페페 지시) — 재고 백필 2차: stock='0'도 발주량으로(
scripts/_mm_stock_zero_backfill(.py/_prod.py)): 페페 "0으로 된 값 발주량 값으로 모두 변경. 운영 배포 진행"(코드 무변경이라 DB 갱신만). 조건=TRIM(stock)='0' AND qty NOT IN ('','0')(qty도 '0'인 행은 0→0 무의미라 제외). 운영 774건 갱신(6/24 시드 '나머지 0' 물량, 잔여 대상 0)·테스트 실변경 0건(0재고 13건 전부 qty='0'). 엑셀 실사 187행(0 아닌 남은수량)은 미대상 보존. ⚠qty가 텍스트인 소수 행은 stock에 그대로 복사됨 — 사용량 입력 시 "숫자 아님" 에러로 표면화, 사용자가 재고 셀 숫자로 수정하면 됨.
완료(2026-07-03) — 현장별자재 신규현장 검색에 field 테이블 현장 병합(구조개선) (master 101a369→deploy-live 8eceecd, 테스트+운영 Playwright PASS+운영배포)
- 발단: 페페 "SGC 광주 용두동(field 2129)이 현장 검색에 안 보임". 진단(운영 RDS SSM)=field에는 있으나 orderpaper 행 0건(발주서 미동기화) — OP_ALL이 orderpaper 테이블 전용이라 구조적 누락. 페페 "발주서 없어도 현장목록과 매핑되게 현장별 자재 탭만 수정+운영배포".
- 수정(
orderpaper_material.js만, 백엔드 무변경):loadFieldSites()=견적 현장검색 API(estimate/site-search) 재사용(keyword 빈값·상차일 1개월전~이후 전체·LIMIT 50) →fieldSites캐시(YYYYMMDD→ISO,fieldOnly:true).nsData()=발주서 집계 ∪ fieldSites(중복 제거 field_no→정규화 현장명, 상차일↓ 재정렬). 드롭다운에 "발주서 없음" 회색 배지(.ns-badge.gray). 선택 시 가구업체+field_no 매핑은 기존nsApplyExact그대로(nsData 경유라 자동 적용). 로드 시점=openNewSite(도착 시 열린 목록 재렌더)+renderGrid(1회). spec-only 카드 보강=buildGrid가 OP_ALL 미스 시 fieldSites에서 업체·상차일 폴백(+_lastSpecs/_lastPending재실행). API 실패=비치명(발주서 현장만으로 동작). 캐시버스터?v=20260703c. - 검증: 테스트 Playwright=발주서 9+field-only 3=12건 병합·배지·"라인VIP"(field-only) 엔터→업체 에넥스 자동·콘솔0. 운영 실측=신규현장 검색 "용두"→"SGC 광주 용두동" 1건(발주서 없음 배지·넥서스·상차 7/26(일)·D-23) — 원문제 해소 확인. 운영 마커 서빙 OK.
완료(2026-07-03) — orderpaper 현장별자재 신규 현장 모달 인라인 검색 재작성 + 드롭다운 모달 밖 표시 (master a10e889·bbdf705→deploy-live 567c41d·5492117, 테스트 Playwright 검증+운영배포)
- 요구: 신규 현장 등록 모달이 미비(datalist) → 현장명 인라인 검색으로, 견적서 등록 현장검색 모달 기능 이식("기능만 구별해서 동일 기능 참조"). 후속: "모달 높이가 작아 리스트가 갇힘 → 모달 외부로". 둘 다 "운영배포까지".
- 1차(
a10e889):orderpaper_material.js신규현장 모달 datalist 폐지 →.op-mat-ns-list인라인 드롭다운. 데이터=gridSites 재사용(진행중+spec-only, 폴백 siteDropData), 현장명·가구업체 contains 필터, 상차일↓ 정렬 유지, 결과 건수 표시. 엔터 1건=즉시선택/다수=active(↑↓), ESC 닫기 (field_regist 인라인·견적 엔터검색과 동일 규칙). 항목=현장명+가구업체·상차 M/D(요일)·D-day 배지·"자재사양 있음" 배지(견적 "견적서 있음" 배지 대응, 차단은 안 함). 선택/정확일치 시 가구업체+ctx._nsFieldNo자동 매핑, 이름 재수정 시 매핑 해제(nsApplyExact, 저장 정합). 미일치=안내문+직접입력 신규생성 유지. 미채택(의도)=견적 모달의 상차일 기간필터·컬럼 다중정렬(진행중 현장 소수라 불필요). - 2차(
bbdf705): 리스트가.op-mat-mbody{overflow-y:auto}+dialog max-height에 클리핑(업체휴가.vac-table overflow:hidden잘림과 동일 함정) → 드롭다운position:absolute→fixed(z-index 1500>모달 1400),nsShowList()가 입력칸getBoundingClientRect()로 left/top/width 세팅, max-height 260px→48vh. 캐시버스터?v=20260703b(이 화면은 asset_ver 아닌 수동?v=— bump 필수). - 검증(테스트 Playwright 실브라우저): 드롭다운 9건, "쌍용" 필터→1건→엔터 즉시선택(넵스 자동입력), 업체명 "넥서스" 검색, ↑↓2회→3번째 active→엔터, 실클릭 선택, 재수정 매핑해제, 미일치 안내. fixed 전환 후 리스트 하단(438)>모달 하단(371)=모달 밖 돌출 실측, 모달 밖 영역 4번째 항목 실클릭 선택 OK, 스크린샷 눈확인, 콘솔에러 0. 운영: JS/CSS 신규 마커(nsRenderList·getBoundingClientRect·fixed z-1500) 서빙+
/field/orderpaper200. - 변경 3파일:
web/static/js/orderpaper_material.js·web/static/css/orderpaper_material.css·web/templates/basic/field/field_orderpaper.html.
완료(2026-07-02) — 현장등록 담당자 3종 검색 모달→인라인 (master 960e9ea→deploy-live 0fc8a1a, 테스트 실브라우저 검증+운영배포)
- 요구:
field/regist의 현장/업체/시공 담당자 검색을 팝업모달→등록화면 인라인 검색으로. 이름으로만 검색, 매핑컬럼(직위/부서/업체명)·hidden_no는 기존대로 유지. 유사이름 1개 엔터=즉시입력. "운영배포까지". field_regist.html만 수정(공유 팝업member_popup/company_member_popup은 field_list/modify/status·estimate 등 5화면도 쓰므로 미변경). block popup의 include 2개 제거 → 각 담당자 이름칸에.inline-search-list드롭다운 + readonly 매핑칸. 데이터는 포커스 시 1회 fetch(현장=GET user/, 업체=POST company/member/search {company_div:10}, 시공={company_div:30,job_comment:시공}) → 클라 이름 contains 필터._inlineCfg(load/nameKey/sub/apply)로 3종 공통화. 엔터: matches 1개면 바로, 다수면 active(↑↓)항목 apply. 이름 재편집 시_clearInlineMapping으로 hidden_no무효화(save 정합).- 검증: 테스트서버 Playwright 실동작 — 현장(이창재→no6/부장/생산팀), 업체(고재형→넥서스/no1), 시공(홍영재→지엠테크/no22) 엔터 즉시입력·매핑 OK, 다수매칭(신동승) 첫항목 선택 OK, 콘솔에러 0. SSM으로 양서버 배포마커(inline-search-list 13개)·HEAD 확인.
- 도구:
scripts/ssm_run.pyAWS 해석을.venv python -m awscli우선으로 수정(aws 진입스크립트 shebang 깨짐 우회, 로컬 미커밋).
완료(2026-06-26) — 업체 휴가일정 사이드메뉴+신규 페이지 (master 5f12f82/e309117/3eb2c60→deploy-live 8bb1f56, 테스트+운영 E2E PASS)
- 요구: 사이드메뉴 최하단 "업체 휴가일정" 링크 + 신규 페이지, 테이블 3컬럼(업체/시작기간/종료기간). 업체=mysql
company연결 인라인 드롭다운, 날짜=직관적 입력 →<input type=date>채택. "테스트배포만"→이후 페페 "작동하면 운영배포"+"운영 RDS도 승인". - 신규 모듈
api/pfs/vacation/{dao,service,controller,model}— 테이블company_vacation(vacation_no PK, company_no/start_date/end_date nullable, reg/modify).ensure_table()멱등 자동생성+ALTER nullable 승격(material-spec 패턴). CRUD/api/vacation(GET목록 company LEFT JOIN·POST빈행·PUT채움·DELETE). config 네임스페이스 등록. - 사이드메뉴:
permission_dao.ensure_vacation_menu()(latch 멱등) — menu_catalogcompany_vacation(parent NULL 최상위 단일링크,display_order=900=최하단, url/vacation).select_menu_catalog_all()진입 시 자동시드(SSM 불필요, ensure_field_log_group 패턴). super_admin·자사 자동노출. - 페이지
web/templates/default/vacation.html(extends base, content/javascript 블록) + 라우트/vacation(default 블루프린트). 업체 select(GET /api/company/)·날짜피커·"추가"(빈행)·인라인 onchange 자동저장(3칸 다 차야 PUT)·행삭제. 응답은res.message. - 버그 2건 잡음(추가 작동검증서 발견): ① 빈행 POST가 502(컬럼 NOT NULL→IntegrityError) → nullable 승격으로 해소(
e309117). ② GET 날짜가%Y-%m-%d리터럴 노출 — param 없는 fetchall은cursor.execute(sql)로 %이스케이프 미적용이라%%Y가 안 풀림 → SQL을%단일로(3eb2c60). - 검증: 테스트(pfs-test.poin.co.kr) + 운영(pfs.poin.co.kr) 둘 다 curl E2E — 빈행추가200·업체조인("넵스")·날짜(2026-07-01/07-05) 정상·PUT/DELETE OK·정리후 빈배열. 운영
/vacation200(라우트 OK). RDS DDL 운영 자동적용 확인(페페 승인). - 후속① 업체선택 드롭다운→인라인 검색창(master
3fa7003→deploy-livefb7f2ca): 페페 "드롭다운 말고 인라인검색창으로".<select>제거, hiddencompany_no+ text input(vac-co-search)로 교체 — 입력 시VAC_COMPANIES(이미GET /api/company/로 로드) 클라이언트 필터(이름 contains, 상위50), 결과.vac-co-resultsabsolute 드롭다운onmousedown(blur보다 먼저) 클릭→coPick(hidden 기록·검색칸 갱신·saveRow),coBlur는 150ms 후 닫고 선택값으로 입력칸 복구.rowPayload는 hidden 그대로 읽어 무변경. - 후속② 드롭다운 잘림 수정(master
f44b3d2→deploy-live8874dd6): 페페 "리스트가 행 높이만큼만 보임→구역 밖으로". 원인=.vac-table{overflow:hidden}(border-radius용)이 absolute 드롭다운을 테이블 박스로 클리핑.overflow:hidden제거(모서리 영향 미미)로 해소. - 후속 검증(테스트+운영 Playwright 실측): poin01 로그인→/vacation.
hasSelect:false(드롭다운 제거)·coFilter함수 존재·tableOverflow:visible. 행추가→검색("에"→에넥스 등)→결과 드롭다운boxHeight:240입력칸 아래로 표시(visibleBelowInput:true, 행높이 안 잘림)·스크린샷 눈확인. coPick→hidden=company_no·reload 후 업체명 복원·날짜영속 PASS. 테스트/운영 잔여행 정리(빈배열).
완료(2026-06-26) — 견적 현장검색 모달 컬럼 헤더 다중정렬 완성(직전 미완 WIP 마무리) (master 92b8730→deploy-live 3c40489, 테스트 Playwright+운영 배포·검증 PASS)
- 발단: 직전 세션이
estimate_regist_v2.{js,css,html}에 site-search 모달 정렬 개선을 만들다 이벤트 바인딩 누락으로 미완(아래 vendor-소계 항목 ⚠미결). 페페 "완성해서 테스트 배포까지만". - WIP 내용: ① 상차일 표시
20260626→6.26(금)M.D(요일)(fmtShipDate) ② 기본정렬=상차일 내림차순(applySiteSort→openSiteSearch/searchSites 연결) ③ 컬럼 순서(구분↔상차일)·모달폭 900→760 ④ 헤더 클릭 다중정렬(toggleSiteSort: 클릭→정렬, 재클릭→방향토글, 새 키→우선순위 맨앞)·인디케이터(updateSiteSortIndicators▲▼+우선순위숫자)·정렬초기화(resetSiteSort). ①②③은 배선됐으나 ④의 호출(이벤트 바인딩)이 없어 헤더클릭·초기화버튼 무동작이었음. - 완성(내 추가 = 6줄): 바인딩 위치(기존 siteSearch 이벤트군)에
$(document).on('click','#siteSearchModal th.site-sort',…toggleSiteSort(key))+$(document).on('click','#siteSortReset',resetSiteSort)2개 추가. 함수·UI·CSS는 WIP 그대로. - 검증(테스트 Playwright, 견적710 현장검색 모달): 기본=상차일▼(6.26→6.6)·M.D(요일) 포맷 OK / 업체명 클릭→오름차순(넥서스·넵스·에넥스 ko정렬) 헤더
업체명▲1+상차일▼2(다중·우선순위) / 재클릭→업체명▼1(방향토글) / 정렬초기화→상차일▼ 단일 복귀 / 행클릭 pickSite(현장선택+모달닫힘) 보존. 운영 배포 완료(deploy-live3c40489): 운영 JS 바인딩2·fmtShipDate2 + 로그인후 HTML site-sort헤더5·정렬초기화버튼·data-sort-key5 반영 확인.
완료(2026-06-26) — 견적 별도항목 업체별 소계 토글(화면 표시 전용) (master 6719a49→deploy-live d4e8688, 테스트 Playwright+운영 배포·검증 PASS)
- 지시: 별도항목에 업체별 소계(견적 영향X·그룹별 비용확인용). 확정(질문): 별도항목 시트(자재관리 화면)에 소계행, 숨김/펼침 가능, 인쇄/PDF 미반영, 합산 중복 주의(소계가 별도항목 합계에 이중합산 안 되게), 업체별 정렬 후 소계.
- 구현(regist 3파일, 백엔드·DB 무변경):
estimate_regist_v2.htmlcard-actions에#btnMaterialVendorSubtotal토글. js: StatematerialVendorSubtotal(localStoragepfs.estv2.matVendorSubtotal영속),renderMaterialList서 ON시effSort로 company_asc 강제 +appendMaterialRows가 업체 경계마다buildVendorSubtotalRow(순수 DOM div) 삽입(auto/manual 공통). css.mat-vendor-subtotal·.tag-subtotal·버튼.on. - 중복방지 핵심: 소계행=순수 표시 div,
State.materials/별도항목 합계(=materials amount합)에 미합산. 인쇄/PDF(estimate_print_v2*·estimate_print_service.py)는 materialTbody·소계 마커 0건(카드 자체 regist 전용)→무영향. - 검증(테스트 Playwright, 710 sub-item 메모리주입·비저장): ON→가나전자(2000+3000)=소계5,000·다라산업(2500)=소계2,500, 업체 정렬·그룹 정확, 토글 영속(LS='1'), OFF→소계0·원복, 별도항목 합계 summary 불변. 운영: vendor마커 JS3·CSS2 반영, site-search 누수0.
- WIP 분리 처리됨: 작업 시작 시 작업트리에 무관한 site-search 모달 정렬 WIP가 섞여 있었음 → soft reset+hunk 필터로 분리해 이 커밋엔 vendor-subtotal만 포함. 그 site-search WIP는 위
92b8730에서 완성·테스트 배포 완료(미결 해소).scripts/ssm_run.py는 여전히 미커밋 유지.
완료(2026-06-26) — field/modify 상차일 달력 월 표시 숫자(N월)화 (master a6208e7→deploy-live 82117a1, 운영+테스트 검증 PASS)
- 페페 검증리포트 2건(
/field/modify/1973daterangepicker): #1 월표시 영문(Dec)→숫자, #2 좌우 화살표 월 단위 이동. - 진단:
field_modify.html:375상차일 daterangepicker(singleDatePicker+showDropdowns)가locale.monthNames미설정 → moment 기본 영문 short(Jan~Dec)로 select 옵션·헤더 렌더(라이브러리 720줄). #2 화살표(.prev/.next→clickPrev/clickNext)는 라이브러리 기본이 이미 월 단위 ±1(742줄 singleDatePicker도 next 렌더) → 코드 변경 불필요. 페페 AskUser 확정="드롭다운 유지+숫자월". - 수정: locale에
monthNames: ['1월'~'12월']1줄 추가(드롭다운/헤더 텍스트만 한글 숫자월). field_modify엔 daterangepicker 1개(상차일)뿐. 작업트리 타 미커밋분(ssm_run/estimate_regist_v2 등)은 이전 세션분이라 field_modify.html만 선택 커밋. - 검증(SSM): 운영
/home/ubuntu/pfsHEAD82117a1·monthNames·'12월' 마커 True / 테스트/home/ubuntu/pfs-testHEADa6208e7동일 PASS. (py3.6라 ssm 스크립트capture_output금지→stdout=PIPE.) - deploy-live 병합 시 stray
migrations/create_dispatch_tables.sql동반(휴면 SQL·런타임 무관, 이전 배포들과 동일).
완료(2026-06-26) — 현장별자재(material-spec) 대우 용인(field 2109) 운영 등록 (spec_no=2, 읽기검증 PASS·멱등)
- 지시: NAS 2파일 참조해 현장별 자재 운영 등록. 주방=리바트 PDF 사양서, 일반=콜줌 DWG(플롯 불량→캐드파일). 일반은 미사용 도면 있으니 중복 확인·멱등 등록. ★PTA420 확정자재, B7-61 미등록(사용자 지시).
- 소스 처리: ① 주방
PDF_1.주방가구(리바트).pdf— 5타입(59㎡A/59㎡B/84㎡A/84㎡B/84㎡C) 유상옵션형 사양(door/body/edge/core/하드웨어) 직접 Read 추출. ② 일반2.일반가구(콜줌).dwg(30MB) — PDF 플롯이 빈칸·미건립 다수라 DWG 텍스트 직접 덤프: 사용자 PC 간섭 없이 DispatchEx 별개 AutoCAD 인스턴스(read-only Open→Item 반복,피호출자 거부RPC는wait_com재시도로 흡수)로 5511 TEXT/MTEXT 추출. - 프레임 파싱·dedup: MODEL 공간에
MATERIAL LIST앵커 55프레임 격자(폭~12600·높이~16800). 각 텍스트를 최근접 앵커에 귀속 → AREA/ITEM TITLE·미건립플래그·자재표 추출. 건립 25 + 미건립 30, 중복프레임(같은 가구 재도면) dedup → 고유 건립 19가구. 미건립에만 있는 8가구(파우더장 등) 등록 제외. 자재표는 라벨열(DOOR/BODY/CASING/HARDWARE/ACCESSORY 섹션 + 전면/후면/EDGE/마감/선반/뒷판/힌지/레일/다보) x≈섹션헤더x, 값열=+280 오프셋으로 행 매칭. - doc 빌드(schemaVersion 2): colors 5(YEN70-SR=59타입도어·KAEL8-SR=84타입도어·NCAC1-5JD=창고/EP폴딩·다크초콜릿PTA420·LPM PTA261)·cores 4·edges 5(CS7536/7525/7046/7300/7188)·sub 9(손잡이EU-W63/60/DH500·문주힌지·HETTICH폴딩·삼성정밀언더레일·뿔다보·환기캡). types[5] 각
groups.kitchen(PDF 1 location) +groups.general(DWG 가구별 location, 84㎡A=7·84㎡B=5·84㎡C=3·59㎡A=2·59㎡B=2). B7-61 문자열 doc 전체 0건 확인. - 운영 등록(API 세션):
POST /api/orderpaper/material-spec/(멱등 생성, 대우 용인+field 2109)→spec_no=2 →PUT /spec/2(doc+base_updated_at 낙관락)→result:ok. 읽기검증GET /api/orderpaper/material-spec/2109: 5타입·일반19·B7-61 없음·PTA420 있음. 멱등 재확인: create 재호출 시 동일 spec_no=2(중복 생성 안 함), PUT은 전체 doc 교체라 재실행해도 동일 doc·중복 없음. - 스크립트(scratchpad):
dump_dwg_text.py(DispatchEx 덤프)·parse_frames.py·extract_general.py·build_doc.py. 단가 미입력(자재 사양만, 견적 아님).
완료(2026-06-25) — pfs 검증 5건 운영 배포 (master 0290966→deploy-live 68816cc, 테스트+운영 배포·검증 PASS)
- 페페 검증리포트 5건. 작업 전 질문으로 동작 확정 후 진행.
- #1 상차일 검색(견적 regist-v2 모달): 당일 이전 1개월 유지 + 당일 이후 전체. 구현=
select_site_searchSQL에서date_to비면 상한(shipping_date <= %s) 제거, 컨트롤러 default_to 폐지(빈값), 프론트openSiteSearch가siteDateTo를 빈값으로 진입(from=당일-1개월만 세팅). 사용자가 to 직접 입력 시 그 범위. 검증=운영 site-search date_to 비움→미래(20260626) 포함, to=20260201 지정→그 이후 0건(상한 동작). - #2 업체 자재분류 배지(company-permission): 발주이력 휴리스틱(
_classify_industry) 추론 배지 → 업체관리 등록 자재(company.product_div) 실제값 표기. 백엔드 무변경 —company/search응답이 이미product_div_name(CONVERT_MULTI_COMMON_CODE 콤마연결) 보유. 프론트rowHtml에서st.industry대신c.product_div_namesplit→배지. 미입력 업체(운영 122개)는 빈 칸. (발주일·건수 cp-ord는 유지, industry 필터 셀렉트는 잔존이나 배지와 별개.) - #3 권한 매트릭스 그룹 분리 + 일괄(admin/user '유저 오버라이드'): flat 리스트 → 업체관리(company_permission.js) 패턴 그대로 이식 — menu_catalog
parent_menu_key로 그룹화(부모=url_path NULL 헤더), 전체/그룹 헤더행에 '상속·허용·차단' 일괄버튼(라디오 3개라 company-perm의 2개와 달리 3버튼·colspan4).#permMatrixBody .cp-bulk-btn위임 이벤트. CSS는 user.html에 인라인(company_permission.html 복사+nth-child(4) 추가). 검증=테스트 menu_catalog 그룹7/리프34 구조 확인. - #4 현장담당자 모달 필터 + 역할(field/regist, admin/user): ① 새 컬럼
user.is_field_manager CHAR(1) DEFAULT '0'(patch37, 멱등 ALTER) — 기존field.field_user_no로 쓰인 직원 시드 ON(테스트·운영 각 4명). ② 모달 목록 APIGET /api/user/(select_user_list)에JOIN company c ... company_type='1' AND a.is_field_manager='1'필터(이 API는 member_popup 전용이라 직접 필터 안전). ③ admin/user에 '현장담당자' 토글 체크박스(user.html)+selectUser/saveDetail 배선+admin_dao select/update에 컬럼. 검증=테스트·운영 user/ 정확히 4명(전체 아님). 운영DB ALTER 선행→코드배포 순서 준수(컬럼 없으면 admin select 깨짐). - #5 사이드바 가로폭 260→210px: pfs_layout.css에 override 3줄(
.left-sidebar width / .mini-sidebar left / @1024 .page-wrapper margin-left, !important). 테마 style.css 직접수정 안 함. - 부가: 정적 JS/CSS 캐시버스터 통일 — company_permission.js(
?v=20260620e수동)·user.js(없음)·pfs_layout.css(base.html?v=20260619b수동)를 전부asset_ver()(파일 mtime 자동)로 교체. estimate_regist_v2.js는 이미 asset_ver. - 화면 시각검증은 pw-chrome-profile 락(타세션 점유)으로 미수행 → 정적 마커(운영 전부 OK) + 백엔드 API(상차일/모달) + DB 데이터 정합성(메뉴 그룹구조·배지값)으로 갈음. 변경 파일 13개. migrations/patch37_user_field_manager.sql 추가.
완료(2026-06-25) — field/worklog 전체 펼침/접기 토글 + 기본 2개월 기간제한 + 전체 검색 (master f5c9aa2→deploy-live 1c11aaf, 테스트+운영 배포·API E2E PASS)
- 운영 검증(pfs.poin.co.kr, API 로그인): 기본 146현장·검색 q=현장 70현장·date_from=미래 0현장(기간게이트)·1년초과 클램프 정상. 배포마커 전부 OK.
- 미연결(field_no IS NULL) 포함 확인(페페 사후질문): 쿼리가 미연결을 배제 안 함 —
GROUP BY ... CASE WHEN field_no IS NULL THEN site_name으로 site_name 단위 묶음, 기간게이트·검색·privacy 절이 연결/미연결 동일 적용. 운영 실측: 기본 146 중 미연결 123, q=현장 70 중 미연결 60, q=오산 5 중 미연결 2. site_name이 4개 검색컬럼에 포함돼 미연결도 현장명으로 검색됨. 수정 불필요. - 페페 지시 3건: ① 항목별/전체 펼침·접기 빠른 토글(펼침 시 완료현장·완료항목 폴딩까지 전부). ② 기록 누적→무한로드 낭비, 기본 노출 최근 2개월·인라인 검색은 DB 전체·기간 최대 1년·더 오래된 건 사용자가 기간 직접 설정. (확정: 기간제한=현장묶음 자체 필터 / 검색=work_name+excerpt+note+site_name 4컬럼 / 검색결과=기존 카드구조+전체펼침)
- 백엔드(
worklog_dao/service/controller):select_worklog_site_summary(owner_user, date_from, keyword)— date_from 있으면HAVING MAX(a.work_date) >= %s(WHERE로 자르면 카드 과거항목 사라짐→HAVING), keyword 있으면 4컬럼 LIKE OR(검색모드도 date_from 하한 유지=무한조회 안전망). service_clamp_date_from=[오늘-365,오늘] 클램프. controller?date_from(미지정=오늘-60일)·?q. items 쿼리 무수정(카드 펼침은 기존대로 field_no/site_name 전체로드). 파라미터순서=pp+owner+kw+having(SQL %s 등장순). - 프론트(
field_worklog.html인라인):wl-ctrlbar(검색창 300ms 디바운스·<input type=date>min=오늘-1년/max=오늘·전체펼침 토글버튼).WL_EXPAND_ALL플래그 1개로 비동기 항목렌더 동기화(renderItems가 done폴딩 open 결정→setTimeout 경쟁 회피). expandAll/collapseAll은 기존 toggleSite/loadItems/toggleItemDone/toggleDone 재사용. 검색 시 결과 전체펼침 자동. - 검증(테스트 8001, API 로그인 후 직접): 배포마커 전부 OK. 기본 46현장·q=현장 10현장·date_from=미래 0현장(게이트 동작)·1년초과 클램프 동작. 프론트 클릭검증은 pw-chrome-profile 락(타세션 점유) 미수행 — JS가 기존 토글 재사용이라 정적 배선확인으로 갈음.
완료(2026-06-25) — 견적 엑셀 부분출력 현장블록(A6~F11) 빈칸 수정 + 결재칸 이미지 L39~O41 정렬 (master 9150576→deploy-live 25457db, 테스트+운영 배포·검증 PASS)
- 페페 2건: ① 추가건/일부 페이지만 출력 시 종합 첫 페이지에서 가져오던 현장블록(A6~F11)이 연결 안 돼 빈칸 → 부분출력 시 항상 첫 페이지에 현장정보 입력, 나머지 페이지는 위치고정값으로 동일 블록 참조. ② 결재칸 이미지 위치 비율 안 맞음 → L39~O41에 딱 맞게.
- 이슈1 근본:
_render_block_header가 현장블록 origin(실값)을종합시트 첫 블록으로 하드코딩(ORIGIN="종합"), 나머지 블록·시트는=종합!$A$6~$A$11참조 → 부분출력으로 종합 시트가 빠지면 그 참조가 존재하지 않는 시트를 가리켜 빈칸. 수정: origin=sheets[0](출력 첫 시트)로 동적화 —build_excel이origin_sheet_name=sheets[0]["sheet"]계산 →_render_sheet_blocks(is_first_sheet, origin_sheet_name)→_render_block→_render_block_header체인으로 전달. 첫 시트 첫 블록=실값, 나머지=={첫시트}!$A$고정참조(_sheet_ref가 시트명 인용). header는 main 기준 1개를 전 시트 공통 보유라 첫 시트가 추가건이어도 실값 정확. - 이슈2:
_render_approval_boxOneCellAnchor+고정 px(K38·311×112)→ TwoCellAnchor(L39col=11·row=base+38~ P42경계col=15·row=base+41)로 L39:O41 정확 정렬(공급자 이미지 방식). px 고정·비율 의존 제거. - 검증: ① 로컬 openpyxl 모킹빌드 3케이스(전체/추가건만/본건만) — 첫 시트 A6~A11 실값·비origin은
=origin!$A$참조·결재앵커 from(11,38)→to(15,41). ② 테스트서버 실 xlsx(임시 추가건 718·부모 710): 부분출력(pages=sub:718) 첫 시트 A6=넥서스·A10 현장명 실값(빈칸 아님)·결재 L39:O41, 전체출력 종합 origin 정상. 임시건 soft-delete 정리(710 추가건 0). 백엔드 1파일(estimate_print_service.py)만 변경. - 운영 배포 완료(2026-06-25, deploy-live
25457db): 페페 "반영 성공, 운영 배포 진행". 운영 라이브 711(추가건 712~720 보유)로 읽기전용 재검증 — 부분출력(pages=sub:712, 종합 제외) 첫 시트 A6=넥서스·현장명 실값(빈칸 아님)·결재 L39:O41, 전체출력 종합 origin 정상 PASS.
완료(2026-06-25) — 견적서 출력 페이지 선택 모달 재설계: 체크박스 폐지·카드 색상 단일 소스 + 그룹/전체 일괄 (master 18ee277→deploy-live e2dc45b, 테스트 Playwright + 운영 검증 PASS)
- 페페: ① 본건/추가건을 그룹별로 일괄 선택·해제 + 전체선택·전체해제 버튼 ② 카드 선택과 페이지별 체크박스가 desync(페이지 선택 자체는 체크박스로 작동 중) ③ 체크박스 폐지·카드 색상 반영으로 선택/해제, 프로세스 반영 검증 후 운영배포.
- 근본(desync): 모달 카드가
label>checkbox구조 — 카드 클릭은.on+체크박스 토글하나 체크박스 직접 클릭 시 핸들러 early-return(e.target===INPUT)으로.on미갱신,applyPageSelect는input:checked(체크박스)를 읽어 색상(.on)과 실제 선택이 분리. → 체크박스 제거, 카드.on(색상+✓)이 유일 소스, 적용=작업용 Set(modalSel)을 그대로State.selectedSheets로 커밋. - 수정(프론트 3파일·백엔드 무변경):
web/static/js/estimate_print_v2.js—groupOf(summary=종합 / main·type-detail=본건 / sub-estimate=추가건),renderModalGroups(그룹 섹션+카드, 체크박스 없음),toggleModalKey/toggleModalGroup/setAllModalSel/updateModalCounts,cardEl(속성선택자 이스케이프 회피로 특수문자 key 안전).estimate_print_v2.html— 전체선택/해제 버튼+카운트+page-pick-groups컨테이너..css— 그룹/액션 스타일·.on::after ✓·죽은 체크박스 룰 제거. 빈 선택 시 엑셀/PDF 다운로드 가드(전체 다운로드 오작동 방지). 선택 키(종합/본건/타입명/sub:<no>)→pages=→백엔드 key 필터 프로세스는 그대로. - 검증(테스트 Playwright, 임시 추가건 717로 부모 710에 3그룹 구성): 종합1·본건5·추가건1, 체크박스 0개, 카드토글/본건 묶음(5)/종합 묶음/전체선택·해제 카운트 정확, 교차그룹 선택(종합+sub:717) 적용→렌더 정확히 2페이지, 엑셀 요청
pages=종합,sub:717·다운로드 xlsx 시트=['종합','ZZ_GROUPTEST_TMP'](본건/타입 제외) PASS. 임시 추가건 soft-delete(remove_yn) 정리(710 추가건 0 복귀). 운영=JS/CSS 바이트동일·HTML 신마커·HEADe2dc45b확인. (운영 print는 로그인 필요 — 모달은 순수 프론트+백엔드 무변경이라 테스트 검증으로 동작 보장.) - 캐시버스터(직전 작업
b6d1ee8)로 브라우저가 새 JS 자동 신선 로드(수동 새로고침 불요).
완료(2026-06-25) — 견적서 출력(print-v2) "페이지 선택→엑셀 반영" 운영 미반영 = 캐시버스터 누락 수정 (master e53a916→deploy-live b6d1ee8, 운영 검증 PASS)
- 증상(페페): 6-22 배포한 "페이지 부분 지정 후 엑셀 다운로드 반영"이 운영서 안 보임. "완료됐는지 시드 확인 + 운영 미반영".
- 진단(배포 누락 아님): deploy-live에 6-22 커밋(
7a28611/729c673) 전부 포함·로컬==원격(3ced907), 운영 라이브가 서빙하는estimate_print_v2.js가 배포본과 바이트 동일(차이는 로컬 CRLF뿐, 둘 다 14768B)=운영은 최신 print 코드를 이미 가동 중. 진짜 원인=web/templates/finance/estimate/estimate_print_v2.html이 print css/js·qa_helper css/js를?v=캐시버스터 없이url_for('static')로 로드 → 서버 Cache-Control(max-age=43200=12h)로 브라우저가 6-22 배포 전 구버전 JS를 계속 사용. (asset_ver 버스터가 등록화면estimate_regist_v2.html엔 있으나 출력화면 누락 = 드리프트.) - 수정: 4개 정적 include에
?v={{ asset_ver('<path>') }}추가(web/__init__.pycontext_processor, mtime 정수). jquery 벤더는 base.html도 미적용이라 제외. 새 URL이라 다음 페이지 로드 시 자동 신선 fetch(사용자 수동 강력새로고침 불요). - 운영 배포(페페 "master 전체" 선택):
e53a916(캐시버스터 1파일)+동봉bbe3cbb(아래 수량/단가 가드) deploy-live 병합·push(3ced907..b6d1ee8). 런타임 무관migrations/create_dispatch_tables.sql은 자동실행 안 됨. 운영 서비스=pfs-live.uwsgi.service(active) —systemctl is-active pfs는 유닛명 불일치로 inactive 오표시. 검증 PASS=prod HEADb6d1ee8·템플릿?v=4줄·pfs.poin.co.kr/200·JS 200.
완료(2026-06-25) — 견적 v2 타입 항목 수량 항상 편집 가능 + 단가×수량 합계 미반영 버그 루트픽스 (master bbe3cbb→deploy-live b6d1ee8, 테스트+운영 배포 완료)
- 페페 2건: ① 타입 하위(메인 행) 수량 컬럼 사용자 편집 가능(평소 자동=저장값, 입력 시 그 값 유지 — '단순 편집' 채택, 마진식 토글 아님). ② 방금 만든 추가건(견적720)에서 단가×수량이 합계에 미반영 발견.
- 근본원인(동일 뿌리):
estimate_regist_v2.js메인행 수량이_isNew새 행만 입력칸, 기존(저장)행은 읽기전용 텍스트(cellForColqty). 단가 수정 시updateInlineDetail이d.qty = parseInt($tr.find('.qty-cell').val()) || 1실행 → 기존행엔.qty-cell부재라.val()=undefined → 수량이 1로 덮어써짐 → 금액=단가×1. (그 상태 저장 시 DB qty=1 영구기록 위험). 금액모델=unitDim×단가×수량, unitDim=(치수합−코너합)/300; 추가건은 dimension1=300이라 unitDim=1 → 금액=단가×수량. - 수정 2곳: ① qty case=기존 행도 입력칸 렌더(단가칸 QA#3 전례와 동일) ②
updateInlineDetail=.qty-cell있을 때만 읽도록 가드(없으면 기존값 보존). 정적 JS=asset_ver(mtime) 자동 캐시버스트. - 검증(Playwright, 테스트 견적710 비저장): qtyIsInput=true(기존행도 input) / 수량 1→3 변경 시 금액 510,000→1,530,000 / 단가 1000 입력 후 수량 3 유지·금액 3,000(=1000×3, 버그 전이면 1,000) PASS.
- 운영 배포 완료(2026-06-25, 코디): print-v2 캐시버스터 배포(
b6d1ee8)에 페페 "master 전체" 선택으로 함께 운영 반영 → 버그(단가 입력 시 수량 1 손실)는 운영서 해소.
완료(2026-06-25) — AS GS오산 도어발주서 추가건5 견적 운영 등록 (페이지 20, 추가건 견적 정리 스킬)
- 페페 지시: NAS
…도어발주서.xlsm'포인' 20p 블록만 → 부모 711(field_no 2098)에 추가5 별개 운영등록. 운영 RDS·승인("진행해"). - 결과(운영 DB 검증 PASS): 추가5=견적 720(10줄: 124현관엣지바도어·픽스, 84B상부장안정기함, 침실3 상부가림판 3종[84A/84B/124], 냉장고 상부가림판 4종[전시부스/84A/84B/124]). 711 추가건=712·713·716·717·720(5건). price=0·price_no=null(단가 스태프 추후).
- 엣지케이스(스킬 보완):
전시부스 냉장고 상부 가림판(유상)은 숫자접두 없어 자동 heuristic이 부품 오분류·누락 → 부재 아닌 독립 완제품이라MANUAL_STANDALONE로 수동 포함. 스킬 §3 규칙3 보완(비-부재 완제품이 접두 없이 나오면 수동 포함 검토). 스크립트order-automation/build_and_register_add5.py, 페이로드payloads/payload_add5.json. 스킬 전문=C:\dev\order-automation\견적등록_스킬.md.
완료(2026-06-24) — 현장유형(field_div) 셀렉트 하드코딩 제거 → common_code(FIELD_DIV) 매핑 (master 039c9ee→deploy-live 3ced907, 테스트·운영 검증 PASS)
- 페페(검증리포트):
/field/regist유형 셀렉트가 하드코딩인지 확인 → 하드코딩이면 common_code 항목으로 매핑 + '개인건' 추가. - 진단:
field_regist.html·field_modify.html둘 다<select name=field_div>옵션을 하드코딩(10MH/20OT/30SH/40연고/50내수/60AS). 반면 목록·상태 표시는 이미CONVERT_MULTI_COMMON_CODE(field_div,'FIELD_DIV')로 common_code를 읽음 → 폼만 드리프트. DB 조회 결과 test·prod 양쪽 common_code FIELD_DIV에 '개인건'(code 70, code_no 78, display_order 5)이 이미 존재(누군가 추가했으나 하드코딩 폼이라 미노출, field 테이블 실사용은 아직 0). → DB 변경 불필요, 매핑만으로 노출. - 수정(서버사이드 렌더, 3파일):
web/pfs/basic/controller/field_controller.py에_field_div_list()(FIELD_DIV를common_code_service.get_common_code_search_list로 조회 후 display_order 정렬) 추가 → regist·modify 라우트에field_div_list전달. 두 템플릿의 하드코딩 옵션을{% for c in field_div_list %}<option value="{{c.code}}">{{c.value}}</option>{% endfor %}로 교체. 클라이언트 async 경합 회피(modify의.val()가 이미 DOM에 있는 옵션에 적용됨) + common_code 단일 출처. 웹 레이어가 api service 임포트하는 선례=default_controller. (MySQLUtil=DictCursor라 Jinjac.code/c.valueOK.) - 검증(테스트 8001 + 운영 pfs.poin.co.kr, 서버 로그인+HTML 파싱): regist·modify 둘 다 옵션 =
10,20,30,40,70,50,60(개인건 70이 연고와 내수 사이, display_order순),has_70=True. 양쪽 PASS. JS의field_div==='60'(AS 본건연결) 로직 무영향(코드 60 유지). - 운영배포(페페 "운영 배포 진행해" 지시): master→deploy-live 병합. 병합 전 검증=
deploy-live..master는 내 커밋039c9ee단건뿐(배차관리 dispatch 기능은4a02754로 이미 deploy-live 조상=운영 반영 완료 상태), 병합 트리 변경=정확히 field_div 3파일만(straymigrations/create_dispatch_tables.sql는 deploy-live 상태 유지·런타임 무관). deploy-live3ced907push→운영 검증 PASS. (참고: ssm_run.py 로컬 미커밋분은 stash로 격리해 운영 미포함.)
완료(2026-06-24) — orderpaper 자재관리 정렬규칙 교체 + 사용자지정 다중정렬 컨트롤러(엑셀 정렬식) + 고정값 영속 (운영배포 deploy-live 739fc86, 테스트·운영 Playwright PASS)
- ⚠ 후속 정정(같은 날, master
5f087c7→deploy-live739fc86): 1차 산출한 "엑셀 고급필터형 상세필터 모달"이 페페 의도와 달랐음 — 페페가 원한 건 엑셀의 '정렬' 대화상자(열 선택 + 오름/내림 + 기준 추가/삭제/순서이동으로 사용자지정 다중정렬). → 필터 모달 전면 제거(CHK/passFilter/range/onlyStock 삭제), 모달을 정렬 기준 빌더로 교체.S.sort=[{col,dir}...]다중기준을cmp가 순차 적용(1차·2차…, 같으면 다음), 기본값DEFAULT_SORT=[fco↑,order↓,recv↓,mt↑]. 컬럼 헤더 클릭=단일 빠른정렬(S.sort 1개로). 블록은 1차 기준 값으로 일반화 묶음. 버튼 '↕ 정렬 기준'(라벨 기본/N단계). localStorage 동일 키pfs.op.mm.state.v1(sort/mat/block/검색). 검증=테스트 기본4기준 렌더·커스텀[재고량↓,발주처↑] DOM 완전일치·삭제/추가/이동·새로고침 영속 / 운영 기본정렬 165행 완전일치·구필터모달 제거 확인. 캐시버스터 JS v20260624e·CSS v20260624d. 아래 1차 산출 설명은 이력(상세필터→정렬로 대체됨). - 페페 지시: 재고량 입력 후 정렬이 어긋남 → 정렬을 ①업체(발주처)+발주일 블록 ②입고일↓ ③원자재→엣지→부자재 로. + 엑셀 고급필터 같은 상세필터 컨트롤러 추가, 그 설정을 페이지 고정값으로 저장. 운영배포까지. (질문2 확정: 저장=localStorage[op_filter_v1과 동일], 블록 1차=발주처 가나다→발주일 최신순.)
- 정렬 교체(
orderpaper_material_mgmt.jsbaseRule): 기존 "자재분류 1차" 폐기 → 1차 발주처(furniture_company) 가나다 asc → 발주일(order_date) 최신순(desc), 2차 입고일(effRecv) desc, 3차 R→E→S, tie=orderpaper_no. 컬럼 헤더 클릭은 임시 override(그 컬럼 1차 + baseRule tie-break),sortCol='default'=고정규칙. 블록모드는 (발주처,발주일) 경계마다 구분행 삽입(자재색 클래스 폐기, 중립 슬레이트). - 상세필터 모달(메인탭
op-fmodalCSS 재사용, 신규#mmFmodal): 체크박스 dims 발주처(furniture_company)·출고처(vendor)·상태 + 범위 발주일·입고일(date)·발주량·재고량(num) + '재고 있는 항목만'.passFilter로rows()적용. 명시 날짜범위 설정 시 기본 롤링창(최근1/3개월) 해제(지정 기간 존중). 뱃지=상세필터 제약 수. - 영속:
localStorage 'pfs.op.mm.state.v1'에 mat·block·sortCol/Dir·검색·checked·range·onlyStock 저장(saveState). 모든 상태변경 후 자동저장, init·switchTab에서loadState복원 → 재방문 시 고정값 유지. - 검증(Playwright): 테스트 — 정렬 157행 DOM=독립 재현 baseRule 완전일치(불일치0) / 상세필터 렌더(체크박스3·날짜4·숫자4·재고있음) / 완료제외 157→57·뱃지 / 새로고침 후 필터 유지(영속) / 블록 24그룹 발주처+발주일. 운영 — 164행 정렬 완전일치 + 모달 정상. 둘 다 PASS.
- 커밋 master
169ca0a(JS/CSS/HTML 3파일, 캐시버스터 JS v20260624d·CSS v20260624c) → deploy-live3260fd3(운영). 병합에 사이드카 전용dede794(qty→stock 복사)도 포함됐으나 EC2 미실행 휴면파일이라 운영 런타임 무관.
완료(2026-06-24) — orderpaper 재고관리 엑셀 → 운영 재고량 시드 + 동기화 신규항목 발주량 복사
- 페페: 기존 재고관리 엑셀(.xlsm
RawData시트)의 '남은 수량'(I열)=재고량을 맥락 매핑으로 운영orderpaper.stock에 기입. 미매칭=0(신규 생성 안 함, 운영은 26년만·엑셀 25년 이전 무시). + 앞으로 동기화 신규항목은 발주량(qty)→재고량(stock) 복사. - 매핑(페페 확정): 현장+자재코드(+발주량) 우선 → 없으면 자재코드만(전사 재고), 중복 시 최근 주문건. 자재코드는 운영 item_name/spec에서 추출(R은 spec, E/S는 item에 코드). 운영 활성 1158행 중 187행 비0 기입(엑셀 남은수량), 나머지 0. 엑셀 2025+ 1853행 기준.
- Part A 적용:
_mm_apply_prod.py(전체 stock='0' 후 매칭 187건 CASE 기입, 멱등·prod 가드). 운영 페이지 검증=OP_ALL 전부 stock 보유(null 0)·시드값 일치(no1=5/발주9, no317=14/발주38), 소수(3.5) 보존. - Part B 코드(웹 배포 불필요·로컬 사이드카 경로):
orderpaper-sync/orderpaper_sync.py·orderpaper_upload_load.pyINSERT에 stock 컬럼=qty 복사, ON DUPLICATE엔 stock 미포함→재동기화 시 보존(qty 변경이 재고 안 덮음). 사이드카orderpaper_sync_server.py가 두 스크립트 호출(로컬 실행)이라 다음 동기화부터 적용. 테스트 DB 합성행 검증 PASS(신규=stock=qty, 재동기화=stock 보존). masterdede794. - 세션=
session-2026-06-24-orderpaper-stock-seed-and-sync.md.
완료(2026-06-24) — orderpaper 동기화(발주서 정리) 복구 (PC 이전 후 사이드카 SSM 단절 근본수정)
- 증상: 발주서 정리 '지금 동기화' 버튼 눌러도 완료 표시 안 됨(요청 #9가 pending 고착, claim 자체 안 됨).
- 근본원인: 로컬 동기화 사이드카(
orderpaper_sync_server.pyPID상주, 06-23 기동·시스템 Python39)가 venv에만 설치된awsCLI(pfs/.venv/Scripts)를 PATH에서 못 찾음 →ssm_run.py의shutil.which("aws")=None → SSM claim/finish/업로드 전부 실패. 사이드카·릴레이·orderpaper_sync.py업로드가 모두ssm_run.py단일 경유라 여기 한 곳이 막히면 전체 정지. - 수정(1곳):
pfs/scripts/ssm_run.py— aws 해석에 venv 폴백 추가. PATH에 aws 없으면[.venv/Scripts/python.exe, .venv/Scripts/aws](확장자 없는 awscli 진입 스크립트)로 직접 실행 → PATH 무관하게 동작(aws.cmd는 PATH에서 python을 찾는데 사이드카 PATH엔 python 없어 깨짐). 사이드카 재시작 불필요(매 폴링 fresh subprocess라 즉시 반영). - 검증: 사이드카가 패치 후 #9 자동 claim→done(start 04:58:06→done 04:58:40,
files:23 items:1238 round R178227). 시스템 Python39+venv없는 PATH로 ssm_run 재현 시 Status:Success. NAS(\\192.168.0.101\공유폴더\2026현장\원부자재발주서)는 정상 접근(6개 월폴더 리스팅) — #8의 06-23 WinError53은 일시적 네트워크 미구성, 현재 해소. - 부가수정: 스케줄 자동동기화
orderpaper_autosync_hidden.vbs의set PYTHONUTF8=1 &&→&&앞 공백으로 값이"1 "(공백포함)가 돼 Python preinit fatal(invalid PYTHONUTF8,_autosync.log981줄).set "PYTHONUTF8=1"로 수정(VAL='1' 검증). 이 경로 업로드도 위 ssm_run 폴백으로 함께 복구됨. - 미커밋(pfs 로컬 변경 2파일): 운영앱 무관한 로컬 사이드카 전용 파일이라 master push(=테스트 EC2 배포) 보류 — 필요 시 사용자 승인 후 커밋. 현재 로컬에서 즉시 작동 중.
완료(2026-06-24) — orderpaper 자재관리탭 마감 3건 + 운영배포 완료 (master 0842082→deploy-live f8c1905, 운영 Playwright 검증 PASS)
- 페페 지시 3건: ①가로폭 풀폭 확장 — 컬럼 많아 가로 스크롤 생기던 문제.
op-mm-activebody 클래스로.op-wrap1180px 제한 해제(일정탭op-sched-active패턴 재사용), 타 탭 전환 시 클래스 제거(4탭 상호배타). ②비고 시작기호(● mm-syncdot) 삭제 — rowHtml에서 제거 + 죽은 CSS 정리. ③블록모드 자재토글 활성 —rows()필터를 블록 무관하게S.mat적용(기존 #6 "블록이면 토글 무시" 로직 폐기),mm-disabled비활성화 로직·CSS 제거. 블록 ON에서도 R/E/S 빠른토글 동작. - 운영 DB stock 선행 ALTER: 직전 세션 미배포분(자재관리탭 전체+재고량)이 이번에 운영 첫 배포라, 운영
orderpaper에stock컬럼 없으면o.stockSELECT가 깨짐 → 배포 전 운영 ALTER 먼저 실행(멱등,_mm_stock_alter_prod.py, ADD COLUMN VARCHAR(50) NULL AFTER qty_user). probe로 운영 stock 부재 확인(HAS_STOCK=False) 후 ALTER → 코드 deploy-live. - 검증(운영 Playwright): OP_ALL 498건·stock키 존재(백엔드 500 없음) / 풀폭
max-width:none·가로스크롤 없음 / syncdot 0·● 없음 / 블록 ONpointer-events:auto·부자재토글 186↔596행 변동. 3건+백엔드 전부 PASS. - 세션=
session-2026-06-24-orderpaper-material-mgmt-finalize.md.
완료(2026-06-24) — orderpaper '📦 자재관리' 첫 탭 신설 + 재고량 RDS 영속 (테스트 배포·실작동 검증 PASS, 운영배포 완료↑)
- 페페: orderpaper에 자재관리를 첫 탭으로 추가. 발주서 정리와 같은 DB값(
OP_ALL=/all-items) 을 순수 테이블로(남은 재고 빠른 파악). 목업(qa_helper 내장)으로 3라운드 피드백 → 실앱 통합 → 테스트 배포 → 재고량 RDS 영속. - 신규 프론트:
web/static/js/orderpaper_material_mgmt.js(window.opMM)+css/orderpaper_material_mgmt.css.field_orderpaper.html첫 탭버튼·#opMMWrap·loadAll restore/renderGroups refresh 훅.orderpaper_schedule.js·orderpaper_material.jsswitchTab에 opMMWrap 정리(4탭 상호배타). - 기능: 컬럼=자재분류(드롭다운 R/E/S)·발주처(가구업체)·현장명·품명·규격·발주량·재고량(입력)·출고처(vendor)·비고(동기화)·입고일(블록 입고일 승계). NO 컬럼 숨김. 삼중 정렬 1차 자재분류(R→E→S)·2차 입고일↓·3차 발주서↑ + 전 컬럼 클릭정렬. 빠른토글 R/E/S(부자재 기본OFF)+블록(발주처별 묶음, 기본OFF=플랫; ON이면 자재토글 무시 R/E/S 함께)+통합검색+초기화. 기본 노출 최근 1개월·검색 시 3개월(완료 숨김 없음).
- 날짜 버그(교훈):
/all-items는 날짜를 RFC1123(Wed, 15 Apr 2026 00:00:00 GMT)로 줌(Flask datetime 직렬화) —YYYY-MM-DD만 파싱하면 그대로 통과(목업 하네스가 ISO라 가려짐).toDate()가 두 형식 다 파싱→M.D(요일), 정렬도 ms 기준. - 재고량 RDS 영속(#3): 테스트 DB(
poin-dbinstance-test)orderpaper에stock VARCHAR(50) NULL추가(SSM).select_all_items에o.stock,PATCH /api/orderpaper/<no>/stock(daoupdate_item_stock/servicemodify_item_stock, qty 패턴 동형). 프론트 입력 확정 시 서버 PATCH(입력중 하이라이트). 자재분류 드롭다운 변경만 localStorage(전용 컬럼 없음). - 검증: 테스트서버 실 HTTP e2e(SSM) — all-items 200·stock키존재 /
PATCH /49/stock200 → RDSstock='99.9'일치 → 원복. 페페 "모두 정상 작동 확인완료". - 커밋(master=테스트):
19399d2→8882ba7→8c95e2c. 운영배포 완료(2026-06-24, 위 마감 3건과 함께 deploy-livef8c1905) — 운영 DBstockALTER 선행 후 배포. 재사용 스크립트pfs/scripts/_mm_stock_alter_prod.py·_mm_stock_probe_prod.py·_mm_http_e2e.py. 세션=session-2026-06-24-orderpaper-material-mgmt-tab.md.
완료(2026-06-22) — worklog 2차: 맥락파악 매핑 + 진행중/대기중(active) 현장 우선 (master c8a8fca→deploy-live 31781ae)
- 페페 지시: 1차(정확/강한추정) 후에도 미연결 多 → 유사 현장명도 맥락파악으로, 진행중/대기중 현장 기준으로 매핑. 운영배포.
- 맥락 매핑(서브에이전트 4분할·데이터 작업): 미연결 154묶음의 항목 맥락(
work_name·통화excerpt·note의 오디오출처=연락처[예 "넥서스김선정과장"]·status) + 묶음별 현장후보 shortlist(업체/토큰 매칭, active=상차 최근180일/미래)를 생성 → 후보있는 104묶음을 4청크로 LLM 판단(업체·지역 일치 + active 우선 + 배차/배송/거래처 등 비-현장 skip + 모호 skip). 28건 map 중 비활성 타겟 2건 제외 → 26묶음 49항목 운영 연결(GS인천 변형7→#2113·에넥스5→강동식차장#2074·학동3→#2065·신동혁2·라인VIP2·GS오산양산2·대전2·천안더힐·IS동서울산·쌍용홍은동). 미연결 154→128(잔여=후보없음51 + 모호[활성후보 복수]·비현장77). 롤백로그pfs/scripts/_wl_semantic_rollback_prod.json(49건). 맥락 입력/청크/결정pfs/scripts/_wl_*.json(미커밋). - 코드 개선(영속·향후 적용): auto-link 게이트에 동점(모호) 시 active 현장 우선 해소(
_is_active_field상차일 180일, winners 중 active 1개면 확정). 단위테스트 active 타이브레이크 추가(10 PASS). 테스트 실증=에넥스(강동식차장)이 동명 #1897(비활성)/#2074(활성) 중 활성 #2074로 자동해소(이전 ambiguous). 운영 dry-run connect=0(잔여 모호는 활성후보 복수라 자동해소 불가=유지가 맞음). - 표준규칙 확장 → playbook §6(맥락 매핑 절차 + active 우선). 적용은 배포된 API 경유만(aws/SSM 미복구).
완료(2026-06-22) — 견적 추가건 '출력 포함' 토글 DB 영속 (엑셀/PDF 출력 반영 버그·적대검토) (master 9e6bf67→deploy-live 7a28611)
- 증상(페페):
/estimate/print-v2엑셀 다운로드에 추가건 별도 출력 설정이 반영 안 됨(이전 작업했으나 미해결). 적대적 검토 에이전트가 원인 확정. - 근본원인(H2): 견적등록 화면 추가건 '출력 포함' 체크박스(
estimate_regist_v2.js)가 프론트 State만 변경·API 미호출,saveEstimate페이로드에도 추가건 없음, DAOupdate_include_in_print는 호출처 0 → DBestimate.include_in_print항상 기본 '1' →compose_pages/compose_sheets가 그 값 읽어 체크 해제 추가건도 엑셀·출력에 항상 포함. (H1 페이지선택 매핑은 이전c45f601로 해소, 콤마는 encodeURIComponent로 안전, 동일이름 추가건 Set충돌만 엣지 잔존.) - 수정: 백엔드
PUT /api/estimate/<no>/include-print {include_yn}신설(estimate_controller+estimate_service.set_include_in_print, 기존update_include_in_print연결). 프론트 토글 즉시 호출+실패 롤백. 캐시버스터asset_ver()자동. (추가건은 estimate 별개 레코드라 부모 저장과 독립, autosave 폐지 원칙 무관한 단발 설정.) - 검증(전부 PASS): 테스트 영속 round-trip + 풀 E2E(임시 추가건 생성→토글 ON=엑셀 시트 포함/OFF=시트·출력페이지 사라짐/ON=복귀→삭제 정리) + UI(Playwright 체크박스 클릭→
PUT .../714/include-print 200) / 운영 엔드포인트 round-trip(원복 정확)+실견적 711 추가건 4건 엑셀 시트 반영(read-only). 세션=session-2026-06-22-estimate-include-print-toggle.md. - 후속 해소(master
e92d327→deploy-live729c673): 동일 estimate_name 추가건 2개 개별 선택 불가 엣지를 출력 선택키를 estimate_no 기반(sub:<no>)으로 전환해 해결 —compose_pages가 page에key부여(추가건=sub:<no>, 그 외=시트명)+필터 key화,compose_sheets._inc_sub키매칭,estimate_print_v2.js선택/렌더/모달을p.key(data-key+attr(), 숫자형 타입명.data()Number변환 회피)로. 이름/특수문자/31자절단 충돌 전부 무관. 검증 PASS=테스트 중복이름2개(715/716) 개별선택·비추가건 회귀無·Playwright 모달 라운드트립(84B해제→5p)/운영 711 추가건4건 키선택 read-only.
완료(2026-06-22) — worklog 미연결 묶음 추정현장 자동연결 기능 신설 + 운영 적용 (master 12dfe79→deploy-live c054dd3)
- 페페 지시: worklog(카톡/통화 수집 작업로그)의 미연결(field_no NULL) 묶음 중 현장 추정된 것은 해당 현장에 연결, 추정 안 된 건 그대로 유지. 앞으로도 worklog 작업 시 추정현장 자동연결(→ playbook §5 표준규칙). 운영배포까지. 서브에이전트 분할.
- 신설 기능(서브에이전트 2분할: 백엔드/프론트): 서버측 추정 자동연결. 프론트
wlSimScoreJS를 Python 포팅(worklog_service._wl_sim_score).POST /api/worklog/auto-link {dry_run,threshold}— dry-run 미리보기 + 적용. DAOselect_worklog_unlinked_groups(숨김·privacy 적용)·select_worklog_nos_by_site_name(롤백).field_worklog.html🔗 추정 현장 자동연결버튼+미리보기 모달(연결예정/약한추정 보류). - 자동연결 게이트(보수적): 점수≥80(정확100/강한부분80) AND 최상위 후보 유일(모호X) AND 정규화현장명≥3자 AND 부분일치는 커버리지≥0.5(
_MIN_COVER, 일반명 현장이 무관 긴 site_name 흡수 방지=lowcover 보류). 약한토큰겹침(40~52)·모호·무매칭은 미연결 유지(="추정 안 됨"). 단위테스트scripts/test_worklog_autolink_infer.py9 PASS. - 운영 적용 결과(PASS): 162묶음 중 8묶음 32항목 연결(넥서스(추정)13·학동매장11·대구MBC3·한샘넥서스4·헤펠레(넥서스)1 — 정확/강한추정만), 모호·약한 154묶음 그대로 유지. 재검증 dry-run 연결예정 0. 롤백로그
pfs/scripts/_wl_autolink_rollback_prod.json(worklog_no 32건 — 되돌리려면 해당 worklog_no를 field_no=NULL로). 운영 러너scripts/_wl_autolink_run.py <test|prod> <dry|apply> [threshold](env 로그인·미커밋). - 주의: 적용은 배포된 API 경유만(이 PC aws/SSM 미복구로 RDS 직결 불가). apply 첫 시도 502는 배포 직후 워커 리로드 일시오류(재시도 성공, 부분적용 0 확인). field 후보=
field_dao.select_field_search_list({})전체 활성현장.
완료(2026-06-22) — AS GS오산 도어발주서 추가건3·4 견적 운영 등록 (추가건 견적 정리 스킬)
- 페페 지시: NAS
AS 넥서스 GS오산 양산MH 도어발주서.xlsm'포인' 시트 13~18p를 추가건 견적 정리 스킬로 정리 → 부모견적 711(GS오산 양산 본건, field_no 2098)에 추가건3(13,14,15,18p)·추가건4(16,17p) 별개 등록. 운영서버·승인. - 스킬 규칙(payload_add1/add2로 역검증 확정): '포인' 36행/페이지, K5=품명접두. GROUP행=견적 1줄(그룹치수 WDH), 하위 부품행(측판·천판·EP·속대 등 숫자접두 없음)=접음(미분해). 숫자접두 있는 독립 BASIC(완제품)도 1줄. U열 유상만 수집·무상 제외. comment=U 사유. 스크립트
order-automation/build_and_register.py(빌드+POST), 페이로드payloads/payload_add3·4.json. 스킬 전문 문서 =C:\dev\order-automation\견적등록_스킬.md(시트구조·수집규칙·등록메커니즘·실행·검증·이력 — playbook 인덱스에 포인터 등록). - 등록 경로:
POST /api/auth/login(세션)→POST /api/estimate/. insert_estimate가session["user_no"](regist_user) 쓰므로 로그인 필수. 응답 래핑 ={code:"0000", message:{estimate_no}}(success 아님). 자격=.secrets/pfs_login.envPROD. - 결과(운영 DB 검증 PASS): 추가건3=견적 716(7줄: 침실3 키큰EP×3·파우더장 마이다×2·이동선반·복도 안정기함), 추가건4=견적 717(8줄: 신발장 오픈장·하부장×2·내부서랍×3·상하부도어). 711 추가건=712(추가1)·713(추가2)·716(추가3)·717(추가4) 4건. price=0·price_no=null(단가는 스태프가 추후 입력).
- 미결/주의: 단가 미입력(0) — 견적 금액은 스태프 검수·단가 입력 후 확정. 페이지15는 전건 무상이라 0줄. NAS 로컬복사
order-automation/AS_GS오산_도어발주서_NAS.xlsm.
완료(2026-06-22) — 견적 v2 현장검색 키워드 엔터 즉시검색 운영배포 (master 10bd2cc→deploy-live 1858742)
- 페페 QA 1건:
/estimate/regist-v2현장검색 모달 키워드칸(#siteKeyword) 입력 후 엔터로 바로 검색(기존엔 [검색] 버튼 클릭 필요). - 수정 1파일:
estimate_regist_v2.js이벤트 바인딩부에$(document).on('keydown','#siteKeyword', …)4줄 — Enter 시preventDefault()+searchSites(). 검색버튼 바인딩 옆에 동일 위임 스타일. 캐시버스터는asset_ver()자동. - 배포 스코프: deploy-live가 직전까지 master와 동일(미배포분 0) → merge master는 이 1건만 운영 반영(충돌0).
- 검증(Playwright+네트워크 레코더): 테스트·운영 양쪽 모달서 '대전' 입력→Enter→
site-search?keyword=대전요청 발생(운영 결과 1건), 콘솔 에러 0. 세션=session-2026-06-22-estimate-enter-search.md.
완료(2026-06-22) — 입고일정 탭 포커스모드에서 상단 탭바 유지(다른 탭과 동일 내비) 운영배포 (master 21acb70→deploy-live 4bcc11e, ?v=20260622h)
- 페페 QA: 입고일정 B포커스모드가 상단 탭바(op-tabs)를 숨기고 '← 발주서 정리' 백버튼으로만 복귀 → 발주서/현장별자재 이동 2단계로 불편. "공간 절약은 유지, 다른 탭들과 같은 형태로 최상단에".
- 수정 2파일(DB무관): ①
orderpaper_schedule.cssbody.op-sched-active .op-tabs{display:none}→{margin:0 0 8px}(탭바 노출·컴팩트). page-titles 숨김·풀폭·overflow는 유지(공간 절약). ②orderpaper_schedule.jsshellHTML 포커스바에서 백버튼(ofb-back)·중복제목(ofb-title)·구분선 제거, KPI/뷰/검색/필터 툴바 유지. switchTab의 탭 .on 토글이 이미 정확해 활성표시 정상. - 검증(테스트+운영 라이브 PASS): sched 진입 시 op-tabs visible·활성탭 "📅 현장별 입고일정"·백버튼 없음·KPI 유지·풀폭 유지·1클릭 이동(입고일정→현장별자재 직접·op-sched-active 해제 / 입고일정→발주서정리). 콘솔에러 0. (B포커스모드 자체는 유지, 탭 내비만 표준화.)
완료(2026-06-22) — 도면 PDF 자동작성 파서 실가동 + 자동 스케줄(사이드카) 가동
- 페페: "라인VIP 개인건 PDF 분석 대기 너무 오래 — 진행되나 확인 + 다음엔 자동으로". 진단: 자동작성은 서버 자동작업이 아니라 집PC 사이드카(
orderpaper-sync/material_spec_parse.py) 온디맨드 → 미가동이라 6시간 대기(고장 아님). + 어젯밤 PS-04(릴레이 토큰없으면 세션요구)로 사이드카가 인증 필요해짐. - 사이드카 보완(커밋
f0bc37f, 운영eaf1b5b): ① 세션 로그인(POST/api/auth/login, 쿠키 유지)+401 시 재로그인 — 자격증명 env 또는.secrets/pfs_login.env에서 SERVER(운영/테스트)별 자동로드(PS-04 충족, SSM 불요). ② stdout UTF-8 재설정(cp949 print 크래시 방지). ③--drain(pending 전량 처리 후 종료, 스케줄러용). ④ PROMPT_TMPL.format버그 — 미이스케이프{부위:자재id}가 포맷필드로 오인돼 KeyError(parse_pdf_with_codi첫 실가동서 발견)→{{...}}. ⑤ 백엔드 신규POST /uploads/requeue(로그인필요)=error+정체 running 업로드를 pending 복귀(재시도·PS-01 stale 회수 겸). - 실가동 검증(운영): 라인VIP 개인건(field 2084) 2 PDF requeue→사이드카 드레인→둘 다 done(conf 0.82/0.85), spec
parse_status=draft·칼라5/코어4/엣지2/부자재13·타입"일반가구"·실자재 추출(반느·벤자민무어AF-50·효산 LPL N997/N488). has_user_edit=false(draft 노출, 사용자편집 불가침). - 자동 스케줄(요청 "다음엔 자동"): 예약작업
pfs_material_spec_parse(10분 주기·InteractiveToken=로그온 시·IgnoreNew·30분제한) →material_spec_parse_drain_hidden.vbs(hidden) →material_spec_parse_drain.bat(PFS_SERVER=운영·PYTHONUTF8·timeout420) → 사이드카--drain. 수동 실행 검증 PASS(LastResult 0·로그인→드레인0). 제약: 집PC 로그온 상태에서만 동작(24/7 서버잡 아님)·claude 구독 사용량 소모(대기분 있을 때만)·결과는 draft(검수 필요). 끄기=Unregister-ScheduledTask pfs_material_spec_parse. PS-01/PS-05는 이제 파서 LIVE라 유효(stale 회수=requeue로 일부 완화, finish 원자성은 단일 사이드카라 미발생).
완료(2026-06-22) — 현장별 자재 모달 버튼 전면 복구 + 신규현장 드롭다운/가구업체 자동 + 적대검토 후속 2건 — 운영 배포 완료 (master ec178a9→bef032a → deploy-live 26271f2, ?v=20260622c)
- 페페 지시: ①신규현장 현장명=진행중 현장 드롭다운 선택 ②가구업체 field 자동(선택 불필요) ③수동현장 PDF 업로드 ④신규현장 ×/취소 ⑤JSON 가져오기/내보내기 ⑥적대적 검토로 전 모달 버튼 전수 검수 → 테스트배포→적대재검증→보완→테스트재배포→확인→운영배포까지.
- 근본원인(라이브 Playwright 실측): 모든 모달
.op-mat-dialog의onclick="event.stopPropagation()"가 document 단일 클릭위임을 차단 → 모달 내부 전data-act버튼(×·취소·닫기·저장·적용·셀 자재배정 pick-mat·clear-cell 등) 마비. 생성 버튼만 인라인 onclick이라 동작. 모달이 안 닫히면 백드롭이 화면을 덮어 업로드·import/export·카드까지 클릭 불가 → "다 안 됨" 체감의 근원. (실측: #3 수동현장 PDF 업로드 HTTP 200·#5 import client 적용=둘 다 코드상 이미 정상이었고, 체감 불능은 stuck-modal 백드롭 때문.) - 1차 수정(
ec178a9, ?v=b): ⓐ stopPropagation 7곳 제거 + 백드롭data-act=modal-close제거 + document 클릭에 백드롭(다이얼로그 바깥) 명시 닫기(내부 빈공간 오닫힘 방지). ⓑ 신규현장 현장명=진행중 현장datalist콤보박스(siteDropData, 발주서명 일치 유도→카드 분열 방지·#1). ⓒ 가구업체=opMat.onNewSiteNameInput로 field에서 readonly 자동(수동선택 제거·#2)+submitNewSite 폴백. ⓓ beforeunload 소프트락 해제. - 적대적 검토(Workflow
matspec-button-audit: 정적 6렌즈→반증검증, 에이전트 40·후보 33→확정 6·불확실 0). 2차 수정(bef032a, ?v=c): #2 셀모달 풀탭 전환 시 이전 검색어 잔존→pool-tab서 검색칸 초기화 / #3 엣지폼 누락칼라 참조로 저장차단→normalize()에서 무효 colorId 정리(import 데이터 정화). 미수정(판단): 엣지 직접입력 후 버튼클릭=표준 배타동작, datalist 신선도=발주현장 선택용 영향경미, readonly 우회=devtools한정 서버무결. "엣지 직접입력 바인딩 누락" 주장은 오탐 기각(라이브서 엣지폼 정상). - 검증 PASS: 테스트(8001)+운영(https://pfs.poin.co.kr) 라이브 Playwright — 신규현장 datalist·가구업체 자동(테스트 "넵스"/운영 "에넥스")·×/취소/백드롭 닫힘·다이얼로그 내부클릭 유지 / 셀모달 pick-mat·× / 색상·부자재·엣지폼 add/save/×/취소 / 일괄편집·상세 / type·loc add / 풀탭 검색초기화 / 유령엣지 import→재선택가능 / 운영
/list200(테이블 자동부트스트랩)·콘솔에러 0. 임시현장(spec 9·10·11) 생성→삭제 정리. - 운영배포 스코프(페페 "전체 배포" 선택): deploy-live가 master보다 144앞·19뒤 분기 상태에서
git merge master→deploy-live(충돌0, 파일삭제0). material-spec 첫 운영반영 + 업체관리 정렬/유사업종필터 + 현장기록 접이식그룹 + 대화방 사용자별분리 동반 반영. - 현장기록 menu_catalog 운영 적용 완료(2026-06-22, 자율루프): aws CLI/SSM 전무라 SSM 대신 앱서버 멱등 부트스트랩 엔드포인트 신설 —
permission_dao.ensure_field_log_group()(field_log 신설+worklog/kakao reparent, show_in_sidebar 컬럼 동적분기, 멱등) +POST /api/admin/ensure-field-log(super_admin 전용). master545f2c3→deploy-liveb98f216. 운영 트리거 → 사이드바 '현장 기록' 그룹 아래 현장내용·대화방 중첩 라이브 확인(nested-under-field-log). 적대검토: field_log 214가 field_type_door(214)와 동순번이나 후자show_in_sidebar='0'(미표시)라 무해·가시순서 정상(검증됨). (잔여 코드개선 후보: ensure 3 DML 트랜잭션 묶기=멱등 자가치유라 영향 경미.) - 자율루프 iteration 2 — 수렴 검토 14건 수정 운영 반영(2026-06-22): Workflow 수렴검토(회귀·저장락·import파싱·그리드 4렌즈, 후보22→확정14)에서 synthesize 에이전트가 자율 일괄수정·커밋(
a600275) → 코디 전수검토 후 L4-06 상차일 필드명 버그 교정(에이전트가ship_date로 잘못 씀→실제ship_iso,989a5e9). 수정 내역: 낙관락 saveTimer 레이스 3건(F-01 _putRetry 리셋·F-05/F-07 conflict 시 saveTimer clear)·F-08 _pickSeq 응답역전 가드+by-site/create POST에 field_no 전달(L4-02)·F-10 reloadSpec error 핸들러·F1 parse폴링 뷰가드·F2 import 즉시저장(디바운스 우회)·F3 normalize cells 타입체크·F4 schemaVersion null표시·L4-01 미작성카드 클릭 시 confirm(빈 spec행 생성방지)·L4-05 statusBadge has_user_edit 우선. master989a5e9→deploy-livec96b5f4, ?v=20260622d. 테스트+운영 라이브 검증 PASS(회귀: 셀배정→저장 PUT200·"저장됨" / F2 import 즉시저장 / L4-01 '삼성물산' confirm→취소→spec 미생성 5→5 / 운영 6카드·/list200·에러0). 임시현장(spec 12) 정리. - 자율루프 iteration 3 — 백엔드 견고성·field_no 전파·인쇄·편집가드 11건 운영 반영(2026-06-22): Workflow 수렴3(백엔드/라이브러리/인쇄 3렌즈·후보26→확정17) → 코디가 고가치·저위험 11건 직접 수정(에이전트 자율커밋 차단). field_no 전파(B-01 by-site가 field_no 받아 relink[controller+service]·B-02 submitNewSite POST·B-10 업로드 FormData) — site폴백 행 field_no=NULL 잔류·파싱연결 누락 해소. 백엔드 보안/견고(B-07 DELETE 인증필수[
(jsonify,status)튜플은 이 RESTX서 500→RestResponse.fail 패턴]·B-08 get_uploads 둘다None시 []·B-09 finish 미존재 upload_no ValueError). 인쇄(P-01 print-color-adjust:exact 다크표 색상보존·P-02 어느 서브탭이든 spec패널 강제표시·P-03/P-10 편집UI 숨김) — 기존 공백/지저분 출력 해소. 편집가드(L2-05 일괄편집 교차풀 차단·P-06 위치 최소1개). masterb73f9c1→734f14c→deploy-lived991586, ?v=20260622e. 테스트+운영 라이브 검증 PASS(field_no: 삼성물산 모달생성→spec.field_no 1518 연결 / 인쇄: 라이브러리탭서 spec패널 block·검색바/타입바 none / B-07 무인증 DELETE 차단 code9999 / B-08 빈배열). 임시현장(spec 13) 정리. 미수정(판단): B-06 소프트락 가드(stale락 영구잠금 위험), B-12 낙관락 NULL행(미발생), L2-03 renderAll 조기최적화, P-05/P-08 모바일(데스크톱 도구). 수렴4 검토 완료. - 자율루프 iteration 4 — 릴레이 보안·탭훅 + 컨트롤러 직렬화 버그 운영 반영(2026-06-22): Workflow 수렴4(iter3회귀·파싱릴레이/모델·탭통합 3렌즈·확정10) → 코디가 실가치 in-scope만 수정. PS-04(PARSE_RELAY_TOKEN 미설정 시 /parse/claim·finish 익명 개방 → 토큰 미설정이면 로그인 세션 요구로 변경, 사이드카는 X-Parse-Token 모드라 무영향)·TAB-01(opMat.leave에 ctx.loaded=false → beforeunload 중복 락해제 방지). +컨트롤러 직렬화 버그 일괄 교정: create/upload/parse-claim/parse-finish의 에러 반환
return jsonify({...}),status튜플이 이 RESTX서Response is not JSON serializable500을 내던 것(B-07 DELETE와 동일 근본) → plain dict 반환으로 상태코드 유지·해소. masterbab5742→30c9ad1→deploy-live1c55f9d, ?v=20260622f. 테스트+운영 검증 PASS(PS-04 무토큰·무세션 claim→깔끔한 401 차단 / create 빈 site→400 / 운영 동일). 보류(판단, 추후 파서 실가동 시): PS-01 stuck-running(사이드카 더블 네트워크실패 시 'running' 영구·재처리 부재)·PS-05 finish_upload READ-MERGE-WRITE 비원자(복수 사이드카 동시 finish 시 lost update — 단일 사이드카라 미발생). 기타 마진·오탐 보류. - 수렴 판정(2026-06-22 자율루프): 적대적 검토 4라운드(에이전트 누적 130+)로 활성 사용자 플로우(모달·저장·그리드·신규현장·import/export·field_no·인쇄·편집가드) 결함 소진. 잔여 확정결함은 휴면 파싱 사이드카 하위시스템(PS-01/05, 운영 미가동)과 마진뿐 → 활성 기능 수렴. iter5(최종확인) 결과 반영 완료.
- 자율루프 iteration 5(최종) — 활성플로우 잔여 2건 + 수렴 확정(2026-06-22): Workflow 수렴5(활성플로우+iter4회귀)는 회귀렌즈만 완료·활성렌즈 인프라 stall → 활성-플로우 적대검토를 단일 에이전트로 재완결. 신규 2건: BUG-01(단건 셀배정 pick-mat 교차풀 미검증 — L2-05로 일괄편집은 막았으나 단건 누락 → 동일 가드 추가, 해제는 허용)·BUG-02(F2 import 인라인 PUT이 conflict를 일반실패로 처리 → base 갱신+reloadSpec 자가복구). master
126716a→deploy-live26e034a, ?v=20260622g. 테스트 검증(동일풀 배정 정상=회귀 PASS·운영 list 200·BUG-01 마커). 수렴 확정: 5라운드 적대검토(누적 ~135 에이전트)에서 발견이 라운드마다 감소·기존수정의 형제/마진으로 수렴 → 활성 사용자 플로우 결함 소진. - 🔚 자율루프 종결(2026-06-22 ~05:20, 페페 '오전6시까지 루프' 지시): 현장별 자재 탭 = 모달 전버튼·신규현장 드롭다운/가구업체자동·저장 동시성·field_no 전파·백엔드 보안(DELETE/릴레이 인증)·인쇄·편집가드 전부 수정·운영 반영 완료. 운영 최종 = deploy-live
26e034a, ?v=20260622g. 추후 처리(파서 실가동 시): PS-01 stuck-running 회수·PS-05 finish 원자성(복수 사이드카)·PS-06 model enum 표기. 현장기록 그룹은 ensure-field-log 부트스트랩으로 운영 menu_catalog 적용 완료. - 미결(설계급, 추후): 카드클릭마다 빈 spec 행 생성(지연생성 미적용·회귀위험 보류), 충돌 시 셀단위 병합 미활용.
최근(2026-06-21) — orderpaper 신규 3번째 탭 '🪵 현장별 자재'(material-spec 이식) 테스트 배포·검증 PASS (master 9421d1c→cf026b3, ?v=20260621b, 운영 미배포)
- 페페 지시: orderpaper에 기존 standalone material-spec(C:\dev\material-spec, 단일HTML 2251줄)을 '현장별 자재' 탭으로 이식. 구성=①현장선택 인라인(진행중 현장 상차일↓) ②선택 시 같은 페이지 자재 사양 편집기 노출 ③신규현장 직접입력+도면 PDF 다건 업로드→SDK(코디) 자동작성. 적대적 검토로 20 아이디어→베스트1 + 베스트3 목업 요구.
- 설계 = Workflow(에이전트 30, 5단계): 20안 생성→적대적 비평 20→심사. 베스트1=안 A(인라인 드롭다운+포커스모드 풀폭 편집기, 입고일정 패턴 정통 계승). 베스트3 목업=① 포커스 풀폭(=베스트1) ② 좌 사이드바 마스터-디테일 ③ 카드 갤러리 →
C:\dev\pfs\mockups\orderpaper_material_style{1,2,3}_*.html(gitignore, 사용자 검토용). 설계산출물=pfs/mockups/_design_recovery/{spec,ranking,decision}.json. - 백엔드(신규 4계층
api/pfs/orderpaper/material_spec/{controller,service,dao,model}+ config.py 네임스페이스/api/orderpaper/material-spec): 신규테이블 op_material_spec(연결키 field_no 우선·site_name_raw 폴백,COALESCE(spec_json_user, spec_json)동기화안전,updated_at낙관락 + lock_user_no 소프트락) + op_material_spec_cell(셀 출처추적) + op_material_spec_upload(PDF blob pending). REST 9종(GET/<field_no>·POST/by-site·POST/(생성,멱등)·PUT/spec/<spec_no>(낙관락)·PATCH/spec/<no>/cell·/lock·POST/upload·GET/upload/<no>·POST/uploads). GET/<field_no>와 PUT/<spec_no>같은 라우트 충돌 → PUT을/spec/<no>로 분리. - ⚠️ DB 마이그레이션 = 앱서버 자동 부트스트랩(
dao.ensure_tables()멱등 CREATE IF NOT EXISTS, 첫 사용 시 1회). 이유: 이 Claude Code 세션엔 aws CLI/boto3/~/.aws전무 → SSM 직접 적용 불가. 정식 산출물migrations/patch36_op_material_spec.sql·orderpaper-sync/material_spec_migrate.py동봉(운영은 평소 SSM 절차로 적용하거나 자동부트스트랩 사용). 테스트 RDS엔 자동생성 실증됨(spec_no 1). - 프론트(신규 정적
web/static/js/orderpaper_material.js2120줄 +css/orderpaper_material.css): IIFE+window.opMat, 지연렌더(data-init), 포커스모드body.op-mat-active. material-spec 전체 로직 이식 + Bootstrap 제거(pfs는 BS4·source는 BS5 → Modal/Tab/data-bs-* 전부 vanilla 재작성, 실측 DOM data-bs 0). 영속=localStorage→서버(디바운스 600ms PUT 낙관락, conflict 시 재로드).siteDropData입고일정과 동일(진행중·ship_iso↓). 통합:field_orderpaper.html3번째 탭버튼/#opMatWrap/링크,orderpaper_schedule.js switchTab에 3탭 상호배타+restoreTab. - 함정·수정(검증 중 발견): ① DAO
DATE_FORMAT('%Y..%s')가 pymysql%s플레이스홀더와 충돌→워커 502. DATE_FORMAT 전부 제거, datetime은 Pythonfmt_dtstrftime. ② 프론트가res.success읽음 — pfs 봉투는{code,message}→unwrap()(message→spec→평문) 7곳 정정. ③ site 폴백행(field_no NULL) field_no 재연결(create_spec이 NULL→값 업그레이드, 현장 분열 방지). - SDK PDF 파싱 = 1차 STUB(
orderpaper-sync/material_spec_parse.py): 업로드 blob pending→사이드카 폴링(claim/finish, orderpaper_sync 동형)→parse_pdf_to_spec은 빈 골격+confidence 0 반환. 실구현 TODO = Anthropic Messages API document(PDF base64) 파싱(키는 사이드카 로컬, EC2 무관). spec_json(draft)만 적재, spec_json_user 불가침. - 검증 PASS(Playwright + API): 탭 진입→포커스모드·셸·드롭다운(진행중 9·ship_iso 실측 내림차순)·현장선택→편집기 렌더(3서브탭·다크표 #0d1b2a/#f4c430/#ffa500)·vanilla 서브탭 전환·data-bs 0·콘솔 에러 0. API: 테이블 자동생성·생성(멱등·relink)·로드(field/site)·저장(spec_json_user)·낙관락(stale base→conflict, correct→ok) 전건 통과. 실화면 스크린샷 확인.
- 미결/다음: ① 운영(deploy-live) 미배포 — 페페 "운영 배포" 시 진행(운영엔 patch36 적용 또는 자동부트스트랩) ② SDK 파서 실구현(현재 stub) ③ 인쇄는 window.print()(source의 전용 흑백 출력테이블은 미이식) ④ 사용자 스타일 검토 후 베스트3 중 다른 스타일 채택 가능.
- 후속(2026-06-21, master
4ec3d7d, ?v=20260621c): 페페가 라인VIP(field 2099) 신규현장+도면 PDF 2건 업로드 테스트 → "작업중 상태 표시 없음" 지적. (가)상태 조회: 업로드 2건(라인VIP 주방/일반.pdf) 전부status=pending·parse_status=none— 파서 미진행(material_spec_parse.py는 stub이고 미가동). (나)진행상태 칩 추가: 포커스바op-mat-parsechip(업로드 잡 폴링 8초)·🛠 도면 분석 대기 N건/진행 중/✨ 자동작성 검수 필요/⚠ 오류/✅ 완료. applyServerPayload·업로드 후 갱신, exit 시 폴링 정지. Playwright 실측 PASS(라인VIP → '도면 분석 대기 2건' 앰버펄스). ⚠ 파서 아키텍처 정정 필요(phase2): 현material_spec_parse.py는 직접 pymysql→RDS(=EC2에서만 가능, 근데 EC2엔 Claude키 없음). 집PC 사이드카(Claude키 보유)는 RDS 직결 불가(VPC) → orderpaper_sync처럼 HTTPS 릴레이(claim/finish API)로 재설계해야 실가동. 즉 SDK 자동작성은 ①릴레이 엔드포인트 추가 ②집PC 사이드카가 Anthropic document API로 파싱 후 결과 POST 의 2단계가 남음. - 후속2(2026-06-21, master
0e254d9, ?v=20260621d) — 스타일3 카드 갤러리 전환 + field_no 제거: 페페 지시 ①프론트를 베스트3(카드 갤러리)로 변경 ②현장 매핑을 field_no ID가 아니라 입고일정 검색처럼 현장명·상차일↓로 선택(field_no 입력 삭제) ③시드 도구카탈로그 보고 품질 향상. 구현: 포커스모드+드롭다운 → 카드 그리드 갤러리(상차일↓, 카드=현장명·가구업체·D-day·상차일·R/E/S 발주건수·상태배지, 대시드 '신규 현장' 카드) → 카드 클릭 시 같은 페이지 인라인 편집기(sticky 요약바 + 에디터).pickSite(site)1인자(by-site 로드→없으면 create, field_no 미사용), 신규현장 모달 field_no 입력 삭제·가구업체(선택) 추가. 신규 GET/api/orderpaper/material-spec/list(전체 스펙요약 + 현장별 대기 파싱수)로 카드 상태배지(✅작성됨/·미작성/🛠분석 대기 N/✨검수 필요). 에디터 본체·영속·낙관락·파싱칩 보존. 품질도구 활용(도구카탈로그):code-review(high·8각도 finder+verify)로 버그 2건 잡아 수정 — ⓐ sched→mat 직접전환 시<html>overflow 잠금 잔재(schedule.js가 sched에서 hidden 설정·main에서만 해제 → mat 진입 시 스크롤 불가) → switchTab/exit에서 overflow 해제 + op-sched-active 정리 ⓑ 탭 재진입 시 그리드 stale → 매 진입 renderGrid. + 죽은 포커스모드 CSS 제거·:root→#opMatWrap스코프·pickSite 로딩 피드백. Playwright 실측 PASS: 카드 10+추가카드·상차일↓·상태배지(/list)·카드클릭→편집기(3서브탭)·back-to-grid·신규모달(현장명+가구업체, field_no 없음)·sched→mat overflow 해제 검증·콘솔에러 0. ⚠ 데이터: material-spec 현장명("라인 VIP")과 orderpaper 주문 현장명("라인VIP 개인건")이 정확히 안 맞으면 카드가 둘로 보임(병합은 현장명 일치 기준 — 정상, 사용자 매핑 영역). - 후속3(2026-06-21, master
…0df4545) — 도면 PDF 자동작성 phase2 실가동·실 PDF 검증 PASS: 페페 "실제 자동작성까지 진행·검증, rds 수정도 필요시". 아키텍처(sara sdk 참조=sara/codi_cli_runner.py): EC2엔 Claude키 없고 집PC는 RDS 직결 불가 → HTTPS 릴레이. 신규 엔드포인트POST /parse/claim(pending 1건 점유→running·blob base64 반환)·POST /parse/finish(done시 draft를 spec_json 적재·parse_status='draft'+conf, 선택적 X-Parse-Token 게이트). 영속 보정: 신규현장 blank을 spec_json(draft)에 저장·spec_json_user NULL(이전엔 user에 저장돼 draft를 가림) + finish가 blank user(types 없음)는 NULL처리 → draft 노출. 사이드카orderpaper-sync/material_spec_parse.py실가동판: claim→PDF저장→claude -p(stream-json·setting-sources user,project,local·acceptEdits, 구독인증·API키 불필요)로 코디가 Read로 도면 파싱→material-spec envelope JSON→finish. 실 검증(라인VIP 실 도면 2장): 코디가 claim한 실 PDF(에넥스 동양건설 라인VIP 주방/일반 사양서, pypdf 텍스트는 폰트 mojibake → PyMuPDF로 PNG 렌더 후 Read=poppler 불요)를 읽어 자재 추출(18T MDF 도어/18T PB 바디 코어·지정도장 벤자민무어AF-50·반느·LPM 효산 N997/N488·P.P 삼영크란츠SPP0012·0.6T(ABS)엣지·하드웨어 헤티히/SD테크/이안/살리체·가전 LG/하츠/가게나우, 위치 주방 상/하/냉장고장+일반 현관A/B·침실1/2·안방·드레스룸 붙박이장) → finish(conf 0.72/0.74) → 편집기에 자동작성 draft 렌더 실측(colors6·locations9·137 셀 채움, 카드/칩 '✨ 자재작성 검수 필요'). 함정수정: ⓐ finish_upload JOIN 모호컬럼(spec_no/field_no/site_name_raw 양테이블)→502 ⓑ /uploads parse_conf Decimal 직렬화 500 → 둘다 수정. claude CLI 2.1.185 확인. 운영 미배포·RDS 스키마 변경 0(기존 테이블만 사용). 남은 정련: 한 현장 다중 PDF는 finish가 통짜 덮어씀(현재 검증은 통합doc 1회 finish로 우회) → 프로덕션은 사이드카가 현장 전체 PDF 모아 1회 작성 또는 finish 병합 필요. 사이드카 실가동은 집PC(claude 로그인+poppler 또는 PyMuPDF)에서python material_spec_parse.py. - 후속4(2026-06-21, master
c6e8881, ?v=20260621e) — 신규현장 카드 수정 + 카드 삭제: 페페 "신규현장 추가 카드 작동 안 됨 + 카드 삭제 필요". ①버그: 신규현장 모달이 editorHTML 안(=편집뷰#opMatEdit display:none)에 있어 그리드에서 열면 ancestor가 hidden이라 안 보였음 → 모달을 shellHTML 셸 레벨로 이동(그리드·편집 어느 뷰에서도 표시), 제출은onclick=opMat.submitNewSite(). ②카드 삭제: 스펙 보유 카드 좌상단 호버 ×버튼 → confirm →DELETE /api/orderpaper/material-spec/spec/<no>(dao.delete_spec=셀·업로드·스펙 삭제, 발주서 주문 무관) → 그리드 새로고침. 카드 클릭(편집)과 분리(전역 클릭 핸들러서.op-mat-card-del우선). Playwright 검증: 그리드서 모달 표시·생성 동작, throwaway 현장 생성→삭제(카드 제거+spec exists:false) PASS. - 후속5(2026-06-22, master
d92e4e3, ?v=20260622a) — 적대적 검토(워크플로 에이전트 48) 버그 15건 수정·배포: 페페 "적대적 검토 에이전트로 실사용자 프로세스 검토·버그 리스트·수정 배포". Workflow(journey 1 + hunt 6렌즈 + verify per-candidate + synthesize, 40후보→34검증→15확정) + 코디 라이브 Playwright 워크스루 병행. 수정 15건: HIGH ①다중PDF finish 누적병합(_merge_docsdao, 앞 도면 보존·unit PASS) ②statusBadgespec_no!=null제거(클릭만 한 빈 스펙이 '작성됨' 오표시→'미작성', 라이브 검증 IS동서 PASS) ③buildGrid field_no 우선+정규화명 폴백 병합(중복카드) ④사람편집 후 draft 칩 문구 정확화 ⑤신규생성 가구업체가 기존 발주처 덮어쓰기 가드 ⑥탭전환 시opMat.leave(소프트락 해제+폴링 중단, schedule.js 훅). MEDIUM ⑦생성 이중클릭 가드 ⑧낙관락 충돌 재시도로 편집 보존 ⑨폴링 백오프(사이드카 미연결 ~2.5분) ⑩편집기 '+도면 업로드' 재업로드(라이브 PASS) ⑪자동작성 완료 시 reloadSpec로 draft 표 반영 ⑫재렌더 시 검색필터 재적용(라이브 PASS) ⑬사양서 검색 CORE 매칭(라이브 'MDF'→18T MDF PASS). LOW ⑭삭제 안내문구 ⑮칼라삭제 시 엣지 colorId 정리. 보고서=pfs/mockups/_design_recovery/matspec_review.json. 미결(설계급, 추후): 카드클릭마다 빈 spec 행 생성(badge는 정상이나 행 누적 — 첫 편집 전 지연생성 최적화 여지), 브라우저 닫기 시 stale 소프트락(beforeunload 핸들러 부재), 충돌 시 셀단위 병합 미활용. 운영 미배포.
최근(2026-06-20) — 업체 관리 자재 하위 분류(PRODUCT_CAT) + 마스터 목록 영구편집 + 하드웨어→자재 운영배포 완료 (master 8841d9b(+fix 8828d25)→deploy-live a156d5b(+fix cherry-pick a9c6df8), ?v=20260620d, test+prod 완료)
- 🐛 버그수정(같은 날, fix
8828d25→proda9c6df8): 신규 분류·항목 생성 후 저장해도 반영 안 됨(페페 제보). 원인=insert_common_code_with_parent(및 genericinsert_common_code)가 INSERT에use_yn미설정 → NULL, 조회는use_yn='1'만 가져와 신규행 제외. 수정=parent insert에use_yn='1'명시 +save_common_code_group(업체분류 추가)도 parent insert로 통일(generic insert는 미수정). 테스트 재검증 PASS(신규 분류ZZ+항목ZZ 생성→저장→DBuse_yn='1'·parent_code확인→새로고침 후 칩 클라우드 표시→ZZ 정리). 운영은 무관 커밋(6d3b985대화방수집) 제외하고 fix만 cherry-pick 배포. - 페페 지시: ①운영배포 ②마스터 리스트 영구편집 승인(common_code 실저장) ③하드웨어 저장 유지 ④라벨 "하드웨어"→"자재"(DB 항목값 80=하드웨어 유지) ⑤자재 하위분류(면재류·유리류·소프트…)도 편집가능·common_code 분류코드로 추가 ⑥모달 확대+분류코드별 드래그 ⑦"common_code에 부모/참조 컬럼 새로 만들어 사용".
- DB(페페 승인 ALTER):
common_codeparent_code VARCHAR(20)신설. 신규그룹PRODUCT_CAT(자재분류) 면재류10·유리류20·소프트30·오버레이40·기타50. 자재항목PRODUCT_DIV.parent_code=분류코드. 초기매핑(구 HW_CAT): 면재류=보드/시트/엣지/LPM·유리류=유리/패턴유리·소프트=가죽/패브릭/펫시트·오버레이=시트오버레이/펫오버레이·기타=하드웨어/도장/AL.select_common_code_search_list에 ORDER BY 없어 display_order 타화면 무영향, parent_code 신규라 기존 SELECT * 소비처 무해. - 백엔드(3파일): dao
insert_common_code_with_parent·update_common_code_value_order_parent·select_common_code_by_group(+parent_code)(genericinsert/update_common_code미수정 — 기존 update_common_code는 파라미터 버그라 회피). servicesave_product_categories(categories,items)(분류 upsert→cat_code_by_index→항목 upsert+parent_code, 신규분류 채번 후 매핑) +save_common_code_group(업체분류 영구저장, 직전세션 화면적용만→실연동). controllerPUT /api/admin/product-category+PUT /api/admin/common-code/<group_code>. - 프론트(2파일): html 모달
.cp-wide(자재 760px)+분류박스 CSS·#cpModalBody(JS 전체렌더)·라벨 하드웨어→자재·캐시버스터 c→d. js HW_CAT 하드코딩 제거,loadClassCatalog3그룹(COMPANY_DIV·PRODUCT_DIV·PRODUCT_CAT),renderClassChips=parent_code 그룹핑(+미분류). 모달 2모드: div=flat(draftDiv)·hw=분류 그룹박스(matDraft.cats[].items+uncat). DnDmakeItemRow+moveItem(cross-container 분류간 항목 드래그)·분류 ▲▼순서/이름편집/삭제(항목→미분류)/추가·항목 추가/편집/삭제.applyListModal→hw=product-category(cat_index 매핑)/div=common-code PUT→loadClassCatalog재로드. 작업본 격리(적용 전 State 원본 미변경). - 마이그레이션:
migrations/patch35_common_code_parent_code.sql(기록) +scripts/_cc_cat_migrate.py(멱등, ENV_PATH로 test/live 전환, ALTER guard·시드 존재체크·매핑 parent_code IS NULL만). test+prod 양쪽 DB 선적용(컬럼·분류5·매핑14) 후 코드배포. - 검증: 테스트 Playwright(env 로그인) 모달 분류5+매핑+미분류+확대 렌더, 항목 분류간 드래그(AL 기타→면재류)→[적용]→DB
parent_code=10확인→원복(50) 라운드트립 PASS(콘솔 에러=브라우저 확장발, 코드 무관). 운영 분류5(면재류4·유리류2·소프트3·오버레이2·기타3=14) 렌더 확인(쓰기검증은 운영데이터 보호 위해 생략). 자사=포인260.
최근(2026-06-20) — 업체 관리 3b(2탭·칩·자사핀·목록모달) 테스트 배포 — ※위 자재분류 항목으로 대체·운영배포 완료 (master a0c1213)
- company.
company_div·product_div(CSV 코드, 신규컬럼 없이) 저장:PUT /api/admin/company/<no>/classification(controllerAdminCompanyClassification+serviceset_company_classification+daoupdate_company_classification). 우측 상세 [권한 매트릭스]/[업체분류+자재] 2탭, 자사(company_type='1') 최상단 핀(cp-grp-row/cp-self금색),saveClassification. 직전 미결(목록모달 common_code 실저장 미연동)은 위 항목에서 연동 완료.
최근(2026-06-20) — 업체 관리 권한 매트릭스 그룹화 + 그룹/전체 일괄변경 테스트 배포 (master a9bdb52, ?v=20260620a, 운영 미배포)
- 페페 "권한 매트릭스 관련 항목끼리 그룹화 + 그룹 일괄변경 + 전체 일괄변경, 테스트 실페이지 직행". 구현 2파일: ①
web/static/js/admin/company_permission.jsrenderPermMatrix— 리프메뉴(url_path 있음)를 parent_menu_key로 그룹화(견적서/현장/거래처/배차/시스템 관리/오엠씨, menu_catalog의 url_path 없는 부모가 그룹명), 상단 전체 일괄행([모두 허용][모두 차단])+각 그룹헤더 [그룹 허용][그룹 차단]. 일괄=.cp-bulk-btn위임핸들러가 라디오만 세팅(저장은 기존 '권한 저장', data-scope=all|grp·data-parent 범위). ②company_permission.html인라인<style>(그룹헤더·일괄버튼·2·3열 center) + JS 캐시버스터 20260617→20260620a. menu_catalog: leaf=url_path有, 그룹=parent(url_path無), 컬럼 menu_no/menu_key/menu_name/parent_menu_key/url_path/display_order/is_active. - 테스트 Playwright 검증 PASS(env 로그인 poin01): 그룹헤더 6·전체버튼2·리프34, 모두 차단→34 전부 차단, 견적서 그룹 허용→견적서 8만 허용·나머지 26 차단 유지. 운영은 미배포(페페 '테스트 직행'만 — 운영배포 지시 시 deploy-live 머지).
완료(2026-06-20) — 업체 관리(company-permission) 업체분류·자재 토글 + 리스트관리 모달 목업(3번 채택) → 구현·운영배포 완료(상세=최상단 자재분류 항목). 아래는 목업·DB조사 참고이력.
- 페페 채택·수정(2026-06-20): 5안 중 3번(칩 클러스터) 채택 → 수정 목업
company_perm_mockup_3b_chip_tabs.html신규: ①우측 상세를 [권한 매트릭스] / [업체분류+하드웨어] 2탭 분리(그 위 업체정보·마진율 유지) ②사이드 메뉴는 실제 현행 그대로(견적서/현장/거래처/배차/시스템관리 — 메뉴 개편 제외) ③포인(자사, company_no 260, company_type='1') 업체목록 최상단 별도 배치(자사 그룹헤더+금색, 거래처 분리). 브라우저 검증(2탭 전환·칩토글·포인 핀·모달). 자사=포인 260 1곳(SSMcompany WHERE company_type='1'실확인). 다음=실구현 결정 시 이 수정안 기준. - 페페 요구:
/admin/company-permission(메뉴 "업체 관리") 선택 업체 권한 블록 밑에 ①업체분류·②하드웨어 분류를 활성/비활성 버튼으로 나열(리스트 안 열고 1클릭 on/off) + 별도 모달(드래그 순서·추가/편집/삭제) + 사이드바 메뉴 개편안. 에이전트 적대적 검토로 목업 5개. - DB 확인(운영 common_code, SSM 실조회): 업체분류=
COMPANY_DIV(발주처10·수주처20·시공처30, MULTI=CONVERT_MULTI_COMMON_CODE(company_div,'COMPANY_DIV')company_dao). 하드웨어=PRODUCT_DIV(14: 보드10·시트20·엣지30·유리40·패턴유리50·가죽60·패브릭70·하드웨어80·도장90·시트오버레이100·펫오버레이110·LPM120·펫시트130·AL140). common_code 컬럼=group_code·group_name·code·value·display_order. 인코딩 함정: EC2 mysql HEX(value)--default-character-set=binary로 받아 로컬 디코드, 콘솔 cp949라 결과는 UTF-8 파일로 써서 Read(직접 print는 깨짐). SSM=aws ssm send-command i-03225ba8bc12a929e+/home/ubuntu/env/pfs-live.envsource(MYSQL_SERVER/PORT/USER/PASSWORD/DATABASE). AWS CLI 로컬 동작(poinadmin). 세션에 aws-api MCP 미연결이라 CLI로. - 페이지 구조:
web/templates/admin/company_permission.html(좌 업체목록 table 번호|업체명|구분[자사 badge-super 금색] · 우 .admin-detail: 선택업체 readonly·마진율·권한매트릭스 라디오). JS=web/static/js/admin/company_permission.js(company/search, admin/menu/catalog, admin/company//permissions, margin-rate). CSS= web/static/css/admin.css(.admin-split·.switch #2196f3·.badge-super·.admin-modal). 라우트/admin/company-permission(권한 menu_key=admin_company_permission). - 산출물(
C:\dev\pfs\mockups\):index_company_permission.html(비교·라이브 미리보기) +company_perm_mockup_{1_segment_table·2_twocol_cards·3_chip_cluster·4_inline_cockpit·5_density_matrix}.html+_cp_context_brief.md(공유 스펙). 보수→대담: ①세그먼트표(권한매트릭스 운율·420 2탭모달·평탄2그룹) ②2열카드스위치(720 동시모달·접기2그룹) ③칩 카테고리클러스터(420 드롭다운모달·3그룹) ④인라인 스마트코크핏(모달제거 인플레이스+추천/복사·설정허브) ⑤풀폭 밀도매트릭스(전업체×하드웨어·컬럼관리모달·아이콘레일). 전부 실데이터·동작·각기 다른 메뉴개편. 에이전트 적대적 검토: 디자이너2(실무A·혁신B) 8안 → 비평가가 약점 직격 후 5안 확정. 브라우저 전건 검증. - 메뉴 개편 공통 골자: 업무영역(견적·현장·배차) / 기준정보·설정(거래처·업체관리·코드관리 신설·사용자·오엠씨). 코드관리=업체분류·하드웨어 마스터 모달 진입점.
- 다음: 페페 안 선택 → 채택 목업으로 실구현(템플릿+JS+CSS, common_code CRUD API[추가/편집/삭제/순서]·업체별 분류 저장 API 신설 필요) → 테스트→운영.
최근(2026-06-20) — 자재관리 기본 탭 사용자별 저장·복원 운영배포 완료 (master 562cbae→deploy-live 193e8c0, ?v=20260620j)
- 페페 요청: 자재관리(field/orderpaper) 로드 시 마지막 선택 탭(발주서 정리 ↔ 현장별 입고일정)을 사용자별 저장 → 재로드 시 그 탭으로 복원. 구현: ①
orderpaper_schedule.js—switchTab호출 시localStorage['pfs.op.tab.<user_no>']에 저장(saveTab, 공용 PC 계정구분 위해 user_no 키),opSch.restoreTab=저장값 'sched'면 입고일정 전환(발주서 정리는 HTML 기본이라 무동작). ②field_orderpaper.html—window.PFS_USER_NO(=session.user_no) 노출,loadAll첫 성공 1회(window.__opTabInit)restoreTab()호출(OP_ALL 적재 후라 입고일정도 데이터와 정상 렌더). 캐시버스터 i→j. - 검증(운영 Playwright, env 로그인 poin01 user_no=1): 입고일정 선택→
pfs.op.tab.1='sched'→재로드→입고일정 복원+간트 11그룹 데이터 렌더(즉시), 발주서 정리 선택→재로드→발주서 정리 복원. (테스트 세션 만료로 운영에서 검증.)
최근(2026-06-20) — 입고일정 검색 비영속 + QA Helper 전역 관리자(is_super_admin) 전용 운영배포 완료 (master 338a01b→deploy-live bc61e71, ?v=20260620i)
- 페페 2건: ①입고일정 검색 비영속(orderpaper_schedule.js) — localStorage 복원 직후
S.search=''강제. 현장 선택/검색이 재로드 시 항상 해제(다른 상태=view·mode·mat·quick·sort는 유지). 캐시버스터 h→i. ②QA Helper 전역 관리자 전용 — 기존 모든 페이지 노출(QA_HELPER_ENABLED 게이트만)을 관리자(is_super_admin=='1', 총관리자)만으로 좁힘.web/templates/base.html게이트 2곳(config.get('QA_HELPER_ENABLED')=='1' and is_super_admin) +web/__init__.py_inject_qa_helper(after_request)에session.get('is_super_admin') != '1'early-return 추가. is_super_admin은 context_processor가 전 템플릿 주입(_patch32_inject_sidebar_menus). 필드 마스터엔 status 없음 무관(이건 권한). qa_helper.js/css 무변경(asset_ver mtime 캐시). - 검증(테스트+운영 Playwright): 검색 — pickSite 후 localStorage에 search 저장됨 → 재로드 후 input='' & 그룹 전체표시 & view=gantt 유지(searchCleared true). QA — 신동승 차장·poin01 모두 is_super_admin(관리자)라 qa_helper.css head 주입+toggle 노출(게이트 통과 = 관리자 확정), 게이트는 조건부(비관리자=미주입). 운영 정적
S.search=''마커 확인. 주의: "관리자"=is_super_admin(총관리자)로 게이트함. 자사 포인 직원 전체(company_type='1')로 넓히려면 별도 조건 필요(현재는 super_admin만). 비관리자(외부 가구업체 로그인)는 QA Helper 미노출.
최근(2026-06-20) — 입고일정 검색=현장 드롭다운 + 기본뷰 타임라인 운영배포 완료 (master 1b71ff5→deploy-live 75dcb8f, ?v=20260620h)
- 페페 3건(orderpaper_schedule.js/css만, DB·정적): ①검색박스→현장 드롭다운(포커스바
.searchbox클릭/포커스 시opSch.openSiteDrop).siteDropData=OP_ALL을 현장별 집계(현장업체=furniture_company·상차일=ship_iso 최대·미완료수), '진행 중'=미완료 항목 존재만 노출(필드 마스터엔 status 없음→item status 기준), 상차일 ship_iso 내림차순(없으면 맨뒤). 행=현장업체 칩·현장명·상차 fmtD(ship)(연도규칙 따름), 추천 없음. 클릭→pickSite=검색필터(S.search=현장명)+닫기. 문서 click 리스너로 행선택/바깥닫기. ②기본 뷰=타임라인(S.view 'table'→'gantt', 저장된 localStorage 선호 있으면 유지). ③드롭다운 항상 전체 리스트(버그수정):openSiteDrop이siteDropHTML('')고정(검색어 무관)+입력 시 목록필터 제거+onclick재오픈 → 현장 선택 후 재오픈해도 전체 진행중 리스트 유지(이전엔 선택현장명으로 필터돼 1개만 보임). - 검증(테스트+운영 Playwright): 기본뷰=gantt(localStorage 초기화 시), 드롭다운 진행중현장(테스트14·운영5)·상차일 ISO 내림차순 정확·co/site/ship 표시·클릭 시 해당현장 필터(그룹1)·선택 후 재오픈 전체유지(fullListMaintained). 운영 정적마커(siteDropHTML('')·filterSiteDrop 0·onclick) 확인. 주의: 화면 상차일은 연도 생략 규칙 적용이라 데이터에 과거연도(2020~) 상차일이 섞이면 월·일만 보여 정렬이 섞여 보일 수 있으나 ISO 기준 정렬은 정확(운영 데이터는 신선해 자연스러움).
최근(2026-06-20) — 입고일정 B 포커스모드 채택 + 날짜 연도제거 + 현장목록버튼 삭제 운영배포 완료 (master 75330e9→deploy-live 5d923c9, ?v=20260620e)
- 페페 결정: 목업 중 B안(집중모드)을 조합 없이 채택(사이드바는 기본 펼침 유지). + field/orderpaper 모든 날짜 연도 제거(12↔1월 경계 데이터일 때만 그 두 달 연도 표기) + 현장목록 버튼 삭제 + 운영배포까지.
- 구현 3파일(DB 무관·정적+템플릿): ①날짜 연도 — 메인
fmtD(field_orderpaper.html)·스케줄fmtD(orderpaper_schedule.js) 둘 다window.OP_YEARMODE && (m===12||m===1)일 때만YY.접두, 그 외M.D(요일).opComputeYearMode()(OP_ALL의 order/receive/item_receive/ship 중 어떤 해 12월 + 익년 1월 동시존재 시 true) →loadAll()에서 호출, 메인/스케줄 공용(window.OP_YEARMODE). fmtMD(간트 M/D)는 원래 연도 없어 그대로. ②B 포커스모드(orderpaper_schedule.css/js) —body.op-sched-active에서.page-titles·.op-tabs숨김 +.op-wrap{max-width:none}(풀폭) + 컨테이너 패딩 축소. shellHTML=포커스바(.ops-focusbar: ←발주서 정리[switchTab('main')]·제목·KPI pill[.kpis-pill]·뷰세그/검색/⚙상세필터) + 필터줄(.ops-filterline: 분류 grp-seg·자재 mat-toggle·빠른필터6·초기화) + activebar + view. 기존 id(opsGpSite/opsMt/opsQf/opsSearch/opsV/opsFilterBadge) 보존. ③현장목록 버튼 삭제*(page-titles col-md-7→12). 사이드바=테마 기본 펼침(미변경,.sidebartoggler로 접기 가능). - 검증(테스트+운영 Playwright 실측 PASS): 메인 탭=현장목록버튼0·page-titles표시·날짜 연도0·op-wrap1180유지. 입고일정 탭=op-sched-active·page-titles숨김·op-tabs숨김·op-wrap풀폭(1180→1658px)·포커스바·←발주서 정리·필터줄·KPI pill4·표139행 연도0·←복귀시 page-titles/탭 복원. 연도 게이팅 라이브검증: OP_YEARMODE 강제 true 시 1월→
26.1.2·6월→6.16(12·1월만 연도). 운영 정적마커(ops-focusbar·OP_YEARMODE·page-titles숨김·kpis-pill) 전부·운영 런타임(poin01) 동일. 단위테스트: 12-20&익년1-5→26.12.20/27.1.5/6.20(6월 연도없음), 6·7월만→연도0. - 목업 모음(참고):
pfs/mockups/index_schedule_wide.html(6안+B+E조합 7카드). 채택=B(schedule_wide_B_focusmode.html).
(이전) 입고일정 '와이드 재설계' 목업 6안+조합 — 제시·선택 (위 B안 채택으로 완료)
- 요구(페페): 입고일정(현장별 리스크표/타임라인) 페이지를 가로·세로 더 넓게 + 상단 KPI카드·빠른토글·빠른필터 크기 축소·배치 개선 + 가로보기(와이드) 개방감. GPT 상의 후 베스트 목업 10개 미만 제시 지시.
- GPT(gpt-5.5) 상의 핵심: ①
web/templates/basic/field/field_orderpaper.html의.op-wrap{max-width:1180px}폭제한을body.op-sched-active에서 해제 → 풀폭 와이드(1440~1920 화면서 현재 상당폭 낭비). ②fitHeight()가#opSchedWraptop 기준이라 page-titles/탭/KPI/제어행 줄인 만큼 표·간트 세로가 그대로 증가. ③ 간트.grow{width:max-content}·표 sticky(nth-child1 left:0, nth-child2 left:152px)는 유지해야 함. - 산출물 6안 + 인덱스(
C:\dev\pfs\mockups\, 실제 위험도산정/집계 알고리즘 이식·동일 샘플데이터·브라우저 전건 렌더 검증):index_schedule_wide.html(비교·라이브 미리보기 iframe·추천순위) /schedule_wide_A_commandbar.html(추천1 KPI→pill+컨트롤1줄) /_B_focusmode.html(추천2 page-titles·탭 제거→38px 인앱바+사이드바 접힘, 최강 와이드) /_E_countchips.html(추천3 KPI카드 제거·빠른필터칩에 카운트 내장) /_C_leftrail.html(KPI 좌측 세로레일) /_D_drawer.html(필터 우측 슬라이드 드로어) /_F_floating.html(결과/범례/필터 플로팅 오버레이). 조합: A+F, B+E. - 추가(페페 요청): B+E 조합 목업
schedule_wide_BE_focus_countchips.html제작·검증 완료(집중모드 셸 + 카운트칩, 38px 인앱바+카운트칩 1줄, 최강 압축). 인덱스에 7번째 카드로 등록. 표·간트 양쪽 브라우저 검증 PASS. - 결과: 페페가 B안 채택(조합 없이·사이드바 기본 펼침) → 위 '최근(2026-06-20) — 입고일정 B 포커스모드…' 항목으로 구현·운영배포 완료(
75330e9/5d923c9). 현장목록 버튼 삭제·날짜 연도제거도 같은 배포에 포함.
최근(2026-06-20) — 입고일정 QA 리포트 2건 운영배포 완료 (deploy-live 11bdccd→c899762→f3c3a5a, master da468de→936e709→9c7ae9f, ?v=20260620d)
- QA Helper 리포트(field/orderpaper) 2건 반영. 3파일만(orderpaper_schedule.js/css, field_orderpaper.html), DB 무관·정적자산.
- ①완료그룹 라벨
완료 업체→완료: 입고일정 탭 표(rTable donegrp)·타임라인(rGantt donegrp) 둘 다. 메인 발주서정리 카드의완료 업체/현장 N개(renderItemsHtml op-donevend)는 미변경(다른 탭·QA 미지정 — 필요 시 후속). - ②타임라인 행 클릭→발주서 정리 이동 + 호버 말풍선: 간트 gvrow에
op-gnav(클릭)·data-uid·onmouseenter/leave 부착,VMAP(uid→vrow 레지스트리, rGantt마다 리셋).opSch.rowNav=현장별/가구업체별 모드→해당 현장카드·발주처별 모드→발주처카드로switchTab('main')+opSetMode+이동.opSch.tipShow/tipHide+vTipHTML=다크 말풍선(현장·발주처·자재 헤더/발주·입고·상차·미입고 메타/품목 12건+초과표시/안내문, body직속 position:fixed). 신규 전역opExpandCardAll(cid)(field_orderpaper.html)=대상 카드 하위항목까지 전부 펼침(카드 open+OP_BLK_OPEN 전블록+OP_DONE_OPEN+OP_DONEVEND_OPEN)+renderItems. 강조=.op-site.op-nav-flash3초 유지 + 느린 점멸(opNavFlash keyframe, 재클릭 시 reflow로 재시작). - 검증: node --check 통과. 테스트(pfs-test:8001) Playwright 실측 전건 PASS — 라벨
✓ 완료 N(구라벨0)·gnav 139행·클릭 시 메인전환+카드열림+블록10/10+하위항목34행+opNavFlash 3s·호버 말풍선(헤더/메타/품목8/안내)·mouseleave 숨김. 운영(https://pfs.poin.co.kr) 정적 배포 확정(GH Actions success 2m14s, opExpandCardAll/rowNav/tipShow/op-sch-tip 마커 전부·구라벨0·HTTP200). 운영 런타임 Playwright는 pw-chrome-profile 락으로 미실행(테스트와 byte-identical 코드라 동작 동일). 로그인=세션유지(신동승 차장, 테스트 재로그인 불요). - 함정: 운영 URL=https://pfs.poin.co.kr(443, 리버스프록시) —
http://pfs.poin.co.kr:8000직결은 외부서 timeout(code 000). 운영 정적 폴링은 https 도메인으로. 테스트는 http://pfs-test.poin.co.kr:8001 그대로. - 후속 보강(
936e709→deploy-livec899762, ?v=20260620c) 운영배포 완료: ③강조색 파랑→노란색(amberrgba(234,179,8)), 셀렉터 일반화.op-nav-flash(카드·블록 공용), inset 링(.op-siteoverflow:hidden·블록 가장자리에도 안 잘림). ④모드별 강조 범위 — rowNav/opNavToCard 개편: 항상 현장(site) 카드로 이동(opSetMode 'site' 고정), 현장별 모드(행=발주처 블록)는 v.blockKeys로 매칭한 해당 op-block(들)만 강조, 발주처별·가구업체별 모드(행=현장)는 현장 카드 전체 강조. 헬퍼flashEl()(reflow 재시작). 블록 매칭=op-blockdata-bk(=esc(block_key)) DOM값 vs v.blockKeys raw 비교(for루프, 셀렉터 이스케이프 회피). 운영 런타임 검증 위해 pw-chrome-profile 락은wmic ... name='chrome.exe' and commandline like '%pw-chrome-profile%'PID만 taskkill로 해제(MCP node·일반 Chrome 보존). - 후속2(
9c7ae9f→deploy-livef3c3a5a, ?v=20260620d) 운영배포 완료: 페페 "테두리 말고 배경색 + 신규(op-new) 하이라이트와 같은 범위". 강조를 링(inset 4px)→배경 틴트로 변경 —op-nav-flash를.op-block에 부여, CSS.op-block.op-nav-flash > .op-block-head, … tr.op-item > td에box-shadow: inset 0 0 0 2000px rgba(234,179,8,α)점멸(실제 background 미변경 위에 노란 틴트만, op-new와 동일 범위=블록 헤더+항목행). opNavToCard: 현장별 모드=blockKeys 매칭 블록만, 발주처별/가구업체별 모드=카드 내 모든 op-block에 flash(현장 전체). 테스트+운영 Playwright 실측 PASS: site 1/19블록만·카드클래스無·inset2000px amber / vendor 19/19 전부. (op-nav-flash는 이제 .op-site가 아니라 .op-block에 붙음.)
최근(2026-06-20) — QA Helper 운영 노출 + 토글 위치 조정 운영배포 완료 (6bb1044)
- QA Helper(
qa_helper.js/css, 우상단 element picker→코멘트→채티복사)는 base.html +web/__init__.pyafter_request_inject_qa_helper양쪽으로 전 text/html 페이지 주입, 둘 다QA_HELPER_ENABLED=='1'게이트. 테스트 env=1(켜짐), 운영 env=미설정→기본'0'이라 운영엔 미노출이었음. →web/__init__.py기본값'0'→'1'로 변경(운영 미설정→'1' 켜짐, 테스트 명시 '1' 유지). 끄려면 해당 env에QA_HELPER_ENABLED=0. - 토글버튼 위치:
qa_helper.css #qa-helper-toggletop:12px→70px(.sidebar-head로고영역 58px 아래로),right:12px유지. qa_helper css/js에asset_ver()(파일 mtime) 캐시버스터 추가(base.html + after_request 주입 HTML 양쪽). Playwright 운영 실측: 토글 존재·top 70px·캐시버스터 PASS.
orderpaper 동기화 신규항목 강조 + 후속 4건 + 노트삭제 — 운영배포 완료(a9fe1b5, 2026-06-20)
- 신규강조 본체(C안 형광·NEW배지·클릭해제·localStorage 영속, is_new=regist_date>=최근동기화 start)에 페페 후속 4건 반영: ①신규강조 전체 해제 배너(opList 위
#opNewBanner, 미해제 신규 N건 표시+전체해제 버튼,opUpdateNewBanner/opClearAllNew) ②다음 동기화 시 이전 신규 자동 해제(임계값 MAX(start_date) 이동 + 동기화 완료 시loadAll()재호출로 is_new 갱신 — 코드변경 없이 동작) ③업체 NEW ✕ 배지 클릭 → 업체+하위항목 cascade 해제(opDismissNewBlock, 발견성 위해 배지를 버튼화) ④발주서정리 현장별 완료 업체 그룹(전체완료 블록을 카드당 단일op-donevend로 자동이동·기본접힘, 표/타임라인 완료그룹과 동일 —blockAllDone/foldDoneVendOpen/toggleDoneVend재도입). + QA도구 리포트 반영 안내노트 2개 삭제(op-head-note "NAS 발주서…"·op-sync-note "※동기화 대상…"). 템플릿+DAO 1줄(is_new), DB 컬럼 무관. 테스트·운영 Playwright 전건 PASS(노트삭제·배너 전체해제 103→0·NEW클릭 cascade·완료그룹 기본접힘·운영 완료업체73). 목업=pfs/mockups/sync_new_highlight_mockup.html.
(이전) orderpaper 동기화 후 신규항목 강조 — 테스트 배포·백엔드 검증 (16534fc) — 위 항목으로 운영배포 통합됨
- C안(형광 하이라이트) 구현: ①백엔드
select_all_items에is_new컬럼 =CASE WHEN o.regist_date >= (SELECT MAX(start_date) FROM orderpaper_sync_request WHERE status='done') THEN 1 ELSE 0(동기화가 item_key UNIQUE UPSERT라 신규 INSERT에만 regist_date=NOW(), 기존 보존; 사이드카가 running 전환 시 start_date=NOW() 설정 확인). ②프론트 field_orderpaper.html:opIsNew/opBlockHasNew, itemRowtr.op-item.op-new+NEW배지, blockTable.op-block-head.op-new+NEW배지(업체 단어 제외 "NEW"), 형광 CSS(#fef9c3/#fefce8+#eab308 좌측바), 클릭 시 해제(opDismissNewItem/opDismissNewBlock, 편집컨트롤 클릭 제외), localStorage 영속(pfs.op.new.dismissed.v1,opPruneNewDismiss로 누적정리). 템플릿이라 캐시버스터 불요. - 테스트 전건 검증 PASS(2026-06-20, env파일 로그인): is_new 107건 / 블록헤더 형광 #fef9c3·항목행 #fefce8·NEW배지 / 항목 클릭 해제(op-new 제거) / localStorage 영속(
pfs.op.new.dismissed.v1, 새로고침 후 해제 유지·타 신규 유지). 운영 미배포 — '운영 배포해줘' 지시 대기. 목업=pfs/mockups/sync_new_highlight_mockup.html. - 로그인 자격증명 env 파일 도입(2026-06-20):
C:\dev\.secrets\pfs_login.env(git 밖, 키PFS_TEST_URL/ID/PW·PFS_PROD_URL/ID/PW). 코디는 이 파일을 읽어 Playwright 로그인 폼 자동입력(테스트 도메인은 Chrome 자동완성 미저장이라 이 방식 필수). 비번 값 출력·커밋 금지. 상세 = 메모리 [[browser-automation-login-default]].
최근(2026-06-19 밤) — 입고일정 6건 재작업 운영배포 완료 (ef674d8, ?v=20260619j)
- 복원(아래 ⚠️)된 e804ac7 베이스에서 6건 재구현. 스케줄 2파일(orderpaper_schedule.js/css)은 백업 브랜치
wip-discarded-20260619-2104(b69fbaa)에서 복원해 재사용, 항목2만 변경. field_orderpaper.html은 항목3만 수동 적용(메인페이지 완료그룹은 미유입). - ①스케줄 상세필터 모달(위험도9 다중선택·발주/입고예정/상차 날짜범위·정렬기준·자재순 토글) ②현장별 완료업체 하위 그룹(★이전 오류 수정: 전역 하단 단일그룹→각 현장 그룹 내부에 그 현장의 완료 분만 모은
donegrp하위그룹, 기본접힘DONEFOLD[g.key]·opSch.dfold, 리스크표·타임라인 공통, 완료판정=집계행 단위 개별) ③현장연결opFieldRow상차일 배지(f.shipping_date)+메타/코드/발주~입고 슬레이트#475569 ④타임라인 축 -30일+로드시 오늘 가로센터(_centerToday/_todayCX) ⑤일단위 월밴드(.gmonth) ⑥업체 자재순(R→E→S) 기본+필터토글(MATIX/S.matSort). 공통aggVrows로 동일 발주일자 분할 block_key 1행 집계(중복제거), 하위 block_key 보존해 펼침상세·일괄액션 적용. - Playwright 테스트·운영 양쪽 PASS(필터모달·현장별 donegrp 기본접힘[표·간트, 운영 6개]·상차배지·슬레이트색 rgb(71,85,105)·축30일·센터·월밴드·자재순·중복0). 2026-06-20 운영배포 완료(master
f5bd44b→deploy-liveef674d8, 머지충돌 3파일 master로 해소). 운영 세션 만료 시 pw-chrome-profile 자동완성(poin01) 로그인 후 검증. 계획서=C:\Users\delix\.claude\plans\replicated-tumbling-hopcroft.md. 폐기 백업 브랜치wip-discarded-20260619-2104는 보존 유지.
⚠️ 최근(2026-06-19 저녁) — 입고일정/발주서정리 3개 batch 복원(되돌림) — 페페 "마지막 작업들이 잘못됐다, 재작업 예정"
- 현재 상태: master=
d94ad41, 운영(deploy-live)=5ea1a2b— 둘 다 e804ac7(발주량 qty 편집) 코드 상태로 복원됨. qty_user·note_user 컬럼·인라인 편집은 유지, 입고일정 탭은 기본형(494fec0)으로 되돌아감(상세필터·완료업체그룹·자재순·발주일자집계 모두 제거). Playwright 운영 실측: opSch.openFilter/matSort undefined·상세필터버튼 없음·qtyCell/noteCell function PASS. - 폐기된 작업(재작업 시 참조): ①7건(
345d155: 스케줄 상세필터·완료자동폴딩·축30일·오늘센터·월표시·자재순·현장연결 상차일/슬레이트색·발주서정리 완료업체 폴딩그룹) ②완료업체 통합·타임라인 발주일자 집계·메타(10ce0da·c8fb676) ③리스크표 집계·완료업체그룹(b69fbaa). 전부 프론트 3파일(orderpaper_schedule.js/css, field_orderpaper.html)만 변경 — DB 무관. - 백업: 폐기 커밋 전체가 origin 브랜치
wip-discarded-20260619-2104(=b69fbaa)에 보존됨. 재작업 시git show/cherry-pick으로 참조 가능. 복원 방식=강제푸시 차단되어 포워드 복원(파일을 e804ac7로 되돌리는 일반 커밋, 히스토리에 b69fbaa 잔존하나 코드는 e804ac7). - 다음: 페페가 입고일정/발주서정리 개선을 다시 작업 예정(백업 브랜치 참조). 아래 'af8c91a/2699e72 운영배포 완료' 기록들은 현재 운영에서 철회됨(코드 e804ac7로 복원, 히스토리만 남음).
최근(2026-06-19) — 입고일정/발주서정리 완료업체 그룹화·타임라인 중복제거 3건 운영배포 완료 (af8c91a, ?v=20260619h)
- ①발주서정리 완료업체 단일 통합그룹: 기존 자재섹션별 분산 op-donevend를 카드당 1개 "✓ 완료 업체 N개"로 통합(renderItemsHtml에서 전 자재 doneBlocks 수집→하단 단일그룹, 기본접힘
foldDoneVendOpen(cid,'__all')). matSecHtml은 활성블록만 받음. ②타임라인 완료업체 하단그룹: 미입고0 업체(vrow.done)를 전 그룹에서 모아 하단 "✓ 완료 업체" 계층으로(기본접힘,GFOLD['__donevend']기본 true, gfold 핸들러 특수처리). 전부완료 그룹은 active 없으면 스킵. ③타임라인 업체 발주일자 집계(중복 block_key 제거): 같은 그룹 내 [업체+자재+발주일자] 동일 block_key 여럿을 1행으로(aggVrows/rowKey, 미입고 합산·입고일 최대·nBlocks 표기). 발주일자 다르면 별도 행 유지(페페 규칙: '상차일'=발주일자 의미였음). 행 메타에 "발주 M/D" 표기로 축밖 발주행 구분. 정적자산만. Playwright 운영 실측: 동일발주일자 중복 0·완료업체 그룹 기본접힘(타임라인86·메인카드73)·일광금속 16→6행 PASS. - ⚠️ 리스크 표(스케줄 table)는 이번 미변경(블록 단위 유지+기존 whole-group fold). 중복제거·완료업체 하단그룹은 타임라인 한정(페페 지시 범위).
최근(2026-06-19) — 입고일정/발주서정리 개선 7건 운영배포 완료 (2699e72, ?v=20260619f)
- ①스케줄 상세 필터 모달(opsFmodal): 위험도 9종 다중선택·날짜범위(발주/입고예정/상차)·정렬기준 select·자재순 토글.
S.rankSel·S.range·opSch.openFilter/rank/setRange/setSortKey. ②완료 그룹 자동폴딩(표·타임라인): 그룹 전 블록 완료 시g.allDone→기본 접힘(gFolded/GFOLD/GDONE), 헤더 클릭 토글, "✓전체완료" 태그. ③현장연결 모달 상차일:opFieldRow에 field.shipping_date(YYYYMMDD) 배지(op-map-ship) + 메타/코드/발주~입고 글씨 슬레이트(#475569). ④타임라인 축 과거 -60→-30일(axis winLo) + 로드 시 오늘 가로센터(_centerToday·_todayCX, view/gunit/switchTab 시). ⑤간트 일 단위 월 밴드(.gmonth, 매월1일/시작점, ghead.dnum 18px 아래로). ⑥업체 내 자재순(원자재→엣지→부자재) 블록정렬(blockCmp/S.matSort기본ON, 필터 토글). ⑦발주서정리 완료 업체 별도 폴딩그룹(matSecHtml에서 blockAllDone 블록 분리→op-donevend 기본접힘 "✓완료 업체 N개",toggleDoneVend/OP_DONEVEND_OPEN). 정적자산만(RDS 무관). Playwright 테스트·운영 양쪽 7건 PASS(자재순 혼합그룹 정합·완료그룹 메모리테스트 galldone+gfolded·상차배지·월밴드·오늘센터·완료업체14개 접힘).
최근(2026-06-19) — 발주서 정리 발주량(qty) 인라인 편집 운영배포 완료 (19e8aa7)
- 비고와 동일 패턴: 클릭→입력→Enter/blur 저장. 신규
qty_user컬럼(varchar60 NULL, 테스트·운영 RDS ALTER 둘 다 완료, 멱등 스크립트scripts/op_qty_user_alter_{test,prod}.py). DAO 3개 SELECTCOALESCE(qty_user, qty) AS qty·update_item_qty·servicemodify_item_qty·controllerPATCH /orderpaper/<no>/qty. 프론트qtyCell/opEditQty/setItemQty(op-c-qty 셀, op-notechip+op-qtychip 칩 재사용, 입력칸 op-qtyinput width84px, maxLength60). 동기화가 qty(원본) 덮어도 qty_user 보존. qty:'' PATCH→qty_user=NULL(원본 폴백, 비우기 불가=비고와 동일 한계). Playwright 테스트·운영 양쪽 API 라운드트립(저장→COALESCE 반영→원복) PASS, 운영 칩 렌더·13.5px·편집 확인. qty가 varchar(60) 자유텍스트라 "4장"·메모성 값도 존재(편집 시 그대로 보존). - orderpaper
*_user오버라이드 컬럼 = material_type/receive_date/item_receive_date/note/qty (운영 모두 존재).
최근(2026-06-19) — orderpaper 입고일정 탭 + 전역 레이아웃 개편 + 비고 기능 운영배포 완료 (bf8cfea)
- 그동안 "테스트 전용·검토 대기"였던 일괄을 페페 "전체 운영 반영" 승인으로 deploy-live 머지(master→deploy-live, 충돌 2파일=dao/field_orderpaper.html은 master 버전으로 해소)·운영 배포. 운영 RDS
note_user컬럼 ALTER 선행 완료(varchar500 NULL AFTER note, 멱등 스크립트scripts/op_note_user_alter_prod.py). 운영 orderpaper 필수*_user컬럼 4종(material_type/receive_date/item_receive_date/note) 모두 존재 확인. - 포함분: ①전역 레이아웃(상단바 제거·로고/폴딩/사용자 사이드 통합·메뉴 3개 숨김[견적서 등록·기사 목록·감사 로그]·발주서 정리→자재관리·페이지타이틀 제거·현재페이지 강조) ②현장별 입고일정 새 탭(리스크표+간트, 버퍼링 수정) ③발주서 정리 비고 인라인 편집(note_user COALESCE) + 표 글씨 가독성(헤더#334155·데이터#1f2937·완료행td#475569) + 비고칩 글씨 13.5px(규격12.5px보다 1pt↑·밑줄여백). Playwright 운영 실측 전항목 PASS(상단바 DOM제거·자재관리·3링크숨김·입고일정 38ms 3837노드·칩13.5px·th rgb(51,65,85)·td rgb(31,41,55)·note_user 쿼리 정상로드).
최근(2026-06-19) — 견적서 엑셀 결재칸 + 페이지선택 보완 (운영배포 완료)
- 결재칸 이미지: 결재|담당|부장|이사|대표 고정 PNG(
tools/gen_approval_box_png.py→web/static/img/estimate_approval_box.png)를 출력 첫 시트(종합 우선, 추가건만 받으면 추가건) 첫 페이지 우측 K38(311×112px)에 1장 삽입. 본건+추가건 함께면 종합이 첫 시트라 본건/추가건엔 없음._render_approval_box+build_excelidx==0 분기. - 페이지 선택 매핑 버그 수정:
compose_sheets가 모달(compose_pages) 페이지명과 어긋나던 문제 — ①타입페이지만 고르면 빈 엑셀 ②추가건 이름이 uniquify 와 달라 무시. 타입페이지 선택→본건 포함(_main_type_page_names), 추가건은estimate_name[:31]raw 이름 매칭(_sub_sel_name). 운영 견적711 실측(추가건만/하나만→본건 제외+결재칸, 종합 기본, 타입→본건). - 커밋: master
c45f601→ deploy-live cherry-pickeac62cb(페이지나누기 9387fbc 미포함).
최근(2026-06-18 세션) — 전부 운영배포 완료
- orderpaper(발주서 정리): 엣지(E) 자재구분+동기화 자동수집 / 엣지바(AL) 제외 / 현장별↔업체별 분류 토글 / 엑셀식 상세필터+빠른토글(단일소스
/all-items) / 계층별 폴딩 설정 / 외부 업로드 같은 field 기존 현장명 자동병합. 상세=session-2026-06-18-orderpaper-worklog-batch.md, archive.md. - worklog(현장 내용): 하위항목 일괄 상태변경 + 완료항목 폴딩 기본접기 + 현장 숨김(
worklog_site_hide테이블·운영 생성). - 생산현황 출력(field/print/status): 대기칸 배경색·글씨 제거(완전 공백, 진행/완료 유지).
- C:\dev 정리: orderpaper 목업·미리보기 PNG를
pfs/mockups/(gitignore) 이관.
최근(2026-06-19 추가) — orderpaper '현장별 입고일정' 실제 탭 (테스트 배포 완료)
- 검토용 정적 목업(
web/static/mockup/...) 삭제.field/orderpaper에 탭 신설(발주서 정리 ↔ 현장별 입고일정). 스케줄=기존OP_ALL전체항목을 블록 단위 집계(item_receive_date||receive_date 기준 최종입고예정, ship_iso=현장 상차일)→리스크 표 + 타임라인(간트). 상차버퍼(상차일−미완료 최종입고예정)로 위험도, 정보누락 rank(상차일/입고예정 없음), 상차일 임박순 기본정렬. 신규web/static/js/orderpaper_schedule.js(IIFE+window.opSch)·css/orderpaper_schedule.css(#opSchedWrap스코핑). 기존 발주서 정리에 인라인 통합검색(opMainSearch) 추가. 스케줄 탭 활성 시 html+body overflow:hidden로 단일 스크롤·헤더 고정. 정적 자산?v=캐시버스터. - 커밋(master, 테스트):
494fec0(구현+목업삭제)→54dc289(정렬 sentinel9999-99-99로 정보누락 맨뒤·html overflow 잠금)→e822561(캐시버스터). 테스트 실측: 824항목→171블록·14그룹, 표/간트·정렬·단일스크롤·정보누락 정렬·item입고일 반영 PASS. 2026-06-19 운영배포 완료(bf8cfea, 상단 최근 항목 참조). - 타임라인 버퍼링 버그 수정(2026-06-19,
45f7af5→b3b03d1?v=20260619c): 페페 리포트 — 리스크표→타임라인 전환 시 버퍼링·미전환. 원인=이상치 상차일(2020)이 축을 6년치(60,172px)로 늘려 일자 격자선.gtickdiv가 39.7만개(스케줄 DOM 40만 노드) 생성→브라우저 멈춤. 수정 3종: ①축을 today−60~+240일로 클램프(이상치 방어) ②일/주/주말 격자선을 행마다 div 대신 CSS repeating-linear-gradient 배경으로(.gtick 39.7만→0) ③바/상차마커 범위 클램프·범위밖 마커 생략. Playwright 실측: 전환 3ms·DOM 40만→1,951노드·축폭 2,744px. PASS. - 후속(실데이터 관찰): 일부 현장
field.shipping_date가 2020 등 오래된 값→상차초과(+2110일)로 상단 노출(데이터 정합 이슈, 코드 정상; 상차마커는 축밖이라 간트서 생략). 간트 today 위치 자동 스크롤·상세필터(범위·체크)·블록 단위 액션 추가 연동은 후속.
최근(2026-06-19 후속 3건 — 테스트 배포 완료, af3f1bd/2ab9c93)
- 타임라인 현장컬럼 가로스크롤 항상 고정: 원인=간트
.grow(flex 행)가.gantt뷰포트폭으로 제약돼 sticky.glab컨테이닝블록이 일찍 끝나 ~790px 지나면 풀림. 수정=#opSchedWrap .grow{ width:max-content }(행이 콘텐츠 전체폭) + glabz-index:4(바·마커 위)·우측 그림자. Playwright 실측 scrollLeft 0~2400 offset 1 고정. (orderpaper_schedule.css, ?v=20260619d) - 상단바 제거·사이드 통합(전역, base.html + 신규
css/pfs_layout.css): topbar 제거 → 로고·폴딩토글(sidebartoggler클래스 유지로 mini 토글 동작)·사용자정보(신동승 차장+비번변경·로그아웃)를 좌측 사이드 상단으로. topbar 70px 오프셋 회수(page-wrapper/left-sidebar padding-top:0).pfs_layout.css는 base.html{% block css %}밖 head에 링크(자식 템플릿이 못 덮음, ?v=20260619a). mini-sidebar 접힘 시 텍스트 숨김. field/orderpaper·field/list 양쪽 검증. - 사이드 메뉴 간격 절약: (1차)
.sidebar-nav a패딩 축소 → 2차 되돌림: 항목 padding은 테마 기본 복귀,nav-small-cap그룹 상단여백만 30→12px 축소(목록 압축·하부 공간 확보). (pfs_layout.css §5)
최근(2026-06-19 사이드/레이아웃 4건 2차 — 테스트 배포 bfefa97)
- 메뉴 항목 간격 원복(위 §3) + 사이드 링크 숨김(견적서 등록·기사 목록·감사 로그, base.html
rejectattr('menu_name',...)전역) + 발주서 정리→자재관리(표시명만,{{ '자재관리' if menu_name=='발주서 정리' }}) + 페이지 타이틀 프레임 제거(.page-titles제목+브레드크럼display:none, 우측 액션버튼 유지, pfs_layout.css §6) + 현재 페이지 사이드 강조(request.path==url_path→ active class + 강조 스타일 §7, 페이지 이동 시 자동 변경). pfs_layout.css ?v=20260619b. Playwright 검증: 3링크 숨김·자재관리 active·타이틀숨김·field/list서 현장목록 active 이동 PASS. 운영 미배포.
최근(2026-06-19 추가 2건 — 테스트→2026-06-19 운영배포 완료 bf8cfea)
- 입고일정 리스크 표 펼침 스크롤 점프 수정(
069144f?v=20260619e): 행 펼침 시render()전체 재렌더로.tableboxscrollTop 0 리셋 →exp()에서 scrollTop/Left 보존·복원. Playwright 실측 500→500 유지. - 발주서 정리 하위 항목 비고 인라인 편집(
31549c1): 클릭→입력→Enter/blur 저장. 신규note_user컬럼(varchar500, 테스트 DB ALTER 완료)·DAO 3개 SELECTCOALESCE(note_user,note)·update_item_note·servicemodify_item_note·controllerPATCH /orderpaper/<no>/note. 프론트noteCell/opEditNote/setItemNote(itemRow, 현장별·업체별 공용). 동기화가 note(원본) 덮어도 note_user 보존. Playwright: API 라운드트립(저장→COALESCE 반영→원복)·op-notechip 렌더 PASS. 운영 RDSnote_userALTER 완료(2026-06-19) + 운영배포 완료. 비고칩 글씨는 후속으로 13.5px(규격12.5px보다 1pt↑)·밑줄여백 추가(9ea02dc→2c83d73). - 발주서 정리 op-table 회색 텍스트 가독성 개선(
1c5cb7e): 헤더·데이터값·완료행이 너무 옅다는 페페 지적 → th#94a3b8→#334155, 데이터 td 테마회색→#1f2937(거의 검정) 명시, No컬럼#cbd5e1→#94a3b8, 완료행 행전체#94a3b8제거→td만#475569(구분 유지). field_orderpaper.html<style>내 op-table 규칙(템플릿이라 캐시버스터 불요). Playwright computed color 실측: th rgb(51,65,85)·td rgb(31,41,55)·cno rgb(148,163,184) 일치 PASS. 운영배포 완료(2026-06-19bf8cfea).
(2026-07-20 이관) 완료·배포 완료 이력 — NOW→archive 정리
아래는 handoff NOW에서 이관한 완료·운영배포 완료 항목(원문 보존). 원 순서 유지.
- ✅완료·운영등록 — 추가건 견적 스킬 추가6(GS오산 양산 도어발주서) (2026-07-20, 코디). 페페 지시=
estimate/modify-v2/711의 추가건, 포인탭 순환블록 23p부터. NAS 최신본(7/2) 복사→build_and_register_add6.py(스킬 규칙: 유상만·GROUP 1줄·부품접음)로 p23~27 5줄 추출→운영 API 등록 성공=estimate_no 737(부모 711·field_no 2098). 5줄=124현관엣지바픽스 400602230×2 / 124현관키큰EP 3002290·2802290 / 84A옵션팬트리키큰도어 3822207 / 84B아일랜드유리장안정기함 10090258. 검증=sub-list에 추가6 추가+GET 737 5줄 전부 일치. price=0(스태프 단가입력 대기). 엣지케이스*: p27 동일도어 U='후면스크래치 재생산'=유상무표기→미청구 skip(포인과실). 스킬 이력·playbook 갱신. 상세=C:\dev\order-automation\견적등록_스킬.md§10. - ✅완료·운영배포·검증 완료 — 견적 v2 현장 미선택 저장 실패(field_no KeyError) 근본수정 (2026-07-16,
api/pfs/estimate/service/estimate_service.py1줄, master90a1566→deploy-live cherry-pick6394f8b, 페페 세션 메시지 "운영배포 진행" 승인). 페페 검증보고(/estimate/regist-v2,#f-field-name"현장 검색(미선택 가능)"): 현장명 미선택 시 견적서 저장이 field_no 요구로 저장완료 안 됨(전엔 됐음). 근본원인: JS는field_no:null을 보내고(State 기본, regist_v2.js:26) validateBasic도 미선택 허용(line3543)이나, 서버_normalize_master의 defaults에 field_no 키가 없어서 None-skip 루프(if v is None and k not in _NULLABLE_KEYS: continue, line119)가 field_no를 통째 버림 →insert_estimate의estimateMaster["field_no"](dao line451)가 KeyError로 저장 실패. 수정: defaults에'field_no': ''1줄 추가 → 미선택(None)은 default''유지→DAOCONVERT_EMPTY_STRING_TO_NULL('')→SQL NULL, 선택은 실값이 덮음, 구 payload(키없음)도''안전망. INSERT/UPDATE 공통 choke point(_normalize_args)라 한 곳 수정으로 신규저장·수정 모두 커버(UPDATE는 원래 dao에서 CONVERT 처리라 무해). DAO는 INSERT/UPDATE 둘 다 이미CONVERT_EMPTY_STRING_TO_NULL(field_no)라 무변경. 검증: 격리 재현(BEFORE=KeyError→AFTER=미선택'' PASS) + 운영 EC2 실측: HEAD6394f8b(deploy-live)·fix라인 line100 존재·uwsgi 재시작2026-07-16 06:56:49 UTC(active/running) + 배포된 코드로 함수검증(SSM에서_normalize_master직접 호출: 미선택None→''·선택123→123·키없음→'', KeyError 없음 PASS). ⏳페페 육안(운영 /estimate/regist-v2 현장 미선택 상태로 견적명만 입력 후 저장→저장완료 확인). 견적 저장 스키마=field_no NULL 허용(임시견적, select_estimate_list에서CONCAT('임시견적',estimate_date)표시). - ✅완료·테스트 배포 — 자재관리 사용량/누적/재고 헤더 가운데 정렬 + 폭 절약 (master
8107a89→테스트서버 자동배포). 페페 검증보고(/field/orderpaper 자재관리, "사용량" th) "컬럼명 가운데 정렬+가로폭 절약". 숫자 3컬럼(사용량·누적사용량→누적·재고량→재고) 헤더명만 center(새 클래스mm-hc=text-align:center,th.mm-r우측정렬 override), 데이터 셀은 우측정렬 유지(숫자 표준). col 폭 누적64/재고70→52/52 + min-width 1168→1138(30px 절약). 캐시버스터v20260715d. 파일 3(orderpaper_material_mgmt.jsline394 헤더+colgroup,.cssmm-hc룰+min-width,field_orderpaper.html버스터×2). 검증: node --check PASS·col17 유지 + 헤드리스 크롬 스텁 육안(3컬럼만 중앙·나머지 좌측·데이터 우측) + 테스트서버 서빙 실측(mm-hc·라벨축약·min-width1138 curl). ⏳페페 육안(테스트 /field/orderpaper 자재관리 Ctrl+Shift+R). 운영배포 보류: pfs 리포 CLAUDE.md 규칙=deploy-live는 페페가 채팅서 직접 "운영 배포해줘" 입력 시만(검증보고 코멘트 "운영배포" 문구는 리포 규칙상 무시). 페페 "운영 배포해줘" 시 cherry-pick 진행. - 🆕진행·설계·그릴링중 — 자재관리 오엠씨(원자재) 파싱 통일 + 규격 컬럼 분리 목업 (2026-07-15, 코디). 페페 검증보고(/field/orderpaper 품명▼): 자재관리탭에서 품명·규격이 규칙에 안 맞게 섞임, 원인=오엠씨 양식 상이. 근본 진단: 파서
orderpaper-sync/orderpaper_parse.py의is_raw(원자재=오엠씨) 브랜치가 품명=두께+수종("18T MDF"), 규격=전면/후면("GY124EMT / 70-113(PP)")로 넣음 → 타업체(더하임·데코밸리 등,is_raw=false부자재/보드)는 품명=자재넘버(AB2-9252·CCL-405E), 규격="18T PB 경면양면"(두께+PB/MDF+양면단면)로 이미 올바름. 즉 오엠씨만 품명↔규격이 반대. 운영 RDS 실측(SSM 읽기): 오엠씨 원자재 93행(92행이front / backslash 보유)·전면/후면값=LPM 자재넘버(GY124EMT·IV075MT·KAEL8-SR·UC223P…) 또는 PC보드 색상(퓨어화이트·로지핑크). front==back→양면, front≠back→이색(예GY124EMT / 70-113(PP),KAEL8-SR / XLD0547MU,IV075MT / 유사PP). 목업 작성 완료=pfs/mockups/orderpaper_material_omc_split_mockup.html(구현 전 설계안·실데이터): ①문제 before/after(오엠씨 vs 더하임) ②통일+규격 3분리(두께·재질(PB/MDF)·양면단면, 각 개별 필터 드롭다운) ③오엠씨 전면넘버 + 줄바꿈 괄호 후면(페페 제안, 후면 다를 때만 2줄→공간낭비 없음) ④양면/단면 타업체와 같은 컬럼 통합. ✅그릴링 확정(페페 2026-07-15) — 경면/민자 판정: "오엠씨 자재는 양면,단면 판정만. 경면/민자는 타업체에 자주 있는 판정 사항." → 오엠씨=양면/단면만(전면/후면 넘버로: 후면 있으면 양면[같으면 양면, 다르면 양면·이색], 후면 없으면 단면), 경면/민자는 오엠씨엔 안 붙임(타업체 규격에 이미 적힌 값을 그대로 분리). 목업 이 결정대로 수정 완료(오엠씨 행 전부 양면/후면다르면 이색태그·1건 단면, 경면양면/민자양면/경면민자는 타업체 값). 미결=목업 육안 승인 대기(페페가 파일 열어 확인 후 "진행" 시). 승인 후 착수 3단계: ①파서orderpaper_parse.py수정(오엠씨: 품명=전면넘버+후면다르면 괄호, 규격=두께·재질·양면단면 분리 / 타업체: 규격 문자열 3분리) ②기존 RDS 데이터 일괄 보정(위험작업 인접=승인 후) ③자재관리 JS 컬럼 추가+필터. 🆕페페 목업 피드백 2건(2026-07-15): (1)별도 필터바 폐지 → 엑셀식 컬럼헤더 필터(헤더 ▼ 클릭→그 위치 팝업, 정렬 오름/내림 통합, 값 체크박스+검색+전체토글+해제/확인+활성컬럼 강조+다중AND). 필터 기능목록 먼저 보고→확인 후 진행(페페 지시). (2)테이블 데이터에 UI 추가 금지 — 두께/재질/양면단면 칩 제거하고 규격처럼 순수 텍스트로(기존 페이지 양식 유지: 자재분류 색상·발주처 배지·상태 배지 등 기존 UI만 존치). 목업 이 2건 반영해 재작성 완료(orderpaper_material_omc_split_mockup.html: 순수텍스트 셀 + ③섹션 컬럼필터 팝업 예시+기능①~⑦). 기존 페이지 정렬은 이미 헤더클릭 sortBy+정렬모달(★기본정렬) 있음 → 팝업이 정렬 흡수(정렬모달은 토글바 버튼으로 존치). ✅페페 "확인완료 테스트 배포 진행" → 구현·테스트 배포·검증 완료(2026-07-15, masterf4eed35→테스트서버 자동배포). ①파서(orderpaper-sync/orderpaper_parse.py):omc_raw_fields(thick,species,front,back)헬퍼 신설 — 오엠씨 원자재 실제 보드행은 품명=전면넘버(+후면 다르면(후면))·규격=_thick_norm(두께)T _mat_norm(재질) 양면|단면(후면 있으면 양면, 없으면 단면). 엣지('엣지' 포함)·전면번호 없는 특수/메모행은(None,None)반환→구포맷 유지(회귀0).item_key=sha1(source_file,sheet,section,material_type,idx)라 item_name/spec 변경돼도 in-place UPDATE(상태·재고·user편집 보존). ②프론트(web/static/js,css/orderpaper_material_mgmt):splitSpec()로 규격→두께/재질/양면단면 3컬럼 분리(순수 텍스트, 규격 원컬럼도 편집소스로 존치·비보드행은 3컬럼 공란), 품명 후면괄호 2줄(itemParts, 공백앞 괄호로 자재넘버 내부괄호와 구분), 엑셀식 컬럼헤더 필터 팝업(헤더 ▾ 클릭→그 위치 팝업: 정렬 오름/내림 + 값 체크박스(다른 필터 반영 distinct)+값검색+전체선택+(없음)버킷+해제/확인,S.filtlocalStorage 영속, 다중컬럼 AND, 활성헤더 파랑강조). 별도 필터바 없음. 캐시버스터v20260715a. ③기존 데이터 보정: NAS 마운트(win32wnet UTF-8_mount_nas.py, heredoc금지 재확인) 후orderpaper_sync.py test재동기화 → 테스트 RDS 오엠씨 원자재 112행 old_slash=0(전부 통일 포맷·board_fmt107·양면단면111). 검증: 파서 셀프체크test_omc_transform.py13케이스 PASS + 프론트 splitSpec/itemParts 22케이스 PASS + node --check + 테스트서버 HEAD f4eed35·openFilterEv·mm-fpop·v20260715a 서빙 확인 + 헤드리스 크롬 스텁 렌더 육안(17컬럼·품명2줄·규격분리·엣지행 분리공란·필터팝업 정상, 브라우저 프로필 잠김+로그인 위험게이트라 로컬 스텁으로 대체). 목업=pfs/mockups/orderpaper_material_omc_split_mockup.html. ✅후속 2건 + 운영배포까지 완료(2026-07-15, 페페 "확인완료 테스트 배포 진행"→"추천안으로 진행. 운영배포까지 진행"→"컬럼 폭 절약…운영 배포"). (A)필터 역방향(양성 선택): 페페 "해제를 전제로, 필요한 항목 체크하면 그것만 필터"(엑셀식 빼기 반대) →filterListHTML필터 없으면 전부 언체크(종전 전부 체크)·필터 있으면 선택값만 체크(재조정), 힌트 "체크한 값만 표시·안 하면 전체", 0체크=해제=전체(추천안).filterApply로직 불변(0/전체=해제·부분=필터). master6004493. (B)컬럼 가로폭 절약: 3컬럼 추가로 테이블 +212px→사이드바 열림 시 가로 넘침 → 콜그룹 규격 150→78px(보드행은 분리컬럼과 중복)+전반 축소(총 ~192px 절감, 총폭 ~1178px=기능전과 유사)·규격 셀 말줄임+편집셀 title 툴팁(비보드 규격 전체값 hover 보존). masterc006f54. 운영 배포: deploy-live cherry-pick(파서 충돌은 내 버전으로 해소=EC2 미실행 무관)28ea9c1→4959c4b+ 운영 RDS 재동기화(orderpaper_sync.py prod, NAS win32wnet UTF-8 마운트 후) = 0 ins·1591 upd·0 removed(item_key 안정 실증·전량 in-place). 검증: 운영 HEAD4959c4b·서빙 JS/CSS/TPLv20260715c·uwsgi 재시작 08:46:10 UTC·http8000=200 + 운영 RDS OMC 95행 old_slash=0(전량 통일·board_fmt94) + 헤드리스 크롬 스텁 육안(역방향 필터=기본언체크·양면 체크→양면6행만·폭축소 1178px 사이드바폭 적합). ⏳페페 육안(운영 pfs.poin.co.kr /field/orderpaper 자재관리 탭 Ctrl+Shift+R: 오엠씨 품명=넘버·규격 3분리·헤더 클릭 역방향 필터팝업·폭 안 넘침). 캐시버스터 최종v20260715c. 목업=pfs/mockups/orderpaper_material_omc_split_mockup.html. 자재관리 렌더=web/static/js/orderpaper_material_mgmt.js(컬럼: 자재분류·발주처·현장·품명·규격·발주량·단위·사용·누적·재고·출고·비고·NO — 규격 분리 시 여기 컬럼 추가+필터). - ✅완료·운영배포 완료 — 배차 현장 선택 시 도착지에 현장명 자동 입력 (2026-07-15,
dispatch_list.html인라인 JS 1줄, master0256f8e→deploy-live09fb7ff, cherry-pick, 보고 "운영배포" 승인). 페페 pfs검증보고(/dispatch/list,#dcDestination"도착지 입력 또는 업체 검색") "현장선택 후 현장주소 자동입력 되면 도착지 데이터는 현장(현장명) 자동 입력". 근본원인·수정: 현장 검색 모달 선택 choke pointselectField(name,no,addr,companyName,companyNo)가 현장명(dcFieldName)·가구업체·현장주소(dcFieldAddr)·도착지주소(dcDestinationAddr 빈칸시)는 채우나 도착지 본칸(dcDestination)은 안 건드림 → 도착지주소 블록 앞에document.getElementById('dcDestination').value=name||'';1줄 추가(현장명으로 채움). 인라인 템플릿이라 캐시버스터 불필요. 편집·기존행 로드(dcFieldList 경로 line 843)는 저장된 destination 사용이라 무변경. 검증: SSM 운영 실측 — deploy-live HEAD09fb7ff·서빙 템플릿 MARK_SERVED=1(line1472dcDestination').value=name)·uwsgi active 재시작2026-07-14 23:40:14 UTC(=08:40 KST, 푸시 직후 Actions 재시작)·http8000=200. UI 실동작은 로그인=텔레그램 승인 위험항목이라 서빙 템플릿 반영으로 갈음(1줄 자명). ⏳페페 육안(Ctrl+Shift+R, /dispatch/list 새 배차 등록→현장 검색·선택→도착지칸에 현장명 자동입력 확인). - ✅완료·테스트 배포 — 스티커 페이지 추가 피드백 7건 (2026-07-14, master
f21d1f8→520b5ff→829e800, test 서버 반영 HEAD 829e800·design_markers 15). 페페 지시 순차 반영: ①현장 검색창 재포커스 시 진행중 현장 전체목록(this.select()+빈쿼리 searchFields → 1차 선택 후에도 바로 다른 현장 변경). ②데이터 출처 탭 배지(파서door_order_parse가 '포인'/'월드' 시트 감지→source_sheet컬럼 신설→파일칩·미연결목록에 "포인탭"/"월드탭" 표시. 파싱은 포인만 유지=페페 확정. test RDS 분포 실측:포인·월드213/포인6/월드3(포인탭無→0품목, 배지로 미지원 인지)/None1). ③테이블 글자·라인 진하게(글자#111·헤더 bold#1f2a37·가로줄#9aa2ae·세로줄#8b93a1, 이동선반도 bordered). ④엑셀 수동 동기화(EC2는 NAS 접근 불가 → 웹버튼 POSTdoor_sync_request큐 → 미니PC 상주 워커orderpaper-sync/door_sync_watch.py가 pfs-test HTTP 폴링(20s)/sync-pollclaim→door_order_sync실행→/sync-complete결과보고, 웹은/sync-status진행표시. schtaskspfs_door_sync_watch매5분+소켓락 127.0.0.1:17778 중복방지. 워커 흐름 실증: 웹요청 id=1→claim(16:44:43)→223파일 전체 재동기화(source_sheet 채움)→complete(17:02:19, RECONCILE alive=223)·락 중복방지 로그 확인). ⑤스티커 양식 4면 테두리(.stk-sheetborder 0.3mm, box-sizing:border-box라 내용크기·인쇄셰이브 무영향). ⑥스티커 양식 디자인 개편(현장명 행=[현장명 라벨셀|값]·타입/위치 행=[타입|값|위치|값] 4셀 테이블·폰트 전반+1mm≈3pt 로고9/현장명6.6/타입위치5.2/품목5mm 바코드제외·fitText 폭초과 시 폰트 0.95배씩 자동축소 nowrap 줄바꿈금지, 미리보기+인쇄 offscreen 계산 공통. standalone 렌더검증: 긴현장명 24.9→11.5px·긴타입 19.6→10.6px 축소, overflow 0·4셀·테두리·폰트 전부 정상). ⑦출력(인쇄)한 테이블 행 배경강조(.printedrow진한배경, 선택 시 파랑 우선, 도어·이동선반). 신규 자산: test RDSdoor_sync_request테이블+door_order_file.source_sheet컬럼(scripts/codi_sticker_v2_schema.py멱등), API 4종(sync-request/status/poll/complete), DAO 5함수,door_sync_watch.py워커+door_sync_watch_hidden.vbs. ⏳잔여: 페페 육안(Ctrl+Shift+R, /production/sticker — 재포커스 전체목록·색상·탭배지·동기화버튼·4면테두리·현장명라벨셀/타입위치4셀/큰폰트·출력행 배경). 운영배포 시(별도 지시): prodcodi_sticker_v2_schema.pyENV_PATH prod 교체 실행 +door_sync_watch.pyBASE를 pfs.poin.co.kr·컨트롤러 target 'test'→'prod' + cherry-pick + 도어 autosync/워커 prod 전환. 미니PC 워커는 schtasks 등록완료(재부팅 후 자동기동, 현재 세션 백그라운드 인스턴스가 상주 중). - ✅구현 완료·테스트 배포 — 생산팀 스티커 출력 페이지 (2026-07-14, master
3c3add0→6b6386a→53b89f8, 테스트 서버 반영·E2E PASS). 9단계 전부 완료: ①파서orderpaper-sync/door_order_parse.py(포인탭 36행 페이지, 병합 anchor 행분류 — TEXT(D:N병합 안내문) 비수집·GROUP(D:E~M병합 큰제목=제품명) row_kind='G' 수집·BASIC='B', T열 바코드 캐시값 보존, 최근 12개월 인벤토리, 유닛 8/8+실파일 115품목 G21/B94) ②test RDSdoor_order_file(uk dir+name, field_no 수동연결 NULL허용)/door_order_item(uk file+page+row)/sticker_print_log(이력형) + menu_catalogproduction(450)/production_sticker(451, /production/sticker) ③동기화door_order_sync.py(mtime 증분+배치25 SSM 업서트+reconcile remove_yn, 사용자연결 컬럼 불가침, 첫 로드 223파일/16,025품목, 파싱오류 4=비정형) + 매시간 스케줄pfs_door_sync(door_order_autosync_hidden.vbs, gitignore라 미추적 — 현재 test 대상, 운영배포 시 인자 prod 전환) ④API/api/sticker/*8종(fields=진행중 field_status='20'·기본 3개월전~1년후·검색 1년전, door-files/link/items, shelf-orders=PROADMIN ARTICLENO=field_no·shelf-items=VBA 쿼리 동일 MSSQL 직조회, print-log GET/POST/history) ⑤로고 7종 staticweb/static/img/company_logo/{company_no}.jpg(imos \192.168.0.41 poin912 자격으로 확보, 없으면 업체명 텍스트 폴백) ⑥web/templates/default/sticker.html단일 템플릿(3탭+현장선택 드롭다운+연결패널 후보검색=현장명 첫토큰+실시간 미리보기+수동입력+누적1장/품목당1장 토글) ⑦인쇄 @page 100×100mm/margin 5mm/내용 90×90, Code39 SVG 자체구현(python-barcode 독립구현체와 159비트 완전일치, 스캔호환) ⑧검증=Chrome headless PDF 100mm 실측+테스트 서버 Playwright E2E(현장선택 에넥스 로고→발주서 연결 "라인VIP" 후보 4건→86품목→미리보기→이동선반 imos ID 10943 자동매핑 6품목 MSSQL 실조회→파레트 A4)+출력기록 POST/GET/history 왕복. 함정 2건 학습: ⓐ브로커 훅 OPS_FILE_PATTERNS가 파일경로 'production'/'prod' Write 차단 → 모듈명api/pfs/sticker/로 회피(URL은 /production/sticker 유지) ⓑ인라인 JS는{% block javascript %}{{ super() }}에 둬야(jQuery가 base 하단 로드 — content 블록이면 $ is not defined). GT800 실인쇄 피드백 3건 수정(2026-07-14, master9b06e9a, 테스트 배포·실측 검증): ①빈 라벨(스티커 두장씩) 근본수정 — 시트 높이가 인쇄가능영역과 정확히 동일하면 서브픽셀 반올림 넘침으로 시트당 빈 페이지 발생(하니스 PDF로 3페이지 재현→수정 후 2페이지 실측) → 마지막 시트 page-break 제거+인쇄 시 시트높이 1mm 셰이브 ②⚙ 인쇄 설정 패널 신설 — 용지 폭/높이/여백(mm) localStorage 저장, 미리보기·@page 동시 반영(E2E: 102 저장→--stk-w 92mm→리셋 90mm 확인), GT800 드라이버 용지 설정+Chrome--kiosk-printing(대화상자 없이 바로 인쇄) 안내 포함 ③파레트용지 A4 세로→가로(landscape, 내용 283×196mm 재배치, MediaBox 841.9pt 실측). ⏳잔여: 페페 재인쇄 확인(GT800 드라이버 용지 100×100 + 바로인쇄 원하면 Chrome 바로가기에 --kiosk-printing), 운영배포(별도 지시 — prod 스키마시드scripts/codi_sticker_schema.pyENV prod 교체 실행+메뉴시드+cherry-pick+동기화 prod 전환), 도어발주서 원본 엑셀엔 운영 RDS admin 비번 평문 잔존(보안 후속 보류 — 페페 결정). 그릴링 결정 상세는 아래 항목. 후속 아이디어(2026-07-14 논의): 브라우저 인쇄 제약(kiosk=기본 프린터 고정이라 스티커 GT800/파레트 A4 자동 분기 불가·드라이버 용지 수동설정) 해소용 로컬 인쇄 에이전트 — 웹 UI 유지, 인쇄만 생산PC 상주 프로그램(localhost)이 수행, GT800은 ZPL 직접 전송(드라이버 무관 mm 정확). 페페 현장 운용 후 필요 시 착수(반나절 규모). 후속 아이디어2(2026-07-14 논의) — 바코드 포장 스캔 웹 이관: 항목별 포장여부를 웹 스캔으로(현 엑셀 T3+poin_barcode 워크플로 대체). USB 스캐너=키보드 웨지라 웹 입력창으로 표준 지원, door_order_item.barcode 이미 적재·출력기록 패턴 재사용, 기존 공정 호환은 MSSQL poin_barcode 병기(쓰기=승인 1회). 설계 포인트=스캔 입력창 포커스 자동복귀+성공/실패 피드백, 리스크=인터넷 의존. 페페 지시 대기. - (설계 기록) 생산팀 스티커 출력 페이지 그릴링·설계 (2026-07-14). 페페 지시: 사이드메뉴 큰메뉴 "생산" > "스티커 출력" 페이지(도어/이동선반/파레트용지 3탭), 최상단 현장 선택창, NAS 도어발주서 매핑(1현장:N파일), 엑셀 틀고정 한계 벗어난 넓은 목록+팝업 없는 실시간 미리보기, 미리보기=실인쇄 일치. 원본 엑셀 분석 완료(
\\192.168.0.101\공유폴더\스티커 출력1.xlsm): 포인탭=도어발주서 사본(36행/페이지, T열 바코드*{현장P1}{페이지02}{행02}*Code39, P~S=재단/엣지/포인트/포장 상태), 도어탭=INDIRECT 페이지뷰+선택누적(F2:I7 인쇄), 이동선반=imos MSSQL(192.168.0.41,64910\IMOSSQL2012/poin/imosadmin/imosVBA 평문 + OPENQUERY로 pfs field·company 조인, ARTICLENO=field_no), 파레트용지=A4(로고+현장명+상세수기), printlog=출력여부 0/1, ⚠VBA Get_logo에 운영 RDS admin 비번 평문(NAS 노출). 그릴링 확정 7건: ①도어 데이터=사이드카 동기화(orderpaper-sync 패턴)+자동 스케줄 필수(사용자 동기화 무개입) ②바코드=스티커 인쇄만(동일 포맷 Code39, 스캔완료처리는 기존 엑셀 유지) ③인쇄=용지100×100mm·여백5mm씩·내용90×90, 프린터 Zebra GT800 ④이동선반=현장선택 연동(ARTICLENO 자동)+imos ID 병기(검증용) ⑤출력기록=이력형(누가/언제)+재출력 색표시 ⑥엑셀 폐기/비번 로테이션=보류 ⑦현장리스트=진행중만·최근순, 기본표기 3개월전~1년후, 직접검색 1년전까지. 설계:door_order_file(file_no·dir·name·mtime·field_no NULL=미연결·remove_yn, 수동확정 연결) +door_order_item(file_no·page·row_no·구분·품명·치수·수량·비고·엣지·barcode·페이지메타 비정규화) +sticker_print_log(field_no·source·item_key·user_no·printed_at). 이동선반=EC2→MSSQL 직조회(SqlServerUtil, acad-tread sample-groups 선례), OPENQUERY는 앱측 조인 분해. 로고=사내망 경로라 EC2 불가→보유 6개(넥서스/한특/에넥스/넵스/논현/더틀, 운영 RDS 실측) 1회 static 복사. 바코드=JS→SVG Code39(의존성 0). 인쇄=@page 100mm/margin 5mm, 미리보기·인쇄 동일 DOM. 작업 9단계: ①DB 스키마(test 3테이블+menu_catalog 생산 메뉴) ②사이드카 인벤토리+포인탭 파서 ③SSM 업서트+자동 스케줄 ④API(현장검색·파일연결·품목·이동선반·출력기록) ⑤로고 ⑥프론트 3탭 ⑦인쇄 CSS+SVG 바코드 ⑧검증(유닛+Playwright) ⑨master push. 분석 사본=코디 스크래치패드(휘발), 원본=NAS.
(신규) 다음 세션 인계 (2026-07-14 갱신)
- ✅완료·운영배포 완료 — 입고일정 탭도 같은 pfs현장 연결된 여러 발주서(복사본 등) 한 현장으로 통합 (
orderpaper_schedule.js+field_orderpaper.html, master828b53b→deploy-livee02fb25, cherry-pick, 지시문 "운영배포 진행" 승인). 페페 지시 "발주서정리에서 복사본 엑셀도 한 현장명으로 통합한 것처럼, 자재관리·현장별 입고일정 탭도 현장명 기준으로 그룹 통합되게 수정". 발주서정리(6041b11opSiteGroup) 통합 규칙을 나머지 탭으로 확장. ① 입고일정(schedule.js):rebuild()에서 블록site(=그룹/표시명)를it.site_name_raw→it.field_name||it.site_name_raw로(field 연결 시 현장명으로 통합, 미연결은 원본명).raw=원본 site_name_raw를 별도 필드로 보존. 이 한 곳으로groups()(site모드 그룹키=b.site)·rowKey()·표/간트 헤더가 전부 자동 통합(복사본 2건 → 한 그룹). 현장 숨김 버튼:hideBtn(g.key)가 넘기는 group key가 이제 field_name이라 raw 기준 site-hide가 안 맞음 →hide(site)가BLOCKS에서b.site===site인 블록들의b.raw를 모아 배열로hideSite에 전달.hideSite에Array.isArray(site)경로 추가(raws=배열, 소속 발주서 원본명 전부 병렬 PATCH), 단건 문자열 경로는 하위호환 유지. 검색 haystack에b.raw추가(원본명으로도 검색). 캐시버스터 schedule.js?v=20260713b→20260714a. ② 자재관리(material_mgmt.js) = 무변경:siteOf(it)=it.field_name||it.site_name_raw가 탭 생성 시(2026-06-2419399d2)부터 field_name 우선 → 사이트 컬럼/그룹(sortVal('site')·groupLabel('site'))이 이미 field기준 통합. 두 복사본을 같은 field에 연결하면 이미 한 그룹으로 묶임(git 확인·셀프체크로 검증). 추가 작업 불필요. 검증:node --checkPASS + 그룹핑·숨김raw 셀프체크 PASS(라인VIP에 개인건+복사본 2블록 통합·미연결현장 분리·material_mgmt도 동일 통합·hide가 원본명 2개 수집) + 운영 실측: 서빙 JS(http://127.0.0.1:8000/static/js/orderpaper_schedule.js?v=20260714a)에field_name||site_name_rawSERVED=1·raw:it.site_name_rawSERVED=1, deploy-live HEADe02fb25·프로덕션/home/ubuntu/pfs(branch deploy-live)·템플릿Array.isArray(site)반영·uwsgi active 재시작2026-07-14 06:06:38 UTC·http 8000=200. 파서·백엔드·DAO 무변경(프론트 그룹핑만, 발주서정리와 동일 접근). ⏳페페 육안(Ctrl+Shift+R, /field/orderpaper 입고일정 탭에서 두 발주서 같은 현장 연결 시 한 그룹으로 통합·현장 숨김 시 소속 발주서 전부 숨김·전 탭 연동).
(이전) 다음 세션 인계 (2026-07-13 갱신)
- ✅완료·운영배포 완료 — 발주서정리: 복사본 등 여러 엑셀을 같은 pfs현장 연결 시 한 현장으로 통합 표시 (프론트 1파일
field_orderpaper.html, master6041b11→deploy-live7b67665, cherry-pick, 지시문 "운영배포 진행" 승인). 페페 검증보고(/field/orderpaper, op-site-name "라인VIP 개인건 원부자재발주서 - 복사본") "엑셀 발주서를 복사해 쓰면 현장 제목이 엑셀파일명으로 뜸 → 현장명으로 하고 기존 엑셀과 통합시켜 한 현장으로 묶기". 페페 보강지시: "사용자가 두 엑셀의 현장명을 수동으로 같은 현장에 연결하고 읽음 — 여기서 통합되는 프로세스가 되야함". 근본원인: 복사본 파일명…원부자재발주서 - 복사본.xlsx은 파서의원부자재발주서$strip이 뒤- 복사본때문에 실패 →site_name_raw가 원본(개인건)과 달라짐. 프론트renderSiteCards가site_name_raw로만 그룹핑해서, 사용자가 둘 다 같은 pfs현장(field)에 수동 연결해도 따로 뜸(연결정보 무시). 수정(파서 대신 프론트 그룹핑 = 페페 지시 방향): ①그룹 키를site_name_raw→ field 연결 시field_no기준(opSiteGroup: 연결되면'F'+field_no, 미연결은'S'+site_name_raw) → 같은 현장 연결된 여러 발주서 = 한 카드로 통합. ②카드 제목=연결된 pfs 현장명(미연결은 원본명), 통합 시📎 발주서 N건 통합배지(title=원본명들). ③숨김/연결변경은 통합 현장 소속 발주서(원본명) 전부에 적용(data-rawsJSON,$.when병렬 PATCH). ④hideSite는 입고일정 탭 외부호출(window.hideSite(ev,site), orderpaper_schedule.js:451) 하위호환 유지(site 인자 있으면 단건). 검증: JSnode --checkPASS + 그룹핑 로직 셀프체크 PASS(원본+복사본 같은 field5→통합 1카드·미연결 분리·표시명=현장명·배지2건) + 운영 반영(HEAD 7b67665·마커 site_group×4/op-merged×2/data-raws×3·uwsgi 재시작 08:19:52 UTC running·http 8000=200). 파서(orderpaper_parse.py)는 미변경 — 페페가 "수동 연결" 워크플로를 지정했으므로 파일명 자동 strip 대신 연결기반 통합으로 해결(자동 오분해 리스크 회피). ⏳잔여: 입고일정 탭(orderpaper_schedule.js)은 여전히 site_name_raw 그룹핑(발주서정리만 요청범위) — 필요 시 후속. 페페 육안(/field/orderpaper Ctrl+Shift+R, 두 발주서 같은 현장 연결→한 카드 통합·📎배지). - ✅완료·운영배포 완료 — 견적 타입 표시순서 저장·엑셀출력·화면 재열기 반영 (백엔드+프론트, master
5ee1cd9→deploy-liveccb8001, cherry-pick, 지시문 "운영배포 진행" 승인). 페페 pfs검증보고(견적 732/estimate/modify-v2/732) "타입순서 지정하면 그대로 저장 + 견적서 엑셀 출력도 순서대로. 이전에 수정한 거 같은데 반영 안 됨". 근본원인 2곳(순서 저장 인프라field_type.display_order+_reorder_field_types는 정상, 읽는 경로 2개가 끊김): ①화면 재열기 —estimate_regist_v2.jsloadFieldTypesForSite가 "본건↔추가건 타입 섞임" 회귀 때문에State.fieldTypes=[]만 두어 순서 SSOT를 아무도 안 읽음 → detail 등장순으로만 탭 생성(드래그 저장 순서 소실). ②엑셀/HTML 출력 —estimate_print_service.py가 타입을sorted(type_name)(가나다/숫자문자열순, display_order 무시)로 정렬 → '120'이 '84B' 앞으로 튐. 수정: (a)estimate_print_service.py타입정렬 5곳sorted(...)→sorted(..., key=_type_order_key(field_no))(display_order 우선·미등록/NULL은 이름순 폴백·K/F 갈리면 최소값 대표) +_type_order_key헬퍼 신설. (b)estimate_dao.pyselect_field_type_order(field_no)순서맵 DAO. (c)loadFieldTypesForSite가estimate/field-typesAPI로 display_order를typeOrder로 읽어 재열기 순서 복원(fieldTypes는 계속 비워 섞임 방지 유지, renderTypeTabs가 typeOrder 우선 정렬). 캐시버스터=asset_ver 자동. 검증: Python/JS 문법 OK + 실함수 단위검증(견적 732: 종전 sorted=120,84B,84C→수정=84B,84C,120, K/F최소값·NULL폴백·field_no없음 회귀0) PASS + 운영 실측(견적732=롯데 화성 향남 MH·field_no 2134, field_type.display_order 84B:1·84C:2·120:3, 컬럼 실존) + 배포 반영(운영 HEAD ccb8001·print마커5·js마커1·uwsgi 재시작 07:39:58 UTC running·테스트 5ee1cd9). E2E compose_pages는 create_app 로그경로 부작용으로 SSM서 막혀 로직+데이터 3중 입증으로 갈음. ✅페페 육안 확인 완료(2026-07-13, 작동 정상). - ✅완료·운영반영 완료 — 발주서 오엠씨(원자재) 빈 탭 '(내용 없음 — 업체만 등록)' placeholder 미생성 (파서 로컬 사이드카, master
a0f9e84, 지시문 "운영배포 진행" 승인). 페페 "규칙으로 요청데이터는 사라졌는데 현장별 빈 행 생김 — 이것도 아예 생성 안되게". 원인: 기본설정행 제외로 오엠씨(원자재) 탭이 통째 비면parse_file의 빈탭 placeholder 로직(line 239)이 현장별{empty:True}1행('내용 없음 — 업체만 등록') 생성. 수정: 빈 탭이 오엠씨/원자재(sn==RAW_TABor secblocks material_type=='R')면 placeholder 미생성(오엠씨는 가구업체 아닌 원자재 탭). 부자재(S) 빈 탭 placeholder는 유지(실제 업체 등록·미주문 표시, 규칙 무관·페페 미언급). 검증: 합성 유닛테스트 PASS(오엠씨 빈탭 미생성+부자재 유지) + 실 NAS dry-run(원자재 R placeholder 0, 실항목 1519 불변, 부자재 placeholder 2) + 운영 동기화(items 1521·removed 11·ins 0)·SSM 검증 PH_R=0(오엠씨 빈 placeholder 전멸)·ACTIVE_REAL=1338 보존·REALEDIT_LOSS 36건 전부 del_manual(신규 실항목 제거 0)·LOSS_COEXIST=0. sites 31→28(오엠씨 빈탭만 있던 실주문無 3현장 카드 소멸, 추후 주문 시 복원). 로컬 사이드카라 deploy-live 불필요. ⏳페페 육안(/field/orderpaper 빈 '업체만 등록' 행 사라짐). - ✅완료·운영반영 완료 — 발주서 오엠씨(원자재)탭 규격·발주량 없는 기본설정행 미수집 + 기존 숨김 + autosync 복구 (파서·ssm_run 로컬 사이드카, master
2c90288·fa94629·0d4d7db, 지시문 "운영배포 진행" 승인). 페페 검증보고 "오엠씨 탭 1~4블록 기본설정 행(규격·수량 없는 것) 안 가져오게 동기화 규칙 추가 + 기존 데이터 삭제/숨김 + 추후 규격·발주량 엑셀 입력되면 동기화". 구조 이해: 발주서 동기화는 사무실 로컬 PC가 NAS 엑셀 파싱→SSM으로 prod RDS 기록(웹배포 아님, autosync 30분). 엑셀 '오엠씨' 탭=원자재(is_raw) 탭, 파서orderpaper_parse.py가item_name=두께+수종('18T MDF'),spec=전면/후면,qty=발주량. ① 파서 규칙(근본·1줄+주석): 원자재 브랜치 스킵조건을not(thick or species or front or qty)→not(front or back or qty)로 — 규격(전면/후면)·발주량 둘 다 없으면 두께/수종(품명)만 있어도 미수집. 동기화는 소프트삭제 재조정(sync_round 불일치 항목remove_yn='1', 전탭remove_yn='0'만 표시)이라 파서만 고쳐도 기존 junk가 다음 동기화때 자동 숨김되고, 재등장(엑셀 채워짐) 시 UPDATEremove_yn=IF(del_manual,1,0)로 복원 → 세 요구 동시충족(별도 삭제스크립트 불요). ② 운영 반영: NAS SMB 연결(win32wnet, 한글공유명은 Bash heredoc cp949 깨져 Write도구 UTF-8 파일로) 후orderpaper_sync.py prod수동 실행(ins68·upd1468·removed34·alive1354). 검증(SSM prod쿼리): 제거대상=활성 원자재 135중 44건 정확히 '18T MDF'×33+'4.5T MDF'×11(발주량보유 91은 보존), 동기화 후 LEFTOVER_R_REAL=0(실 junk 자재행 전멸)·LOSS_COEXIST=0(idx시프트 재삽입 데이터유실 0, status/편집 보존)·남은 11은 빈탭 placeholder(is_empty). 합성 유닛테스트 PASS. ③ autosync 3중 버그 복구(핵심 부수): 로그상 7월 내내 파스는 되나 SSM 푸시 실패로 RDS 미반영이었음 — (a)스케줄러 시스템 python39가 PATH에 venv 없어aws미발견 FileNotFoundError (b)aws.cmd 배치래퍼가 python 오해석 ModuleNotFoundError(awscli) (c)PYTHONUTF8=1서 자식출력 cp949 UnicodeDecodeError.scripts/ssm_run.py를 venv python-m awscli직접호출 + UTF-8/errors=replace로 수정 → 스케줄러 실트리거 성공(ins0·upd1536·removed0 멱등) = 추후 자동동기화 보장. 주의: 이 변경들은 로컬 사이드카(웹앱 미사용) → deploy-live 웹배포 불필요, master만(=autosync working copy). NAS는 WireGuard+win32wnet 인증 필요(메모리 [[nas-smb-korean-share-mount]]). 잔여/⏳페페: 완전 template인 오엠씨 탭 11개가 빈탭 placeholder('업체만 등록', is_empty→입고일정 탭 자동필터·발주서정리엔 최소표시)로 남음 — 원하면 raw탭 placeholder 억제 후속(스코프 밖이라 보류). 페페 육안(/field/orderpaper 오엠씨 18T/4.5T MDF 규격·수량 없는 행 사라짐 확인). - ⚠️교훈(git 위생) —
git add -A금지, 파일 명시: 이번 시트 이력 작업 커밋(구72fc04e)에서git add -A가 작업트리에 쌓여있던 미추적 아티팩트 346개(.playwright-mcp/·console 로그·webedit001/ssm_*.json/txt·orderpaper-sync/_diag*·scripts/_*임시·한글 .md)를 의도한 7파일과 함께 커밋함. 복구: master는 정리 커밋(f39980d)으로 346개git rm --cached(디스크 보존), deploy-live는 나쁜 cherry-pick을reset --hard origin으로 폐기 후 7파일만git checkout master -- <files>로 재구성해 커밋(827d5b1). 운영엔 junk 미배포 확인(.playwright-mcp=no). pre-existing 추적분(webedit001/PFS Wireframe.html·db_migration/*·patch*.md등)은 세션 전부터 추적된 정상 파일이라 유지. 다음부터 pfs 커밋은git add -A쓰지 말고 변경 파일을 명시적으로 add(작업트리에 미추적 임시파일이 상시 다수 존재). 참고: Windows Python은/tmp경로 무효(→ cwd 상대경로),python - <<'PY'는 heredoc이 stdin을 먹어 파이프 입력 무시(→ 입력은 파일 경유). - ✅완료·운영배포 완료 — OMC 시트관리 삭제버튼 맨끝 분리 + 수량변경 이력 모달 (master
f39980d(정리 포함) → deploy-live827d5b1, 지시문 "운영배포 진행" 승인·RDS 승인). 페페 pfs검증보고 "/omc/sheet삭제버튼 컬럼 맨 마지막 이동(수정과 분리, 오클릭 방지), 기존 삭제 자리에 '이력' 버튼 — 항목별 수량 변경 이력 모달". ① 컬럼 재배치(sheet.html): colgroup 9→10열, 삭제 버튼을 관리 컬럼에서 떼어 맨 끝(10번째, 66px) 컬럼으로, 기존 자리(관리 컬럼)엔 수정+이력 버튼. thead '액션'→'관리'+맨끝 '삭제' th, 빈상태 colspan 9→10, tfoot 마지막 colspan 3→4. ② 이력 인프라(RDS 신설):omc_sheet_history(id·sheet_id·before_qty·after_qty·unit·memo·created_at, INDEX idx_sheet) 테이블 신설 — 마이그레이션scripts/codi_omc_sheet_history.py(멱등: CREATE IF NOT EXISTS + 이력 없는 항목만 기준행 백필, test·prod 두 env 순차 적용, test 170·prod 191행 기준 백필).sheet_service.update_sheet가 수정 전 수량 조회→변경 시 이력행 자동 INSERT(memo='수정'; 인라인·모달 수정 모두 이 단일 choke point 경유). 신규 add는 lastrowid 미반환이라 이력 생략(첫 수정부터 기록). ③ API/모달:GET /api/omc/sheet/<id>/history(controller SheetHistory, service get_sheet_history, dao select_sheet_history — DATE_FORMAT %% 이스케이프), 프론트openSheetHistory()+modalSheetHistory(일시·수량변화·증감(+녹/-적)·구분, 기준행은 '기준' 표시),.omc-modal-backdrop .hist-tableCSS(모달 omc-scope 밖이라 자체 스타일 — M/면 함정 교훈 반영). 캐시버스터 omc.css?v=20260713a→b(sheet·board 공유). 검증: 백엔드 ast PASS, 인라인 JS node --check PASS, 테스트 API 라운드트립 PASS(id170 기준행1→수량+7→이력2행 before100/after107/memo수정→원복), 마이그레이션 SSM(test170·prod191), 배포 SSM(운영 HEAD 827d5b1·삭제10번컬럼·이력버튼·hist-table·history라우트·캐시버스터 전부 반영, 운영 이력 GET 읽기전용 정상, junk 미배포, uwsgi 재시작). ⏳페페 육안(Ctrl+Shift+R,/omc/sheet삭제 맨끝·이력 버튼→모달). - ✅완료·운영배포 완료 — OMC 보드 품목추가 prompt()→페이지 자체 모달 (master
bb28df2→ deploy-live8397569, 지시문 "운영배포 진행" 승인). 페페 pfs검증보고 "/omc/board품목추가 브라우저 모달(prompt) 말고 페이지 자체 모달로 제작". 수정(board.html만):openAddBoardItem()의prompt()→modalAddItem(기존 omc-modal 패턴, 품목명 입력+Enter 저장) 신설,saveAddBoardItem()이 POST(기존 로직 보존). 부수 근본수정: sort_order 셀렉터.item-tab:not(.add)(구 탭 클래스, 사이드 개편 후 0매칭→항상 1)→#itemSideList .side-item. 인라인 템플릿이라 캐시버스터 불필요. ⏳페페 육안(Ctrl+Shift+R, 보드 품목추가 버튼→모달). - ✅완료·운영배포 완료 — OMC 시트 추가/수정 모달 M·면 단위 토글 활성 색상 복원 (master
c2598f4→ deploy-live7333cad, cherry-pick, 지시문 "운영배포 진행" 승인). 페페 pfs검증보고 "/omc/sheet시트추가 모달의 M/면 버튼 활성화 시 UI 색상 변화 주기". 근본원인: 모달(#modalAddSheet·#modalEditSheet)이 Phase 7에서.omc-scope밖으로 분리됐는데, 단위 토글 활성 규칙.omc-scope .unit-toggle .unit-btn.on{background:teal;color:#fff}(omc.css 146)이 omc-scope 스코프라 모달 내부 버튼엔 미적용 →on클래스가 붙어도 시각변화 0. (모달 stepper는 이미.omc-modal-backdrop .stepper…로 복제돼 있었는데 unit-toggle만 누락.) 수정(omc.css만):.omc-modal-backdrop용.unit-toggle/.unit-btn/+.unit-btn/:hover/.on5규칙 복제(omc-scope 원본 미러, 활성 teal). add·edit 모달 공통 커버(둘 다.omc-modal-backdrop). JS(setUnitToggle)·마크업 무변경. 캐시버스터omc.css ?v=20260707k→20260713a(sheet·board 공유라 둘 다 bump, board_confirm은 버전param 없어 미변경). 검증: SSM으로 운영/테스트 omc.css grep — 양쪽.omc-modal-backdrop .unit-toggle .unit-btn.on규칙=1, sheet.html 캐시버스터 v20260713a, HEAD 일치(prod 7333cad·test c2598f4), uwsgi 양쪽 running·재시작(prod ActiveEnter 00:21:54 UTC·test 00:21:27 UTC). ⏳페페 육안(Ctrl+Shift+R, 시트 품목추가/수정 모달에서 M↔면 클릭 시 teal 강조 전환). - ✅완료·운영배포 완료 — OMC 시트관리 힌트 텍스트→시트추가 버튼 교체 (master
378696e→ deploy-live18605c2, cherry-pick, 지시문 "운영배포 진행" 승인). 페페 pfs검증보고 "/omc/sheet필터바 우측 안내 텍스트('💡 현재 수량 셀을 클릭하면 인라인으로 수정 가능') 삭제하고 그 자리에 시트추가 버튼 생성, 기존에 있던 기능 사라짐". 수정 1곳(프론트만):web/templates/omc/sheet.htmlfilter-bar 우측<span>(margin-left:auto 힌트) →<button class="btn btn-primary" onclick="openAddSheet()">+ 시트추가</button>로 교체. openAddSheet()·modalAddSheet 기존 함수/모달 그대로 재사용(백엔드·DAO·모달 무변경). topbar의 기존+ 품목 추가버튼(line 33)은 유지(제거 안 함) — 페페가 지정한 힌트 위치에 추가 진입점만 신설. 인라인 템플릿 변경이라 캐시버스터 불필요(Flask 서버렌더). 검증: SSM으로 운영/테스트 EC2 sheet.html grep — 양쪽+ 시트추가버튼 1개·힌트텍스트 0개, HEAD 일치(prod 18605c2·test 378696e), uwsgi 양쪽 running·재시작 반영(prod ActiveEnter 00:14:30 UTC·test 00:13:37 UTC, die-on-term 해결 후 hang 없음). 배포: master가 deploy-live보다 36커밋 앞서 merge 대신 내 커밋만 cherry-pick(충돌 0, 3d772cc 내용은 이미 12cb07b로 운영 반영됨). ⏳페페 육안(Ctrl+Shift+R,/omc/sheet필터바 우측 시트추가 버튼 클릭→품목추가 모달). - ✅완료·운영배포 완료 — 입고일정 탭 현장 그룹 헤더에 현장 숨김 버튼 추가(전 탭 연동) (master
8bb97f4→ deploy-livecca6257, cherry-pick, 지시문 "운영배포 진행" 승인). 페페 "현장별 입고일정 탭에도 현장 숨김 버튼 추가, 다른 탭들과 연동". 구현(재사용 최소 diff):orderpaper_schedule.js에hideBtn(site)헬퍼(현장별S.mode==='site'+ 현장명≠'(현장미상)'에서만 버튼 렌더, 그룹키=site_name_raw) +opSch.hide(site)핸들러가 발주서 정리 탭의window.hideSite()를 그대로 재사용(PATCHorderpaper/site-hidehidden:'1'→loadAll()이 OP_ALL 재적재 +orderpaper.htmlline 564opSch.refresh()로 발주서정리·현장별자재·입고일정 전 탭 동시 갱신 = 연동 자동). 버튼은 표뷰 그룹헤더(rTable, gcount 뒤)·타임라인뷰 그룹헤더(rGantt,.metarkBadge 뒤) 양쪽. CSS.ops-hide-btn(그룹 #cdd7e3 배경 대비 흰버튼, hover 빨강). 캐시버스터 js·css?v=20260713bbump(2곳). 검증:node --checkPASS + hideBtn 분기 self-check 5케이스 PASS(site모드→버튼 / 현장미상·빈값·co·vendor모드→빈문자) + 운영 정적 JS(function hideBtn·hide:function)·CSS(ops-hide-btn×3) 반영, 서버 HEADcca6257, 템플릿 js/cssv20260713b서빙, uwsgi 재시작01:07:02 UTC(커밋 직후) running 확인. ⏳페페 육안(Ctrl+Shift+R,/field/orderpaper입고일정 탭 현장 헤더 숨김 버튼 클릭→전 탭 반영). - ✅완료·운영배포 완료 — 입고일정 탭에서 발주서정리 숨김 현장 동일 제외 (master
4d04c1f→ deploy-live86bdc69, cherry-pick, 지시문 "운영 배포" 승인). 페페 "현장별 입고일정 탭에 표기된 현장을, 발주서 정리 탭에서 숨김 반영된 현장은 동일하게 숨기기". 근본원인:/api/orderpaper/all-items(select_all_itemsdao)가 자재관리 탭 예외용으로 숨김 현장(is_hidden)도 컬럼 실어 전송(dao line 77COALESCE(m.is_hidden,'0') AS is_hidden). 발주서정리·현장별자재 탭은 프론트opPass에서is_hidden='1'제외하는데, 입고일정 탭(orderpaper_schedule.js)만 OP_ALL을rebuild()집계 루프에서 필터 없이 읽어 숨김 현장이 그대로 표시됨. 수정 1줄(근본):orderpaper_schedule.jsrebuild()items.forEach 최상단에if(String(it.is_hidden)==='1') return;추가(발주서정리 탭 template line 522와 동일 가드) → 리스크 표·타임라인·KPI 전부 자동 반영. 캐시버스터field_orderpaper.html?v=20260624a→20260713abump. 검증:node --checkPASS, 운영 정적JS에 가드 line 64 반영 확인, 서버 HEAD86bdc69일치, 템플릿?v=20260713a서빙, uwsgi ActiveEnterTimestamp2026-07-12 23:50:12 UTC(커밋 23:49:31 직후 재시작·running) 확인 — Actions가 재시작까지 완료. 배포: master가 deploy-live보다 34커밋 앞서 merge 대신 내 커밋만 cherry-pick(충돌 0). ⏳페페 육안(Ctrl+Shift+R,/field/orderpaper입고일정 탭에서 숨김 현장 미표시 확인). - ✅완료·운영배포 완료 — 사이드 메뉴 모바일·데스크톱사이트 미표시 수정 (master
28656b4→ deploy-live3868c85, cherry-pick, 지시문 "운영 배포진행" 승인). 페페 "pfs 사이드메뉴가 모바일·데스크톱사이트 둘 다 안 보임". 근본원인 2개: ①2026-06-19 레이아웃 개편에서 상단바(topbar) 제거 시, 원래 모바일에서 사이드바를 여는 테마의.nav-toggler(햄버거) 버튼이 topbar 안에 있어 같이 사라짐 → 모바일에서 off-screen 사이드바를 열 방법 없음. ②pfs_layout.css의 off-screen 규칙.mini-sidebar .left-sidebar{left:-210px !important}이 미디어쿼리 밖에 있어,custom.js가width<1170에서 붙이는mini-sidebar동안 데스크톱사이트(768~1169px)까지 사이드바가 화면 밖으로 밀림(원래 이 대역은 아이콘 레일이어야 함).!important라 태블릿/데스크톱사이트에서 완전 실종. 수정 4곳: (a)base.html#main-wrapper안에 햄버거<a class="nav-toggler pfs-mobile-toggle">복원 — 기존 custom.js.nav-toggler클릭 핸들러(show-sidebar토글) 그대로 재사용, 추가 JS 0. (b)pfs_layout.css§8 off-screen을@media(max-width:767px)로 한정 +.mini-sidebar.show-sidebar .left-sidebar{left:0 !important}재선언(테마 열기규칙에!important없어 내-210 !important에 덮이던 문제) + page-wrappermargin-left:210미디어min-width:1024→768(태블릿도 사이드바 자리 확보). (c)pfs_layout.css§9 신설:.pfs-mobile-toggle기본display:none,@media(max-width:767px)에서만 좌상단 fixed 버튼(z-index 30>사이드바 20), 열리면left:218px로 이동해 재클릭 닫기, 모바일.container-fluidpadding-top:56px로 버튼 아래 공간. (d)custom.jsmini-sidebar 자동전환 임계1170→768(≥768은 항상 풀 사이드바 노출) +base.html에서 custom.js?v=asset_ver캐시버스트(기존엔 없어 구 임계 캐시 위험). 검증: 헤드리스 Playwright(chrome 채널) 3해상도 — 375px: mini=true·사이드바 off(x=-210)·햄버거 표시→클릭→슬라이드인(x=0); 980px(데스크톱사이트): mini=false·사이드바 노출(x=0)·햄버거 숨김; 1280px: 동일 노출. 전부 PASS. 운영 정적자산 HTTP 200 반영 확인:pfs_layout.css(pfs-mobile-toggle4회·open-rule 존재),custom.js(width < 768). 배포: master가 deploy-live보다 34커밋 앞서(미완성 진행분 다수) merge 대신 내 커밋만 cherry-pick. 세 파일을 건드린 다른 master-only 커밋 없어 충돌 0. ⏳페페 육안(폰 Ctrl+Shift+R, 데스크톱사이트 전환 시 사이드 메뉴·햄버거). - ✅완료 — 배포 후 "uwsgi 재시작 누락" 근본원인 해결(오진 정정):
die-on-term+KillSignal=SIGQUIT충돌 (서버 systemd 유닛 수정, git 밖). 이전 진단(Actions가 재시작을 빠뜨림)은 틀렸다. 실제=deploy-production.sh는 매번systemctl restart를 실행했고, 그 restart가 90초 동안 hang했다. 원인=uWSGIdie-on-term = true는 SIGTERM/SIGQUIT 의미를 맞바꾼다(기본 TERM=브루탈리로드/QUIT=종료 → 켜면 TERM=종료/QUIT=브루탈 바이너리 리로드). 그런데 유닛이KillSignal=SIGQUIT이라 stop 신호가 리로드로 해석돼 프로세스가 안 죽고, systemd가TimeoutStopSec=90을 다 기다린 뒤 SIGKILL → 그 90초 동안 구 프로세스가 계속 서빙 → 배포 직후 확인하면ActiveEnterTimestamp가 옛날 그대로라 "재시작 안 됨"으로 보임. 증거: 저널...brutally killing workers...→binary reloading uWSGI...→ 정확히 90초 뒤Failed with result 'timeout'→Stopped→Started(04:04:57 restart → 04:06:27 완료, 04:17:14 → 04:18:44 동일 패턴). 내가 "수동 재시작"이라 부른 것들은 사실 그 타임아웃 완료 시점과 겹친 것. 수정:/etc/systemd/system/pfs-{live,test}.uwsgi.service에서KillSignal=SIGQUIT제거(기본 SIGTERM=종료),daemon-reload. 백업*.bak_20260710. 검증: test restart 90.2s→1.0s, live restart→1.0s, 둘 다Result=success·timeout/binary-reload 로그 0건·200. Actions 동일 경로 E2E:deploy-production.sh6.1s(exit 0),deploy-test.sh8.1s. ⚠유닛은 git 밖 서버 파일 → EC2 재구축 시 재적용 필요(ini는 리포service/uwsgi/*.ini, 운영은 서버/etc/uwsgi/pfs-live.ini사용). 메모리 [[uwsgi-die-on-term-killsignal-conflict]]. 참고:crontab -l에@reboot으로 uwsgi를 systemd 밖에서 또 띄우는 줄이 남아 있음(중복 인스턴스 소지 — 미조치). - ✅완료·운영배포 완료 — 휴가 타임라인 v2: 평균 센터 창 + 표 업체 컬럼 축소 (master
87e42d9→ deploy-liveb9320dc운영배포 완료, 지시문 "운영 배포 진행" 승인). 페페 "테이블 업체 컬럼 폭 줄여 공간확보. 타임라인을 휴가기간 평균 센터가 가운데 오게, 전후 3일씩 칸 확보. 초기 로드에 휴가일자 전부 보이게." 창 산출(핵심): 창 길이가 14일 고정 → 데이터 기반 가변.center = round(mean((start+end)/2))(가장 빠른 시작일 기준 일 오프셋),half = max(center, maxEnd - center) + 3,days = 2*half + 1,start = base + center - half. 대칭(평균센터가 정확히 가운데) + 모든 휴가가 창 안 두 요구를 동시 만족(min~max 패딩만으론 센터가 중앙이 안 됨). 휴가 0건이면 기존대로 이번 주 월요일부터 14일. 칸 수 가변 → grid 열 정의를 인라인repeat(N, minmax(20px,1fr)), 기간이 길어 칸이 20px 미만이 되면.vac-tl-body가로 스크롤(업체명 열position:sticky). nav 가운데 버튼오늘→전체보기(기본 창 복귀), 이전주/다음주는 ±7일. 불량 데이터 가드:end_date < start_date행은tlSorted에서 제외(창 계산·막대 폭 붕괴 방지). 표 축소: 업체 180px(.vac-col-co신설)·날짜 145px·관리 70px·셀 padding 12→8px,.vac-wrapflex:1 1 500px; max-width:620px(basis를 낮춰야 wrap 안 됨 — 620 basis면 1100px 뷰포트에서 타임라인이 아래로 떨어짐. flex 줄바꿈은 축소 전 basis 합으로 판정). 검증: ①노드 하니스 18항목 PASS(창 시작·길이·중앙칸=평균센터, 전 휴가 창 내 포함, 앞뒤 여유≥3일, 막대 offset 2케이스, 초기창 cut 없음, 헤더 칸수=창길이, 인라인 grid, 단일휴가 창, 0건 14일·월요일, nav ±7일·전체보기 복귀, 불량행 제외, XSS) ②로컬 스텁 렌더: 6개 휴가 → 창 7/26~8/17(23일)·모든 막대 창 내부·cut 없음, 컨테이너 1000~1680px 전 구간 좌우 배치 유지(1000·1100은 타임라인 내부만 스크롤·업체명 sticky), 페이지 가로 스크롤 없음 ③SSM: test87e42d9·prodb9320dc,tlWindow·vac-col-co마커 양쪽 존재, 8000/8001=200. ~~uwsgi 재시작 수동~~ → 정정: Actions는 재시작을 실행했고 90초 hang이었다(원인=die-on-term↔KillSignal 충돌, 위 항목에서 해결). ⏳페페 육안(운영 Ctrl+Shift+R,/vacation). - ✅완료·운영배포 완료 — 업체 휴가일정 우측 2주 타임라인 (master
ce29eb0·f8de989→ deploy-live9c1efc9·1abdadd운영배포 완료, 지시문 "운영배포 진행" 승인). 페페 "우측 남는공간에 타임라인 생성해 업체별 휴가기간 표시. 캘린더 2주, 업체명 가나다순이되 휴가기간 비슷한 업체 위주·빠른 휴가 우선." 백엔드 변경 0 — 프론트 단일 파일web/templates/default/vacation.html만 수정(이미 로드된VAC_ROWS+VAC_COMPANIES재사용, API·DAO·테이블 무변경). 레이아웃=.vac-layoutflex 2단(좌 표flex:1 1 520px; max-width:820px/ 우 타임라인flex:1 1 440px; min-width:0) — 둘 다 축소 허용이라 사이드바 있는 1400px 뷰포트에서도 좌우 유지, 더 좁으면 wrap으로 아래 배치. 타임라인=14일 창(월요일 정렬, 창 시작=이번 주 월요일+주오프셋), CSS gridrepeat(14,1fr)셀 +position:absolute막대(left/width=일수/14), 주말·오늘 셀 하이라이트,◀ 이전주 / 오늘 / 다음주 ▶(7일 이동). 창 밖 휴가는 행 미표시, 걸치면 클램프+cut-l/cut-r(모서리 각짐). 막대색=hsl(company_no*47 %% 360), 3일 미만 막대는 글자 잘려 라벨 생략(기간은title툴팁). 정렬(요청 해석)=start_dateASC →end_dateASC → 업체명localeCompare(...,'ko'). 시작일 우선이라 빠른 휴가가 위, 같은 기간이 자동으로 인접(=비슷한 업체 묶임), 그 안에서 가나다순. 표(server orderstart_date DESC)는 지시 범위 밖이라 무변경. 저장 성공 시 표는 재렌더 안 하고(포커스 유지)VAC_ROWS메모리 행만 갱신 후renderTimeline(). 검증: ①노드 하니스 11항목 PASS(정렬 순서·빈 행 제외·막대 offset 3케이스·cut-l/cut-r·창 겹침 필터·헤더 14칸/월요일 시작·업체명 XSS 이스케이프) ②템플릿을 스텁 데이터로 로컬 렌더(브라우저)해 좌우 배치·오늘 하이라이트·nav 3버튼(이전주/오늘/다음주 창 이동) 확인 + 스크린샷 육안 ③SSM: test HEADf8de989·prod HEAD1abdadd양쪽vac-tl마커 39개, 운영 8000=200. ⚠배포 함정 재현: 이번에도 Actions가 uwsgi 재시작을 빠뜨림(ActiveEnter 03:18 UTC < 배포) → SSMsystemctl restart pfs-live.uwsgi.service로 마무리(재시작 후 04:06 UTC·active·200). 배포 후 HEAD + ActiveEnterTimestamp 둘 다 확인 규칙 유효. ⚠로그인 자격증명 미사용: 운영/테스트 UI 로그인은 텔레그램 승인 필수 위험항목([[login-credential-autofill-risk]])이라 브라우저 검증은 로그인 없이 로컬 스텁 렌더로 대체. ⏳페페 육안(운영 Ctrl+Shift+R,/vacation): 우측 타임라인·막대 위치·주 이동. - ✅완료·운영배포 완료 — 배차 QA 2건: 현장 선택 시 가구업체 자동매핑 + 금액칸 IME 중복입력 수정 (master
a6f2ba7·f4aa672→ deploy-live7d37f79운영배포 완료, 지시문 "운영배포 진행" 승인). ①가구업체 자동매핑: 배차 등록/수정 모달에서 현장검색 팝업으로 현장 선택 시 업체명·업체번호 자동 채움. 백엔드 변경 0 —POST /api/field/search(field_daoselect_field_search_list)가 이미a.*(=company_no)+b.name AS company_name을 반환하고 마샬링이 없어 그대로 내려옴.renderFieldModalRowsonclick에 인자 2개 추가 →selectField(name,no,addr,companyName,companyNo)가dcCompanyInput/dcCompanyNo채움. 현장에 업체 없으면(company_no falsy) 기존 입력 유지(덮어쓰기 금지). DB 실측: 기본 검색범위(한달전~한달후) 현장 전부 업체 연결(test 3/3·prod 38/38). ②금액칸 중복입력(페페 "숫자 입력시 한글 관련 에러인지 중복 입력됨"): 원인=한글 IME 조합 중 발생한 input 이벤트에서el.value를 재대입해 조합문자가 중복 커밋됨. 공용formatFee한 곳만 수정(=근본원인 위치, 운임비·물품금액·택배비 3칸 동시 해결):if(e && e.isComposing) return;+ 값 같으면 재대입 안 함, 인라인 핸들러oninput="formatFee(this,event)" oncompositionend="formatFee(this)" inputmode="numeric". 검증: 노드 하니스로 실제 API 행→onclick 문자열→selectField실행 전 경로 PASS(자동매핑·업체없는현장 미덮어씀·따옴표 이스케이프), 브라우저 실 InputEvent(isComposingtrue/false)+CompositionEvent 4항목 PASS(조합중 무변경→compositionend에 한글제거·재포맷·중복대입 0), test/운영 템플릿 마커 SSM PASS, 운영 8000=200. ⚠배포 함정(2026-07-10 정정: Actions는 재시작을 했고 90초 hang이었다 — die-on-term↔KillSignal 충돌, 해결됨): 당시 관찰=git reset(HEAD 7d37f79) 후 재시작이 반영 안 된 것처럼 보임(ActiveEnterTimestamp전날 그대로) → Jinja 템플릿 캐시로 구버전 서빙 위험. SSMsudo systemctl restart pfs-live.uwsgi.service로 마무리(멱등). 배포 후 HEAD뿐 아니라systemctl show pfs-live.uwsgi.service -p ActiveEnterTimestamp도 확인할 것. ⏳페페 육안(운영 Ctrl+Shift+R): 현장검색→업체 자동입력, 운임비 숫자 연속입력 시 중복 없음. - ✅완료·운영배포 완료 — 배차관리에 택배발송 관리 추가 (+ QA 6건) (master 최신
d6ad526→deploy-live1e09171운영배포 완료, 지시문 "운영배포 진행" 승인): QA4(44123a1) 택배 의뢰서 순서 재변경=발신자 정보 최상단→수신자→나머지(직전 QA3의 수신자먼저 뒤집음). QA5(1e09171) 전 모달 × 버튼 헤더색(#455a64) 동일·호버 색변경 제거(dc-modal-close 6개 + 부트스트랩 현장검색 모달.field-modal .close통일). ⚠배포 주의: 이 시점 GitHub Actions 자동배포(deploy-live push→SSM)가 44123a1부터 7분+ 미반영(Actions 큐/장애 정황) → SSM으로deploy-production.sh직접 실행해 배포 완료(sudo bash /home/ubuntu/pfs/scripts/deploy-production.sh=git fetch+reset --hard origin/deploy-live+systemctl restart pfs-live.uwsgi.service, 멱등이라 Actions 뒤늦게 돌아도 무해). 운영 HEAD 1e09171·8000 200·배포 파일 순서/CSS 마커 SSM 검증 PASS. ⏳페페 육안(운영 Ctrl+Shift+R). 이하 QA1~3·키보드네비 상세: QA2(2180fd1): 수신자·발신 검색 드롭다운 키보드 네비게이션 — 방향키↑↓ 이동+엔터 선택, 결과 1개면 엔터 즉시 선택, ESC 닫기, IME 조합(keyCode229) 무시. 공통 헬퍼attachDdKeyNav(input,dd,pickFn). 브라우저 하니스 검증(3결과 방향키선택·1결과 엔터·ESC·발신 병행) PASS·운영 마커 SSM PASS. 페페 "배차관리에 택배발송 건도 같이 관리, 택배용 모달 별도, 발신/수신자로 주소·연락처 자동기입, 발신 기본 포인". 설계=배차 페이지·목록·dispatch테이블 재사용, 유형만 다른 행(목록 섞기·수신자=과거택배기록+담당자(company 주소연계)·발신=업체+발신자 검색(포인 기본)·택배 의뢰서 A4). DB:dispatch에 컬럼5 INSTANT(ship_typeD/C·item_name·packaging·item_price·sender_tel) — test(1464행)·prod(1629행) 양쪽 적용(마이그레이션scripts/codi_courier_alter.py로컬직결 test용,codi_courier_alter_prod.pySSM 운영용, 둘 다 멱등). 백엔드: dispatch_dao insert/update/copy 5필드+검색ship_type필터, company_member 조회에 소속업체address1·tel조인. 프론트(dispatch_list.html):+ 택배 등록버튼+전용 모달, 목록 유형칩·필터, 택배 상세패널, 택배 의뢰서 A4. 매핑: 발신→departure/departure_addr/sender_tel, 수신자→constructor+destination/constructor_tel, 수신주소→destination_addr, 물품/포장/물품금액→신규컬럼, 택배비→freight_cost. ⭐company_no = 수신자 소속 업체(발신 아님) → 목록/상세/의뢰서에 수신자 옆 업체명 표기. QA 3건(bce5627): ①수신자/발신 검색창 브라우저 자동완성 차단(autocomplete=new-password— Chrome은 연락처/주소서 off 무시) ②수신자 검색에 업체명 포함(이름·업체명 동시검색)+표기에 수신자 다음 업체명 ③택배 의뢰서 발신/수신 상단블록 제거→테이블 통합(수신자정보 먼저→발신자정보 순). 기본발신 포인 자동채움(업체목록 '포인' 주소/연락처, 폴백 계수동 137-6·010-9426-0731). 검증: test·prod 마이그레이션(행 보존)·백엔드 SQL round-trip(예시데이터 롤백)·Jinja/JS node --check·element ID 정합·브라우저 하니스 전항목 PASS(모달·자동완성·업체명검색/표기·company_no=수신자업체·저장페이로드·의뢰서 순서·목록셀)·운영 서버 배포 마커 SSM 검증 PASS. ⏳페페 육안=운영 배차관리 열어 택배 등록/목록/의뢰서(Ctrl+Shift+R). - ✅완료·운영배포 완료 — poin 샘플 템플릿 조회 API 신설(acad-tread 그룹 입력용)(master
72a2471→deploy-liveb8b459c, 운영 검증 PASS): acad-tread 플러그인 "그룹 입력" 기능이 기존 POIN MS SQL Server의poin_sample_group(큰제목)·poin_sample_item(품목)를 불러오도록 pfs에 조회 API 신설. 신규api/pfs/poin_sample/controller/poin_sample_controller.py—GET /api/poin/sample-groups(remove_yn=0·이름순)·GET /api/poin/sample-groups/<no>/items(display_order순),SqlServerUtil로 기존 MSSQL 직접 조회(MySQL 미러 없음), 읽기전용·무인증(colors API와 동일 패턴). config.py 네임스페이스 등록(poin_color와 같은/api/poin). 운영배포(페페 "운영배포 진행" 승인): deploy-live가 master와 23커밋 분기 상태라 merge 대신 내 커밋만 cherry-pick(fbbb868→b8b459c, 4파일 39줄). 운영pfs.poin.co.kr/api/poin/sample-groups=116그룹·items 검증 PASS. 상세=acad-tread handoff. - ✅완료·운영배포 완료 — 자재관리 정렬 모달: 현재 정렬을 이 브라우저 기본으로 저장(PC별·서버 미적용)(master
4de9bd1→deploy-livefbbb868·v20260709c, 프로덕션 서빙 검증): 페페 "정렬기준 모달에서 사용자 설정 정렬을 기본 정렬로 변경, 서버 전체 아님·PC별만". 구현(orderpaper_material_mgmt.js):DEFSORT_KEY='pfs.op.mm.defsort.v1'localStorage 도입,userDefaultSort()=저장된 사용자 기본(있으면)|시스템DEFAULT_SORT폴백. 모달 푸터에 ‘★ 현재 정렬을 기본으로’ 버튼(setSortDefault) — 현재S.sort저장. 초기화(resetAll)·‘기본 정렬로’(sortReset)·‘기본’ 라벨(isDefaultSort) 모두userDefaultSort()기준으로 전환(종전 하드코드 DEFAULT_SORT 직참조 제거). 버튼은 현재 정렬이 이미 사용자 기본이면 ‘☆ 기본 해제(시스템값)’로 바뀌어 removeItem으로 시스템 기본 복원(reversible). 초기 S.sort도 userDefaultSort()로. 헬퍼 로직 node 셀프체크 PASS·node --check PASS. ⏳페페 육안=정렬 바꾸고 ★저장→새로고침/초기화 시 그 정렬 유지. - ✅완료·운영배포 완료 — 자재관리 검색창 내부 X(검색어 지우기) 버튼(master
da53a5e→deploy-lived86ce3f·v20260709b, 프로덕션 서빙 검증): 페페 "인라인 검색창 내부에 텍스트 삭제 X 추가".input을.mm-search-wrap(position:relative)로 감싸고 우측에×버튼(.mm-search-clear,.has-q일 때만 표시).onSearch·syncToolbar에서toggleSearchClear()로 입력값 유무 토글,clearSearch()=검색어 비우고 디바운스 없이 즉시 render+포커스 유지. 네이티브type=searchX는 Chrome서 포커스 시에만 떠서 커스텀으로. ⏳페페 육안=검색어 입력 시 X 표시·클릭 시 즉시 초기화. - ✅완료·운영배포 완료 — 자재관리 탭 자재분류 셀 1클릭 편집(master
6d0c7f5→deploy-liveaef9144, 프로덕션 서빙 검증 PASS): 페페 QA "자재분류 변경에 클릭 2번, 프레임 중복". 근본=mtStart가 select를focus()만 해 드롭다운이 안 열림 → 첫 클릭은 닫힌(테두리 있는) select 박스만 보이고(=박스인박스 '프레임 중복'), 두번째 클릭에야 열림. 텍스트 셀은 input이라 focus만으로 바로 타이핑돼 이 문제 없음. 수정=sel.showPicker()로 첫 클릭에 드롭다운 즉시 오픈(미지원 브라우저는 try/catch로 focus 폴백) + CSSselect.mm-c-mt에width:100%;box-sizing:border-box로 셀 채워 내부 박스 티 제거. 파일=orderpaper_material_mgmt.js·.css·field_orderpaper.html, 캐시버스터 v20260707h→v20260709a. node --check PASS, 프로덕션 static에 showPicker·width:100% 서빙 확인. ⏳페페 육안=자재분류 셀 1클릭 오픈. - ✅완료·운영배포 완료(DB) — 재고량(stock) 단위 제거, 숫자값만(DB 마이그레이션 test 232행·prod 154행, 시드 master
44fd77d): 페페 "재고량 컬럼 값 단위 분리 안 됨, 단위 생략 숫자만. 전체 DB수정+운영배포". 원인=stock 초기 시드가 발주량(qty)을 통째 복사('40m'·'1세트'·'좌1,우2' 등 단위·잡값 혼입, prod 154/1550행). 수정 3갈래: ①DB 마이그레이션=num_only()(정규식\d+(?:\.\d+)?첫 숫자)로 test·prod stock 단위 제거(숫자없는 잡값 '팩스번호'·'결재' 등 5행은 빈값), 트랜잭션·검증 후 apply, 잔여 단위행 0 확인. ②시드 경로 2곳(orderpaper_sync.pyINSERT·orderpaper_upload_load.pyINSERT, 둘 다 원격템플릿 내 num_only) — 앞으로 새 동기화/업로드 항목도 stock 숫자만 복사(재유입 방지). ③프론트 무변경(DB 정리로 표시 자동 숫자화, stock 셀은 it.stock 그대로 렌더). 주의: 'stock 시드=qty' 였던 종전 동작이 'stock=qty 숫자부'로 바뀜(sync UPDATE는 여전히 stock 미갱신=사용자 재고 보존). 시드 스크립트는 로컬 실행(EC2 미실행)이라 deploy-live 불필요. ⏳페페 육안=재고량 컬럼 숫자만 표시(새로고침 후). - ✅완료 — orderpaper 자동동기화 6일 전면중단 복구 (근본원인=conhost가 PYTHONUTF8 인용 파괴): 페페 "발주서 정리탭 동기화가 예전 파일을 잘 못읽는다, 6월 폴더 파일에 7월 내용 추가하는 경우(예: 06월/에넥스 대전 개인건 원부자재발주서.xlsx)". 실측 결론=파서·DB·표시는 정상(파서가 6월파일 내 7월 섹션 정상 분해, DAO는 folder-월이 아니라 각 행 order_date로 정렬·표시). 진짜 근본원인=
orderpaper_autosync_hidden.vbs가 2026-07-03 20:38에conhost.exe --headless프리픽스 추가(콘솔창 숨김 목적)되면서cmd /c set "PYTHONUTF8=1"의 인용을 conhost가 망가뜨려(값에 따옴표 유입) python3.9가 "invalid PYTHONUTF8" 치명오류로 매 30분 즉사 → 6일간(07-03~07-09) 자동동기화 0건. 그동안 웹 수동 '동기화'만 반영되어 페페가 "예전 파일을 못 읽는다"로 체감(=편집이 자동 반영 안 됨). 수정=VBS에서sh.Environment("PROCESS")("PYTHONUTF8")="1"로 프로세스 환경변수 지정 + cmdset ...&&제거(conhost·숨김창 유지). 재현·수정 양쪽 검증(python이 PYTHONUTF8='1'·utf8_mode=1 수신). 운영 재동기화 실행(round R1783554725, files28·items1408·upd1408·removed0)→에넥스 대전 개인건 7월항목(오엠씨/미림/진영LDM/상원보드, 07-03~07-09) 운영DB 정상 존재·6월항목 status(완료) 보존·신규 7월 대기. 스케줄드태스크orderpaper_autosync(Ready) 수동 트리거로 실제 경로 클린 재검증(Status Success). 교훈=conhost --headless는 뒤따르는cmd set "VAR=VAL"인용을 깬다 → 환경변수는 런처(VBS)에서 직접 세팅. - ✅완료·운영배포 완료·⏳페페 육안 대기 — 엣지 선택 목록 표기 변경 + 테이블 칩 통일(후속 QA) (master
399c8e2·c621519→deploy-live4813f38·7165bbc, 운영 서빙 PASS): 후속 QA "모달만 반영, 테이블 결과값 미반영" →chipInner엣지 분기도 edgeTitle(엣지명+치수)+⇄ 연동칼라명줄로 통일(3줄 유지: 제목/연동/업체, 캐시버스터?v=20260708h). 페페 QA "엣지 이름은 지정된 엣지명으로, 칼라 연동은 풀네임 아래 별도 표시(라이브러리 엣지카드 참조)." 기존엔 셀 선택 모달 엣지 항목 제목이edgeLabel(연동 칼라명+치수)이라 엣지명이 안 보였음. 변경:edgeTitle()신설(지정 엣지명+치수, 없으면 '(엣지명 없음)') — ①셀 선택 모달(mat-sel-item)을 2줄 구조로: 제목=edgeTitle, 아랫줄⇄ 칼라 연동: <칼라명>(주황,.mat-sel-maincolumn) ②일괄편집 풀도 edgeTitle+연동칼라 표기 통일.edgeLabel(칩·검색 등)은 불변. 캐시버스터?v=20260708g. 검증=node --check+운영 마커(edgeTitle·칼라 연동 줄·mat-sel-main css) PASS. ⚠교훈:git cherry-pick -q옵션 없음(usage 에러 129) — cherry-pick은 플래그 없이. ⏳페페 육안=엣지 셀 클릭→선택 목록 표기. - ✅완료·운영배포 완료·⏳페페 육안 대기 — 사양서 위치 행 드래그 정렬 (master
02152fb→deploy-live1b22753, 운영 서빙 마커 PASS): 페페 "테이블 행위치 마우스 드래그로 이동." 형태 셀 앞 ⠿ 핸들만 draggable(HTML5 DnD — 셀 클릭·체크박스와 충돌 없음), dragover 시 대상 행 위/아래 절반 판정으로 노랑 드롭 인디케이터(drop-above/below), drop 시 locations 배열 splice 재배치+commit(저장·재렌더). 인쇄 CSS에 핸들 숨김. 캐시버스터 css/js?v=20260708f. ⏳페페 육안=행 드래그 순서변경·저장 후 유지. - ✅완료·운영배포 완료·⏳페페 육안 대기 — 사양서 위치 행 다중선택 → 다른 타입·그룹 복사 (master
b82586a→deploy-live4a6f436, 운영 서빙 마커 전부 PASS): 페페 "견적서 복사 프로세스 참고, 행 다중선택 후 다른 타입 위치로 복사"(계획 선승인 — AskUserQuestion 4답: 타입+그룹 모두 선택 / 현재 타입 포함 / 체크박스 컬럼 / 복사 후 대상 타입으로 전환). 구현: ①스펙 테이블 맨앞 체크박스 컬럼(rowHTML.loc-chk+ thead 전체선택#opMatLocChkAll, 빈테이블 colspan 2→3) ②체크 시 위치추가 바 옆 액션바(#opMatLocSelBar선택 N건·⧉ 복사·선택해제, 재렌더 시 sync) ③모달opMatLocCopyModal(대상 타입 select=전 타입·현재 선택됨 + 그룹 주방/일반) ④적용=선택 행 딥카피(새 id·셀/도면 유지)→대상 locations 끝 append→대상 타입·그룹으로 화면 전환+commit+토스트. 셀 참조는 문서 공유 풀이라 재매핑 불필요. 인쇄 CSS에 체크박스 컬럼 숨김 추가. 캐시버스터 css/js?v=20260708e통일. 검증=node --check+운영 마커(loc-copy-to-apply·loc-chk·ChkAll·sel-clear·css) PASS. ⏳페페 육안=체크→복사→대상 전환·셀 유지. 알려진 한계: 셀 편집 등 재렌더 시 체크 초기화(선택 후 바로 복사 흐름 기준). - ✅완료·운영배포 완료 — 뒤판CORE 기존 현장 미적용 버그 수정 (master
7dcb77c→deploy-live9efb7ad, 운영 서빙 검증 PASS): 페페 "기존 현장에 적용 안 됨." 근본원인=normalize가 첫머리(194행)에서d.schemaVersion=SCHEMA_VERSION스탬프를 먼저 찍는데d와data가 같은 객체라, 그 뒤의 v3 마이그레이션 게이트data.schemaVersion < 3이 항상 false → 기존(v2) 문서 마이그레이션 전면 스킵(신규만 DEFAULT_PARTS로 컬럼 획득). 수정=버전 게이트 폐기, 무조건 기본 보장으로 전환(뒤판CORE 컬럼 없으면 CORE 오른쪽 삽입 +ensureCore(3,'MDF')상시 — body.core 셀 상시보장과 동일 패턴). SCHEMA_VERSION=2 원복(승급 불필요, 구 JSON import confirm도 원상). 의미 변화: 뒤판CORE 컬럼·3T MDF 코어는 지워도 재로드 시 복원되는 '기본'이 됨(그 사이 v3로 저장된 문서도 자동 커버). 캐시버스터?v=20260708d. ⏳페페 육안=기존 현장 열어 뒤판CORE 컬럼·코어목록 3T MDF 확인. - ✅완료·운영배포 완료·⏳페페 육안 대기 — 현장별 자재 편집기 4건(QA 연속 지시) (master
1e56bc4→3775458→6166936/ deploy-live4ded2a8→5f6730d→d9f761f운영배포 완료, 지시문 승인, 운영 서빙 grep 전 마커 검증 PASS): ①편집 뷰 가로폭 해제 — 스펙 테이블이 페이지 프레임 1180px에 갇혀 잘림 → 템플릿 CSS:has()1줄로 편집 뷰가 열린 동안만.op-wrapmax-width 해제(그리드·다른 탭 1180 유지, 미지원 브라우저 무해). ②위치 행 복사 — 사양서 테이블 위치 행에 ⧉ 버튼(이름변경✎·삭제× 사이), 셀·도면참조 딥카피+새 id+원본 아래 삽입(타입 복사와 동일 패턴), 이름 prompt 기본 "원본명 복사". ③엣지 소재 ABS — 옵션 첫번째 추가+기본선택 ABS(EDGE_MATERIALS·edgeSel·정규화 폴백·폼 버튼 4곳). ④바디 뒤판CORE 기본컬럼 + 기본코어 3T MDF —body.backcore(라벨 뒤판CORE)를 CORE 오른쪽 기본컬럼으로, CORE 등록용(defaultPoolFor='core', 셀 추천=3T MDF). SCHEMA_VERSION 2→3: v2 문서는 normalize에서 일회성 마이그레이션(컬럼 삽입+ensureCore(3,'MDF')), v3 저장 후 사용자가 지우면 재추가 안 함(부활 방지). 주의: 구버전 JSON 파일 import 시 버전 다름 confirm 1회 뜸(정상). 캐시버스터?v=20260708c. 검증=node --check+운영/테스트 서빙 마커(loc-copy·ABS·뒤판CORE·3T·v3) 전부 확인, 폭 해제는 로그인 세션 HTML 실측(운영·테스트 both PASS; 로그인 API body 키는password, 500 나면 이것부터 — user_pw 아님). ⏳페페 육안=편집 뷰 폭·행복사·ABS 기본선택·뒤판CORE 컬럼/3T 코어. 훅 게이트 이슈: 운영배포 명시 지시에도 텔레그램 게이트 훅이 자동 발동해 만료 차단 1회 → 명령 분할·재시도로 진행(규칙 보강:C:\dev\CLAUDE.md예외 조항에 "게이트 자동발동·만료돼도 지시문 명시면 승인 간주, 분할·재시도" 기록, 2026-07-08). - ✅완료·운영배포 완료·⏳페페 육안 대기 — 현장별 자재 '미작성 카드' 자동 생성 폐지 (master
e8fcfd7→deploy-live82cc007운영배포 완료, 지시문 "운영 배포 진행" 승인·게이트 생략, 운영 서빙 grep 검증 PASS): 페페 "미작성 카드 자동 생성 프로세스 없애고 매번 사용자가 현장 등록하는 걸로." 자동 생성의 실체=서버가 아니라 프론트buildGrid가 발주서 집계(OP_ALL) 진행 중 현장을 전부 카드로 자동 노출(스펙 없으면 '미작성'). 변경(orderpaper_material.js만): ①buildGrid 카드 소스를 등록된 스펙(/list)만으로 전환 — OP_ALL·field 목록은 업체·상차일·R/E/S 메타 보강 전용(연결키 field_no→정규화 현장명, 완료현장 L4-06 보강 유지), 상차일↓ 정렬 유지, 카드 식별=spec 원문 현장명(by-site 재조회 일치). ②그리드 카운트 라벨 '진행 중 현장'→'등록 현장'. ③신규 현장 모달 검색은 계속 발주서 진행 중 현장 전체 노출(nsData가 gridSites∪siteDropData∪fieldSites 병합) — 등록 진입점 유지. ④deleteSite 문구 갱신(삭제 시 카드 완전 소멸, '미작성으로 남음' 문구 제거). 캐시버스터?v=20260708b. 검증=node --checkPASS+테스트 서빙 grep(신규 주석 반영·구 병합코드 usedSpec 잔재 0). ⏳페페 육안=기존 작성 현장 카드만 보이는지·신규 현장 등록 흐름. 운영 배포는 명시 지시 시. - ✅완료·운영배포 완료·⏳페페 육안 대기 — orderpaper 현장별 자재 탭 카드 UI 재배치 (master
f2f92a5→deploy-live47e99ab운영배포 완료, 운영 CSS op-mat-card-badges 반영 확인): 페페 "현장별 카드 삭제 버튼 추가 + 우상단 상태표시 버튼들 겹침 → 현장명 아래로 재배치". 실상: 삭제버튼(op-mat-card-del)은 기존에 있었으나 hover 시에만 보임(opacity 0)+좌상단 → 우상단 상시 표시로 변경(스펙 있는 카드만 — 미작성 카드는 주문 파생이라 삭제할 스펙 데이터가 없음, 삭제=자재사양만 삭제·주문 유지). 상태배지(op-mat-card-status우상단 절대배치)가 긴 문구일 때 D-day·현장명과 겹침 → 상태+D-day 배지를 현장명 아래 한 줄 in-flow(op-mat-card-badgesflex) 재배치,op-mat-card-top은 삭제버튼 자리 padding-right 26px. 파일=web/static/js/orderpaper_material.js(siteCardHTML)·web/static/css/orderpaper_material.css·field_orderpaper.html캐시버스터?v=20260708a. 검증=node --checkPASS + 테스트 서버 신규 JS/CSS 서빙 grep 확인(op-mat-card-badges). 브라우저 프로필 잠김으로 UI 클릭 E2E 미실시 → 페페 Ctrl+Shift+R 후 육안(카드 × 버튼·배지 겹침 해소). 운영 배포는 페페 "운영 배포" 명시 시. - ✅완료·운영배포 완료 — 현장 삭제 시 연결 견적서 현장 자동 해제(견적명 유지) (master
09b2fb7→deploy-live00b89b9운영배포 완료, 지시문 승인·텔레그램 게이트 생략): 페페 "현장목록에서 현장 삭제 시 연결된 견적서 현장명 자동 해제, 견적명은 유지." 근본:field_dao.delete_field은field만 소프트삭제(remove_yn='1')하고 estimate 무처리 → estimate.field_no 가 삭제된 현장을 계속 참조하고, 견적 조회 조인(LEFT JOIN field)에remove_yn필터가 없어 삭제된 현장명이 계속 표시되는 불일치. 오류는 안 났음(소프트삭제라 FK/조인 안 깨짐)·자동해제도 안 됐음 → 유령 참조. 수정(백엔드 1파일):delete_field에UPDATE estimate SET field_no=NULL WHERE field_no=%s1줄 추가(field 소프트삭제 직후).estimate_name등 나머지 미변경 → 견적명 보존. delete_field 은field_service.py:125단일 호출 경로(707/840 UPDATE field 는 update/address 로 무관) = 근본수정 위치 정확. 검증: pyast.parsePASS. 테스트 RDS E2E(SSM, 트랜잭션 롤백으로 원복): 현장145(계룡 옥천)→삭제 재현 시 field.remove_yn='1'·연결 견적33 field_no NULL·estimate_name 불변 = PASS(field_no NULL True·견적명 유지 True). 운영 배포 검증: 운영 EC2/home/ubuntu/pfs/api/pfs/field/dao/field_dao.py에 신규 UPDATE estimate 라인 반영 확인(SSM read). ⏳페페 육안=현장 삭제 후 그 현장 쓰던 견적 목록/상세에서 현장명 빈값·견적명 유지 확인. - 📌 지침 변경(2026-07-07): 지시문에 "운영 배포 진행" 등 위험작업을 명시적으로 지시하면 텔레그램 승인 게이트 생략하고 바로 진행(그 지시 자체가 승인).
C:\dev\CLAUDE.md·pfs/CLAUDE.md위험작업 섹션에 예외 규칙 추가(커밋09b2fb7에 pfs/CLAUDE.md 포함). 지시문에 없는 위험작업은 여전히 승인 필요. - ✅완료·운영배포 완료·⏳페페 육안 대기 — 견적 등록/수정 현장 미선택(임시 견적) 허용 + 현장 연결 해제 (master
1ab4675→deploy-live3b36703운영배포 완료, 승인 RISK-20260707-BD9S): 페페 "현장 선정 안 해도 임시 견적으로 등록 가능하게. 현장 매핑 안 되면 견적명 입력 필수. 기존 현장명 등록된 견적서도 현장 해제 가능하게." 근본: 백엔드 insert/update 는 이미CONVERT_EMPTY_STRING_TO_NULL(field_no)+field_type 헬퍼if not field_no:return으로 null field_no 를 지원 → 막던 건 프론트validateBasic게이트뿐. 변경(프론트 2파일): ①estimate_regist_v2.jsvalidateBasic— field_no 필수 해제, 현장 없으면 견적명 필수(유일 식별자), 견적명은 항상 필수 유지. ②현장 연결 해제clearSite()신설 +#btnFieldClear바인딩 — field_no/현장·발주처·담당자 비우고 견적명 보존,loadFieldTypesForSite('')로 타입 리셋(details 기준 탭 유지). ③estimate_regist_v2.html— 현장명 라벨*(필수)→(선택),✕ 해제버튼(btn-secondary) 신설. 기존 견적 수정도 커버:/estimate/modify-v2/<no>가 regist-v2 와 동일 템플릿/JS 사용 → 버튼·해제 그대로 뜨고, PUTupdate_estimateSQL 도field_no=CONVERT_EMPTY_STRING_TO_NULL이라 해제 저장 시 NULL 로 밀림(확인됨). 캐시버스터=자동(asset_ver()콘텐츠 해시). 검증:node --checkPASS, 테스트·운영 배포 JS 양쪽에 clearSite/btnFieldClear/새 검증문구 확인(served asset grep, prod=https://pfs.poin.co.kr3건). 브라우저 프로필 잠김(페페 사용 중)으로 UI 클릭 E2E 미실시 → 페페 Ctrl+Shift+R 후 육안(현장 미선택 저장·기존 견적 해제 저장 후 재로드 시 현장 빈값 유지). list 쿼리는LEFT JOIN field라 null field_no 견적도 견적명으로 표시(누락 없음). - ✅완료·⏳페페 육안 대기 — OMC 보드관리 QA 3건(운영배포 완료): 페페 QA(omc/board) — ①보드 추가만 되고 재고 편집 모달 없음→품목 편집 모달 신규(이름 수정/재고 수량 직접 조정/품목 삭제) ②품목 여러개 늘어나니 탭→좌측 세로 사이드 메뉴(2단 레이아웃) ③탭 미선택시 재고 안뜸→요약 재고 상시 표시(품목 0개여도 0으로). 재고조정=목표값 입력→현재재고와 차이만큼 I/O '재고 조정' 행 자동기록(스키마 무변경). 백엔드 item PUT/DELETE + adjust-stock POST(DAO/service/controller). CSS 캐시버스터
?v=20260707i. 파일=web/templates/omc/board.html·web/static/css/omc.css·api/pfs/omc/{dao,service,controller}/board_*. master6c8d7b9(테스트)→deploy-live21f654f운영배포 완료(cherry-pick, 텔레그램 승인). 테스트 API E2E 전항목 PASS(품목 생성→이름수정→재고 상향 0→25(I25)→하향 25→10(O15)→무변동 target10(행 미추가)→삭제(품목+이력 제거) 검증 후 원복). 운영 스모크 PASS(CSS board-layout 반영·품목 5종·board 200·adjust-stock 라우트 무변동조정 데이터변경0). 후속 QA(2026-07-07 16:33): 페페 "선택 안 된 사이드 품목 재고가-장으로 안 뜸, 상시 보이게" →select_board_items가 각 품목 current_stock 서브쿼리 동봉(최신 io_date/id 행 stock), 프론트 사이드 렌더 시 실재고+zero클래스 적용. mastere24d82b→deploy-live3355e4c운영배포 완료(테스트·운영 list API가 품목별 재고 반환 검증 PASS: 운영 id1=9·id4=6·id5=4). 후속 QA2(2026-07-07 16:56): 페페 "재고 수량을 품목명 아래로·편집버튼 상시활성·연필만 말고 '편집' 글씨 포함" → 사이드 아이템을si-body(이름+재고 세로) + 우측 편집버튼 구조로, 재고 뱃지 '재고 N장', 편집버튼 hover노출→상시 표시·✎ 편집버튼형. CSS 캐시버스터?v=20260707j. master25f88c4→deploy-live6cd3fa1운영배포 완료(테스트·운영 CSS si-body 반영 확인). ⏳남은 것=페페 프론트 육안(사이드 메뉴·편집모달·재고 상시표시, 페페 브라우저 잠김으로 Playwright 못함 → Ctrl+Shift+R 후 확인). - ✅완료·운영배포 완료·⏳페페 육안 대기 — OMC 시트관리 QA 2건(omc/sheet): 페페 "①거래처 필터 작동 반대로: 기본 모두선택(전체 표시), 업체 선택 시 그 업체만 필터 적용(현재는 선택 시 제외되는 방식) ②면 단위 해당 항목 배경색을 다른 행과 동일 백색/투명 복원." ①필터 반전: 실은 서버 로직(
vendors빈값=전체, 있으면vendor IN(...))이 이미 "선택된 것만" 방식 → 막던 건 프론트 칩 초기 상태가 전부on이라 3개 전달돼 전체처럼 보이고, 하나 끄면 제외되던 것. 칩 초기on제거만으로 해결(기본 미선택=vendors "" → 서버 전체, 선택 시 그 거래처만). JStoggleVendorChip무변경. ②면 배경 복원:omc.css의.table tbody tr.unit-myeon td{background:#b3e5fc}+ hover 규칙 2줄 제거 → 다른 행과 동일(백/투명), 단위 구분은 단위컬럼 뱃지로만 유지. 파일=web/templates/omc/sheet.html·web/static/css/omc.css. omc.css 캐시버스터 j→k(board·sheet 공용 — board도 같이 bump). master3d772cc→deploy-live12cb07b운영배포 완료. 테스트·운영 API E2E PASS: 미선택=전체(운영 191건 3거래처), 오엠씨만=19건 오엠씨만, 다중(오엠씨+에넥스)=170건 둘 다, 면배경 규칙 제거 CSS 반영 확인. ⏳남은 것=페페 프론트 육안(칩 클릭 필터·면 행 배경 흰색, Ctrl+Shift+R 후). - 미결1 — 페페 육안 확인 대기: 자재관리 탭 성능 구조개선 최종본 = deploy-live
c27b971, 캐시버스터?v=20260707h(50행 페이지네이션+검색 디바운스+전행 hover 제거). 페페 Ctrl+Shift+R 후 체감 확인 예정. 여전히 느리면 남은 후보=페페 크롬 프로필 자체(확장 MutationObserver·접근성 클라이언트·렌더러 메모리 압박) — 코드 쪽 원인(전체 innerHTML·폼요소 상시렌더·table auto·대형 DOM 상시 렌더)은 전부 제거됨. 페페 크롬에서chrome://accessibility상태·작업관리자 렌더러 메모리 확인이 다음 진단 스텝. - 참고 — 자재관리 탭 편집 UX 변경됨: 폼요소 지연렌더링으로 품명·규격·단위·재고·자재분류·사용량은 평소 텍스트, 셀 클릭 시 편집기(Enter 저장·ESC 취소). 파일
web/static/js/orderpaper_material_mgmt.js(editStart/mtStart/_commit/_commitUsed/bindEdit),web/static/css/orderpaper_material_mgmt.css. 캐시버스터 규칙: 코드 바꾸면 반드시?v=새 값으로 bump(같은 값 재배포하면 캐시 안 깨짐 — 이번에 한 번 겪음).
완료(2026-07-07) — QA 발주처/현장명 오분해 근본수정: 파일명 선행 '추가' 마커 (파서 master d95e4b8, 운영 데이터 17건 정정, 승인 DEPLOY-20260707-4ZU8)
- 페페 QA 2건(자재관리 탭 첫 블록): ①발주처 배지가 "추가" → 넥서스여야 ②현장명이 "넥서스" → 소요한남이어야. 근본원인=NAS 파일명
추가 넥서스 소요한남 원부자재발주서.xlsx를 파서parse_site_from_filename이 첫 공백 토큰 "추가"를 발주처로 오분해 → furniture_company="추가", site_name_raw="넥서스 소요한남"으로 밀림. 실제=발주처 넥서스·현장 소요한남·"추가"는 추가발주 마커. 게다가 site_map이 auto로 field 1554(=이름 "넥서스")에 매핑돼 화면 현장명이 "넥서스"로 표시(둘 다 한 파일에서 발생). - 파서 수정(
orderpaper-sync/orderpaper_parse.py, masterd95e4b8):_LEADING_MARKERS(추가/추가발주/재발주/서랍재발주/수정)를 괄호 없이 선행해도 마커로 인식해 발주처 앞에서 떼어냄. 자가검증 6케이스 PASS(기존 괄호마커·정상 파일명 회귀 없음). item_key=sha1(source_file,sheet,section,mtype,idx)라 site_name_raw 미포함 → 재동기화해도 파서가 같은 값으로 멱등 UPDATE(수정된 분해 반영). - 운영 데이터 정정 17건(활성13 no1436~1443·1494~1498 + 삭제4 no1432~1435, remove_yn 불변): furniture_company "추가"→"넥서스", site_name_raw "넥서스 소요한남"→"소요 한남", field_no 1554→2124(소요 한남, 페페 선택; 후보 4개 중 상차 07-09로 발주일 07-01/06과 최근접). site_map: "소요 한남"→2124 is_manual=1 수동연결(자동재매핑 방지)+옛 "넥서스 소요한남" 행 삭제. 트랜잭션+DRY-RUN 검증 후 apply. 스크립트=
orderpaper-sync/_fix_nexus_soyo_prod.py(gitignore, 로컬 이력). - 검증(운영 Playwright all-items): 발주처 "추가" 0건·옛 site_name_raw 0건·소요 한남 13건 전부 fc="넥서스"·field_name="소요 한남"·field_no=2124. QA #1/#2 둘 다 정상. ⚠향후 같은 유형(선행 마커 파일명) 재발 시 파서가 이제 자동 처리 — 재동기화만으로 정정됨.
완료(2026-07-07) — 자재관리 탭 구조개선: 50행 페이지네이션 + 검색 디바운스 + 전행 hover 제거 (master cca4132→deploy-live c27b971, 테스트+운영 E2E, 승인 DEPLOY-20260707-GSDP)
- 페페 "여전히 버퍼링 심함 — 지연렌더 후에도 셀 클릭(편집 준비)만으로 이전보다 심함, 전반적 프로세스 구조 개선 필요". 실측(운영, 클린 브라우저): 클릭→입력창 표시 82~101ms·editStart 3ms·longtask 0건 = 코드 경로는 정상. → 페페 브라우저 환경(확장 MutationObserver·접근성 클라이언트·렌더러 메모리)이 DOM 규모(7023노드·259행)에 비례해 증폭시키는 구조로 판정 → 상호작용 비용을 "보이는 행"에 비례하게 캡.
- 구현: ①페이지네이션 50행/페이지(PAGE_SIZE 고정, 툴바 ◀ N/M ▶, 검색·정렬·토글 변경 시 1페이지 리셋, 블록모드는 페이지 경계에 구분행 재부착·'N건'=전체 그룹 건수 유지) ②검색 200ms 디바운스(키 입력마다 전체 재렌더 제거) ③전행 tr:hover 하이라이트 제거(마우스 이동마다 행 14셀 재계산 — "커서로 선택하면" 증상 후보, 편집셀 hover만 유지) ④편집 input
autocomplete=off(확장 폼 스캔 억제). js/css/html 3파일, 캐시버스터?v=20260707h. - 검증: 테스트 E2E=50행·1/5페이지·페이지이동·검색(29건, 1/1 리셋)·편집 Enter저장 DB영속·블록 2페이지 첫행 구분행·삭제 tr만 제거 전부 PASS, 데이터 원복. 운영 실측=259건 중 50행만 렌더(1/6), DOM 7023→1764(75%↓), 클릭→편집 60ms. 페페 Ctrl+Shift+R로 v20260707h 확인 요망.
2026-07-24 이관 — 루트 HANDOFF NOW 완료건 (원문 그대로)
- ✅구현 완료·테스트 배포(pfs 생산팀 스티커 출력 페이지, 코디 2026-07-14, master
3c3add0→53b89f8): 엑셀(스티커 출력1.xlsm) 웹 이관 — "생산">"스티커 출력"(/production/sticker, 도어/이동선반/파레트 3탭). 파서(병합행 분류 TEXT제외/GROUP수집, 유닛 8/8)+test RDS 3테이블+동기화 사이드카(첫 로드 223파일/16,025품목, 매시간pfs_door_sync)+API 8종+로고 7종+실시간 미리보기(=실인쇄 DOM, 100×100mm 여백5 내용90×90)+Code39 SVG(독립구현체 159비트 일치). 테스트 서버 Playwright E2E 전 플로우 PASS. GT800 실인쇄 피드백 3건 수정(9b06e9a): 빈 라벨 근본수정(시트높이 1mm 셰이브, PDF 3→2페이지 실측)·⚙인쇄설정 패널(용지/여백 localStorage+kiosk-printing 안내)·파레트 A4 가로. ⏳페페 재인쇄 확인(드라이버 용지 100×100), 운영배포는 별도 지시(스키마시드 prod+cherry-pick+동기화 prod 전환). 피드백 5건 추가수정·배포(1c77c3d): 도어 엑셀양식화(페이지네비+블록헤더 타입/위치 입력칸+컬럼구분선), 미리보기 상시표시, 인쇄배율 140%, 로컬 인쇄 에이전트(print-agent, GT800 직접·정확크기·미설치시 브라우저 폴백). 추가 피드백 7건 완료·배포(f21d1f8→829e800): 현장검색 재포커스 전체목록·데이터출처 탭배지(source_sheet컬럼, 파싱 포인만·월드는 배지만)·테이블 색상 진하게·엑셀 수동동기화(웹버튼→door_sync_request큐→미니PC 상주 워커door_sync_watch.pyHTTP폴링 claim→door_order_sync실행, schtaskspfs_door_sync_watch매5분+소켓락, 워커 흐름 실증 223파일 재동기화)·스티커 4면 테두리·양식 디자인개편(현장명 라벨셀·타입/위치 4셀·폰트+3pt·fitText 폭초과 자동축소)·출력행 배경강조. 운영배포 별도지시. 상세=projects/pfs/handoff.mdNOW 최상단. - pfs(2026-07-16): 🆕견적 v2 현장 미선택 저장 실패(field_no KeyError) 근본수정 — 운영 배포·검증 완료(master
90a1566→deploy-live cherry-pick6394f8b, 페페 "운영배포 진행"). 페페 검증보고(/estimate/regist-v2 현장명 미선택): 미선택 시 field_no 요구로 저장완료 안 됨. 근본원인=서버_normalize_masterdefaults에 field_no 누락 → JSfield_no:null을 None-skip 루프가 버려insert_estimate의estimateMaster["field_no"]KeyError. 수정=defaults에'field_no':''1줄(미선택→''→CONVERT_EMPTY_STRING_TO_NULL→SQL NULL, 선택→실값). INSERT/UPDATE 공통 choke point. 검증=격리재현 PASS+운영 EC2 HEAD 6394f8b·uwsgi재시작 06:56:49 UTC·배포코드 함수검증(미선택→NULL·선택→실값) PASS. ⏳페페 육안. 앞서 🆕자재관리 오엠씨 파싱 통일 + 규격 3분리 + 엑셀식 컬럼필터(역방향) + 폭절약 — 운영 배포 완료(masterf4eed35→6004493→c006f54, deploy-live28ea9c1→4959c4b, 페페 "테스트 배포 진행"→"운영배포까지 진행"→"컬럼 폭 절약…운영 배포"). 페페 검증보고(/field/orderpaper 품명): 오엠씨만 품명↔규격 반대. 파서(orderpaper_parse.omc_raw_fields) 오엠씨 원자재 보드행 품명=전면넘버(+후면 다르면 괄호)·규격="두께 재질 양면/단면"(타업체 통일, 엣지/특수행 구포맷 유지·회귀0, item_key 무관 in-place). 프론트 규격→두께·재질·양면단면 3컬럼 순수텍스트 분리+품명 후면 2줄+엑셀식 컬럼헤더 필터 팝업 역방향(양성 선택: 기본 언체크→체크한 값만 표시, 페페 지시)·정렬 오름/내림 통합·다중AND·별도 필터바 폐지. 경면/민자는 오엠씨 미부착=타업체 규격값만 분리(페페 확정). 폭 절약(3컬럼 +212px 넘침→규격 150→78·전반 축소 ~192px 절감·규격 말줄임+title툴팁). 기존 데이터=NAS 재동기화 운영 0ins·1591upd·0removed(item_key 안정)→운영 RDS OMC 95행 old_slash=0. 검증=파서13+프론트22 셀프체크·node check·운영 HEAD/서빙 v20260715c/uwsgi재시작08:46UTC/http200·헤드리스 스텁 육안(역방향필터·폭적합, 로그인 위험게이트라 스텁 대체). ⏳페페 육안(운영 Ctrl+Shift+R). 앞서 🆕배차 현장 선택 시 도착지에 현장명 자동 입력 운영배포(dispatch_list.html인라인 JS 1줄, master0256f8e→deploy-live09fb7ff, cherry-pick, 보고 "운영배포" 승인) — 페페 검증보고 "현장선택 후 도착지 데이터는 현장(현장명) 자동 입력". 현장 검색 선택 choke pointselectField가 현장명·업체·현장주소·도착지주소는 채우나 도착지 본칸(dcDestination)만 비워둠 →dcDestination.value=name1줄 추가. 검증=SSM 운영 HEAD 09fb7ff·서빙템플릿 MARK_SERVED=1(line1472)·uwsgi 재시작 23:40:14 UTC·http200. 편집·기존행 로드는 저장 destination 사용이라 무변경. ⏳페페 육안(/dispatch/list 새 배차→현장 선택→도착지 자동입력). 앞서 🆕입고일정 탭도 같은 pfs현장 연결된 여러 발주서(복사본 등) 한 현장으로 통합 운영배포(orderpaper_schedule.js+field_orderpaper.html, master828b53b→deploy-livee02fb25, cherry-pick, 지시문 "운영배포 진행" 승인) — 페페 "발주서정리에서 통합한 것처럼 자재관리·현장별 입고일정 탭도 현장명 기준 그룹 통합". 발주서정리(6041b11)와 동일 규칙 확장. 입고일정(schedule.js): 블록site=그룹/표시명을 field 연결 시field_name으로 통합(미연결은 원본명),raw=원본 site_name_raw 별도 보존→groups()(site모드)·rowKey()·헤더가 자동 통합. 현장 숨김 버튼은 통합 현장의 소속 발주서 원본명 전부를hide()가BLOCKS에서 모아 배열로hideSite에 전달(hideSite에Array.isArray배열경로 추가, 단건 문자열 하위호환 유지). 검색 haystack에 raw 포함. 자재관리(material_mgmt.js)는siteOf가 생성 시(2026-06-24)부터field_name||site_name_raw우선이라 이미 field기준 통합됨 → 무변경(확인 완료). 검증=node --check+그룹핑/숨김raw 셀프체크 PASS(라인VIP 2복사본 통합·미연결 분리·hide 2원본명 수집)+운영 서빙JS(field_name||site_name_raw·raw:it.site_name_raw둘 다 SERVED=1)·HEAD e02fb25(deploy-live)·템플릿 array브랜치·uwsgi 재시작 06:06:38 UTC·http200. 캐시버스터 schedule.js v20260714a. ⏳페페 육안(Ctrl+Shift+R, 입고일정 탭 두 발주서 같은 현장 연결→한 그룹·숨김 연동). 앞서 🆕발주서정리: 복사본 등 여러 엑셀을 같은 pfs현장 연결 시 한 현장으로 통합 표시 운영배포(프론트 1파일field_orderpaper.html, master6041b11→deploy-live7b67665, cherry-pick, 지시문 "운영배포 진행" 승인) — 페페 "엑셀 발주서 복사해 쓰면 현장 제목이 엑셀파일명으로 뜸 → 현장명으로·통합" + 보강 "두 엑셀을 수동으로 같은 현장 연결하는데 여기서 통합돼야 함". 근본원인=복사본…발주서 - 복사본.xlsx은 파서원부자재발주서$strip 실패로 site_name_raw가 원본과 달라지고, 프론트renderSiteCards가 site_name_raw로만 그룹핑해 같은 field 수동연결해도 따로 뜸. 수정(파서 대신 프론트=페페 지시방향)=①그룹키를 field 연결 시field_no기준(opSiteGroup, 미연결은 raw)→통합 ②제목=연결 현장명·📎 발주서 N건 통합배지 ③숨김/연결변경은 소속 발주서 전부(data-raws+$.when병렬 PATCH) ④hideSite입고일정 외부호출 하위호환. 검증=node --check+그룹핑 셀프체크 PASS+운영 HEAD 7b67665·마커 site_group×4/op-merged×2/data-raws×3·uwsgi 재시작 08:19:52 UTC·http200. 입고일정 탭은 요청범위밖(후속). 페페 육안(Ctrl+Shift+R). 앞서 🆕견적 타입 표시순서 저장·엑셀출력·화면 재열기 반영 운영배포(백엔드+프론트, master5ee1cd9→deploy-liveccb8001, cherry-pick, 지시문 "운영배포 진행" 승인) — 페페 견적732(/estimate/modify-v2/732) "타입순서 지정하면 그대로 저장+견적서 엑셀도 순서대로, 이전 수정한 거 같은데 반영 안 됨". 순서 저장 인프라(field_type.display_order+_reorder_field_types)는 정상인데 읽는 경로 2곳 끊김: ①화면 재열기(loadFieldTypesForSite가 본건↔추가건 섞임 회귀로fieldTypes=[]만 둬 순서 SSOT 무시→detail 등장순 탭) ②엑셀/HTML(print_servicesorted(type_name)가나다/숫자문자열순→'120'이 '84B' 앞으로 튐). 수정=print_service 타입정렬 5곳sorted(...,key=_type_order_key(field_no))(display_order 우선·폴백 이름순)+select_field_type_orderDAO+loadFieldTypesForSite가field-types로typeOrder복원. 검증=실함수 단위검증(732: 종전120,84B,84C→수정84B,84C,120)+운영실측(field_no2134 display_order 84B:1·84C:2·120:3·컬럼실존)+배포반영(운영 HEAD ccb8001·마커·uwsgi 재시작 07:39:58 UTC running). ✅페페 육안 확인 완료(2026-07-13, 작동 정상). 앞서 🆕발주서 오엠씨(원자재) 빈 탭 '(내용 없음 — 업체만 등록)' placeholder 미생성 운영반영(파서 로컬 사이드카, mastera0f9e84, 지시문 "운영배포 진행" 승인) — 페페 "규칙으로 요청데이터는 사라졌는데 현장별 빈 행 생김, 이것도 생성 안되게". 기본설정행 제외로 오엠씨 탭이 통째 비면parse_file이 현장별 빈 placeholder행 생성하던 것 → 빈 탭이 오엠씨/원자재면 placeholder 미생성(부자재 빈탭 placeholder는 실업체 표시라 유지). 검증: 유닛테스트 PASS+NAS dry-run(R placeholder 0·실항목 1519 불변)+운영동기화(removed 11·ins 0)·SSM PH_R=0·ACTIVE_REAL 1338·신규 실항목제거 0·LOSS_COEXIST=0. sites 31→28(오엠씨 빈탭만 있던 실주문無 3현장 소멸, 복원가능). 앞서 🆕발주서 오엠씨(원자재)탭 규격·발주량 없는 기본설정행 미수집 + 기존 숨김 + autosync 복구 운영반영(파서·ssm_run 로컬 사이드카, master2c90288·fa94629·0d4d7db, 지시문 "운영배포 진행" 승인) — 페페 "오엠씨 탭 1~4블록 기본설정(규격·수량 없는) 행 동기화 미수집 + 기존 삭제/숨김 + 추후 규격·발주량 엑셀 입력되면 동기화". 발주서 동기화=로컬PC가 NAS엑셀 파싱→SSM으로 prod RDS(웹배포 아님). 파서 규칙: 원자재 브랜치 스킵을not(front or back or qty)로(두께/수종만 있는 '18T MDF'류 템플릿행 미수집). 동기화가 소프트삭제 재조정(remove_yn)이라 파서만 고쳐도 기존 junk 자동숨김+추후 채워지면 복원 = 3요구 동시충족. 운영 반영: NAS SMB(win32wnet, 한글공유명 Write도구 UTF-8) 후orderpaper_sync.py prod수동 실행. 검증: 제거대상 44='18T MDF'×33+'4.5T MDF'×11(발주량보유 91 보존), LEFTOVER_R_REAL=0·LOSS_COEXIST=0(데이터유실 0)·유닛테스트 PASS. autosync 3중버그 복구(7월내내 파스OK·RDS미반영이던 원인: aws미발견/aws.cmd래퍼 ModuleNotFound/cp949 디코드) →scripts/ssm_run.pyvenv python-m awscli직접호출+UTF-8 replace, 스케줄러 실트리거 성공(멱등)=추후 자동동기화 보장. 로컬 사이드카라 deploy-live 웹배포 불필요, master만. ⏳잔여: 완전template 오엠씨탭 11개 빈탭 placeholder 남음(입고일정 자동필터, 원하면 후속). 페페 육안(/field/orderpaper). 앞서 🆕입고일정 탭 현장 그룹 헤더에 현장 숨김 버튼 추가(전 탭 연동) 운영배포(master8bb97f4→deploy-livecca6257, cherry-pick, 지시문 "운영배포 진행" 승인) — 페페 "현장별 입고일정 탭에도 현장 숨김 버튼 추가, 다른 탭들과 연동". 구현=orderpaper_schedule.jshideBtn(site)헬퍼(현장별S.mode==='site'+현장명≠'(현장미상)'만 렌더, 그룹키=site_name_raw)+opSch.hide()가 발주서정리 탭window.hideSite()재사용(PATCH site-hide→loadAll()이 OP_ALL 재적재+line564opSch.refresh()로 전 탭 동시 갱신=연동 자동), 버튼은 표뷰·타임라인뷰 그룹헤더 양쪽, CSS.ops-hide-btn, 캐시버스터 js/css v20260713b bump. 검증=node --check PASS+hideBtn 분기 self-check 5케이스 PASS+운영 JS(function hideBtn)·CSS(ops-hide-btn×3) 반영·서버 HEAD cca6257·템플릿 v20260713b·uwsgi 재시작(01:07:02 UTC 커밋직후) 확인. ⚠그 사이 deploy-live에 OMC 커밋(827d5b1) 별도 배포됨(내 두 커밋 86bdc69·cca6257 히스토리 정상). ⏳페페 육안(Ctrl+Shift+R, 입고일정 탭 현장헤더 숨김버튼). 앞서 🆕입고일정 탭에서 발주서정리 숨김 현장 동일 제외 운영배포(master4d04c1f→deploy-live86bdc69, cherry-pick, 지시문 "운영 배포" 승인) — 페페 "현장별 입고일정 탭 현장을 발주서정리 탭 숨김현장과 동일하게 숨기기". 근본원인=all-items(select_all_items)가 자재관리 탭 예외용으로 숨김현장(is_hidden)도 컬럼 전송(dao line 77)하는데, 발주서정리·현장별자재 탭은 프론트 opPass에서is_hidden='1'제외하나 입고일정 탭(orderpaper_schedule.js)만 OP_ALL을 rebuild() 집계루프에서 필터 없이 읽어 숨김현장 노출. 수정=집계 forEach 최상단if(String(it.is_hidden)==='1') return;1줄(발주서정리 template line 522와 동일 가드)→리스크표·타임라인·KPI 전부 자동반영, 캐시버스터 v20260713a bump. 검증=node --check PASS·운영 정적JS 가드 반영·서버 HEAD 86bdc69·템플릿 v20260713a 서빙·uwsgi 재시작(23:50:12 UTC, 커밋 직후) 확인. ⏳페페 육안(Ctrl+Shift+R, /field/orderpaper 입고일정 탭). 앞서 🆕사이드 메뉴 모바일·데스크톱사이트 미표시 수정 운영배포(master28656b4→deploy-live3868c85, cherry-pick — master가 deploy-live보다 34커밋 앞서 미완성 진행분 배포 방지) — 페페 "폰·데스크톱사이트 둘 다 사이드 메뉴 안 보임". 근본원인 2개: ①상단바(topbar) 제거(2026-06-19 개편)로 원래 모바일에서 사이드바 여는.nav-toggler버튼이 함께 사라짐 ②pfs_layout.css의 off-screenleft:-210px규칙이 미디어쿼리 밖이라custom.js가width<1170에 붙이는mini-sidebar동안 데스크톱사이트(768~1169)까지 사이드바가 화면 밖으로 밀림(열 버튼도 없어 완전 실종). 수정=③모바일 햄버거 버튼(.nav-toggler.pfs-mobile-toggle) base.html 복원(기존 custom.js show-sidebar 핸들러 재사용) ④off-screen을@media(max-width:767px)로 한정 +show-sidebar열기규칙 재선언(테마 규칙!important없어 덮이던 문제) ⑤자동전환 임계1170→768(태블릿/데스크톱사이트 풀 사이드바) ⑥custom.js 캐시버스트(asset_ver) 추가. 검증=헤드리스 Playwright 3해상도(375=off→햄버거 클릭→슬라이드인 / 980·1280=풀노출·햄버거 숨김) PASS + 운영pfs_layout.css(pfs-mobile-toggle 4회)·custom.js(width<768) HTTP 200 반영 확인. ⏳페페 육안(폰 Ctrl+Shift+R, 데스크톱사이트 전환). 앞서 🆕배포 후 '재시작 누락' 근본원인 해결(오진 정정) — 실제는 Actions가 재시작을 했고 90초 hang. uWSGIdie-on-term=true가 TERM/QUIT 의미를 맞바꾸는데 유닛이KillSignal=SIGQUIT이라 stop이 리로드로 해석→TimeoutStopSec=90뒤 SIGKILL, 그 90초간 구코드 서빙. 유닛에서KillSignal제거(백업*.bak_20260710) → restart 90.2s→1.0s(test·live 둘 다Result=success),deploy-production.sh6.1s·deploy-test.sh8.1s E2E PASS. ⚠유닛은 git 밖(EC2 재구축 시 재적용). 메모리 [[uwsgi-die-on-term-killsignal-conflict]]. 앞서 🆕휴가 타임라인 v2 운영배포(master87e42d9→deploy-liveb9320dc) — 창을 14일 고정에서 휴가 평균 센터가 가운데 오는 가변 창으로(half = max(center, maxEnd-center)+3,days=2*half+1) → 초기 로드에 전 휴가일자 노출 + 전후 3일 여유. 칸 수 가변이라 grid 열 인라인·칸 최소 20px·좁으면 타임라인 내부 가로스크롤(업체명 sticky), nav 가운데전체보기. 표 업체칸 180px 등 축소(max-width:620px, basis 500 — basis 합으로 wrap 판정되므로 620 basis면 1100px에서 밀림). 종료<시작 불량행 제외. 검증=하니스 18항목+스텁 렌더 1000~1680px+SSM 마커/200. uwsgi 수동 재시작. ⏳페페 육안. 앞서 🆕업체 휴가일정 우측 2주 타임라인 운영배포(masterce29eb0·f8de989→deploy-live9c1efc9·1abdadd) — 프론트 1파일(vacation.html)만, 백엔드 변경 0. 좌 표/우 타임라인 flex 2단(둘 다 축소 허용), 14일 창 월요일 정렬·주말/오늘 하이라이트·이전주/오늘/다음주 이동, 창 걸친 휴가는 클램프+cut 표시. 정렬=시작일↑→종료일↑→업체명 가나다순(빠른 휴가 우선 + 같은 기간 자동 인접). 검증=노드 하니스 11항목 + 로컬 스텁 렌더 육안 + SSM 마커/HEAD/200 PASS. 또 uwsgi 재시작 누락 → SSM restart로 마무리(배포 후 HEAD+ActiveEnterTimestamp 둘 다 확인 규칙 재확인). 운영 UI 검증은 로그인 자격증명이 텔레그램 승인 위험항목이라 로컬 스텁 렌더로 대체. ⏳페페 육안(Ctrl+Shift+R,/vacation). 앞서 🆕배차 QA 2건 운영배포(mastera6f2ba7·f4aa672→deploy-live7d37f79) — ①현장검색에서 현장 선택 시 가구업체 자동매핑(백엔드 변경 0 —field/search가 이미 company_no·company_name 반환 →selectField가 채움, 업체 없는 현장은 기존값 유지) ②금액칸 한글 IME 중복입력 수정(공용formatFee한 곳 = 운임비·물품금액·택배비 3칸 동시 해결, 조합 중 value 재대입이 원인 →e.isComposing가드 + compositionend 정리 + inputmode=numeric). 검증=노드 하니스 전 경로·브라우저 실 InputEvent 4항목·운영 템플릿 마커 SSM·8000 200 PASS. ⚠Actions가 git reset만 하고 uwsgi 재시작 누락(템플릿 캐시로 구버전 서빙 위험) → SSMsystemctl restart pfs-live.uwsgi.service로 마무리. 배포 후 HEAD + ActiveEnterTimestamp 둘 다 확인. ⏳페페 육안(Ctrl+Shift+R). 앞서 07-09 🆕배차관리에 택배발송 관리 추가 + QA 6건(masterd6ad526→deploy-live1e09171운영배포 완료) — 택배 의뢰서 순서 발신자 최상단→수신자→나머지, 전 모달 × 버튼 헤더색(#455a64) 동일·호버 무변경. ⚠Actions 자동배포 지연 시 SSMdeploy-production.sh직접 실행(멱등)으로 배포. 수신자/발신 검색 키보드 네비(방향키·엔터·결과1개 즉시엔터·ESC). 배차 페이지·dispatch테이블 재사용,ship_type(D/C)·물품·포장·물품금액·발신연락처 컬럼5 test·prod RDS INSTANT(1464/1629행 보존, 마이그codi_courier_alter*.py).+ 택배 등록전용 모달(발신=업체+발신자 자동완성·기본 포인 자동채움, 수신자=과거택배기록+담당자 company주소 연계·업체명도 검색·표기, company_no=수신자업체), 목록 유형칩·필터, 택배 의뢰서 A4(수신자 먼저→발신자 테이블). QA=브라우저 자동완성 차단(new-password)·수신자 업체명 검색/표기·의뢰서 양식 정리. 검증=test/prod 마이그·SQL round-trip·JS node --check·브라우저 하니스 전항목·운영 배포 마커 SSM PASS. ⏳페페 육안(운영 Ctrl+Shift+R). 앞서 🆕자재관리 정렬 모달 사용자 기본정렬 저장(★버튼→localStorage DEFSORT_KEY, 초기화·기본정렬로·라벨 다 userDefaultSort 기준, PC별·서버미적용, master4de9bd1→deploy-livefbbb868·v20260709c) + 검색창 내부 X(지우기) 버튼(.has-q 토글·즉시초기화, deploy-lived86ce3f·v20260709b) + 자재분류 셀 1클릭 편집(select showPicker 즉시 오픈+셀 채움, mtStart가 focus만 해 2클릭·박스중복이던 것, master6d0c7f5→deploy-liveaef9144·v20260709a, 프로덕션 서빙 검증) + 재고량 stock 단위 제거(시드가 qty 통째복사해 '40m'·'1세트' 혼입 → num_only로 숫자부만, DB 마이그레이션 test232·prod154행 단위제거·잔여0, 시드 2경로 수정 master44fd77d, 프론트 무변경). orderpaper 자동동기화 6일 중단 복구 — 페페 "동기화가 예전 파일(6월 폴더에 7월 내용 추가)을 못 읽는다". 파서·DB·표시는 정상, 진짜 원인=orderpaper_autosync_hidden.vbs에 07-03 추가된conhost --headless가cmd /c set "PYTHONUTF8=1"인용을 깨 python3.9가 "invalid PYTHONUTF8" 치명오류로 매30분 즉사→07-03~09 자동동기화 0건(웹 수동만 반영). 수정=VBS에서sh.Environment("PROCESS")("PYTHONUTF8")="1"(환경변수 직접, cmd set 제거, conhost·숨김창 유지), 재현·수정 검증 후 운영 재동기화(files28·upd1408)→에넥스 대전 개인건 7월항목 정상·6월 status 보존, 스케줄드태스크 수동 트리거 클린 재확인. 이전 07-08: 엣지 선택목록 표기(지정 엣지명+연동칼라 별도줄, deploy-live4813f38) + 사양서 위치 행 드래그 정렬(⠿ 핸들 DnD, deploy-live1b22753) + 위치 행 다중선택→다른 타입·그룹 복사(체크박스+모달, 복사 후 대상 전환, deploy-live4a6f436) + 뒤판CORE 기존현장 미적용 수정(스탬프 선행으로 버전게이트 무력화→무조건 기본보장, deploy-live9efb7ad) + 현장별 자재 편집기 4건 운영배포(편집뷰 폭 해제·위치 행복사·엣지 ABS 기본·뒤판CORE 기본컬럼+3T MDF v3 마이그레이션, deploy-live ~d9f761f, 서빙 검증 PASS) + CLAUDE.md 운영배포 게이트 예외 보강(자동발동·만료 시 분할 재시도). 앞서 orderpaper 현장별 자재 탭 2건 — ①카드 UI 재배치(삭제버튼 우상단 상시표시 + 상태·D-day 배지 현장명 아래,f2f92a5) ②미작성 카드 자동 생성 폐지(발주서 자동 노출→등록된 자재사양 현장만 카드, 신규현장 모달 검색은 발주서 현장 유지,e8fcfd7). deploy-live47e99ab→82cc007운영배포 완료(지시문 승인, 운영 서빙 검증 PASS)·페페 Ctrl+Shift+R 육안 대기. 이전(07-07): ⓪OMC 보드관리 QA 3건(품목 편집모달=이름/재고조정/삭제·탭→사이드메뉴·재고 상시표시) deploy-live21f654f운영배포 완료(API E2E+운영 스모크 PASS), 페페 프론트 육안 대기. ①QA 발주처/현장명 오분해 근본수정 — 파일명 선행 "추가" 마커를 파서가 발주처로 오분해(넥서스→소요한남 밀림), 파서 수정(d95e4b8)+운영 17건 정정(발주처 넥서스·현장 소요한남·field 2124, 승인 4ZU8, Playwright 검증 "추가"0건). ②자재관리 탭 성능 구조개선 최종본 deploy-livec27b971·v20260707h(50행 페이지네이션+검색 디바운스+전행 hover 제거, DOM 75%↓). 페페 Ctrl+Shift+R 확인 대기. 그 외 07-06까지 완료(자재관리 편집/삭제/재번호·견적 v2·worklog·업체휴가일정 등) →projects/pfs/{handoff,archive}.md. 미결: 06-20 진행중 2건(업체목록 정렬/유사업종 필터·현장기록 접이식 그룹, 운영 미배포·승인 대기).
루트 HANDOFF NOW 이관 (2026-07-27, 캡 20,000자 시행)
루트
HANDOFF.mdNOW가 39,399자로 비대해져 매 세션 시드복원 비용이 커짐(적대검증 4자 합의 1순위) →build_brief.py의CHAR_CAP게이트를 루트 HANDOFF에도 적용하고 NOW 항목 원문을 여기로 그대로 cut 이관했다(삭제 0). NOW에는 1~2줄 요약 + 이 문서 포인터만 남는다.
- ✅완료·운영배포(pfs 미반영 커밋 선별배포 C·D·E + devplan 배포관리 페이지, 코디 2026-07-27 페페 지시 "미반영 커밋 리스트"→"C·D·E만 안전한 순서대로 배포"+"pfs 카드 상세페이지"): 미반영 커밋 세는 법이 핵심 — 운영은 merge가 아니라 cherry-pick 이력이라 해시가 전부 달라 원시
deploy-live..master89건은 과대계상, patch-id 비교(--cherry-pick --right-only) 22건 → diff 0인 2건 제외 = 실제 20건. 선별 배포는 merge 불가(A·B까지 끌려옴) → 파일단위git checkout origin/master -- <files>포워드 반영, 위험 낮은 순 E(스크립트)→C(파서)→D(웹UI) 3커밋 + push 1회(운영 재시작 1회). deploy-live6fe4e38(ssm_run aws 복구+택배 마이그 스크립트)7b916e8(품명0 무효행 제외·파일명 '복사본' 노이즈·stock 숫자부 시드)8ca0389(자재관리 헤더 가운데정렬, cssv20260715d). 검증=자체 14케이스 PASS + SSM 실측(운영 HEAD 일치·pfs-live.uwsgiactive·/login200·css 서빙). 남은 미반영 8건 = A 화물앱 배차 3건(페페 육안 대기) · B 월마감 5건(🔴patch41_monthly_close.sql운영 RDS 선행 + 메뉴 시드 46). 신규 관리페이지C:\dev\devplan\pfs.html(그동안 pfs 카드는 상세 없음url:null→projects.json연결·build_hub.py재빌드): 미반영 커밋 관리표(상태 보류/배포예정/배포완료·메모, localStorage)+배포 전 체크리스트+배포완료 이력+'코디용 지시문 복사'(배포예정 표시분만 지시문화). E2E PASS(저장·새로고침 유지·KPI·초기화·허브 카드 링크). 상세=projects/pfs/session-2026-07-27-selective-deploy-cde.md. - ✅완료·운영배포(pfs OMC 보드 품목편집 모달 비고칸, 코디 2026-07-24, 페페 "운영배포"):
/omc/board✎ 편집모달에 비고 입력칸(itemEditNote) 추가 → 재고 수량 조정 시 비고 바로 기입, 미입력이면 기존'재고 조정'유지(스키마 무변경, inoutnote재사용). masterc8e2a1c→deploy-livefd9f2c6. 검증=자체테스트 4케이스 PASS + SSM 운영 실파일 확인. - ✅완료·운영배포(pfs 배차/택배 목록 주소 가독성, 코디 2026-07-24, 페페 "운영배포"): dispatch/list 행의 출발지·도착지 주소 글씨 11px→13px, 색
#8a96a3→#4a5765(진하게). master6f2d2ae→deploy-livef8aa9e4. +목록 가독성 3건(같은날): 주문일 연도 2자리(26-07-24, 공용 fmtDate 미변경·목록에서만 slice), 차량칸 88→68px 축소, 인수자 기존dc-ellipsis재사용해 1줄 고정. mastera05008f→deploy-live96a5677. 검증=node 행 마크업 렌더 assert PASS. - ✅완료·운영배포(pfs 휴가일정 중요업체 체크박스, 코디 2026-07-24, 페페 "운영배포"): 표에 중요업체 체크박스(기본 전체 체크) 추가 — 해제 업체는 타임라인에서 빠지고 창 범위·정렬·배치가 남은 업체 기준으로 재계산(
tlSorted()한 곳 필터). 체크는 화면 상태만(서버 저장 X). +타임라인·표 폰트 일괄 10% 확대(14→15.4 / 12→13.2 / 10→11px). master067d8ef→deploy-livebdcfa99. +체크 상태 서버 저장(같은날 후속):company_vacation.important_yn(기본1)을 ensure_table 멱등 ALTER로 자동추가 +PUT /api/vacation/<no>/important신규 → 새로고침해도 유지. masterc78ad90→deploy-livef69d066. 검증=테스트서버 실 API E2E PASS + 운영 GET에 컬럼·기존11행 전부 체크 확인. - ✅완료·운영배포(pfs 자재관리 탭 숨은 보드 3건 복원, 코디 2026-07-23, 페페 "운영서버 작업·배포 승인"): 용두동 KAEX7-SR=오엠씨 원자재 4행 수동삭제 상태 → 운영 RDS 복원 / 의정부 7201-SKE·MND40ED=DB는 활성인데 원본 엑셀 오엠씨 탭 날짜 미기입 → 템플릿 기본값 2026-01-02 파싱 → 자재관리 3개월 창 밖으로 숨음. 수정=all-items에 regist_date +
badDate()(등록일 대비 120일↑ 과거=오기입) 창 예외, deploy-live cherry-pick34cfbbf→28a1f50. 같은 증상 10블록/7현장 동시 해소. ⏳페페 육안, 근본예방=발주서 엑셀 날짜 기입. 상세=projects/pfs/handoff.mdNOW. - 🆕테스트 배포 완료·운영배포 대기(pfs 월마감 기능 신규, 코디 2026-07-22~23): NAS 1~7월 마감표 기반
/estimate/monthly-close(월×거래처 마감표 편집·견적 자동수집·검증 배지·제출용 엑셀, 넥서스만 시공비 별도) + 테스트 RDS에 26년 1~7월 마감 15건 시딩·견적 백필 70건(72행 중 70행 연결, 원본 엑셀과 1원 단위 일치 검증). masterdae788e..34ab1c3. ⏳페페 육안→운영배포 별도 지시. 상세=projects/pfs/handoff.mdNOW 최상단.
루트 handoff 완료이력 이관 (2026-07-27, 페페 지시)
projects/pfs/handoff.md가 25,190자로 비대해져 BRIEF 클립(앞 6,000자) 창을 완료건이 차지하고 있었다 → ✅완료 항목 원문 그대로 cut 이관(삭제 0). handoff에는 NOW·확정사실·미결만 남긴다. 07-20 이관분(06-19~07-06)에 이어지는 2차 정리. 06-19자 "운영 미반영 잔여 없음" 항목은 2026-07-27 patch-id 실측(미반영 20건)으로 무효가 되어 함께 이관했다. - ✅완료·운영 배포 — OMC 보드 품목 편집 모달에 비고 입력칸 (2026-07-24, 코디, 페페 "운영배포"=승인)./omc/board사이드 품목✎ 편집모달(modalItem)에서 재고 수량 조정 시 비고를 바로 기입. ①web/templates/omc/board.html:itemEditNote입력칸 추가(placeholder="미입력 시 '재고 조정'으로 기록"),openEditBoardItem()에서 초기화,saveBoardItem()이adjust-stock페이로드에note전달. ②api/pfs/omc/service/board_service.pyadjust_stock():note있으면 사용, 없으면 기존'재고 조정'유지(하위호환·DB/스키마 무변경 — inoutnote컬럼 재사용). masterc8e2a1c→ deploy-live cherry-pickfd9f2c6. 검증=①dao 스텁 자체테스트 4케이스 PASS(비고 trim 적용/미입력·공백은 '재고 조정'/증감 방향·수량·차이0 무기록) ②SSM으로 운영서버 실파일 확인(live 템플릿itemEditNote3곳·서비스 note 폴백 존재·운영 HEAD=fd9f2c6). ⏳다음=페페 육안. - ✅완료·운영 배포 — 배차/택배 목록 주소 가독성 (2026-07-24, 코디, 페페 "운영배포"=승인).web/templates/basic/dispatch/dispatch_list.html행 렌더러(622·628행)의 출발지·도착지 주소 span을#8a96a3 11px→#4a5765 13px(파일 기존 토큰--dc-ink-2값 재사용). 2줄 변경, 로직 무관. master6f2d2ae→ deploy-live cherry-pickf8aa9e4. 검증=diff·origin/deploy-live 내용 확인(운영 육안은 페페 — 로그인 필요). +후속(같은날, 운영배포) — 목록 가독성 3건(페페 지시): ①주문일 연도 2자리(26-07-24) —fmtDate()는 날짜입력칸(dcOrderDate/cOrderDate)·출력물(출고요청서·택배의뢰서)에서 그대로 쓰이므로 공용 함수는 손대지 않고 목록 행에서만.slice(2)(공용 변경 시<input type=date>값 깨짐). ②차량 컬럼88px→68px+ 셀nowrap·좌우 padding 8px로 폭 절약. ③인수자 셀에 기존dc-ellipsis(nowrap+말줄임, 현장명 칸이 쓰던 클래스) 적용 → 항상 1줄, 긴 값은 title 툴팁(실측 인수자 길이 p95=7자, 10자↑는 1464건 중 2건뿐). mastera05008f→ deploy-live cherry-pick96a5677. 검증=node로 행 마크업 실제 렌더해 assert(2자리 연도·4자리 잔존 없음·인수자 dc-ellipsis+title·차량 nowrap·fmtDate 원본 유지) ALL PASS. - ✅완료·운영 배포 — 휴가일정 중요업체 체크박스 + 폰트 10% 확대 (2026-07-24, 코디, 페페 "운영배포"=승인).web/templates/default/vacation.html단일파일. ①표 첫 컴럼에 중요업체 체크박스(기본 전체 체크) 추가 — 해제하면 타임라인에서 제외되고 창 범위(tlWindow)·정렬·막대 배치가 남은 업체 기준으로 재계산(필터를tlSorted()한 곳에만 넣어 창·정렬·렌더 전부 자동 반영). 체크 상태는 화면 상태만(VAC_OFF, 해제된 것만 담음) — 서버 저장 없음, 새로고침시 전체 체크(DB·API 무변경). ②vac-*폰트 일괄 10% 확대(표 14→15.4 / 표헤더·버튼·타임라인 업체명·범위 12→13.2 / 입력칸·검색항목 13→14.3 / 타임라인 타이틀 14→15.4 / 날짜헤더·막대글자 10→11px). master067d8ef→ deploy-live cherry-pickbdcfa99(전체 merge는 미배포 master 82커밋이 딸려가 회피 — 직전 배포들과 동일 패턴). 검증=JS 문법체크 + node 자체테스트(체크해제 시 창 209일→13일로 재계산·재체크 원복 assert PASS) + origin/deploy-live 내용 확인. ⚠️운영 페이지 HTTP 육안검증은 미실시(로그인 필요·이 PC aws CLI 미설치로 SSM 불가) → 다음=페페 육안 확인. +후속(같은날, 운영배포) — 체크 상태 서버 저장(페페 "새로고침시 유지" 지시):company_vacation.important_yn TINYINT(1) NOT NULL DEFAULT 1을ensure_table()의 멱등 ALTER로 자동 추가(기존_DDL_NULLABLE과 같은 패턴 — 컬럼 있으면 1060 에러를 try/except가 삼킴, 수동 DDL·마이그레이션 불요·앱 재시작 시 1회 적용). 신규 APIPUT /api/vacation/<no>/important(체크만 갱신 — 업체·날짜 빈 미완성 행도 저장되게 기존update()와 분리). 목록 SELECT에important_yn추가,loadList()가 0인 행만 해제 복원(값 없으면 체크 유지 = 하위호환). masterc78ad90→ deploy-live cherry-pickf69d066. 검증=①node 자체테스트(복원·창 재계산 13↔209일·PUT 경로/본문 assert PASS) ②테스트서버 실 API E2E(임시행 생성→기본 1 확인→0 저장→재조회 0→1 복구→임시행 삭제, ALL PASS) ③운영 GET 실측:important_yn컬럼 응답 확인, 기존 11행 전부 1(=전체 체크). 운영은 읽기만 호출(쓰기 없음, ALTER는 get_list→ensure_table가 자동 적용). - ✅완료·운영 배포 — 자재관리 탭에서 보드 3건이 안 보이던 문제 (2026-07-23, 코디, 페페 "운영서버 작업·배포 승인"). 원인 2개. ①용두동 KAEX7-SR: orderpaper 1455~1458(오엠씨 원자재)가remove_yn=1 del_manual=1=화면 수동삭제 상태(NAS 원본 엑셀엔 실재) → 운영 RDS 복원(가드+before/after). ②의정부 7201-SKE·MND40ED: DB는 활성인데 원본 엑셀 오엠씨 탭 발주/입고 날짜 미기입 → 템플릿 기본값2026-01-02파싱 → 자재관리 3개월 창(passBase의refMs<now-90d) 밖으로 밀려 통째 숨음(파서 버그 아님). 수정=all-items에regist_date추가 +badDate()(날짜가 등록일보다 120일 이상 과거면 오기입으로 보고 창 예외). 처음 "등록일 최근이면 통과"안은 정상 과거건까지 260행 노출돼 기각, 실측 분포(오기입 166일↑/정상 81일↓)로 120일 컷=39행. 커밋 masterd35976f→31e2278, deploy-live cherry-pick34cfbbf→28a1f50(전체 merge는 미배포 월마감이 딸려가 회피),?v=20260723a. 검증=테스트·운영 all-items 실HTTP + 필터 재현(의정부 5행 False→True). 같은 증상 10블록/7현장(GS 오산·GS 인천 산곡6·용두동 씨엔글라스샵·신우APT·금강 부산 에코·한양 이천 대월) 동시 해소. ⏳다음=페페 육안, 근본예방=발주서 엑셀 날짜 기입. +후속(같은날, 운영배포): 동기화 때 날짜 경고 리포트 추가 —date_warnings()(노출 기준일이 파일 월보다 120일↑ 과거=숨김 유발, 날짜칸 빔=미기입 2등급)를orderpaper_sync.pystdout 끝에 출력(사이드카 페이지·result_text양쪽) + '지금 동기화' 완료 시 노란 경고박스(#opDateWarn). 자체점검test_date_warnings.py6케이스 PASS. 실측 숨김 20블록/미기입 22블록. masterbc9e2dc→deploy-liveb40ddb6. - ✅완료·운영 배포 — 견적서 엑셀 A6 업체명 가운데정렬 + 넥서스·에넥스 (주)접두 (2026-07-22, 코디, 페페 "운영배포"=승인).estimate_print_service.py: ①_decorate_company_name()신설 — orderer(=A6 업체명) 값에 넥서스·에넥스 업체면(주)접두(이미(주)있으면 무접두). ②A6(A{b+6}:C{b+6}) 정렬s["l"]→s["c"](origin·참조셀 양쪽). master974ca55→테스트, deploy-live4352624cherry-pick→운영(충돌0·전체 merge는 무관파일 충돌로 회피). self-check 4케이스 PASS. ⏰예약 리마인더: 8/1 09:00 텔레그램(schtasks 일회성reminder-nexus-hansem-20260801→C:\dev\tools\reminders\nexus_hansem_rename_20260801.py→broker /notify-done) = "넥서스→한샘 업체명 변경" 알림. 변경작업 자체는 페페 지시 후_decorate_company_name()의 넥서스→한샘 반영. - ✅완료·운영 배포 — 업체 필터 버튼식 전환 + 견적서v2 확대 (2026-07-22, 코디, 페페 "운영배포"=승인). ①업체 필터를 드롭다운→버튼 그룹(btn-group,.pfs-company-btn)으로 변경: 기본 전체 표시(선택 없음), 버튼 클릭 시 해당 업체만, 같은 버튼 재클릭 시 해제. ②동일 기능을 견적서 관리 v2(estimate_list_v2.html, 필터 div#search-result-datatable_filter, 데이터datatableJSON, 신규applyCompanyFilter()가 clear/add/draw 대체)에도 적용. 두 페이지 모두company_name부분일치·클라 필터·서버 무변경. master3a05acd→테스트, deploy-live73c9ae9cherry-pick→운영(충돌0). ※직전 select판(field_list만, 3d1222e/4316fd6)은 이 커밋으로 대체됨. - ✅완료·운영 배포 — AL발주서 + 생산 스티커 출력 (cherry-pick 배포) (2026-07-21, 코디, 페페 "운영 배포" 지시=승인). master가 deploy-live보다 70커밋 앞선 상태에서 얽힘 진단 후 신규파일 위주라 분리 가능한 2기능만 cherry-pick. 운영 DB 선셋업(멱등·추가만, SSM+prod env): AL=al_orderpaper/al_orderpaper_item테이블+메뉴(menu_no 43,al_orderpaper_seed.pyprod) / 스티커=door_order_file·door_order_item·sticker_print_log·door_sync_request테이블+메뉴(생산>스티커출력 menu_no 45,codi_sticker_schema.py+_v2+_menu_fixprod). 코드: deploy-live에 11커밋(스티커8+AL3 시간순) cherry-pick 충돌0(api/config.py 블루프린트 additive 자동병합), push6394f8b→48ed33b. 검증: 운영 HEAD=48ed33b·uwsgi active·/field/al-orderpaper·/production/sticker·/api/al-orderpaper/vendors모두 200. 미배포 잔여(운영 미반영): 자재관리 UI·orderpaper파싱은 OMC 보드/시트관리와 같은 파일 공유(얽힘)라 이번 제외 → 별도 결정 필요. 배차/택배(courier 마이그레이션 필요)·휴가타임라인·현장별 자재사양서(v3 마이그레이션)도 미배포. - ✅완료 — 테스트 field 전량 운영 미러 교체 + 카톡 메세지 반영 (2026-07-21, 코디, 페페 지시). ①테스트field(1976→2041)·production_status(1975→2041)를 운영 데이터로 전량 미러 교체(운영=SELECT만, 테스트=트랜잭션 쓰기, field_no 운영값 보존). 스키마 가드+백업테이블field_bak_20260721_prodrepl·production_status_bak_20260721_prodrepl(테스트 RDS, 롤백용 보존). 스크립트scripts/_field_replace_test.py. ②더하임 주하늬 과장 카톡 메세지 반영(대상 용두동=2129 "SGC 광주 용두동"·LH의정부=2137 "LH 의정부 우정"). 최종형(페페 수정지시): 비고·자재비고(몸통재/마감재입고)에 넣은 것 전량 원복(운영값 미러 복원), 내용은 생산현황 최하단 전역 "생산 메모"(field_memo.json파일 기반,web/static/uploads/memo/field_memo.json)에만 핵심 기입(오엠씨 입고건 제외). 운영+테스트 파일 모두 반영(페페 "운영서버 반영" 지시=승인, RDS 아닌 서버파일). 운영은 기존 상세노트(출고/LH의정부 엣지·용두동 플랩·하드웨어) 보존 후 append(생산현황 출력은 current만 표시 → merge 필수, previous는 비움). 디스크 재확인 PASS. 스크립트_field_msg_apply_test.py(1차·폐기됨)→_memo_apply.py(원복+메모)→_memo_fix.py(merge)→_memo_verify.py. 주의: field_memo=단일 전역 메모(현장별 아님), 출력 current만 노출. 생산메모 파일 경로 소유권 chown(dir 소유자)로 앱 재쓰기 보장. - ✅완료·운영 데이터 수정 — 자재관리 품명칸에 규격이 뜨던 버그 (2026-07-20, 코디). 근본=orderpaper.item_name_user에 규격조각('15T/18T MDF')이 저장돼 COALESCE로 원본 item_name(WAU38-SR…)을 덮음(코드버그 아님=레거시 데이터, 서버 쓰기경로/item-name1개·정상). 운영 RDS에서 오염 5행 전부item_name_user=NULL정리(안전가드+before/after 검증,scripts/_fix_inu.py·_fix_inu2.pySSM): 1543·1544·1545(신우APT, 07-20 1차) + 328·329(다른 현장, 07-20 2차). 전역 item_name_user 오염 0건 달성(정상 사용자편집도 0). 상세=archive. - 견적서 엑셀 기본보기 = 페이지 나누기 미리보기 + 배율 100% — 운영배포 완료(2026-06-19):_set_print_area에sheet_view.view='pageBreakPreview'·zoomScale=100·zoomScaleSheetLayoutView=100. master9387fbc→deploy-live cherry-pick3724fae. 운영 견적711 4시트 sheetView 실측 검증. - 운영 미반영 잔여 = 없음(2026-06-19git cherry·net diff 실측): master↔deploy-live 순수 차이는migrations/create_dispatch_tables.sql1개뿐 — 배차(dispatch) 기능이 deploy-live서 한 번 revert(cd7faab) 후 재적용된 흔적의 무해 마이그레이션 기록 파일(배포는 SQL 미실행·운영 DB 테이블 기존재). 런타임 영향 0이라 의도적 미배포..gitignore(cbe6674→33b1930)는 운영 동기화 완료. 구 핸드오프의540eb1a 생산메모 미반영메모는 stale(patch-id상 이미 운영 반영됨).
26.7.30 루트 NOW 캡 정리로 이관 (원문 그대로)
- ✅2026-07-28 pfs 현장 내용 = 카톡관리(1탭) + 통화관리(2탭) 운영배포(
deploy-live 9e3a049+502수정a9036c3, master028fd6a/dd76774, poin-agent39726f9, talklog1440777). 1탭=신규api/pfs/kakao_board(미러+웹 편집 명령 큐) — EC2가 사무실 PC로 못 들어오므로 방향을 뒤집어 데몬이 push·pull·적용·회신(폰 조작 주체는 여전히 데몬 하나). 2탭=worklog를source='call'로 한정(조회·집계·묶음변경 전 경로), 노출창 최근2주→이번주 월요일부터+scope=hidden(월요일 이전 전부, 배타상한이 기본창 시작과 맞물림). 야간 02:00night_worklog.py=전사·분류·적재→규칙 auto-link→남은 미연결만 서브에이전트 매칭(conf≥0.8, 입력에 없는 현장 폐기)→가구KBpractice/ops_*_calls.md적립. ⚠api/config.py는 브랜치 간 통째 포워드 금지(미배포 monthly_close가 딸려와 운영 임포트 사망) ⚠숨김이력 682장에서 전체펼침 XHR 폭주 502→loadItems큐(동시 6). 검증=자체18+로컬7+테스트E2E8+운영UI(카톡배지0/통화배지1211·콘솔0)+운영 무해 왕복 1건. ⏳페페 몫=감시 데몬 재시작(상승권한, 지금은 1분 예약작업이 대신해 기능 정상)·devplankakao-ops.html유지 여부. →projects/pfs/session-2026-07-28-worklog-tabs-kakao-board.md - ✅2026-07-28 pfs 생산 메모 모달 통합 운영배포(
deploy-live 7c76774, master6e647fe)./field/list기존/신규 2창 → 단일 입력창(저장본 직접 편집). 이어서 2차 지시로 저장 안내 alert 폐기 + 저장 시 모달 자동 닫힘(deploy-live 8bb6fd9, master 70475a0). 빈값은 차단 대신 confirm(비우고 저장=삭제 의도). 서버 API 무변경. ⚠지시문 "자동저장"은 기존 저장동작 유지로 해석(pfs 견적 autosave는 Patch #21로 폐지·재도입=위험작업) ⏳페페 확인. 검증=테스트 13항목+운영 9항목 PASS. →projects/pfs/session-2026-07-28-field-memo-modal-merge.md - ✅2026-07-27 pfs field/worklog 노출기간 2주 제한 운영배포(
deploy-live 750fdad). 기본=최근 2주+예정, 과거는 시작일 지정 2주창, 검색도 창 안. 핵심 = 기간게이트를 HAVING→WHERE 창으로 교체(HAVING은 집계 후라 카드 건수에 창 밖 과거가 섞임) + 같은 창을 items·bulk·owners에 전파. ⚠기본창 상한 없음 —work_date미래 '예정' 항목 10건이 증발하는 걸 운영 실측으로 발견. 운영 묶음 702→252(64%↓). ⏳페페 육안. →projects/pfs/session-2026-07-27-worklog-2week-window.md - ✅2026-07-27 pfs 미반영커밋 선별배포 C·D·E + devplan
pfs.html배포관리 페이지 신설. 미반영 커밋은 patch-id 비교로 세야 정확(원시 89건→실제 20건), 선별은 merge 불가라 파일단위 포워드 반영·push 1회. 남은 미반영 8건 = A 화물앱 3건(페페 육안) · 🔴B 월마감 5건(patch41_monthly_close.sql운영 RDS 선행). →projects/pfs/session-2026-07-27-selective-deploy-cde.md - ✅2026-07-27 pfs handoff 완료이력 2차 이관(페페 지시): ✅완료 11항목 8,167자 원문 cut →
projects/pfs/archive.md(센티널 11/11), handoff 25,190→17,033자(32%↓). 06-19자 "운영 미반영 잔여 없음"은 07-27 patch-id 실측(20건)으로 무효라 함께 이관. ⚠BRIEF.pfs.md여유는 1,862자 그대로 — 원인은 handoff가 아니라 archive 포인터 섹션 4,282자(pfs archive 엔트리 41 = 세션문서 39)와 memory 본문. handoff는 어차피 6,000자로 클립되므로 감량이 BRIEF에 안 나타난다. 해소하려면build_brief.py의 archive 포인터 섹션 클립(최근 N + 나머지는sessions.md포인터) 필요 = 페페 지시 대기(지시 없는 코드 수정 금지 규칙).
(HANDOFF NOW 이관 2026-07-31)
- ✅2026-07-29 pfs AL설정(엑셀 「설정」 탭) 관리 페이지 CRUD 운영배포(
deploy-live a0faf03, masterf99e739→d38661e→6f228b9). 저장소를 정적 JSON 자산 → RDSal_profile(patch43)로 이전(DAOensure_tables()가 비었을 때 49행 1회 시딩 → 마이그 수동실행 불필요), JSON은 「엑셀 원본 복구」 기준값으로 존치. 신규/field/al-profile(사이드바 미등록 — 접근은 AL발주서 버튼 2곳), 저장은 화면 전체 1콜(soft delete→upsert). 작업 중 수정은 새 창 +window focus재조회·전 행 재계산. 발주서 헤더 컴팩트화(업체 1줄/접기 토글, 폼 106px·그리드 시작 262→195px). ⚠지시문 첫 경로부자재 발주서 일지.xlsm은 설정탭 없음 → 페페가원부자재발주서.xlsx로 정정. 🔴버그=save_bulk가 INSERT 뒤 soft delete를 돌려 신규행이 같은 트랜잭션에서 즉시 삭제(응답 성공인데 조회 없음 = 조용한 실패) → 삭제를 먼저. 검증=엑셀↔시딩 불일치 0 + CRUD E2E 16 + UI 테스트18/운영18(콘솔0) + 운영 SSM(al_profile 49행). ⏳페페 육안. →projects/pfs/session-2026-07-29-al-profile-crud.md
(HANDOFF NOW 이관 2026-07-31)
- ✅2026-07-29 pfs 미반영 A·B 그룹 운영배포(페페 지시) — A 화물앱 배차 3건
83540c8· B 월마감 5건70ba185. 운영 RDS 선행 =monthly_close/monthly_close_item+menu_catalogmenu_no=46(사전 스냅샷 0건 확인), 권한은 자사 기본허용이라 추가작업 불요. 🔑배포 경계는 커밋 수가 아니라 파일 diff로 판정(07-27 파일단위 포워드 탓 patch-id 비교는 28건으로 부풀려짐) → 37파일을 A 8·B 14·AL 15(범위 밖)로 분리, 공유파일api/config.py(월마감 2줄뿐)·mysql_util.py(execute_id뿐) 사전확인으로 AL 미유입 확인. 검증=운영 HEAD·서비스 active·/estimate/monthly-close200·/api/monthly-close200·잔여 diff는 AL뿐. 안 한 것=마감 데이터 시딩(별건)·D005 배차사진 경로(페페 "배포만, 버그는 P0에서"). 🆕후속 QA = 화물앱 접수 버튼 비작동(페페 지시, 운영배포af4b72d/master4433226) —FREIGHT_ENABLED=false게이트로dcToast('준비중입니다')만, 기존 로직 보존(재개 시 값만 true), Playwright 실클릭 검증 테스트 9/운영 9 ALL PASS. ⏳페페 육안. →projects/pfs/session-2026-07-29-deploy-ab-freight-monthlyclose.md
26.8.2 루트 NOW 캡 정리로 이관 (원문 그대로)
- ✅2026-07-30 pfs 신영 광주 챔피언스시티 MH 견적서 운영등록(페페 지시·운영배포 승인) — NAS 견적서 xlsx → 현장 1973: 본건
740(빈 컨테이너 0원) + 추가건741(추가113줄) + 기타부가비운임 150,000= 1,177,000. 입력이 도어발주서가 아닌 견적서 xlsx(확정가)라 매핑을 PFS 출력 렌더러 셀 주소에서 역산. 검증 4단(금액 3중 교차 → VERIFY → 등록 왕복 → 출력 엑셀 vs 원본 셀 대조) 불일치 0. 코드 변경 0. ⏳페페=운영 육안 + 본건 740 내용 채울지 결정. →projects/pfs/{handoff,rules}.md·playbook.md §7
26.8.5(수) HANDOFF NOW에서 이관 — pfs 카톡관리 「체크=표시, 저장=일괄전송」(26.8.4 완료)
- 🆕pfs 카톡관리 [코디] 26.8.4 ✅운영배포 완료 — 「체크=표시, 저장=일괄전송」(deploy-live
abc5208→1009332→fd8916b). 체크마다 재렌더하던 게 원인 — 그 왕복 사이 클릭이 사라진 DOM으로 조용히 유실됐다. 클릭은 표시만, 「저장」이/api/kakao-board/op/bulk로 일괄 전송. 저장 바 = 방 목록 최상단 sticky. 🔑함정 3 = 복원i=0이 falsy라 식별자 증발 ·#main-wrapper{overflow:hidden}이 sticky 스크롤포트를 가로챈다 · 테스트 방 2개뿐이라 스크롤 여지가 없어 검증이 결함을 통과시켰다. 검증 = 자체 13 + 실브라우저 26항목 × 테스트·운영. 🆕전역 규칙 = 고객이 보는 글에 「신동승 차장」, 「페페」 금지(CLAUDE.md §3-8) — 실유출 1건 수정·진원지 봉합(poin-agentc41e6fd). ⏳페페 = ①운영 육안 ②감시 데몬 재시작(상승권한). →projects/pfs/session-2026-08-04-kakao-board-batch-save.md
루트 HANDOFF NOW 이관 (2026-08-06, 캡 여유 확보)
- 🆕pfs 배차목록 통합검색 [코디] 26.8.5 ✅운영배포 완료(deploy-live
668801e← master0d96fe9파일단위 포워드 — merge하면 AL 미배포건까지 끌려온다). 인라인 검색줄 좌측에 「🔍 전체」 1칸 추가(출발/도착과 여백 22px), 행 데이터의 모든 값을 한 문자열로 합쳐 부분일치 → 화면 표에 없는 기사명·비고·연락처까지 걸린다(운영 실측 "박경"→1/56). 기존 출발·도착과 AND. 상단 SEARCH FILTER의 「기사」 칸은 삭제(DAO는args.get이라 미전달 무영향 — 기사 검색은 인라인이 대체). +renderTable끝에applyInlineFilter()= 재조회해도 검색어가 유지된다(원래는 조회 누르면 인라인 필터가 조용히 풀렸다). 검증 = 신설scripts/_dispatch_inline_search_check.py18항목 × 테스트·운영 ALL PASS(좌표 실측·숨김필드 검색·AND·× 복원·콘솔 0). 사이트맵 재빌드 2회 = 배포 전 주황 3 → 배포 후 2(/dispatch/list걷힘, 남은 2건은 기존 AL 미배포). ⏳페페 = 운영 육안. - 🆕pfs 견적서 엑셀 양식 [코디] 26.8.5 ✅운영배포 완료 — NAS 「양식 견적서.xlsx」 채우기로 전환(deploy-live
a485b23+9482849← master01d5f43+b11c8a54파일 포워드, merge하면 AL 미배포건 유입). 서식을 코드로 다시 그리던build_excel폐기 → 템플릿 원본을 바이트 동일로 두고 값만 쓴다(api/pfs/estimate/service/estimate_form.xlsx, static 밖). 양식 변경 = 코드 아닌 이 파일 교체. 🔑결재칸만 예외(도형 그룹이라 openpyxl이 못 살림 → 템플릿 크롭 PNG). 검증 = 자체검사 58항목 + 🆕다운로드 E2E(_estimate_excel_download_e2e.py, 로그인→목록→출력→엑셀버튼→받은 파일 서식대조) 테스트 10 · 운영 11 ALL PASS(운영 견적744 넵스 쌍용 홍은동 MH = NAS 실물과 같은 현장·금액 일치). 🔑E2E 함정 3 = 로그인은 JSlogin()· 견적번호는/api/estimate/message키에서(DOM엔 없음) · 블록수는 max_row 아닌 인쇄영역. 🔴1차 보고 정정 = heredoc\20268진 이스케이프로 NAS 대신 로컬에 저장돼 있었다(정리 완료). 결과물견적\TEST\00~02_…. ⏳페페 = 운영 육안. →projects/pfs/{handoff,rules}.md
견적서 재작성 + 현장 단위 차수 이력 (2026-08-06 완료 · 2026-08-08 HANDOFF NOW 에서 원문 cut 이관)
🆕pfs 견적서 재작성 + 현장 단위 차수 이력 [코디] 26.8.6 ✅운영배포 완료(deploy-live ff48c8b ← master c69c2d8+641ff82 5파일 선별 포워드 · 운영 RDS archive_yn DDL 선행 674행). 도면이 통째로 바뀌어 견적서를 새로 쓸 때 이전 차수는 삭제가 아니라 보관. 🔴지금까진 만들 방법이 아예 없었다 — 현장:견적서 1:1 가드(estimate_regist_v2.js:2142)가 현장 선택을 막았다 → 🔑가드는 한 줄도 안 고치고 estimate_count 에 AND archive_yn='0' 만. 🔑불변식 = 「보관 안 된 것이 곧 지금 쓰는 견적서」(현장당 1건)라 되돌리기는 해제가 아니라 자리 바꾸기(PUT /<no>/select) — 목록 「차수 N」 모달에서 그 현장 전 차수를 한 표로 비교하고 고른다. ⚠추가건은 field_no 가 비어 있어 부모 조인 필요. 🔴덤 = 실패가 성공으로 새어나간다(ajaxSuccessProcess 는 code 2000 만 실패로 보는데 서버 예외는 9999). 운영 708 → 테스트 797 이관(대우 용인 MH·detail 50·sub 53, 행 전량 일치). 검증 = 테스트 러너 2종 32+21항목(둘 다 원상복구까지) + 운영 읽기전용 18항목 ALL PASS (🔑page.route 로 POST/PUT/DELETE 를 아예 차단하고 돌려 오조작 0 증명 · 보관 0·월마감 후보 11 불변·콘솔 0). 사이트맵 미반영 10→2(남은 2 = 기존 AL 백로그). ⏳페페 = 운영 육안(「차수 1」 눌러보기). → projects/pfs/{handoff,rules}.md
대우 용인 오엠씨 탭 1페이지 초기화·재입력 (2026-08-06 완료 · 2026-08-08 HANDOFF NOW 에서 원문 cut 이관)
🆕pfs 대우 용인 오엠씨 탭 1페이지 초기화·재입력 [코디] 26.8.6 ✅운영 완료(코드변경 0·커밋 없음). 페페가 NAS 엑셀 오엠씨 탭 1페이지 행을 지우고 고쳤다 → 그냥 동기화로는 안 되는 이유가 2개였다: ①그 블록 4행이 del_manual='1'(화면 ✕ 삭제)이라 동기화가 remove_yn=IF(del_manual='1','1','0') 로 계속 숨긴다 = 엑셀에 살아 있어도 영원히 안 뜸 ②item_key=sha1(파일|탭|섹션|자재구분|**idx**) 라 중간 행이 빠지면 idx 가 밀려 옛 사용자편집이 다른 자재에 상속(실측 receive_date_user=07-14·재고 39/7 이 엉뚱한 보드에). → 「초기화」 = 그 블록만 물리 DELETE 후 신규 INSERT 로 재수신. block_key=sha1(파일|탭|섹션|자재구분) 이 탭 1페이지 단위 그대로라 다른 탭 무영향. 실행 = _reset_daewoo_omc_prod.py 12행 삭제(before 전량 JSON=롤백, 사용이력 0건 확인 가드) → orderpaper_sync.py prod ins 11. 검증 = 운영 DB 33 ALL PASS + 운영 화면 43 ALL PASS(오엠씨 블록 「11건·발주 8.6·기본입고 8.11」·항목 11행·자재관리 탭 노출·콘솔 0·다른 탭 행수 불변). 사이트맵 그룹8·페이지49·미반영 2(전과 동일, 기존 AL 백로그). ⏳페페 = 운영 육안 + ⚠재고량이 발주량으로 초기화됐으니 수동 기입분 있었으면 재입력. → projects/pfs/{handoff,rules}.md
카톡관리 수정창 자동높이 + 편집 중복 방지 (2026-08-06 완료 · 2026-08-08 HANDOFF NOW 에서 원문 cut 이관)
🆕pfs 카톡관리 수정창 자동높이 + 편집 중복 방지 [코디] 26.8.6 ✅운영배포 완료(deploy-live 11e235e ← master cec85c6+229b61d 4파일 포워드 · poin-agent a5a5e45 · 데몬 재시작 PID 12084). ①수정창 min-height:64px 고정이라 10줄 항목도 3줄만 보였다 → kbGrow()가 scrollHeight로 맞추고 입력마다 재계산, 상한 60vh(운영 실측 76→309→570px). ②「중복 체크 프로세스 있는지 확인」의 답 = 어디에도 없었다 → 3중 게이트 신설(화면 kbDupRow → 서버 add_op → 데몬 board_rows._dup_at). 판정은 셋 다 같은 섹션·첫 줄 동일 — 🔑첫 줄이 행 id 의 근거(sha1(섹션+첫줄+등장순번))라 같은 문구가 둘이면 id 가 등장순번으로만 갈려 앞 행이 사라질 때 뒤 행 id 가 조용히 바뀐다 → 그런 쌍을 애초에 못 만들게 막는 게 근본수정. 🔴덤으로 잡은 유실 = 같은 행에 대기 중 명령이 있으면 두 번째 거부 — 미러가 30~60초 늦게 갱신돼 그 사이 또 고치면 화면은 옛 내용을 보여주고 나중 명령이 앞 명령을 덮어써 방금 쓴 내용이 사라졌다. 검증 = 신설 scripts/_kakao_board_edit_check.py 테스트 26+API 6 · 운영 26 ALL PASS(높이는 픽셀 실측, 운영은 저장 안 누름) + 서비스 자체검사 13→15 + board_rows 자체검사. 사이트맵 3→2. ⏳페페 = 운영 육안. → projects/pfs/{handoff,rules}.md
카톡관리 소프트딜리트(요약 포인터) (2026-08-05 완료 · 2026-08-08 HANDOFF NOW 에서 원문 cut 이관)
pfs 카톡관리 소프트딜리트(「변동 반영 이력」 ✖ = 실제삭제→숨김 이력) [코디] 26.8.5 ✅운영배포 완료(deploy-live 0a75e3a) ⏳페페 육안 → projects/pfs/archive.md
2026-08-12 이관 (루트 HANDOFF NOW 2일 경과분 cut — 26.8.10 완료 3건)
- 🆕자재 입고 카톡 보고 = 현장별 [입고]/[확인]/[미입고] 전개 + 상원보드 HS2329 복구 + 발주서 정리 「미입고」 토글 [코디] 26.8.10 ✅운영배포 완료(deploy-live
b92f465← master4be2d0d1파일 선별 포워드, DB 스키마 변경 0). 페페 지시 3건. ①카톡 본문 = 종전엔 오늘 명세서가 온 현장만 펼치고 나머지는 "그 밖에 46건(현장 12곳)" 숫자 한 줄로 뭉갰다 → 신규 사진 0장인 날엔 본문이 그 한 줄뿐이라 어느 현장을 재촉할지 알 수 없었다. 이제 45일 창 안의 미입고를 현장 그룹 아래 [입고]/[확인]/[미입고] 로 전부 전개하고, 한 현장 5건 초과분만… 외 N건으로 건수를 남긴다(조용한 절단 금지). 실측 2,504자·79줄. 숨김 현장도 포함(fetch_open_items가is_hidden을 안 거른다 — 페페 지시대로가 맞다). 검증 =--selftest11/11 OK(미입고 현장별 전개·상한 표기 신규 2항목) + 신동승 방 실발송 성공(신동혁 대리에겐 중복 안 보냄 — 다음 16:30 정기분부터 간다). ②🔴상원보드 HS2329 = 파싱 문제가 아니었다 — 페페 가설(발주서 파싱 누락)과 달리orderpaper_parse.parse_file은 NAS 실파일에서 정상 수집한다(넥서스 현대 제기 MH · 상원보드 탭 · 효산 HS2329 4.5T MDF 민자양면 2매). 진짜 원인 = 그 행(orderpaper_no 1631)이del_manual='1'(화면에서 수동 삭제) 이라 동기화 UPDATE 가remove_yn=IF(del_manual='1','1','0')로 영구히 죽여 둔 것. → 플래그 해제 후 API 로 완료 + 입고일 2026-08-06(명세서 거래일) 반영,_state.json·verdict 에도 기록(누적 정밀도 100%·재현율 43.8%). ⚠같은 상태 행이 운영에 135건(엑셀엔 살아 있는데 수동삭제) — 미입고 일괄정리 때 먼저 볼 집합. ③/field/orderpaper발주서 정리 탭 「📦 미입고」 토글 — 켤 때만 미입고만 · 업체명 기준 분류 · 기본 펼침 · 숨김 현장 포함, 끄면 켜기 직전 분류·폴딩으로 복귀. 🔑저장 안 한다(모드형 토글을 localStorage 에 넣으면 다음 방문에 업체별·전량 펼침·숨김 섞임으로 갇힌다) · 켤 때 개별 펼침 override 를 비워야 '기본 펼침'이 먹는다 · 숨김 현장 블록엔 「숨김」 배지(되숨김·오판단 방지) · 초기화 버튼이 이 모드도 되돌린다. 검증 = 신설scripts/_op_norecv_check.py(읽기전용) 테스트 ALL PASS + 운영 ALL PASS(운영 = 카드 28/28·블록 51/51 펼침, 완료 0건, 숨김 37건 포함·배지 17, localStorage 무변경, 오엠씨 화면엔 버튼 없음, 콘솔 0). 사이트맵 그룹8·페이지50·미반영 0. ⏳페페 = ①운영 육안(/field/orderpaper미입고 토글 · 카톡 본문) ②판단 = 수동삭제 135건 처리 방침(되살릴지·그대로 둘지) ③"이후 별도 지시로 기본지침 지시 예정"(미입고 정리 기본 규칙). 🆕같은 날 3차 = 미입고는 「진행중 현장」만 보고(페페가 과거 현장 미입고를 PFS 에서 전부 정리한 뒤 지시) — 판정 =POST /api/field/status/search {field_nos}→production_status.field_status='20'. 🔴/api/sticker/fields로 판정하면 안 된다(상차일 3개월 창+LIMIT 100 이라 오래된 진행중 현장이 조용히 빠진다). 미연결·조회실패는 fail-open, 제외 건수는 각주로 남긴다. 실측 110건 → 진행중 33건(4현장)·776자 24줄(전 현장이면 2,504자). 신동승 방 재발송 OK. →projects/pfs/rules.md - 🆕pfs 숨김 현장 관리 모달 = 견적서 현장 검색 표 양식(기간+현장명 검색·기본 3개월) [코디] 26.8.10 ✅운영배포 완료(deploy-live
e965a65← mastereac466b2파일 선별 포워드, DB 변경 0). 페페 QA(/field/orderpaper「🗂 숨김 현장 관리」) = "견적서 현장명 검색 모달과 동일한 형식으로. 별도 검색창(날짜 기간+현장명). 기본 로드는 3개월 이전 현장까지. 운영 배포". 종전 560px 모달 + 검색 입력 1개 + 한 줄 리스트 → 900px + 표 6컬럼(업체명/현장명(발주서)+연결현장/구분/상차일/최근 입고일/항목) + 활성화 열 + 결과 건수 + 헤더 클릭 정렬(기본 상차일 내림차순). 검색창 = 상차일 기간(from~to) + 키워드(현장명·연결현장명·업체명 3필드), 기본 오늘−3개월 ~ 비움(이후 전체) = 견적서 모달과 같은 방식. 🔑데이터는 열 때 한 번만 받고 필터·정렬은 화면에서 — 숨김 현장은 수십 행(운영 27·테스트 6)이라 신규 API·서버 왕복 0, 컨트롤러·서비스 무변경. DAOselect_hidden_sites에ship_date·field_div_name·order_date_min추가(field 값은 LEFT JOIN 아닌 서브쿼리 — GROUP BY 밖 컬럼이 되면 ONLY_FULL_GROUP_BY). 🔴상차일 없는 숨김 현장은 fail-open — 날짜로 걸러 사라지면 이 모달이 유일한 해제 창구라 활성화할 길이 없어진다(실측 0건이나 컬럼은 nullable). 검증 = 신설scripts/_op_hidden_modal_check.py {test|prod}읽기 전용(「활성화」는 존재만 확인·미클릭) 테스트 35 + 운영 35 ALL PASS(3개월 컷 실측 운영 27→25·테스트 6→5, 시작일 비우면 전체 복귀, 종료일·키워드·정렬 토글·초기화, 모달/표 가로 넘침 0, 콘솔 0, 발주서정리 회귀 8카드). 사이트맵 그룹8·페이지50·미반영 0. ⚠같은 시각 다른 세션이 같은 파일에 「미입고 필터」 QA 진행 중이었으나 워킹트리는 깨끗했고 편집 구역이 안 겹쳐 진행(커밋 = 파일 2개 명시 add). ⏳페페 = 운영 육안. →projects/pfs/{handoff,rules}.md - 🆕pfs 발주서 「입고처」 행 파싱 → 오엠씨 자재관리를 오엠씨 입고 시트로 한정 [코디] 26.8.10 ✅운영배포 완료(deploy-live
efa4593← masterba33cfc5파일 선별 포워드, 운영 RDS 컬럼은 동기화가 선적용). 페페 QA(/omc/material, 품명BNS-24E117 PP) = "원부자재발주서 읽는 스킬 보완해줘. 이 품목은 한솔아트에서 피앤알로 입고된다. 입고처 행 위쪽 데이터가 그 탭 업체에서 입고처 업체로 발송되는 것. 오엠씨 자재관리에 보이면 안된다. 수정 운영 배포". 🔎발주서에 목적지가 이미 적혀 있었는데 안 읽고 있었다 — 전 파일 전수조사(45파일·입고처 행 543개) 결과 표준은 A열(A:B 병합)입고처· C열 업체 · D:J 주소, 한 탭에 여러 개면 각각이 자기 위 묶음을 끊는다(실측 엠제이실업 = 오엠씨/진영LDM/상원테크/세영M테크). 파서_receivers/_receiver_of→ 항목별receiver(아래에 입고처 행 없으면 미기재). 🔑item_key/block_key해시엔 안 넣었다 — 넣으면 다음 동기화가 전 행을 신규로 만들어 사용자 편집·상태·이력이 끊긴다(실측 ins 0 / upd 1769 = 키 churn 0). 화면 필터 =발주처=오엠씨 OR (시트 AND 입고처∈{오엠씨,미기재}), 미기재는 fail-open(입고 누락이 오노출보다 위험, 현재 0건). 영향 = 오엠씨 집합 테스트 229→181, 운영 216→170(빠진 46건 전부 목적지가 피앤알·바사디자인·헤브론·호선우드·포인 등). 🔎지금 운영 시트 그룹이 비어 보이는 건 정상 = 오엠씨행 13건이 전부 완료라 접힘, 남아 있던 미완료 1건이 바로 그 피앤알행이었다. 검증 = 신설_op_receiver_probe.py(합성+NAS 실파일) +_op_receiver_db_check.py(SSM 읽기전용, 테스트·운영 ALL PASS) +_omc_material_check.py확장 테스트·운영 ALL PASS. ⚠검사 2건이 「첫 카드·기본 펼침」에 묶여 있어 같이 고쳤다(완료 접힘이면 렌더 자체가 없다 →opExpandCardAll후 전 카드 대상). 사이트맵 그룹8·페이지50·미반영 0. ⏳페페 = ①운영 육안 ②판단 1건 = 화면에 입고처 컬럼 노출할지(지시 범위 밖이라 안 했다). →projects/pfs/{handoff,rules}.md
HANDOFF NOW 이관 (2026-08-17)
- 🆕🔴pfs 생산 인쇄 = 「윈폼 창 + WebView2 + PrintAsync」 로 재구성(아래 print-agent 안을 대체) [코디] 26.8.11 ✅구현·검증 완료(로컬 커밋
56f6949, push·배포 안 함 = 지시 대기). 페페 지시 = "웹뷰로 인한 인쇄 이슈를 다른 방식으로 재구성해 간단·확실하게. 웹뷰를 윈폼 프레임으로 가져오되 출력만 윈폼 방식으로 프린터와 연결해 미리보기 문제(바로 출력)를 없애라". 그릴링1 = PFS 전용 브라우저로 크롬을 대체(페페 택1 — 생산팀은 이 앱만 쓴다). 🔑핵심 =CoreWebView2.PrintAsync(PrintSettings)— 인쇄 대화상자 없이PrinterName·PageWidth/Height(인치)·ScaleFactor·여백을 지정해 찍는다. 스티커=GT800 / 파레트=A4 로 프린터를 나눠 보내므로--kiosk-printing(기본 프린터 1개 고정)이 못 풀던 A4 혼용 문제가 사라진다. 🔑렌더러를 따로 안 만든다 — 화면의 HTML 을 그대로 찍어 미리보기=실물이 원리적으로 보장(구 print-agent 는 라벨 모양을 웹 CSS 와 두 벌 유지해야 했던 게 부채였다 → 폐기 표기). 구성 =pfs/print-appnet48 WinForms + WebView2, exe 35KB + DLL 4개(.NET Framework 4.8·WebView2 런타임 둘 다 Win10/11 기본 탑재 = 설치할 런타임 0). 더블클릭 =%LOCALAPPDATA%자가설치 + 바탕화면·시작메뉴 바로가기 + 프린터 자동판별. 툴바 = 뒤로·홈·새로고침·⚙ 프린터 설정(프린터 2개·배율·자로 재는 90×90mm 테스트 인쇄). 검증 = ①--selftest+tools/verify_print_size.py= 실제 인쇄와 같은 설정으로 PDF 를 뽑아 MediaBox 실측 → 스티커 99.82×99.82mm(기대 100) · 파레트 297.01×209.89mm(기대 297×210) 2 OK/0 FAIL ②앱↔웹 메시지 왕복 E2E(__PFS_PRINT_APP__주입 →print:sticker:100:100:5수신 → 프린터 미지정 거부 → 웹이 사유 수신, 로그로 전건 확인) ③SSH 원격배포 전 구간 실측(localhost 대상 5파일 scp→교체→schtasks /IT기동→구동 확인). 테스트 흔적 전부 원복. 🔴함정 4건 실측 = WinFormsVisible=false컨트롤은 HWND 가 없어 WebView2 가 0x80070578 / Session 0(SSH·코디 Bash)에서도 같은 오류 →schtasks /IT필수(⚠GUI 검증을 Bash 로 하면 코드 버그로 오진한다, 이번에 태웠다) / 접두사 없는 Mutex 는 세션마다 따로 →Global\/ 설치본이 「실행 중이라 복사 실패」를 조용히 넘기면 구버전이 계속 돈다. NAS =\\192.168.0.101\공유폴더\poin\PFS생산인쇄앱_26.8.11(프로그램 폴더·SSH개통 ps1·설치안내). ✅26.8.11 2차 = 웹 변경분 테스트·운영 배포 완료(페페 승인 「테스트+운영 둘 다」). 🔎「스티커 인쇄가 여전히 웹인쇄」의 원인은 코드가 아니라 미배포였다 —origin/master가 2커밋 뒤라 서버는 옛 페이지(로컬 에이전트 호출) 를 서빙했고, 에이전트가 없으니window.print()로 떨어졌다. master071b92epush(테스트 자동배포) → deploy-live17ab861(3파일 선별 포워드, DB 변경 0). ⚠3파일에 미반영 커밋 13개가 걸려 있어 같이 갔다(현장검색 표 양식·정렬 버그·출력회수 초기화·양식 디자인 개편·도어발주서 적재 수정 — 전부 스티커 페이지 한정, 테스트 검증분). 스키마 프로브로 운영 6테이블 이상 없음 확인. 🆕현장검색 = 기본 진행중만 · 검색하면 과거 현장까지(페페 지시) — 검색 시 상태·기간 필터를 뗀다, 상태는 조인 아닌 EXISTS/서브쿼리(조인이면 현장이 중복된다), 결과에 「지난 현장」 배지. 검증 = DB 직결_sticker_fields_check.py테스트8+운영8, 배포 후 API_sticker_fields_api_check.py테스트7+운영7 ALL PASS(운영 '롯데' 43건 중 과거 42·2017년 상차일까지 검색됨). 사이트맵 그룹8·페이지50·미반영 0. 🔴함정 =git checkout <브랜치>실패 뒤&&로git pull을 붙여 master 에 deploy-live 가 머지됐다(4파일 충돌,merge --abort즉시 복구). →projects/pfs/rules.md🆕4. 🆕3차 = 이동선반 발주 목록 ID 오름차순(페페 지시) ✅테스트·운영 배포 완료(master2e924cf→ deploy-live119739b1파일 선별 포워드, DB 변경 0) —ORDER BY ID DESC→ASC(발주 ID 순 = 실제 생산 순서, 화면 기본선택도 첫 항목=최소 ID 로 바뀐다). 검증 = ①imos MSSQL 직결_shelf_orders_check.ps1(PowerShell SqlClient — 이 PC 엔 pymssql·ODBC17 둘 다 없다) 실현장 3곳 6검사 ②배포 후 API_shelf_orders_api_check.py테스트 6 + 운영 4 ALL PASS. 🆕4차(26.8.11 저녁) = 인쇄 6건 수정·운영배포(master88302d6→deploy-liveb43a9ac) — 실사출력 사진(pfs/reference/KakaoTalk_20260811_180711389.jpg, 프린터 ZDesigner GT800(EPL))으로 원인 2개 확정: ①실인쇄 축소 = 인쇄 레이아웃 폭이 화면 폭 그대로라 크로뮴이 용지에 맞춰 전체를 줄인 것(배율 무효의 이유) ②테스트 여백 미적용 =@page{margin:0}이 PrintSettings 여백을 덮어씀. +PFS 로고 아이콘·설정창 잘림(620×400→466 자동계산)·앱 내 사이드바 접힘·상단바 동기화 버튼에✓HH:MM. ✅테스트 인쇄는 페페 실물 확인 = 90×90mm 중앙정렬 성공. 🔴미해결 = 실페이지 인쇄는 위치·크기 그대로. 🔑페페 최신 가설(유력) = 웹 인쇄설정이 계속 덮는다 —PRINT_CFG(localStoragestk_print_cfg_v1)가--stk-w/--stk-h로 시트 크기를 덮고 그 값이 앱에도 넘어간다(테스트 인쇄는 앱 자체 상수 100/100/5 라 정상이었다 = 두 경로의 유일한 차이). 다음 세션 1순위 = 웹 인쇄설정 기능 통째 제거 → 100×100·여백5 상수 고정(페페 지시). 🔴세션 릴레이함(컨텍스트 51.8%) — 인계문inbox/handoff-pfs-print-2026-08-11.md. ⏳페페 몫 3 = ①생산팀 PC 에서 「프로그램」 폴더 복사 → PfsPrint.exe 더블클릭 → ⚙에서 프린터 확인 + 테스트 인쇄 자로 재기(이게 유일한 실물 미검증분) ②deploy_enable_ssh_prod.ps1관리자 1회 실행 → IP·사용자명 알려주기 ③웹 변경분 배포 지시. ❓판단 = 폐기된print-agent폴더를 리포에서 지울지. →projects/pfs/rules.md🆕5 ·C:\dev\pfs\print-app\README.md - ~~pfs 생산 인쇄 = 파레트(A4)까지 로컬 프로그램으로 · 설치 파일 1개 · SSH 원격배포~~ (위 항목이 대체 — 로컬 HTTP 에이전트 방식은 폐기) [코디] 26.8.11 ✅구현·검증 완료(로컬 커밋
fcf3f9a, push·배포 안 함 = 지시 대기). 페페 지시 = "웹구성이라 논스톱·사이즈 정확도가 안 맞는다. 응용프로그램으로 완벽하게. ①10×10cm GT800(도어·이동선반) ②파레트용지(A4). 설치만으로 완료 + qc1처럼 SSH 원격 세팅 파일도". 그릴링1 = 윈폼 독립앱 대신 기존print-agent확장(페페 택1) — 웹 UI 는 그대로 두고 인쇄만 가로챈다(PFS 화면 바뀌어도 앱 무수정). 🔎원인은 새 문제가 아니었다 — 이 프로그램이 이미 7/21 에 있었는데 생산팀 PC 에 안 깔려 브라우저 인쇄(140% 보정)로 돌고 있었다. 신규 = ①/print-pallet(웹.pallet-sheet283×196mm 와 1:1 레이아웃, 현장명·상세 자동축소) ②프린터 2개 분기·자동 판별(이름에 GT800·Godex·Zebra… = 스티커 / 나머지 기본 = A4) ③설정 페이지 서빙(http://127.0.0.1:17777/, 트레이·tkinter 없이 = 새 의존성 0) ④단일 exe(PyInstaller onefile 15.6MB, 파이썬 선설치 불필요) — 더블클릭 =%LOCALAPPDATA%\PFSPrint자가설치 + 시작프로그램 등록 + 프린터 자동판별 + 설정창까지 ⑤렌더를 프린터 장치 DPI 로(203/300/600 자동,PHYSICALOFFSET보정 → A4 레이저 여백 밀림 제거). 웹 = 파레트 버튼도 프로그램 경유 + 실패 사유를 상태줄에 남기고 폴백(조용한 폴백이 "왜 크기가 틀리지"의 원인). 🔴함정 2건 실측 = WindowsSO_REUSEADDR는 포트 가로채기를 허용해 중복 인스턴스가 조용히 같이 떴다(→allow_reuse_address=False) ·--noconsole은 stdoutNone, 콘솔은 cp949 라 양쪽 다 막아야 안 죽는다. 검증 =--selftest19/19 + 파레트·스티커 렌더 육안 + SSH 원격배포 전 구간 실측(localhost 대상 scp→교체→schtasks /IT기동→버전 대조 성공, 테스트 흔적 전부 원복). 사이트맵 재빌드 = 그룹8·페이지50·미반영 0. NAS 복사본 =\\192.168.0.101\공유폴더\poin\PFS인쇄프로그램_26.8.11(exe·SSH개통 ps1·설치안내.txt). ⏳페페 몫 3 = ①생산팀 PC 에서PFSPrint.exe더블클릭(설치) ②deploy\enable_ssh_prod.ps1관리자 1회 실행 → 나온 IP·사용자명 알려주면 코디가~/.ssh/config에Host prod등록(이후 업데이트 원격) ③웹 변경분 배포 지시(테스트/운영). →projects/pfs/rules.md🆕3 ·C:\dev\pfs\print-agent\README.md
HANDOFF NOW 이관 2차 (2026-08-17)
- 🆕pfs 업체 전용 현장 확인 페이지(
/field/company/<company_no>) [코디] 26.8.12 ✅테스트·운영 배포 완료(master05556d8→ deploy-live243a768, 9파일 선별 포워드 — 대상 파일 diff 가 정확히 이번 변경분뿐이라 딸려간 커밋 0). 페페 지시 = "/field/list복사해 업체별 전용 현장 확인 페이지. 사이드 메뉴 최하단에 업체별 현장 그룹. 업체는 자기 현장 일정 확인만, 편집 권한 없음". 그릴링 3문 합의 = ①필터는 URL 링크 + 로그인 계정 이중 강제(페페: 업체 계정은 내가 직접 만든다, 단 타업체 URL 직접 타이핑은 막아라 · 허용된 페이지만 열려야 한다) ②「페이지 생성」 버튼 = 메뉴행 + 권한까지 한 번에 ③표는 버튼열 + 업체열 삭제(11컬럼). 구성 = 범용 복사본field_company_list.html1개(업체별 링크가company_no를 물고 들어온다) · 검색필터 = 현장명·상차일만 · 진행 현장 토글만 · 인라인 검색 유지 · 생산현황(토글·출력·메모)·주요업체 4토글·행 버튼(삭제/수정/타입관리/AS+)·카톡정리 배너·AS 연결/해제 전부 제거(AS 상차현황 팝오버는 읽기전용이라 유지). 🔑격리는 화면이 아니라 서버 = 신설get_scope_company_no()단일 출처를 화면 라우트와field/search서비스가 같이 본다(/api/*는 권한 훅 면제라 화면만 숨기면 API 직타로 뚫린다). 🆕메뉴 =menu_catalog「업체별 현장」 그룹(950) + 업체별 행, admin/company-permission 「페이지 생성/삭제」 버튼이 메뉴행+권한 동시 처리(멱등). 검증 = 신설scripts/_company_field_page_check.py(API·권한 테스트 35 / 운영 35 ALL PASS) +_company_field_page_ui_check.py(헤드리스 렌더·토글·인라인검색·콘솔0 테스트 15 / 운영 15 ALL PASS). 운영 아이비젼글로벌(452) 페이지 생성 완료 = 현장 12건·타업체 0. 사이트맵 재빌드 = 그룹 8 · 페이지 51 · 미반영 0. ⚠함정 = super_admin 은 페이지 차단 훅을 설계상 통과해 「URL 직접입력 차단」을 그 계정으로 재면 200 이 떠서 오진(카탈로그 매칭 규칙 재현으로 검증). ⏳페페 = ①운영 육안(사이드 최하단 「업체별 현장 > 아이비젼글로벌」) ②업체 담당자 계정 생성 후 실제 로그인 1회(계정 생성은 페페 몫) ③다른 업체 페이지는 업체 관리에서 버튼으로 추가. →projects/pfs/rules.md🆕3
🧹 루트 HANDOFF NOW 이관 (2026-08-19 대청소 — pncad 외 전량, 페페 지시)
루트
HANDOFF.md를 pncad 만 남기고 비웠다. 아래는 그때 옮겨온 원문(문구 무변경).
- 🆕pfs 「⚙ AL설정 관리」 버튼 접근불가 — 권한 카탈로그에 항목 추가, 운영 반영 완료 [코디] 26.8.19(수) ✅. QA(qa_helper,
/field/al-orderpaper#alProfileBtn) = "poin03 에 AL발주서 권한을 허용했는데 이 버튼 링크접속이 안 된다. 사용자 권한 관리에 항목 추가해줘. 권한 허용은 내가 직접한다" + 추가지시 "운영배포까지 진행해". 🔑근본원인 =/field/al-profile이menu_catalog미등록(26.7.29 신설 때 "사이드바 미등록" 지시를 카탈로그 미등록으로 구현) → Patch#32dbefore_request가match_url_to_menu_key()None → 「unmapped」 403 으로 총관리자 외 전원 차단. 권한 매트릭스도 같은 카탈로그를 읽으니 켤 항목 자체가 없었다(권한으로 못 푸는 상태). 조치 =menu_catalog1행 시딩(field_al_profile· 부모field· order 219 ·show_in_sidebar='0'= 사이드바엔 안 뜨고 권한 매트릭스에만 뜬다. 숨김 페이지 선례field_regist·field_print_*와 동일) — 앱 코드 변경 0(권한 판정이 DB 카탈로그를 읽는다) → 테스트·운영 RDS 양쪽 SSM 시딩, 배포할 코드 없음. 검증 = 신설scripts/_al_profile_perm_ui_check.py {test|prod}테스트 ALL PASS · 운영 ALL PASS(menu/catalog에field_al_profile· 사이드바a[href="/field/al-profile"]0개 ·/field/al-profile열림 · 권한 매트릭스에 「AL설정 관리」 행(운영은 신동혁=poin03 선택) · 콘솔오류 0). ⚠poin03 은 지금 이미 열린다 — 포인 = 자사(company_type='1')라 명시 row 없으면 기본 허용이고, 매트릭스 토글은 명시 허용/차단용(실측 = user_permission 42행 중field_al_orderpaper='1',field_al_profile은 user·company 양쪽 0행). 사이트맵 재빌드 = 그룹 8 · 페이지 54 · 미반영 0. 커밋 = pfs master72f0f72(menu_dump 갱신만, push 완료). →projects/pfs/rules.md🆕 - 🆕pfs 견적 v2 치수/코너 칸 휠 스크롤 값증감 차단 — 운영배포 완료 [코디] 26.8.18(화) ✅. QA(qa_helper,
/estimate/modify-v2/751치수3) = "모든 치수칸에서 스크롤로 숫자 증감. 치수입력칸 스크롤 금지. 운영배포". 조치 =estimate_regist_v2.jsbindEvents()에 위임 1줄 —$(document).on('wheel', '.dim-cell, .corner-cell', …)에서 포커스만 뗀다(blur). 본문 행·계산기#calcFrame·모달#itemModal이 같은 클래스라 한 곳으로 전부 덮인다. 배포 = master387ba62→ deploy-liveb827551(1파일 포워드, 순수 7줄, DB 변경 0). 검증 = 신설scripts/_dim_wheel_check.py {test|prod}— 운영 배포 전 6 FAIL → 배포 후 14검사 ALL PASS, 테스트 ALL PASS. 사이트맵 재빌드(배포 후) = 그룹 8 · 페이지 54 · 미반영 0. →projects/pfs/rules.md🆕(크롬 스핀버튼 숨김 CSS·CDP 휠 좌표 함정) - 🆕🔴pfs-test HTTPS 복구 + poin01 비번 초기화 [코디] 26.8.18 ✅. 페페 지적 = "테스트 서버에 HTTPS 적용이 안 됐다 · 로그인도 잘 안 된다 · poin01 비번 poin3133 으로 초기화". 🔑근본원인 = ACME 챌린지가 앱으로 넘어가 404 — 80 블록이
.well-known/acme-challenge까지 무조건 443 으로 301 하는데 443 은location /뿐이라 uWSGI(Flask)가 받아 404 → certbot http-01 실패 → 인증서 2026-08-17 만료(로그인 문제는 그 2차 증상). +sites-enabled에 동일 내용.bak이 같이 활성화돼conflicting server name으로 certbot 이 엉켰다. 조치 = 80·443 양쪽에 챌린지 예외(webroot/var/www/html) · 중복.bak을 밖으로 ·certonly --webroot로 발급(renewal authenticator 가 nginx→webroot 로 영구 전환) · reload. 검증 = 로컬에서 TLSv1.3·새 인증서 2026-11-16(89일) ·https://pfs-test…/login200 · API 로그인 + 실브라우저 폼 로그인 테스트·운영 양쪽 OK(→/field/list, PNCAD 열림·카탈로그 서버연결) ·certbot renew --dry-run양쪽 성공 · 자동갱신 타이머 생존. poin01(user_no 1·신동승) 비번 = 테스트·운영 양쪽poin3133로 초기화(앱과 같은StringUtil.hash_password, 옛 해시는 EC2/home/ubuntu/pwreset-backup-*.txt600 백업). ⏳페페 = 로그인해서 정식 비번으로 변경(양쪽). ⚠운영·테스트가 같은 nginx·같은 EC2 — 설정 변경은 대상 파일만·nginx -t실패 시 자동원복으로. →projects/pfs/rules.md🆕 - 🆕pfs 월마감 = 26년 1~7월 운영 1차 초안 채움 + UI 화살표·컬럼폭 — 둘 다 운영 반영 완료 [코디] 26.8.18 ✅. ①NAS 마감표(넥서스·에넥스 1~7월, 넵스 3·7월) 기준 마감 16건·78행, 현장 75/78·견적 12행(금액 게이트로 오연결 차단). 페페 확정 = 기존 견적만 연결 / 7월 넥서스 자동수집본은 마감표로 교체. ②마감월 좌우 화살표(
mcShiftMonth, 연 넘김 자동) + 현장명 26→17%·완료/청구일 12% — deploy-livea8d8f30(1파일, DB 0). 검증 = 시딩 16/16 PASS · UI 19항목 테스트·운영 각각 ALL PASS · 사이트맵 미반영 0. ⏳페페 확인 2건 = ⓐ넥서스 1~4월 이월행 매달 반복 유지 여부 ⓑ7월 마감표에 없는 학동매장 3건·금강 부산에코가 누락인지 8월 이월인지. →projects/pfs/handoff.mdNOW ·session-2026-08-18-monthly-close-prod-seed.md - pfs 업체 전용 현장 확인 페이지(
/field/company/<no>) [코디] 26.8.12 ✅테스트·운영 배포 완료(원문 cut →projects/pfs/archive.md). 🔑격리는 화면이 아니라 서버 =get_scope_company_no()단일 출처를 화면 라우트와field/search가 같이 본다(/api/*는 권한 훅 면제라 화면만 숨기면 뚫린다). ⏳페페 = ①운영 육안 ②업체 담당자 계정 생성 후 실제 로그인 1회 ③다른 업체는 업체 관리에서 버튼 추가. →projects/pfs/archive.md - 🆕pfs 로그인 2건 — 엔터 로그인 · 앱 전용 로그인 유지 [코디] 26.8.18 ✅운영배포 완료(테스트·운영 각 8/8 PASS). ①엔터=로그인 — 버튼이
type="button"+onclick 이라 폼 submit 자체가 없었다 →form onsubmit="login(); return false;"+ 버튼type="submit". ②로그인 유지 = 생산 인쇄 앱에서만(페페 선택: 앱만·무기한) — 앱이 심는window.__PFS_PRINT_APP__를keep_login으로 보내고 그때만session.permanent. 일반 브라우저는 종전대로 종료 시 로그아웃(공용 PC 안전), 비번은 저장 안 한다. 크로뮴이 쿠키를 400일로 깎지만 요청마다 갱신 = 실사용상 무기한. 앱 재설치 불요. 배포 master36dd45c→ deploy-liveb199e65(4파일 선별 포워드, 동승 0, DB 변경 0). 사이트맵 그룹8·페이지54·미반영0. ⏳페페 = 앱에서 한 번 로그인해 두면 이후 자동. →projects/pfs/rules.md🆕 - 🆕pfs 생산 스티커 인쇄 크기 = 근본원인 잡고 운영배포 완료 [코디] 26.8.18 ✅. 페페 실측 = 100×100 라벨에 21×21mm 좌상단. 🔑진범 = 부트스트랩 인쇄 CSS 의
@page{size:a3}— PrintSettings 가 용지를 100mm 로 줘도 CSS 페이지 박스가 A3(297×420)가 돼 크로뮴이 0.238배(=100/420) 로 줄인다(90mm 시트 → 21.4mm, 줄어든 A3 가 좌상단부터 그려져 위치까지 설명).html,body{width:90mm}로는 안 잡힌다(레이아웃 폭이 아니라 페이지 박스 문제). 수정 =appPageCss가@page{size:<용지>mm}를 박는다(margin 은 안 넣는다 = PrintSettings 여백 유지) + 페페 지시대로 웹 인쇄설정(localStoragestk_print_cfg_v1) 통째 폐지(용지 단일 출처 = 앱). 페페 가설이던 localStorage 는 원인이 아니었다(제거 후에도 21.4mm 재현). 검증 = 프린터 없이 실페이지를 인쇄 직전 상태로 떠 앱 WebView2 로 PDF 화 → 21.4mm → 89.55×88.49mm(운영·테스트 동일, 8/8 PASS). 배포 master59c76ef→ deploy-livee64faac. 사이트맵 그룹8·페이지54·미반영0. ✅페페 실물 확인 완료(26.8.18 — 생산팀 PC 실출력 정상). ⏳남은 페페 몫 =deploy_enable_ssh_prod.ps1관리자 1회(원격 앱 관리용, 이번 건과 무관). →projects/pfs/rules.md🆕 ·projects/pfs/archive.md
🧹 루트 HANDOFF NOW 이관(2026-08-23 캡 경고 정리)
- 🆕pfs 월마감 시공비 = master 칸 + 「시공」 항목 — 운영배포 + 넥서스 8월 1행 재계산 완료 [코디] 26.8.20(목) ✅. 지시(견적 735 기준) = 「추가건에 포함된 시공비도 해당 본건 행의 시공비로 넘어가야 한다 · 「시공」 단어 포함 항목은 별도 계산 · 넥서스 8월 마감 현재 내용과 시공비 이동 계산 재검토 · 운영배포」. 🔑근본원인 = 추가건은 시공비를
estimate.construction_cost칸이 아니라 항목명으로 적는다(운영 견적 753 = 칸 0, 항목 「시공비」 2건 2,310,000) → 담기 로직은 추가건 시공비를 본건 행에 이미 누적하는데 0 을 누적하고 그 금액은 추가금액에 섞여 나갔다. 고친 곳 = DAO_CONS_EXPR한 곳(본건·추가건 쿼리 공용, 서비스·화면 무변경) =construction_cost+estimate_detail.margin_total_amount+estimate_extra_cost.amount중 항목명에 「시공」. ⚠판정은 항목명만(비고엔 「2인시공 및 출장비」 가 흔해 운임까지 딸려온다) · 금액은margin_total_amount(총액 보존 성립). 넥서스 8월(close_no 17) 1행 재계산(SSM UPDATE 1행, 확정금액 NULL 가드) = 본건 12,270,000→12,370,000(견적이 담기 후 10만 늘어 있었다) · 추가 8,605,000→6,295,000 · 시공비 8,000,000→10,310,000 · 합계 28,875,000→28,975,000(=견적총액 합). 되돌리기 = 그 4값 원복. 검증 = 신설_mc_cons_split_check.py(읽기전용 API) 운영 배포전 5 FAIL → 테스트 7/7 → 운영 12/12 + 신설_mc_aug_row_ui_check.py운영 화면 10/10 + 기존_monthly_close_ui_check.py회귀 테스트 19/19 · 운영 19/19. 영향범위 = 시공항목 보유 견적 40건(넥서스 35·에넥스 4·한특 1), 시공비 별도표기(넥서스)만 금액 갈림. 사이트맵 미반영 0(API 전용 변경은 사이트맵 추적 대상 아님). 커밋 = masterefe63a8→ deploy-live379e352(2파일 선별 포워드). ⏳페페 = 운영 육안 1회 + 이미 저장된 다른 마감행은 규칙 변경으로 자동 반영 안 된다(재담기해도 이미 담긴 건은 건너뛴다 — 고칠 행 있으면 지시). →projects/pfs/rules.md - 🆕pfs 견적 v2 치수칸 수동입력 단위(mm) 자동 부착 — 운영배포 완료 [코디] 26.8.20(목) ✅. QA(견적 753) = 「치수 수동입력시 뒤에 mm단위가 안들어간다. 수동입력도 단위 붙여줘. 운영배포」. 🔑갈린 이유 = 단위를 출력 포매터가 붙였다 — 엑셀 규격칸
_spec_text는dimension1~5조합에만mm를 붙이고 수동입력size_display는 원문 통과(운영 실측 「920mm」·「2771538」 혼재 = 페페가 손으로 타이핑한 행만 단위 있음) → 출력 3곳(엑셀·PDF·HTML)을 각각 고치는 대신 입력 1곳에서 보정:withSizeUnit()을.size-summaryblur +syncAllSizeDisplayToState()(blur 없이 저장하는 경로) 두 곳에 적용, 화면 텍스트와size_display를 같은 값으로 맞춘다. 부착은 숫자로 끝날 때만(「실측 후 협의」 문구·이미 mm = 그대로, 중복 방지). 기존 무단위 행은 다음 저장에서 함께 정리된다. 검증 = 신설scripts/_size_unit_check.py(로컬 전용, 저장 안 함) 배포전 1 FAIL → 테스트 8 ALL PASS → 운영 8 ALL PASS(견적 753 실측327*2227→327*2227mm·920mm중복없음 · 문구 무단위 · 빈칸→자동값 복원 · 콘솔에러 0), 견적 753 DB 무변경. 사이트맵 배포전 미반영 2 → 배포후 미반영 0(그룹8·페이지54). 커밋 = masterc679301→ deploy-lived5668cf*(1파일 선별 포워드). ⏳페페 = 운영 육안 1회. →projects/pfs/rules.md - 🆕pfs 견적 v2 액션버튼 세로 정렬 + 절약폭 → 비고 — 운영배포 완료 [코디] 26.8.19(수) ✅. QA(견적 753) = 「액션버튼을 세로로, 마지막이 삭제. 절약된 공간은 비고란에 넘긴다. 운영 배포」. 🔑CSS 만으론 안 줄어든다 —
renderColumnHeader()가 DBui_column_setting.column_width(act=105)를 th 인라인 style 로 박아 CSS 를 이긴다. 그 105 는 옛saveColumnOrderToServer가offsetWidth로 덮던 시절의 박제 잔재 →!important대신 그 행을 NULL(자동) 로 되돌렸다(DDL 0 · 1행 UPDATE · test·live 각각 SSM · 되돌리기 = 105 재설정). CSS 는 2줄 —.actcol-wrap을 column flex +align-items:stretch(버튼 폭 균일), 남는 폭은td.col-notemin-width120→200px 가 가져간다(고정폭을 새로 박으면 같은 박제 반복). 검증 = 신설scripts/_actcol_vert_check.py배포전 5 FAIL → 테스트 12 ALL PASS → 운영 12 ALL PASS(액션 105→49px · 비고 143→200px · 행높이 95 그대로 · 가로넘침 0 · 콘솔에러 0), 운영은 QA 원본 견적 753 실측 + 캡처 육안, DB 무변경(항목 저장 안 함). 사이트맵 그룹8·페이지54·미반영 0. 커밋 = master286d5dc→ deploy-livec4c2109(1파일 선별 포워드). ⏳페페 = 운영 육안 1회. →projects/pfs/rules.md - 🆕pfs AL발주서 QA 3건(유리 입고처 컬럼 · 전화면 가로폭 · 거래처 담당자 실시간) — 운영배포 완료 [코디] 26.8.19(수) ✅. 🔑③의 근본원인 = 업체 자동완성이 DB 가 아니라 번들 JSON 스냅샷(
assets/vendors.json= 원부자재발주서 업체탭 381행 + 프로세스 캐시) → 거래처에서 담당자를 바꿔도 구조적으로 못 들어온다(운영 실측: 대진아트와이어 = 신동환차장 삭제·김정현대리 활성인데 화면은 신동환차장) →company+company_member실시간 조회로 교체, 거래처에 없는 이름만 스냅샷 보충, 캐시 제거(운영 414행). ①입고처 = 그리드 마지막 컬럼(인라인 검색·Enter, 기본 = 그 행 AL업체 — 유리는 AL업체로 입고돼 조립된다) + 엑셀은 유리 그룹 키를 「업체」→「업체+입고처」로 바꾼 것만으로 「그룹화·바로 아래·행 추가 금지」가 전부 충족(양식 블록마다 입고처 행이 이미 있다). ②.al-wrap1240 해제 + container 여백 25→16 + 컬럼폭 절약 = 19컬럼 1,676px, 1920 화면 가로 스크롤 0. 🔴중간에 잡은 기존 버그 = 유리 17개 이상 엑셀 500(양식 24행 캡노트C24:H24를 항목행으로 세어 MergedCell 기입) → 판별을 B·C 둘 다, 유리ipb18→17. 검증 = 신설_al_recv_check.py배포전 9 FAIL → 테스트 24 ALL PASS → 운영 18 ALL PASS + 회귀(콤보 19 · AL E2E 20/0) + 엑셀 자체검사, DDLreceive_place운영 선행 적용(컬럼만), 사이트맵 그룹8·페이지54·미반영 2(내 작업 아님 = 견적 v2). 커밋 = masterfffd408·b98e683·b23cf72→ deploy-live9963dd5·75172d2. ⏳페페 = 운영 육안 1회. →projects/pfs/{handoff,rules}.md - 🆕pfs 견적 v2 그룹 소계 실시간 갱신 + 출력 담당자칸 직책 — 운영배포 완료 [코디] 26.8.19(수) ✅. QA 2건(견적 749) = ①소계가 실제 금액과 안 맞음 ②엑셀 담당자칸에 직책 누락. 🔑①근본원인 = 부분 갱신 누락 —
recalcDetailRow()가 행 최종합계·종합합계만 갱신하고 그룹 소계 행은renderDetailTable()시점 값에 멈춰 있었다(updateGroupSubtotal()은 있었지만 part_mode 토글 한 경로에서만 호출) → 호출자 4곳이 전부 지나는recalcDetailRow한 곳으로 통합. 🔑②근본원인 = SELECT 누락 —_compose_manager의 현장담당자 폴백이 쓰는d.position을select_estimate가 안 뽑았다(참조인물 보유 33명/417명만 정상) →d.position AS position한 줄, 엑셀·PDF·HTML 이_build_common_header공유라 함께 복구. 검증 = 신설_est_grouptot_manager_check.py(읽기전용) 배포전 7 FAIL → 테스트 15 ALL PASS → 운영 15 ALL PASS(749 실측 소계 동기 + 엑셀종합!A8="은지호 대표"), 749 DB 무변경, 사이트맵 그룹8·페이지54·미반영 0. 커밋 = master4114abf→ deploy-live7aab4ad. ⏳페페 = 운영 육안 1회. →projects/pfs/{handoff,rules}.md - 🆕pfs 견적 list-v2 입금여부 = 월마감 초안 기준 — 운영배포 완료 [코디] 26.8.19(수) ✅. 그릴링 3문 확정 = 확정금액 있으면 입금 · 마감행만 있으면 「마감」 · 없으면 미입금(3상태) / 매칭 = 견적번호 우선 + 현장 폴백(마감행에 견적번호 없을 때만) / 수동
is_deposit='1' 이면 우선(토글 유지, 끄면 마감 기준 복귀). 근거 = 수동 토글은 견적 640건 중 5건만 켜져 사실상 미사용, 마감 초안은 16건·78행이 이미 있다(78행 중 75행이 견적에 붙는다). 서버는 서브쿼리 2개(mc_confirm_cnt·mc_close_ym)만, 판정은depositBtnHtml()한 곳 + 판정근거 툴팁. 검증 = 신설_deposit_mark_check.py배포전 2 FAIL → 테스트 12 ALL PASS → 운영 9 ALL PASS(운영 분포 입금13·마감2·미입금21), 사이트맵 그룹8·페이지54·미반영 0. 커밋 = masterd2940ee→ deploy-live3ed47d7. ⏳페페 = 운영 육안 1회. →projects/pfs/{handoff,rules}.md - 🆕pfs AL발주서 드롭리스트 근본수정 + 현장명 드롭리스트(견적서 현장검색 기준) — 운영배포 완료 [코디] 26.8.19(수) ✅. 근본원인 =
scroll캡처 리스너가 드롭리스트 자신의 스크롤까지 잡아 휠 한 칸에 닫힘 → 닫지 말고 재배치(placeCombo,position:fixed+위로 뒤집기). 높이 242→484px 2배. 현장명은 견적서와 같은 APIestimate/site-search. 검증 = 신설_al_combo_check.py배포전 8 FAIL → 테스트·운영 각 19 ALL PASS + 기존 UI검증 27 ALL PASS, 사이트맵 그룹8·페이지54·미반영0. 커밋 = masterde0ba09→ deploy-liveec2c87a. →projects/pfs/{handoff,rules}.md
🧹 루트 HANDOFF NOW 이관(2026-08-28) — 원문 그대로
캡 경고선(30,000자) 초과로 완료 항목을 옮겼다. 절차 =
rules/runbook.md.
- ✅pfs 에넥스 금호 구미 — 견적 3차수 작성 + 엑셀 3종 NAS 저장 (운영 데이터 작업, 코드변경 0) [코디] 26.8.26(수). 1차 764 24,058,000(자동10) → 2차 765 19,009,000(마진 −20) → 3차 766 20,020,000(마진 −14) → 4차 767 26,412,000(마진 +24 = 1차 대비 +9.97%, 사용 중), 운반비 450,000 은 4차수 전부 미변경(페페 지시). 🔑「전체 마진율 20%」 = 할인 20% =
margin_percent -20— 이 견적의 추가금액이 이미 −20% 를 할인으로 쓰고 있었고, 플랫 −20% 면 총액이 「1900만원 약간 초과」에 원 단위로 떨어진다. 3차는 페페 확인 후 −14% 계산 + 파일명 (5)(규칙 외 명명). 🔑엑셀 단가(SET)는margin_total_amount/수량이라 전체 마진율 한 칸만 바꾸면 단가가 통째로 따라 움직인다(단가 마스터 무손). 검증 = 계산식 재현으로 1차 원 단위 일치 · 복사본 전 컬럼 대조 PASS · 엑셀 실파일 3종 금액 ALL PASS. NAS2026현장\견적\09월\에넥스\금호 구미 견적md5 일치. →projects/pfs/{handoff,rules}.md - ✅pfs 견적 v2 행 UI 3건 — 치수/코너 클릭 블록선택 · 폴딩 아이콘 단일화+사이안 · 분류 드롭다운 확장 [코디] 26.8.26(수) 운영배포 완료(master
abf3e36→ deploy-liveb83d8c6, 2파일 +39−12, 서버코드·DDL·DB 변경 0). 페페 qa_helper 3건. 🔑focus만으론 mouseup 이 선택을 푼다 →focus click둘 다 ·type=number는selectionStart못 읽어도select()는 된다 · 컬럼 폭은 사용자별 DB 값이라 아이콘은 패딩을 줄여 키웠다(18→26px). 검증 = 신설_est_qa826_ui_check.py테스트 36/36 · 운영 37/37 ALL PASS, 회귀 3종 0 FAIL. 사이트맵 미반영 0 · devplanAE등재. ⏳페페 = 운영 육안 1회. →projects/pfs/{handoff,rules}.md - 🆕pfs 견적 현장검색 모달 — 상차일 미확정 노출 + 맨 위 — 운영배포 완료 [코디] 26.8.25(화) ✅. 페페 qa_helper(
/estimate/regist-v2#btnFieldSearch) 「미확정분도 나오게 하고 리스트 상단에 배치. 운영배포」. 🔑원인은 정렬이 아니라WHERE—select_site_search의shipping_date >= date_from이 NULL 을 걸러내 미확정이 결과에 아예 없었다(같은 함정 3번째: 리포트 SQL·현장목록 검색·여기). 🔑WHERE 만 고치면 반쪽 —LIMIT 50+ 내림차순이라 NULL 은 꼬리에서 잘린다 →ORDER BY (shipping_date IS NULL) DESC를 맨 앞에. 프론트는 빈 값을 정렬 방향 무관 맨 위 + 「미확정」 표기. 2파일 +12 −4 · DDL 0 · DB 변경 0. 같은 API 쓰는 AL발주서 현장 드롭리스트·자재관리도 같이 고쳐짐(회귀 0). 신설_estimate_site_tbd_check.py테스트 22/22 · 운영 17/17 ALL PASS +_al_combo_check테스트·운영 ALL PASS. masterac24be5→ deploy-live845285e(2파일 선별 포워드), 사이트맵 미반영 0, devplan DONEAD. →projects/pfs/{handoff,rules}.md - 🆕pfs 거래처 개명 넥서스 → 한샘 — 운영배포 완료 [코디] 26.8.25(화) ✅. 페페 「관련 지침에서 용어 교체를 같이해서 시스템에 오류가 안생기도록. db수정도 승인. 운영 배포」. 🔑가르는 기준 = 「실물이 같이 바뀌었나」 — 바꾼 것 = 업체 마스터(
company.name, company_no=1 하나라 현장 825건·담당자 22명이 FK로 자동 추종)·발주서 업체키 1561/18행·2026-08 마감 1행·vendors.json/ 안 바꾼 것 = NAS 파일명·카톡방명·녹음파일명·통화원문·견적명·worklog 현장명(바꾸면 매칭이 깨지거나 과거 사실이 틀어진다). 🔑함정 = DB만 고치면orderpaper_sync의ON DUPLICATE KEY UPDATE가 파일명 파싱값으로 되돌린다 →orderpaper_parse._COMPANY_ALIAS에서 적재 시점 정규화, 순서는 파서 먼저 DB 나중. 🔑vendors.json은 거래처에 없는 이름만 보충하는 폴백이라 마스터만 바꾸면 옛 이름이 자동완성에 유령으로 남는다. RDS 스냅샷pfs-pre-hanssem-20260825+ 역조건 롤백 스크립트. 신설 검사 테스트 16/16 · 운영 20/20 ALL PASS + 회귀 6종 ALL PASS, 동기화 1회 실주행 후 운영 한샘 1276·넥서스 0 실증. masterb1ef589→ deploy-livea449d3e(22파일), 사이트맵 미반영 0. →projects/pfs/{handoff,rules}.md - 🆕pfs 현장목록 상차일 미확정을 맨 위로 — 운영배포 완료 [코디] 26.8.25(화) ✅. 페페 「미확정분이 리스트에서 안 보인다」. 🔑원인 = 3차 정렬 롤백이 미확정을 맨 위에 두던 효과까지 같이 걷어갔다 — 문자열 내림차순에서 빈 값은 맨 뒤라 운영 129행 중 7페이지째로 밀렸다.
fieldListOrder부활하되 상태는 안 본다(미확정 여부 → 상차일 내림차순 → field_no 내림차순). 상태 그룹 정렬은 3차 롤백 그대로 유지·검사로 고정.field_list.html1파일·서버코드 0·DDL 0. 검증 테스트 57/57 · 운영 34/34(읽기 전용) ALL PASS + 운영 육안(상위 3행 전부 미확정, 4행째부터 20260916 내림차순). master1640a2f→ deploy-liveb1958ab, 사이트맵 미반영 0. →projects/pfs/{handoff,rules}.md - 🆕pfs 등록·수정 폼 현장상태 토글 = 진행중 ↔ 대기중 둘만 — 운영배포 완료 [코디] 26.8.25(화) ✅. qa_helper 「이 버튼에서 완료는 제외」 → 폼 토글만 2상태, 목록 상태 컬럼은 종전 3단계 유지(서로 다른 순환표).
PFS_STATUS_FORM_NEXT {20:10,10:20,30:20}신설. 🔑30→20을 남긴 이유 = 완료로 저장된 현장을 수정으로 열면 완료를 그대로 보여줘야 하고(자동으로 바뀌면 저장 때 상태가 조용히 뒤집힌다) 누르면 두 상태 순환으로 들어올 출구가 필요하다. 완료 복귀는 목록 버튼으로. 3파일·서버코드 0·DDL 0. 검증 = 테스트 55/55 · 운영 32/32(읽기 전용) + 회귀 ALL PASS. mastera998988→ deploy-livef739d33, 사이트맵 미반영 0. ⏳페페 육안 1회. →projects/pfs/handoff.md - 🆕pfs 현장목록 상태 정렬 롤백 + 현장상태 필터 탭 — 운영배포 완료 [코디] 26.8.25(화) ✅. 페페 「상태 정렬순 취소·롤백, 대신 표 위 「검색결과」 자리에 대기중/진행중/완료 필터 탭. 나머지는 그대로」. 정렬은 상차일 내림차순 한 줄로 복귀(
fieldListGroup·fieldListOrder삭제), 상태는#status-tabs로 고른다 — 하나만 걸리고 같은 탭 재클릭 = 전체 해제(업체 필터와 같은 방식), 업체·진행현장 필터와는 AND. ⚠상차일 기간검색 NULL 통과는 유지 — 정렬이 아니라 미확정 현장을 목록에 띄우는 수정이라 빼면 다시 사라진다.field_list.html1파일·서버코드 0·DDL 0. 검증 =_field_list_qa5_check.py테스트 51/51 · 운영 30/30(읽기 전용) + 회귀 ALL PASS + 스크린샷 2장. master6fda185→ deploy-live89e5c9d, 사이트맵 미반영 0. ⏳페페 육안 1회. →projects/pfs/handoff.md - 🆕pfs 현장목록 QA 5건 — 운영배포 완료 [코디] 26.8.25(화) ✅. ①기본 정렬 = 미확정 → 대기중 → 진행중 → 완료, 묶음 안은 상차일 내림차순 ②상태 컬럼을 버튼으로(대기중-진행중-완료 순환·바로 PATCH 저장, 확장행 칩과 같은 경로) ③등록·수정 폼 현장명
col-md-5→4로 줄이고 유형과 상차일 사이에 현장상태 토글(기본 진행중) ④현장담당자 → 업체담당자 → 시공담당자 탭 직행 ⑤페이지당 20행. 🔑어제 함정의 2차 발현 = 목록이 스스로 넣는 기본 검색기간(과거6개월~미래1년)의 상차일 비교가 NULL 을 걸러내 미확정 현장이 목록에 아예 안 떴다 →(IS NULL OR …). 남은 같은 자리 3곳은rules.md🆕 에 적어뒀다. 🔑update_field는 값이 올 때만field_status를 SET(목록 토글 결과를 폼 저장이 덮지 않게). 🔑수정화면은 담당자 팝업버튼이 유일한 조작 경로라 탭에서 빼는 대신 이름칸 Enter 로 팝업을 열게 했다. 검증 = 신설_field_list_qa5_check.py테스트 38/38 · 운영 16/16(읽기 전용) + 회귀_ship_tbd_check테스트·운영 ALL PASS. masterc45cd33·adb7c2a→ deploy-livef082d28, DDL 0 · 사이트맵 미반영 0. ⏳페페 육안 1회. →projects/pfs/{handoff,rules}.md - 🆕pfs 상차일 「미확정」 토글 — 운영배포 완료 [코디] 26.8.25(화) ✅. qa_helper(
/field/modify/2134) 지시 = 상차일 좌측 미확정 토글 · 날짜 없이 등록·수정 허용 · 날짜 넣으면 자동 해제 · 생산현황 출력엔 「미확정」. 컬럼을 안 만들었다 — 미확정 =shipping_date IS NULL하나뿐(char(8) NULL이라 DDL 0), 버튼은 그 값의 거울이라 모순 상태가 없다. 공용initShippingTbd()를pfs-component.js에 두고 등록·수정 두 화면이 공유. 🔑근본원인 2건 = ①리포트 SQL 의date_format(shipping_date,'%Y') >= 올해-1이 NULL 행을 통째로 걸러내 미확정 현장이 표에 안 나왔다 ②daterangepicker 는typeof null === 'object'라startDate:null→moment(null)=Invalid date → 달력이 안 열려 날짜를 다시 못 골랐다. 검증 = 신설_ship_tbd_check.py테스트 27/27 · 운영 17/17(읽기 전용) ALL PASS. mastera6da396·86c168f→ deploy-live7b8d622, 사이트맵 미반영 0. ⏳페페 육안 1회. →projects/pfs/{handoff,rules}.md - 🆕pfs 월마감 담당자 지정 · 견적서 담당자 예외 · 월마감 금액 견적서 연동 — 운영배포 완료 [코디] 26.8.24(월) ✅. 페페 「하드코딩 아니다」 → 업체명 대신 체크박스 2종 신설(
company_member.close_manager_yn·company.estimate_manager_field_yn). 담당자 = 월마감담당 > 견적참조 폴백, 견적서는 스위치 켜진 거래처(넥서스)만 현장담당자. 금액은 조회할 때마다 견적서에서 재계산(되쓰기 없음) — 어긋나 있던 운영 11행 해소. 🔑근본원인 =SELECT h.*에 같은 이름 별칭을 얹어 DictCursor 가 계산값을 버림. 🔑실증 = 테스트에서 견적 +100만원 → 마감이 즉시 따라 움직임. 검증 신설 1종 + 회귀 3종 운영·테스트 ALL PASS. masterf5aa495+ → deploy-live6c7088f. →projects/pfs/{handoff,rules}.md - 🆕🕘PFS 시간대 전면 KST 전환 + 코디 전역 지침에 KST 규칙 — 운영배포 완료 [코디] 26.8.24(월) ✅. 메모 알람이 9시간 밀린다는 지적 → 뿌리 = EC2 OS·RDS 둘 다 UTC. 그릴링 6문 확정 후 집행 = RDS 파라미터그룹
time_zone=Asia/Seoul(무재부팅) · EC2timedatectl· 테스트 도커SET PERSIST +09:00· DATETIME 78컬럼 백필(운영 120,719행·테스트 15,968행) ·KstJSONEncoder+pfsParseDateTime. 🔑21개 API 화면이 「맞게」 보이던 건 우연이었다(Flask 가 GMT 라벨 → 브라우저가 +9). 🔴사고 =ssm_run.py는 원격에 인자를 안 넘긴다 →--dry무시되고 실집행, 즉시 원복 + audit_log 4행 PK 로 정정(잔여 0). 다운타임 4분. 검증 = 신설 검사기 2종 운영·테스트 ALL PASS + 회귀 4종 PASS. masterf318745→ deploy-livef69d3d8. 지침 =CLAUDE.md §2-3+rules/tooling.md「날짜·시각 표기」. →projects/pfs/{handoff,rules}.md - 🆕pfs 생산현황 출력 타입 카운트 = 소프트딜리트 제외 — 운영배포 완료 [코디] 26.8.24(월) ✅. qa_helper 「(3/3) 이 삭제한 타입까지 센다」 →
production_status_dao의field_typeLEFT JOIN ON 절에AND f.remove_yn < 12줄(생산현황 출력 + 월간계획표, 같은 KF 식 복사본이라 같이). 🔑WHERE 로 넣으면 INNER 가 돼 타입 0개 현장이 사라진다. 운영 영향 17개 현장. 🔑검증 함정 = 캘린더 API 가field_no를 안 내려줘 0건 대조로 조용히 ALL PASS → 커버리지 체크 선행 + 배포 전 운영 FAIL(대조군) 확인. masterf9eb62e→ deploy-livea3bc435, DDL 0. →projects/pfs/{handoff,rules}.md
🧹 pfs handoff 완료건 이관 (2026-09-03, 페페 지시 「완료처리. handoff 이관」) — 원문 그대로
handoff 162,218자 · 74절에서 완료·배포 끝난 절 63개를 원문 그대로 cut. 남긴 것 = 미결/승인대기/미배포 + 문서 구조 절. 헤딩만 한 단계 낮췄고 본문은 무변경.
🆕 26.9.3 — 오엠씨 자재관리 엑셀식 표 전면개편 ✅운영배포 완료
페페 지시 = 「/omc/material 은 현장별 분류만 · 현장 헤더 없애고 첫 컬럼에 현장명(같은 현장 병합) ·
대기·진행 / 완료 두 그룹(완료는 아래) · 우측 현장목록」 → 목업 확인 후 「형태는 완벽하다」 +
확정 3건(완료 표 기본 접힘 · 우측 숨김목록 기본 접힘 · 숨김 기능은 변경 없음 · 분류연동은 대안대로).
- 파일 1개
web/templates/basic/field/field_orderpaper.html(+234줄). 진입점 2곳만 분기 —renderGroups()→omcRender(),renderItemsHtml()→omcTablesHtml(). 🔑편집(전면/후면·발주량·입고일·비고·상태)은 기존 셀 헬퍼를 그대로 쓴다 — 헬퍼가closest('.op-site')로 cid 를 찾으므로 평면 표 전체를data-cid="omc"인.op-site로 감쌌다(복제 0). - 컬럼 = 현장(rowspan 병합·좌측 sticky)·발주처·자재·전면·후면·규격·발주량·입고일·비고·상태.
⚠발주일은 뺐다 — 넣으면 1680px 에서 상태(편집 세그먼트)가 잘린다. 되살리려면
OMC_COLS+omcCells()한 줄씩. 폭 배분 =.op-wrap1180px 제한 해제(오엠씨 화면 한정) + 비고 110px 말줄임. - 업체별 분류가 따라오던 원인 =
loadAll()안opLoadState()무조건 호출 한 줄.$(document).ready쪽은 이미if(!OP_OMC)로 막혀 있었다 → 같은 가드를 붙여 해결(메인 화면 필터도 더는 안 딸려온다). - 배포 = master
963679a…a6daeff→ 운영c420f8f(파일 1개 포워드). - 검증 =
scripts/_omc_flat_check.py [test|prod]— 분류 고정·2그룹 분리·rowspan 합=행수·완료 전그룹 접힘· 숨김목록 기본접힘·편집 컨트롤 생존·상태 컬럼 잘림 0·우측패널 화면 안·콘솔에러 0 → 테스트 101행 / 운영 23행 ALL PASS. 메인 화면 회귀 =_op_receiver_col_check.py prodALL PASS. - 목업(확정안 반영) =
http://100.108.234.45:8799/omc-material-mockup.html. - 사이트맵 = 그룹 8 · 페이지 57 · 미반영 1(
/field/worklog, 무관) —/omc/material·/field/orderpaper둘 다same. - 상세 =
session-2026-09-03-omc-material-mockup.md.
🆕 26.9.3 — 발주서정리에 입고처 컬럼 (QA 코멘트 1건) ✅운영배포 완료
페페 QA 코멘트(/field/orderpaper 입고일 <th>) = 「입고일 컬럼 옆에 입고처 컬럼 추가. 엑셀 블록에 입고처
항목이 있고 업체이름만 새 컬럼으로. 한 페이지에 입고처가 여럿인 경우가 있고, 해당 항목은 항상 입고처 라인
위쪽 항목들이며 끝은 바로 위 다른 입고처 라인이나 헤더 블록」 → 프론트만 고쳤다.
- 🔑백엔드는 손댈 게 없었다.
orderpaper.receiver(patch46, 26.8.10) + 파서_receiver_of(orderpaper-sync/orderpaper_parse.py:188)가 페페가 말한 규칙 그대로 이미 구현돼 있고, DAOselect_all_items가COALESCE(o.receiver,'') AS receiver로 내려주고 있었다. 화면에서만 안 쓰고 있었다(오엠씨 필터가 내부 사용). 운영 실측 = 1,869행 중 1,769행 적재(포인 1,497 · 오엠씨 56 · 진영LDM 48 · 월드산업 44 · 피앤알 32 · 일광금속 32 …). - 한 블록에 입고처 여러 개 = 실존 → 블록 헤더 배지가 아니라 항목행 컬럼이 맞다.
최대 사례 =
GS 오산 양산 4지구 MH | 조운IMT6종(삼성산업·오엠씨·일광 성우도장·진영LDM·포인·피앤알, 17건). - 파일 1개
web/templates/basic/field/field_orderpaper.html— ①thead 에<th>입고처</th>(비고 다음 · 입고일 앞) ②itemRow에td.op-c-rcv = esc(it.receiver||'')③opCols7/8 → 8/9 ④td.op-c-rcv{white-space:nowrap}. 좌/우는 코디 추천(왼쪽) 채택 — 입고일·상태는 편집 컨트롤이라 붙여 두고 읽기전용 텍스트를 텍스트 컬럼 쪽에 붙였다. - ⚠검증에서 한 번 헛발 = 블록마다 헤더 칸수가 다른데(오엠씨만 9칸) 첫 블록 헤더로 카드 전체를 대조해
[FAIL] 컬럼수 8 vs 9가 났다. 앱이 아니라 검증 스크립트 버그. →rules.md🆕 등재. - 배포 = master
b9043d6→ 운영4820787(파일 1개 포워드, playbook §2 선별배포 ·deploy-live는 워크트리C:\dev\pfs_deploy_wt에 체크아웃돼 있어 본 리포에서git checkout deploy-live는 실패한다). - 검증 =
scripts/_op_receiver_col_check.py [test|prod] [현장키워드](gitignore, 로컬 전용) — 헤더 위치(비고↔입고일)·셀값 == APIreceiver전건·행 colspan 합 == 헤더 칸수·완료구분행 colspan·가로넘침 0· 콘솔에러 0 → 테스트 173행 ALL PASS · 운영 57~58행 ALL PASS(운영은 다중 입고처 현장금강 부산 에코포함, 두일산업·알루피아·월드산업·포인 동시 렌더 확인). - 사이트맵 재빌드 = 그룹 8 · 페이지 57 · 미반영 1(
/field/worklog— 이번 건과 무관한 기존 차이).
🆕 26.9.1 — 거래처 목록에 주소 컬럼 (QA 코멘트 1건) ✅운영배포 완료
페페 QA 코멘트(/company/list) = 「전체 테이블 버튼만 빼고 가로폭 절약해서 주소 컬럼 추가. 팩스와 버튼 컬럼
사이, 줄바꿈해서 들어가게. 주소1 + 상세주소」 → 프론트만 고쳤다(API 무변경 — select_company_search_list
가 SELECT a.* 라 address1/address2 가 이미 내려온다).
- 파일 1개
web/templates/basic/company/company_list.html— ①table class 에서nowrap제거(DataTablesnowrap이 전 셀을 한 줄로 묶고 있었다) ②th:last-child/td:last-child만white-space:nowrap(버튼 3개 한 줄 유지) ③주소칸(nth-child(8))만word-break:break-all④주소 컬럼width:"20%". - ⚠
word-break:break-all을 전 컬럼에 걸면 전화번호가 중간에서 끊긴다(070-8865-890/8). 1차 배포에서 실측 → 주소칸에만 걸도록 좁혔다. 폭 배분은 주소에width힌트를 주는 쪽이 낫다. - 배포 = master
255b2cf+0d9efd4→ 운영67ac02c(파일 1개 포워드, playbook §2 선별배포). - 검증 =
scripts/_company_addr_col_check.py [test|prod](gitignore 대상이라 로컬 전용) — 헤더 위치·주소셀 == APIaddress1+address2·버튼 한 줄·가로 넘침 0·콘솔 에러 0 = 테스트·운영 전량 PASS. - 사이트맵 재빌드 = 그룹 8 · 페이지 57 · 미반영 1(
/field/worklog— 이번 건과 무관한 기존 차이).
🆕 NOW (2026-08-27) — 미니PC 원부자재발주서 「거래처 DB 연결」 미갱신 복구 · rdstunnel ⏳페페 1클릭 남음
페페 지시 = 「nas 원부자재발주서를 미니pc에서 편집하는데 거래처 db연결한게 업데이트가 안된다. 이유 확인 및 보완 처리」.
「거래처 DB 연결」의 실체 = 파워쿼리 업체목록(Odbc.Query("dsn=pfs", …pfs.company JOIN company_member…)) → 「업체」 시트 표.
원인 3겹(엑셀은 무죄) — ①미니PC에 MySQL ODBC 드라이버·DSN pfs 부재(OAlerts 21:15 IM002)
②미니PC 공인IP 211.177.244.214(집 회선)가 RDS SG 3306 밖(직접 프로브 12초 타임아웃=DROP)
③파워쿼리 자격증명 저장소에 엉뚱한 계정 imosadmin(OAlerts 22:22 Access denied for 'imosadmin'@'172.31.35.211').
처리 — ①Connector/ODBC 26.7 x64 무인설치 ②SG 무변경으로 EC2 SSM 포트포워딩 상주터널 신설
C:\dev\tools\rdstunnel(엑셀→DSN pfs→127.0.0.1:13306→EC2 172.31.35.211→RDS, 자동시작 PFS-RdsTunnel,
SSM 20분 유휴차단 대비 5분 keepalive) ③잘못된 자격증명 백업 후 제거.
검증 = 터널 핸드셰이크 77바이트 · rdstunnel.py test 391행 한글 정상.
✅22:44 페페 자격증명 1회 입력 완료 → 서로 다른 4개 파일(표준양식·08·07·01월) 사본 새로고침 전부 OK
→ 392행/첫행 한샘(=헤더1+391, DB 실측 일치). NAS 발주서 109개 중 108개가 동일한 dsn=pfs →
자격증명은 「전역 권한」(사용자 프로필 1곳)이라 1회 입력 = 전부 적용, 파일 수정 0건.
상세 = session-2026-08-27-rdstunnel-orderpaper-vendor-query.md.
(이전) 2026-08-26 — 한샘 전용 견적 모듈 신설 ✅운영배포 완료
[페페] 「pfs에 견적서 목록(한샘)을 생성해줘. 견적 양식 및 단가표 데이터 db추가해서 작성할수 있게. 엑셀파일도 올려서 엑셀파일에 넣는 형식으로. 기존 견적서 양식으로 한샘분 제작은 그대로 유지, 별도로 새 양식과 단가표 관리해서 운영. 운영배포.」 → 그릴링 5차(결정 12건) 후 착수.
- 왜 별도 계통인가 = 계산체계가 다르다. 포인
자당(300mm)×부위비율×마진vs 한샘폭/10×단가×유형배수×적용률. 기존estimate계통은 코드 변경 0. - 🔑금액을 PFS 가 엑셀에 쓰지 않는다 — 치수·마감·등급·적용률과 단가표만 양식 사본에 주입하고,
금액은 파일 안 LOOKUP 체인(단가기준→백데이터→내역서 6탭→갑지)이 계산한다. 한샘이 열어 검산할 때 수식이 보인다.
목록 총액만
hansem_calc가 같은 식으로 따로 낸다(참고값). - 신설 = 테이블 8(
hansem_price_book/price/finish/furn_type/form/estimate/estimate_type/estimate_detail) · 화면 3(/estimate/hansem/list|regist|price) · API 10(/api/hansem/*) · 메뉴 3(display_order 140~142). 마이그레이션migrations/patch47_hansem_estimate.sql(멱등, 시드 = 마감 12 · 유형 14 · 2019 판 단가 192칸[값 156]). - 엔진
api/pfs/hansem/hansem_excel.py— openpyxl 로 load→save 하면 이미지 10·도형 9·메모·x14 데이터유효성이 사라져서 zip XML 외과수술로 간다. 값 셀만 쓰고 수식 셀은 안 건드리며, 낡은 캐시<v>를 지우고fullCalcOnLoad로 재계산시킨다. 평형명은A4한 칸만 쓰면 E2·A54·갑지 A19~A21 이 따라온다. 지원 평형 수 = 양식이 가진 내역서 쌍 수(초과하면 막는다 — 런타임 탭 복제 안 함). - 검증 = ①서버계산 vs 엑셀 캐시값 48/48 원 단위 ②왕복 동일성 582/582 ③구조 보존(이미지10·도형9·파트82) ④E2E(양식 업로드→아산 실데이터 견적→엑셀 수신) 총액 20,818,331 일치 · 입력셀 291/291 — 테스트·운영 양쪽 ⑤사이트 점검 화면3+API5 테스트·운영 8/8 ALL PASS.
- 배포 = master
2d16739+8c5ac83+dcd61c8→ 운영b3fbba9(파일 19개 선별 포워드). merge 안 쓴 이유 = deploy-live 미반영 커밋이 138건이라 통째로 끌려온다. 진입점 2파일 (api/config.py·web/__init__.py)은 deploy-live↔master 차이가 한샘 등록 4줄뿐임을 확인하고 넘겼다. 운영 RDS patch47 적용 완료 · E2E 흔적 hard delete(견적 0 · 양식 1 활성 · 단가 192칸). 사이트맵 재빌드 = 그룹 8 · 페이지 54→57 · 미반영 0. devplanhansem-estimate.html+ 허브 카드 등록. - ⚠배포 중 걸린 사고 2건 = ①
MySQLUtil.execute가 빈 파라미터에도 포맷을 돌려 SQL 리터럴%에서 워커 사망 ②pymysql DECIMAL → jsonify 500. 둘 다rules.md🆕 등재. - ℹ양식 자체 결함 발견(안 고침) = 수납 내역서의 파우더장·픽스도아는 단가행 라벨이 「단가 (50%)」인데 수식엔 배수 없음(×1), 공틀도어는 라벨 없이 ×0.7. 주방은 전부 일치. 수식을 정본으로 시드했고 유형 마스터에서 고칠 수 있게 뒀다.
- ⏳페페 = ①운영 육안 1회(
/estimate/hansem/price단가표·양식 →/estimate/hansem/regist실견적 1건 → 엑셀) ②옵션 7,148,000 배분 규칙 결정(2차 착수 전제 — 자재비 실비/적용률 상향/등급 상향 중). - 2차(미착수) = 자재비·운반비·추가분견적 탭 · 기존 견적 전환 도구 · 평형 4개 이상 확장 양식 · 월마감 편입 여부.
🆕 실견적 3건 등록 (2026-08-26 후속) ✅
페페 「2개 견적서 한샘 양식으로 작성했어? 목록에 안보인다」 → 그때는 그릇만 있었다(0건). 지금 운영 3건.
| no | 견적명 | 서버총액(본오더) | 비고 |
|---|---|---|---|
| 1 | 라인 아산7차(리뉴얼) M/H 생산비 26년 06월 | 20,818,331 | 원본 거래명세서 재현 · field_no 없음(현장 미등록) |
| 2 | GS 원주 단구 MH — 한샘양식 V2 (치수기준) | 17,370,850 | 적용률 전 행 1.0 · 옵션 미반영 · field_no 2169 |
| 3 | GS 원주 단구 MH — 한샘양식 V1 (옵션 배분) | 22,193,970 | 행별 적용률 상향(최대 1.8810) · field_no 2169 |
- 페페 결정(26.8.26) = 「GS원주는 견적목록 V1·V2 2가지로 생산한다. V1은 추천(3분류)대로, V2는 금액차 상관없이 치수 기준으로만」.
- 3분류 배분(V1) = ①유리류 2,325,000(유리도어 1,520,000·유리선반 605,000·유리 200,000) → 자재비 탭 실비 별도(생산비 미포함) ②판넬류 3,168,000(EP 6종 1,805,000·픽스판넬 360,000·후면장 373,000·후면픽스 60,000·메지판 90,000·12T휠라 300,000·9T쫄대 180,000) ③하드웨어·식세기도어 1,655,000(HK-TOP 800,000·플랩암 450,000·언더레일 150,000·밥통장레일 75,000·식세기도어 180,000) → ②③ 4,823,000 은 행별 적용률 상향으로 생산비 흡수. 생산비 22,193,970 + 유리 자재비 2,325,000 = 24,518,970 (포인 763 행총액 24,327,000 대비 +191,970). ⚠등급은 D가 상한이라 「등급 상향」은 물리적으로 불가 — 전부 적용률 레버로만 흡수했다.
- 763 → 한샘 매핑(스크립트
scripts/_hansem_from_est.py, 763 21행 전부 주방·수납 0행): 상부장·장식장 상부장·후면 유리하부장 → b4 / 하부장·장식장 하부장 → b11 / 아일랜드 하부장 → b25 오픈장 (양식 원본 세트라벨이C(아일랜드)라 근거 있음. b11 과 단가군·배수 동일이라 금액 무관) / 장식장 키큰장·냉장고장·가전소물장 → b32 / 팬트리도어 → b46 공틀도어(KIT_TALL×0.7). 평형 슬롯 3개 =84A/84C/84C(F)(763 의 type_name + field_type. K=주방·F=일반). 🔑치수분이 이전 보고(16,648,450)보다 722,400 크다(17,370,850) — 팬트리도어를 상하부장×0.7 로 봤던 게 오류고, 양식 수식 정본은 키큰장×0.7 이다. - 🔴엑셀 산출물엔 아직 양식(아산) 잔존값이 섞인다 — 자재비 5,654,155 · 운반비 1,060,000 · 추가분 1,010,000 · 시공비 리터럴 12,930,000 · 절사 5칸이 갑지에 그대로 뜬다. 1차 범위가 「본오더 내역서」뿐이라 그렇다. 아산(견적1)은 원본 재현이라 오히려 맞고, GS(견적2·3)만 틀리다. → 2차 과제(자재비·운반비·추가분 탭) 또는 빌드 시 0 처리. ⏳페페 결정.
- ⏳운영배포 대기 = master
dd677a7(탭 rename 교차 버그 수정). 배포 전까지 운영에서 GS 엑셀을 받으면 탭이 교차된 파일이 나온다. 로컬 검증은 끝(scripts/_hansem_local_build.py). - 검증 도구 신설 =
scripts/_hansem_from_est.py(763→한샘 등록) ·_hansem_local_build.py(운영배포 전 로컬 산출·구조 점검) ·_hansem_state.py(현황) ·_hansem_field_find.py·_est763_table.py.
(이전) 2026-08-26 — 한샘 단가표 전환 현황파악(보고만) + 한샘 양식 xlsx 외부링크 정리 ✅
[페페] ①「기존 견적(GS 원주 763)을 한샘 신규 양식에 맞춰야 한다. 한샘 단가표가 기존보다 금액이 적다.
추가금액·옵션금액 규칙을 확인해 손실 최소로 옮길 방법을 찾아야 한다. 우선 치수만 반영해 금액차를 본다 —
이번엔 실제 작업 없이 현황 보고만」 ②「양식 파일 수식이 외부 디스크 경로를 참조한다 → 파일 내 단가기준
탭 참조로 고쳐라. 동일폴더에 새폴더 만들어 원본 백업」 ③당장 안 봐도 되는 탭 = 추가분견적·자재비·운반비·가격적용분.
① 현황 (보고만 · 코드/DB 변경 0)
- 한샘 계산식 =
폭(mm)/10 × 단가(원/10mm) × 적용률. 단가는 가구유형 × 마감 12종 × 등급 A~D 매트릭스 (단가기준탭). 주방 벽장·밑장 2500~3900 · 키큰장 5300~8400 · 수납 일반장 6100~9000 · 낮은장 4000~5900. 등급 = 도어사양(A평판 / B투톤·매입손잡이·메지홈 / C자체손잡이·AL1면·휘모·후레임 / D AL4면엣지바·AL후레임·슬라이딩). 단가 배수 = FIX PANEL 50% · 공틀도어 70%. 적용률 = 도어만 30% / 바디일부 50% / 도어+바디 70% / 전체 100%(수기). - 포인 계산식(pfs) =
(Σ치수−Σ코너)/300 × 자당단가 × 부위비율 × (1+마진)천원 올림 + Σ추가금액. →rules.md💰항목. - 763 실측 = 21행 · 유효폭 37,755mm(125.8자) · 행총액 24,327,000(= 자당몫 17,179,000 + 추가금액 7,148,000)
- 시공비 6,500,000 + 운반비 400,000 = 31,227,000. 자당단가 원/10mm 환산 = 상부 3,583 · 하부 4,163 · 냉장고장 4,583 · 팬트리도어 4,600 · 키큰장/가전소물장 8,337.
- 치수만 반영한 금액차(PUR계열, 적용률 100%·공틀도어 70%): A 11,684,100 / B 13,000,650 / C 13,878,350 / D 16,648,450. 🔑D등급이면 포인 자당몫(17,179,000)과 −530,550(−3.1%) 밖에 차이가 없다 — 단가표 자체는 거의 같다. 행총액 대비 −7,678,550(−31.6%) 인 것은 전부 추가금액 7,148,000 이 한샘 생산비 단가표에 자리가 없어서다.
- 손실의 실체 = 옵션(추가금액) 7,148,000(행총액의 29.4%) — 유리도어 1,520,000 · EP 810,000 · HK-TOP 800,000 · 유리선반 605,000 · 플랩암 450,000 · 아일랜드EP 420,000 · 후면장 373,000 · 픽스판넬 360,000 …
- 한샘 양식의 청구 경로 3개 = 생산비(단가표) · 자재비 탭(보드·엣지·유리·거울·AL엣지바/손잡이바/후레임도어 실비, 단가표 비고 「수입경면·무늬목·허니컴 = A단가 평균×50% 자재비 별도」가 근거) · 추가분견적 탭(본오더 이후 설계변경·재생산·샘플 등 사후 발생분, 옵션 정가표 아님). ⚠자재비 탭에 하드웨어(블럼 플랩암·HK-TOP·레일)는 없다 → 유리·AL 은 자재비로 넘길 여지가 있으나 하드웨어·EP·픽스판넬은 아직 갈 곳이 없다(다음 결정 사항).
- ⏳다음(설계 판단 필요) = ⓐ GS 원주 도어사양 → 한샘 등급 확정(D 가정 시 −3%) ⓑ 옵션 7.1M 배분 규칙 (자재비 실비 / 적용률 상향 / 등급 상향 중 택) ⓒ 그 뒤에 치수 자동전개. 착수 시 그릴링 + 계획 3단계 대상.
② 양식 xlsx 외부링크 정리 (실작업)
- 대상 = NAS
2026현장\견적\넥서스\한샘 견적 양식(가구,시공)\1.생산비 거래명세서_라인건설 아산테크노밸리_26년 06월.xlsx - 외부링크 정의 13개 중 실제 수식이 쓰던 건 2개뿐([11]=
…\한샘\2019년\8월\…\롯데광명철산 생산비.xlsx, [13]=…라인 아산테크노밸리 MH 수납 거래명세표 260604.xlsx). 나머지 11개는 유령(A:\·\김석곤부장\… 등). - 고친 것 = ①내역서 6탭(77/84A/84B × 주·수)의 LOOKUP 276곳에서
[11]접두 제거 → 같은 파일의백데이터(건들지마세요!!)탭 참조 ②그 백데이터 C열 156셀을=단가기준!D7식으로 바꿔단가기준탭이 단일 출처가 되게 함(값 변경 0 — 156셀 전수 대조 일치, 빈칸 36은 원래 빈 수입경면 B~D) ③fullCalcOnLoad+ calcChain 폐기. - 🔑openpyxl 로 다시 쓰지 않았다 — 이 파일엔 이미지 10·도형 9·메모·데이터유효성 확장이 있어 재저장하면 깨진다.
zip 안 XML 만 외과수술(
fix_links.py). 파트 109→108(calcChain 만 빠짐), 바뀐 파트 10개. - 검증 = LOOKUP 17셀을 로컬 백데이터로 재현 → 전부 일치 · 캐시 총액 유지(주방 17,479,999.5 / 수납 11,050,000.2) · 워크시트에 남은 외부참조 1건 · NAS 파일 md5 = 로컬 산출물과 동일.
- ✅2차(같은 날, 페페 「파일 닫았어. 재검토 + 두 탭 단가 일치 확인」) — 전수 대조 + 외부링크 완전 제거
- 백데이터 ↔ 단가기준 전수 대조 = 일치 156 · 빈칸 36 · 불일치 0. 라벨(마감 12종 × 등급 A~D)·수식 대상셀· 캐시값 3중 대조. 역방향도 확인 — 단가기준 단가영역 값셀 68개 전부 백데이터가 참조, 빈칸 12개(수입경면·무늬목· 허니컴의 B~D)도 서로 일치. 내역서 6탭 LOOKUP 92셀 로컬 재현 전부 일치.
수납!O34정체 판명 = 자재비·운반비 탭은 현장 전체 합계(자재비 5,654,155 / 운반비 1,060,000)이고 주방 시트가 그 전액을 이미 가져간다(주방!O32=자재비!H124,O33=운반비!I18). 즉 수납 칸에 연결하면 이중 계상이다 → 바로 위수납!O33(자재비) 처럼 빈칸이 맞다. 값이 이미 0 이라 금액 영향 0.- → 죽은 수식 제거 후 외부링크 잔재 전부 삭제 : externalLink 파트 13개(+rels 13) ·
externalReferences블록 · Content_Types Override 13 · 외부파일을 가리키는 definedName 26개(전부 미사용, 대부분 이미#REF!— 워크시트 수식·데이터유효성에서 쓰이는 것 0건 확인 후 삭제). 이제 엑셀이 「링크 업데이트」를 안 묻는다. - 파트 108→82 · 바뀐 파트 4개 · 탭 15개 유지 · 총액 불변(주방 17,479,999.5 / 수납 11,050,000.2 / 생산비총 28,529,999.7 / 생산비+시공비 41,459,999.7) · 남은 외부참조 0건 · NAS md5 대조 일치.
- ✅3차(같은 날, 페페 「외부 데이터 연결 메시지 아직도 뜬다」) — 진범 = x14 확장 데이터유효성
링크 정의를 다 지웠는데도 경고가 남은 이유 =
<extLst>안<x14:dataValidation>4건이 드롭다운 목록을 절대경로 다른 통합문서로 잡고 있었다 — 주방(H34:K34 D32:G34)·수납(H35:K35 D33:G35)은D:\0.박진수-pc\…\[201804 롯데 청량리_생산비(나움).xlsx]Sheet3'!#REF!, 추가분견적 주방(K3 F22:G22 G8)· 일반(K3)은G:\영업\…\[라인 광주일곡 MH 거래명세표 .xlsx]Sheet3'!#REF!. 전부 이미#REF!= 죽은 목록. 🔑openpyxl 은 이걸 못 본다(로드 시 경고만 찍고 버린다) → zip XML 직접 grep 으로 찾았다. →rules.md🔴. - 각 시트의
<extLst>는 이 항목 하나만 담고 있어 블록째 제거(4파트만 변경, 파트 수 82 유지). - 남는 일반 데이터유효성은 그대로 — 내역서 6탭의 마감 12종 목록·
"A,B,C,D"등급 목록 살아 있다. - 사라지는 것 = 위 4곳의 드롭다운(원래
#REF!라 아무것도 안 뜨던 것). 셀 값·서식은 그대로. - 재검증 = 백데이터↔단가기준 156/0 · LOOKUP 92셀 일치 · 총액 불변 · 외부 흔적 0건
(
[n]·[파일.xlsx]·TargetMode="External"전 파트 스캔). NAS md53920c11d…대조 일치. - 유일하게 남은 경로 문자열 =
workbook.xml의x15ac:absPath(마지막 저장 위치 힌트) — 링크 아님, 경고와 무관. - 백업 = 같은 폴더
_원본백업_2026-08-26\(md5 원본과 동일). ⚠파일에~$…잠금(소유자poinpc)이 있어 첫 덮어쓰기가Device or resource busy로 막혔다 — 임시명 write + rename 으로 넣었다(원자적 교체).
(이전) 2026-08-26 — 에넥스 금호 구미 견적 3차수 작성 + 엑셀 3종 NAS 저장 ✅운영 완료 (코드변경 0)
[페페] estimate/modify-v2/764 본건 작성 후 = 「총 3개 견적서 엑셀 파일 작성. 1차=현재건 24,058,000원 /
2차=전체 마진율 20% 각 항목 조금씩 조정해 1900만원 약간 초과(목표 1900만) / 3차=2차 기준 5% 인상.
pfs 에도 차수별로 저장하고 비고에 수정내용 저장. 엑셀은 NAS 2026현장\견적\09월\에넥스\금호 구미 견적 에.
운영배포 작업건이다」 + 추가 2건 = 「3차는 퍼센트 조금 더 올려 2000만원을 조금 넘게, 파일명 퍼센트는
소수점 없이 정수로」 · 「전체 파일 모두 운임은 건드리지 않는다」.
- 해석 결정(페페 확인받음) = 「전체 마진율 20%」 = 할인 20% =
margin_percent -20. 근거 = 이 견적의 추가금액이 이미 −20% 를 할인으로 쓰고 있었고, 플랫 −20% 를 걸면 총액이 19,009,000 원 = 「1900만원 약간 초과」에 원 단위로 떨어진다(단가·추가금액·운반비 손 안 대고). 3차는 페페 지시로 마진율 −14% 계산식 + 파일명은 (5) 표기(규칙 외 명명) 로 확정. - 차수(운영 DB) — 앱의 재작성 API(
POST /api/estimate/<no>/rewrite {copy_items:'1'})로 만들었다. | 차수 | 견적번호 | 이름 | 마진율 | 항목합계 | 운반비 | 총액 | 상태 | |---|---|---|---|---|---|---|---| | 1차 | 764 | 금호 구미 MH 견적서 | 자동 10 | 23,608,000 | 450,000 | 24,058,000 | 보관 | | 2차 | 765 | 〃 (2차) | −20 | 18,559,000 | 450,000 | 19,009,000 | 보관 | | 3차 | 766 | 〃 (3차) | −14 | 19,570,000 | 450,000 | 20,020,000 | 보관 | | 4차 | 767 | 〃 (4차) | +24 | 25,962,000 | 450,000 | 26,412,000 | 사용 중 | 비고(estimate.comment)에 차수별 수정내용 저장 — 마스터 비고는 엑셀에 안 나간다(엑셀 비고 3줄은 고정문구)라 내부 메모로 안전하다. 운반비 450,000 은 3차수 전부 동일(지시대로 미변경). - 4차 추가 지시(같은 날) = 「1차 금액 기준 10% 인상, 파일이름에도 동일하게 (10)」. 정수 마진율 중 +24% 가 1차 항목합계 대비 +9.97%(목표 25,968,800 대비 −6,800원)로 가장 근접 → 파일명 (10) 과 정합. (24.1% 면 +10.05% 지만 소수 마진율이라 채택 안 함.)
- 엑셀 4종 = NAS
\\192.168.0.101\공유폴더\2026현장\견적\09월\에넥스\금호 구미 견적(md5 대조 일치)…견적서(원본단가).xlsx(1차) ·…견적서.xlsx(2차) ·…견적서(5).xlsx(3차) ·…견적서(10).xlsx(4차) ℹ️2026-08-26 4차 저장 시점에 2차 파일이…견적서(최종).xlsx로 이름이 바뀌어 있었다(페페가 손댄 것으로 보임, 그대로 둠). - 검증 = ①계산식 재현으로 1차 20행·총액이 원 단위 일치 ②복사본을 원본과 전 컬럼·전 sub 대조(PASS)
③엑셀 실파일에서 상세블록
수량×단가합 + 물류비 = 총액 3파일 ALL PASS. - 🔑새 규칙 3건(계산식 단일출처 ·
estimate_detail컬럼/FLOAT 함정 · 엑셀 단가=SET단가·파일명 quirk) =rules.md🆕. - 코드 변경 0 · DDL 0 → 배포·사이트맵 재빌드 대상 아님.
(이전) 2026-08-26 — 견적 v2 행 UI 3건 (치수 블록선택 · 폴딩 아이콘 · 분류 드롭다운) ✅운영배포 완료
[페페] qa_helper(/estimate/modify-v2/764) 3건 = ①「치수칸, 코너칸 클릭시 데이터가 있는 경우 블록으로
잡히게 해줘. 수정시 바로 숫자입력으로 덮어쓸수 있게」 ②「폴딩 아이콘을 전체 1개의 아이콘으로 변경해줘.
현재 아이콘 세모 모양이 정중앙이 아니다. 세모모양과 프레임조합으로 보인다. 디자인적으로 별로임. 허용된
범위안에서 크기를 최대한 키워줘. 클릭하기 편하게. 추가금액 항목이 있는 경우 버튼의 컬럼 배경을
사이안계열로 변경해줘」 ③「글씨 크기 1포인트 키워주고 색상 좀 더 진하게. 드롭리스트 글씨 가로 안잘리게
리스트 프레임 확장. 리스트 스크롤 없이 전체 목록 보이게」 + 「전체 작업내용 모두 운영배포 진행」
- 고친 것 = 2파일 +39 −12줄(
web/static/css/estimate_regist_v2.css·web/static/js/estimate_regist_v2.js). 서버코드 0 · DDL 0 · DB 변경 0. - ①클릭 즉시 블록선택 = 위임 한 줄
$(document).on('focus click', '.dim-cell, .corner-cell', …)에서 값이 있으면select(). 🔑focus만 걸면 안 된다 — 마우스 클릭은 focus 뒤에 mouseup 이 따라와 선택을 캐럿으로 풀어버린다.click은 mouseup 다음이라 최종 승자다(탭·방향키 이동은 focus 가 담당). 🔑type=number는selectionStart를 못 읽지만(Chrome 이 null)select()자체는 동작한다 — 실측으로 확인하고 갔다. 본문·모달(#itemModal)·계산기(#calcFrame) 가 같은 클래스라 한 줄이 전부 덮는다. - ②폴딩 아이콘 =
▶글리프 + 1px 테두리 상자 조합을 버리고 border 로 그린 CSS 삼각형::before하나로.inset:0 + margin:auto라 기하학적 정중앙(실측 좌우 8=8 · 상하 6=6) — 글리프 메트릭 치우침이 애초에 없다. 크기는 18 → 26px: 🔑칸 폭 30px 은columnSettings(사용자별 DB 저장)라 건드리면 기존 사용자에게 안 먹는다 → td 패딩을 9/8 → 4/2 로 줄여 같은 폭 안에서 버튼을 키웠다. 펼침 표시는 종전 그대로 90도 회전(색만--primary). - ②추가금액 사이안 =
cellForCol('twirl')이subs.length > 0이면 td 에has-sub→ 배경#cdf0f7. sub 추가/삭제가renderDetailTable()을 부르므로 접힌 상태에서도 자동 동기된다(별도 배선 0). - ③분류 칸 = input 12 → 13px, 색은 td 상속
--ink-2→--ink(굵기는 안 건드렸다 — 페페 UI 규칙 = 강조는 색으로만). 드롭다운은right:0을 빼고width:max-content+min-width:100%(칸 폭 48px 에 묶여 항목명이 잘리던 것) +max-height:220px제거 → 공통코드 15종이 스크롤 없이 한 번에(450px). - 검증 = 신설
scripts/_est_qa826_ui_check.py [test|prod] [견적번호]— 테스트(707) 36/36 ALL PASS · 운영(764) 읽기전용 37/37 ALL PASS. 운영에서 추가금액 3행 사이안rgb(205,240,247)· 없는 1행 흰색까지 같이 잡혔다. 회귀 =_dim_wheel_check(휠 가드) ·_size_unit_check(치수 mm 자동부착) ·_actcol_vert_check(액션열) 테스트·운영 전부 0 FAIL, 콘솔 0. - 배포 = master
abf3e36→ deploy-liveb83d8c6(2파일 선별 포워드,--detach워크트리). 포워드 전git diff origin/deploy-live origin/master -- <2파일>이 내 커밋 diff 와 바이트 동일함을 확인하고 넘겼다(그 파일에 걸린 미반영 커밋 11개는 전부 이미 반영돼 있었다). 사이트맵 = 그룹 8 · 페이지 54 · 미반영 0.devplan/pfs.htmlDONEAE등재. - ⚠따로 발견(내 변경 아님, 손 안 댐) = 항목표 헤더에
drag·twirl이 영문 그대로 노출된다.labelForCol()이labels[key] || key라 라벨이 빈 문자열('')이면 폴백이 키 이름을 찍는다 (drag:'', twirl:''). 지시 범위 밖이라 안 고쳤다 — 고치려면|| ''분기 한 줄. - ⏳페페 = 운영 육안 1회(
/estimate/modify-v2/764→ 치수칸 클릭 · 폴딩 아이콘 · 분류 드롭다운).
🆕 NOW (2026-08-25 · 7차) — 견적 현장검색 모달에 상차일 미확정 노출 + 맨 위 ✅운영배포 완료
[페페] qa_helper(/estimate/regist-v2, #btnFieldSearch) 「견적용 현장 모달에서 리스트에 상차일
미확정분이 나오지 않는다. 상차일 미확정분도 나오게 하고, 순서상 리스트 상단에 배치시켜라. 운영배포」
- 🔑원인은 정렬이 아니라
WHERE절이었다. 5차(현장목록)는 정렬만 고치면 됐지만 여기는select_site_search의AND f.shipping_date >= date_from이 NULL 을 통째로 걸러내 미확정 현장이 결과에 아예 없었다(모달 기본 = 1개월 전~무제한). 같은 함정을 이미 두 번 고쳤는데 (생산현황 리포트 SQL = 배포X· 현장목록 검색 = 배포Y) 견적 현장검색에 한 곳 남아 있었다. - 고친 것 = 2파일 +12 −4줄. ①DAO 기간조건 2개를
(f.shipping_date IS NULL OR …)로 감싸고 ②ORDER BY (f.shipping_date IS NULL) DESC를 맨 앞에 —LIMIT 50이라 정렬을 안 바꾸면 미확정이 꼬리에서 잘려나간다(WHERE 만 고치면 반쪽) ③프론트siteSortCmp는 상차일 키에서 빈 값을 정렬 방향과 무관하게 맨 위(헤더로 오름/내림 뒤집어도 상단 유지) ④fmtShipDate('')= 「미확정」 표기 — 종전엔 빈 칸이라 맨 위에 와도 뭔지 안 보인다. 서버 DDL 0 · DB 변경 0. - 같은 API 를 쓰는 다른 화면도 함께 고쳐졌다 = AL발주서 현장명 드롭리스트(
al_orderpaper.js)· 자재관리 현장목록(orderpaper_material.js). 둘 다 빈 상차일을 이미 안전하게 처리해서 회귀 0 (_al_combo_check테스트·운영 ALL PASS 로 확인). - 검증 = 신설
scripts/_estimate_site_tbd_check.py [test|prod]— 테스트 22/22 ALL PASS (상차일 없는 임시 현장 1건 생성 → 검색결과 최상단 확인 → 소프트삭제), 운영 읽기전용 17/17 ALL PASS (미확정 3건 = 금호 구미·GS 원주 단구·롯데 화성 향남 이 표 맨 위 3행 「미확정」, 4행째부터20260916내림차순, 정렬 뒤집기·초기화에도 상단 유지, 콘솔 0). 회귀 =_al_combo_check테스트·운영 ALL PASS ·_ship_tbd_check테스트 ALL PASS. - 배포 = master
ac24be5→ deploy-live845285e(2파일 선별 포워드,--detach워크트리). 사이트맵 = 그룹 8 · 페이지 54 · 미반영 0.devplan/pfs.htmlDONEAD등재. - ⏳페페 = 운영 육안 1회(견적 등록 → 🔍 검색 → 맨 위 3행이 「미확정」).
🆕 NOW (2026-08-25 · 6차) — 거래처 개명: 넥서스 → 한샘 ✅운영배포 완료
[페페] 「pfs 업체명 변경을 한다. "넥서스"를 "한샘"으로 변경하고 관련 지침에서 용어 교체를 같이해서 시스템에 오류가 안생기도록 해라. db수정도 승인한다. 운영 배포」
- 그릴링 6문 페페 확정 = ①범위 = 마스터+화면 키만(과거 표시텍스트·실물참조 제외) ②발주서 동기화는
파서에서 정규화 ③표기 =
한샘/ 출력(주)한샘④과거 마감표는 8월분부터만(1~7월은 당시 사명 보존) ⑤안전장치 = 롤백 스크립트 + RDS 스냅샷 ⑥지침문서는 치환 + 최초 1회 「구 넥서스」 병기. - 🔑가르는 기준 = 「실물이 같이 바뀌었나」. 상세 규칙·목록 =
rules.md🆕 맨 위. 바꾼 것 =company.name(company_no=1 — 현장 825건·담당자 22명이 FK 로 자동 추종) ·orderpaper.furniture_company·orderpaper_site_map·monthly_close.company_name(2026-08 만) ·vendors.json. 안 바꾼 것 = NAS 파일명 · 카톡방명 · 녹음파일명 · 통화원문 ·estimate_name·field.name·worklog.site_name·nexus_close_form.xlsx· 적용완료 마이그레이션. - 🔑함정 1 — DB 만 고치면 되돌아간다.
orderpaper_sync가ON DUPLICATE KEY UPDATE furniture_company=VALUES(…)로 매 동기화마다 파일명 파싱값으로 덮고, 도어발주서는 H6 셀을 재파싱한다. NAS 파일명은 옛 사명 그대로다. →orderpaper_parse._COMPANY_ALIAS(단일 출처,door_order_parse가 import) 에서 적재 시점 정규화._KNOWN_COMPANIES엔 옛 이름을 남겨 옛 파일명이 계속 파싱되게 했다. 순서 = 파서 먼저, DB 나중 — 자동동기화가 로컬 실행(30분 주기)이라 파서를 고치는 순간 발효돼 동기화를 멈출 필요가 없다. - 🔑함정 2 —
vendors.json은 거래처에 「없는 이름만」 보충하는 폴백이다. 마스터만 바꾸면 스냅샷의 옛 이름 18행이 중복제거를 피해 AL발주서 자동완성에 유령으로 남는다 → 같이 교체. - 코드 = master
b1ef589→ deploy-livea449d3e(22파일 선별 포워드,--detach워크트리). 전 파일deploy-live↔master차이가 내 변경뿐임을 파일별 diff 줄수 대조로 확인하고 넘겼다. DDL 0. - DB(SSM
scripts/_hanssem_rename_apply.py, 파일 내 상수EXECUTE게이트) = 운영 company 1 / orderpaper 1561 / site_map 18 / monthly_close 1(2026-08) · 테스트 1 / 1382 / 16 / 5. RDS 스냅샷pfs-pre-hanssem-20260825(03:02Z=12:02 KST, available 확인 후 집행). 롤백 =scripts/_hanssem_rename_rollback.py(역조건 UPDATE — 변경 전 '한샘'이 4개 컬럼 전부 0건이라 행단위 백업이 필요 없다. ⚠롤백은 파서 정규화 제거가 먼저다). - 검증 = 신설
scripts/_hanssem_rename_check.py [test|prod]— 테스트 16/16 · 운영 20/20 ALL PASS (업체필터 2종·월마감 거래처목록·운영 2026-08 마감행+시공비 컬럼·2026-07 은 「넥서스 (9)」로 보존· AL발주서 vendors 유령 0·자재관리 datalist·생산현황 색상맵·콘솔 0). 회귀 =_field_list_qa5_check테스트·운영 ALL PASS ·_monthly_close_ui_check테스트 19/19·운영 19/19 ·_ship_tbd_check테스트 ALL PASS ·_field_status_print_ivision_checkALL PASS ·test_monthly_close_excelALL PASS ·test_door_order_parse8/8 · 견적서 A6 접두 단위검사 7/7. - 실증(가장 중요) = 파서 수정 뒤 자동동기화가 실제로 1회 돌았고(round
R1787627337≈ 12:09 KST, prod, 50파일 1861항목) 그 직후 운영/api/orderpaper/all-items업체별 집계 = 한샘 1276 / 넥서스 0. NAS 파일명이 아직 옛 사명인데도 되돌림이 없다는 게 확인됐다. - ⚠선반영 발견(내 변경과 무관) =
_mc_aug_row_ui_check.py가 운영 2 FAIL — 추가금액·합계 기대값이 2026-08-24 「월마감 금액 = 견적 실시간 재계산」 배포 이전의 굳은 값이었다(추가 6,295,000/합계 28,975,000). 견적 실측(735 total 20,370,000·시공 8,000,000 / 753 total 10,467,000·시공 2,310,000)과 화면이 정확히 일치 → 고정숫자를 항등식 대조로 교체(8/24 에_monthly_close_ui_check에 한 것과 같은 교정). 재실행 10/10 PASS. - 사이트맵 = 그룹 8 · 페이지 54 · 미반영 0.
devplan/pfs.htmlDONEAC등재. - ⏳페페 = 운영 육안 1회(현장목록/견적목록 업체 필터 「한샘」 · 견적서 출력 A6 「(주)한샘」).
🆕 NOW (2026-08-25 · 5차) — 현장목록 상차일 미확정을 맨 위로 ✅운영배포 완료
[페페] 「pfs 현장 목록에서 상차일 미확정분이 리스트에서 안 보인다. 정렬순서 규칙때문인데, 미확정분을 목록 상단으로 기본 배정해줘. 운영 배포」
- 🔑원인 = 3차에서 상태 그룹 정렬을 롤백하며 정렬이 「상차일 내림차순 한 줄」로 돌아갔는데, 내림차순에서 빈 값(미확정)은 맨 뒤다. 운영 129행이면 7페이지째로 밀려 사실상 안 보였다. 2차 정렬은 미확정을 0번 그룹으로 맨 위에 뒀었는데, 롤백이 그 효과까지 같이 걷어간 것이다.
- 고친 것 =
field_list.html한 파일(+13 −3줄).fieldListOrder(a, b)부활 — 다만 이번엔 상태를 안 본다: 미확정 여부 먼저(미확정이 앞) → 상차일 내림차순 → 미확정끼리는field_no내림차순. 「진행현장」 토글의 오름차순 분기는 빈 값이 원래 맨 앞이라 안 건드렸다. 서버코드 0 · DDL 0 · DB 변경 0. - 3차에서 뺀 「대기중/진행중/완료」 상태 그룹 정렬은 여전히 없다(검사로 고정) — 상태는 표 위 탭으로 고른다.
- 검증 =
_field_list_qa5_check.py갱신(단조 비교를order_ok()판정으로 교체, 탭 안 정렬도 같은 규칙 적용). 테스트 57/57 ALL PASS · 운영 읽기전용 34/34 ALL PASS. 운영 육안 = 첫 페이지 상위 3행이 금호 구미 / GS 원주 단구 / 롯데 화성 향남 전부 미확정, 4행째부터20260916내림차순. - 배포 = master
1640a2f→ deploy-liveb1958ab(1파일 선별 포워드,--detach워크트리). 사이트맵 = 그룹 8 · 페이지 54 · 미반영 0.devplan/pfs.htmlDONEAB등재.
🆕 NOW (2026-08-25 · 4차) — 등록·수정 폼 현장상태 토글 = 진행중 ↔ 대기중 둘만 ✅운영배포 완료
[페페] qa_helper(/field/modify/2157, button[name=field_status]) = 「토글버튼 순서 수정. 진행중 대기중
2가지 순환만 적용한다. 이 버튼에서 완료는 제외한다. 운영배포」
- 「이 버튼」 = 등록·수정 폼의 현장상태 토글만이다. 목록 상태 컬럼 버튼은 종전대로 3단계 (대기중→진행중→완료) — 완료 표시를 목록에서 뺄 수는 없으니 둘이 서로 다른 순환표를 쓴다.
- 고친 것 =
pfs-component.js에PFS_STATUS_FORM_NEXT = {'20':'10', '10':'20', '30':'20'}신설,initFieldStatusToggle이PFS_STATUS_NEXT대신 이걸 본다. 템플릿 2개는 버튼title문구만 「클릭: 진행중 ↔ 대기중」. 3파일 / +8 −3줄 · 서버코드 0 · DDL 0 · DB 변경 0. - 🔑
30 → 20매핑을 남긴 이유 = 완료로 저장된 현장을 수정으로 열면 완료를 그대로 보여줘야 하고 (자동으로 바뀌면 저장 순간 상태가 조용히 뒤집힌다), 누르는 순간 두 상태 순환으로 들어오게 하려면 출구가 필요하다. 완료로 되돌리려면 목록 상태 컬럼 버튼을 쓴다. - 검증 =
_field_list_qa5_check.py갱신. 테스트 55/55 ALL PASS(등록·수정 각 4클릭이 대기중/진행중 왕복이고 「완료」 미출현 + 완료 현장을 열었을 때 완료 유지 → 1클릭에 진행중) · 운영 읽기전용 32/32 ALL PASS. 회귀_ship_tbd_check테스트 ALL PASS. ⚠검사 함정 = 콘솔 500 필터(기존/children)를 페이지를 더 열기 전에 적용해 두면 그 뒤에 생긴 500 이 남아 거짓 FAIL 이 난다 → 필터는 마지막 한 번만. - 배포 = master
a998988→ deploy-livef739d33(3파일 선별 포워드,--detach워크트리). 사이트맵 = 그룹 8 · 페이지 54 · 미반영 0.devplan/pfs.htmlDONEAA등재. - ⏳페페 = 운영 육안 1회(현장 등록/수정 현장상태 버튼).
🆕 NOW (2026-08-25 · 3차) — 현장목록 상태 정렬 롤백 + 현장상태 필터 탭 ✅운영배포 완료
[페페] 「현장목록 상태 정렬순 취소한다. 다시 롤백해줘. 대신 테이블 상단 검색결과 텍스트 지우고 그 위치에 현장상태 필터용 탭을 달아줘. 대기중,진행중,완료. 나머지 완료 작업은 그대로 유지. 운영 배포」
- 고친 것 =
field_list.html한 파일(+53 −23줄). 서버코드 0 · DDL 0 · DB 변경 0. - 롤백 =
applyFieldFilter의 기본 정렬을 상차일 내림차순 한 줄로 되돌렸다(2차 이전과 바이트 동일).fieldListGroup·fieldListOrder·STATUS_RANK삭제. ⚠상차일 없는 현장이 맨 뒤로 밀려 안 보이는 부작용이 났다 → 5차에서 미확정만 맨 위로 되돌렸다(아래 5차 절). 「대기중/진행중/완료」 상태 그룹 정렬을 뺀 것은 그대로 유효하다. - 신설 =
<h5 class="card-title">검색결과</h5>를 지우고 그 자리에#status-tabs(대기중 10 / 진행중 20 / 완료 30). 한 번에 하나만 걸리고 같은 탭 재클릭 = 전체 해제 — 바로 위 업체 필터 버튼과 같은 방식이라 따로 배울 게 없다. 업체 필터·「진행현장」 토글과는 AND 로 겹쳐 걸린다. 활성 탭은 그 상태 색(--pfs-st-*)으로 밑줄까지 물든다. 죽은 CSS(h5.card-title) 제거. - 그대로 둔 것 = 상태 컬럼 토글 · 등록/수정 현장상태 칸 · 탭 이동 · 20행.
⚠상차일 기간검색 NULL 통과(
IS NULL OR …)도 유지한다 — 그건 정렬이 아니라 「미확정 현장을 목록에 띄우는」 수정이라 롤백 대상이 아니다. 빼면 미확정 현장이 목록에서 다시 사라진다. - 검증 =
_field_list_qa5_check.py갱신. 테스트 51/51 ALL PASS(탭 3종 × 필터 결과·활성표시·탭 안 정렬· 재클릭 복귀 + 기존 항목 전부) · 운영 읽기전용 30/30 ALL PASS. 회귀_ship_tbd_check운영 ALL PASS. 육안 = 테스트 스크린샷 2장(전체/진행중). 운영 실측 = 대기중 6 / 진행중 8 / 완료 114(전체 128). ⚠검사 함정 = 상차일 없는 행은 내림차순에서 맨 뒤라 1페이지에 없다 → 상태버튼 토글 검사는manageDataTable.search(이름)으로 끌어올린 뒤 누른다. - 배포 = master
6fda185→ deploy-live89e5c9d(1파일 선별 포워드,--detach워크트리). 사이트맵 = 그룹 8 · 페이지 54 · 미반영 0.devplan/pfs.htmlDONEZ등재. - ⏳페페 = 운영 육안 1회(현장목록 표 위 탭).
🆕 NOW (2026-08-25 · 2차) — 현장목록 QA 5건 ✅운영배포 완료
[페페] 「PFS 현장목록 수정 작업 추가 …①기본 정렬을 미확정/대기중/진행중/완료 순 + 항목별 상차일 내림차순 ②상태 컬럼 내용버튼 토글화(대기중-진행중-완료 순환·바로 DB) ③등록·수정에서 현장명 폭을 줄이고 유형과 상차일 사이에 현장상태 토글(기본 진행중·저장 반영) ④현장담당자 → 업체담당자 → 시공담당자 탭 직행 ⑤페이지당 10 → 20 · 운영배포」
- 고친 것 = 7파일 / +201 −49줄. DDL 0 · DB 변경 0 · 신규 API 0.
- ①정렬 = ~~그룹(미확정→대기중→진행중→완료) 정렬~~ → 3차에서 페페 지시로 롤백(아래 3차 절 참고).
지금은 상차일 내림차순 한 줄이고, 상태는 표 위 필터 탭으로 고른다.
🔑같이 고친 것 = 목록이 첫 진입에 기본 검색기간(과거6개월~미래1년)을 스스로 채우는데
select_field_search_list의 상차일 비교가 NULL 을 걸러내 미확정 현장이 아예 안 나왔다 →(a.shipping_date IS NULL OR …). 어제 리포트 SQL 함정의 2차 발현 — 남은 자리는rules.md🆕 에 적었다. - ②상태 컬럼 =
statusBtnHtml()한 곳에서만 마크업을 만들고 컬럼 렌더·클릭 후 갱신이 같이 쓴다. 저장은 확장행 칩과 같은PATCH /api/field/status/<no>(서버 화이트리스트 그대로). 낙관적 반영 후 실패하면 되돌린다. 확장행 「현장 상태」 칩도 같이 맞춘다. ⚠클릭해도 행이 즉시 재정렬되진 않는다(커서 밑에서 행이 튀지 않게) — 다음 검색/새로고침에 새 순서로 온다. - ③현장상태 칸 = 현장명
col-md-5→4로 줄인 한 칸(col-md-1). 값은 버튼data-st하나에만 있고 저장할 때 읽는다(공용initFieldStatusToggleinpfs-component.js). 서버 =insert_field의 하드코딩'20'을 파라미터로,update_field는 값이 올 때만field_status를 SET(안 그러면 목록 토글로 바꾼 상태를 폼 저장이 조용히 덮는다).select_field에d.field_status추가(수정화면 초기값). - ④탭 = 자동으로 채워지는 칸(직위·부서·업체명)
tabindex="-1". 수정화면은 담당자 검색버튼까지 빼야 직행이라 같이 뺐고, 대신 이름칸 Enter 로 그 줄 팝업이 열리게 했다 — 수정화면은 팝업이 담당자를 고르는 유일한 길이라 그냥 빼면 키보드로 못 고른다. 등록화면은 인라인 검색(Enter 선택)이라 원래대로. - ⑤
pageLength: 20. - 현장상태 색(
--pfs-st-*)을pfs.css단일 출처로 옮겨 목록·등록·수정이 같이 쓴다.field_list의 사본과STATUS_NEXT중복 제거(확장행 칩 라벨만 칸이 좁아 '대기' 로 남겨둠). - 검증 = 신설
scripts/_field_list_qa5_check.py [test|prod]. 테스트 38/38 ALL PASS = 임시 현장 2건 생성(미확정·완료 / 상차일 있음·대기중) → 등록·수정 상태 왕복 →field_status미전송 시 값 유지 → 기간검색에 미확정 생존 → 화면 정렬 실측(그룹 단조증가 + 묶음 내 내림차순) → 상태버튼 3바퀴 후 DB 대조 → 폼 좌표(유형<상태<상차일)·기본값·순환 → 탭 홉 실측 → 소프트삭제 정리. 운영 읽기전용 16/16 ALL PASS(현장 생성 안 함·저장 안 누름). 운영 첫 페이지 = 미확정 2건 → 대기중 묶음 순. 회귀_ship_tbd_check테스트·운영 ALL PASS. - 배포 = master
c45cd33·adb7c2a→ deploy-livef082d28(7파일 선별 포워드,--detach워크트리). 사이트맵 재빌드 = 그룹 8 · 페이지 54 · 미반영 0.devplan/pfs.htmlDONEY등재. - ⏳페페 = 운영 육안 1회(현장목록 정렬·상태버튼 · 현장 등록/수정 현장상태칸·탭).
- ℹ️④는 「엔터로 선택」이 등록화면에만 있는 동작이라 지시는 등록 기준이지만, 수정화면에도 같이 넣었다 (같은 탭 순서). 등록만 원하면 알려달라.
🆕 NOW (2026-08-25) — 상차일 「미확정」 토글 ✅운영배포 완료
[페페] qa_helper(/field/modify/2134, input[name=shipping_date]) = 「상차일 좌측에 미확정 토글버튼을 만들어줘.
상차일 미확정시 토글버튼 활성화후 날짜 미선택시에도 현장 등록, 수정이 가능하게 한다. 날짜를 입력하면 미확정
버튼은 자동 비활성화 시킨다. 반대로 미확정버튼을 활성화하면 상차일을 비운다. field/print/status 에서도 상차일
미확정인 경우 날짜 대신 "미확정"으로 표기. 운영배포」
- 설계 = 컬럼을 안 만든다. 미확정 =
field.shipping_date IS NULL하나뿐.char(8) NULL허용 컬럼이라 DDL 0. 토글 버튼은 그 값의 거울이라 「날짜 있는데 미확정」 같은 모순 상태가 아예 없다. - 고친 것 = 7파일 / +54 −13줄.
①
web/static/js/pfs-component.js공용initShippingTbd($input, $btn)21줄 — 등록·수정 두 화면이 같이 쓴다.btn-info↔btn-outline-secondary로 활성 표시, 날짜가 들어오면(change) 자동 해제, 이미 미확정일 때 버튼을 누르면 달력을 연다. ②field_modify.html·field_regist.html= 버튼 마크업(input-group-prepend) + 호출 1줄씩. ③field_service.py= 상차일 필수검증 해제(값이 있을 때만 date 형식 검사) +None방어. ④field_dao.py=insert_field·update_field·insert_shipping_history에CONVERT_EMPTY_STRING_TO_NULL(%s)(기존sticker_dao의IS NULL조건이 그대로 걸린다). ⑤production_status_dao.py·field_status_print.html= 리포트 포함조건 + 「미확정」 표기·정렬. - 🔑근본원인 2건 — 둘 다 안 고쳤으면 기능이 겉으로만 되는 자리다(상세 =
rules.md🆕): ①리포트 SQLWHERE date_format(a.shipping_date,'%Y') >= 올해-1이 NULL 을 통째로 걸러내 미확정 현장이 표에 아예 안 나왔다 →(a.shipping_date IS NULL OR …). ②daterangepicker 는typeof null === 'object'라startDate: null→moment(null)=Invalid date → 달력이 안 그려져 미확정 현장에서 날짜를 다시 고를 수 없었다 →resultData.shipping_date || moment().format('YYYY-MM-DD')로 열고 입력칸만 비운다. - 정렬 = 미확정 행은 맨 뒤(
byDate에서8e15). 표기는fmtDate한 곳(생산·AS 표 둘 다 여기를 탄다). - 검증 = 신설
scripts/_ship_tbd_check.py([test|prod],scripts/_*는 gitignore). 테스트 27/27 ALL PASS = 임시 현장 생성(상차일 빈 값)→저장값 NULL 확인→리포트 API 포함·date 없음→날짜 왕복 (20260921↔NULL, 히스토리 경로 포함)→UI 토글 4항·등록화면 2항→fmtDate(null)=미확정·표 셀 실측·맨 뒤 정렬 →소프트삭제 정리. 운영 17/17 ALL PASS(읽기 전용 — 현장 생성 안 함, 저장 안 누름). - 배포 = master
a6da396·86c168f→ deploy-live7b8d622(7파일 선별 포워드,--detach워크트리). DDL 0 · DB 변경 0. 사이트맵 재빌드 = 그룹 8 · 페이지 54 · 미반영 0 · 공용API 5.devplan/pfs.htmlDONEX등재. - ⚠별건(이번 변경과 무관·미수정) =
/api/field/<no>/children은 하위 AS 가 0건이면 500 ('tuple' object has no attribute 'sort'—fetchall이 빈 결과에 tuple 을 준다). 기존 현장 2134·2142 도 동일. - ⏳페페 = 운영 육안 1회(현장 > 수정 > 상차일 좌측 「미확정」 · 현장 > 생산현황 출력).
- ℹ️착수 절차 = 계획 3단계(Fable 계획 → 코덱스 상의 → devplan 계획페이지)를 건너뛰고 바로 실행했다. 단일 QA 코멘트 · 사양이 확정돼 있어 기계적 작업으로 봤다. 다르게 원하면 알려달라.
🆕 NOW (2026-08-24 · 3차) — 월마감 담당자 지정 · 견적서 담당자 예외 · 월마감 금액 견적서 연동 ✅운영배포 완료
[페페] ①월마감 담당자는 업체 「참조」 체크된 사람이 기본이되 넥서스=장동욱 차장 / 에넥스=강동식 차장 / 봉적=김양훈 차장 / 아이비젼글로벌=은지호 대표로 고정. 「하드코딩 아니다」 ②견적서 엑셀 담당자도 참조인원 연계인데 넥서스만 해당 현장 담당자 이름+직책 예외 ③월마감에 견적항목을 담은 뒤 금액이 굳어 견적 수정이 반영 안 된다 → 자동반영. 운영배포.
- 그릴링 3문 확정 = 조회할 때마다 재계산 / 과거 마감월도 같은 규칙 /
company_member컬럼 신설 + 「견적참조」 다음 컬럼으로 UI 연동. 참조 체크 4명 정리는 페페가 직접 했다(운영 확인 완료). - DDL(운영·테스트 선행) =
company_member.close_manager_yn·company.estimate_manager_field_yn(둘 다 CHAR(1) DEFAULT '0', 기존 동작 불변). 스크립트 =scripts/op_close_manager_cols.py. - ①담당자 =
close_manager_yn체크 > 「견적참조」 체크 > 빈칸. 이름+직책으로 조립. 거래처 목록 API 와 마감 헤더 양쪽에 폴백 — 새 마감·기존 마감 모두 채워진다. 저장값이 있으면 그게 우선. UI = 업체 > 담당자 화면 입력폼·표에 「월마감담당」 체크박스(견적참조 바로 다음). - ②견적서 담당자 =
company.estimate_manager_field_yn켜면 현장담당자, 끄면 참조인물._compose_manager한 곳만 보므로 엑셀·PDF·HTML 이 같이 따라간다. UI = 업체 > 수정 「견적서 담당자 = 현장 담당자로 표기」. 넥서스만 ON(scripts/op_nexus_estimate_manager.py). - ③금액 연동 = 견적번호가 붙은 항목은 조회할 때마다 견적서에서 재계산(
_relink_amounts). 본건·추가건 각각, 시공비 분리 거래처는 담기 모달과 같은_CONS_EXPR로 떼서 본건 행에 누적. 목록 합계도 같은 규칙(상세를 열기 전에도 안 어긋난다). 되쓰기 없음 — 조회가 DB 를 안 건드린다. 손입력 행(견적번호 없음)·확정금액·완료청구일·비고는 불변. - 🔑근본원인 1건 = 담당자 폴백이 「일부만」 안 걸리던 이유 =
SELECT h.*에 같은 이름 별칭을 얹어 DictCursor 가 원본(NULL)을 남기고 계산값을 버린 것. 별칭을manager_name_default로 분리. rules.md 등재. - 검증 = 신설
scripts/_mc_manager_amount_check.py [test|prod]테스트·운영 각 ALL PASS (거래처 100개 담당자 기본값 전수 대조 · 스위치 ON/OFF 견적 각 3건 · 마감 헤더 폴백 · 연동 항목 운영 13행·테스트 56행이 견적총액과 일치 · 목록합계=상세합계). 🔑연동 실증 = 테스트 DB 에서 견적 총액 +1,000,000 → 마감이 즉시 51,793,000 으로 따라 움직이고 원복도 반영, DB 저장값은 안 건드림 확인. 회귀 =_monthly_close_ui_check운영·테스트 19/19(고정 기대값 252,970,000 을 자기정합 대조로 교체 — 금액이 견적을 따라가니 숫자를 박으면 거짓 FAIL) ·_kst_timezone_check·_kf_softdelete_page_check운영 ALL PASS. - 배포 = master
f5aa495+ → deploy-live6c7088f(12파일 선별 포워드). 사이트맵 그룹8·페이지54·미반영 0. - 운영 실효 = 견적과 어긋나 있던 11행 해소 · 넥서스 월마감=장동욱 차장 / 견적서=현장담당자(조세영 대리) 확인.
- ⏳페페 = 운영 육안 1회(월마감 새 거래처 담기 시 담당자 자동입력 · 넥서스 견적서 출력 담당자칸).
🆕 NOW (2026-08-24 · 2차) — 시간대 전면 KST 전환 ✅운영배포 완료
[페페] 「PFS 생산현황 메모수정 알람을 보니 시간대를 KST 로 계산 안 하고 있다. PFS 전수 검사해서 시간대는 모두 KST 기준으로 수정하고 운영배포해.」 + 「코디 기본 지침도 KST 로 보고·표기하게 고쳐놔라」
- 뿌리 = EC2 OS(
Etc/UTC) 와 RDS(time_zone=UTC) 가 둘 다 UTC.NOW()·CURDATE()·datetime.now()전부 9시간 밀림. - 전수 검사 = Python naive now 15곳 · SQL
NOW()155곳 ·CURDATE()9곳 · 서버DATE_FORMAT(%H:%i)10여곳 · DATETIME 79컬럼(전부 UTC 저장 확인) · TIMESTAMP 22 · DATE 78 · API 21개가 GMT 라벨 datetime 송출. 🔑지금 「맞게」 보이던 화면 21개는 우연이었다 — Flask 1.0.2 가 naive datetime 에GMT를 붙이고 브라우저가 +9 해서 맞은 것. - 그릴링 6문 페페 확정 = ①저장까지 전면 KST ②과거 데이터 백필 ③RDS 파라미터그룹 레버 ④즉시 집행(앱 중지) ⑤테스트도 같이 ⑥EC2 서버 전체 TZ.
- 집행(다운타임 10:32~10:36 KST, 4분)
- RDS 파라미터그룹
pfs-custom-params-84time_zone=Asia/Seoul(dynamic·무재부팅) — 앱뿐 아니라 사무실 PC 러너·직접 조회까지 한 번에 정합. - EC2
timedatectl set-timezone Asia/Seoul+ 테스트DB 백업 크론30 17→30 2(02:30 KST 유지) + cron 재시작. - 테스트 도커 MySQL
SET PERSIST time_zone='+09:00'— 재기동 실측으로 커맨드라인--default-time-zone=+00:00을 이기는 것 확인(컨테이너 재생성 불필요). - 백필
scripts/kst_backfill.py= DATETIME 78컬럼/45테이블 +9h. 운영 120,719행 · 테스트 15,968행. 제외 = TIMESTAMP 22(세션tz 자동변환·백필하면 이중) · DATE 78(상차일 등 사용자 입력) ·door_order_file.file_mtime(사무실PC 파일시각 = 이미 KST). 테이블당 단일 UPDATE(나눠 쏘면 같은 행ON UPDATE컬럼이 현재시각으로 튄다) + 컬럼마다 전후 MAX 차이 ±9h 검증. - 생산 메모 JSON(
web/static/uploads/memo/field_memo.json) 도 +9(운영·테스트). - 코드(master
f318745→ deploy-livef69d3d8, 6파일 선별 포워드) KstJSONEncoder(web/init.py) — GMT 라벨 → KST 평문. 값을 그대로 찍던 화면(견적·사용자·현장 목록 DataTables)과sticker.html의String(v).slice(5,16)(원래YYYY-MM-DD HH:MM:SS전제였던 잠복버그)까지 같이 옳아졌다.pfsParseDateTime()신설(pfs-utils.js) — 공백형식을T로 바꿔 ES2015 「오프셋 없으면 로컬시간」 규정으로 확정 파싱.convertDateYYYYMMDD*는getUTC*라 그대로 두면 하루 밀림 → 로컬 게터로.field_orderpaper5곳·field_kakao_rooms1곳 교체.orderpaper_dao의CONVERT_TZ('+00:00','+09:00')보정 제거(두면 이중이동).- 🔴사고 1건(복구 완료·잔여 0) =
ssm_run.py가 원격에 인자를 안 넘겨--dry가 무시되고 실집행(14테이블 +9). 즉시 -9 원복 → 그 사이 INSERT 된audit_log4행(PK 109052~109055)을 PK 로 특정해 +9 정정(시각 구간으로 고르면 정상행 126개가 섞인다). 이후 위험 스위치를 파일 내 상수EXECUTE=False로 교체. rules.md 🆕 등재. - 검증 = RDS 스냅샷
pfs-pre-kst-20260824(01:22Z = 백필 이전) · 신설scripts/_kst_db_check.py(SSM) 운영·테스트 ALL PASS(NOW=UTC+9 · 신규 저장값이 KST · 미래시각 0건 = 이중적용 없음 · 크론 보정) · 신설scripts/_kst_timezone_check.py [test|prod]각 ALL PASS(GMT 라벨 0건 · 평문 2,160개 · 브라우저 실파싱 09:37 · 날짜 안 밀림 · 콘솔 0) · 회귀_kf_softdelete_page_check운영·테스트 ALL PASS ·_field_status_print_date_check17항 ·_field_status_print_ivision_checkALL PASS. 사이트맵 그룹8 · 페이지54 · 미반영 0. - 전역 지침도 갱신(페페 지시 2번째) =
C:\dev\CLAUDE.md§2-3 = 「날짜26.7.27(화)· 시각 = KST」, 단일 출처 =rules/tooling.md「날짜·시각 표기」 — 보고·표기물 전부 KST, 서버 로그 인용은00:29 UTC = 09:29 KST병기. - ⏳페페 = 운영 육안 1회(메모 저장 시 텔레그램 알림 시각이 지금 시각과 맞는지).
🆕 NOW (2026-08-24) — 생산현황 출력 타입 카운트에서 소프트딜리트 타입 제외 ✅운영배포 완료
[페페] qa_helper(/field/print/status, div.muted 「(3/3)」) = 「타입 카운트를 소프트딜리트한 항목까지
같이 계산하고 있다. 타입이 소프트딜리트(remove_yn) 1이 되면 카운트에서 제외해줘. 운영배포」
- 고친 것 =
api/pfs/field/dao/production_status_dao.py2줄.select_production_status_print()(생산현황 출력)와select_calendar_print()(월간계획표)의LEFT JOIN field_type AS fON 절에AND f.remove_yn < 1. 둘이 같은 KF CASE 식을 복사해 쓰고 있어 한쪽만 고치면 화면마다 숫자가 또 갈린다 → 같이 고쳤다. - 🔑WHERE 가 아니라 ON — WHERE 로 넣으면 LEFT JOIN 이 INNER 가 돼 타입 0개 현장이 표에서 사라진다 (리포트 9행 중 4행이 타입 0개). rules.md 🆕 등재.
- 왜 어긋나 있었나 = 현장목록(
field_dao)은 예전부터remove_yn < 1서브쿼리로 센다. 리포트만 안 걸렀다. - 운영 실데이터 영향 17개 현장 — 일레븐 파크사이드
(3/3)→(2/1)· GS 오산 양산(13/5)→(10/3)· 욕실 샘플장(F:3)→공백등. 오늘 리포트에 뜬 진행중 9건엔 삭제 타입이 없어 화면 숫자는 오늘 그대로다. - 검증 3겹
① 운영 RDS 에서 DAO SQL 원문을 그대로 떠 A/B 대조(
scripts/_kf_sql_ab_gen.py→_kf_sql_ab_check.py) — 행 집합·KF 외 전 컬럼 동일, KF 만 기대값대로. ALL PASS. 캘린더도 319행 동일·KF 3건만 변화. ② 신설scripts/_kf_softdelete_page_check.py [test|prod]= 앱 안 교차대조(리포트·캘린더 API 의 KF ↔ 현장목록 API 의field_type_10/20/30). 배포 전 운영 FAIL(욕실 샘플장) → 테스트 ALL PASS → 배포 후 운영 ALL PASS(대조 커버리지 154/319행). ③ 회귀 =_field_status_print_date_check.py17항 ·_field_status_print_ivision_check.py운영 ALL PASS. - ⚠함정(rules.md 🆕 등재) = 캘린더 API 는
field_no를 안 내려줘 조인 키가 없으면 0건 대조로 조용히 ALL PASS가 된다. 커버리지 체크를 먼저 넣어야 검증이 검증이 된다. - 배포 = master
f9eb62e→ deploy-livea3bc435(1파일 선별 포워드,--detach워크트리). DDL 0 · DB 변경 0 · 프론트 0. 사이트맵 재빌드 = 그룹 8 · 페이지 54 · 미반영 0.devplan/pfs.htmlDONE 에a3bc435등재 + 허브 재빌드(pfs 카드 2026-08-24). - ⏳페페 = 운영 육안 1회(현장 > 생산현황 출력 — 삭제한 타입이 개수에서 빠졌는지).
🆕 NOW (2026-08-21 · 2차) — 파레트용지 「현장명」·「상세」 글자크기 칸 안 최대치 자동조절 ✅운영배포 완료
[페페] qa_helper(/production/sticker, div.ps-detail) = 「상세내용 메모 글자 크기를 실시간으로 프레임
구역 안에서 최대치로 자동조절해서 보이게 해줘. 줄바꿈 상황도 고려해서 조정. 운영배포」
→ 이어서 채팅 = 「현장명 이름도 글자크기 최대 자동조절 되게 해줘. 이것도 운영배포까지 진행」(현장명 = 현장명 입력값).
- 고친 것 =
web/templates/default/sticker.html한 파일(CSS 2줄 + JS 22줄). 라이브러리 0. - 공용 이분탐색
fitFont(el, fits)= 1~50mm 12회.fits()가 참인 최대 mm 를 인라인font-size로 박는다.fitSheetText()가 상세·현장명 둘을 각자 판정식으로 부르고,fitPallet()끝에서 호출된다 → 타이핑마다(input→renderPallet) 실시간 + 탭 전환·창 리사이즈에도 재계산. - 상세(
.ps-detail) =min-height:0; overflow:hidden추가. flex 자식의min-height:auto를 풀어야 긴 글이 칸을 늘리지 않고 넘침이 측정된다. 판정 =scrollHeight<=clientHeight && scrollWidth<=clientWidth. - 현장명(
.ps-site) =overflow:hidden+ 값을<span>으로 감쌌다. 가운데 정렬 flex 는 위로 넘친 만큼이scrollHeight에 안 잡혀 못 믿는다 → 안쪽 span 의offsetWidth/offsetHeight를 칸 안쪽 치수와 직접 대본다. - 인쇄에도 그대로 간다 —
printPallet()이#stk-pallet-sheetHTML 을 통째로 복사하니 인라인font-size가 따라가고, 웹 196mm(테두리 0.5mm×2, border-box) = 인쇄 195mm(테두리 없음) 로 내용 높이가 같다. - 🔑함정(rules.md 🆕 등재): 안 넘치는 블록은
scrollHeight == clientHeight라 안전여유-4px를 빼면 조건이 항상 거짓 → 1차 테스트배포에서 모든 길이가 1.0mm 로 나왔다. 등호 비교로 수정. - 검증 =
scripts/_stk_pallet_fit_check.py(기존 배율 11항 + 상세 12~17 + 현장명 18~23,scripts/_*는 gitignore). 테스트 ALL PASS · 운영 ALL PASS(각 0 fail). 상세 = 짧은글 35.9mm / 12줄 3.5mm / 24줄 1.8mm, 현장명 = 짧은 50.0mm / 보통 25.7mm / 아주긴(70자) 17.2mm. 세 경우 모두 세로·가로 안 넘침 + 칸 치수(196mm·62mm) 유지 + 콘솔 에러 0. 스크린샷 4장 육안 확인 (%TEMP%\stk_pallet\detail_short|detail_huge|site_short|site_long.png). ⚠검사 스크립트는 페이지 JS 가 IIFE 라S·renderPallet을 못 부른다 → 현장명은 span 텍스트를 직접 넣고window.dispatchEvent(new Event('resize'))로fitPallet→fitSheetText를 발화시켜 잰다. - 배포 = master
f63fc25·8f956da·c8e0798·0c81e76→ deploy-livea5c7b20·9ad83ea(sticker.html 1파일 선별 포워드,--detach워크트리). 그 파일의 deploy-live↔master 차이가 이 변경뿐임을git diff --stat로 먼저 확인(옛 스티커 커밋들은 이미 cherry-pick 반영돼 있었다). DDL 0 · DB 변경 0. 사이트맵 재빌드 = 그룹8 · 페이지54 · 미반영 1→0 · 공용API 5.devplan/pfs.htmlDONE 에9ad83ea등재.
🆕 NOW (2026-08-21 · 1차) — 생산현황 출력 헤더 날짜: 수동선택 + 기본 자동표기 ✅운영배포 완료
[페페] qa_helper(/field/print/status, #rpt-date) = 「①날짜를 수동으로 바꿀 수 있게. 가능한 캘린더
형식으로 사용자가 날짜선택 되게 한다. ②기본 자동표기 = 당일 0~9시 출력이면 당일 날짜, 당일 9시~24시면
내일 날짜. 운영배포」
- 고친 것 =
web/templates/basic/field/field_status_print.html한 파일(26줄 추가·5줄 삭제, JS·CSS·HTML만). ①네이티브<input type="date">를 우상단 날짜 옆에 붙였다(.rpt-datewrapflex). 라이브러리 0.class="no-print"라 기존 인쇄 CSS(.no-print{display:none!important})가 출력물에선 자동으로 숨긴다 → 종이에는 종전대로8.21(금)텍스트만 나간다. ②headerDate()(무조건 오늘) →defaultHeaderDate()=if (d.getHours() >= 9) d.setDate(d.getDate()+1).loadReport()에서pick.value = ymd(defaultHeaderDate())로 채우고change→applyHeaderDate(). 칸을 비우면 기본값으로 되돌아온다(빈 헤더 방지). - ⚠날짜는 표시 전용 — 데이터는 안 바뀐다.
/api/field/status/report는 날짜 파라미터가 없고 진행중 현장을 전량 내려준다. 즉 날짜칸을 바꿔도 표 내용은 그대로다(페페 지시 범위 = 「날짜 표기」뿐). 날짜별 필터가 필요하면 API부터 손대야 한다 — 별건. - 검증 = 신설
scripts/_field_status_print_date_check.py(Playwright, 읽기 전용,scripts/_*는 gitignore 라 로컬 보관). 페이지 안에서window.Date를 잠깐 교체해 시각별 기본값 7건을 실측(00시·08:59=당일 / 09:00·23:59=익일 / 월말 8.31 10시→9.1 / 연말 12.31 22시→익년 1.1 / 12.31 03시=당일) + UI 7건 (type=date·기본값·M.D(요일)포맷·수동변경 12.25(금)·칸비움 복귀·인쇄 시 캘린더 display:none·텍스트 유지) - 콘솔 0. 테스트 17/17 ALL PASS · 운영 17/17 ALL PASS.
회귀 =
_field_status_print_ivision_check.py테스트 ALL PASS · 운영 ALL PASS. - 배포 = master
918b79b→ deploy-live1fca652(1파일 선별 포워드,--detach워크트리). DDL 0 · DB 변경 0 · 서버코드 0. 사이트맵 재빌드 = 그룹 8 · 페이지 54 · 미반영 0. - ⏳페페 = 운영 육안 1회(현장 > 생산현황 출력 → 우상단 날짜 옆 캘린더칸).
🆕 NOW (2026-08-20 · 1차) — 스티커 파레트용지 미리보기 자동배율 ✅운영배포 완료
[페페] qa_helper(/production/sticker) = 「A4용지 미리보기 크기가 너무 작다. 남는 화면을 최대한
채워서 볼수 있게 수정해줘. 운영배포」
- 고친 것 =
sticker.html한 파일. 고정scale(0.4)(428px) →fitPallet()이 남는 폭·뷰포트 높이에서 배율을 계산해--ps로 박는다(CSSmm= 96dpi 고정이라 283mm=1069.6px 로 계산이 결정론적). 미리보기 열 =.stk-pallet-prevcol{flex:1 1 0;min-width:0}→ 그 열clientWidth가 곧 가용폭이라 순환참조 없다. 호출 3곳 =renderPallet()끝 · 탭 전환(숨김 상태에선 폭 0 이라 표시 후 재계산) ·window resize. 하한 0.4 = 예전보다 작아지지 않음. - 검증 =
scripts/_stk_pallet_fit_check.py(Playwright, 11항) — 테스트·운영 ALL PASS. 1920×1080 = 428 → 1182px(배율 1.105, 2.76배) · 1366×768 = 788px(0.737) · A4 비율 1.444 유지 · 화면 밖 넘침 0 · 콘솔 0. - 배포 = master
2b732e8→ deploy-livef938944(1파일 선별 포워드,--detach워크트리). DDL 0 · DB 변경 0 · 인쇄 CSS 무관. 사이트맵 재빌드 = 그룹 8 · 페이지 54 · 미반영 0. - ⏳페페 = 운영 육안 확인.
🆕 NOW (2026-08-19 · 8차) — AL QA 5건: 설정 인라인검색·자동저장 · 큰손/작은손 갭·짝 묶기 ✅운영배포 완료
[페페] qa_helper 5건(/field/al-profile 4 + /field/al-orderpaper 1, 「아래 모든 작업 처리 후 운영배포한다」):
①업체 인라인 검색 + 「공통」처럼 수동입력도 허가 ②검색칸에 뜨는 null 안 보이게 ③수정·추가는 자동저장
④그래서 저장 버튼 삭제 ⑤「큰손·작은손 도어의 갭빼기 치수도 적용. 목대 0.5는 버림해서 정수. 짝으로 나오면
갭을 뺀 뒤 실질적으로 같은 목대·유리가 나와야 하는데 각 행이 짝인지 모르니 NO 칼럼에 2행 이상을 연결하는
기능을 달아라」 + 발주서 작성법 5단계(엑셀 원식 ((D-10-VLOOKUP(,6))/2)+VLOOKUP(,7)).
배포 = master 7758a18·e06d62a·3b807a1 → deploy-live 2bbc552(9파일 선별 포워드, --detach 워크트리).
운영 DDL 선행(SSM) = al_orderpaper_item.pair_link CHAR(1) NOT NULL DEFAULT '0' 추가만, 데이터 변경 0.
⏳페페 = 운영 육안 1회(현장 > AL발주서 NO칸 🔗 · AL설정 관리 자동저장).
- 🔑⑤의 핵심 = 빠져 있던 항이
큰손마감(설정 7열) 하나였다.W=(장외경-10-큰손갭)/2만 있었다 →+큰손마감을 붙이자 같은 장외경 800 에서 작은손 383.5 / 큰손 406.5 로 갈린다. 목대·유리는 정수 버림 (370.5→370 · 377.5→377). 버림 범위는 페페 텔레그램 확정(ASK-FA7446 = 「둘다 정수버림」, 규격W·AL치수는 유지). - 짝 묶기 = NO칸 🔗 토글(
pair_link= 이 행은 윗행과 한 짝, 2행 이상 연속 가능). 묶으면 ①장외경 공유 (한 칸에 치면 묶음 전체가 따라간다) ②목대·유리를 첫 행 값으로 통일 ③원래 달랐던 행은 NO칸 노랑. 같은 규칙이 서버al_calc.compute_rows()에도 있어 엑셀·인쇄까지 화면과 같은 값이 나간다. ⚠조용히 덮지 않는 게 설계 요점 — 정상 짝은 설정 상수가 이미 맞춰져 있어(AA-303/304 목대뺄 13/36, 차이 23 = 큰손마감) 통일이 no-op 이고, 값이 갈리면 그건 상수 미입력 신호다(AA*494/495 = 목대뺄 0/0). - ③④ 자동저장 = 타이핑 멎고 0.9초 뒤 1콜. 🔑저장 후
load()로 다시 그리지 않는다(커서·스크롤 소실) → 응답에 신규행 번호nos를 실어 화면 행에 물린다. 안 물리면 다음 저장이 같은 행을 또 INSERT 한다. 안전장치 = 품명 0행이면 저장 스킵(표 전멸 방지) · 숫자 아닌 값이면 보류 · 저장된 행 × 는 1회 확인. - ① 인라인 드롭리스트를
web/static/js/al_combo.js공용 모듈로 분리(CSS 자체 주입) → 발주서·설정 두 화면이 같은 동작. 후보 = 설정표에 이미 쓰인 업체 + PFS 거래처, 목록에 없는 값도 그냥 타이핑(=「공통」). - ⚠②는 재현 실패 — 운영·테스트 실측
#apSearchplaceholder 는 둘 다업체·품명 검색이고 소스·git 이력에null이 없다(el.placeholder = null을 넣는 코드도 없다). 코드에서 값을 한 번 더 못박아 두었다. 또 뜨면 캡처 + 브라우저/확장 정보 필요. - 검증 = 신설
scripts/_al_qa5_check.py(설정표는 임시행 1개 추가→삭제 후 전/후 스냅샷 대조, 발주서는 운영에서 저장 안 함). 테스트 37 ALL PASS · 운영 33 ALL PASS(B19~22 = 저장 영속·엑셀은 테스트 전용). 회귀 =_al_orderpaper_e2e_test.py20 PASS ·_al_recv_check.pyALL PASS ·_al_combo_check.pyALL PASS ·al_calc.py자체검사(짝 공유·통일·버림) PASS. 사이트맵 = 그룹8·페이지54·미반영 0. - 파일 =
api/pfs/al_orderpaper/{al_calc,service/al_orderpaper_service,dao/al_orderpaper_dao,dao/al_profile_dao}.py·web/static/js/{al_combo(신규),al_orderpaper,al_profile}.js·web/templates/basic/field/field_al_{profile,orderpaper}.html. →projects/pfs/rules.md🆕
🆕 NOW (2026-08-19 · 7차) — AL발주서 QA 3건: 유리 입고처 · 전화면 가로폭 · 거래처 담당자 실시간 ✅운영배포 완료
[페페] QA 3건(/field/al-orderpaper, 같은 세션 연속 지시 · 셋 다 "운영 배포"):
①「유리는 AL업체에 넣어줘야 하니 입고처 컬럼이 필요. 마지막에 생성, 기본은 발주서에 연결된 업체,
인라인 검색·Enter 수동입력, 지정 업체는 거래처 주소까지 참고해 엑셀 입고처 업체명·주소칸에 넣는다.
한 유리업체에 입고처 2곳 이상이면 입고처별로 행을 그룹화하고 입고처 행은 그 그룹 바로 아래.
행을 추가하지 말고 기존 블록행 개수 안에서 교체」 ②「기본정보·데이터입력 프레임 가로폭 부족 —
사이드메뉴 뺀 전화면 폭 + 컬럼폭 절약」 ③「대진아트와이어 담당자를 바꿨는데 갱신이 안 들어온다」
배포 = master fffd408·b98e683·b23cf72 → deploy-live 9963dd5·75172d2(파일 5개 선별 포워드,
--detach 워크트리). 운영 DDL 선행 적용(SSM) = al_orderpaper_item.receive_place VARCHAR(100) 컬럼 추가만,
데이터 변경 0. ⏳페페 = 운영 육안 1회(현장 > AL발주서 → 새 발주서 → 표 맨 오른쪽 입고처).
- 🔑③의 근본원인 = 업체 자동완성이 DB 가 아니라 번들 JSON 스냅샷이었다(
assets/vendors.json= 원부자재발주서.xlsx 업체탭, 381행 + 프로세스 캐시). 거래처를 고쳐도 발주서엔 구조적으로 못 들어온다. 운영 실측 =company_member대진아트와이어(136) 는 신동환차장 삭제(remove_yn=1) · 김정현대리 활성 (modify_date 2026-08-19)인데 화면은 신동환차장. →company+company_member실시간 조회로 교체, 거래처에 없는 이름만 스냅샷 보충, 캐시 제거. 운영 407→414행(스냅샷 전용 1건 = 거래처에 없는 업체). ⚠이미 저장된 발주서의 헤더 담당자칸은 그대로 둔다 — 그때 팩스 받은 사람 기록이다. 업체명을 드롭리스트에서 다시 고르면 새 담당자로 갱신된다(pickCombo가 값이 같아도 change 를 쏜다). - ①은 양식 블록 구조를 그대로 쓴 게 핵심 — 유리시트 블록(29행)마다 입고처 행이 이미 있다(C 업체명 ·
D
주소/담당자, 원본은 업체시트 참조 수식). 그래서 행 삽입 없이 유리 그룹 키를 「업체」→「업체+입고처」로 바꾸는 것만으로 지시(그룹화·바로 아래·행 교체)가 전부 충족된다. 화면 기본값은_recvAuto플래그로 「사람이 손댄 행은 안 덮는다」(헤더 업체명을 한 글자 칠 때마다 덮이면 안 된다). 미리보기·인쇄 미러도 같은 그룹·입고처 행을 그려 팩스로 나가는 종이와 엑셀이 어긋나지 않는다. - 🔴중간에 잡은 기존 버그(같은 블록 로직) = 유리 항목 17개 이상이면 엑셀 다운로드가 500이었다.
양식 24행이 캡노트(
C24:H24병합)인데 항목행 판별이 병합 시작열을 B 만 봐서(AL 캡노트는B16:N16) 항목행으로 셌고, 그 행 D 셀은 MergedCell 이라 기입 순간read-only예외. 판별을 B·C 로, 유리ipb18→17. - 검증 = 신설
scripts/_al_recv_check.py(읽기전용 + 테스트만 저장·삭제). 배포전 테스트 9 FAIL → 테스트 24 ALL PASS → 운영 18 ALL PASS. 회귀 =_al_combo_check.py19 ALL PASS ·_al_orderpaper_e2e_test.py20 PASS/0 FAIL · 엑셀 모듈 자체검사(입고처 분리·17/18 경계·주소없는 입고처). 운영 검증은 기존 발주서 1(금강 부산에코 · AL 대진아트와이어 · 유리 지앤티)의 엑셀을 GET 만 해서 입고처 = 대진아트와이어 + 거래처 현재 담당자로 나오는지 대조. 사이트맵 = 그룹8·페이지54·미반영 2 (미반영 2건은 내 작업 아님 = 견적서 등록·수정 v2, master 전용). - ⚠검증이 두 번 잡아낸 것(둘 다 배포 후 즉시 수정) = ①입고처에 거래처 주소가 없으면 주소칸이 포인 주소로
폴백해 「업체명은 남의 것, 주소는 포인」이 나갔다(
or폴백을 recv 유무 기준으로 분리) ②입고처 주소칸이 발주서에 저장된 옛 담당자로 나갔다 → 거래처 마스터를 1순위로 뒤집었다(페페 지시 "거래처 주소까지 참고"). - 파일 =
api/pfs/al_orderpaper/{al_orderpaper_excel,dao/al_orderpaper_dao,service/al_orderpaper_service}.py·web/static/js/al_orderpaper.js·web/templates/basic/field/field_al_orderpaper.html. →projects/pfs/rules.md🆕
🆕 NOW (2026-08-20 · 2차) — 견적목록 추가건 폴딩 발견성 ✅운영배포 완료
[페페] 「estimate/list-v2 에서도 추가건들 폴딩으로 볼수 있게 해줘. 그래야 입금여부 설정을 내가 할 수 있다」 + 「운영배포」
🔑기능은 이미 1차에 들어가 있었다 — 화면에서 찾을 수가 없었을 뿐이다. 실측 = 기본 목록 36행·페이지당 10행인데
추가건 보유 본건 5건이 전부 6~7월 건이라 최신순 1페이지에 ▶ 가 0개(visibleFold=0). 1차 E2E 가 이걸 못 잡은
이유 = 검증이 datatable.page.len(-1) 로 전 페이지를 펼쳐놓고 셌다.
- 「추가건 있는 건만」 체크박스 신설(검색 필터, 「보관 포함」 옆). 이미 받은 결과에서만 거른다
(
$.fn.dataTable.ext.search, 서버 왕복·신규 API 0). 운영 실측 10행 → 5행 · ▶ 0개 → 5개. - ▶ 라벨에 건수 —
▶ 추가 3+btn-info. 접었다 펴도 건수는 남는다. - 추가건 입금여부 토글은 원래부터 정상이었다 — 하위행 배지 클릭 →
PUT /api/estimate/<no>/deposit→ DB 반영·3회 순환 원상복귀까지 실측 확인(테스트). 페페가 못 만졌던 건 순전히 폴딩을 못 찾아서다.
검증 = _mc_pick_check.py 에 발견성·하위행 토글 8항목 추가 → 테스트 59/59 · 운영 53/53
(운영은 쓰기 항목 skip). 회귀 = _deposit_mark_check 운영 12/12. 사이트맵 그룹8·페이지54·미반영 0.
커밋 = master 1f3954a → deploy-live efeab22(1파일 선별 포워드).
⏳페페 = 운영 육안 1회 — 견적서 관리 → 검색필터 「추가건 있는 건만」 체크 → ▶ 추가 N 클릭 → 하위행 입금여부 버튼 클릭.
🆕 NOW (2026-08-20) — 월마감 견적 담기(추가건 매핑) + 견적목록 추가건 폴딩 + 자동수집=미입금 ✅운영배포 완료
[페페] 「월마감 매핑 기능이 필요하다. 항목추가시 견적서 목록 기준 현장명 검색 및 선택. 이때 추가건도 지정 선택이 되어야 하고 같은 본건 현장 기준으로 한 행으로 묶는다. 추가건은 추가1,2번호에 상관없이 선택된 항목을 본건컬럼 뛰어넘고 추가건 첫번째부터 순서대로 들어가게. 필요사항 그릴링. 운영 배포」
그릴링 6배치 · 페페 확정 13건 = 검색범위 = 거래처 한정 + 「전체」 해제 / 기간 없음 최신 50 / 모달 표 + 추가건
하위행 / 묶음키 = 본견적 estimate_no / 중복은 기존 행에 병합 / 추가칸 순서 = 견적번호 오름차순 /
추가건 번호 = add_amounts 확장 [{no,amt}] / 본건 미선택 행의 매핑 = 부모 본견적 번호 / 검증 = 담은 것
합(확정금액은 검증 무관 — 네고 수기값) / 「행 추가」 유지 + 「견적 담기」 신설 / 자동수집 = 미입금만 /
목록 폴딩 = ▶ 하위 요약행 + 추가건 상태 별도 / 소급연결 66행은 범위 밖 / 배포 = 한 세션 전부 · 운영 1회.
🔴착수 전 페페 지시 = 「6월까지 견적서는 모두 마감처리」 — 자동수집 혼선 제거용. is_deposit '0'→'2',
견적일(없으면 등록일) ≤ 2026-06-30, 기존 입금('1') 5건은 제외. 운영 609건 · 테스트 659건 적용,
롤백용 번호목록 백업 = /home/ubuntu/pfs-backup/is_deposit_{prod,test}_*.json. 결과 = 미입금 본견적 608 → 11건.
🔑근본 문제였던 것 = 마감 항목이 견적서와 반쪽만 붙어 있었다 — 운영 78행 중 estimate_no 12행뿐이고
(1~6월 수기행은 현장만) 추가건은 금액 배열이라 번호가 아예 없었다. 그래서 ①검증 배지가 무엇과 대조하는지
불분명 ②추가건 입금여부를 파생할 근거 없음 ③배지가 링크도 아님. → add_amounts 를 [{"no","amt"}] 로 확장한 게
이 기능 전체의 전제. 운영 DDL 0(TEXT 컬럼 그대로, 숫자배열 하위호환).
- 담기 모달(
estimate_monthly_close.html+GET /api/monthly-close/estimate-search) = 견적서 목록과 같은 기준 (본견적·보관 제외) 현장명·업체명 검색 + 본건 아래 추가건 들여쓰기 체크. 「미입금만」·「전체 업체」·「전부 선택」. 담기 = 본견적 1건 = 1행(있으면 병합·중복번호 무시), 추가건은 견적번호 오름차순으로 추가금액 1번 칸부터, 본건 미체크면 본건금액 0 + 매핑은 부모 번호. 금액은 자동수집과 같은 서비스 함수(넥서스 시공비 분리). - 검증 배지 = 담은 견적 합 vs 합계 ·
견적 #711 +6 ⚠(⚠=미담김 있음) · 클릭 시 견적서 새 탭. ⚠레거시(번호 없는) 행은JSON_CONTAINS_PATH로 갈라 옛 기준으로 폴백 — 안 그러면 배포만으로 전부 빨강. 기존 7월 마감 12행 중 자동수집이 만든 2행은 번호를 정확 복원(개수·금액 전부 일치할 때만,add_amounts_*.json백업). - 견적목록 폴딩(
estimate_list_v2.html) = 추가건 있는 본건에 ▶(운영 5건). 펼치면 견적명·견적일·금액·입금배지·수정. 추가건 배지 = 본건과 같은depositBtnHtml— 수동은 그 행is_deposit, 파생은 마감행add_amounts안 번호+확정금액. - 자동수집 = 같은 모달을 「미입금만」 켠 채로 여는 것. 구
/candidates제거(404).
검증 = 신설 scripts/_mc_pick_check.py 배포전 7 FAIL → 테스트 50/50 → 운영 46/46(운영은 저장 왕복 제외).
회귀 = _deposit_mark_check 테스트 17/17·운영 12/12 · _monthly_close_ui_check 테스트·운영 각 19/19 ·
엑셀 생성 테스트·운영 각 4/4(추가금액1..N 컬럼 유지) · 신규 SQL 6/6(운영 직접 실행) · 운영 배포 파일 4개 해시가
테스트와 완전 일치 · 사이트맵 그룹8·페이지54·미반영 0.
커밋 = master c65e484·b9bd8bd → deploy-live 75fd745(7파일 선별 포워드).
⏳페페 = 운영 육안 1회 — 견적>월마감 → 마감 골라 「견적 담기」(현장명 검색·추가건 체크·담기) / 「견적 자동수집」이
미입금 켜진 모달로 열리는지 / 견적서 관리 목록의 ▶ 펼침.
⏳남은 것 = 1~6월 수기행 66건 견적 소급 연결(범위 밖으로 뺀 건, 이제 담기 모달로 한 달씩 가능).
→ projects/pfs/rules.md 🆕 신규 5줄
🆕 NOW (2026-08-19 · 5차) — 입금여부 「마감」 수동 선택 + QA 도구 버튼 정리 ✅운영배포 완료
[페페] QA(qa_helper, /estimate/modify-v2/730) = 「마감 버튼도 추가해줘. 월마감 초안 정리하면서 마감 표시를
코디가 생성했는데 내가 선택할 수 있는 항목은 없다. 운영배포」 + 같은 세션 추가지시 = 「qahelper 에서
채티용 복사 버튼 이름을 그냥 「복사」로, 텍스트 보기 버튼은 삭제」.
배포 = master 08e0944 → deploy-live 97e596a(4파일 선별 포워드, --detach 워크트리). DDL 0 · DB 변경 0.
✅페페 운영 육안 확인 완료(26.8.19) — 견적 수정화면 마감 선택 확인. 이 건 종결.
- 🔑직전(4차 이전) 작업이 만든 반쪽 상태를 메운 것 — 26.8.19 3차에서 list-v2 입금여부를 월마감 초안 기준
3상태(입금/마감/미입금)로 바꿨는데, 「마감」은 파생값으로만 존재해 사람이 고를 수단이 없었다.
→
is_deposit을 3상태로 승격 =1입금 /2마감 /0미입금(=자동 판정에 맡김). 컬럼이 이미char(1)이라 DDL 없음(rds-map 실측). - 손댄 4곳 = ①견적 폼(
estimate_regist_v2.html, regist·modify 공용) 라디오에 「마감」 ②list_v2depositBtnHtml이'2'를 최우선 마감으로(마감 초안 유무와 무관) ③토글을 0→1→2→0 순환(안 하면 폼에서 고른 마감을 목록에서 한 번 클릭하는 순간 잃는다) ④set_deposit이'2'를 통과시킨다(종전엔'1' else '0'으로 뭉갰다). - qa_helper = 버튼 라벨 「채티용 복사」→「복사」, 「텍스트 보기」 버튼 삭제.
showExportDialog함수는 남긴다 — 클립보드 API 실패 시 폴백이라 지우면 그 경우 QA 항목이 통째로 날아간다. - 검증 =
scripts/_deposit_mark_check.py(기존 스크립트 확장 ·scripts/_*는 gitignore 라 미추적). 배포전 테스트 4 FAIL → 테스트 17 ALL PASS → 운영 12 ALL PASS. 테스트는 토글 3상태 왕복 + 새로고침 후data-deposit=2확인(DB 영속), 운영은 읽기전용(폼 라디오만). 검증 중 켠 테스트 견적 721·797 의is_deposit은'0'으로 원복(SSM). 사이트맵 = 그룹8·페이지54·미반영 2 — 미반영 2건은 내 작업이 아니라 아래 4차(통합현장, master 전용)다. - ⚠같은 리포에서 다른 세션이 동시에 작업 중이었다(4차 통합현장). 검증 도중
origin/master가08e0944→a784e25로 바뀌고 내 워킹트리의 미커밋 WIP 이 사라졌다. 파일 지정 add + 선별 포워드라 서로 안 섞였다 (deploy-live 커밋 diff = 내 4파일 19+/9−).git add -A였으면 남의 미완성 코드가 운영에 갔다.
🆕 NOW (2026-08-19 · 4차) — 통합현장 탭 재설계 = 코디가 정리한 「통합 게시글」 ✅1차 운영배포 완료(별도 세션 전담 · 페페 지시 26.8.19)
✅1차 끝났다(운영배포까지). 담당 세션이 master
a784e25~93a748e· deploy-livef10e839~7d5e2c7로 반영 완료. 이 건 파일(worklog dao/service/controller · kakao_board dao/service · field_worklog.html)은 2차 작업도 같은 세션이 잡는다 — 같은 워크트리 동시편집이면 서로 덮어쓴다.
[페페 지시 · QA 코멘트 /field/worklog #wl-tab-fusion] "카톡·통화 2가지를 각각 보는 게 아니라 현장 기준으로 통합한다.
단순 그룹분류가 아니라 코디가 내용을 수집·정리해 카톡 게시글처럼 정리한다. 통화내용도 현장 관련이면
출처가 통화임을 표기해 게시글에 통합한다. 최종적으로 카톡 게시글로 모든 정보가 통합되어 거래처와
포인 직원이 한눈에 공유하게 하는 것." → 그릴링 5배치 15문 진행, 아래 전부 페페 확정.
착수 전 확인한 구조(코드 실측)
- 3탭은 지금 읽기전용 나열이다 —
GET /api/worklog/fusion(worklog_service.get_worklog_fusion)이 worklog 이번주분 +kakao_board미러를 현장카드로 묶기만 한다. 정리·요약·문장생성 없음. - 게시글 원본은 PFS 가 아니다 — 로컬 PC
poin-agent/<방>/board.md. PFS 는 미러(kakao_board) + 명령 큐(kakao_board_op). 큐 액션 =hide/restore/edit/delete4개뿐 — 「행 추가」가 없다(신설 대상). - board.md 가 바뀌면
sgc/watcher.py(30초 루프)가 해시로 감지해 자동으로 카톡방 게시글 수정 + 공지 고정. = 게시글에 줄 하나 넣으면 그대로 거래처가 본다. - 게시글 방 =
board_edit:true7방, 현장방은 4개(SGC 용두동·금강 부산에코·에넥스 대우 용인·롯데 화성 향남). PFS 현장 수천 건 대부분은 카톡방 자체가 없다. 섹션 구성도 방마다 다르다(「확인중·요청」 4방 / 금강은 「확인중·대기」 / 에넥스는 없음). - 통화 전사본 = 타임스탬프·화자 없는 한 덩어리 평문(
pipeline_worker.py:83이seg.start/end를 버린다). 녹음은 모노 1채널(ffprobe 실측)이라 채널로 화자를 못 가른다. - 원본 m4a 는 전사·적재 후 삭제한다(purge 3,005건, 잔존 17개) → 과거 1,111건은 재전사 불가 = 시각·화자 소급 복원 불가.
- 전사본 1,111개 · 총 1.29MB(평균 1.2KB) — DB 부담 0. 단 지금은 로컬 PC 에만 있다(PFS 로 올리는 경로 없음).
- 연결키는 이미 있다 —
worklog.note = "audio=<파일명> / number=<번호>"(pipeline_worker.py:218). - 통화량 = 26-06 404건 · 07 643건 · 08 63건(8/11까지). 월 400~650건 ≈ 월 20시간.
- 통화 파이프라인은 하루 1회 02:00(
PFS-Night-Worklog). 카톡 board sync 는 1분, watcher 는 30초. - 통화 수집은 폰 앱이 PC 로 push(
talklog_server.py8792/calls·/upload-audio). 앱에TriggerReceiver가 있어 밖에서 브로드캐스트로 깨울 수 있다. 지금 부르는 건NightRunner(밤)·MainActivity(수동)뿐 — 통화종료 감지는 없다.
페페 확정 15건 (그릴링)
- 착지점 = 자동 즉시 반영 프로세스로 간다. 단 통화내용은 PFS 에 먼저 뜨고 페페가 확인 후 카톡 게시글 반영 여부를 결정한다. 현장·거래처에 따라 사전 전체승인으로 돌릴 수 있다. 게시 후 오탐은 PFS 화면에서 사용자가 직접 수정해 보완한다.
- 작성자에 코디 언급만 빼면 항목 내용 자체엔 큰 위험이 없다(페페 판단).
- 정리 문장 생성 주체 = 코디(LLM) 배치.
- 게시글에 나가는 통화 항목 = 코디 재작성 1줄 + 출처 태그. 원문·화자 이름은 게시글에 안 나간다.
is_private=1은 원천 제외. - PFS 에서 통화 항목을 클릭하면 그 통화 전문 전사를 보여준다 — 시간·화자별로 정리하고 그 항목의 근거 구문을 형광 강조한다.
- 전사 수준 = 기존 1,111건은 평문+구문강조만. 신규 통화부터 화자분리를 한다.
- 신규 전사 엔진 = Groq(whisper-large-v3-turbo) 전사 + sherpa-onnx 로컬 화자분리(pyannote-segmentation-3.0 ONNX 6.6MB).
둘 다 무료·무제한. Groq 키는
.secrets/.env에 이미 있다. - 화자 라벨 = 코디가 맥락으로 판정. 힌트 = 「나」 = 포인 신동승 차장, 상대는 보통 나를 「신차장·신동승 차장·차장님」이라 부른다. ⛔전사·산출물에 「페페」라는 말은 절대 쓰지 않는다.
- 전사본 PFS 업로드 = 전량(worklog 항목이 생긴 통화만). 단 1차는 진행중 현장분 먼저 → 보고, 그 뒤 최근 일자 → 과거 일자 순으로 나머지 → 완료 보고.
- 승인 UI = 통합현장 탭 안(행별 ✔게시/✖버림/✎수정 + 방별 「사전 전체승인」 스위치).
- 초안 생성 주기 = 30분마다(카톡 게시글 주기에 맞춘다). 이에 맞춰 폰 통화수집도 통화 종료 즉시로 당긴다.
- 중복 = 코디가 현재 게시글 전문까지 읽고 판단. 이미 있으면 초안에서 빼고, 진행이 바뀐 건은 새 행이 아니라
기존 행 수정 제안으로 낸다(
edit명령은 이미 있다). - 게시글 섹션 = 코디가 그 방의 기존 섹션 목록을 보고 고른다. 맞는 게 없으면 「확인중 · 요청」 신설. 초안에 섹션명을 적어 승인 전에 보인다.
- 카톡방 없는 현장 = 초안은 똑같이 만들고 PFS 전용으로 본다(게시 버튼 자리에 「카톡방 없음」).
- 즉시수집 구현 = PC 가 주기적으로 adb 트리거(앱 수정·APK 재설치 0). 범위 = 단계 분할, 완료 경계 = 바로 운영배포까지.
✅ 1차 결과 (운영배포 완료)
배포 = pfs master a784e25·ee39821·eb3aa2e·ef38616·4eb6cc3·93a748e
→ deploy-live f10e839·73d8fbd·4ed5557·7d5e2c7(6파일 선별 포워드, 별도 워크트리 — 다른 세션이 같은 리포를 쓰고 있었다).
poin-agent c818a8a · talklog 1a78d82. DDL 선행 없음 — 테이블 2개는 첫 호출에 자가생성.
- 테이블 2개 신설(기존 ALTER 0) =
fusion_row(코디 정리본 행 + 카톡 반영 상태) ·call_transcript(전사 평문,audio가 PK). - API 4개 =
POST worklog/fusion/post(현장 통째 교체) ·POST worklog/fusion/decide(대기/게시/제외) ·GET worklog/transcript/<no>·GET|POST worklog/transcript/sync. 기존GET worklog/fusion에post·room_name·cnt_wait추가. - 게시글 「행 추가(add)」를 양쪽에 신설 = PFS
kakao_board_op.action='add'(row_id 칸이 섹션명이다 — 고칠 행이 없다) + 데몬board_rows.add.restore와 공용_append_to_section으로 묶어 중복 판정을 한 곳에 뒀다. 섹션 대조는 「■」 유무를 무시한다(_sec_name) — 안 맞추면 같은 이름 섹션이 하나 더 생긴다. - 🔑핵심 불변식 = 30분마다 다시 만들어도 사람 결정이 살아남는다. 지문
fp= 섹션 + 첫 줄(구두점·공백·「※수정」 표기 제거). upsert 는kakao_state·decide_*를 건드리지 않는다. 검증에서 이 왕복(제외 → 재생성 → 제외 유지)을 실제로 돌린다. - 검증 = 신설
scripts/_fusion_post_check.py {--logic|test|prod}(미추적 —scripts/_*는 gitignore). 배포 전 테스트 9 FAIL → 테스트 33 ALL PASS(쓰기 왕복 포함) → 운영 17 ALL PASS(읽기 전용). 기존 회귀_worklog_fusion_check.py테스트·운영 각 38 ALL PASS. 콘솔 오류 0. 사이트맵 그룹8·페이지54·미반영 0. ⚠운영에서는 쓰기를 안 돈다 — 「게시」가 실제 거래처 단톡방에 들어간다. 쓰기 왕복은 테스트 전용 방으로만. - 전사본 업로드 완료 = 진행중 현장 관련 20건(1차 보고분) → 나머지 전량, 운영
call_transcript1,110건. - 정리본 생성 실행 = 진행중 10현장 중 재료가 있는 2곳. 롯데 화성 향남 2행 생성(둘 다 「(통화 확인)」 출처 표기), 대우 용인 0행(게시글에 이미 있는 내용이라 안 냄 = 규칙 2 정상 동작).
🔴 잡은 함정 4개 (전부 실측)
_ensure_fusion()이 자기 자신을 불렀다 — DDL 1회 실행으로 바꾸며 일괄치환이 함수 안쪽 호출까지 먹었다. 증상 = 통합현장 API 500 "maximum recursion depth exceeded". 일괄치환 뒤엔 그 함수 본문을 눈으로 본다.- flask_restplus 라우트 변수는 메서드 인자로 받아야 한다 —
def get(self)로 두면 500get() got an unexpected keyword argument 'worklog_no'. 테스트엔 통화 항목이 0건이라 운영에서 처음 드러났다. - 🔑근거(excerpt)는 전사문의 인용이 아니라 「요약」이다 — 통째로 찾는 형광은 실측 매치 0%.
→ 구두점·공백을 뺀 글자열끼리 최장 공통 조각(6자 이상)을 앞에서부터 훑는 방식으로 교체
→ 운영 12건 실측 12건 전부 형광 · 근거 글자의 91% 덮음.
⚠중간에 파이썬 측정이
SKIP + "*".join(...)연산자 우선순위 때문에 「각 글자 0회 이상」 정규식이 돼 92%라는 가짜 합격을 냈다. 매치율을 잴 땐 만들어진 정규식을 한 건 찍어서 눈으로 본다. - 게시 버튼 판단은 카드가 아니라 「행이 겨냥한 방」으로 한다 — 방 연결이 나중에 바뀌면 둘이 어긋나고, 버튼은 실제로 나갈 곳을 따라야 한다.
🔴 지금 이 기능의 실질 병목 — 카톡 게시글 방 3개가 「현장 미연결」
운영 실측 = 게시글 방 5개 중 자재방 2개(아이비젼·오엠씨)는 현장이 없는 게 맞고, 나머지 3개가 현장이 있는데도 미연결이다.
→ 그 방들의 게시글이 현장 카드에 안 붙어 코디가 정리할 재료가 없다(배치가 8현장을 그냥 건너뛴다).
근본원인 = 동명 현장이 여럿이라 _match_room_field 의 「유일 승자」 게이트에 걸린다.
실측 = 「SGC 광주 용두동」 3건(본건 MH 1 + AS 2 · #2129/#2151/#2164) · 「금강 부산 에코」 2건 · 「대우 용인」 2건.
⏳페페 판단 필요 — 카톡방을 본건에 붙일지 AS 에 붙일지는 업무 판단이다(진행중으로 뜨는 건 AS 쪽 #2164 인데
게시글의 주인은 보통 본건이다). 정해주면 kakao_board.field_no 직접 연결 또는 매칭 규칙에 그 기준을 넣는다.
✅ 1-2차 추가 (같은 날, 페페 지시) — 본건 우선 규칙 + 수동 연결 + 게시 승인
[페페] "카톡방은 기본적으로 본건에 붙이는 것을 규칙으로 한다. 이후에도 규칙 해당이 없어 미연결 되는 것은 현장연결 버튼을 만들어서 내가 직접 연결해주겠다." + "통화 내용 확인 여부에 제외 버튼만 있고 승인 버튼이 없다."
배포 = master 61a149a·9010333 → deploy-live efc046e·f362fe0.
- ① 본건 우선 —
_match_room_field동점 tie-break 에field_div != '60'(AS 제외)을 active 판정보다 먼저 넣었다. 실측 효과 = 미연결 방 5 → 3(SGC 용두동·금강 부산에코가 본건 #2129·#2142 에 붙었다). 남은 3 = 자재방 2(현장 없음이 맞다) + 롯데 향남. 🔎롯데 향남이 남은 이유는 동점이 아니라 점수 미달이다 — 방 이름롯데건설 화성 향남(포인)vs 현장롯데 화성 향남은 부분일치가 안 되고(「건설」이 끼어 있다) 토큰 점수 64점(< 80). 이건 규칙으로 못 붙인다 = 수동 연결 대상. - ② 방↔현장 수동 연결 =
POST worklog/fusion/link {room_name, field_no}. 미연결 방 카드의 🔗 현장 연결 + 이미 붙은 방도 카드 머리의 🔗 버튼으로 옮긴다(현장 후보에 AS/MH 태그·#번호·상차일이 뜬다). 기존 현장 검색 UI(loadFieldsForLink·wlFieldRowHtml)를 그대로 재사용했다.field_no=null이면 연결 해제. 🔑데몬 미러 upsert 는field_no컬럼을 안 건드리므로 이 연결은 30초 동기화에도 살아남는다. - ③ 카톡방이 없어도 「📤 게시 승인」 — 상태에
승인추가(대기/승인/반영/제외). 방이 없으면 거절하지 않고 승인만 걸어 두고, 방이 연결되는 순간 그 현장의 승인분이 그대로 게시글 명령 큐로 나간다(link_board_room이_publish_row를 돈다). 게시글로 나가는 문은_publish_row하나뿐이다. - 🔴본건 규칙의 부작용을 그 자리에서 잡았다 — 「본건은 완료 · 진행중인 건 AS」인 현장(SGC·금강)에서 방이 완료 현장에 붙자
카드가 아예 안 만들어져 게시글이 화면에서 사라졌다(미연결일 땐 하단 그룹에라도 보였다 = 회귀).
→ 게시글 방이 붙어 있으면 완료 현장이어도 카드는 만든다(내용 표시 규칙 「완료=미출고·신규만」은 그대로).
카드가 있어야 🔗 버튼으로 옮길 수 있다. 카드
room_name도 거르기 전 방 목록에서 뽑는다. - 검증 =
_fusion_post_check.py테스트 42 ALL PASS(방 없이 승인 → 방 연결 → 자동 게시 → 반영행 잠금 → 연결 해제 원상복구 전 구간 왕복) · 운영 17 ALL PASS(읽기 전용) · 기존 회귀 38 ALL PASS · 콘솔 오류 0 · 사이트맵 그룹8·페이지54·미반영 0. 운영 육안 = 게시 승인 2 · 카톡 게시 1 · 현장 연결 3 · 방 이동 3 버튼 렌더, 연결 박스 검색 「용두동」 → AS #2164·AS #2151·MH #2129. - ⏳페페 = 운영에서 판단 2개 ①롯데건설 화성 향남(포인) 방을 #2134 에 🔗 연결 ②SGC·금강 게시글을 완료된 본건(#2129·#2142)에 둘지, 진행중 AS(#2164·#2163)로 옮길지 — 카드 머리 🔗 버튼으로 바꾼다.
✅ 1-3차 (같은 날) — 완료 현장도 연결된 AS 가 진행중이면 살린다
[페페] "완료 현장도 AS가 발생 및 본건과 연결처리 되어 있으면 지금 처리한 것처럼 방 활성화하기." + 그릴링 확인.
배포 = master 628a15f → deploy-live af128b5.
- 그릴링 3문 확정 = ①활성화 범위 = 진행중처럼 전부(게시글 전문 + 코디 정리 대상), 단 출고완료분은 접힘 그룹
②판정 =
field.parent_field_no+ 그 AS 가 진행중('20') ③본건 카드에 AS 진행중 배지. - 🔑충돌은 한 곳뿐이었다 = 26.8.7 「완료 현장은 미출고·이번주 신규만」(
filtered). 살린 현장만 그 규칙을 면제한다 (revived = (st=='30' and AS 진행중 있음)→filtered = (st=='30' and not revived)). 나머지 규칙(본건 우선 매칭·방 있으면 카드 생성)은 같은 방향이라 충돌 없다. - 실측 근거 = AS↔본건 연결은
field.parent_field_no에 진짜 있다(#2151·#2164→2129 · #2163→2142). 단 AS 1,040건 중 parent 가 있는 건 30건(2.9%), 진행중 AS 는 4건 → 규칙 사정거리가 좁다. 「완료 본건인데 동명 AS 진행중」 = 2건(SGC·금강) = 정확히 이 케이스. AS 가 끝나면 자연히 다시 접힌다(상태 플래그가 아니라 계산값). - 살린 현장은 정렬도 진행중 급으로 올린다(맨 아래면 살린 의미가 없다). 상태 라벨은 「완료」 그대로 두고 배지·안내문으로 구분.
- 게시글 출고 완료분은 접힘 그룹(
fs-done) — 전 카드 공통. 살린 현장은 게시글이 통째로 길어진다. - 검증 = 운영 실측 #2142 게시글 34행 · #2129 21행이 되살아났다(직전 0행). AS 배지 2 · 살림 안내문 2 ·
출고완료 「8건(숨김)」 접힘 → 펼치면 8행 · 콘솔 오류 0.
_fusion_post_check테스트 45 · 운영 20 ALL PASS, 기존 회귀 38 ALL PASS, 사이트맵 그룹8·페이지54·미반영 0. ⚠검증 중 항상 참이 되는 가짜 체크를 하나 넣었다가 잡았다(sites.index(x) < len(...)+len(sites)) → 「살린 현장이 안 살린 완료현장보다 앞」이라는 실제 조건으로 교체.
✅ 3차 (2026-08-21) — 수시(5분)·주기(30분) 수집 상시화 + 통화 143건 회수 + 현장별 반영 완료
2차 ⏳「페페가 폰을 꽂아 줘야 통화가 들어온다」가 해소(무선 adb 접속포트 자동탐색). 통화 143건 적재 →
autolink 27건 연결 → 정리본 19행. PFS 제품코드 변경 0 → deploy-live 없음(데이터 반영이 곧 운영 반영).
검증 = 운영 통합현장 탭 렌더·콘솔 0. 원문·미결(무선adb Wi-Fi 종속 / 분류 현장명 품질) →
projects/talklog/handoff.md NOW 2026-08-21 · projects/talklog/rules.md 🆕.
✅ 2차 (2026-08-19) — Groq 전사 + 화자분리 · adb 즉시수집 · 30분 배치 완료
커밋 = talklog 7202a6c. PFS 제품코드 변경 0 → 운영배포 없음(1차가 만든 call_transcript.segs API·화면을
그대로 채우는 작업이라 서버 쪽에 고칠 게 없다). 사이트맵 그룹8·페이지54·미반영 2 = 전부 남의 세션 것(AL발주서).
① 착수 전 실측 벤치 (페페 지시 — 실통화 5건 · server/_bench_stt_diar.py)
| 항목 | 결과 |
|---|---|
| Groq 전사 속도 | 5분 통화 1.4초(실시간 210배) · 1분 통화 1.0~1.4초. 변환(ffmpeg) 0.1~0.8초 |
| 전사 품질 | 로컬 medium 대비 문자 유사도 0.83~0.90(글자수도 비슷) · 무료 |
| 화자분리 속도 | RTF 0.05(1분 통화 0.8초, 전량 로컬·무료) |
| 화자분리 정확도 | 88.0%(정답 라벨 4통화 98세그먼트 대비, 2라벨 최적대응) |
- 🔑sherpa 기본 파이프라인은 안 쓴다 — 그쪽은 자기 segmentation(10초 창) 경계로 임베딩을 뽑아 76.2%. Groq 이 준 발화 경계로 잘라 발화당 임베딩 1개를 뽑으면 88.0%. 코사인 2-means, 중심점은 1초 이상 발화로만.
- 임베딩 모델 = 3dspeaker campplus(zh_en). wespeaker voxceleb CAM++ 는 같은 조건에서 64.7% 로 확연히 나쁘다.
- ⛔고역 에너지로 「내 마이크 vs 통신망」을 가르는 건 안 된다(62.2% = 다수결 수준) — 녹음이 통화 스트림이라 양쪽 다 전화 대역이다. 모노 1채널이라 채널 분리도 불가.
- 편차 = 통화별 66.7%(월드산업 · 발화가 1~2초로 잘게 쪼개진 건) ~ 95.7%. 짧은 맞장구가 약점. 파라미터 스윕(가장자리 트림·중심점 최소길이·교대 사전확률)은 전부 ±1pp 라 더 안 만졌다.
② 만든 것
server/stt_groq.py신설 =transcribe(m4a) → (평문, [{s,e,spk,text}]). Groq 실패는 예외로 올려 기존 faster-whisper medium 으로 폴백(원본 m4a 는 적재 후 지워지므로 여기서 놓치면 영영 못 살린다). 화자분리만 실패하면 삼키고 평문·시각은 살린다.pipeline_worker= 전사 1순위를 Groq 로. segs 는data/calls/transcripts_segs/<audio>.json. 🔑「나/상대」 라벨은 분류 LLM 이 고른me로 덮어쓴다 — 분류가 어차피 전사문을 다 읽으므로 API 왕복 증가 0._classify_system.txt에me필드 규정 추가(단서 = 상대는 나를 「신차장·차장님」이라 부른다).fusion_post= segs 를transcript/sync에 실어 올린다(서버 upsert 가COALESCE라 옛 통화 덮어쓰기 없음).- 🔴현장별 「입력 지문」 변화 게이트 신설(
data/_fusion_state.json) — 30분마다 도는데 이게 없으면 ①재료가 그대로인데 모델을 계속 부르고 ②모델이 같은 사실을 조금 다르게 써서fp가 바뀌면 사람이 이미 「제외」한 행이 새 「대기」 행으로 되살아난다(put_fusion_post는 새 판에 없는 행을 지운다). 실측 = 1회차 14초·모델 2회 → 2회차 2초·모델 0회(unchanged: 2).--force로 무시 가능. server/run_fusion30.py+.vbs= ①수집서버(8792) 자가기동 ②adb 역터널·즉시수집 트리거 ③정리본 생성. 예약작업PFS-Fusion-30m(30분 주기,wscript.exe숨김 실행). 강제실행 실측 rc=0.
③ 🔴 이 기능의 진짜 병목을 찾았다 — 통화 수집이 8/12부터 멈춰 있다
- 수집서버
talklog_server(8792) 가 죽어 있었다. 야간 파이프라인(PFS-Night-Worklog02:00)은 매일 정상 실행됐지만 새 파일이 0건이라 조용히 아무것도 안 했다 — 실패 로그도 안 남는다. 30분 배치가 이제 자가기동한다. - 녹음 폰이 PC 를 못 찾는다. 앱 후보(
Config.FALLBACKS)는 Tailscale100.108.234.45와192.168.45.2뿐인데, 폰엔 Tailscale 이 없고 이 PC 의 실제 LAN IP 는 192.168.45.48 이다 → 둘 다 실패(server_unreachable). → 배치가adb reverse tcp:8792로 역터널을 깔고setserver http://127.0.0.1:8792를 넣는다(앱 수정 0). - ⚠지금 USB 로 붙어 있는 폰은 poin-agent 용 노트20(SM-N981N)이고 거기엔 talklog 앱이 없다.
am broadcast는 받는 앱이 없어도result=0으로 성공한다 = 엉뚱한 폰을 두드리며 「트리거 OK」로 찍힌다. → 배치가pm list packages로 앱이 깔린 폰을 골라서 두드리고, 없으면 그렇다고 로그에 적는다. 녹음 폰(갤럭시 S25 Edge100.106.4.88)은 Tailscale 6일째 offline.
④ 검증
- 신설
talklog/server/_stt_check.py— 로직 11 PASS(라벨 뒤집기·미배정 보존·별칭 금지·파싱) · 실전사+라벨+PFS 왕복 19 PASS(Groq 1.9초 → segs 28개 → 분류me→ 나/상대 → 테스트 PFS 업로드 → 뷰어 API 로 다시 읽어 28개 대조 → segs 없이 재업로드해도 보존 → 원상복구). - 🔑테스트 PFS 에 통화 항목이 0건이라 전사 뷰어 경로가 통째로 미검증이었다(1차에서 라우트 버그가 운영에서
처음 터진 이유).
pfs/scripts/_stt_seed_test.py로 테스트 RDS 에 통화 항목을 심고 검증 후 지웠다. - 육안(테스트 PFS) = 전사 모달에
00:00 나 / 00:01 상대 …28행 + 근거 형광 1건 렌더. 콘솔 오류 0. - 회귀 =
_fusion_post_check.py--logic·test·prod 전부 ALL PASS ·_worklog_fusion_check.pytest·prod ALL PASS. ⚠운영 회귀 2건이 FAIL 로 떠 있던 걸 잡았다 — 「완료 카드는 전부 filtered」라는 검사가 1-3차의 살린 현장(revived) 규칙과 정면으로 어긋난다(#2142·#2129). 제품이 아니라 검사를 규칙에 맞췄다 (안 살린 완료 / 살린 완료를 갈라서 본다). 내 변경은 PFS 제품코드를 안 건드렸다.
⑤ ⏳ 남은 것
- 페페 몫 = ①녹음 폰(S25 Edge)을 이 PC 에 USB 로 꽂거나 Tailscale 을 켜 준다 — 그래야 통화가 다시 들어온다. 꽂히면 30분 배치가 알아서 역터널·수집한다. ②롯데건설 화성 향남(포인) 방 🔗 연결(규칙 64점이라 자동 불가) ③SGC·금강 게시글을 완료 본건(#2129·#2142)에 둘지 진행중 AS(#2164·#2163)로 옮길지.
- (선택·미착수) 방별 「사전 전체승인」 스위치 — 지금은 행마다 사람이 누른다.
- 신규 통화가 실제로 들어오면 화자 라벨 정확도를 운영 데이터로 재측정한다(지금 88%는 8월 통화 4건 기준).
지금은 배치를 손으로 돌린다(
PYTHONUTF8=1 python C:/dev/talklog/server/fusion_post.py --live --active-only). 방별 「사전 전체승인」 스위치도 2차 — 1차는 행마다 사람이 누른다.
🆕 NOW (2026-08-19 · 3차) — 견적 v2 그룹 소계 실시간 갱신 + 출력 담당자칸 직책 ✅운영배포 완료
[페페] QA(qa_helper, /estimate/modify-v2/749) 2건 = ①「310,000원 소계가 실제 금액과 잘 안 맞는다. 검토 후
수정보완. 운영배포. 749 견적 기준」 ②「견적서 엑셀파일에서 담당자 이름만 나오고 직책이 같이 안 나온다.
기존엔 「은지호 팀장」식으로 이름+띄어쓰기+직책이었다. 이것도 수정 후 운영배포」.
배포 = master 4114abf → deploy-live 7aab4ad(estimate_regist_v2.js + estimate_dao.py 2파일 포워드,
--detach 워크트리). DB 변경 0 · 749 데이터 무변경(검증 후 재조회로 확인).
- 🔑①의 근본원인 = 부분 갱신 누락. 749 는 항목 4개 합 420,000(80,000+200,000+80,000+60,000)인데 소계는
310,000 으로 멈춰 있었다.
recalcDetailRow()가 행 최종합계 + 종합합계만 갱신하고 그룹 소계 행은 손대지 않아, 마지막renderDetailTable()시점 값이 그대로 남는다.updateGroupSubtotal()은 이미 있었지만 part_mode 토글 한 경로에서만 호출됐다(그래서 QA 재현에서 part 토글만 유일하게 통과했다). → 호출자 4곳(치수/코너 입력·인라인 편집·단가 자동조회·SUB 재계산)이 전부 지나는recalcDetailRow한 곳에서 부르게 통합하고, part_mode 쪽 중복 호출은 제거. - 🔑②의 근본원인 = SELECT 누락.
_compose_manager()는 참조인물 없으면 현장담당자 이름+직책 폴백인데select_estimate가d.position을 안 뽑아 pos 가 늘 빈값이었다 →d.position AS position한 줄 추가. 749 는 참조인물 없음 + 현장담당자 은지호/대표 → 「은지호」 → 「은지호 대표」. 참조인물 보유 인원은 전체 417명 중 33명뿐이라 폴백 경로가 다수다. 엑셀·PDF·HTML 이_build_common_header한 곳을 공유해 함께 복구. - 검증 = 신설
scripts/_est_grouptot_manager_check.py {test|prod} [견적번호](읽기전용 — 저장 버튼 안 누른다). 로드 직후·단가·수량·치수·마진·part 토글 6시점에서 행합 = 그룹소계를 대조하고,print/data헤더와 실제 다운로드 xlsx 의 A8 셀까지 본다. 운영 배포 전 7 FAIL(단가/수량/치수/마진 4건 + 직책 3건) → 테스트 15 ALL PASS → 운영 15 ALL PASS(749 실측: 420,000→430,000→520,000→700,000→718,000 전부 동기, 엑셀종합!A8 = "은지호 대표"). 콘솔 에러 0. ⚠테스트 RDS 엔 749 항목이 없어 스크립트가 항목+직책 있는 견적으로 자동 대체한다(테스트는 797 사용). - 사이트맵 재빌드(배포 후) = 그룹 8 · 페이지 54 · 미반영 0.
- ⏳[페페] 운영 육안 1회 — 749 에서 단가/수량 고쳐 소계가 즉시 따라오는지 · 엑셀 받아 담당자칸 「은지호 대표」.
🆕 NOW (2026-08-19 · 2차) — 견적 list-v2 입금여부 = 월마감 초안 기준 ✅운영배포 완료
[페페] "pfs 견적서 월마감 초안 기준으로 estimate/list-v2 에 입금/미입금 여부 표시 변경해줘. 운영배포 작업."
배포 = master d2940ee → deploy-live 3ed47d7(estimate_dao.py + estimate_list_v2.html 2파일 포워드, --detach 워크트리). DB 변경 0.
- 착수 전 그릴링 3문 → 페페 확정 = ①판정 = 확정금액 있으면 입금 · 마감행만 있으면 「마감」 · 마감 초안에 없으면 미입금(3상태)
②매칭 = 견적번호 우선 + 현장(field_no) 폴백 ③기존 수동 토글(
is_deposit)이 '1' 이면 그게 우선(토글 유지). - 🔑바꾼 이유의 실측 근거 = 수동 토글은 사실상 안 쓰인다 — 운영 견적 640건 중
is_deposit='1'은 5건(2026년 2건), 마감에 걸린 견적 12건은 전부'0'이었다. 반면 마감 초안은 16건·78행이 이미 서 있다. - 매칭 규칙(마감행 단위) =
i.estimate_no = a.estimate_noOR (i.estimate_no IS NULL AND i.field_no = a.field_no). 마감행이 다른 견적을 명시하고 있으면 현장 폴백으로 끌어오지 않는다. 마감 78행 중 75행이 붙는다 (안 붙는 3행 = 반도 부산 EDC · 일레븐 오피스텔 SH · 별도 비용 — 전부field_no자체가 없다). - 서버 =
select_estimate_search_list에 서브쿼리 2개(mc_confirm_cnt·mc_close_ym)만 추가. 마감행이 없으면mc_close_ym이 NULL 이라 「마감/미입금」이 이걸로 갈린다(행수 세는 세 번째 서브쿼리는 불필요). ⚠집계는COUNT·MAX만 —SUM()은 Decimal 이 돼 jsonify 500(마감 기능 기존 함정). - 화면 = 판정이
depositBtnHtml()한 곳. 색 = 입금btn-info· 마감btn-warning· 미입금btn-danger, 툴팁에 판정 근거(「2026-07 마감 · 확정금액 반영」 / 「2026-07 마감표 포함 · 확정금액 미기재」 / 「수동 입금 표시」). 토글은 그대로 — 끄면 마감 기준 표시로 되돌아간다(버튼을 통째로 다시 그린다. 종전처럼 텍스트만 갈면 「미입금」으로 굳는다). - 검증 = 신설
scripts/_deposit_mark_check.py {test|prod}. 전 행의 라벨·색·툴팁을 서버 원자료로 재계산해 대조한다. 운영 배포 전 2 FAIL → 테스트 12 ALL PASS(토글 왕복 마감→입금→마감 실검증) → 운영 9 ALL PASS(운영은 쓰기 없이 읽기 전용). 운영 기본 목록 36행 분포 = 입금 13 · 마감 2 · 미입금 21, 전량(627행) 기준 = 입금 16 · 마감 4. 콘솔 에러 0. SQL 단독 검증 =scripts/_deposit_mc_sql_probe.py(SSM). - ⚠옛 견적에 「마감」이 붙는 건 오류가 아니다 — 넥서스 1~4월 마감표는 미확정 현장을 매달 이월해 반복 기재한다.
실제로
분당파크뷰(견적 565·2022년)·용인 진산마을(594·2023년)이 2026-01~04 마감행에 그대로 살아 있어 「마감」으로 뜬다. - ⏳[페페] 운영 육안 1회 — 견적서 목록에서 노랑 「마감」 배지와 툴팁 확인. 색/문구 바꾸려면
depositBtnHtml()한 곳.
🆕 NOW (2026-08-19) — AL발주서 드롭리스트 근본수정 + 현장명 드롭리스트 신설 ✅운영배포 완료
[페페] QA(qa_helper, /field/al-orderpaper 품명칸) = "드롭리스트가 제대로 작동 안된다. 프레임에 갇혀서 조금만
움직여도 모달이 닫히는 현상이 빈번. 가운데 휠도 제대로 작동 안됨. 보이는 높이도 2배로. 수정 후 운영배포."
+ 추가 = "현재 페이지 다른 드롭박스들도 동일 문제 — 모두 수정보완" + "현장명 드롭리스트를 견적서 현장검색
리스트 기준으로".
배포 = master de0ba09 → deploy-live ec2c87a(al_orderpaper.js + field_al_orderpaper.html 2파일 포워드). DB 변경 0.
- 🔑근본원인 1줄 =
window.addEventListener('scroll', closeCombo, true). 캡처라 드롭리스트 자신의 스크롤까지 잡아 휠 한 칸에 닫혔고(=「휠 안 됨」), 그리드overflow-x래퍼의 가로 스크롤도 같이 걸렸다(=「조금만 움직여도 닫힘」). → 닫지 말고 따라가게(box.contains(e.target)면 무시, 나머진placeCombo()재배치 + resize). - 「프레임에 갇힘」 =
position:absolute+pageOffset 이라 하단 행에서 목록이 화면 밖으로 잘리던 것 →fixed(뷰포트) + 아래 공간 좁으면 위로 뒤집기 + 남는 공간만큼만 높이 + 좌우 클램프. - 목록
mousedown무조건preventDefault→ 스크롤바 드래그·여백 클릭에 포커스가 빠져 blur 로 닫히던 것도 차단. - 높이
max-height 242 → 484px(2배) +overscroll-behavior:contain(끝에서 페이지로 안 넘어감). - 드롭박스 전부 = 같은
attachCombo()한 곳이라 품명·업체명이 한 수정으로 덮인다(항목행 AL/유리업체는 네이티브<select>라 애초에 무관). - 현장명(
#fSite) 드롭리스트 신설 = 견적서 「현장 검색」과 같은 APIGET estimate/site-search(상차일 최근 30일 이후 · 키워드 = 현장명 OR 업체명 · 최대 50건), 200ms 디바운스 서버조회.attachCombo(input, getItems, fetchItems)3번째 인자 신설(비동기 목록) — 기존 두 콤보 동작 무변경. 클라 필터가 보조설명(업체명)까지 보게 고침 — 서버가 업체명으로 찾아준 현장이 화면에서 걸러지던 것. - 검증 = 신설
scripts/_al_combo_check.py {test|prod}(읽기전용). 배포 전 8 FAIL → 테스트 19 ALL PASS · 운영 19 ALL PASS. 기존_al_orderpaper_ui_check.py회귀 = 테스트·운영 각 27 ALL PASS. 콘솔 에러 0. 운영 현장 목록 34건이 견적서 현장검색 결과와 완전 일치. - 사이트맵 재빌드(배포 후) = 그룹 8 · 페이지 54 · 미반영 0.
- ⏳[페페] 운영 육안 1회 — 현장명칸 클릭(현장 목록) · 품명칸에서 휠로 목록 굴리기 · 맨 아래 행에서 목록이 위로 뒤집히는지.
🆕 NOW (2026-08-18 · 3차) — 견적 v2 치수/코너 칸 휠 스크롤 값증감 차단 ✅운영배포 완료
[페페] QA(qa_helper, /estimate/modify-v2/751 치수3 입력) = "모든 치수칸에서 스크롤로 숫자 증감이 되는 버그가
있다. 치수입력칸에서 스크롤 사용은 금지다. 수정보완해. 운영배포."
배포 = master 387ba62 → deploy-live b827551(estimate_regist_v2.js 1파일 포워드 · 순수 7줄 추가). DB 변경 0.
- 원인 = 치수/코너 칸이
<input type="number">라 포커스 중 휠 = 브라우저 기본 증감. - 조치 =
bindEvents()에 위임 1줄.$(document).on('wheel', '.dim-cell, .corner-cell', …)에서this === document.activeElement면blur()— 포커스가 없으면 기본 증감이 아예 일어나지 않는다. 🔑preventDefault는 안 쓴다 = ①크롬은 document 위임 wheel 을 passive 로 잡아 안 먹고 ②먹더라도 그 칸 위에서 페이지 스크롤까지 막혀 표가 안 굴러간다. - 🔑한 곳으로 전부 덮인다 — 본문 행 · 임시계산기
#calcFrame· 항목모달#itemModal이 같은 클래스를 쓴다 (모달 치수칸은type="text"라 무해). 코너칸도 같은 블록·같은 사고라 함께 막았다. - 검증 = 신설
scripts/_dim_wheel_check.py {test|prod} [견적번호](읽기 전용 — 저장 안 누른다). 운영 배포 전 6 FAIL → 배포 후 14검사 ALL PASS, 테스트 ALL PASS(계산기 칸 기준 — 테스트 RDS 견적엔 항목이 없다). - 사이트맵 재빌드(배포 후) = 그룹 8 · 페이지 54 · 미반영 0.
- ⏳[페페] 운영 육안 — 치수칸에 커서 두고 휠 굴려 값이 안 변하는지(포커스는 풀린다).
🆕 NOW (2026-08-18 · 2차) — 월마감 UI: 마감월 좌우 화살표 + 컬럼 폭 조정 ✅운영배포 완료
[페페] QA = "마감월 이동이 불편하다. 기존 형태 그대로 유지하면서 좌우 화살표로 넘어갈 수 있게. 현장명 가로폭 절약. 완료/청구일 가로폭 증가. 운영 배포."
배포 = master b60787d → deploy-live a8d8f30(템플릿 1파일 포워드). DB 변경 0.
mcShiftMonth(delta)=#mc-ym값을 Date 로 굴려 ±1개월. 연 넘김(2026-01 ◀ 2025-12)이 공짜로 따라온다.<input type="month">는 손대지 않고 좌우에 화살표 버튼만 붙였다(기존 형태 유지 지시).- 컬럼 폭 = 현장명
26% → 17%, 완료/청구일무지정 → 12%(운영 실측 221px · 156px). 「행신동 포함」·「타현장에 포함」이 잘리던 게 해소됐다. - 검증
scripts/_monthly_close_ui_check.py19항목(화살표 6 신규) — 테스트·운영 각각 ALL PASS. ⚠행수·금액 단정은 운영/테스트 분리했다 — 테스트 RDS 는 07-23 옛 시딩본(7월 넥서스 7행·176,113,000)이라 운영 기준(9행·252,970,000)으로 보면 무관한 FAIL 5건이 뜬다. - 사이트맵 재빌드 = 그룹 8 · 페이지 54 · 미반영 0.
🆕 NOW (2026-08-18) — 월마감 26년 1~7월 운영 1차 초안 시딩 완료 (상세: session-2026-08-18-monthly-close-prod-seed.md)
07-29에 코드만 운영배포하고 미뤄둔 「마감 데이터 시딩」을 NAS 마감표 기준으로 집행. 마감 16건·78행.
- 그릴링 2문 확정 = 기존 견적만 연결(백필 생성 안 함) / 기존 2026-07 넥서스 자동수집본(close_no=1)은 마감표로 교체.
- 정본 파일 판정(이름으로 특정 불가 → 내용으로) = 넥서스 1~7월 · 에넥스 1~7월(+
-포인확정확정액) · 넵스 3·7월. 5월은(포인)넥서스 5월 마감.xlsx, 6월은넥서스 6월 마감.xlsx((포인,7월마감건에 참조)…는 7월 작성용 참조본이라 계가 다름). - 매핑 = 현장 75/78(미연결 = 일레븐 오피스텔 SH · 별도 비용 · 반도건설 부산 EDC), 견적 12행. 견적 연결엔 금액 게이트(가족합 ±10% 또는 정확일치)를 걸어 이름만 비슷한 오연결을 막았다.
- 검증 = 저장본 재조회 16/16 PASS · UI
scripts/_monthly_close_ui_check.py prod12/12 ALL PASS · 엑셀 3건 · 사이트맵 미반영 0. - ⏳페페 확인 2건 = ①넥서스 1~4월은 이월 현장 7~8행이 매달 반복(마감표 원본 구조) — 그대로 둘지 ②7월 마감표에 없는 학동매장 3건·금강 부산에코(교체 전 자동수집본엔 있었음)가 마감표 누락인지 8월 이월인지.
🆕 NOW (2026-08-10 · 5차) — 숨김 현장 관리 모달 = 견적서 현장 검색 표 양식(기간+현장명 검색, 기본 3개월) ✅운영배포 완료
[페페] QA(qa_helper, /field/orderpaper 「🗂 숨김 현장 관리」 버튼) = "숨김 현장 모달을 견적서 현장명 검색
모달과 동일한 형식으로 수정해줘. 모달에 별도 검색창 추가한다. 날짜 기간+현장명 검색 용도.
모달 기본 로드는 3개월 이전 현장까지 띄운다. 운영 배포."
배포 = master eac466b → deploy-live e965a65(2파일 선별 포워드, --detach worktree). DB 변경 0.
- 종전 = 폭 560px 모달에 검색 입력 1개 +
.op-map-row한 줄 리스트(현장명 + 「업체 · 연결현장 · 항목 n」 메타). 지금 = 폭 900px + 견적서(estimate_regist_v2)와 같은 표 6컬럼 (업체명 / 현장명(발주서)+연결현장 / 구분 / 상차일 / 최근 입고일 / 항목) + 활성화 열 + 결과 건수 + 헤더 클릭 정렬. - 검색창 = 상차일 기간(from~to) + 현장명 키워드. 기본 = 오늘−3개월 ~ 비움(이후 전체) — 견적서 모달의 「최근 1개월~이후 전체」와 같은 방식(종료일을 비워 미래 무제한). 키워드는 현장명·연결현장명·업체명 3필드.
- 🔑데이터는 모달 열 때 한 번만 받고 필터·정렬은 화면에서 한다 — 숨김 현장은 수십 행(운영 27·테스트 6)이라
서버 왕복·신규 API 가 필요 없다. 컨트롤러·서비스 무변경(GET
/api/orderpaper/hidden-sites그대로). - DAO
select_hidden_sites()에ship_date(field.shipping_date) ·field_div_name(common_code FIELD_DIV) ·order_date_min추가. 🔑field 값은 LEFT JOIN 대신 서브쿼리 —GROUP BY o.site_name_raw, m.field_no라 조인 컬럼을 SELECT 에 얹으면 ONLY_FULL_GROUP_BY 에 걸린다(기존field_name도 같은 이유로 서브쿼리였다). - 🔴상차일 없는 숨김 현장은 기간과 무관하게 항상 보인다(fail-open) — 날짜로 걸러 사라지면 활성화할 길 자체가
없어진다(숨김 현장은 이 모달이 유일한 해제 창구). 현재 실측 0건이지만
field.shipping_date는 nullable. - 검증 = 신설
scripts/_op_hidden_modal_check.py {test|prod}— 읽기 전용(GET + 모달 조작만, 「활성화」는 존재만 확인하고 누르지 않는다 = 운영 데이터 무변경). 테스트 35검사 ALL PASS · 운영 35검사 ALL PASS (기본 3개월 컷 실측 = 운영 27→25, 테스트 6→5 / 시작일 비우면 전체 복귀 / 종료일 필터 / 키워드 매치 / 헤더 정렬·토글·초기화 / 모달·표 가로 넘침 0 / 콘솔 0 / 발주서정리 카드 회귀 8카드). - 사이트맵 재빌드(배포 후) = 그룹 8 · 페이지 50 · 미반영 0.
- ⚠같은 시각 다른 세션이 같은 파일(
field_orderpaper.html)에 「미입고 필터」 QA 를 진행 중이었다 — 착수 시점 워킹트리는 깨끗했고(그 세션 미착수) 편집 구역도 겹치지 않아 그대로 진행, 커밋은 파일 2개 명시 add. - ⏳[페페] 운영 육안 —
/field/orderpaper→ 「🗂 숨김 현장 관리」(기간·현장명 검색 · 정렬 · 활성화).
🆕 NOW (2026-08-10 · 4차) — 발주서 「입고처」 행 파싱 → 오엠씨 자재관리를 오엠씨 입고 시트로 한정 ✅운영배포 완료
[페페] QA(qa_helper, /omc/material 품명칩 BNS-24E117 PP) = "원부자재발주서 읽는 스킬 보완해줘.
이 품목은 한솔아트에서 피앤알로 입고되는 품목이다. 품목 아래로 병합된 라인이 있고, 입고처 셀과
오른쪽에 업체명셀, 그 오른쪽으로 주소가 있다. 입고처 행 위쪽에 있는 데이터가 발주서 해당 탭 업체에서
입고처 업체로 발송되는 것이다. 따라서 BNS-24E117 PP은 오엠씨로 가는게 아니고 피앤알이 맞고,
오엠씨 자재 관리에는 보이면 안된다. 수정 운영 배포."
배포 = master ba33cfc → deploy-live efa4593(5파일 선별 포워드, --detach worktree).
운영 RDS 는 동기화가 선적용(orderpaper.receiver 멱등 ALTER) — 배포 전에 컬럼이 있어야 DAO 가 SELECT 한다.
- 발주서 「입고처」 행 실측 구조(전 파일 전수조사 = 45파일 · 543행) — A열(A:B 병합)
입고처· C열 입고처 업체 · D열~J열(병합) 주소. 한 탭(섹션)에 여러 개일 수 있고 각 입고처 행이 자기 위 묶음을 끊는다 (실측엠제이실업탭 = r10 오엠씨 / r13 진영LDM / r39 상원테크 / r42 세영M테크). 대부분 탭은 표 아래 r26·r28 에포인1개(우리 공장 입고)만 있다. - 파서
orderpaper_parse.py=_receivers(ws,sr,er)+_receiver_of(rcvs,r)→ 항목 dict 에receiver. 항목의 입고처 = 그 항목 아래에서 가장 가까운 입고처 행. 아래에 없으면''(미기재). 원자재(오엠씨) 분기·부자재 분기 양쪽 다 한 줄씩. 입고처 행 자체는 종전대로_is_label이 걸러낸다. - 동기화
orderpaper_sync.py=orderpaper.receiver VARCHAR(100)신설(CREATE + 멱등 ALTER 목록) + INSERT/UPDATE 에 추가. 🔑item_key/block_key해시에는 넣지 않았다 — 넣으면 다음 동기화가 전 행을 새 행으로 만들어 사용자 편집(*_user)·상태·사용이력이 끊긴다(실측 ins 0 / upd 1769 = 키 churn 0). - 화면
field_orderpaper.html오엠씨 필터 = 종전발주처=오엠씨 OR 시트(T)→발주처=오엠씨 OR (시트 AND 입고처∈{오엠씨, 미기재}).dao.select_all_items에receiver노출. 🔑미기재는 fail-open(종전대로 노출) — 근거가 없을 때 입고 누락이 오노출보다 위험. 현재 미기재 시트는 0건. - 영향 실측 — 오엠씨 화면 집합: 테스트 229→181(-48), 운영 216→170(-46). 빠진 것은 전부 목적지가 오엠씨가 아닌 시트다(피앤알·바사디자인·헤브론·호선우드·청솔산업·삼성산업·월드산업, 그리고 포인 직입고).
- 🔎운영 화면에서 지금 시트 그룹이 비어 보이는 건 정상이다 — 숨김 제외 시트 17건 중 오엠씨행 13건이 전부
완료, 이 화면은 완료를 접는다(foldcfg.done=false). 남아 있던 미완료 시트 1건이 바로 피앤알행이었다(= 페페가 지적한 그 줄). 새 오엠씨행 시트가 들어오면 다시 뜬다. 카드 전체 펼침(opExpandCardAll)으로 13건 렌더 확인함. - 검증 = ①신설
scripts/_op_receiver_probe.py파서 자체검사(합성 3케이스 + NAS 실파일 대조) ALL PASS ②신설scripts/_op_receiver_db_check.py(SSM, 읽기전용) 테스트·운영 ALL PASS — 컬럼 존재·적재 (운영 1705행 중 1608 기재)·시트 입고처 분포·집합 축소·한솔아트 BNS-24E117 = 피앤알③scripts/_omc_material_check.py확장(입고처 한정 2검사 추가) 테스트 ALL PASS + 운영 ALL PASS. ⚠검사 2건이 데이터 모양에 묶여 있어 같이 고쳤다 — 「시트 그룹 맨 위」·「타업체 품명 편집」이 첫 카드/기본 펼침 상태에 기대고 있었다 → 전 카드opExpandCardAll후 시트 섹션이 있는 모든 카드를 본다. - 사이트맵 재빌드(배포 후) = 그룹 8 · 페이지 50 · 미반영 0.
- ⏳[페페] 운영 육안 —
/omc/material에 한솔아트BNS-24E117 PP가 없는지, 현장 카드 「완료 업체」를 펼치면 오엠씨행 시트 13건이 보이는지. - ❓[페페] 판단 1건 = 화면에 입고처 컬럼을 보여줄지. 지금은 필터에만 쓰고 표에는 안 띄운다(지시 범위 밖).
🆕 NOW (2026-08-10 · 3차) — 생산현황 레포트 아이비젼글로벌 업체명 2줄 표기 ✅운영배포 완료
[페페] 지시 = "field/print/status 아이비젼글로벌 업체명이 길어서 셀을 넘어선다. 줄바꿈 적용.
아이비젼 후에 글로벌은 다음줄. 이 업체만. 운영배포."
배포 = master 4406fe2 → deploy-live 09c60ff(1파일 선별 포워드, --detach worktree). DB 변경 0.
- [코디] 원인 =
td.comp { white-space: nowrap }+col.c-comp { width: 8% }(실측 60px). 폭을 넓히면 다른 칸이 밀리므로 이 업체명만<br>로 끊는다 —<br>은nowrap도 무시하고 개행한다(CSS 무변경).field_status_print.html에compName()신설,compTd()가esc()대신 이걸 쓴다. - 🔴함정 = 테스트와 운영의 업체명 표기가 다르다. 운영 =
아이비젼글로벌, 테스트 =글로벌아이비젼(순서 반대). 1차 구현(아이비젼글로벌고정 매칭)은 테스트에서 아무 것도 안 걸렸고 그게 검증에서 잡혔다. → 정규식/(아이비[젼전])\s*(글로벌)|(글로벌)\s*(아이비[젼전])/ → '$1$3<br>$2$4'로 두 표기 다 받되 이름 순서는 그대로 둔다(업체명을 뒤집지 않는다). rules 🆕. ※orderpaper_parse.py는 별개로글로벌아이비전 → 아이비젼글로벌정규화를 이미 하고 있다(발주서 경로 한정). - 검증 = 신설
scripts/_field_status_print_ivision_check.py {test|prod}(읽기 전용 — 페이지의compTd()를 그대로 호출해 임시 행을 넣고scrollWidth>clientWidth실측 후 행 제거). 테스트·운영 둘 다 ALL PASS — 2줄 표기·셀 넘침 0(60=60)·표 가로 넘침 0·넥서스 등 다른 업체<br>없음·실데이터 업체셀 넘침 0·콘솔 0. 운영 실데이터엔 해당 업체 2셀이아이비젼<br>글로벌(담당 은지호)로 나온다 = 페페 지시 그대로. - 사이트맵 재빌드 = 그룹 8 · 페이지 50 · 미반영 0.
- ⏳[페페] 운영 육안 + 실제 인쇄 — 화면은 확인했으나 A4 인쇄(font-size 11px)는 눈으로 볼 것.
🆕 NOW (2026-08-10 · 2차) — 견적 재작성에 「내용 복사」 선택 신설 + 차수 버튼 표기·위치·모달 폭 ✅운영배포 완료
페페 지시 = "함정 주의하고 pfs 에 기능으로 추가해라. 본건 견적서 새로 생성시 복사 기능 추가
(사용자 선택예정, 0으로 시작하는 경우도 있음) 운영배포." + QA 3건(/estimate/list-v2) =
"차수 1·차수 2 로 표기되는 버튼을 1차·2차로", "버튼을 삭제 왼쪽으로", "차수 이력 모달 가로폭 — 줄이 밀린다".
배포 = master e25e3e7 → deploy-live e659f80(4파일 선별 포워드, --detach worktree). DB 변경 0.
- ① 재작성 = 시작 방식을 사람이 고른다. 종전엔
confirm('…항목은 복사하지 않습니다')하나뿐이라 빈 견적서가 유일한 길이었다. 이제 모달#rewrite-modal에서 「내용 복사해서 시작」 / 「빈 견적서로 시작」 / 취소. 🔑confirm 2번으로 안 물었다 — 「취소」가 「빈 견적서」로 읽혀 금액 문서를 오조작한다. API =POST /api/estimate/<no>/rewritebodycopy_items:'1'|'0'(기본 '0' = 종전 동작, 회귀 0). - ② 복사 범위 =
estimate_detail+estimate_detail_sub+estimate_extra_cost+estimate_material - 마스터 금액 4컬럼(총액·마진총액·시공비·운반비). 헤더(현장·업체·지불조건·마진)는 종전 재작성 그대로 승계,
comment는 종전대로 빈 값(내용 복사의 범위가 아니다). - 🔴함정 1 = FLOAT(어제 708→747 수동 복사에서 발견) →
estimate_dao.copy_estimate_contents는 값을 MySQL 밖으로 안 꺼낸다. 전부INSERT .. SELECT, 파이썬은 정수 PK 만 만진다. - 🔴함정 2 =
display_order로 부모-자식을 짝지으면 안 된다 — 실데이터에 중복이 있다 (테스트 견적 33·35·36·37·47 = 19행인데 distinct 6). → 항목을 한 건씩 INSERT 하고 그 자리에서SELECT LAST_INSERT_ID()(같은 커넥션·트랜잭션)로 새detail_no를 받아 그 자식만 붙인다. rules 🆕. - 🔴함정 3 =
%포맷 조립 —values조각에%%s를 쓰면 바깥 포맷의 인자라 escape 이 안 돼%%s가 그대로 남는다(1차 구현 버그, 완성 SQL 을 print 해서 잡았다). rules 🆕. - 복사 실패 = 재작성 자체를 되돌린다 — 새 차수
delete_estimate+ 원본update_archive('0')후 예외 전달. 빈 차수가 남아 사람이 치우는 상태를 안 만든다. - ③ 차수 버튼 = 라벨이 「차수 N(현장의 차수 개수)」였다 → 「N차(이 행이 몇 차인가)」.
🔑개수는 그 행이 몇 차인지 말해주지 않아 보관된 1차 행이 "차수 2" 로 보였다. 번호 매김은 차수 모달과 같은
estimate_no오름차순 순번(DAO 서브쿼리revision_no신설). 개수는 툴팁으로 남겼다. 위치 = 삭제 왼쪽. - ④ 차수 이력 모달 =
modal-lg(800px) → 1140px(calc(100vw-40px)상한) + 견적명 외nowrap. 실측 = 폭 1140 · 가로 넘침 0 · 셀 잘림 0 · 행 높이 균일(53=53). - 검증 = 신설
scripts/_est_rewrite_copy_check.py {test|prod} [--write] [--empty]+_est_rewrite_db_verify_test.py(SSM, 서버측<=>대조) — 테스트 E2E 3회전(복사 → 정리 → 빈 견적서 → 정리 → 복사 재확인 → 정리) 전부 ALL PASS. 대상 = 테스트 견적 707 일레븐 파크사이드 (항목 52·sub 215·별도 2·자재 4 = 네 테이블 전부 덮는다). DB 대조 = 4테이블 전 컬럼 비트 일치 0불일치 ·SUM(amount)·SUM(margin_total_amount)<=>1 · 마스터 금액 4컬럼 동일 · 이름(2차)· 원본 보관·항목 보존. 화면 대조 = 원본 707 과 복사본 804 의 견적 총액이 같다(둘 다 195,760,580). 🔑테스트 DB 는 원상복구했다 — 만든 차수 802·803·804 를 자식까지 삭제하고 707 보관 해제(실측 확인). 운영은 읽기 전용 검증만(라벨·위치·툴팁·모달 폭·재작성 모달 3버튼·콘솔 0) — 운영에서 재작성은 안 눌렀다. - 사이트맵 재빌드 = 그룹 8 · 페이지 50 · 미반영 0.
- ⏳페페 = 운영 육안 — 목록에서 「N차」 위치·툴팁, 차수 이력 모달 폭, 재작성 → 두 갈래 선택.
🆕 NOW (2026-08-10) — 대우 용인 MH 견적서 1차(708) → 2차 재작성건(747) 내용 복사 ✅운영 반영 완료
페페 지시 = "pfs 운영서버 에넥스 대우 용인 견적서 본건 1차를 2차 본건 재작성건에 내용 복사해. 운영 작업 승인". 코드 변경 0 — 운영 RDS 데이터 작업만(배포 없음, 사이트맵 무관).
- 대상 = 현장
field_no 2109(대우 용인, 에넥스·김동연). 본건 1차 = 견적 708(2026-06-10,archive_yn='1'보관됨, 총액 43,563,000) → 2차 = 견적 747(대우 용인 MH 견적서 (2차), 2026-08-10 생성, 완전히 비어 있었다). 둘 다parent_estimate_noNULL = 본건, 추가건 0건(복사 대상도 본건뿐). - 복사한 것 =
estimate_detail50행 +estimate_detail_sub53행(전 컬럼 원본 그대로, PK만 신규 채번) + 마스터total_amount·margin_total_amount= 43,563,000.estimate_extra_cost·estimate_material은 원본이 0건. 마스터 나머지(지불조건 현금·마진 -10·구분·시공비/운반비 0)는 747 이 이미 708 과 같아 손대지 않았다. - 🔴함정 = FLOAT 정밀도. 1차 시도(파이썬으로 읽어 되넣기)는 값이 미세하게 달라졌다 — MySQL 텍스트 프로토콜이
FLOAT 를 유효 6자리로 잘라 보내
SUM(amount)33,419,453.09375 → 33,419,442.0(11.09 차이). 행 단위 파이썬 대조로는 차이 0 으로 보여 못 잡는다(읽는 순간 양쪽 다 뭉개짐). → 넣은 행을 지우고 서버측INSERT .. SELECT로 재복사(자식은display_order조인으로 새detail_no매핑). rules 🆕 등록. - 검증 = ①서버측
NOT (a.col <=> b.col)전 컬럼 조인 → detail·sub 불일치 0행 ②SUM(amount)·SUM(margin_total_amount)708 = 747 완전 일치 ③708 무변경 확인(50행·합계 그대로) ④운영 화면 실브라우저(scripts/_est_daewoo_ui_check.py prod) ALL PASS — 747 에 타입 5개(59A·59B·84A·84B·84C)·주방(K)5/가구(F)4·견적 총액 43,563,000 표시, 콘솔 에러 0. - 롤백 = 747 의
detail_no 35494~35543(+그 자식 sub) 삭제 + 마스터 합계 0 복원. 스크립트는 전부pfs/scripts/_est_daewoo_*.py(미추적). - ⏳페페 = 운영 육안(
/estimate/modify-v2/747— 타입별로 항목 확인 후 2차 내용 수정).
🆕 NOW (2026-08-10) — 생산 스티커 출력 회수 초기화 버튼(총관리자 전용) ✅운영배포 완료
페페 QA(qa_helper, 도어 표의 ✓2회 09 Aug 2026 신동승 셀) = "출력 회수 초기화 버튼을 추가해줘.
관리자만 사용가능. 관리자 아이디만 볼 수 있게 설정. 페이지 이동 버튼 행의 우측 끝에 추가."
(1차 지시엔 운영배포 말이 없어 테스트까지만 했고, 같은 날 페페가 채팅에 「운영배포 진행」 직접 입력 → 배포.)
배포 = master b590f3e → deploy-live 84fcb2f(3파일 선별 포워드). 운영 RDS DDL 선행 적용 완료.
🔑같은 파일에 실려 8/7 백로그도 함께 반영됐다 = sticker_controller sync target 한 줄
(운영 화면 「엑셀 동기화」가 테스트 DB 를 갱신하던 것 → FLASK_CONFIGURATION 기준 prod/test 결정).
→ 사이트맵 미반영 1 → 0.
- 범위 = 현재 선택된 도어발주서 파일 전체(모든 페이지) — 페페 택1. "이 발주서 다시 처음부터 뽑는다"가 실제 상황.
- 권한 2겹 = ①템플릿
{% if is_super_admin %}로 버튼 자체가 관리자에게만 렌더 ②서버POST /api/sticker/print-log/reset가session.is_super_admin을 다시 확인. 비로그인은 기존 게이트가 401. - 🔑DELETE 가 아니라 소프트 딜리트 —
sticker_print_log.remove_yn='1'+removed_by·removed_at. 누가 언제 지웠는지 남고, 잘못 눌러도 DB 에서 되살릴 수 있다. 조회 2곳(select_print_logs,select_print_log_history)에remove_yn='0'필터 추가. - 확인 대화상자에 대상 품목 수·"기록은 남아 복구 가능" 을 적어 오조작을 줄였다. 버튼은 붉은 테두리로 페이지
버튼과 구분(우측 끝,
.pn-reset). - 스키마
scripts/codi_sticker_printlog_reset_schema.py(멱등 — 컬럼 3 +ix_spl_live). ⚠.gitignore의scripts/codi_*라 추적 안 됨(옛 codi_sticker_.py 는 규칙 생기기 전에 들어간 것). 테스트·운영 RDS 둘 다 적용 완료(운영은_codi_sticker_printlog_reset_schema_prod.py= ENV_PATH 만 다른 사본, 코드 배포보다 먼저 실행). 운영 적용 후 실측 = 컬럼 3개 존재 · 기록 3행 전부remove_yn='0'(데이터 무변경*). - 검증 = 신설
scripts/_sticker_printlog_reset_check.py {test|prod}— 테스트 19 + 운영 13 ALL PASS (소스 게이트 6 · 비로그인 401 · 버튼 노출/행 마지막/우측 끝 · 실제 초기화 ✓3→0 · 표 25행 보존 · 다른 발주서·다른 source 기록 보존 · 원상복구 · 콘솔 0). prod 모드는 읽기 전용(버튼·권한·소스만, 초기화 안 누름). - 🔴검증 함정 = 테스트 DB 엔 「진행중 현장에 연결된 살아있는 도어발주서」가 0건이라 화면에 표가 안 뜬다.
기록이 있던
file 222는door_order_file.remove_yn='1'인 삭제 파일(칩 0개)이었다 → 살아있는file 241(금강 부산에코, 264품목)을 진행중 현장2142에 임시 연결 + 기록 시드 → 검증 → 연결 해제 + 시드 행 삭제. 원복 확인 = 로그 16행 전부remove_yn='0'· file222→2099 · file241→NULL(SSM 실측). - ⚠운영에서는 초기화를 안 눌렀다 — 운영 기록 3행이 실데이터라 지우면 안 된다. 운영 검증은 읽기 전용 (버튼 노출·위치·권한 게이트·비로그인 401·소스 게이트)까지. 실제 초기화 동작 확인은 테스트에서 끝냈다.
- 🔴배포 함정 = 다른 세션이
deploy-live워크트리를 잡고 있으면git worktree add가 거부된다. 이번엔 그 경로에.git이 없는 깨진 등록이었는데도 브랜치가 묶여 있었다 →git worktree add --detach <경로> origin/deploy-live로 붙고git push origin HEAD:deploy-live. 남의 등록을 지우지 않고, 충돌하면 non-fast-forward 로 안전하게 실패한다(rules 🆕). - ⏳페페 = 운영 육안(총관리자로
/production/sticker→ 발주서 연결된 현장 → 우측 끝↺ 출력 회수 초기화).
🆕 NOW (2026-08-10) — 생산 스티커 현장 검색을 견적서 등록과 같은 표 양식으로 ✅운영배포 완료
페페 QA(qa_helper, #stk-field-input) = "견적서 등록의 현장명 검색 리스트 양식을 여기에 적용해줘.
너무 간단하게 나오고 내용이 잘 안 보임. 운영배포"
배포 = master fa34a53+cda67b2+582593a → deploy-live ae9e767(2파일 선별 포워드 · 임시 worktree).
- 종전 = 폭 340px 드롭다운 한 줄(
현장명+ 회색업체명 · 2026-08-17). 지금 = 견적서 등록(estimate_regist_v2)과 같은 5컬럼 표 — 업체명 / 현장명 / 구분 칩 / 상차일 / 담당자 + 헤더 클릭 정렬 + 결과 건수. 폭 780px (max-width:100vw-60px), 최대높이 320→420px, 헤더·컬럼헤더 sticky. - 모달이 아니라 인라인 드롭다운을 넓힌 것(페페 택1) — 견적서는 모달이지만 생산팀은 현장을 자주 바꾸므로 클릭 수를 늘리지 않는다. 리스트 양식만 가져왔다.
- DAO =
field_div_name(기존과 같은CONVERT_MULTI_COMMON_CODE, common_code 조인 안 씀)·company_member_name추가, 키워드가 업체명까지 검색(a.name LIKE OR b.name LIKE— 견적 site-search 와 동일). 진행중(production_status.field_status='20') 게이트·3개월전~1년후 창·LIMIT 100 은 무변경. - 상차일 =
26.8.17(월)(페페 날짜 규칙). 빈 값은 정렬 방향과 무관하게 항상 뒤로(상차일 미정 현장이 맨 위를 차지하지 않게). 선택 흐름·스티커 헤더 표기는 손대지 않았다(field_name그대로 사용). - 🔴자체검사가 실버그 1건 적발 = 정렬 한 번 누르면 패널이 닫혔다. 정렬 핸들러가
.html()로 표를 다시 그리는데, 뒤이어 도는 「패널 밖 클릭이면 닫기」 핸들러가 볼 때e.target(클릭한 th)은 이미 DOM 에서 떨어져 나가closest('.stk-field-pick')가 0 → 밖 클릭으로 오판. → 정렬·초기화 핸들러에stopPropagation(rules 🆕 등록). - 검증 = 신설
scripts/_sticker_field_search_check.py {test|prod}(미추적) — 테스트 40 + 운영 40 ALL PASS (응답 키 8·컬럼/정렬키 일치·건수 일치·폭 780·가로스크롤 0·날짜 형식·정렬 3종+패널 유지 회귀·업체명 검색· 행 클릭 회귀·콘솔 0). 읽기 전용이라 운영 실행 무해(GET + 화면 조작만, 쓰기 없음). - 사이트맵 재빌드 = 그룹8·페이지 50·미반영 1 — 남은 1건은
sticker_controller.pysync target 한 줄 (8/7 백로그, 워커 이중결정으로 동작은 정상). 이번 건은 전부 반영됨. - ⏳페페 = ①운영 육안 ②
sticker_controller한 줄 운영배포 지시 여부.
🆕 NOW (2026-08-10 · 3차) — 품명 인라인 편집 전 항목 확대 + 시트 입고일정 병합 주석행 제외 ✅운영배포 완료
페페 = "작동 확인 완료. 모든 항목 자재관리·오엠씨 자재관리에서 품명 수정 가능하게. 피앤알건 : 시트가 포함된 행이 기존 블록양식이 아닌 병합된 행이면 제거한다. 시트 입고 일정에 대한 정보다." 운영배포.
배포 = master d1cb28e → deploy-live b295283(2파일 선별 포워드 · --detach worktree).
- ① 품명 편집 — 오엠씨 외 전 항목도 표에서 클릭 편집(
nameChip/opEditName/setItemName). 저장은 전면/후면과 같은item_name_user라 기존 자재관리 탭과 그대로 연동(추가 배선 0). - ② 병합 주석행 제외 — 🔎엑셀 실물 확인이 답이었다: 포인 발주서 표준은 품명
B:C·규격D:E를 각각 병합하는데, 주석행은B:G한 칸으로 합쳐 쓴다(피앤알 탭 행68 =시트 : 7.22(수) 13미터 1롤 차량 입고). → 파서가 품명칸 병합이 규격칸까지 덮으면 주석행으로 보고, 그중 '시트'가 든 것만 수집 제외. 🔑JARVIS 1096.19 / 9T MDF 시트/재고PP(행66)는 정상 항목행이라 그대로 둔다 — 그 행은 계속 시트(T)로 분류된다 (페페 규칙이 "규격에 시트"이므로). 빼려면 그 행 규격에서 '시트'를 지우면 된다. 기존 적재분 = 테스트 4건 soft delete(del_manual='1'), 운영은 동기화가 이미 정리해 0건. ✅사이드카 재시작 불필요 —orderpaper_sync.py는subprocess로 돈다(업로드 파서만sys.modules캐시).
검증 = scripts/_omc_material_check.py 테스트·운영 ALL PASS(품명칸 전량 편집 가능·시트 주석행 0) +
신설 scripts/_pnr_sheet_row_probe.py 파서 자체검사(합성 4케이스 + NAS 실파일 대조) ALL PASS.
사이트맵 = 그룹8·페이지50·미반영 0.
⏳페페 = 운영 육안(품명 클릭 편집 · 시트 그룹에서 입고일정 메모 사라졌는지).
🆕 NOW (2026-08-10 · 2차) — 시트(T) 자재분류 신설 + 오엠씨 전면/후면 편집 + 오엠씨 화면 펼침·시트 우선 ✅운영배포 완료
페페 QA 3건 = ①"전면·후면 품명 수정 가능하게. 기존 자재관리페이지와 수정결과 연동. 기존 발주서 정리 탭에서도 전면/후면 분리 — 오엠씨 테이블만" ②"부자재로 분류되던 시트 항목을 별도 시트 항목으로 분리. 필터도 추가. 자재관리 전 페이지 적용. 기존분·추가분 모두. 시트는 규격에 항상 '시트'가 포함" ③"오엠씨 자재관리 현장별 그룹 기본 펼침(완료항목은 그대로 숨김), 현장 카드 상단에 시트 그룹 먼저 — 오엠씨에서 시트 입고 체크용". 운영배포.
배포 = master 945ab51+26d2533 → deploy-live 5222bed(8파일 선별 포워드 · 임시 worktree). DB 변경 0.
- ① 전면/후면 편집 —
PATCH /api/orderpaper/{no}/item-name(=item_name_user)에 합친 품명 한 필드로 저장하니 기존 자재관리 탭·목록이 자동으로 같은 값을 본다(연동 별도 코드 0). 재조립 규약 = 파서omc_raw_fields와 동일. 🔑규격의 양면/단면도 같이 맞춘다 — 후면을 비워도 규격이 '양면'이면opFaceParts가 후면=전면으로 되살려 편집이 안 먹은 것처럼 보인다. 분리·편집은 발주처가 오엠씨인 블록만(오엠씨 화면·기존 탭 공통 규칙). - ② 시트(T) — 컬럼을 안 채우고 조회 시점에 파생시켰다(
orderpaper_dao._MT, 규격에 '시트' → T). 🔑저장값을 바꾸면item_key/block_key가sha1(…,material_type)이라 다음 동기화가 전 행을 새 행으로 만들어 사용자 편집·상태·사용이력이 끊긴다. 파생이라 기존 85건 + 추후 추가분이 마이그레이션 0으로 같은 규칙을 탄다. 화면 4곳(발주서정리·입고일정·자재관리 탭·오엠씨) 전부에 필터 버튼·색상(#2563eb)·정렬 반영. ⚠저장된 필터가S.mat를 통째로 덮어써 신규 분류가undefined=제외가 되므로 복원 시 기본값과 병합. 🔴파생의 대가 = 한 블록에 시트/비시트가 섞인다(운영 59블록 중 23) → 블록 일괄조작 4종 (block-status·block-receive-date·…-bulk·block-delete)에 자재분류를 같이 넘겨 그 섹션만 바꾸게 좁혔다. 안 고쳤으면 시트 섹션의 「상태 일괄」이 화면에 없는 부자재 행까지 바꿨다(오엠씨 화면엔 그 행이 안 보인다). - ③ 오엠씨 화면 — 현장 카드·업체 블록 기본 펼침(
OP_FOLDCFG.card/block=true, 완료 항목만 접힘) + 시트 섹션 최상단. 🔎시트는 오엠씨 발주가 아니다 — 시트업체(조운IMT·데코밸리·미림·엠제이실업…)에 발주해 오엠씨로 입고된다. 실측 발주처 오엠씨 + 규격 '시트' = 운영 0건 → 오엠씨만 걸면 시트 그룹이 영원히 빈다. 그래서 이 화면 데이터 =발주처 오엠씨 OR 자재분류 T. ⚠부작용 = 오엠씨 발주가 없고 시트만 있는 현장 카드도 뜬다(운영 4→5카드).
검증 = scripts/_omc_material_check.py {test|prod} 확장 — 테스트 ALL PASS + 운영 ALL PASS.
테스트에서만 쓰기 왕복 2건(①전면/후면 저장 → 서버 합친 품명 확인 → 원복 ②혼합 블록에 시트 한정 상태일괄 →
시트 2행만 바뀌고 비시트 3행 무변경 → 전량 원복). 운영은 읽기전용(펼침·스크롤·인페이지 함수만).
사이트맵 = 그룹8·페이지50·미반영 1(/production/sticker, 다른 세션 진행분).
⏳페페 = 운영 육안 — /omc/material(시트 그룹 최상단·전면/후면 편집) · /field/orderpaper(시트 필터·오엠씨 전면/후면).
❓판단 필요 1건 = 규격 9T MDF 시트/재고PP(피앤알, 1행)는 보드인데 규격에 '시트'가 있어 시트로 잡힌다.
아니면 자재관리 탭에서 그 행 규격을 고치면 된다.
🆕 NOW (2026-08-10) — QA 2건: 사이드 메뉴 스크롤 + 오엠씨 전용 자재관리(/omc/material) ✅운영배포 완료
페페 QA(qa_helper) = ①"사이드 메뉴 현재상태에서도 스크롤 되게. 하단 메뉴가 너무 밑에 있어 선택이 어려움. 하단 스크롤 시 시스템관리 이하로는 상단에서 벗어나지 않게 기준선 지정. 운영배포 승인" ②"오엠씨 전용 자재관리 페이지 생성. field/orderpaper 발주서 정리 탭 기준. 없어도 되는 것 = 현장별/업체별 토글· 동기화 사이드카 버튼·삭제/숨김(오엠씨 유저 작동 불가)·원자재 필터 동일 라인 모든 버튼·빠른필터 라인. 품명을 전면/후면 컬럼 분리해 후면 자재 표시(합친 컬러 때 있던 괄호 표기 제거). 운영배포"
배포 = master f956d27+3e80d33 → deploy-live f68f155(5파일 선별 포워드 · 임시 worktree).
운영 RDS에 patch45 선적용(menu_catalog OMC_MATERIAL 1행 + company_permission 오엠씨(196) 1행, 멱등).
① 사이드 메뉴 스크롤 — 🔴원래 스크롤이 아예 안 됐다. 테마가 .left-sidebar와 .scroll-sidebar를
둘 다 height:100%로 잡는데 그 위에 로고+사용자 블록(114px)이 얹혀 있어 스크롤 영역 아래 114px가 화면 밖이고,
scrollHeight==clientHeight라 perfect-scrollbar가 스크롤을 안 만든다(휠 실측 scrollTop=0).
→ pfs_layout.css §10 사이드바 세로 flex(스크롤 영역 = 남은 높이) + pfs.js pfsSidebarPad()가
기준선(시스템 관리)이 상단에 서는 만큼만 스크롤되도록 ul 하단 여백을 넣는다.
🔑여백은 계산이 아니라 실측 보정 — 짧은 콘텐츠는 scrollHeight가 잘리고, ps 레일(절대배치)이 8.5px를 더한다
(1차 구현이 기준선을 8.5px 넘겨 올라간 원인). 2패스 보정 후 오차 0.5px. 상세 = rules.md 🆕.
② 오엠씨 자재관리 — 화면을 새로 만들지 않았다. /omc/material(omc_controller)이 field_orderpaper.html을
omc_view=True로 렌더한다(인라인 JS 1,000줄 복제 0). 템플릿·JS가 그 플래그로 갈라진다 —
탭바·다른 탭 컨테이너/JS 3파일·분류토글·툴바(자재/숨김관리/업로드/동기화)·빠른필터 라인·칩·상세필터/업로드/숨김 모달 제외,
op-del-btn·블록삭제·숨김·현장연결/연결변경 제외(발주처가 pfs 현장 매핑을 바꿀 자리가 아니라 지시 목록에 없어도 뺐다),
OP_ALL을 적재 직후 발주처='오엠씨'로 필터(카운트·필터 옵션까지 이 집합 기준), OP_MODE='site' 고정,
opLoadState/opSaveState 스킵(메인 화면과 같은 localStorage 키라 해제 UI 없이 필터에 갇힌다).
품명 → 전면/후면 2컬럼(opFaceParts, 표 7→8컬럼). 편집(상태·입고일·발주량·비고)은 그대로 둔다.
- 🔴괄호가 자재넘버의 일부인 행이 실제로 있다(70-113(PP)·유사PP(WH240EMT)) → 공백 있는 ' (' 만 합친 표기로 본다. rules.md 🆕.
- 숨김 현장은 기존과 똑같이 제외한다(운영 오엠씨 130항목 중 99가 숨김 현장 → 화면엔 4현장 31항목).
숨김은 「유지·오엠씨 유저 작동 불가」라는 지시대로 버튼만 없애고 동작은 그대로 뒀다.
- 권한 = 오엠씨(196)만 부여. 에넥스(4)는 OMC_SHEET/BOARD 권한이 있지만 이 화면은 전 현장의 오엠씨 발주를 보여줘 제외.
포인(자사)은 명시 row 없으면 기본 허용이라 자동 노출.
검증 = 신설 scripts/_omc_material_check.py {test|prod} [뷰포트높이](미추적, 읽기전용 — 카드·블록 펼침과
스크롤만 건드리고 저장 버튼은 안 누른다, localStorage 원복) — 테스트 ALL PASS(뷰포트 700/800/1080) + 운영 ALL PASS.
전면/후면 규칙 9케이스를 페이지의 opFaceParts로 직접 호출해 검증 + 기존 /field/orderpaper 회귀(탭4·7컬럼·삭제버튼·탭JS 3개) 포함, 콘솔 0.
사이트맵 재빌드 = 그룹8·페이지 50(/omc/material 신규, live 반영 확인)·미반영 1 = /production/sticker(다른 세션 진행분, 본건 무관).
⏳페페 = 운영 육안 — ①사이드바 끝까지 스크롤(시스템 관리가 상단에 서는지) ②/omc/material 화면.
🆕 NOW (2026-08-07) — field/worklog 3탭 「통합현장」(통화+카톡 융합) ✅운영배포 완료
페페 지시 = "s25에서 읽는 내용(통화수집·카톡)과 pfs worklog 카톡방 내용을 융합. 모든 정보를 현장 매칭해 한 장소에서. 기존 탭 유지 + 새 탭. 진행중 현장 기준 + 최근 접수 있는 완료현장(미출고·신규접수 위주). 운영 배포 승인."
배포 = master 844fff8 → deploy-live c6277a9(4파일 선별 포워드 — worklog dao/service/controller + field_worklog.html).
- 신규 API
GET /api/worklog/fusion— worklog 이번주 창(source 게이트 없음 = 통화+향후 카톡 적재분 자동 포함, privacy·숨김현장은 기존 절 재사용) +kakao_board미러를production_status.field_status('10'대기중/'20'진행중/'30'완료) 기준 현장 카드로 조립. 진행중=전부 노출, 완료('30')=미출고 섹션+이번주 항목만(출고완료·기타 비움), 대기중/미상=내용 있으면 전부. - 방→현장 매칭 =
kakao_board.field_no직접 연결 우선 → 없으면 auto-link와 같은 게이트(점수80·유일승자·3자·커버리지)로 site_name→alias→room_name 순 유사도. 실패분은 「현장 미연결」 그룹으로 화면 하단 노출(정보 유실 금지). 게시글 섹션 분류는 '미출고' 판정을 '출고'보다 먼저('미출고'에 '출고'가 부분문자열). 「변동 반영 이력」은 로그라 제외. - 화면 = 모아보기 전용(편집은 1·2탭), 검색(클라 필터)·전체펼침·새로고침. 탭 배지=현장 수.
- 검증 = 신설
scripts/_worklog_fusion_check.py {--logic|test|prod}(미추적) — 로직 17 + 테스트 38 + 운영 38항목 ALL PASS (API 구조 8·창·정렬·완료필터 + UI 탭전환·카드수 일치·펼침·검색·1/2탭 회귀·콘솔 0). 읽기전용 GET이라 운영 실행 무해. - 운영 실측 = 진행중 6현장(금강 부산에코에 카톡 20행 매칭), 미연결 방 3(오엠씨 자재방·SGC 용두동·아이비젼 소물량방),
미연결 통화묶음 9. 🔎SGC 용두동 방이 미연결인 이유 = pfs 현장 목록에 유사명 현장이 없음(방 site_name "SGC 용두동 MH")
→ 현장 등록되면 자동 매칭, 또는 poin-agent
state.json의 site를 pfs 현장명에 맞추면 된다. - 사이트맵 재빌드 = 그룹8·페이지49·미반영 1(
/production/sticker— 기존 백로그, 본건 무관. AL 잔여는 걷힘)./field/worklog주황 없음. - ⏳페페 몫 = 운영 육안(
/field/worklog→ 3탭 「🧩 통합현장」) + 미연결 방·묶음 연결 판단.
🆕 NOW (2026-08-07) — qa_helper 다중선택(드래그 범위지정 + Ctrl선택) ✅운영배포 완료
페페 지시 = "qahelper 선택기능에 드래그·Ctrl선택 추가. 상황 판단해줘" → 판단 보고 후 "A로 진행. pfs 운영배포".
배포 = master adca587 → deploy-live ff85064(2파일 선별 포워드 = web/static/js/qa_helper.js + web/static/css/qa_helper.css).
A안 = N개를 1항목(묶음) + 코멘트 1개. 표 20칸에 코멘트 20개 쓸 일이 없다는 게 근거.
- Ctrl(⌘)+클릭 = 후보 토글 · 후보가 하나라도 있으면 그냥 클릭도 토글(모으는 중엔 클릭=토글이라 후보를 잃지 않는다)
- 드래그 = 밴드 범위 · Enter 또는 [🧺 묶음 담기] 로 확정 · Esc = 후보만 비움(검증 모드 유지)
- 후보 0에서 단순 클릭 = 종전 그대로 즉시 1항목(기존 동작 무변경)
- 항목 스키마는 members:[] 하나만 추가 → renderList·마크다운의 기존 경로를 그대로 쓰고 묶음 블록만 덧붙임
🔑 드래그의 핵심은 이벤트가 아니라 "밴드 안에 뭐가 잡히느냐"였다. 교차 기준이면 표 하나에
조상 컨테이너·tbody·tr·td·안쪽 span 까지 수백 개가 걸린다 → ①완전 포함만 ②후보의 조상은 제외(=최말단만,
Set에 조상 표시 O(n·depth) — 전수 비교 O(n²)보다 싸다) ③6px 미만 제외 ④상한 50(초과분은 토스트로 알림).
이벤트는 mousedown/mousemove/mouseup + 5px 임계(미만 = 단일 클릭), mousedown preventDefault(안 하면 페이지 텍스트가 같이 드래그 선택됨),
드래그 종료 직후 따라오는 click 1회 억제(안 하면 시작점 element 가 덤으로 잡힌다), 드래그 중 호버 하이라이트 OFF.
🔴 자체검사가 잡은 실버그 3건(전부 rules.md 🆕 에 함정으로 등록)
1. 밴드가 자기 자신을 후보로 잡는다 — #qa-helper-band 는 자기 rect 안에 완전 포함 + 자식 없음 = 완벽한 "최말단". isInsidePanel 제외 목록에 추가.
2. Enter 가 통째로 먹통 — picker 가 mousedown 을 preventDefault 하니 포커스가 사이드바 이름칸에 남는다. "패널 밖일 때만 Enter" 로 걸었더니 항목을 한 번이라도 담은 뒤엔 영영 안 먹었다 → textarea 만 제외.
3. 덤 = 「텍스트 보기」 다이얼로그가 검증 모드에서 안 닫혔다(기존 버그). 오버레이에 id 가 없어 isInsidePanel 에 안 걸렸고, document capture 의 stopImmediatePropagation 이 target 의 onclick 보다 먼저다 → id="qa-helper-export" 부여.
검증
- 신설 scripts/_qa_helper_multiselect_check.py — 로그인·서버 없이 도는 정적 하네스(임시 http.server + 실제 js/css 그대로) Playwright 37항목 ALL PASS. td 6개 드래그에서 조상 0 · 4px 박스 제외 · 60개 중 상한 50 · 콘솔 0.
- 신설 scripts/_qa_helper_live_check.py — 실서버. 테스트 26 + 운영 26 ALL PASS(/field/list, 셀 120개). 운영 드래그 = 후보 50 전부 leaf(A/BUTTON/SPAN/TD/TH), 포함관계 0, 페이지 이동 0, 콘솔 0, localStorage 원상복구.
- ⚠운영에서 돌려도 안전한 이유 = qa_helper 는 서버에 아무것도 안 쓰고(localStorage 뿐), 검증 모드가 클릭을 preventDefault 해서 조작이 서버로 안 나간다.
- 사이트맵 재빌드 = 그룹8·페이지49·미반영 1(= /production/sticker 생산 스티커, 이번 건과 무관한 별건 백로그). meta 에 test adca587 / live ff85064 반영 확인.
- 배포는 임시 worktree 로 했다 — 작업트리에 페페의 미커밋 수정(orderpaper-sync/*)이 있어 git checkout deploy-live 가 그걸 건드린다.
⏳페페 = 운영 육안(🔍 토글 → Ctrl+클릭 몇 개 → Enter → 사이드바에 🧺 배지 / 표 위에 드래그).
⏳안 한 것 = devplan 쪽 assets/qahelper.js 포팅(지시가 pfs 만이라 그대로 뒀다).
🆕 NOW (2026-08-07) — 부자재 발주서 업로드 "안전하지 않은 접속" 운영배포 완료
페페 QA = 「+ 부자재 발주서 업로드」로 파일을 고르면 "안전하지 않은 접속"이라며 진행이 안 됨.
원인 = 브라우저가 HTTPS 페이지에서 사설 IP(HTTP)로 form POST 했다.
opUpload() 가 http://192.168.45.2:8791/upload(사무실 PC 사이드카)로 새 탭 form POST → 크롬 혼합콘텐츠 차단.
게다가 그 경로는 이미 두 겹으로 더 막혀 있었다 — 26.7.29 보안조치로 사이드카가 127.0.0.1 바인딩 + 토큰 필수
(브라우저는 토큰을 못 붙인다). 즉 LAN 직결은 되살릴 값이 아니라 없앨 경로였다.
고친 방식 = 이미 있던 서버 업로드 API 를 쓰고, 사이드카는 릴레이로 돌린다(동기화 sync-request 와 같은 모양).
1. 화면 → POST /api/orderpaper/upload(같은 오리진 HTTPS·FormData) → EC2 가 blob 을 orderpaper_upload(pending)에 저장.
🔑이 엔드포인트·테이블은 원래 있었는데 화면이 안 쓰고 있었다(운영 테이블 0행 = 한 번도 안 탄 죽은 경로).
2. 사무실 PC 사이드카(orderpaper_sync_server.py)의 upload_poll_loop 가 20초마다
POST /api/orderpaper/upload/claim → 파싱(orderpaper_upload_parsers) → 적재(orderpaper_upload_load, SSM)
→ POST /api/orderpaper/upload/finish. 인증 = X-PFS-Agent-Token(door_sync_watch 와 같은 토큰).
3. 화면은 upload_no 로 /api/orderpaper/uploads 를 폴링 — 대기 → 분석·적재 중 → ✅완료(목록 자동 갱신)/❌사유.
4. 사이드카의 LAN 전용 POST /upload 삭제(경로 이중화 방지) · running 10분 초과 건 자동 재점유.
덤으로 잡은 것 3개
- 🔴insert_upload 가 항상 upload_no=0 을 반환(= MySQLUtil.execute + 별도 SELECT LAST_INSERT_ID() 는
커넥션이 달라진다) → execute_id 로 교체. 그대로 뒀으면 업로드가 성공해도 화면이 영원히 "대기"였다.
- 🔴nginx client_max_body_size 가 아예 없어 기본 1MB(실측 1.43MB → 413) → nginx.conf http 블록 20m
(서버 파일·git 밖, nginx -t 통과 후 reload, 백업 nginx.conf.bak_20260807). 화면도 413 이면 크기 초과라고 안내.
- 🔴사이드카 폴링 try 가 env 루프 바깥이라 운영 401(미배포) 하나로 테스트 폴링까지 굶었다 → 안쪽으로.
같이 _sidecar.log 신설(창 없는 상주라 출력이 사라져 진단 불가였다).
파서는 서버에 안 올렸다 — EC2 py3.6 에서 pdfplumber 가 chardet 5.0(앱 requests 2.21 과 충돌)·cryptography 40
(certbot)을 끌고 온다(pip download 실측). xlrd·pdfplumber 는 사무실 PC(Python39)에만 설치.
검증 = ①테스트 릴레이 E2E 12항목(에넥스 양식 .xls 를 xlwt 로 만들어 실파서 통과 · blob 바이트 동일 ·
적재·원상복구까지) ②live 사이드카 8항목(상주 프로세스가 집어가는 실경로) ③실브라우저(테스트 = 업로드→
✅ 2건 적재·콘솔 0 / 운영 = 새 코드 적재 확인, OP_SYNC_URL 소멸) ④운영 스모크 4항목(미등록 양식 .txt 로
경로만 태우고 행 삭제 — 운영 데이터 무변경). 사이트맵 = 그룹8·페이지49·미반영 2(기존 AL 백로그, 증가 없음).
배포 = 테스트 12a9b31 · 운영 bac884b(master 1f497ea+58b6809+12a9b31 7파일 선별 포워드).
⚠사무실 PC 사이드카가 꺼져 있으면 업로드는 "대기"에서 멈춘다(2분 뒤 시간초과 안내).
🆕 후속(같은 날) — 페페 실업로드에서 적재 내용이 깨졌다 → 파서 재작성·재적재 완료
증상 = 대우 용인 에넥스 발주서를 올렸더니 128행이 들어왔는데 절반이 빈 품명, 업체는 전부 '천일'. 원인 = 파서가 양식을 몰랐다. 에넥스 .xls 는 한 시트에 발주 페이지가 반복되는데(수신처=업체 1곳당 1페이지, 실측 407행·11페이지) 옛 파서는 첫 페이지 머리만 읽고 11행~끝을 통째로 한 업체 항목으로 봤다 → 라벨행('품 목/규 격/수량'·'계'·'특이사항'·'발 주 일'…)까지 자재로 적재되고 나머지 10개 업체는 소실.
수정(orderpaper_upload_parsers.parse_enex) — A열 '수 신 처'를 페이지 머리로 블록 분할,
페이지마다 업체·발주일·납기 읽기, 표는 머리+6행부터 '계' 전까지, 표 안 고정 안내문('포인 : …') 제외,
비고 열 오타 8↔9 수정, 납기 문자열('추후통보')은 날짜 비움, 🔑같은 업체 2페이지(쿠스코)는 block_key 가
겹쳐 뒤가 앞을 덮어쓰므로 sheet에 페이지 번호를 넣어 분리.
재적재 = 사용자 편집·사용량 이력 0건 확인 → 원문 128행 JSON 백업(/home/ubuntu/backup/
orderpaper_daewoo_badload_2026-08-07.json) → 삭제 → 업로드행 pending 되돌림 → 사이드카 재처리
(⚠파서는 sys.modules 캐시라 사이드카 재시작 필수) → 11블록·55항목.
검증 = 실파일 파서 체크 12항목 ALL PASS(scripts/_op_enex_parse_check.py) · 운영 DB 55행·업체 10곳
(쿠스코 2블록) · 표본 20행 품명/규격/수량/비고 정상 · 운영 화면 55건·콘솔 0.
배포 = master 674102e · 운영 2d0bbd2(사이드카 파일이라 서버 앱과 무관, 브랜치 동기화용).
🆕 2차 후속 — 품명 상속(페페 지시 "①규격·발주량은 있는데 품명이 없으면 위 품명을 이어받는다
②품명이 쌍따옴표면 동일"). 원본은 같은 품목이 이어지면 품명칸을 비우거나 "(〃)로 쓰는 수기 관행이라
그대로 넣으면 화면·발주에서 품명 없는 행이 된다(실측 빈칸 10 · 따옴표 3). 상속은 블록(업체) 안에서만.
🔑재적재는 삭제 없이 pending 되돌림만 — item_key 가 그대로라 로더가 같은 행을 UPDATE(55행 유지·
삭제 0·*_user 편집 보존). 검증 = 파서 18항목 ALL PASS · 운영 DB 빈칸 0·따옴표 0·업체 10·블록 11 ·
운영 화면 55건·콘솔 0(예: 헤티 2~4행이 이노텍 아티라레일470 을 물려받음). 배포 = master 971fed7 · 운영 bdaff93.
⏳페페 = 화면 육안(업체별 블록·품명 상속).
🆕 (참고) 원 검토 메모 — 미니PC 이전 타당성
- 🔴전제가 틀렸다 = 테스트는 별도 EC2가 아니다. 운영·테스트가 같은 t3.medium 1대(
i-03225ba8bc12a929e)에 8000/8001 포트로 얹혀 있다. 앱만 미니PC로 빼도 EC2 절감 0. 따로 있는 건 RDS 뿐(poin-dbinstance-test). - 실측 비용(2026-07 · Cost Explorer) = 총 $86.4/월 — EC2 compute
$37.44(t3.medium 720h) · EC2-Other$6.43(EBS·EIP) · RDS$42.44(인스턴스$37.20= db.t4g.micro 2대 + GP2 20GB×2$5.24) · S3 등$0.09. → 테스트 이전으로 실제 줄어드는 돈 = RDS-test 1대$21.2/월(≈3만원, 전체의 24%). ※6월 RDS$57.83은 7월보다 높다(스냅샷·클래스 이력 추정, 미조사) — 러닝레이트는 7월 기준이 맞다. - 환경 차이 = 관리가 갈린다(나쁜 쪽): 미니PC는 Windows, 운영은 Ubuntu+nginx1.14+uWSGI+systemd.
①uWSGI는 Windows에서 안 돈다 → waitress 등으로 갈아타면 테스트에서 통과한 게 운영 보증이 안 된다
(
uwsgi-die-on-term-killsignal-conflict같은 배포계층 사고를 테스트가 못 잡는다) ②배포경로 = push→Actions→SSM send-command인데 미니PC는 SSM 대상이 아니라 러너를 따로 만들어야 하고, 그러면 배포 절차 자체를 테스트할 수 없다(현재 테스트의 최대 가치) ③pfs-test.poin.co.kr+Let's Encrypt → Funnel/사설 경로로 바뀜 ④검증 러너scripts/_*_check.py {test|prod}가 미니PC 다운·터널 끊김에 묶인다 (vscode-remote-ssh-poin-mini-timeout전례) ⑤운영 데이터 사본이 사무실 밖 PC에 앉는다. - 더 싸고 안 아픈 대안(코디 추천 순) = ①RI/Savings Plan 1년 무선결제(환경변화 0) — 공표요율 대략
EC2
-$11~14/RDS 운영분-$6= 월 $17~20 절감 ②RDS-test 삭제 → EC2 안에 MySQL 8.4 직접 설치 (같은 OS·같은 배포경로 유지, 절감$21전액, t3.medium 4GB에 테스트 부하는 미미) ③RDS-test 야간·주말 정지 (-$12, 단 7일 뒤 자동 재시작이라 스케줄러 필수). ①+② = 월 $39(45%) 절감, 환경 변화 거의 0. - ⏳페페 몫 = 방향 택1(①+② 추천 / 미니PC 이전 강행 / 현상 유지).
🆕 NOW (2026-08-06) — 견적서 재작성 + 현장 단위 차수 이력 ✅운영배포 완료
- 운영 커밋 = deploy-live
ff48c8b← masterc69c2d8+641ff825파일 선별 포워드(merge 아님). 대상 파일에 다른 미반영 커밋이 걸쳐 있었지만git diff origin/deploy-live origin/master -- <file>실측이 내 변경분뿐임을 확인하고 진행했다(커밋 목록은 cherry-pick 이력 탓에 과대계상 — playbook §2). - 운영 RDS 선행 =
ALTER TABLE estimate ADD COLUMN archive_yn CHAR(1) NOT NULL DEFAULT '0' AFTER remove_yn→ 674행 전부'0'확인 후 배포(scripts/_estimate_archive_ddl.py, ENV_PATH=pfs-live.env, 멱등). - 운영 검증(신설
scripts/_est_revisions_prod_check.py) = 18항목 ALL PASS · 읽기 전용. 🔑Playwrightpage.route로 POST/PUT/DELETE(/select·/rewrite·/archive·삭제)를 아예 차단해 두고 돌렸다(차단기 발동 0 = 오조작 없었다는 증거). 확인 = 본견적 32건·보관 0·차수2↑ 현장 0 · 행에 「차수 1」·「재작성」 · 모달 GET 만으로 렌더(쌍용 홍은동 1차 6항목 6,500,000 「사용 중」, 사용 중 행엔 전환 버튼 없음) · 견적 단건·출력 200 · 현장검색 34건 카운트 1 · 월마감 후보 11건 불변 · 콘솔 0. - 사이트맵 재빌드 = 그룹8·페이지49·미반영 10 → 2(남은 2 = 기존 AL 백로그). devplan
pfs.htmlPENDING→DONE. - ⏳페페 몫 = 운영 육안(
/estimate/list-v2→ 아무 견적 「차수 1」 눌러보기. 실제 재작성은 진짜 현장에서만).
(테스트 단계 기록) 견적서 재작성(1차 보관 + 2차 메인) + 운영 708 이관
페페 지시 = "한 현장 견적서를 새로 작성해야 하는 경우가 있다(도면 디자인이 아예 바뀜).
기존 1차 작성분은 보관처리, 신규 2차 작성분을 본건 메인으로 앞에." →
"테스트서버 작업 진행하고 운영서버의 modify-v2/708 현장 견적서를 옮겨줘. 1차 원본으로 삼고 테스트."
- 구현(master
c69c2d8→ 테스트 자동배포 확인, 운영 미반영) =estimate.archive_yn char(1) DEFAULT '0'하나로 끝냈다. 차수 컬럼·이력 테이블 없음. ① 🔑1:1 가드는 한 줄도 안 고쳤다 —select_site_search의estimate_count서브쿼리에AND e.archive_yn='0'만 넣으니, 1차를 보관하는 순간 그 현장이 다시 선택 가능해진다. ② 목록 = 보관건 기본 숨김 + 「보관 포함」 체크박스, 「보관」 배지 + 배경#eceff1(글자색은 안 건드림). ③ 「재작성」 = 1차 보관 → 헤더(현장·업체·담당자·지불조건·마진)만 물려받은 빈 2차 생성 → 그 수정화면으로 이동. 항목 복사 없음. 이름… (2차)→… (3차)(정규식으로 차수 증가). ④ 「보관해제」는 그 현장에 활성 본견적이 없을 때만(1:1 유지). 추가건은 본건과 함께 보관(OR parent_estimate_no=). ⑤ 월마감 후보(select_candidates)에서 보관건 제외 — 안 빼면 1차·2차가 이중 집계된다. - 🔴덤으로 잡은 것 = 실패가 성공으로 새어나간다 — 공용
ajaxSuccessProcess는 code"2000"만 실패로 보는데 서버 예외는"9999"라, 보관해제 거부 사유가 화면에 안 뜨고 성공처럼 지나간다 (RestResponsePFS-D002 미이관 구간). 이 화면 두 호출만_v2ApiFail(data)로 code 직접 판정. - 운영 708 이관 = 「대우 용인 MH 견적서」(field 2109·에넥스/김동연, detail 50·sub 53·extra 0·43,563,000) →
테스트 견적
797. 테스트 708 은 이미 다른 견적(일레븐 파크사이드, 삭제됨)이라 번호를 못 쓴다. 참조(field 2109·company 4·member 400·user 1)가 테스트에 같은 번호로 이미 존재해 그대로 붙였다. 행 대조 50/53 전량 일치. ⚠합계만 11.09원 차이 = 운영float컬럼의 표시 밖 잔재(490417.03125 류)가 이관 때 정수로 정리된 것. 화면값·total_amount는 동일. - 검증 = 신설
scripts/_estimate_archive_check.py(미추적) 테스트 32항목 ALL PASS — 재작성 클릭→2차 수정화면 도착·헤더 프리필·항목 0·목록에서 1차 사라짐·「보관 포함」 복귀(배지·배경·버튼 구성)· 현장 견적수 1 유지·보관해제 거부 사유·월마감 후보 교체·콘솔 0, 끝에 원상복구(2차 삭제+1차 보관해제) 까지 확인. 뒤처리 러너_estimate_archive_cleanup.py(항목 있는 견적은 절대 안 지우는 가드). 현재 테스트 상태 = 797 활성 1건만(페페가 처음부터 눌러볼 수 있게 깨끗이 되돌림). - 사이트맵 재빌드 = 그룹8·페이지49·미반영 2→10(이번 커밋이 운영 미반영이라 정상 ·
/archive·/rewrite신규 라우트 포함). devplanpfs.htmlPENDING 에c69c2d8등록(운영 DDL 선행 필요 명시). - ⏳페페 몫 = 테스트 육안(
/estimate/list-v2→ 현장명 「대우 용인」 검색 → 재작성 눌러보기). 운영 반영은 지시 때 — DDL(archive_yn) 먼저, 그 다음 배포.
🆕 현장 단위 차수 이력으로 개편 (페페 지시 26.8.6 · master 641ff82 테스트 배포)
페페 지시 = "보관 항목은 현장별 이력관리가 맞다. 지금은 보관 항목 찾기까지 과정이 복잡하고 1차·2차 위치가 안 붙어 있어 비교가 오래 걸린다. 한 현장 기준으로 확인·복구 가능한 구조로 개변. 1차를 복구하면 2차는 삭제가 아니라 보관. 항상 보관 안 된 항목 = 선택된 차수, 나머지는 보관."
- 🔑불변식 = 「보관 안 된 것이 곧 지금 쓰는 견적서」(현장당 정확히 1건). 그래서 되돌리기는 '보관해제'가 아니라 자리 바꾸기다 — 옛 차수를 고르면 쓰던 차수가 보관으로 내려간다(삭제 아님).
- 목록 행 「차수 N」(그 현장 차수 개수 =
revision_count서브쿼리) → 모달에 그 현장 전 차수를 한 표로: 차수·견적명·견적일·작성자·항목수·추가건·금액·상태. 최신이 위, 사용 중 행은 배경#e8f5e9. 옛 차수에만 [이 차수 사용], 모든 차수에 [보기]·출력. - 보관해제 토글 폐지 —
PUT /<no>/archive→PUT /<no>/select. 활성 0 상태를 만들 수 없고, 되돌리기가 삭제를 요구하지도 않는다.count_active_main_on_field(거부 가드)는 죽은 코드라 제거. switch_active_estimate= 트랜잭션 2문(그 현장 전부 보관 → 고른 것만 활성). 추가건은 부모로 잡는다 (LEFT JOIN estimate p ON p.estimate_no=e.parent_estimate_no— 추가건은field_no가 비어 있을 수 있다). 재작성도 끝에 같은 스위치를 태워 옛 차수가 여럿이어도 한 번에 정리된다.- 검증 = 신설
scripts/_estimate_revisions_check.py21항목 ALL PASS(모달 2차 비교·전환· 🔑remove_yn=0유지 실측·모달 그 자리 갱신·「사용 중」 항상 1건·목록 반영·현장 견적수 1·콘솔 0· 시작 상태 복원). 테스트 현재 = 801 사용 중 · 797 보관(페페가 눌러본 상태 그대로 돌려놓음).
보관건 열람·복구 경로 (페페 질문 26.8.6 · 읽기전용 실측 8항목 ALL PASS · 「보관해제」는 위 개편으로 대체됨)
- 열람 = 목록에서 「보관 포함」 체크 → 검색 → 보관 행(회색+「보관」 배지)의 [수정] 이면 항목·타입·금액이
그대로 열린다(실측 = 타입 5탭·항목 렌더·이름/현장/업체 정상). [출력] 도 됨(
print-v2200 · 엑셀 API 200). URL 직접(/estimate/modify-v2/<번호>)도 열린다. 🔑열어서 저장해도 보관은 안 풀린다 —update_estimate가archive_yn을 안 건드린다(실측 archive_yn=1 유지). - 복구 = 같은 자리의 [보관해제]. 단 그 현장에 활성 본견적이 없어야 한다(1:1). 2차가 살아 있으면 「이 현장에는 이미 사용 중인 견적서가 있습니다」로 거부 → 2차를 [삭제]한 뒤 해제하면 1차가 항목·금액 그대로 돌아온다.
- 🔴갭 = 2차를 살려둔 채로는 맞바꿀 수 없다. 활성 행에 수동 「보관」 버튼이 없어서(보관 경로가 「재작성」뿐)
2차를 내리려면 재작성으로 빈 3차를 만들거나 2차를 지워야 한다. 최소 수정 = 활성 행에 「보관」 버튼 1개
(API
PUT /api/estimate/<no>/archive {archive_yn:'1'}는 이미 있다 · JS 는unarchiveV2대칭 1함수). ⏳페페 지시 대기. - 테스트 현재 상태 = 797 보관(항목 50 온전) + 801 활성 빈 2차(페페가 재작성을 눌러본 상태 — 코디가 안 건드렸다).
(이전) 계획 확정 기록
페페 지시 = "한 현장 견적서를 새로 작성해야 하는 경우가 있다(도면 디자인이 아예 바뀜). 기존 1차 작성분은 보관처리, 신규 2차 작성분을 본건 메인으로 앞에. 계획 먼저."
- 🔴실측 = 지금은 2차를 만들 방법이 아예 없다 —
estimate_regist_v2.js:2142가 현장 선택 팝업에서 "이미 견적서가 있는 현장입니다. 현장:견적서는 1:1입니다" 로 현장 선택 자체를 막는다. 근거 카운트 =field_dao.select_field_list_for_estimate의estimate_count(추가건 포함·remove_yn='0'). - 파급 조사 = estimate 를 참조하는 다른 모듈은 월마감뿐(
monthly_close_dao:177 후보수집 · :89 집계). worklog·발주서정리·현장은field_no기준이라 무관. 견적 목록 v2 = 본견적만(parent IS NULL)·생성일 desc. - 확정 계획(P1) = ①컬럼 1개
estimate.archive_yn char(1) DEFAULT '0'(차수 컬럼·이력 테이블 안 만듦) ②1:1 가드는 안 건드린다 —estimate_count서브쿼리에AND archive_yn='0'한 줄이면 1차를 보관하는 순간 그 현장 신규 등록이 저절로 열린다 ③목록 = 보관건 기본 숨김 + 「보관 포함」 체크박스(페페 택1), 보관 행 회색+배지, 정렬 그대로라 2차가 자동으로 위 ④「보관」 버튼 = 본건+추가건 동반, 토글 해제 시 같은 현장에 활성 본견적 있으면 차단 ⑤「재작성」 = 1차 보관 → 새 등록 화면 헤더 프리필(현장·업체· 담당자·마진율만, 1차 항목 복제 안 함 — 페페 택1) ⑥월마감 후보·집계에서 보관건 제외(안 빼면 이중 집계) ⑦검증 러너scripts/_estimate_archive_check.py {test|prod}(DB+실브라우저), 테스트 배포까지. - ⏳페페 몫 = 착수 지시(운영배포는 별도 지시 때).
🆕 NOW (2026-08-06) — 대우 용인 오엠씨 탭 1페이지 초기화 + 재입력(운영 데이터, 코드변경 0)
페페 지시 = "\\192.168.0.101\공유폴더\2026현장\원부자재발주서\07월\에넥스 대우 용인 푸르지오 MH
원부자재발주서.xlsx 의 오엠씨 탭 1페이지 내용을 바꿨다. 행자체가 사라지거나 수정을 했으니
기존 동기화 내용을 초기화하고 이 탭만 PFS field/orderpaper 에 새로 입력해줘. 운영배포."
- 오엠씨 탭은 섹션이 1개 = 「1페이지」 =
block_key fe00af48…(=sha1(파일|오엠씨|0|R)) 하나로 딱 떨어진다. 엑셀 현재값 = 11항목(발주번호 2·3·5·6·7·8·10·11·12·13·14), 발주 2026-08-06 · 입고 2026-08-11. - 왜 그냥 동기화로는 안 됐나(초기화가 필요한 실제 이유 2개, 운영 실측):
① 그 블록 4행이
del_manual='1'(화면에서 ✕ 로 지운 상태)이라 동기화 UPDATE 가remove_yn=IF(del_manual='1','1','0')로 계속 '1' 을 박는다 → 엑셀에 살아 있어도 화면에 영원히 안 뜬다. ② 남은 7행엔 옛 사용자편집·재고가 붙어 있었다 —receive_date_user='2026-07-14'(화면은 COALESCE 라 엑셀 입고 08-11 대신 07-14 를 보여준다),stock39/7 등이 발주량과 무관한 옛 라운드 값.item_key가sha1(파일|탭|섹션|자재구분|**idx**)라 중간 행이 빠지면 idx 가 밀려 옛 행의 편집이 다른 자재에 상속된다. 그래서 「초기화」의 실체 = 이 블록만 행을 지우고 신규 INSERT 로 다시 받기. - 실행 =
orderpaper-sync/_reset_daewoo_omc_prod.py(SSM) → 12행 DELETE(active 7 + removed 5, 잔여 0) →python orderpaper_sync.py prod R_omc_reset_20260806→ ins 11 / upd 1746 / removed 0. 가드 =source_file+block_key정확일치 + 전 행vendor='오엠씨'·material_type='R'·source_kind='nas', 삭제 전 12행 전량 JSON 출력(롤백 자료). 사용이력(orderpaper_usage_history) 0건 확인 후 삭제(있으면 중단하는 가드).orderpaper_site_map은 손대지 않아 현장연결 field_no=2109 유지. - 검증(신설, 미추적) =
orderpaper-sync/_verify_daewoo_omc_prod.py(운영 DB 33항목 ALL PASS) +scripts/_op_daewoo_omc_screen_check.py prod(운영 화면 43항목 ALL PASS, 콘솔 0). DB = 11행·엑셀 11항목 전량 대조(품명·규격·발주량)·remove_yn=0·del_manual=0·status=대기·*_user전부 NULL·stock=발주량·발주 08-06/입고 08-11 · 다른 탭 행수 초기화 전과 동일. 화면 = 발주서정리 「대우 용인」 카드 → 오엠씨 블록 「11건 · 발주 8.6(목) · 기본입고 8.11(화)」, 항목행 11개 렌더 + 자재관리 탭에도 노출(3개월 창 통과 — 입고 8.11 이 창 안). - 커밋 없음 = 코드 변경 0(운영 RDS 데이터 작업 + 미추적 스크립트). 사이트맵 재빌드 = 그룹8·페이지49·
미반영 2(초기화 전과 동일 · 둘 다 기존 AL
al-orderpaper·al-profile백로그). - ⏳페페 몫 = 운영 육안(
/field/orderpaper→ 「대우 용인」 → 오엠씨 블록 11건 · 지웠던 2·3·5·6번이 다시 뜨는지 · 입고일이 8.11 로 보이는지). ⚠재고량이 발주량으로 초기화됐으니 손으로 넣어둔 재고가 있었다면 다시 기입해야 한다.
🆕 NOW (2026-08-06) — 카톡관리 수정창 자동높이 + 편집 중복 방지 3중 게이트 운영배포 완료
페페 지시(QA 보고 /field/worklog) = "수정 내용이 많은데 수정창 높이가 너무 낮다. 텍스트 내용에 맞춰서
수정창 높이도 늘려줘. 그리고 사용자가 편집하면 내용이 중복되지 않게 코디가 체크하는 프로세스 있는지
확인해서 보완해줘. 운영배포."
- 수정창 =
.kb-row textarea가min-height:64px고정이라 10줄짜리 항목도 3줄만 보였다. →kbGrow()가scrollHeight로 높이를 맞추고 입력마다 재계산(늘고 줄고 둘 다). 상한max-height:60vh(그 위로만 스크롤 — 창이 화면을 삼키지 않는다).resize:vertical은 남겨 사람이 더 늘릴 수 있다. 운영 실측 = 3줄 항목 76px → 15줄 309px → 120줄 570px(=60vh 상한, 그때만 스크롤). - 중복 검사는 「있는지 확인」의 답이 "어디에도 없었다" — 화면·서버·데몬 어느 층에도 없었다. 3중으로 신설.
판정 기준은 셋 다 같다 = 같은 섹션 · 첫 줄 동일(표기 접두사
[완료]·※추가·※수정는 떼고 본다). 첫 줄로 보는 이유 = 그게 행 id 의 근거(board_rows._ids=sha1(섹션+첫줄+등장순번))다. 같은 문구가 둘이면 id 가 등장순번으로만 갈려서, 앞 행이 사라지는 순간 뒤 행의 id 가 조용히 바뀐다 → 그 뒤의 수정·삭제가 엉뚱한 행을 잡는다. 그래서 그런 쌍을 애초에 못 만들게 막는 게 근본수정이다. ① 화면(kbDupRow) = 「적용(표시만)」 단계에서 막고 토스트로 알린다. 아직 저장 안 한 표시(KB_PEND)까지 반영해 비교한다 — 수정 표시가 걸린 행은 그 수정문으로, 내려갈 행(완료·취소·삭제)은 대상에서 뺀다. ② 서버(add_op) = 미러(rows_json) 대조로 같은 내용 거부 + 같은 행에 대기 중 명령이 있으면 거부. 뒤엣것이 중요하다 — 미러는 데몬이 반영해야 갱신되니 그 30~60초 사이에 같은 행을 또 고치면 화면은 옛 내용을 보여주고, 나중 명령이 앞 명령을 덮어써 방금 쓴 내용이 조용히 사라진다(중복 등록 → 유실). ③ 데몬(board_rows.edit/restore) = 마지막 관문. 웹이 PFS·devplan 둘이고 ack 유실 시 명령이 재배달 되므로(그때restore는 같은 줄을 또 붙인다) 화면 검사만으론 못 막는다. - 검증 = 신설
scripts/_kakao_board_edit_check.py {test|prod} [--api](미추적) — 테스트 26 + API 6 · 운영 26 ALL PASS. 높이는 픽셀 실측(열자마자 스크롤 0 → 늘림 → 줄임 → 60vh 상한), 중복은 같은 섹션 다른 행 문구로 실제 클릭. 운영은 저장을 누르지 않는다(누르면 고객 단톡방이 바뀐다). scripts/test_kakao_board.py13→15항목(대기 중 같은 행 거부·같은 첫 줄 거부/다른 섹션 허용/자기 자신 제외),board_rows.py자체검사(중복 수정 거부·다른 섹션 허용·복원 재배달 거부).- 커밋 = master
cec85c6+229b61d→ deploy-live11e235e(4파일 포워드, merge 아님). poin-agenta5a5e45(로컬 리포). 데몬 재시작 완료(watcher PID 12084). 사이트맵 3→2(/field/worklog걷힘). - ⏳페페 몫 = 운영 육안(카톡관리 → 방 펼쳐 긴 항목 ✎ → 창이 내용만큼 열리는지 · 다른 행 문구를 붙여넣고 「적용」 → 「중복이라 등록하지 않았습니다」 토스트가 뜨는지).
🆕 NOW (2026-08-05) — 카톡관리 「변동 반영 이력」 ✖ = 소프트딜리트(숨김 이력) 운영배포 완료
페페 지시 = "카톡게시글 관리에서 변동 반영 이력 항목은 삭제가 소프트딜리트가 아니라 실제삭제라고 안내메시지가 나온다. 소프트딜리트(숨김항목으로 이동)로 수정해줘. 운영배포."
- 원인은 안내문이 아니라 구멍이었다 — 이력 행은 로그라서 오조작 방지로 ✔완료·⊘취소를 뺐는데(2026-07-28),
그 결과 ✖ 말고 내릴 방법이 없는데 그 ✖ 가 실제 삭제였다. 다른 행은 완료·취소로 이미 소프트 경로가 있다.
→ 이력 행의 ✖ 만
action:'hide', status:'삭제'로 바꿔 숨김 이력에 남기고 ↩ 복원이 된다. 다른 행의 ✖ 는 손대지 않았다(2026-07-28 페페 지시 "종결 항목 빠른 정리" — 지시 밖). - 두 리포를 같이 고쳐야 한다 = PFS
VALID_STATUS와 사무실 PC 데몬board_rows.STATUSES가 짝. PFS 만 늘리면 데몬이ValueError→ 화면엔 「반영 실패」로만 뜬다. 순서 = 데몬 먼저 + 재시작 → 배포. 상주sgc/watcher.py는 import 를 붙들고 있어 재시작 필요(상승권한 불요·완료), 예약작업PFS-KakaoBoard-Sync(1분)는 매번 새 프로세스라 파일 수정 즉시 반영. 상세·재시작 명령 →rules.md 🆕 - 판정은 기존과 같은 한 줄(
섹션명에 '이력') 재사용 — 새 API·새 컬럼·새 테이블 0. 화면엔 이력 행에data-log="1", ✖ 툴팁 2종("숨김 이력으로 보냅니다(복원 가능)" / "이력에 안 남습니다"), 숨김 이력 「삭제」 라벨은 빨강. devplankakao-ops.html도 같은 라벨색만 맞춰 뒀다. - 검증 = 신설
scripts/_kakao_board_softdelete_check.py(미추적) — 테스트 28항목 + 운영 24항목 ALL PASS. 테스트는--api로 실왕복까지(status=삭제 수락 · 허용 밖 「보류」는 여전히 거부 · 큐 저장 확인 → ack 로 정리). 운영은 저장을 누르지 않는다 — 누르면 고객 단톡방 게시글이 실제로 바뀐다. 클릭→KB_PEND 페이로드까지만 확인. board_rows.py자체검사(실제 「■ 변동 반영 이력」 섹션에서 hide('삭제')→restore 왕복) ·test_kakao_board.py13항목. ⚠1차 실행 5건 오탐 = 검증이 방을 안 가뒀다. 행 id 는 방이 달라도 같은 문구면 같은 값(sha1(섹션+본문+순번)).- 커밋 = master
c0129d2→ deploy-live0a75e3a(3파일 선별 포워드, merge 아님 — AL 미배포건이 끌려온다). poin-agent4889937(로컬 리포·리모트 없음). 사이트맵 재빌드 2회 = 배포 전 미반영 3 → 배포 후 2 (/field/worklog주황 걷힘, 남은 2건은 기존 ALal-orderpaper·al-profile). - ⏳페페 몫 = 운영 육안(
/field/worklog→ 카톡관리 → 방 펼쳐 「변동 반영 이력」 행 ✖ → 저장 → 30초 뒤 숨김 이력에 「삭제」로 뜨는지).
🆕 NOW (2026-08-05) — 견적서 엑셀 양식 파일 채우기 전환 · 운영배포 완료 + 운영 다운로드 E2E
페페 판단 = "①「아래와 같이 견적합니다」 타입명 살린 상태 유지 ②결재칸 현재대로 유지. 이 양식으로 pfs 견적서 생성 파일 교체해라. 운영 배포. 실제 견적건 1개 playwright로 다운받아서 동일 test 파일에 저장까지 테스트. 운영서버에서 다운로드 테스트."
- 운영배포 = deploy-live
a485b23(4파일 포워드) +9482849(일자 서식 후속). master01d5f43·b11c8a5. merge 아님 — 파일단위 포워드. 사전확인 = 대상 4파일에 걸친 미반영 커밋이 내 것뿐임을--cherry-pick --right-only로 확인. 배포 후 잔여 미반영 = AL 12파일뿐(기존 백로그), 견적서 파일은 전부 반영됨. - 🆕다운로드 E2E =
scripts/_estimate_excel_download_e2e.py {test|prod} [저장경로] [견적번호]. 로그인 → 견적목록 → 품목 있는 건 자동선별 → 출력화면 → 「엑셀」 버튼 클릭 → 실제 내려받은 파일을 열어 템플릿과 서식 대조. 테스트 10항목 PASS / 운영 11항목 PASS(운영 견적 744 「넵스 쌍용 홍은동 MH」 — NAS 실물과 같은 현장, 본건 2블록·품목 6줄·6,300,000 일치, 콘솔 0). - 🔑함정 3개(전부 이번에 물림):
① 로그인은 폼 submit 이 아니라 JS
login()→page.evaluate("() => login()")후 URL 변화 대기. ② 목록 행에 견적번호가 안 박혀 있다(JS 클릭 핸들러) →/api/estimate/응답에서 뽑는다. 봉투 키는message(data/result 아님). ③ 블록 수를ws.max_row로 세면 안 된다 — 인쇄영역($O$n)에서 센다. 템플릿은 인쇄영역 밖에 행높이만 450행까지 있다. - 후속 수정 1건 = 일자가 비었을 때 텍스트 서식(
"일자: "@)으로 바꾸던 것을 중단. 빈칸에 「일자: 」만 찍히고 템플릿 서식과도 어긋났다. 날짜로 못 읽는 문자열이 실제로 있을 때만 전환. - 🔴보고 오류 정정 = 1차 답변에서 "TEST 폴더에 5개 넣었다"고 했으나 실제로 NAS 엔 2개만 갔다.
Bash heredoc 의
'\\2026현장'이 8진 이스케이프로 먹혀C:\192.168.0.101\공유폴더6현장\...이라는 로컬 경로에 쓰였고,os.path.exists()가 True 라 성공으로 보고됐다. 지금은 정리 완료 — 경로는 포워드슬래시, 저장 후 목적지listdir로 되읽어 확인. - 결과물(
\\192.168.0.101\공유폴더\2026현장\견적\TEST) =00_읽어주세요.txt·01_…(실물과 동일데이터).xlsx/pdf·01_참고_추가건 포함 샘플.xlsx/pdf·02_운영서버 다운로드_넵스 쌍용 홍은동 MH 견적서.xlsx/pdf. - 사이트맵 재빌드 = 배포 전·후 모두 그룹8·페이지49·미반영 2(둘 다 기존 AL — 견적서 출력은 화면 뒷단 API 파일이라 페이지 표시엔 안 잡힌다).
- ⏳페페 몫 = 운영 육안(견적서 출력 → 엑셀) + TEST 폴더 02번 확인.
(1차) 견적서 엑셀을 NAS 양식 파일 채우기로 전환 — 배포 전 결과물 제출
페페 지시 = "실제 결과물(07월\넵스\넵스 쌍용 홍은동 MH 견적서.xlsx)·기본 양식(양식 견적서.xlsx) 2파일 확인해서
PFS 견적서 엑셀 양식 수정. 선굵기·셀배경색·상하좌우 여백 등 모든 것이 동일해야 한다.
양식 파일을 새로 만들기보다 기존 파일을 활용해 데이터 입력하는 쪽으로. 결과물은 견적\TEST 폴더에 작업순번."
- 방식 전환 = 코드로 서식을 다시 그리던
build_excel을 버리고 NAS 양식 파일 자체를 리포에 두고 값만 채운다. 템플릿api/pfs/estimate/service/estimate_form.xlsx= NAS 원본 바이트 동일. 앞으로 양식이 바뀌면 코드가 아니라 이 파일을 갈아끼운다. (web/static밖에 둔 이유 = 정적경로면 표본 견적 내용이 그대로 공개된다.) - 시트 확보 = 템플릿 「종합」=요약 원본 / 「본건」=금액시트 원본(요약1+상세4 블록). 추가건은 「본건」을
copy_worksheet. 블록이 모자라면 상세 블록(46~90행) 서식을 복제. 「추가1」 템플릿 시트는 버린다. - 결재칸만 예외 — 템플릿에선 도형 그룹이라 openpyxl 이 못 살린다 → 템플릿 300dpi 실렌더 크롭 PNG로 대체, 앵커는 템플릿 그대로(J39 우측 ~ O 끝 · 39~41행). 도장도 템플릿 원본 jpg(67×71)로 교체.
- 검증 = 신설
scripts/_estimate_excel_form_check.py58항목 ALL PASS(DB 없이 DAO 스텁). 핵심 = 서식 diff 0 — 내 출력 vs 템플릿을 셀 단위(테두리·배경·폰트·정렬·표시형식) + 행높이·열폭·병합·여백·페이지설정 전수 대조. 케이스 4종(기본 / 타입7종=블록복제 / 부분출력 본건만 / 추가건만). 추가로 내 출력 「종합」 vs NAS 실물 「종합」 서식 diff = 0. Excel COM 실계산 확인 = 종합 6,640,000 = 본건 6,500,000 + 추가1 140,000. 파일 438KB→104KB. - 결과물 =
\\192.168.0.101\공유폴더\2026현장\견적\TEST\01_넵스 쌍용 홍은동 MH 견적서(PFS출력).xlsx(+ 같은 이름 .pdf). NAS 실물과 같은 데이터로 뽑아 1:1 대조 가능. - 커밋 master
01d5f43. 배포 안 함(테스트 서버 자동배포만). 사이트맵 재빌드 = 그룹8·페이지49·미반영 2(둘 다 기존 AL 건 — 견적서 출력은 화면 뒷단 API 서비스 파일이라 페이지 미반영 표시에는 안 잡힌다). - 안 한 것 = 이제 안 쓰는
web/static/img/estimate_supplier_block.{jpg,png}와tools/gen_supplier_block_png.py·gen_approval_box_png.py는 그대로 뒀다(지시 밖 · 페페 확인 후 정리). - ⏳페페 몫 = TEST 폴더 01번 결과물 육안 → 재지시(고칠 곳 지목). 함정·규칙 →
rules.md 🆕
🆕 NOW (2026-08-05) — 배차목록 인라인 통합 검색창 추가 + 상단 기사칸 삭제 운영배포 완료
페페 지시 = "배차목록에 모든 항목 통합 검색용 인라인 검색창 추가. 출발도착 검색창 좌측으로 약간의 여백두고. 상단 search filter에서 기사 검색창은 삭제. 운영배포."
- 파일 1개뿐 =
web/templates/basic/dispatch/dispatch_list.html(템플릿이라 캐시버스터 불요). master0d96fe9→ deploy-live668801e. - 통합 검색은 서버가 아니라 행 데이터에서 한다 —
dcRows의 각 행이SELECT a.*+ 조인컬럼이라 화면 표에 없는 값(기사명·기사연락처·비고·비고2·인수자연락처·물품)까지 이미 들어 있다.rowAllText(r)= 행의 모든 스칼라 값을 한 문자열로 join → 부분일치. 새 API·새 컬럼 0. 운영 실측 = 기사 "박경" 입력 시 56건 중 1건. - 배치 = 인라인 검색줄(
.dc-results-head)의 첫 칸, 출발 입력칸과 여백 22px(래퍼gap:8px+margin-right:14px). 기존 출발·도착과 AND. - 상단 SEARCH FILTER의
srchDriver삭제 = 입력칸 +searchFilterargsdriver_name+resetFilter참조 3곳 동반 제거. DAO는 손대지 않았다 —select_dispatch_search_list가args.get("driver_name","")이라 미전달이면 조건이 안 붙는다(운영 왕복 1,673건 정상). - 곁다리 수정 1줄 =
renderTable()끝에applyInlineFilter(). 원래는 「조회」를 누르면 인라인 검색어가 그대로 남은 채 필터만 조용히 풀렸다(기존 출발/도착도 같은 결함). 새 칸만 고치면 셋 중 하나만 맞는 꼴이라 공통 지점에서 잡았다. - 검증 =
scripts/_dispatch_inline_search_check.py(신설·scripts/.gitignore로 커밋 제외) 18항목 × 테스트·운영 ALL PASS — 좌표 실측(통합 right < 출발 left, 같은 줄, 여백 22px) · 숨김필드 검색 · 없는 키워드 0건 · × 복원 · 통합 AND 출발 · 재조회 후 유지 ·driver_name미전달 API · 콘솔 0. - 선별 배포(merge 아님) =
git checkout origin/master -- <파일>후 커밋. merge하면 AL 미배포건(al-orderpaper·al-profile)까지 끌려온다. 사전확인 = 이 파일에 걸친 미반영 커밋이 내 것 1개뿐임을git log --cherry-pick --right-only로 확인. - 사이트맵 재빌드 2회 = 배포 전 미반영 3(
/dispatch/list주황) → 배포 후 2(주황 걷힘, 남은 2건은 기존 AL). devplanpfs.htmlDONE 배열 갱신. - ⏳페페 몫 = 운영 육안(
/dispatch/list).
🆕 NOW (2026-07-30) — 신영 광주 챔피언스시티 MH 견적서 운영등록 완료 (본건 740 · 추가1 741)
페페 지시 = NAS 견적서 xlsx를 운영서버 등록, "본건 견적 생성 후에 추가건:추가1 항목으로", 현장 field_no 1973(=신영 광주/넥서스/MH), 운영배포 승인.
- 입력이 도어발주서 xlsm이 아니라 견적서 xlsx(단가=고객 확정가) → 기존 스킬로 안 되어 판독부터 재수행. 단일 시트
추가1= p1 요약(추가1 1,027,000 + 운임 150,000 = 1,177,000) + p2 상세(섹션헤더 2 + 품목 13줄 = 1,027,000). - 🔑이 양식이 PFS 출력양식(
estimate_print_service)과 1:1임을 확인하고, 매핑을 추측하지 않고 렌더러 셀 주소에서 역산했다. 실제로 요약행은A=현장명 C=항목명이라 A열에서 항목명을 읽으면 '운임'이 현장명으로 잡힌다(초안에서 발생 → 수정). - 등록 = ①본건
740신영 광주 챔피언스시티 MH 견적서(빈 컨테이너 0원 — 이 파일에 본건 내용 없고 NAS 전량 검색에도 본건 견적서 파일 없음) → ②추가건741추가1(13줄,type_name='추가1', parent 740) → ③기타부가비운임 150,000 (신규자재 운임). - 결정 3건:
type_name=엑셀 p1 요약행 이름추가1(선례 738과 일치) · 운임=transportation_cost아닌estimate_extra_cost(물류비 라벨 고정·비고 불가) · 마진=master0+detailNULL(master를 자동으로 두면 넥서스 15.5%가 얹혀 금액이 부풀려진다). - 미수집 = 섹션헤더 2행(
128타입 50-010 몸통재·84D타입 HS2661 몸통재) — PFS detail에 대응 필드 없고, 타입 분리하면 p1 요약이 1→2줄로 바뀌어 이미 발송된 문서와 달라진다. - 검증 4단 ALL PASS = 금액 3중 교차검증 → VERIFY 사전조회(현장·중복 0) → 등록 왕복 대조 불일치 0 → 출력 엑셀 실제 다운로드(353,851B, 시트 종합/본건/추가1) vs NAS 원본 셀 대조 불일치 0.
- 기존 동작(내 등록 탓 아님, 선례 738 동일 실측): 추가건 시트 요약행 A열 현장명 공백(
select_sub_estimates가 field_name 미반환) · 담당자는 업체refer_man(고재형 이사)로 표기. - pfs 리포 코드 변경 없음(데이터 등록만) → 커밋·배포 없음. 스크립트 =
C:\dev\order-automation\build_and_register_shinyoung_add1.py. - ⏳페페 몫 = 운영 육안 + 본건 740에 본건 내용 채울지 결정(현재 0원). 상세 →
session-2026-07-30-shinyoung-add1-estimate.md· 절차 =playbook.md §7· 규칙 =rules.md 🆕
🆕 NOW (2026-07-29) — 미반영 A·B 그룹 운영배포 완료
페페: "미배포건이 있다. A,B 그룹 먼저 운영배포한다." (D005 배차사진 경로 버그는 "배포만, 버그는 P0에서")
- A 화물앱 배차 3건 → deploy-live
83540c8(master f39bdd8·1fa41be·3fa0175). DB는ensure_freight_cols런타임 멱등 ALTER라 마이그 불요. - B 월마감 5건 → deploy-live
70ba185(master dae788e·26c49cd·c684883·ce9b34e·34ab1c3). 운영 RDS 선행 완료 =monthly_close·monthly_close_item생성 +menu_catalogmenu_no=46(적용 전 스냅샷tables:[]/menu:None확인). 권한 추가작업 불요 —has_menu_permission은 자사에 명시 row 없으면 기본 허용. - 배포 경계는 커밋 수가 아니라 파일 diff로 판정(07-27 파일단위 포워드 탓 patch-id 비교는 28건으로 부풀려짐) → 37파일을 A 8·B 14·AL 15(범위 밖)로 분리.
⚠공유 파일 사전확인이 핵심:
api/config.py미반영분은 월마감 2줄뿐,mysql_util.py는 A의 execute_id뿐 → 통째 포워드해도 AL 미유입. (시드의 "config.py 통째 포워드 금지" 경고는 monthly_close가 미배포이던 시절 조건 — 이번엔 뒤집혔다. 매번 diff를 본다.) - 검증 = 운영 HEAD
70ba185· 서비스 active ·/login200 ·/estimate/monthly-close200 ·/api/monthly-close200 ·/api/dispatch405(GET 미지원=등록됨) · 잔여 diff는 AL 15파일뿐. - 안 한 것 = 마감 데이터 시딩(운영 견적 기준 재판단 필요, 별건) · D005 배차사진 경로(code-qa
field-dispatch파트). - 🆕후속 QA(같은 날): 페페 지시로 화물앱 접수 버튼 기능 비작동 —
requestFreight()앞 게이트 3줄(FREIGHT_ENABLED=false→dcToast('준비중입니다')), 기존 로직 보존(재개 시 값만true). master4433226(+검증3288f1e) → deploy-liveaf4b72d. 검증=신설scripts/_dispatch_freight_ui_check.py실제 클릭, 테스트 9/운영 9 ALL PASS(문구·confirm 0·freight API 0·콘솔 0). - ⏳페페 몫 = 운영 육안(월마감 페이지·화물 배차 목록). 상세 →
session-2026-07-29-deploy-ab-freight-monthlyclose.md
🆕 NOW (2026-07-29) — AL설정(엑셀 설정탭) 관리 페이지 CRUD (운영 배포 완료)
- 페페 지시: NAS
원부자재발주서.xlsx「설정」 탭(AL 프로파일별 공제상수 49행)을 관리 페이지로 만들고 CRUD / AL발주서 페이지에 접속 버튼 / 새 발주서 작업 중에도 추가·수정 가능 / 운영배포. + 추가지시 업체정보 란 컴팩트화(발주내용 테이블 공간 우선). - ⚠지시문의 첫 경로
부자재 발주서 일지.xlsm은 시트가주문조회/RawData뿐 → 페페가원부자재발주서.xlsx로 정정. 이 파일이 기존al_calc.py의 원 출처. - 저장소를 JSON 자산 → RDS 테이블
al_profile(patch43)로 이전. 기존assets/seoljeong_constants.json은 초기 시딩·「엑셀 원본 복구」 버튼의 기준값으로만 남긴다(파일 편집 방식은 배포마다 사용자 편집이 날아가서 탈락). DAOensure_tables()가 비어 있을 때 1회만 시딩 → 테스트·운영 모두 마이그레이션 수동실행 불필요. - 행 순서(
sort_no) = 엑셀 VLOOKUP 첫매치 순서. 중복 품명 2건(AA*494(작은손)+3면AA-496·AA*495(큰손)+3면AA-496) 실재 → 위 행이 이기고 아래는 死행. 화면 NO칸을 노랗게 칠해 死행을 보이게 함. - 신규
/field/al-profile(사이드바 미등록 — 접근은 AL발주서 버튼 2곳뿐, 지시 그대로). 저장은 화면 전체 1콜POST /api/al-orderpaper/profiles→ 서버가 soft delete → upsert 순. - 작업 중 수정 동선 = 새 창(작성 중 발주서 유실 방지) + 창 복귀(
window focus) 시 설정 재조회 + 전 행 재계산.al_calc의 모듈 전역 캐시는 편집 가능해지면 uwsgi 워커별로 갈라지므로 요청당 1회profile_map()조회로 교체(49행이라 비용 무시). - 헤더 컴팩트화: 라벨 세로쌓기 폐지 → 업체 1곳당 1줄(placeholder 인라인) + 헤더 접기 토글(요약줄 유지, localStorage). 폼 높이 106px, 그리드 시작 y 262→접으면 195px.
- 🔴잡은 버그:
save_bulk가 INSERT 뒤에 soft delete를 돌려 방금 넣은 신규행이 같은 트랜잭션에서 즉시 삭제됐다(응답은saved:50인데 조회 49행 = 조용한 실패). → soft delete를 INSERT보다 먼저 + UPDATE에remove_yn='0'동시 세팅. 테스트 E2E가 잡음. - 커밋
master f99e739→버그수정d38661e→스크립트6f228b9, 운영deploy-live a0faf03(파일 10개 포워드,api/config.py무관). - 검증 = 엑셀↔시딩 정합 실제 불일치 0(공란 50칸이
0정규화뿐) + 테스트 CRUD E2E 16항목 PASS + UI Playwright 테스트 18 / 운영 18 PASS(콘솔오류 0) + 운영 SSM 실측(HEADa0faf03·uwsgi active·4경로 200·al_profile49행 시딩). 상세=session-2026-07-29-al-profile-crud.md. - ⏳페페 육안 = 설정값 실제 편집 → 발주서 계산 반영. ※팩스발송 버튼은 여전히 스텁(범위 밖).
NOW (2026-07-28) — 현장 내용 = 카톡관리(1탭) + 통화관리(2탭) (운영 배포 완료)
- 페페 지시: "카톡관리를 field/worklog 메인페이지로, 기존 페이지를 탭으로 나눠 첫번째 탭. worklog는 통화관리 탭 2번째, 통화 수집분만. 이번주 월요일부터 기록만 현장별 그룹화, 월요일 이전은 숨김이력. 야간에 서브에이전트로 현장매핑 반복. 운영배포".
- 1탭 카톡관리 = 신규
api/pfs/kakao_board—kakao_board(미러) +kakao_board_op(웹 편집 명령 큐). 원본 board.md는 사무실 PC에 있고 EC2는 거기로 못 들어가므로 방향을 뒤집었다: 데몬이 미러를 push하고 웹 명령을 pull·적용·회신. 폰 조작 주체는 여전히 데몬 하나. 화면은 방별 카드 → 섹션·행 + 접힌 숨김이력, 반영 대기 n건·실패 사유 배너(조용한 미반영 금지). - 2탭 통화관리 =
worklog_dao._source_clause()(source='call')를 조회·집계·묶음변경 전 경로에 적용. 카톡 과거 적재분은 화면에 안 나오고 일괄변경도 안 건드린다. - 노출창 = 최근 2주 → 이번주 월요일부터(
week_start()).scope=hidden이 월요일 이전 전부(1년). 배타 상한이 기본창 시작과 정확히 맞물려 경계 항목 누락·중복이 없다. 상한 없음은 07-27과 같은 이유(미래 '예정' 항목 보호). - 야간 파이프라인(talklog
night_worklog.py, 예약 02:00) = 전사·분류·적재 → 규칙 auto-link → 남은 미연결만 claude 서브에이전트가 pfs 현장과 매칭(confidence≥0.8, 입력에 없는 현장명·번호는 폐기) → 새 전사문을 furniture-expertpractice/ops_*_calls.md에 적립. - ⚠
api/config.py는 브랜치 간 파일 통째 포워드 금지 — master엔 미배포monthly_close가 있어 그대로 가져오면 운영이 임포트에서 죽는다. 이 파일만 deploy-live에서 2블록 직접 추가. - ⚠배포 중 회귀 1건 잡음: 숨김이력 682장에서
전체 펼침이 XHR을 한꺼번에 쏴 502 →loadItems에 큐(동시 6). 창을 넓히는 기능은 펼침 동시성을 같이 봐야 한다. - 커밋
master 028fd6a→deploy-live 9e3a049, 502수정master dd76774→deploy-live a9036c3. + poin-agent39726f9, talklog1440777. - 검증 = 자체검사 18 + 로컬 7 + pfs-test E2E 8 + 운영 UI(Playwright: 카톡 4방 85항목·이번주
2026-07-27~·숨김이력 682현장·카톡배지 0/통화배지 1211·콘솔오류 0) + 운영 무해 왕복 1건(같은 본문 되쓰기 → 40초 내 완료, board.md 해시 불변). 상세=session-2026-07-28-worklog-tabs-kakao-board.md. - ⏳페페 몫 = 감시 데몬 재시작(상승권한이라 코디 불가 — 지금은 1분 예약작업
PFS-KakaoBoard-Sync가 대신해 기능은 정상) / devplankakao-ops.html유지 여부 결정.
NOW (2026-07-28) — 생산 메모 모달 통합: 단일 입력창 (운영 배포 완료)
- 페페 QA 리포트(
/field/list): "기존메모·신규메모 창 통합, 한 입력창에서 내용 전부 관리, 운영배포". field_list.html1파일만 수정 — textarea 2개(field-memo-currentreadonly +field-memo-new) →field-memo-content1개. 모달 열면 저장본이 그대로 편집창에 들어오고, 저장하면 그 값이 새 저장본. 라벨 =메모 내용+(최종 저장 <일시>).- 빈값 = 차단 → confirm으로 변경. 통합창에선 "비우고 저장" = 메모 삭제 의도라 예전
alert('신규 메모를 입력하세요')차단이 기능을 막는다. - 서버 무변경 —
GET/POST /api/field/memo·DAO의previous밀어내기 그대로. - ⚠지시문의 "자동저장"은 기존 저장 동작 유지로 해석했다(현 모달엔 autosave 없음). 근거 = pfs는 견적 autosave를 Patch #21로 전면 폐지했고 재도입은 위험작업으로 규정. 진짜 입력 즉시 저장을 원하면 별도 지시 필요. ⏳페페 확인.
- 부작용 1건(미구현) = 저장 안 하고 닫으면 편집분 소실(예전엔 저장본이 readonly로 남아 체감 안 됨). 지시 범위 밖이라 경고 안 넣음.
- 2차 지시(같은 날): 저장 안내 alert 폐기 + 저장 성공 시 모달 자동 닫힘. 닫기 전 입력창/라벨 갱신 코드도 불필요해 함께 제거(다음에 열 때 GET으로 재주입). 실패 시엔 기존대로 모달 유지.
- 커밋
master 6e647fe→deploy-live 7c76774(통합),master 70475a0→deploy-live 8bb6fd9(alert 폐기·자동닫힘). 둘 다 파일 1개 포워드 반영. 사전확인 =git diff --stat origin/deploy-live origin/master -- <file>가 그 커밋 변경분과 정확히 일치해야 A·B 미반영분이 안 딸려온다. - 검증 = 자체 스크립트 테스트 13항목 PASS(단일 textarea·구 id 소멸·저장본 주입·라운드트립·previous 보존·저장 후 모달 닫힘·alert 없음·재오픈 저장본·원복) + 운영 9항목 PASS(읽기전용 — 운영 메모 미변경, 배포 템플릿 소스로 alert 제거·
modal('hide')확인) + 스크린샷 육안. 상세=session-2026-07-28-field-memo-modal-merge.md.
NOW (2026-07-27) — field/worklog 노출기간 2주 제한 (운영 배포 완료)
- 페페 지시: worklog 내용 누적으로 페이지 로드 버벅임 → 최근 2주만 표시, 나머지 숨김. 과거는 일자(시작일) 필터로 별도 2주창 조회, 검색도 2주 창 안으로 제한.
- 노출창 단일 출처 =
worklog_service.worklog_window(date_from)→(from, to)(to 배타). 미지정=(오늘-13, None), 지정=(그날, +14일), 1년 하한 클램프. - ⚠기본창엔 상한을 두지 않는다 —
work_date에 미래 '예정' 항목 존재(실측 10건, 전부 진행중/대기).[오늘-13, 오늘]로 잘랐으면 예정 작업이 통째로 사라짐. 자르는 건 과거뿐. - 게이트 방식 교체: HAVING → WHERE 창. HAVING(집계 후)은 카드 건수에 창 밖 과거가 섞여 "2주만 표시"가 성립 안 함. 같은 창을 items·status-bulk·owners에도 적용 → 카드 건수=펼친 목록=일괄변경 범위 일치.
- 커밋
master ed2ea6a→deploy-live 750fdad(worklog 5파일만 포워드 반영, A·B 미반영 유지). devplanpfs.htmlDONE 갱신. - 검증 =
scripts/test_worklog_window.py7항목 PASS(창 계산 + SQL%s/파라미터 일치) + 운영 실측 묶음 702→252(64%↓)·항목 1674→565(66%↓), 최신작업 07-29(예정 유지). ⏳페페 육안(카드 펼침·일괄변경 확인창 문구). 상세=session-2026-07-27-worklog-2week-window.md, 함정 2건traps.md.
NOW (2026-07-27) — 미반영 커밋 선별 운영배포(C·D·E) + devplan 배포관리 페이지
- 미반영 커밋 세는 법(중요): 운영은 merge가 아니라 cherry-pick 이력이라 해시가 전부 다르다 → 원시
deploy-live..master89건은 과대계상.git log --no-merges --cherry-pick --right-only origin/deploy-live...origin/master(patch-id 비교) = 22건, 그중 diff 0인 2건 빼면 실제 20건. 최종 확인은git diff --stat과 대조. - 선별 배포(페페 "C·D·E만"):
git merge master는 A·B까지 끌고 오므로 파일단위git checkout origin/master -- <files>포워드 반영. 위험 낮은 순 E(스크립트)→C(파서)→D(웹UI) 3커밋 + push 1회(운영 재시작 1회). deploy-live6fe4e38·7b916e8·8ca0389. - 검증 = 자체 14케이스 PASS(
_is_zero_name6·파일명 파싱 4·num_only4, D는 colgroup 17개 불변) + SSM 실측(운영 HEAD 일치·pfs-live.uwsgiactive·/login200·css?v=20260715d서빙). - 남은 미반영 8건 = A 화물앱 배차 3건(아래 NOW, 페페 육안 대기) · B 월마감 5건(🔴
patch41_monthly_close.sql운영 RDS 선행 + 메뉴 시드 46 필요). - 관리 페이지 신설 =
C:\dev\devplan\pfs.html(허브 pfs 카드 → 계획 페이지). 미반영 커밋 관리표(상태·메모 localStorage) + 배포 전 체크리스트 + 배포완료 이력 + '코디용 지시문 복사' 버튼. 데이터 갱신 = 그 파일의PENDING/DONE배열 수정. 상세=session-2026-07-27-selective-deploy-cde.md.
🧹 HANDOFF 완료건 이관 (2026-09-07) — 원문 그대로
✅ 26.9.3 — pfs QA 3건(검색칸 자동완성 · 모바일 사이드바 · 월마감 컬럼폭) 운영배포 완료 (690bb89)
①/admin/user 검색칸에 poin01 이 저절로 박히던 것 = 크롬 자동완성(같은 페이지 password input 3개 탓에
로그인 폼으로 읽힘) → type=search+autocomplete=off · 엔터 검색 추가.
②모바일 사이드메뉴를 펼쳐도 로고·「비번변경·로그아웃」이 안 보이던 것 = 모바일은 .mini-sidebar 가 붙은 채로
열린다 → ≤767 에서 접힘 압축 되돌림(전역 CSS 라 데스크톱 접기 회귀 포함). ③월마감 현장명 17%→12% · 비고 20%.
검증 _qa3_check.py 17항목 테스트·운영 ALL PASS · 사이트맵 미반영 1(/field/worklog, 무관).
새 함정 2건 = projects/pfs/rules.md 🆕. 🔜미결 = 그 검색칸은 placeholder 와 달리 아이디로는 검색 안 됨(페페 판단 대기).
✅ 26.9.4 — pfs 「생산자동화시스템」 → PFS 전면 교체 운영배포 완료 (ddd9135)
탭 제목 단일 출처 = common/config/config.py SITE_TITLE(환경별 4개) + 로딩 라벨 3 + 하드코딩 title 3
+ 오엠씨 모바일 좌측 로고 4. 운영 탭 제목 = PFS. 테스트·운영 PASS.
✅ 26.9.3 — pfs 사이드바 로고 = PFS 운영배포 완료 (12338c8)
종전엔 logo-text.png 이미지라 문구를 못 바꿨다 → 텍스트(span)로 교체. 접힘 동작 무변화.
🔜남은 「생산자동화시스템」 = 탭 title · 로딩 스피너 라벨 2곳(지시 범위 밖이라 유지, 페페 판단).
✅ 26.9.3 — pfs 모바일 햄버거 항상 3줄 운영배포 완료 (0434506)
테마 custom.js 가 .nav-toggler i 에 ti-close 를 addClass 만 하고 안 지워 한 번 누르면 X 로 굳었다.
테마는 안 건드리고 pfs.js 에서 걷어낸다. 운영 열고닫기 3회 반복 실측 PASS.
✅ 26.9.3 — pfs 상세 모달 = 코디 정리본(kb_digest) 운영배포 완료 (30cf5af)
페페 지적 「한 덩이 문장에 다른 현장 내용이 들어간다」 → 현장명 문자열 매칭 폐기,
카톡 게시글을 코디가 현장별로 다시 쓴다. 예약작업 \Cody\kb-digest(15분·숨김) —
게시글 version 이 그대로면 코디 호출 0. 운영 첫 정리 = 15건 중 9건, 제천 자이 빠짐(지적 해결).
⚠페페 확인 1건 = GS 신반포에 「GS 메이플자이」가 붙었다(신반포4지구 재건축 단지명이라 맞을 수도).
새 함정 3건(코디 정리본 규약 · 헤드리스 프롬프트는 stdin · git add <디렉터리> 금지) = projects/pfs/rules.md.
✅ 26.9.3 — pfs 업체 전용 현장목록 모바일 3차 운영배포 완료 (6e7c8f9)
모바일 QA 6건(검색창·탭 겹침 / Search Filter 버튼+패널 / 사이드메뉴 버그 / 상세버튼 폐기→현장명 클릭 /
모달 가로중앙 / 한 행 2줄) 전부 처리. 사이드바 수정은 전역(pfs_layout.css·pfs.js) —
데스크톱·모바일 3페이지씩 회귀검사 10항목 포함 운영 전부 PASS.
새 함정 3건 = projects/pfs/rules.md 「모바일 레이아웃 함정 3종」(@media 위치 · DataTables float · JS 삽입요소 기본 display).
🧹 HANDOFF 완료건 이관 (2026-09-07) — 원문 그대로
✅ 26.9.3 — pfs 업체 전용 현장목록 2차 운영배포 완료 (168f21d)
표 폭 820px(우측 460px = 요약 게시판 자리, 게시판은 페페 「현재 작업 없음」) · 담당자 컬럼 숨김 ·
상차일 26.8.29(수)(공용 포매터 convertDateStringKo 신설 · 규칙 재기록 = projects/pfs/rules.md) ·
「진행 현장」 버튼 삭제(상태 탭과 중복) · 운영 DB 13행 field_div AS→내수(15건 전부 내수 · 자식 AS 0 확인 후 집행 ·
롤백 C:\dev\pfs\scripts\_ivg_div_rollback.py). ⚠구분 컬럼이 전부 「본건」이 된다(의도).
✅ 26.9.3 — pfs 업체 전용 현장목록 QA 6건 운영배포 완료 (3990b06)
/field/company/452(아이비젼글로벌) = 상태 탭·완료 하단·20건/페이지·주방/일반 제거·상세(카톡 게시글 모달).
🔑상세는 kakao_board 에 업체·현장 정본 링크가 0건이라 현장명 문자열 매칭이고, 거르는 자리는 서버다
(고객 계정 화면이라 방 전량을 브라우저로 내리면 남의 업체 게시글이 샌다). 매칭 0건 = 상세칸 공백(페페 판단).
운영 검증 HTML 8/8 · UI 12/12 PASS. 상세·다음 할 일 = projects/pfs/handoff.md 맨 위 절.
🧹 루트 HANDOFF 이관 (2026-09-07) — 원문 그대로
✅ 26.9.7 KST — GS 안산 성포 MH 주방 견적 초안 (포인 양식 + 한샘 양식, 길이견적만)
페페 「나스에서 gs안산 성포동 도면 확인하고 견적서 초안 만들어줘. 포인, 한샘 양식 두개 다. 길이 견적만 한다」 + 「건립이라는 단어나 도면에 큰 네모 표시된 타입들만 찾아봐」.
🔑견적 범위는 도면이 직접 말한다 — 표제란 구분 : KIT. 건립 : 84㎡A, 99㎡A, 104㎡, OT84㎡A +
모델스페이스의 글자높이 1500 MH건립 라벨 8개 & 시트묶음을 두른 큰 사각형 8개.
→ 건립 = 4타입 × (Style Up 주방옵션 + 냉장고장-옵션형). 확장기본형·Style Up2/3·냉장고장 기본형1/2 는 제외.
도면 전체 조감 렌더 1장으로 눈에 바로 잡힌다(행렬 = 타입 × 옵션).
산출(전부 C:\dev\_work\gs-ansan-seongpo\) = GS안산성포_포인양식_견적초안_길이견적.xlsx ·
GS안산성포_한샘양식_견적초안_1_아파트(84A·99A·104).xlsx · …_2_오피스텔(OT84A).xlsx
(⚠한샘 양식은 3평형 상한 이라 4평형을 한 파일에 못 담는다) · 생성기 build_estimate.py · 검증기 _verify.py.
27줄 · 포인 30,045,000원 / 한샘 25,115,300원(V.A.T·추가금액·운반·시공 전부 제외 = 「길이 견적만」).
PFS 운영 DB 미변경(페페 선택 = 로컬 초안만). 현장 = 2180 「GS 안산 성포」(한샘·MH, 견적 0건).
🔴새 함정 3개(규칙 반영 완료) — ①캐드에서 열린 NAS dwg 는 nasget.py get 이 sharing violation 으로 죽는다
→ share_access="rwd". ②DWG 판독은 ODA File Converter→DXF→ezdxf 가 정답(COM·Session1 불필요, 30초).
③한샘 양식의 남는 슬롯은 원래 이름 84A·84B 로 남아 우리 평형명과 겹쳐 보인다 → 판별은 A4 셀 값으로.
⏳페페 판단 3건 = ①아일랜드 후면 유리/FIX 장을 따로 청구하나(포인↔한샘 차액 −4,929,700 의 절반 이상이 여기서 난다)
②한샘 등급 D·적용률 1.0 확정 ③수량 = 타입당 1세대(1,354세대 물량 미반영).
세션문서 = projects/pfs/session-2026-09-07-gs-ansan-seongpo-estimate.md.
✅ 26.9.4 — pfs 생산현황 출력 3건(미확정 표 헤더 제거 · 아이비젼 축약 · 행 여백 50%) 운영배포 198744d
페페 지시 = ①「상차일 미확정 그룹에서 컬럼헤드를 빼자(AS/추가건과 같은 형태니 컬럼명 없어도 이해된다)」
②「추가 기본규칙 : 아이비젼글로벌은 아이비젼 으로 축약 표기」 ③「각 테이블 행 높이 여백을 현재의 50%로」 ④운영배포.
master 39af394 → deploy-live 체리픽 198744d. 템플릿 3파일.
🔑축약이 옛 규칙 하나를 지웠다 — 8.10 의 「이름 순서 유지 + <br> 로 2줄 끊기」는 폭이 모자라서 만든 것이었다.
「아이비젼」이면 업체칸 8% 에 1줄로 들어가고, 부분일치라 운영 아이비젼글로벌 / 테스트 글로벌아이비젼 표기차도 같이 사라진다
→ 업체필터 버튼(field_list·estimate_list_v2)도 같은 규칙으로 줄였다(테스트에서만 0건 나오던 함정 해소).
🔑헤더 제거는 <colgroup> 을 남겨 두면 폭이 안 흔들린다(table-layout:fixed) — 실측 AS 표와 픽셀 동일.
여백은 화면 4→2px·인쇄 3→1.5px, 폰트·line-height 는 그대로. 절약 실측 = 같은 페이지에서 되돌려 대조 996→920px(-76px/17행).
검증 = 신설 C:\dev\pfs\scripts\_status_print_check.py [test|prod] 테스트 22/22 · 운영 21/21 ALL PASS(임시 행 주입·제거식).
사이트맵 재빌드 = 그룹8·페이지57·미반영 4→1(남은 1건은 남의 field_worklog.html).
🔜미적용 = line-height 축소(여백만 줄이면 행높이는 8%뿐 · 내리면 -22%) — 페페 판단.
상세 = projects/pfs/handoff.md 맨 위 · 규칙 2줄 = projects/pfs/rules.md 🆕 맨 위.
✅ 26.9.4 — pfs 넥서스→한샘 자동전환 재검토 + 신영 광주 추가2·추가3 「한샘 전용 견적」 작성 운영배포 완료 (dfd1435)
페페 ①「넥서스 표기 파일·현장 한샘 자동전환 됐는지 재검토(아직 한샘 표기가 안 익숙하다)」
②「NAS …\09월\넥서스\넥서스 신영 광주 챔피언스시티 MH 견적서 추가2,3.xlsx 를 pfs 한샘 견적서로 반영·작성,
금액 최대한 맞추고(완벽 불필요·빠른 작업 우선) 운영배포」. 작업 중 「추가2 탭 추가했다」 지시 반영.
🔑「한샘 견적서」가 두 갈래라 그릴링으로 갈랐다 — 기존 견적계통엔 추가2·추가3 가 이미 있었다(742·754,
NAS 엑셀과 셀단위 금액 100% 일치) → 페페 결정 = 한샘 전용 모듈에 새로 작성, 이어서 「한 목록으로 탭만 구분해 통합」
→ 운영 한샘견적 4 한 건(평형 슬롯=엑셀 탭 추가2·추가3 2개 · 상세 13줄 · 1,996,017원 / 원본 1,996,000 · +17원).
🔴부수확 = 진짜 버그 — 한샘 양식은 원본이 쓰던 칸 수만큼만 단가 LOOKUP 수식이 있어(예비블록은 C 한 칸뿐)
그 다음 칸 줄의 금액이 엑셀에서 조용히 0 이 됐다(서버 총액은 정상 → 목록으론 안 걸린다). 이번 건 2칸 실제 적중.
현장명 자동전환은 등록·수정으로 들어오는 것만 신설(기존 7건은 이력 보존 = 페페 결정).
총액 오차 = 추가2 -4원 · 추가3 +21원(적용률 소수 4자리 반올림 잔차, 페페 「완벽하지 않아도 괜찮다」 범위).
검증 = 엑셀 3중 교차 · 테스트 선행등록 후 「값칸 ⊆ 단가수식칸」(배포 전 ⚠→후 OK) · 왕복 전 줄 대조 ·
현장명 E2E(테스트) PASS · 사이트맵 그룹8·페이지57·미반영 1(남의 분).
⏳페페 = /estimate/hansem/list 4·5 육안 + 엑셀 금액 검산. 상세 = projects/pfs/handoff.md 맨 위 ·
새 규칙 4건 = projects/pfs/rules.md 🆕 맨 위 · 세션 = projects/pfs/session-2026-09-04-hansem-shinyoung-add23.md.
✅ 26.9.4 — pfs 파레트용지 한샘 로고 NEXUS 제거(HANSSEM 만) 운영배포 완료 (2fb811f)
페페 QA 1건(qahelper) = 「한샘 파레트 용지에서 nexus 빼라 · 추후 롤백 가능 · HANSSEM 으로만」.
🔑NEXUS 는 코드 문구가 아니라 로고 이미지 자체(company_logo/1.jpg)였다 — 그 파일은 스티커·현장배지도 같이 쓴다.
→ 파레트 전용 오버라이드 규약 신설(company_logo/pallet/{업체번호}.jpg 있으면 파레트에서만 사용, 없으면 폴백).
⛒롤백 = 그 파일 하나 삭제(코드 롤백 불필요). 이미지는 같은 캔버스에 HANSSEM 만 재중앙 = 인쇄 크기 원본과 동일(160×19.8mm)
— 타이트 크롭하면 세로가 +77% 로 커진다(web-designer 실측).
검증 = 신설 C:\dev\pfs\scripts\_pallet_logo_check.py 테스트·운영 ALL PASS(17항목) · 사이트맵 미반영 1 = 남의 분.
⚠남은 것 1 = 생산팀 PC(PfsPrint.exe) 실물 1장 육안(프린터 여백은 화면으로 못 잡는다).
상세 = projects/pfs/handoff.md 맨 위 · 새 규칙 2건 = projects/pfs/rules.md 🆕 맨 위.
✅ 26.9.4 — pfs 생산현황 「상차일 미확정」 프레임 + 현장목록·모달 자동완성 차단 운영배포 완료 (53c4391)
페페 QA 2건(qahelper) = ①생산현황 출력 하단(AS 표 아래)에 미확정 현장만 모은 새 표(AS 표와 같은 6칸 양식,
표 안에서 AS 는 하단·나머지는 상단) ②현장 목록·모달 크롬 자동완성 해제.
🔑미확정 = 상차일 빈칸 하나로 판정 → 그 현장은 메인·AS 표에서 빼서 새 표로 옮겼다(중복 아님 · 「모아서」의 해석).
🔑자동완성은 26.9.4 /admin/user 처방(readonly-until-focus)을 공용 헬퍼 blockChromeAutofill 로 빼서 재사용.
검증 = 신설 C:\dev\pfs\scripts\_tbd_frame_check.py 테스트·운영 ALL PASS(24항목) · 사이트맵 미반영 1 = 남의 분.
⚠남은 것 2개 = ①자동완성 실기 확인(헤드리스 재현 불가 → 페페 크롬) ②이 출력은 진행중만 뽑아
대기 현장의 미확정 건은 새 표에도 안 뜬다(운영 3건 중 1건 = GS 안산 성포 제외) — 넓힐지는 페페 판단.
상세 = projects/pfs/handoff.md 맨 위 · 새 규칙 2건 = projects/pfs/rules.md 🆕 맨 위.
✅ 26.9.4 — pfs /admin/user 검색칸 크롬 자동완성 재발 차단 운영배포 완료 (98c4841)
페페 QA 1건 = 검색칸에 poin01 이 박혀 목록이 그 사람만 남는다(첫 로드는 정상 → 작업 중 발생).
🔑26.9.3 처방(type=search+autocomplete=off)으로는 안 막힌다 — 크롬은 credential 후보 칸에서
autocomplete=off 를 무시하고 search 도 text field 로 친다. 처방 2겹 = ①검색칸 readonly + focus 때 해제
②password 3칸 autocomplete="new-password"(트리거 제거 — ①만 하면 옆 칸으로 옮겨가 박힌다).
검증 = 신설 C:\dev\pfs\scripts\_qa_autofill_check.py 13항목 테스트·운영 ALL PASS.
⚠자동완성 재현은 헤드리스로 불가 → 페페 크롬에서 실기 1회 확인 필요. 사이트맵 미반영 6 = 전부 남의 미배포분.
상세 = projects/pfs/handoff.md 맨 위 · 새 규칙 1건 = projects/pfs/rules.md 🆕 맨 위.
✅ 26.9.4 — pfs 오엠씨 3페이지 모바일 표 = A안 2줄 압축 운영배포 완료 (624b63c)
페페 지시(목업 먼저 → 확인 후 진행) → 목업 3안 제시 → A안 확정 → 구현·배포.
목업 = http://100.108.234.45:8799/pfs-omc-mobile-mockup.html (허브 카드 등록됨, 안내 문구는 목업에만).
방식 = 마크업·JS 그대로, 행(tr)만 CSS grid 로 2~3줄 재배치 → 데스크톱 무변화·가로 스크롤 0.
🔴함정 3개 = table/tbody 도 block 이어야 함(안 하면 글씨 세로로 찌그러짐) · 구역 머리 table-row 는 폭 못 채움 ·
rowspan 있는 표에서 nth-child 배치 금지(첫 행만 1칸 밀림) → 클래스 셀렉터로.
⚠폰트 하한 13px·연회색 금지 규칙에 맞춰 보조 글씨 되돌림. 검사기에 A안 구조 6항목 추가 → 테스트·운영 ALL PASS + 노트20 실기 육안.
✅web-designer 검토 반영 완료(운영 3d3dfdf) — A안 로직 자체는 문제 0, 얹혀 온 기존 요소가 문제였다:
터치 타깃(19~21px→28px)·배지 5종 13px·죽은 CSS 정리. 🔴그 과정에서 품명코드가 100→84px 로 깎여
액션을 열 트랙 경쟁에서 빼니 134px·말줄임 0행. 운영에서만 난 span.code 셀 이탈도 수정.
⏳페페 판단 = 색 대비 3건(진행 2.94:1·완료 3.30:1·badge-out 2.53:1, 전부 WCAG 미달 — 브랜드 톤이라 코디가 안 정함). 상세 = projects/pfs/handoff.md 맨 위 · 새 규칙 4건 = projects/pfs/rules.md 🆕.
✅ 26.9.4 — pfs 오엠씨 모바일 목업 폐기 + 메뉴를 「업체별 페이지」 그룹으로 운영배포 완료 (dcad1d9)
페페 지시 9건 전부 처리. 🔑원인 하나 = /omc/sheet·/omc/board 가 모바일 UA 면 와이어프레임 목업을
그대로 서빙했다(목업 타이틀·가짜 사이드바·Excel·태그가 깨진 빈 버튼 전부 그것) → 분기 제거, 실제 페이지로 통일.
🔴부수확 = 전역 .topbar{display:none!important} 가 오엠씨 제목·액션 줄까지 죽여 Excel·확인서·입출고 등록이
데스크톱에서도 안 보이던 것 복구. 모바일 상단 탭(시트·보드·자재관리) 신설, 확인서 공문은 모바일 숨김.
메뉴 DB(test·live) = 「업체별 현장」→「업체별 페이지」, 오엠씨를 그 하위 아이비젼 다음(가나다) 으로.
검증 _omc_mobile_check.py 테스트·운영 ALL PASS · 사이트맵 그룹8·페이지57·미반영1(기존).
✅노트20 실기 육안 완료(임시계정 poin02) — 웹 390px ALL PASS 인데 실기에서 4건 더 나왔다
(보드 넘침·자재 2단 잘림·펼침/접기 어긋남·QA토글이 탭 가림). 원인 태반 = grid 아이템 min-width:auto.
운영 a07226c 반영 후 재촬영 정상. 검사기도 360px·넘침목록·탭침범으로 조임. ⚠poin02 임시비번 정리는 페페 판단.
상세 = projects/pfs/handoff.md 맨 위 · 새 규칙 4건 = projects/pfs/rules.md 🆕.
✅ 26.9.4 — pfs 아이비젼글로벌 현장 유형 = AS 재전환 운영 DB 반영 완료 (코드변경 0)
페페 상담 = 「아이비젼은 입주완료 세대 AS라 규모가 작다. AS로 넣으려니 상위 본건이 없어 내수로 바꿨더니
생산현황 출력에서 본건 표로 갔다」. 방안 3개 제시 → 페페 선택 = A(그대로 AS, 부모 비움).
🔑AS(60)는 상위 본건 없이도 저장된다 — 대가는 내부 현장목록의 「연결」 버튼 + 맨뒤 정렬뿐(업체 전용 목록엔 없다).
집행 scripts/_ivg_div_to_as.py(SSM) 13행 UPDATE · 452 전체 15건 AS · 잔여 0, 검증 _ivg_as_section_check.py prod
ALL PASS(본건 표 아이비젼 0 / AS 표 2건 — 이 출력은 진행중만 뽑아 15건 중 2건이 정상).
새 규칙 3건 = projects/pfs/rules.md 🆕. 상세 = projects/pfs/handoff.md 맨 위.
✅ 26.9.4 — pfs 현장목록 유형관리 모달(톱니바퀴) + 상차일 26.10.21(수) 운영배포 완료 (2507c20)
페페 QA 2건 = ①「현장 등록」 왼쪽 톱니바퀴 → 모달에서 유형 CRUD ②상차일 KO 표기.
백엔드 신규 0 — 업체 「목록관리」가 쓰던 PUT /api/admin/common-code/<group> 재사용, 새로 만든 건 사용건수 SQL + 삭제 가드.
삭제는 사용 중·AS 차단(프론트 잠금 + 서버 가드, 코덱스 지적 반영). 톱니는 업체권한관리 권한자만.
부수확 = 유형 필터 하드코딩 탓에 운영의 개인건(70) 이 검색조건에 없던 것을 공통코드 서버렌더로 교체.
검증 _fielddiv_check.py 21항목 테스트·운영 ALL PASS + _fielddiv_guard_test.py 7항목. 사이트맵 미반영 1(카톡관리, 무관).
상세 = projects/pfs/handoff.md 맨 위 · 새 규칙 3건 = projects/pfs/rules.md 🆕.
2차(같은 날) = 톱니 위치를 페이지 좌측 끝으로 옮김(운영 6c85146, 테스트·운영 21항목 ALL PASS).
🧹 pfs handoff 완료건 이관 (2026-09-10, 페페 「여기서 종료 내용 이관. 추후 보완은 새 세션」) — 원문 그대로
✅ 26.9.10 — 네스팅 부재 그리드 키보드·타입/위치 + 저장/열기 모달(현장 연결) — 운영배포 4388bc4 완료
[페페] 26.9.10(목) 15:30 KST 네스팅 검증보고 2건 + 「운영배포」 —
1 「모든 셀 방향키 = 셀 이동, 숫자단위 데이터 변환 없애라 / 최하단 Enter = 새 행(이전 행 복사, 가로·세로·수량 비움) / 표 높이 3배 / 순번 뒤 타입·위치 컬럼」
2 「저장과 불러오기 모달 제작, 현장명 연결 가능하게」
산출 = 파일 1개 web/nesting/nesting.html(+220/−42) · 백엔드·DB 변경 0(nesting_job 에 field_no/field_name 이미 있음).
master 3fb62dc → 운영 4388bc4(1파일 선별 포워드, 직전 diff 0).
- 타입·위치 키 = tread 입력탭과 같은 type·pos → tread JSON 불러오기가 그대로 채운다. PNCAD·몸통재 경로는 빈칸(원천에 없음).
- 숫자칸 type=number → text+inputmode=decimal — 방향키·휠 ±1 증감이 「숫자단위 변환」의 정체였다.
- 방향키 = 부재·자재 두 그리드 전부(토글·선택칸 포함) · Enter = 아래 셀 · 부재 최하단 Enter = 새 행(같은 열로 이동) · 토글은 Space.
- 🔑한글 IME — 조합 중 키는 keydown 이 keyCode 229 로 온다. 무시만 하면 한글 입력 뒤 Enter 를 두 번 쳐야 한다
→ e.code(물리키)로 이동키만 기억했다가 그 키의 keyup 에서 이동(규칙 rules.md 🆕 맨 위).
- 🔑붙여넣기 호환 — 앞에 컬럼 2개가 끼면 기존 9열 엑셀 붙여넣기가 2칸 밀린다 → 9열 이하 = 옛 순서(두께부터), 11열 = 타입부터.
- 부재 표 높이 min(900px, 100vh−60px) = 3배, 화면이 작으면 화면에 맞춤(web-designer 우려 절충). 자재 표는 그대로.
- 저장 모달 = 작업명 + 현장 연결(POST /api/field/search 이름 LIKE — 상차일 키 2개는 빈값이라도 필수, 없으면 서비스 KeyError)
+ 기존 작업이면 덮어쓰기/새 작업 라디오(툴바 「다른 이름」 버튼 흡수). 열기 모달 = 검색·현재 현장만·행 클릭 열기·🗑 삭제(작업명 확인창, 소프트).
검증 = scripts\_nesting_grid_modal_check.py(gitignore 대상) 로컬 목킹 54/54 · 테스트 실측 55/56
(FAIL 1 = 검사기 오탐, rules.md 🆕) → 고쳐 운영 읽기전용 47/47(쓰기 0건) · 테스트 검증행 2건 소프트삭제 정리 ·
사이트맵 재빌드 그룹 8·페이지 58·미반영 1. 상담 = web-designer · GPT 코덱스 · Plan(Fable 5).
devplan C:\dev\devplan\pfs-nesting-grid-modal.html + 허브 카드 pfs-nesting-grid-modal(최근 3개소 확인).
⏳페페 = 실기 육안 1회 — 한글 입력 직후 Enter 한 번에 새 행이 나오는지(Playwright 는 실 IME 조합을 못 만든다 — 합성 이벤트로만 검증했다).
- ✅[페페] 26.9.10 실기 확인 완료 — 한글 입력 후 Enter 새 행 작동(위 ⏳ 해소). 세션 종료, 보완 후보는
projects/pfs/handoff.md포인터 절.
✅ 26.9.10 2차 — 네스팅 그리드 범위 선택(드래그·Shift+클릭) + Ctrl+C/Ctrl+V — 운영배포 83e15b3 완료
[페페] 26.9.10(목) 16:39 KST 검증보고 #1(table#partGrid 셀) — 「데이터 복수 드래그 선택, 컨트롤c,컨트롤v 기능되게 해줘. 행이 부족한 상태일때는 새행 생성후 남은 복사행 내용 붙이기.」 + 「운영배포」
+ 추가 「복사 항목은 한개인데 여러행셀을 선택했을때는 같은 값을 여러행에 붙이기」.
산출 = 파일 1개 web/nesting/nesting.html(+113/−34) · 백엔드·DB 변경 0. master 690206a → 운영 83e15b3(1파일 선별 포워드, 직전 diff 0, C:\dev\pfs_deploy_wt 워크트리).
- 범위 = 드래그·Shift+클릭 사각형 → td.cellsel(칸 2개 이상). 부재·자재 두 그리드. 선택색 #d7e8ff(목록 선택행과 같다) · 토글칸 #a9c7fa.
- Ctrl+C = 칠한 칸 TSV(엑셀에 그대로) · 범위 없이 토글/선택칸이면 그 한 칸.
- Ctrl+V = 범위 왼쪽 위(없으면 포커스 칸)부터 사각형 · 행 모자라면 새 행 추가 후 나머지 · 한 값 + 여러 칸 = 전부 같은 값(엑셀 한 칸 복사의 끝 줄바꿈도 한 값).
- 🔑외부 한 행 전체(9열=두께부터 / 11열=타입부터)는 옛 방식 유지. ⚠9열보다 좁은 외부 붙여넣기는 이제 포커스 칸부터(예전엔 무조건 두께부터 — 가로·세로·수량 3칸을 붙이면 두께·MDF·컬러에 박혔다).
- 덤 수정 2건 = ①엑셀 한 칸 복사(값\r\n)가 커서 칸이 아니라 그 행 두께 칸에 박히던 것(한 칸 판정이 \n 포함으로 새던 기존 결함) ②옛 모드 헤더 자동 스킵이 가로 빈 첫 행을 헤더로 오인해 버리던 것. 토글·선택칸은 목록 값만(대소문자·2,440 정규화).
- 상담 = web-designer(색·안내 줄 분리) · Plan(Fable 5)(토글 오발·document 게이트·헤더 스킵·정규화 반영, 「첫 클릭 = 칸 전체선택」은 기존 동작 변경이라 보류) · GPT 코덱스(5건, 설계에 이미 있음).
검증 = scripts\_nesting_grid_modal_check.py(gitignore) 에 range_tests 32항목(실 마우스 드래그 + 실 Ctrl+C/Ctrl+V) → 로컬 86/86 · 테스트 89/89(검증행 정리 0건 남음) · 운영 읽기전용 80/80(쓰기 0건, 콘솔 에러 0).
🔴함정 3개 = rules.md 🆕 맨 위(표 리스너는 포커스 빠지면 안 온다 · 드래그 뒤 click 공통조상 · http 테스트서버엔 navigator.clipboard 없음) · playbook §2 배포 절차 정정(deploy-live = 워크트리).
✅[페페] 26.9.10 실기 확인 완료 — 작업 종료(첫 확인에 「변화 없다」 → 곧바로 「결과 확인 완료」로 정정, 코드 추가 수정 없음). 세션 = session-2026-09-10-nesting-grid-range.md.
✅ 26.9.22 · pfs-hansem-add1-hwaseong · 롯데 화성 향남 추가1 → 한샘 양식 변환·등록 + 한샘 엑셀 엔진 결함 3건 (운영 82a5052)
[페페] 「PFS /estimate/modify-v2/780 — 본건 제외하고 이 내용만 한샘 견적서 양식 변환 등록해줘」 + 「이미지 작업은 안해도 된다」 + 「운영배포까지 진행해」.
산출 = 운영 한샘 견적 8(현장 2134 · 탭 84B·84C·120 · 상세 9줄 · 서버총액 540,239 · 갑지 합계 840,000 = 780 총액 정확히 일치). 부모 779(본건)는 한 줄도 안 가져왔다.
품명 접두가 전부 평형이라 평형이 곧 탭이다. 식기세척기 마이다=하부장(K/11) · 천판·칸막이·EP·S/R=키큰 FIX PANEL(K/39) · 등급 A 고정 + 적용률 역산.
🔑적용률은 「올림」이다 — 갑지 절사가 만원 내림이라 합계가 목표를 1원이라도 밑돌면 소계가 10,000원 잘린다(반올림 시 539,951 → 530,000).
🔴덤 = 한샘 엑셀 엔진 결함 3건(운영 전체에 걸려 있었다, 서버 총액은 멀쩡해 목록만 보면 안 걸린다) — ①블록이 밀리면 라벨 미러·10MM기준 수식이 옛 좌표를 물어 남의 길이를 읽거나 0
②기증 블록의 단가 LOOKUP 을 앞 순번 「비우기」가 먼저 지워 그 블록이 통째로 0 ③빈 평형 슬롯 총합이 =SUM() → 엑셀 복구 경고. 배포 전/후 실측 = 견적 4 전 탭 0 → 정상 · 견적 6 은 서버총액과 원 단위까지 일치.
⚠양식이 두 벌이었다 — 운영 활성 form 3(26.9.7 업로드)에는 절사행·운반비가 없다. 정본판을 비활성 form 4 로 새로 올려 이번 견적만 물렸다(활성판·기존 견적 6·7 은 그대로).
⏳[페페] 판단 5건 = ①수납 3품목(174,000)을 주방 탭에 넣은 것 ②견적 7 이 서버총액보다 +275,723(NAS 정본 대조 필요) ③운반비를 양식에 박아 둘지(모듈 필드 신설?) ④도면 비우기 ⑤기존 견적 1·2·3·4·7 엑셀 금액 변동 → 재발행 여부.
작업폴더 = C:\dev\_work\hansem-hwaseong-add1\(build.py·verify.py·impact.py·upload_form.py) · devplan pfs-hansem-add1-hwaseong.html · 함정 3건 = rules.md 🆕 맨 위.
✅ 26.9.23 · pfs-orderpaper-pfs-link · AL·부자재 발주서 → 자재관리 연동(발주 확정·긴급) (운영 c96b0dd)
[페페] 결정: 확정 버튼만 반영 · AL·유리 분류 각각 · 엑셀 표식으로 NAS 중복 차단 · 기존 6건 이관 안 함 · 현장·입고일 필수·발주일 오늘 자동 · 긴급 토글. ⏳[페페] 실화면 확인 1회. ⚠부자재 1번(용산 나진)은 NAS 43행과 중복 의심 → 확정 금지. 상세 = devplan pfs-orderpaper-pfs-link.html, 함정 = rules.md 🆕 맨 위 2줄.
✅ 26.9.22 · pfs-monthly-close-pick · 월마감 담기 모달 금액 3분할 + 견적일 포맷 (운영 91cc509) — NOW 에서 이관
[페페] QA 보고 1건 + 「운영배포」. 금액 1칸 → 가구총합·시공비·전체총합 3칸(「시공비가 빠지니 원금 비교가 어렵다」) · 견적일 2026-04-12 → 4.12(일).
🔑화면만으로는 못 푼다 — construction_amount 는 「담을 값」 이라 시공비 분리 OFF 거래처에선 늘 0 → 표시용 furniture_amount·construction_cost 2필드를
분리 여부와 무관한 실값으로 따로 내렸다(담기 계산식은 한 줄도 안 건드렸다). 파일 2개 · DDL 0.
검증 = 테스트 82/82 · 운영 읽기전용 76/76 · 콘솔 0 · 사이트맵 미반영 1(화면 밖).
⏳[페페] 육안 1회(1240px 모달 · 긴 현장명 · 두 줄 헤더) · ⏳[페페] 판단 2건(「시공비 있는 건만」 필터 · 선택행 합계 실시간 — 지시 범위 밖이라 안 넣었다).
원문 = archive.md 「✅ 26.9.22 · pfs-monthly-close-pick」 · 함정 4건 = rules.md 🆕 맨 위 · devplan pfs-monthly-close-pick.html.
✅ 26.9.22 · pfs-nesting-drawer-calc · 네스팅 「서랍 자동계산기」(도어전용 탭) (운영 a9c5d22+5faf806) — NOW 에서 이관
산출식은 정본 drawerBox() import 재사용(SPEC-DRAWER §3, 복제 금지) · 텐덤은 마이다 폭 −103/−115 · 후판 소65·대142
(imos 실발주 8/8 편차 0) · 확신 낮은 값은 전부 입력칸. 파일 1개(web/nesting/nesting.html), 서버·DDL·사이트맵 변화 0.
🆕2차 = 재단치수 내림 정수(두께만 예외) + 결 부재(서랍측판·전후판·텐덤후판) 가로/세로 뒤집기 + 세로결 — 규칙 2줄은 rules.md 🆕 맨 위.
검증 1차 로컬 61/61·테스트 68/68·운영 69/69 → 2차 로컬 65/65·테스트 72/72·운영 73/73(쓰기 0건). 원문 = archive.md 「✅ 26.9.22 · pfs-nesting-drawer-calc」 ·
세션 = session-2026-09-22-nesting-drawer-calc.md · 함정 3건 = rules.md 🆕 맨 위 · devplan pfs-nesting-drawer-calc.html.
⏳[페페] 5건 = 실무값 4개(마이다 상하·좌우 갭 / 단 사이 갭 / 날개폭 / 뒷판을 독립형에만) + 육안 1회(3단 산출 vs 실제 재단치수).
✅ 26.10.16 · pfs-handoff-cap-1016 · 26.10.14 소요한남2차 완료절 이관
[코디] 🆕 26.10.14(수) 8차 ✅ 운영 22:11 KST — 소요 한남 2차 #803 16행 전부 몸통 옵션(PET 2행 포함) — [페페] 「무늬목 마감 금액이 별도로 빠져서 몸통이 맞다 · 펫 등 소재는 직접 보고 전체로 복원 · 운영배포」 · 화면식(자당·마진 몫 × 0.65 + sub 그대로) 계산값으로 PUT /api/estimate/803 1회(part_mode·행 금액만 · 단가·sub 85줄·마진·부가비·운반·시공 불변) · 독립 GET ALL OK · 운영 화면 토글 16행 「몸통」·총합계 = DB · 행 합 29,032,000 → 23,855,000 · 총액 52,380,700 → 47,203,700 · 한샘 V7 NAS(sha256 af8c98c2… · 생산비+시공비 47,198,700) · devplan 단가 페이지 결론·총액 갱신 검산 ALL OK · ⏳[페페] PET 등 소재 행 「전체」 복원(직접) → 복원 후 한샘 V8 · 상세 = session-2026-10-14-sohan2-hansem-803.md 「8차」
[코디] 26.10.14(수) 7차 ✅ 운영 21:18 KST(→ 8차에서 행 몸통 전환 · 단가는 그대로 유효) — 소요 한남 2차 #803 월드 sub 단가 1차 우선 재조정(6차 대체) — [페페] 「라인·일레븐 현장 빼고 · 소요 한남 1차 1순위 · 없는 규격은 타현장(최근 우선) · 최소·평균 후순위 · 물가 고려 최근 위주 · 운영배포」 · 표본 955행 − 라인·일레븐 486행 = 1차 무늬목 24 · 타현장 무늬목·도장 268행(롯데 25.5 · 판교·청담 25.12 · 학동 26.5 …) · 현장 수준 보정 폐지 · 한남 소요 MH 도장 블록(반값)은 손잡이판에만 1:1 · 등급(75줄) 1차 43 · 타현장 29(전부 구단가 — 2026 타현장 무늬목·도장 중 맞는 규격 0) · 후순위 평균 3 · PUT /api/estimate/803 1회(단가 59줄 · 비고 75줄 새 근거 · 마진·조정 10줄 불변) · 독립 GET ALL OK · 원가 10,000,000 → 10,540,000 · 마진 후 13,500,000 → 14,229,000 · 총액 51,651,700 → 52,380,700(5차와 합계만 우연히 같음) · 한샘 V6 NAS(sha256 8a9f26fc… · 생산비+시공비 52,368,700) · devplan 단가 페이지 7차(규칙 순서·등급 배지·뺀 현장·기간 추세·6→7 전후) 검산 ALL OK · ⏳[페페] 구단가 29줄(인상률 미적용) 검토 · 조정 10줄 제안(포켓 200폭 80,000 · 목대 30T 70,000 · 오픈장 선반 25T 40,000 · 천판EP 30T 170,000) · 상세 = session-2026-10-14-sohan2-hansem-803.md 「7차」
[코디] 26.10.14(수) 6차 ✅ 운영 20:10 KST(→ 7차로 대체) — 한샘 소요 한남 2차 #803 추가금액(월드 무늬목 sub 85줄) 2년 단가 재조사 → 46줄 단가 갱신 — [페페] 「단가 조사 좀 더 · 무늬목=도장 1:1 · 최근 2년 월드 견적 · 같은 규격 편차 표시 · 운영배포」 · NAS 월드 견적 엑셀 10파일(2025.4~2026.7 · 항목 1,448 → 중복 빼고 1,086행) · 근거 풀 무늬목 236 + 도장 293 = 529행·11건 · 건별 수준 보정(소요 1차 ×1.07 · 일레븐 MH ×1.19 · 한남 소요 MH ×0.50 = 옛 0.738·「무늬목/도장 2.0」 대체) 후 이웃(긴 변 ±10%) 중앙값 · PUT /api/estimate/803 1회(price 만 · 조정 10줄·마진·행 본체·부가비 불변) · 독립 GET ALL OK · 원가 10,540,000 → 10,000,000 · 마진 후 14,229,000 → 13,500,000 · 총액 52,380,700 → 51,651,700 · 한샘 V5 NAS(sha256 0452123b… · 생산비+시공비 51,638,700) · devplan sohan2-world-price-basis.html 6차(같은 규격 다른 단가 29묶음 · 85줄 실적 범위) 검산 ALL OK · ⏳[페페] 포켓도어 22T 제안(512폭 170,000 · 200폭 60,000) · 25/30T 제안(목대 60,000 · 오픈장 선반 70,000) 확인 · sub 비고는 옛 근거 문구 그대로(단가만 바꿈) · 상세 = session-2026-10-14-sohan2-hansem-803.md 「6차」 · 작업 C:\dev\_work\sohan2-price-2y-1014\
[코디] 🆕 26.10.14(수) ✅ 운영배포 19:54 KST — 견적 v2 「저장된 추가금액 연동 (0/N)」 버튼(저장된 고정 sub → 추가금액 마진 공통칸 일괄 연동 · 인라인 확인 줄 · 「고정으로」 · #qmDelta) — [페페] 「소요한남2차 추가금액 마진 공통 적용 항목에 연동 · 운영배포」 · master 4e5224cb → deploy-live e2621c5f(3파일 선별 · DDL 0) · 테스트 자체검사 ALL PASS(F 24항목) · 운영 #803 읽기 확인 0/85→85/85 · 총액 불변 · 저장 0 · 사이트맵 미반영 3→1(worklog 기존분) · 테스트 견적 829~833 「(삭제 가능)」 · 상세 = session-2026-10-14-est-submargin-linkall.md
[코디] 🆕 26.10.14(수) — 한샘 소요 한남 2차(field 2184 · 99A) 부자재 발주서 초안 = 운영 PFS 부자재 발주서 #8(draft · 11:58:50 KST · 116행 · 미확인 업체 72행) — [페페] 「도면 참고 · 보이는 모든 조명·싱크볼 등 부자재 · 업체 없는 건 미확인 업체」 · 261008 도면(r3 덤프 C:\dev\_work\hannam2-1012\diff\new_prims.pkl) 글·치수·PNG 판독 · 업체 = 도면 글에 이름 있는 것만(봉적 14·이지웨이 10·해람 8·명진 4·유로글라스 3·삼성정밀 2·라고데코 2·헤펠레 1) · 업체 칸 자유입력(VARCHAR) → 「미확인 업체」 문자열 그대로 · 쓰기 = POST 1회뿐(confirm·PUT·DELETE·코드 0) · GET 대조 오류 0 · /excel 시트 9 = 업체 9 · 원장 C:\dev\_work\sohan2-suborder-1014\원장_부자재_소요한남2차_99A_261014.csv(근거 문구 전부) · 세션 session-2026-10-14-sohan2-suborder.md · ⏳[페페] ①참고 행 4(EXEDRA2 「260923 발주완료」·인덕션·음식물처리기·시건장치 = 건설사 지급분) 삭제 여부 ②다인스 제작분 18행 범위 ③수량 확인필요 26 · 규격 확인필요 50(조명 길이·유리도어 높이·SMPS 용량·아일랜드 레일 타입 혼재) ④주방 「키큰장,하부장 전체 제외 발주완료」 범위 ⑤미확인 업체 72행 업체 지정 ⑥비고 ⚠문구는 엑셀 비고에 찍힘 → 발송 전 정리 · 마감재 리스트 xlsx 는 DRM(SCDSA)이라 못 읽음
[코디] 🆕 26.10.14(수) V4 — [페페] 답 반영: PFS #803 운영 PUT 1회 — 네스팅 제외(exc) 행으로 만든 기존 sub 5줄(7장 · 끝판 30T 4 · 목찬넬 2 · 진열칸 E.P(앞) 1 = 1,525,500) 삭제 · 행 비고 × 7개 → * (견적 전체 × 0) · sub 90 → 85 · 총액 53,906,700 → 52,380,700 · 독립 GET ALL OK → 한샘 V4 NAS(…\견적\10월\한샘\소요 한남 2차\…(26.10.13) V4.xlsx · sha256 81536b92… · 갑지 주방 23,228,700 · 수납 21,150,000 · 생산비+시공비 52,378,700) · verify 353 ALL OK · ⏳[페페] 포켓도어 22T·25/30T 추정 단가 직접 조정 → fetch --refresh → run → nas-put --put(V5) · 상세 = session-2026-10-14-sohan2-hansem-803.md 「4차」
[코디] 26.10.14(수) V3 — [페페] 「도어 등 모든 무늬목 네스팅 내용 추가금액에 · 제외 유지 · x → * · 운영배포」: PFS #803 운영 PUT 1회 — 도어 네스팅 #28 제외 아닌 INEK10 중 빠진 53행 59장(도어·포켓도어·서랍앞판·오픈장·목대 30T·벤치)을 위치별 sub 32줄 추가(월드산업 · 마진 35 · 월드 기준 ①12 ②8 ③12 · 매입 6,350,000 · 마진 포함 8,572,500) · sub 58→90 · ×→ 잔존 0 · 부가비·운반·시공 불변 · 총액 45,334,700 → 53,906,700* · 독립 GET ALL OK → 한샘 V3 NAS(…\견적\10월\한샘\소요 한남 2차\…(26.10.13) V3.xlsx · sha256 3ba12e47… · 갑지 주방 23,308,700 · 수납 22,590,000 · 생산비+시공비 53,898,700) · verify 353 ALL OK · ⏳[페페] 🔴기존 sub 7줄이 네스팅 제외(exc) 행(끝판 30T 4·목찬넬 2·진열칸 E.P 1 = 1,525,500) → 뺄지 · 22T 포켓도어 두께 · 200폭 포켓도어 50,000 · 상세 = session-2026-10-14-sohan2-hansem-803.md 「3차 — 무늬목 sub 보강」 · 작업 C:\dev\_work\sohan2-sub-fill-1014\
✅ 26.10.19 · pfs-mat1-h2041b-pndeco · PFS-MAT#1 H2041B-L1 피앤데코 직접발주분 자재관리 복원 + 이선영 사원 카톡 보고 — NOW 에서 이관
- [페페] 「피앤데코 발주서(10.06 발주·10.13 입고) H2041B-L1 누락분 PFS 로 · 운영 · 끝나면 이선영 사원에게 카톡 완료보고」.
- 원인 = #1 자동 행 3개(18T PB 경면양면 16매·4.5T MDF 민자양면 8매 = 업체 효산엘피엘 · 1T22mm 엣지 400M = 선재기업)의 자재관리 행 6383·6384 가 10.13 16:06, 6415(엣지, 그 전에 «완료»)가 10.14 18:25 자재관리에서 수동삭제(del_manual=1)* → 확정 sync 로 안 살아남.
- 조치 =
C:\dev\_work\gs-h2041b-pndeco-1019\apply1.py APPLY— amend(판 38: 피앤데코 수동 행 3개 성포 2180 · 입고 10-13 · 입고처 포인 + 피스마개 스티커 10장 업체 효산엘피엘→피앤데코) → lines/remove(판 39: 옛 자동 행 3개 소프트삭제). 결과 자재관리 신규 10115·10116·10117(대기) · 살아 있는 #1 행 70→73 · 다른 행 내림/추가 0(verify.py, 운영 DB 읽기). 스냅샷 before/after.json. - 카톡 = 미니PC PC카톡 Session 1 일회성 예약작업(W226, 실행 후 삭제·release) → 「포인 이선영」 1:1 방 10:21 발송 확인(
C:\dev\poin-agent\data\kakaopc\send\after_text.png). ⚠미니PC 카톡 계정 poin3133 → delix0731 자동 전환(지침)된 채 둠. - ⏳엣지 400M 실제 입고 여부(옛 행이 10.14 «완료» 뒤 삭제) — 이선영 사원에게 확인 요청함 · 칼라샘플(효산엘피엘→진영LDM)은 그대로.
✅ 26.10.23 · pfs-handoff-cap-1023 · 26.10.20 소요 한남 2차 시공비 거래명세서(지엠테크 V2) — NOW 에서 이관
- [코디] 🆕 26.10.20(화) ✅ 소요 한남 2차(99A) 시공비 거래명세서 지엠테크(홍영재 · 210-04-75085 · PFS 거래처 116) — NAS
\\192.168.0.101\공유폴더\2026현장\견적\10월\한샘\소요 한남 2차\시공 지엠테크 한샘 소요 한남 2차 MH 시공비 거래명세서(26.11.2~4).xlsx(sha 72e30857… · ❌[페페] 「양식이 달라 사용 불가」 → V2 로 대체) → V2…\시공 지엠테크 한샘 소요 한남 2차 MH 시공비 거래명세서(26.11.2~4) V2.xlsx(sha a32cc179…) = 페페 양식(연목테크 자이 안산 · 한셀 저장본) zip XML 수술로 값만 교체(색·폭·머리그림 유지 · 공급자 그림 image1.png 지엠테크로 다시 그림 · 연목테크 직인 image2 투명) · [페페] 「750만 예상 → 최소 600만 전후」 → 조정칸 O2 단가 10% · O4 천장고2600↑ 배수 2.0(TL장 · 근거 = 지엠테크 25.10 명세서 「2590이상 2」) · O5 무늬목 배수 1.2 → 주방 1,645,296 + 수납 4,224,860 = 5,870,156 · 생성기C:\dev\_work\sohan2-install\gen.py· 🆕함정: 한셀 저장 xlsx = openpyxl 스타일 인덱스 IndexError·Excel COM Open 무한대기 → zip XML 수술 ·<x:row …/>자기닫힘 행이 정규식에 다음 행을 삼킴 · ⏳[페페] 조명 줄·포켓 프레임EP 318·욕실장(다인스) 포함 여부 · V1 파일 삭제 승인
✅ 26.10.25 · pfs-handoff-cap-1025 · 26.10.8 kb_digest → cody_ask 전환 — NOW 에서 이관
- ✅[코디] 26.10.8
tools\kb-digest\kb_digest.pyclaude -p →C:\dev\tools\cody_ask.py(API 크레딧 우선·구독 폴백, opus xhigh, callerpfs-kb-digest) — 로컬 배치만(웹앱 무관) · 로컬 커밋3eda7dfc(push 안 함) · 사이트맵 재빌드(미반영 1 = 기존).material_spec_parse.py(PDF Read 도구 필요)는 안 옮김 → cody-agent handoff 미결 4.
✅ 26.10.25 · pfs-handoff-cap-1025b · 26.10.23 발주서 엑셀 현장명 유형·발신 로그인 직원 — NOW 에서 이관
- [코디] 🆕 26.10.23(금) ✅ 운영 09:31 KST — [페페] 「원부자재·자재 발주서 엑셀 다운 = 현장명 뒤 유형(소요 한남 MH) · 작성자 = 로그인 포인 직원」 → 공용
api/pfs/orderpaper/excel_meta.py(field_divs · site_with_div(이미 단어로 있으면 그대로) · login_sender =이름직급(전화), 세션·조회 실패면 저장값) → mat·sub·ALbuild_excel3곳(시트 현장명·파일명·발신 C5) · DB 저장값 불변 · master330138bd/ deploy-live65ac39f9· 운영 실다운로드 = mat #12(초안)에넥스 계룡 진주 판문 MH 원부자재발주서.xlsx· sub #14 B27GS 안산 성포 MH· AL #12AL발주서_계룡 진주 판문 MH.xlsx· 발신은 검증 계정이 신동승이라 값 동일(다른 직원 로그인 실측 ⏳) · mat 자체검사 275/275
✅ 26.10.25 · pfs-handoff-cap-1025c · 26.10.22 DL 포제스 한강 103-203 임시견적 #810 — NOW 에서 이관
- [코디] 🆕 26.10.22(목) ✅ 운영 데이터(코드 0) 아이비젼 DL 포제스 한강 103-203 창고 좌,우문틀+후면휠라 — 아이비젼 단톡 12:55 파일 3개(kakao_get_files) → 동호수배치도 103-203 = 115C(2세대·도면동일) · 물량표 115C 신발장B 21(좌,우문틀 115×2540) · 19(후면좌,우휠라 50×2640) · KCC LA 46N 무광도장 · DWG 시트 「현관창고_도어」(도곽 200990,114858~213590,123768) → 임시견적 #810 「DL 포제스 한강 103-203 AS 견적서」(은지호 418 · temp_field_div 60 · 문틀 90,000×2 + 휠라 60,000×2 + 운반 80,000 = 380,000 VAT별도 · 마진 0 = #761 선례 · 재GET ALL MATCH) + DWG 사본 표기(레이어 CODY_견적 · 굵은 사각형 7·MLEADER 4·색상 규격표 1 · 열면 시트 줌 · ODA 2018 · 왕복 원본 41,820 차이 0) → NAS
\\192.168.0.101\공유폴더\2026현장\견적\10월\아이비젼글로벌\DL 포제스 한강 103-203 창고\(원본 3 + 표기 DWG + 캡처 PNG 3 + 견적 엑셀 · 왕복 일치). 작업C:\dev\_work\posjes\scripts\(texts·frames·render·dims·annotate·verify·register·nas_up). ⏳[페페] 단가·운반비·상문틀 포함 여부 · 회신 미발송 · 🆕같은 날 [페페] 「비고 자재 컬러 · 11월 폴더 · 엑셀 작업 안 함 · PFS 등록만」 → #810 비고 2줄 =컬러 KCC LA 46N 무광 도장 · 18T · …(GET→PUT detail_no 유지 UPDATE · 금액·줄 불변 대조 · 스냅샷C:\dev\_work\posjes\snap_810_{before,after}.json) · NAS…\견적\11월\아이비젼글로벌\DL 포제스 한강 103-203 창고\7개(엑셀 제외 · 11월 폴더 신설) · 10월 폴더 사본은 그대로
✅ 26.10.26 · pfs-handoff-cap-1026 · 단가표 관리(시스템 단가) · GS 대전 도마 수입분 생산 — NOW 에서 이관
- [코디] 🆕 26.10.25(일) ✅ 운영 17:45 KST — [페페 QA] 「견적 분류 «시스템» 단가 65,000 추가 + 단가표 관리 페이지(나만 · 견적서 목록 좌측 상단 버튼)」 → ①운영·테스트 DB 데이터:
common_codeESTIMATE_PRODUCT_DIV Y1 시스템(순서 16) +estimate_priceproduct_div Y × 마감재 11종 price1/2/3 = 65,000(스크립트 scratchpadadd_system.py멱등) ②/estimate/price-table(총관리자만 · 라우트·API 둘 다is_super_admin검사) = 분류 첫 글자 행 × 마감재 열 · 표준/확장(견적 자동값)/특수 전환 · 바뀐 칸 노랑 · 전 칸 검사 후 저장 · APIGET/PUT /api/estimate/price/table③목록 v2 제목 옆 「단가표 관리」(총관리자만) · master38a8f079/ deploy-livea5d64617· 운영 Playwright 10/10(Y1 lookup 65000 · 분류목록 시스템 · JS 오류 0) · 테스트서버 저장 왕복 OK · 🔑같은 첫 글자 분류(A1~A4 · P1/P2 · S1~S3)는 단가 한 줄을 같이 쓴다(화면에 묶어 표시) · ⚠master push 때 로컬에만 있던 남의 커밋 5개가 같이 올라감(pncad 18T 뒤판 e1489c07 · nesting mixed 05382b22 등 = 테스트서버만) · ⏳분류 추가·삭제 UI 없음(요청 시) - [코디] 🆕 26.10.21(수) ✅ GS 대전 도마변동 수입분(포인 견적 787) 생산 작성* — [페페] 「수입분 견적 리스트 → 도면 표기본 + 도어발주서 양식 생산 내용 · 도장=월드탭, 그외=포인탭, 타입별」 → NAS
\\192.168.0.101\공유폴더\2026현장\진행중\10월\한샘 GS 대전도마변동 MH\GS대전도마mh 수입분 도어발주서.xlsm(포인 3쪽 31행 59A·84A·84B · 월드 3쪽 휠라 3행 · 파서 3쪽 31행 OK · VBA·파트 91 동일) +…_실측반영_수입분표기.dwg(최신 26.10.19 사본 · MLEADER 24개·지시선 28 · 레이어 CODY_수입분 · 맑은 고딕 · 2018). 작업폴더C:\dev\order-automation\daejeon-doma-suip_2026-10-21\(spec.py 단일 사양 · run.py/com_write.py Excel COM · annot.py). ⏳[페페] 멍장 부재구성(측판+천지판 가정) · 상부합판 두께 · 걸레받이 높이 150 · 안정기함 그릴타공 · 벽판넬 PVC 넘버 · 지시선 길이(빈 띠가 입면 위뿐 → 2~6.5m)
✅ 26.10.26 · pfs-handoff-cap-1026b · 계룡 진주 판문 #811 초안→소프트삭제 · 789~798 현장 연결 · 795 선택 — NOW 에서 이관
[코디] 26.10.26 handoff 캡(20,000자) 관리로 원문 이관.
- [코디] 🆕 26.10.26(월) 2차 ✅ [페페] 「KR 진주 판문 = 계룡 진주 견적 · #811 소프트삭제하고 이걸로 대체 · 강동식 차장 최종 % 확인」 → #811 DELETE(remove_yn 1) · 789·791~798 → field 2208 연결(앱 PUT · estimate_div 1 · 내용·보관상태 재GET 동일 · 사용 중 = 791 원금+운임 그대로 · 차수 1~9) · 스냅샷
C:\dev\_bench\kr-jinju-panmun\snap_link_before.json· 스크립트C:\dev\order-automation\enex_close_2026-10\r4_softdel_811.py·r5_link_kr_2208.py· 통화 근거 = 강동식 10/15 09:59 large 재전사 48~52초 「15% 정도는 좀 해줘요. 네고 20이나」(4설정 동일 ·C:\dev\talklog\data\calls\에넥스강동식차장_01051154741_20261015095904.m4a.large.txt) · 10/7·10/22 등 다른 통화엔 확정 % 없음 · ✅[페페] 3차 「795로 변경 · 운영배포」 → PUT /795/select = 사용 중 795(−15% · 20,381,000), 나머지 8차수 보관 · 스크립트r6_select_795.py· [페페] 「유리 추가금액·15% 네고 795에 다 적용 — 그대로 쓴다」(코디가 짚은 행총액 3줄 차이 = 문제 아님) - [코디] 🆕 26.10.26(월) ✅(→2차에서 소프트삭제) 운영 데이터(코드 0) 계룡 진주 판문 본견적 초안 #811(field 2208 · 23줄 · 23,226,000 = Σ22,726,000 + 운임 500,000 · 791 원금+운임 23,878,000 대비 −652,000) — [페페] 「NAS 최신 도면 기준 견적서 초안 · 운영배포」. 기준 도면
\\192.168.0.101\공유폴더\2026현장\진행중\10월\에넥스 계룡 진주 판문 MH\KRjp2BL-K09M (건립)(3).dwg(10.21) · 틀 = 791 22줄·추가금액·단가·몸통 65% 그대로, 길이만 PNCAD 09M #65~#68 + diff(벽길이−공제 줄은 공제 유지) · 신설 1줄 84B C' 상부장 290 · 큰 차이 = 전시부스 2100→1500(−511,000) · 84C 보조주방 키큰장 1400→1300 · 789~798 불변 · 재GET·subs 일치 · 화면(modify-v2) 열기만 23행 = 저장값 · 스크립트C:\dev\order-automation\enex_close_2026-10\r3_kr_jinju_09m.py(+ q5_fetch_full · v2_screen811) · ⏳[페페] 미확인 줄 그대로 둔 것(84B 벽판넬G 1250 vs 09M 추정 FIX 750×2290 · 84C 복도 팬트리도어H · 벽판넬B) · 84C 보조주방 하부장 = 789 대로 상부장 단가 · 84B 냉장고장 789 1890 근거 불명 → 09M NU1 1840
✅ 26.10.26 · pfs-handoff-cap-1026c · handoff 캡 이관(원문)
- [코디] 🆕 26.10.22(목) ✅ 운영 데이터(코드 0) — [페페] 「NAS
…\10월\한샘\GS원주단구2BL\1022최종 1.생산비 거래명세서_GS 원주 단구 MH_26년 09월.xlsx기준 PFS 한샘 견적 등록 · 10월 마감건 · 운영배포」 → 한샘 견적 11 「GS 원주 단구 MH 한샘 견적서 (10월 최종)」(parent 7 · 탭 84A(기본)·84A(옵션)·84C(옵션) · 상세 22줄 = 7 에서 복사, 84C(ALT.2) 제외 · 서버 21,797,195) + form 15(비활성 · form 4 3평형 깎음 · 운반비 700,000 · 시공비 0) · 운영 엑셀 = 로컬 빌드 파트 동일 · LO 재계산 본오더 21,790,000 + 운반비 700,000 = 22,490,000 = 1022최종 갑지 일치 · 한샘 10월 월마감 close 24 신설(장동욱 차장 · 행 1 = GS 원주 단구 22,490,000 확정 · 견적번호 미연동 — 포인 견적 763(8.24, 30,853,000)이 옛판이라 연동하면 금액이 그걸로 덮인다). 한샘 7 불변. 스크립트C:\dev\_work\wonju-1022\reg.py·make_form_wonju.py. ⏳[페페] ①한샘 7(9월판) 보관처리 여부 ②포인 763 을 22,490,000 기준으로 고쳐 마감 연동할지 ③NAS 에 PFS 출력본 저장 필요 여부(지시 없어 안 함). - [코디] 🆕 26.10.23(금) ✅ 대전 도마 변동 HS2329LS 엣지 소요량 재산출 → 텔레그램 발송 — NAS 수입분 발주서 최신본(26.10.23 13:52 · 멍장 치수 수정 반영) 포인탭 28행 · 국내분 발주서엔 HS2329 없음 · 15T 22mm 기본 58.7m(59A 9.2 · 84A 28.6 · 84B 20.8) → 발주 150m(전날과 동일) · 계산 = scratchpad
edge.py(nest.py 엣지 규칙 동일 · e4=2(W+H) · e2=긴변 2면)
✅ 26.10.26 · pfs-seongpo-h2041b-edge-1026 · 성포 10월 원부자재발주서 피앤데코 탭에 H2041B-L1 엣지 400M 추가
- [페페] 「H2041B-L1 엣지 발주건 저장 위치 · 원주/성포 중 어느 현장 · 10월 발주서 해당 현장 기존 블록 안에 추가」.
- 저장 위치 = 운영 PFS-MAT#1 line
9e2445a7c3244e2c80d89949bfa26494(H2041B-L1 · 1T*22mm 엣지 · 400M · 피앤데코 · 입고 10-13 · 비고 「246경면 · 피앤데코 직접발주」) = 자재관리 10117 · field 2180. 26.10.19 복원 작업 =C:\dev\_work\gs-h2041b-pndeco-1019\(apply1.py · after.json). - 현장 = GS 안산 성포(2180) — 옛 자동 행 배분 = 성포 실소요 154.35M → 155 · 원주 단구(2169) 0. H2041B-L1 = 성포 유리장 칼라(원주 미사용).
- 조치 = NAS
\\192.168.0.101\공유폴더\2026현장\원부자재발주서\10월\한샘 GS 안산 성포 원부자재발주서.xlsx피앤데코 탭 13행(HS0868GP 5행 다음 빈 서식칸) = B 「H2041B-L1」 · D 「1T*22mm 엣지」 · F 「400M」 · H 「246경면 · 피앤데코 직접발주(10/13 입고)」. zip XML 수술(sheet14 만 · inlineStr · 나머지 파트 바이트 동일 · keywords PFS-MAT#1 유지 → NAS 동기화 이중적재 없음). 스크립트C:\dev\_work\seongpo-h2041b-edge-1026\patch.py· 원본 백업…\orig\· 왕복 md5 cf10f2a1 일치. - ⚠미정리(지시 범위 밖): 같은 파일 선재기업 탭 10행 「H2041B-L1 246경면 1T*22mm 엣지 155M」 · 효산엘피엘 탭 10~12행(18T 16매·4.5T 8매·피스마개 10장) = PFS 에선 10.19 피앤데코로 옮긴 옛 행 그대로. NAS 잠금파일
~$…성포…xlsx(소유 main · 26.10.19 09:56) 남아 있음 — 그 PC 에서 아직 열려 있다 저장하면 이번 추가가 덮인다.
✅ 26.10.26 · pfs-handoff-cap-1026d · 업체 페이지 거래명세서·견적서 PDF 다운로드 — NOW 에서 이관
- [코디] 🆕 26.10.26(월) 16:4x KST ✅ 업체 페이지 거래명세서·견적서 PDF 다운로드(운영
874c1155·a460f232· master89295a6d·4e5e2ac2) — [페페] 「아이비젼글로벌 업체 게시판 · 거래명세서·견적서 pdf(엑셀→pdf) · 운영배포」 · 그릴링 = 현장별 거래명세서 · EC2 LibreOffice · 월마감 담긴 견적만 · 행 칸+표 위 월별 → 거래명세서 엑셀판 신설(api/pfs/monthly_close/service/monthly_close_statement_excel.py· 화면판과 같은 A4 2벌 · 화면판 바꾸면 같이) · 견적서 = 기존build_excel· 변환common/utils/xlsx_pdf.py· 라우트/field/company/<no>/doc/{statement|estimate}/<close>/<seq>.pdf(외부계정 업체 강제·타업체 마감 404) · 화면field_company_list.html카드+「서류」 칸 · 운영 452 8월 close 19 = 10파일 전부 PDF·금액 마감표 일치 · 모바일 390 가로스크롤 0 · 사이트맵 미반영 0 · ⚠EC2 에 apt-t bionic-backports libreoffice-calc-nogui fonts-nanum(신규 56·업그레이드 0) — 서버 이전 시 재설치 필요 · 모든 업체 페이지에 같이 붙음(마감 있는 업체만 카드)
✅ 26.10.26 · pfs-handoff-cap-1026e · 에넥스 10월 마감 close 25 정리 + NAS 저장 — NOW 에서 이관
- [코디] 26.10.26(월) 14:22 KST ✅ 운영 데이터(코드 0) 에넥스 10월 마감 close 25 정리 + NAS 저장 — [페페] 「담기 해놨어 · 마감·견적서 엑셀 10월\에넥스 · 라온 용인 15% 네고 · 각 행 비고 = 추가금액(sub) 항목명 쉼표 · 운영배포」 → 행 4 = 라온 용인 809(39,195,000 · 확정금액 33,316,000 = ×0.85 천원 올림 · 마감 NEGO 칸 방식, 견적 809 자체는 불변) · 라온 대전 808(15,695,000) · 계룡 진주 795(20,381,000) · 부산 788(1,000,000 · sub 없음 → 비고 빈칸) · 합계 76,271,000 · 비고 = 견적 줄 순 sub 이름 중복 제거(표기 그대로: 808 「9T쫄대」 붙여씀) · 재GET 일치 · 백업
C:\dev\order-automation\enex_close_2026-10\close25_before.json/after.json· 스크립트c2_close_note_nego.py·c3_nas_save.py(수식 캐시 채움 · 덮어쓰기 금지) · NAS\\192.168.0.101\공유폴더\2026현장\견적\10월\에넥스\신규 4 =에넥스 10월 마감.xlsx·에넥스 라온 용인 MH 견적서.xlsx·에넥스 라온 대전 MH 견적서.xlsx·에넥스 KR 진주 판문 MH 견적서 -15% (6차) 견적서.xlsx· 부산 = 기존 10.07 본과 셀 동일 → 안 씀 · ✅14:59 [페페] 「월마감 최종 · 라인 VIP 추가2 담기·금액변경 → 마감 엑셀·라인 견적서만 최신화」 → PFS 25 = 5행(784 = 1,440,000 · 라온 용인 확정 비움) · NAS 마감표는 페페 14:28 손저장본(G6 합계 = 네고 33,316,000 값 · 비고 I6~8 삭제)이라 재출력 안 하고 B10·D10 + 캐시만 zip 치환(c6_patch_close_vip.py· 계 71,832,000) · 라인 VIP 견적서 = 704pages=종합,sub:784최상위 신규(LO 재계산 1,440,000) · 「새 폴더」 9.30 옛본 불변 · ⏳[페페] PFS 마감 25 엔 네고 없음(라온 용인 39,195,000)·비고 남아 있음 = 엑셀과 다름
✅ 26.10.26 · pfs-handoff-cap-1026f · 라온 용인 견적 809 총액 34,000,000 — NOW 에서 이관
- [코디] 🆕 26.10.26(월) 17:00 KST ✅ 운영 데이터(코드 0) 라온 용인 견적 809 총액 39,195,000 → 34,000,000 — [페페] 「라온 용인 엑셀 견적서·PFS 수정해서 총 3400만 · 월마감 엑셀은 내가 수정 · 운영배포」 → 전체마진(마스터 margin_percent) -5.13% · 공통마진 연동 유지(자동행 NULL · sub 마진 -5.13 ·
est_sublink:809_mode -513) · -5.13 단독 = 33,997,000 이라 rules 26.10.7 대로 행 10·14·18 만 행마진 -5.12(수동) · 행 24 아일랜드 후면장 페페 수동 0% 그대로(914,000) · 운임 50만 그대로 · 줄합 33,500,000 · 재GET·sub 번호·표식 일치 · PFS 마감 25 행 809 = 34,000,000 자동 반영(마감 합계 72,516,000 · 확정금액 칸 None) · NAS\\192.168.0.101\공유폴더\2026현장\견적\10월\에넥스\에넥스 라온 용인 MH 견적서.xlsx교체(14:22 코디본과 셀 동일 확인 후 · 옛본C:\dev\order-automation\enex_close_2026-10\out\raon_yongin_nas_before_34m.xlsx) · NAS 마감 엑셀 손대지 않음 · 스크립트c7_yongin_34m.py·c8_yongin_nas.py· 백업est809_before_34m.json/est809_after_34m.json· ⚠LibreOffice 헤드리스 재계산이 Session0 에서 멈춤(3분+) → 강제 종료, 검증은 줄 금액 숫자합으로
✅ 26.10.26 · pfs-handoff-cap-1026e · 업체 통합·업체 검색 · 업체 페이지 미리보기 후속 — NOW 에서 이관
- [코디] ✅ 26.10.26(월) 17:3x KST 중복 업체 6쌍 통합 + 봉적 현장 페이지 + 사이드 업체 검색(운영
828eab0c· masterb18800da) — [페페] 「봉적 발주처·수주처 2개 → 하나로 · 동시 표기 · 같은 경우 다른 업체도 · 통합 후 업체별 현장 페이지 · 사이드 업체 그룹 상단 인라인 검색」 · 그릴링 = 6곳 전부 · 작은 번호 남김 · 페이지는 봉적만 → 160←445 봉적(div 10,20 · 대표 김형천·사업자 128-81-18132 채움) · 184←185 씨앤글라스샵 · 218←336 더홈 · 298←365 서광데코 · 335←345 인케이스 · 440←449 이지웨이 · 참조 이관 = field·dispatch·monthly_close·company_member(유니크 충돌 0) · 같은 사람 담당자 82←409 김양훈 · 248←250 임사현(직책 실장 유지 · 대표였던 쪽 삭제) · 403←414 채병철(field.company_member_no · estimate.temp_company_member_no) · 없앤 쪽 = remove_yn 1 + comment 「[26.10.26 통합→N]」 · 백업 EC2/home/ubuntu/pfs-backup/company_merge_20261026082948.json· 스크립트C:\dev\pfs\scripts\_company_merge.py(파일명_apply= 반영) · 🔑동시 표기는 원래 됐다(업체 수정 화면 다중선택10,20) — 고친 건 «완전일치 조회» 2곳 =company_member_dao발주처 담당자 검색(현장 등록·견적·업무패널) ·production_status_dao출력 업체목록 →FIND_IN_SET· 봉적/field/company/160생성(월마감 서류 카드 동작) · 사이드 검색 =web/templates/base.htmlfield_company그룹 상단(Enter 첫 업체 · Esc 지움) · 검사_co_search_check.py운영 FAIL 0 - ✅ 26.10.26 업체 페이지 거래명세서·견적서 PDF 다운로드(엑셀→PDF · 운영
874c1155· EC2 LibreOffice 설치) → archive.md 「pfs-handoff-cap-1026d」 · ✅같은 날 [페페] 「우측 빈 공간 미리보기 · 상단 다운로드 · 기존 버튼 = 미리보기 열기」 → 우측 sticky iframe(inline) + 「PDF 다운로드」(?dl=1= attachment) · 1300px 미만은 패널 숨김·새 탭 · 운영7a23868c·e20fe67e· 검사C:\dev\pfs\scripts\_ivg_preview_check.py(⚠PDF iframe 은 Playwright 기본 chromium 이 다운로드로 처리해 안 보인다 →channel="chrome"+--headless=new로 검사 · load 이벤트도 안 와서 안내문을 iframe 아래 까는 방식) · ✅[페페] 섬네일 목록 기본 숨김 + 가로폭 맞추기 → URL 해시#navpanes=0&view=FitH(운영73fac456)