PLD-900 · MD-05·06·07·08 · 그룹3

조건별 판매 옵션 — 이벤트 엔진 흡수

히어로 단품 판매가에 수량·업종·업장·지역 조건을 걸어 타겟 업장에게 할인가로 노출합니다. 별도 엔진을 새로 만들지 않고 이벤트 상품 관리(PLD-548) 위에 흡수합니다. 08/13 회의(버기·미스틱) 반영판.

Type A · 이번 차수 이벤트 엔진 흡수 당사부담 · 정산 불변 프론트 + 백엔드 08/13 회의 반영

바로가기 개요정책ERDDDL화면예외변경점개발노트이슈

✏️ 기존 엔진 확장
이벤트 상품 관리 엔진에 수량 구간 · 정률 · 상시 · 최종가 정책을 얹어 조건별 판매를 완성. 📍 프로모션 관리 › 이벤트 · 조건별 판매

한눈 결론

범위Type A(단품 판매가 할인)만 이번 차수. Type B(결합)=다음 플래닝, Type C(증정)=폐기.
조건 축수량 · 업종 · 업장 · 지역 — 이벤트 엔진의 세그먼트로 녹임(오늘 배포된 세그먼트와 대부분 겹침).
값 · 기간정액(원) / 정률(%) · 기간 지정 / 상시(무기한). 🆕 정률·상시=그룹3 추가
최종가 정책쿠폰 · 프라이싱 기본 제외 = 이 판매가가 최종·최상위가. 옵션 토글로 개별 허용 가능. 🆕 08/13 회의 핵심
겹침 / 공급사동일 상품 이벤트 겹치면 최저가 적용 · 공급사 여러 + 센터 세그먼트 = 매칭 센터 ∩ 타겟 센터 교집합.
정산공급가 · 공급사 정산 불변. 할인 차액은 당사 비용(뒷단). MD 매출엔 판관비 별도라 무관.
01

개요 — 왜 새 엔진이 아니라 흡수인가

그룹3의 미해결 2개를 이벤트 엔진이 이미 풀고 있어, 3~4개만 더하면 완성됩니다.

MD가 요청한 것은 “히어로 단품 판매가를 업장·업종·지역 대상으로 다르게 세팅”입니다(버기). 이는 오늘 배포된 이벤트 상품 관리의 세그먼트 타겟팅과 대부분 겹칩니다. 별도 엔진을 새로 짜면 소스가 이원화되므로, 미스틱 제안대로 이미 개발된 이벤트 엔진 위에 얹습니다(진입점 통합 = 안정성).

이벤트 엔진이 이미 해결한 것박스/세트 묶음 → Type B(결합) · ② “판매가 할인을 누가 부담?”당사부담 모델(공급가·정산 불변) · ③ 업종·업장·지역 타겟 → 세그먼트(고객·업종·센터).
그룹3 완성을 위해 더하는 것 🆕 수량(볼륨) 구간 · 🆕 정률(%)(기존 Type A는 정액만) · 🆕 상시(무기한) 기간 · 🆕 쿠폰·프라이싱 최종가 정책(08/13) · 🆕 적용 마진율 경고(원가/KPI 미달). 조건은 단품(히어로) 단위(그룹 아님).
02

정책 / 정의

조건 축 · 유형 · 값/기간 · 최종가 정책 · 상태.

조건 축 → 세그먼트 매핑

조건 축(MD 요청)이벤트 엔진에서비고
수량🆕 수량 구간 N개 이상 → 추가 할인율가산 · 겹치면 최저가
업종세그먼트 › 업종 단위 (1차 · 세부)biz_type 재사용
업장세그먼트 › 고객 단위(업장 ID) · 엑셀/직접입력기존 판매가 설정과 동일 개념
지역세그먼트 › 센터 단위(복수)MFC 과도기 → 센터 매핑

이벤트 유형

유형내용상태
Type A · 판매가 할인단품 하나에 이벤트 판매가(정액/정률). “990원 딜”·“−12%”. 여러 상품을 각각 만들 수 있음.이번 차수
Type B · 결합 할인최대 10개 묶음 세트 할인(구성 상품을 모두 담아야 적용). 박스/세트 = 여기서 대체.다음 플래닝
Type C · 증정N개 구매 시 증정품. (초기 abc 중 c)폐기
“그룹은 아니에요”(버기) — 조건은 단품(상품) 판매가에 겁니다. 상품을 묶어 파는 건 Type B. 단품을 여러 개 각각 등록하는 것과 결합은 다릅니다.

값 · 기간

항목옵션계산 / 규칙
할인 값정액(원) / 정률(%) 🆕정액=고정가 · 정률=현재판매가×(1−r/100). 차액=현재가−이벤트가(개당 자사부담).
기간기간 지정 / 상시(무기한) 🆕상시=end_at NULL·상태 always·언제든 즉시 중단.
수량 구간🆕 on/offN개↑ → 추가 할인율(%) 가산. 앱에 “3개↑ −5%” 안내.
적용 마진율🆕 실시간 표시 + 경고(적용가−NET단가)/적용가 · NET단가=NET공급가×1.1. 원가 미달=역마진 ⛔ · KPI(16.5%) 미달 ⚠️(소프트, 저장 가능).

🆕 쿠폰 · 프라이싱 최종가 정책 08/13 회의 핵심

이벤트 판매가는 이미 상품 마진을 태워 정한 값입니다. 위에 쿠폰·VIP프라이싱·사이렌(신규회원가)·영업 개별가가 겹치면 실결제가 원가·시장가 밑으로 빠질 수 있습니다(바이럴·경쟁사 노출 리스크). 그래서 기본은 추가 할인을 막아 이 판매가를 최종·최상위가로 고정합니다.

옵션기본값의미
coupon_allowed 쿠폰 적용false (제외)이 상품엔 쿠폰 사용 불가.
pricing_included 프라이싱 포함false (제외)VIP 프라이싱 · 사이렌 · 영업 개별가 미적용.
합의 근거 — MD: “쿠폰·마케팅비는 판관비 별도라 MD 매출엔 무관.” 전략(미스틱): “그래도 유저 체감가·외부 노출 방어가 필요.” → 기능은 제공하되 기본 제외, 필요 시 토글로 개별 허용. Type B에도 동일.

상태 머신

임시저장 승인대기 예정 진행중/상시 종료·중단(즉시)

승인 완료 시 노출. 기간 지정=예정→진행중→종료 자동. 상시=승인 후 always 유지, 수량 소진 또는 수동 중단으로 종료.

03

데이터 모델 (ERD)

신규 5테이블(1 결합은 다음 차수) + 기존 참조.

신규 (NEW)
event_sale NEW
idPK
typeA/B
value_modeamt/pct
valuenumeric
period_moderange/always
start_at / end_atts
coupon_allowedbool ⊘
pricing_includedbool ⊘
budget_capnumeric
statusenum
이벤트/조건별 판매 마스터. hl=그룹3 추가 컬럼.
event_sale_product NEW
idPK
event_sale_idFK
hero_code단품
group_code식별
base_price스냅샷
event_price계산
supplier_id참고(hero)
1 이벤트 : N 단품(히어로). 공급사는 히어로에 종속.
…_volume_tier NEW
idPK
event_sale_idFK
min_qtyN개↑
discount_rate%
🆕 수량(볼륨) 구간. 0..N행.
…_segment NEW
idPK
event_sale_idFK
seg_typeall/cust/biz/center
segment_ref_idFK?
value_jsonjsonb
타겟 세그먼트. 세그먼트 관리 참조 또는 직접값.
기존 참조 (READ)
seller_product READ
hero_code단품
sale_price현재가
margin_rate마진
현재 판매가·마진 기준값.
member READ
member_id업장
sub_biz_type_id업종
고객/업장 타겟.
center · biz_type READ
center_id지역
biz_type.parent_id1차/세부
지역·업종 세그먼트 원천.
segment READ
segment_idPK
rule_json구매이력·등급
세그먼트 관리 — 불러오기/결합.
event_sale 1 ─< event_sale_product >─ seller_product(hero_code) · >─ seller(supplier_id)
event_sale 1 ─< event_sale_volume_tier · 1 ─< event_sale_segment ─> segment / member / center / biz_type
event_sale 1 ─< event_sale_combo_item (Type B · 다음 차수)
04

DDL

Postgres 기준 초안. 🆕 = 그룹3 추가 컬럼/테이블.

-- 조건별 판매(이벤트) 마스터
CREATE TABLE event_sale (
  id                BIGINT PRIMARY KEY,
  name              VARCHAR(120) NOT NULL,
  type              VARCHAR(1)  NOT NULL DEFAULT 'A',   -- A:판매가할인, B:결합(다음)
  value_mode        VARCHAR(3)  NOT NULL DEFAULT 'amt', -- 🆕 amt:정액, pct:정률
  value             NUMERIC(12,2),                       -- 정액=원, 정률=%
  period_mode       VARCHAR(6)  NOT NULL DEFAULT 'range',-- 🆕 range/always(상시)
  start_at          TIMESTAMP,
  end_at            TIMESTAMP,                             -- always면 NULL
  per_store_limit   INT,                                   -- 업장당 구매 한도
  total_qty         INT,                                   -- 총 판매 수량
  auto_end_soldout  BOOLEAN DEFAULT TRUE,
  budget_cap        NUMERIC(14,0),                        -- 자사부담 예산 상한
  coupon_allowed    BOOLEAN NOT NULL DEFAULT FALSE,  -- 🆕 08/13: 기본 제외
  pricing_included  BOOLEAN NOT NULL DEFAULT FALSE,  -- 🆕 VIP/사이렌/영업가 기본 제외
  status            VARCHAR(12) NOT NULL DEFAULT 'draft',
  approved_by       BIGINT,  approved_at TIMESTAMP,
  created_by        BIGINT,  created_at  TIMESTAMP DEFAULT now()
);

-- 대상 상품 · 이벤트 판매가 (단품 기준, 1:N)
CREATE TABLE event_sale_product (
  id             BIGINT PRIMARY KEY,
  event_sale_id  BIGINT NOT NULL REFERENCES event_sale(id),
  hero_code      VARCHAR(20) NOT NULL,     -- 단품
  group_code     VARCHAR(20),               -- 같은 상품의 공급사 그룹(식별)
  base_price     NUMERIC(12,2),             -- 현재 판매가 스냅샷
  event_price    NUMERIC(12,2),             -- 계산·저장된 이벤트가
  supplier_id    BIGINT                     -- 히어로의 공급사(참고, hero에 종속)
);

-- 🆕 수량(볼륨) 구간
CREATE TABLE event_sale_volume_tier (
  id            BIGINT PRIMARY KEY,
  event_sale_id BIGINT NOT NULL REFERENCES event_sale(id),
  min_qty       INT NOT NULL,          -- N개 이상
  discount_rate NUMERIC(5,2) NOT NULL  -- 추가 할인율 %
);

-- 타겟 세그먼트 (1:N, seg_type별)
CREATE TABLE event_sale_segment (
  id             BIGINT PRIMARY KEY,
  event_sale_id  BIGINT NOT NULL REFERENCES event_sale(id),
  seg_type       VARCHAR(10) NOT NULL,    -- all/customer/biz/center
  segment_ref_id BIGINT,                    -- 세그먼트 관리 FK(불러오기)
  value_json     JSONB                      -- cust:[store_id] / biz:{first,sub[]} / center:[id]
);

event_sale_combo_item(Type B 결합)은 다음 차수라 생략. 노출 조회 시 coupon_allowed=false면 장바구니·결제 단계에서 쿠폰/프라이싱 스택을 차단.

05

화면 흐름 — 등록 모달 (라이브 프로토)

오른쪽 번호가 왼쪽 프로토의 각 블록 설명입니다. 🆕 = 그룹3 추가 · 회색 번호 = 기존 엔진.

↕ 프레임 안에서 스크롤 · 새 창에서 열기 ↗
1이벤트 유형 A / BType A(단품 판매가)만 이번 차수. B(결합)=다음, C(증정)=폐기.
2🆕 할인 방식 — 정액 / 정률기존 A는 정액(990원)만 → 정률(%) 추가. 조건별 판매는 대개 정률.
3🆕 기간 — 지정 / 상시상시(무기한) 모드 추가. 종료일 없이 노출, 즉시 중단 가능.
4대상 상품 · 이벤트 판매가 (단품)단품(히어로) 하나 선택 + 이벤트가. 현재가→적용가·할인율·차액 + 🆕 적용 마진율(원가·KPI 미달 시 경고). 여러 상품은 각각 추가.
5🆕 수량(볼륨) 구간N개↑ 추가 할인율. 가산 · 겹치면 최저가 · 앱 “3개↑ −5%” 안내.
6타겟 세그먼트전체 / 고객(업장ID) / 업종 / 센터 + 세그먼트 관리 불러오기 · 구매이력·등급 결합.
7🆕 쿠폰 · 프라이싱 최종가 정책기본 제외 = 이 판매가가 최종·최상위. 앱 미리보기에 “🔒 최종가” 표기.
8예산 시뮬 · 겹침 경고 · 앱 미리보기예상수량×차액=자사부담 vs 상한. 동일유형 겹침 경고(최저가).
  1. 상품·유형 선택 — 단품 검색 → Type A · 정액/정률 · 기간(지정/상시).
  2. 조건 설정 — 대상 공급사 · 수량 구간 · 타겟 세그먼트(업종/업장/지역).
  3. 정책 확인 — 쿠폰/프라이싱 제외(기본) · 예산 상한 · 겹침 경고 확인.
  4. 승인 요청 → 승인 완료 시 타겟 업장에 최종가로 노출.
06

정책 · 예외

상황처리
같은 상품에 이벤트 겹침최저가 적용(가장 큰 할인). 동일 유형 겹침은 등록 시 경고.
공급사 여러 + 센터 세그먼트공급사 매칭 센터 ∩ 타겟 센터 교집합에만 노출.
쿠폰 / VIP프라이싱 / 사이렌 / 영업 개별가기본 제외(최종가 고정). 옵션으로 개별 허용.
공급가 · 공급사 정산불변. 할인 차액 = 당사 비용(뒷단).
수량 소진auto_end_soldout면 자동 종료.
승인 전노출 안 됨(임시저장/승인대기). 승인 완료 후 노출.
Type B(결합) / Type C(증정)B=다음 플래닝 · C=폐기.
07

원본 대비 변경점 — 이벤트 목업 v3.0 → 그룹3 흡수

원본(이벤트 상품 관리 v3.0, 미스틱)이 이미 갖고 있던 것 위에, 그룹3에서 없던 것만 얹었습니다.

화면 나란히 (Before / After)

BEFORE 원본 이벤트 목업 v3.0
원본 이벤트 상품 등록 모달
유형 · 기간(지정만) · 대상상품 · 계산 · 예산시뮬 · 미리보기 · 타겟 세그먼트.
AFTER 그룹3 흡수판
그룹3 흡수판 등록 모달
+ ②🆕정률🆕상시🆕적용 마진율🆕수량 구간🆕최종가 정책 · 앱 “🔒 최종가”.

왼쪽=원본, 오른쪽=흡수판. 오른쪽에만 있는 ②③④⑤⑦(보라 🆕)이 이번 추가분입니다. 번호는 프로토 우측 설명 패널과 동일.

A. 원본 그대로 재사용 vs 🆕 흡수판 추가

영역원본 v3.0 (재사용)🆕 흡수판에서 추가
이벤트 유형Type A(판매가 할인) / Type B(결합)상태 명확화 — A=이번 차수 · B=다음 · C(증정)=폐기
할인 값정액(원)만 — 예 990원🆕 정률(%) 토글 (현재가×(1−r/100))
기간기간 지정(시작~종료, 필수)🆕 상시(무기한) 모드 (end 없음·즉시 중단)
대상 상품+상품 선택 · 이벤트 판매가 · 현재가→차액단품 명시("그룹 아님")
적용 마진율— (없음)🆕 실시간 표시 + 원가/KPI 미달 경고
수량업장당 구매 한도만🆕 수량(볼륨) 구간 — N개↑ 추가 할인율
타겟 세그먼트전체 / 고객(업장ID) / 업종 / 센터 + 세그먼트 관리 불러오기 + 구매이력·등급 결합그대로 (그룹3의 업종·업장·지역이 이걸로 해결)
가격 정책— (없음)🆕 쿠폰·프라이싱 최종가 정책 토글 2개 (08/13)
당사부담 모델공급가·정산 불변 · 차액 당사 뒷단그대로 (그룹3의 "부담 주체" 미해결을 이게 해결)
예산 시뮬 · 미리보기 · 승인 · 겹침 경고전부 있음미리보기에 "🔒 최종가" 표기 · 겹침=최저가 문구
요약 — 원본이 이미 세그먼트(업종·업장·지역)·당사부담·예산시뮬·유형 A/B·미리보기·승인을 갖고 있었고, 그룹3에 필요하지만 없던 5가지(정률·상시·수량 구간·대상 공급사·최종가 정책)만 추가했습니다.

B. 그룹3(MD-05·06·07·08) 요구 → 어디에 어떻게 녹였나

그룹3 요구녹인 위치방식
업장 대상 판매가 세팅타겟 세그먼트 › 고객 단위(업장 ID)원본 재사용
업종 대상 판매가타겟 세그먼트 › 업종 단위원본 재사용
지역 대상 판매가타겟 세그먼트 › 센터 단위원본 재사용
수량 조건 (10개↑ %)🆕 수량(볼륨) 구간추가
정률 할인 (%)🆕 할인 방식 · 정률추가
상시 판매🆕 기간 · 상시(무기한)추가
여러 상품 동시 할인단품을 각각 추가 (그룹 아님)단품 모델
마진 하한 보호 (KPI)🆕 적용 마진율 + 경고추가
박스/세트 묶음 (복제코드 대체)Type B · 결합 할인다음 차수
판매가 / 부담 주체당사부담 모델원본이 이미 해결
겹치면 최저가겹침 경고 + 최저가 규칙원본+강화
쿠폰·프라이싱 배제🆕 최종가 정책 토글추가 · 08/13
08

개발 노트

적용/노출 계산 순서 · 승인 권한 · 인덱스 · 롤아웃.

노출 · 가격 적용 순서 (앱 조회 시)

  1. 대상 상품 매칭 — event_sale_product의 hero_code(단품) 기준 후보 산출. 공급사는 히어로에 종속.
  2. 세그먼트 교집합 — 업장이 타겟 세그먼트(고객/업종/센터)에 속하는지 + 공급사 매칭 센터 ∩ 타겟 센터 교집합 확인.
  3. 기간·상태 필터 — status ∈ {진행중, 상시} 이고 기간 내(상시는 무기한).
  4. 가격 계산 — 정액=value / 정률=base×(1−value/100). 수량 구간이 켜져 있으면 담은 수량으로 tier 매칭해 추가 할인 가산.
  5. 겹침 해소 — 같은 상품에 복수 이벤트가 걸리면 최저가 선택.
  6. 추가 할인 차단coupon_allowed=false/pricing_included=false면 장바구니·결제 단계에서 쿠폰·VIP프라이싱·사이렌·영업개별가 스택을 제외(최종가 고정).
차단 지점정책 차단은 가격 계산이 아니라 장바구니→결제 파이프라인에서 적용해야 합니다(다른 할인 소스가 그 단계에서 합산되므로).

승인 · 권한 · 상태 전이

행위권한결과
등록/수정 · 임시저장MDstatus=draft (노출 안 됨)
승인 요청MDdraft → pending
승인승인권자(전략/책임)pending → scheduled/running(또는 always)
즉시 중단MD/승인권자running/always → stopped (노출 즉시 내림)

인덱스 · 마이그레이션 · 롤아웃

  • 인덱스event_sale(status, start_at, end_at) · event_sale_product(hero_code, supplier_id) · event_sale_segment(event_sale_id, seg_type). 앱 조회는 hero_code→활성 이벤트 역인덱스가 핵심.
  • 마이그레이션 — 신규 테이블만 추가(기존 스키마 무변경). 이벤트 엔진(PLD-548) 위 확장이라 파괴적 마이그레이션 없음.
  • 롤아웃 — 이번 차수 Type A만. 겹침=최저가·정책 기본 제외로 배포 → 데이터 관찰 후 Type B(결합)·조건축 세그먼트 완전 통합은 다음 플래닝.
  • API 개요 — 목록/상세/생성/수정/승인/중단 + 앱 노출조회(hero_code·업장 컨텍스트 → 적용가·정책 플래그).
09

오픈 이슈 · 다음 단계

정렬 필요이벤트 상품 관리는 별개 프로젝트(PLD-548, 오너 미스틱). “흡수”는 곧 그룹3(PLD-900)을 이 엔진에 얹자는 조직 결정 → 오너 정렬이 선행. 이 문서·프로토가 정렬 자료.
다음 플래닝(미스틱)조건 축(수량·업종·업장·지역)을 세그먼트로 완전 통합하는 고도화 기획을 다음 플래닝에 리뷰 예정. 이 프로토를 골조로 사용.
  • 월 구매량별 조건은 다음 차수로 미뤄도 되는지(현재 수량=단건 볼륨).
  • 권역(센터 묶음) 정의 기준 — MFC 과도기 반영.
  • 공급사 협의 범위 — DC 매입 상품 한정 여부.
  • 쿠폰 토글 = 쿠폰 1개 vs 쿠폰·프라이싱 2개 (현재 2개).

검수 결과 — 배포 시 이펙트 (DB 실측 반영)

기존 기능과의 관계 · DB 확정member_discounts(discount_type=사이렌·업종별상품·업장별상품 할인, hero_product_code·discount_rate·기간·엑셀)가 이미 존재. 이벤트(당사부담)와 자금 성격이 달라 별개 기능이나, 같은 히어로에 둘 다 걸리면 가격 우선순위 규칙을 두 소스 공통으로 정의해야 함.
이펙트대응
쿠폰/프라이싱 배제는 결제 단계 가드 — 이번엔 토글(UI)만, 실제 차단은 장바구니·결제에서 “이벤트가 쿠폰=off면 스킵”차단 로직 미배포 시 이벤트 상품 수동 제외 운영 필요(사이렌·프라이싱·쿠폰).
역마진/과할인 — 정률+수량구간 가산으로 원가·KPI 미달 가능🆕 적용 마진율 경고(소프트) 반영. 하드 차단 여부는 정책 결정.
바이럴·경쟁사 유출 — 세그먼트 타겟이어도 캡처 유출큰 할인일수록 리스크. 노출 범위·배지 문구 검토.
상품단위 자사부담 누적 — 예산 상한은 이벤트별같은 상품 다수 이벤트 겹칠 때 총부담 관리 장치 필요.
MFC 과도기 — 센터 재편(영등포·마포·서울대) 중센터 세그먼트 매핑 주기적 갱신.
정산·회계 — 자사부담 차액 계정 처리재무 정합(GMV 1원단위·데이터마트) 확인.
승인 병목 · 조회 성능승인 워크플로 · 앱 핫패스(event+segment+discount+coupon) 인덱스/캐시.
OrderHero · MD 조건별 판매 옵션(PLD-900 · 그룹3) · 08/13 회의 반영 · rev 2026-08-14
라이브 프로토: md-group3-absorb.pages.dev · 원본(05·06·08): md-group3-app.pages.dev