상품 수정 이력 MD-12
한눈결론
- 🆕[이력] 탭 신설 — 공급사 상품관리 편집/가격 모달에 필드 단위 변경 이력 탭 추가. 셀러 미노출, 내부 직원만.
- 📍4요소를 남긴다 — 무엇(변경항목)·언제(변경일시)·누가(변경자)·어떻게(변경경로 MANUAL/EXCEL/SYSTEM) + 전/후 값.
- ⛔append-only — 수정·삭제 불가. 정정도 새 행. 이력 기록 실패가 상품 저장을 막지 않도록 분리 커밋.
- 🔒민감정보 마스킹 — 넷 공급가 등은 권한별 ●●●(is_masked). EXCEL 변경은 업로더를 변경자로, batch_id로 원본 연결.
- ⚠️미정 2+3 — 과거 이력 백필 범위·마스킹 대상 필드 목록이 개발 전 결정 필요. 그 외 프로토에서 임의 가정한 항목은 「미정의 항목」에 명시.
01개요
이 기능이 왜 필요하고 무엇을 만드는지.
공급사 상품 데이터(가격·품절·기본정보·코드·노출)는 직접 편집, 엑셀 일괄 업로드, 시스템 자동 반영 등 여러 경로로 자주 바뀐다. 현재는 "언제 누가 무엇을 어떤 경로로 바꿨는가"가 필드 단위로 남지 않아, 가격 분쟁·오작동 추적 시 근거가 부족하다.
MD-12는 공급사 상품관리 편집/가격 모달에 [이력] 탭을 신설해, 상품 필드 변경을 append-only로 필드 단위 기록·조회한다. 기존에 흩어져 있던 seller_product_sold_out_log(품절)·product_price_change_message(가격)를 통합 뷰로 흡수한다.
02정책·정의
기록·조회·권한·마스킹 규칙.
| 정책 | 내용 | 구분 |
|---|---|---|
| 4요소 기록 | 변경항목(field_label)·변경일시·변경자·변경경로 + 전/후 값을 누락 없이 남긴다 | 신규 |
| 내부 직원 전용 | 이력 탭은 내부 롤로 게이팅. 공급사 계정엔 탭 자체 미노출 | 신규 |
| append-only | INSERT 전용. 수정·삭제 금지. 정정은 새 행으로 적재 | 신규 |
| 비차단 기록 | 이력 append는 상품 저장 트랜잭션과 분리. 기록 실패가 본 작업(저장)을 막지 않음 | 신규 |
| 엑셀 출처 표기 | EXCEL 변경자는 업로더 계정으로 표시, batch_id로 원본 업로드 레코드 연결 | 신규 |
| 민감정보 마스킹 | 넷 공급가 등 민감 필드는 is_masked=true → 권한 없는 사용자에게 ●●● | 신규 |
| 페이지네이션·필터 | 20행 기본. hero_product_code + created_at DESC 정렬. 경로·항목칩·기간 필터 | 신규 |
| 레거시 통합 | 품절·가격 변경 로그를 필드 단위 통합 뷰로 흡수 | 기존연동 |
정의: 변경경로(change_source) / 변경분류(change_category)
| 축 | 값 | 의미 |
|---|---|---|
| 경로 | MANUAL | 어드민 직접 편집(IP·세션 메타 동반) |
EXCEL | 엑셀 일괄 업로드(업로더·batch_id 동반) | |
SYSTEM / API | 배치·재고 자동 반영 등 시스템 발생분 | |
| 분류 | PRICE | 판매가·넷 공급가 등 (마스킹 대상 다수) |
SOLD_OUT | 품절/재판매 상태 | |
BASIC | 상품명·카테고리 등 기본정보 | |
CODE | 바코드·코드류 | |
EXPOSURE | 노출/숨김 상태 |
03데이터 모델
신규 테이블 seller_product_change_history (append-only).
| 컬럼 | 타입 | 설명 |
|---|---|---|
| id | BIGSERIAL PK | 레코드 식별자 |
| hero_product_code | VARCHAR(100) | 상품 표준키(조회·정렬 기준) |
| group_id | INTEGER null | 상품 그룹(그룹 상품일 때) — MD-15 연계 |
| seller_id | VARCHAR(100) | 공급사 ID(내부 조회용) |
| change_source | VARCHAR(20) | MANUAL / EXCEL / API / SYSTEM |
| change_category | VARCHAR(30) | PRICE / SOLD_OUT / BASIC / CODE / EXPOSURE |
| field_name | VARCHAR(100) | 내부 컬럼명 (예: net_supply_price) |
| field_label | VARCHAR(100) | 표시 라벨 (예: 넷 공급가) |
| before_value | TEXT | 변경 전 값(직렬화) |
| after_value | TEXT | 변경 후 값(직렬화) |
| is_masked | BOOLEAN | 민감정보 여부 |
| batch_id | BIGINT null | 엑셀 업로드 참조(EXCEL 경로) |
| changed_by | VARCHAR(50) | 사용자 또는 'system' |
| created_at | TIMESTAMP | 변경 시각(Asia/Seoul) |
인덱스: (hero_product_code, created_at DESC) 기본 정렬, change_source·change_category·batch_id 필터용.
seller_product_sold_out_log → SOLD_OUT, product_price_change_message → PRICE로 흡수. 두 로그가 필드 단위 전/후를 온전히 갖는지, 백필 시 무엇을 채울 수 있는지는 미정(§미정의 2).04화면·데이터 흐름
기록 경로별 적재와 조회 흐름.
기록(쓰기)
- MANUAL: 편집/가격 모달 저장 → 필드 diff 계산 → 변경 필드마다 1행 append(IP·세션 메타 포함). 상품 저장 성공 후 분리 커밋.
- EXCEL: 일괄 업로드 처리 시 변경분마다 append,
changed_by=업로더,batch_id=업로드 레코드. - SYSTEM: 재고 동기화·배치가 상태 변경 시 append,
changed_by='system'.
조회(읽기)
- 이력 탭 진입 → hero_product_code로 필터 → 경로/항목칩/기간 AND 조건 → created_at DESC 20행 페이지.
- 행 클릭 → 상세 모달: EXCEL은 파일명·업로드시각·업로더·batch_id, MANUAL은 IP·세션.
- 마스킹 필드는 권한 확인 후 값 또는 ●●● 렌더.
05프로토타입
클릭 가능한 화면. 탭·필터·상세 모달 동작. 우측 번호 핀 = 개발 포인트.
⭐ 미정의 항목
스펙에 정해지지 않은 것. 프로토는 아래 가정대로 그렸으나, 확정 전까지 추측이다. 개발 착수 전 결정 필요.
기존 상품 데이터는 created/updated 타임스탬프만 있고 필드 단위 전/후가 없다. 어디까지 복원 가능한지·언제부터 채울지 결정 필요. 복원 불가 구간은 "이력 없음"으로 둘지, 스냅샷 1행을 넣을지 미정.
넷 공급가는 확실하나, 그 외 어떤 필드까지 마스킹할지(원가·마진율·특정 코드 등)와 마스킹 해제 권한 등급 정의가 없다. is_masked를 채우려면 필드→민감 여부 매핑표가 선행돼야 한다.
이력을 개별 상품(hero_product_code) 단위로만 볼지, 그룹 상품(group_id) 단위로도 묶어 볼지 미정. MD-15의 그룹3 흡수/분리 결정에 따라 group_id 조회 축과 탭 노출 위치가 달라진다.
스키마엔 API와 SYSTEM이 별개지만 필터·배지에서 이를 구분 노출할지, 하나로 합칠지 미정.
MANUAL 상세에 IP·세션을 그대로 보일지, 보안상 상위 롤만 볼지 미정. 감사 가치 vs 내부 프라이버시 절충 필요.
20행 고정인지 사용자 조절 허용인지, CSV/엑셀 내보내기 제공 여부, 이력 보존기간(retention)/파티셔닝 정책 미정.
06다음 단계
- 미정의 1·2 확정백필 범위 + 마스킹 필드·권한 매핑표를 개발 착수 전 결정(가장 앞선 선행).
- 테이블·인덱스 생성seller_product_change_history DDL + append 리포지토리(비차단 커밋).
- 기록 훅 연결편집/가격 저장 diff, 엑셀 업로드 배치, 시스템 반영 3경로에 append 삽입.
- 레거시 통합·백필품절·가격 로그를 통합 뷰로 매핑, 확정된 범위만 백필.
- 이력 탭 UI탭·칩/경로/기간 필터·20행 페이지·상세 모달·권한 마스킹.
- 롤 게이팅·QA내부 롤 접근제어, 셀러 미노출 검증, append-only 회귀 테스트.