협상카드
- 목록/조회를 등록자 개인 → 회사(company.users 조인) 단위로 확장: 같은 회사 유저 카드 + 공용(user_id NULL)
- 공용 카드는 기본 제공 자산 → 수정·삭제 불가(OWNER 포함), is_shared=True API 등록 거부
- 개인 카드 변경은 본인∪최고관리자만, 프론트 버튼 disable+툴팁
- 공개범위 셀렉터·엑셀 공개범위 컬럼·CardTable 전체 배지 제거(항상 개인 등록)
- test_card.py 5케이스 재작성
견적 목표가 산정내역
- get_setting_rates: 단일 컬럼 select 결과를 이중 인덱싱해 항상 예외 → 마진율이 늘 0으로 적용되던 버그 수정
- get_target_breakdown: 채택 후보 판정을 '현재 최소값' → '저장 목표가와 값 일치'로 변경(산정 후 상품가 변동에도 초록 체크 유지)
- 견적상세 협상카드 탭 세션ID 컬럼 제거
견적생성 모달
- 목표가 미리보기·마감기한 기본값(+1h)·미래 검증, combobox 팝오버 scrollIntoView, maskPrices 비율(%) 마스킹
Little-Helped: Stupid Claude
라우터가 req.model_dump(exclude_unset=True)로 dict를 만들어 넘기던 것을
req(Req_*) 객체 그대로 전달하도록 변경. 서비스 시그니처를 전부 타입드로 통일.
- create 5개(quotation/card/item/supplier/quotation_setting): ORM은 명시 kwargs
조립(item만 컬럼 16개라 model_dump 펼침). 경계 검증·타입 유지, **data 결합 제거.
- update 4개: 서비스가 req 받아 내부에서 model_dump(exclude_unset=True) 생성 후
CRUD(dict)로 전달 — 공식 PATCH 메커니즘 유지.
- 서비스 계층 data: dict 시그니처 0개. CRUD는 dict 유지(의도).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>