2026-10-07 세션 — 견적 v2 QA 묶음: 새 견적 빈 1줄 · 추가금액 마진 전역 연동/수동 · 추가금액 빈 줄+Enter · 헤더 전체 펼침 · 별도항목 사용처 펼침
[코디] 26.10.7(수) 09:50~10:50 KST · 총괄 배정 worker(opus xhigh) · [페페] 검증 보고 2건(09:50 KST) + 추가 QA 3건(「운영배포. 이것까지 포함해서 작업해」·「운영배포. 작업추가.」) — 같은 배포.
논의·대안
- 요구
-
1
/estimate/modify-v2#btnAddItem왼쪽 정렬 + 「견적서 시작시 항목 1줄은 기본 빈칸으로 미리」. -
2 하위 그리드 추가금액 마진율(
input.sub-margin)에도 전역 자동·수동 — 상부 「전체마진」 바로 아래 2줄. 기존 견적은 결과값 반영하지 않고 고정. 새 견적은 전체마진과 동일 적용, 직접 입력하면 분리. - B1 (789) 추가금액도 기본 빈 줄 바로 보이게 + 입력 후 Enter = 새 줄.
- B2 (790) 헤더 3번째 「twirl」 = 타입별 추가금액 전체 펼침/접기.
- B3 (790) 별도 항목 자동집계 행(「auto유리도어」) 클릭 = 타입·항목 위치·개별 금액 펼침 목록, 행 클릭 펼침/접기, 이동 · 삭제.
- 추가금액 마진 «연동 여부» 저장 방식 — 대안 3개
- ① sub
margin_percentNULL = 자동 규약(항목 행 마진과 같은 방식) → ⛔기각: 운영estimate_detail_sub818행 중 69행이 이미 NULL(견적 779 복구분). 기존 데이터를 연동으로 오분류한다. - ② 견적
regist_date컷오프 + 값 일치로 연동 추론 → ⛔기각: 의도를 복원할 수 없음(코덱스 동의). - ③ 화면 세션 플래그(
_smAuto) + DB 는 지금처럼 구체값만 → ✅채택. DDL 0. - 운영 실측(SSM 읽기): 운영 sub 저장 금액 ≠ 화면 재계산식(
qty×price×(1+m/100))인 행 = 0건 → 다시 그려도 기존 값이 안 바뀐다. 테스트 DB 는 707 에 18행 어긋남(테스트 데이터, 옛 재계산 동작 그대로). - 코덱스 상의 = 세션 플래그안이 안전 + 미편집 sub 는 NULL·마진·금액 원본 보존 + 「전체 다시 연동」 명시 버튼 권장(범위 밖으로 미결).
- web-designer 상담 2회(작업자 + 총괄 — ruleguard 가 서브에이전트 상담을 못 봐서 총괄 1회 필요, tooling.md 26.9.29 기지 함정 재발).
결정
- #2 추가금액 마진
- 2번째 줄
[추가금액 마진][입력][연동/수동]%. 새 견적 = 연동(전체마진 값 그대로 따라감). - 전역칸 직접 입력 = 수동(분리). 배지 클릭 = 연동 복귀.
- 개별 sub 칸을 직접 입력해 값이 달라지면 그 행만 고정. 비우고 나가면 연동 복귀(「0」 = 고정 0%).
- 저장돼 있던 sub = 전부 고정으로 로드 — 값·금액·NULL 그대로. 전역 모드만 추론: sub 없음 또는 sub 마진 최빈값 = 전체마진이면 연동, 아니면 수동(값 = 그 견적 sub 최빈값).
- ⚠저장 후 다시 열면 연동 칸도 고정으로 열린다(설계, 범례 문구로 안내).
- #1 빈 1줄
- 새 견적(추가건 등록 포함) 시작 = 타입 없는 빈 줄 1개. 첫 타입을 만들면 그 타입으로 들어간다.
- 손대지 않은 새 줄(
isBlankDetail)은 저장 payload 에서 제외. 타입 없이 내용을 넣으면 저장 차단 안내. - +항목 추가 = 왼쪽 60px(추가금액 그리드 시작점).
- B1: sub 0건이면 화면에만 빈 줄(State 미포함 — 저장·집계·「하위 N건」에 안 샌다). 처음 입력할 때 진짜 sub 로 만든다.
- Enter: 마지막 줄 + 품명 있음 = 새 줄(업체 칸 포커스). 품명이 비면 무동작. 중간 줄이면 같은 열 다음 줄.
- 한글 조합 중 Enter·업체 자동완성 Enter 는 양보. 셀렉터는
#qeBody .sub-row로 한정(계산기.sub-grid공유 클래스). - 신규 항목은 추가금액 그리드를 펼친 채 시작.
- B2: 헤더 twirl 버튼 = 현재 타입(+K/F) 중 sub 있는 행 전부 펼침/접기. 하나라도 접혀 있으면 펼침. sub 0건 탭이면 disabled. 계산기 헤더는 그대로.
- B3: 자동집계 행 클릭 = 사용처 줄
[타입][K/F] 항목 No.n 「제품명」 · 수량 · 금액 [이동][삭제]. 펼침 상태 =State.matOpen(입력마다 재렌더해도 유지). - [이동] = 그 타입·K/F 로 전환 → 펼침 → 항목·sub 줄
.new-row2.5초 → 스크롤 → 품명 포커스. - [삭제] = 인라인 2단계([정말 삭제] 3초), × 버튼과 같은 후처리 + 다른 탭 항목 합계 재계산.
- web-designer 처방 반영
- 배지 =
<button>13px 클래스 토글(인라인 style 제거).btn-sm/xs13px. 라벨 #4a5765. - 연동 칸 = #e8f4fd + 점선 #3b8bc2. sub-title·tag 13px + 범례 글자.
산출물·커밋
- 파일
C:\dev\pfs\web\static\js\estimate_regist_v2.jsC:\dev\pfs\web\static\css\estimate_regist_v2.cssC:\dev\pfs\web\templates\finance\estimate\estimate_regist_v2.html- 자체검사
C:\dev\pfs\scripts\_est_submargin_check.py - 커밋
- master
0da95f22(기능) ·78f2ad9c(사이트맵 menu_dump + 검사 기준 스냅샷 보정) - 운영 deploy-live
6a11ee17= 3파일 선별 포워드(배포 경계 diff 0 확인). 운영 정적 md5 = master 일치. - 검증
- 테스트 ALL PASS(기존 707·797 + 새 견적, 저장 payload 는 POST 가로채기 = DB 쓰기 0).
- 운영 ALL PASS 80항목(기존 789·790·785·779 + 새 견적 화면, 저장·POST 0) · 스크린샷 육안(2줄 마진·왼쪽 버튼·연동/고정 칸·사용처 펼침).
- 사이트맵: 배포 전·후 그룹 8 · 페이지 62 · 미반영 1(
/field/worklog타 세션) · estimate 페이지 same.
2차 (11:30~11:43 KST 페페 QA 3건 · 각각 「운영배포」)
- E 헤더 twirl 버그(789) 「먼저 열린 펼침 항목이 안 닫힌다. 전역 접힘·펼침 쓰면 기존 형태 무시하고 따라가게」
- 원인 =
toggleAllSubRows·syncTwirlAll이 「추가금액 1건 이상 행」만 대상으로 잡았다(오전 배포분). - 그래서 추가금액 0건인데 개별로 연 행은 전역 접기 뒤에도 열린 채 남았다. 그런 행만 열린 탭에선 헤더 버튼이 disabled 라 닫을 수단도 없었다.
- 운영 789(84B/K) 재현 = 5번째 행(sub 0, 페페 지목 tr nth-of-type(9)) 개별 열기 → 전역 2회 뒤에도 5번째만 열림.
- 수정 = 대상 = 현재 탭 모든 행. 판정 = 하나라도 열려 있으면 전부 접기, 전부 닫혀 있으면 전부 펼치기(헤더 ▼ = 열린 행 있음 → 표시와 다음 동작 일치).
- master
70a038db· 운영9894a956. - F 타입 항목 0건 화면 = 빈 1줄(789, 지목 = 분류 칸 td5) — 보고 있는 타입(+K/F)에 항목이 0건이면
renderDetailTable이 빈 줄(_seed)을 올린다. - 입력하면 그대로 실제 행이 된다. 손대지 않으면 저장 payload·K/F 건수에서 빠진다(합계 0).
- 오전 #1 새 견적
seedBlankRow는 걷어내고 이 한 곳으로 합쳤다. - master
0842ddba· 운영426cdcde. - G 「단품」 분류(789) 「최상단 · 별도 견적가 없이 치수 300 · 견적서 표기 공백 또는 . · 단가는 직접」
- 분류 마스터 = DB
common_codeESTIMATE_PRODUCT_DIV(15행, code char(2)). 운영 INSERT 안 함 → 화면 가상 분류 U1 을 맨 위에 끼운다(마스터에 U1 생기면 안 끼움). 총괄 승인. - 선택 = 치수1 300·나머지 0·
price_noNULL·단가 자동조회 안 함 → 단가 칸 포커스. 금액 = 단가×수량(1자), 마진 = 기존 행 규칙(자동 = 전체마진, 자당 몫에만). - 출력 치수 공백(「.」 대신 공백 — 수동 치수 문구 있으면 그 문구) 4곳:
_format_dims(인쇄·PDF) ·_spec_text(엑셀 규격) ·estimate_print_v2.js formatDims· 구 v1 인쇄 SQLD1. - master
6aead1b2· 운영a3738ef0(운영 uwsgi 11:54:27 KST 재기동, print data·excel API 789·790 = 200). - ⚠가상 코드 영향 = 마스터 조인
product_div_nameNULL → v2 화면은 화면 매핑으로 「단품」, 구 v1 견적 화면(estimate_modify/regist.html, 사이드바 링크 없음)만 분류명 공백. 출력물은product_div_name안 씀. - 검증 = 자체검사 테스트 76/76 · 운영 110/110 ALL PASS(쓰기 0, test 저장은 비GET 전부 가로채기) · 사이트맵 미반영 1(타 세션) · estimate 페이지 same. master 사이트맵
585a5138.
3차 (16:1x KST) [페페] 결정 「결정필요 사항 모두 추천대로 진행한다. 승인. 2. 연동 유지」 + 신규 「새 견적은 저장 후 다시 열어도 추가금액 마진 연동 유지」
- 결정 3건
- 단품 common_code 정식 INSERT = 보류
- 「모두 연동으로」 버튼 = 안 넣음
- 추가금액 없는 기존 견적의 새 sub = 연동 유지(현행)
- 저장 방식 (DDL 0 · 서버 코드 0)
- 범용 UI 설정 테이블
ui_column_setting(docstring 「UI 컬럼 범용 설정」, UNIQUE(page_key,column_key), 운영 page_key 는 견적 컬럼 1종뿐)과 기존 API(POST /api/common/column-setting/bulk-saveupsert ·GET list/<page_key>)를 재사용한다. - 표식 행:
- page_key =
est_sublink:<estimate_no> _mode행 = is_visible '1' 연동 / '0' 수동, column_width = 추가금액 마진 전역값×100d<항목 display_order>s<sub display_order>행 = is_visible '1' 연동 / '0' 고정
- page_key =
- 메인 저장 성공 뒤 payload 와 같은 위치 규칙으로 현 위치를 전부 덮어쓴다(삭제 API 없음 → 남은 옛 위치 행은 현 위치와 안 겹쳐 무해). 실패는 삼켜 저장 결과 불변.
- 재진입 복원 = 표식 연동 + 저장값 = 지금 전역값일 때만 연동(코덱스 지적 「표식 저장 실패 시 낡은 표식」 대응 — 로드만으로 값이 바뀌는 일 0).
- 표식 없는 견적(이 기능 전 · 복사·재작성본) = 지금처럼 전부 고정.
- 기각한 대안
- sub margin_percent NULL 규약(운영 NULL 69행)
- estimate 헤더 비고·temp_company_name 류 칸(사용자에게 보이거나 의미 무관)
- 서버 트랜잭션 안 저장(돈 경로 서버 변경 — 위 복원 가드로 원자성 없이도 값 안전)
- master
242e6770· 운영9e9d09b2(JS 1파일). - 검증
- 테스트 81/81 — 실저장은 테스트 서버만, 새 견적 822 생성(이름 「자체검사 연동유지 26.10.7 (삭제 가능)」 · 지우지 않음).
- 표식 payload → 재진입 연동/고정 → 전체마진 추종 → 수동 8 저장·재진입 유지 → 9 추종.
- 운영 110/110(쓰기 0): 789·790·785·779 = 표식 없음 → 전부 고정 · 마진 = API 원본 · 운영 정적 md5 = master.
- 사이트맵 미반영 1(타 세션) · master
3d5b261e.
다음
- ~~[미결3] 「단품」 정식 등록 선택지~~ → [페페] 26.10.7 보류 결정. 선택지 원문(참고용): =
INSERT INTO common_code (group_code, group_name, code, value, display_order, use_yn, regist_date) VALUES ('ESTIMATE_PRODUCT_DIV', <기존 group_name>, 'U1', '단품', 0, '1', CURDATE())테스트·운영 각 1줄(운영 DB 쓰기 = 별도 승인). 하면 구 v1 분류명 공백도 풀린다. 화면은 자동으로 마스터 것을 쓴다. - ~~[미결1] 「모두 연동으로」 버튼~~ → [페페] 26.10.7 안 넣음(종결).
- ~~[미결2] 기존 견적 sub 0건의 새 sub = 연동~~ → [페페] 26.10.7 연동 유지(종결).
- 미결 0. 참고 = 테스트 서버 견적 822 는 자체검사용(지워도 됨, 지우는 건 별도 지시).
- 참고(범위 밖·안 고침): 헤더 drag 칸 「drag」 글자 노출 · 1024px 표 넘침 · 항목 행 auto/manual 10px 배지 ·
addNewItemRowmargin_percent 10 고정(자동행이라 입력 시 동기화).
관계
- 주제 그룹: estimate v2 (견적)
- 관련 문서: pfs-session-2026-09-17-estimate-temp-site