MD-12 · 상품 수정 이력

상품 수정 이력 (필드 단위 변경 추적)

상품의 무엇이 · 언제 · 누가 · 어떻게 바뀌었는지 필드 단위로 기록하는 내부 직원 전용 이력 탭 신설(엑셀분 포함).

🟡 준비 필요 상품관리 내부 전용 백필 범위 결정 대기
🆕 신규 화면 개발
무엇 — 상품의 무엇이 · 언제 · 누가 · 어떻게 바뀌었는지 필드 단위로 기록하는 내부 직원 전용 이력 탭 신설(엑셀분 포함).📍 위치: 상품관리 › 공급사 상품 관리 › 편집/가격수정 › 이력

핵심 결정

무엇을 기록
무엇/언제/누가/어떻게 4요소 — 가격 변경·품절 해제·엑셀분 포함 필드 단위
접근 범위
내부 직원 전용 (공급사 노출 X) — 접근권한 신설
저장 방식
신규 테이블 seller_product_change_history — append-only, 상품 저장과 비동기 best-effort
엑셀분 표시
변경자 = 업로더 계정, batch_id로 원본 업로드 이력 역추적
결정 대기
예전 이력 백필 범위 (과거 데이터는 created/updated만 존재 → 복원 한계)
01

화면 — 먼저 보기

이 티켓이 실제로 어떤 화면이 되는지부터

현재는 만든 날·수정한 날만 남고 엑셀로 올린 변경은 추적 불가 → 필드 단위 이력 신설. 공급사에게는 노출하지 않는 내부 전용 화면이다.
현행 화면 · 실제 캡처
현행 「상품 수정」 — 변경 이력 추적 대상
현행 「상품 수정」 — 변경 이력 추적 대상
변경안 · 이렇게 바뀜
상품관리 › 공급사 상품 관리 › 편집/가격수정 › 이력신규 탭 + 신규 테이블
변경경로 ▾변경항목 ▾🔍 히어로코드·상품명·변경자 검색기간 조회CSV 내보내기
변경일시히어로코드상품명변경항목 🆕변경 전 🆕변경 후 🆕변경경로 🆕변경자 🆕
2026-07-29 14:22HERO0012345국산 대파 1kg넷 공급가●●●●●●직접편집김상품
2026-07-28 09:05HERO0012345국산 대파 1kg품절 여부품절판매중시스템system
2026-07-27 18:40HERO0012345국산 대파 1kg판매가3,2002,980엑셀이엑셀

▲ 상품 수정 이력 조회 — 바뀌는 컬럼 🆕 강조(실 데이터 예시)

1
편집/가격수정 화면 진입 — 공급사 상품 관리에서 상품의 편집 또는 가격수정 모달을 연다. 상단 탭에 '이력' 탭이 신설되어 있다(내부 직원에게만 노출).
2
이력 탭 조회 — 이력 탭을 누르면 해당 히어로코드의 변경 내역이 최신순으로 표시된다. 변경일시·변경항목·변경 전/후·변경경로·변경자를 한 줄씩 확인.
3
필터로 좁히기 — 변경경로(직접/엑셀/시스템)와 변경항목 칩, 기간으로 필터. 이력이 많아도 페이지네이션(기본 20행)으로 나눠 본다.
4
엑셀분 추적 — 경로가 '엑셀'인 행은 변경자에 업로더 계정이 뜨고, 행을 눌러 원본 업로드 배치(파일명·업로드 시각)로 역추적한다.
5
민감정보 열람 — 넷 공급가 같은 민감 항목은 권한 없는 조회자에게 ●●●로 마스킹된다. 열람 권한자만 실제 값 확인.
6
저장 시 자동 기록 — 상품 저장·가격 수정·품절 해제·엑셀 반영이 커밋되면 이력이 비동기로 append된다. 이력 기록이 실패해도 본 저장은 정상 완료된다.
02

정책 / 정의

용어를 못 박고, 규칙을 명확히

용어 정의
용어정의
필드 단위 이력상품 레코드 전체가 아니라 바뀐 개별 항목(예: 넷 공급가, 품절 여부)별로 변경 전/후 값을 한 줄씩 남기는 기록 방식.
변경경로 (change_source)변경이 발생한 통로. 직접편집(MANUAL)·엑셀 업로드(EXCEL)·API·시스템/배치(SYSTEM)로 구분.
엑셀분엑셀 대량 업로드로 발생한 변경. 변경자는 파일을 올린 직원 계정으로 표시하고 원본 업로드(batch)와 연결.
민감정보 마스킹넷 공급가 등 열람 권한이 제한된 값을 권한 없는 조회자에게 가려 보여주는 처리(is_masked).
넷 공급가 (net)공급사로부터의 매입 순공급가. 이력에서 민감정보로 분류되어 마스킹 대상.
백필 (backfill)이력 기능 도입 이전의 과거 변경분을 소급 적재하는 작업. 범위·가능 여부는 결정 대기.
best-effort 기록이력 저장이 실패해도 본 작업(상품 저장)은 그대로 커밋되도록 분리한 비차단 기록 방식.
정책 (규칙)
#규칙비고
1무엇/언제/누가/어떻게 4요소를 모두 남긴다변경항목(field_label)·created_at·changed_by·before/after_value. 하나라도 누락 없이 기록.
2내부 직원 전용 접근권한 신설공급사 계정에는 이력 탭 자체를 노출하지 않는다. 어드민 role 기반 게이트.
3이력 기록 실패가 본 작업을 막지 않는다상품 저장 트랜잭션과 분리(afterCommit/비동기). 이력 insert 실패는 로그만 남기고 저장은 성공 처리.
4엑셀분 변경자는 업로더 계정으로 표시change_source=EXCEL, changed_by=업로더, batch_id로 seller_product_excel_update_history 원본 연결.
5민감정보는 권한별 마스킹넷 공급가 등 is_masked=true 행은 권한 없는 조회자에게 값 대신 ●●● 표시. (가정: 마스킹 대상 필드 목록은 착수 전 확정)
6이력 많아도 나눠 본다히어로코드+created_at DESC 인덱스 기반 페이지네이션(기본 20행). 기간·경로·항목 필터 병행.
7이력은 append-only, 수정·삭제 금지감사 추적 무결성. 정정도 새 행으로 남긴다.
8기존 산발 로그와의 관계 정리품절=seller_product_sold_out_log, 가격=product_price_change_message가 이미 존재. 신규 테이블로 필드 단위 통합 조회하되 이중기록 회피(가정: 신규는 통합 뷰 소스로 일원화).
9예전 이력 백필 범위 = 결정 대기과거 상품은 created/updated 타임스탬프만 존재해 필드별 before/after 복원 불가. 백필 대상 기간·방식 착수 전 결정 필요.
03

ERD

데이터 구조 · 관계 · DDL

seller_product_change_history 신규
idPK bigserial
hero_product_codeFK varchar(100)
group_idinteger
seller_idvarchar(100)
change_sourcevarchar(20)
change_categoryvarchar(30)
field_namevarchar(100)
field_labelvarchar(100)
before_valuetext
after_valuetext
is_maskedboolean
batch_idFK bigint
changed_byvarchar(50)
created_attimestamp
상품 필드 단위 변경 이력(신설). 내부 전용·append-only. 가격/품절/엑셀분 통합.
seller_product READ
hero_product_codePK varchar(100)
group_idinteger
seller_idvarchar(100)
created_attimestamp
updated_attimestamp
공급사 상품 원장(62,497행). 이력의 대상. 히어로코드/그룹/공급사 키 제공.
seller_product_excel_update_history READ
idPK bigint
seller_idvarchar(50)
file_nametext
created_byvarchar(20)
created_attimestamp
엑셀 업로드 배치 헤더(182행, 기존). 엑셀분 이력의 batch 역추적 소스.
seller_product_sold_out_log READ
hero_product_codevarchar(100)
change_typevarchar(20)
sold_outboolean
created_byvarchar(20)
기존 품절 해제 로그(618행). 신규 통합 이력이 이 change_category=SOLD_OUT 소스와 정합.
seller_product_change_history.hero_product_code → seller_product.hero_product_code (N:1, 상품별 이력)
seller_product_change_history.batch_id → seller_product_excel_update_history.id (N:1, 엑셀분만, nullable)
seller_product_change_history.change_category=SOLD_OUT ↔ seller_product_sold_out_log (동일 사건 정합, 통합 조회 대상)
-- 상품 필드 단위 변경 이력 (신설) : 내부 직원 전용, append-only
-- 무엇이/언제/누가/어떻게 바뀌었는지 필드 단위로 기록. 엑셀분 포함.
CREATE TABLE seller_product_change_history (
    id               BIGSERIAL    PRIMARY KEY,                    -- 이력 PK
    hero_product_code VARCHAR(100) NOT NULL,                      -- 히어로코드(상품 표준키)
    group_id         INTEGER      NULL,                           -- 상품 그룹 ID(seller_product_group_mscd)
    seller_id        VARCHAR(100) NOT NULL,                       -- 공급사 ID(내부 기록용, 노출 X)
    change_source    VARCHAR(20)  NOT NULL,                       -- 변경경로: MANUAL(직접편집)/EXCEL(엑셀)/API/SYSTEM(배치·자동)
    change_category  VARCHAR(30)  NOT NULL,                       -- 변경분류: PRICE(가격)/SOLD_OUT(품절)/BASIC(기본정보)/CODE(관리코드)/EXPOSURE(노출)
    field_name       VARCHAR(100) NOT NULL,                       -- 실제 컬럼명(net_supply_price 등)
    field_label      VARCHAR(100) NOT NULL,                       -- 화면 표시용 한글 라벨(넷 공급가 등)
    before_value     TEXT         NULL,                           -- 변경 전 값(문자열 직렬화)
    after_value      TEXT         NULL,                           -- 변경 후 값(문자열 직렬화)
    is_masked        BOOLEAN      NOT NULL DEFAULT FALSE,         -- 민감정보 마스킹 대상 여부(넷 공급가 등)
    batch_id         BIGINT       NULL,                           -- 엑셀분 원본 업로드 연결(seller_product_excel_update_history.id)
    changed_by       VARCHAR(50)  NOT NULL,                       -- 변경자(엑셀분은 업로더 계정, 시스템분은 'system')
    created_at       TIMESTAMP    NOT NULL DEFAULT (CURRENT_TIMESTAMP AT TIME ZONE 'Asia/Seoul')  -- 변경 발생 시각
);

-- 상품별 최신순 조회(이력 탭 기본 정렬) + 페이지네이션
CREATE INDEX idx_spch_hero_created ON seller_product_change_history (hero_product_code, created_at DESC);
-- 변경경로/분류 필터
CREATE INDEX idx_spch_source ON seller_product_change_history (change_source);
CREATE INDEX idx_spch_category ON seller_product_change_history (change_category);
-- 엑셀 배치 역추적
CREATE INDEX idx_spch_batch ON seller_product_change_history (batch_id);

COMMENT ON TABLE seller_product_change_history IS '상품 필드 단위 변경 이력(내부 전용, append-only). 가격·품절해제·엑셀분 포함';
04

화면 상세 — 세부 표·규칙

목록 외 품목표·모달·규칙 등 세부 화면

변경 상세 / 엑셀 배치 역추적 (행 클릭 모달)
항목
변경경로엑셀 업로드
원본 파일20260727_가격일괄.xlsx
업로드 시각2026-07-27 18:39
업로더이엑셀 (batch #182)
변경 전 → 후3,200원 → 2,980원
엑셀분 행 클릭 시 seller_product_excel_update_history의 원본 배치로 연결. 직접편집 행은 IP·세션 등 부가 메타 표시.
변경경로·분류 코드 규칙표
구분코드설명
경로MANUAL어드민 직접 편집
경로EXCEL엑셀 대량 업로드(업로더 표시)
경로SYSTEM배치·자동 품절/재고 반영
분류PRICE / SOLD_OUT / BASIC가격·판매가 / 품절 / 기본정보
change_source·change_category 정의표. 마스킹 대상(PRICE 중 넷 공급가)은 별도 관리. (가정: 마스킹 필드 목록 착수 전 확정)