MD-15 · 상품 관리

고객별 일회성 수량제한

상시 수량제한(기간 없는 업장별 구매 캡)에 더해, 기간·업장별 횟수/수량·한정 풀·일회성 특가를 같은 히어로 코드에 별도로 얹는 프로모션 제한. 정상가 노출은 유지하고, 소진은 결제완료 기준으로만 카운트한다.

MD-15 상품 관리 어드민 그룹3 흡수/분리 미정
신규 + 확장
신규 테이블 2 + 기존 재고/결제/노출 파이프 연동. 상시 제한은 그대로 두고 일회성 제한을 별도 레코드로 추가. seller_product_onetime_limit · seller_product_limit_ledger (신규) · seller_product_member_limit (기존) · sample_manage (참조)

한눈 결론

카운팅
결제완료만 풀 차감 · 입금대기 미카운트 · 취소/환불은 원장 역분개
노출
정상가 카드 유지 + 같은 코드에 일회성(선착순/샘플링) 별도 추가
제한 축
기간(효력~마감) · 업장별 횟수/수량 · 전체 한정 풀 · 재고연동
동시성 초과
발주 확정 단계에서 최종발주취소로 정정
⚠ 최대 미정
그룹3(이벤트 엔진) 흡수 vs 분리. 본 문서/프로토는 분리로 가정 — 결정 시 진입·소유·특가계산 이관
01

개요

현재 오더히어로에는 상시 수량제한이 있다 — 기간 개념 없이 한 업장이 특정 히어로 코드를 몇 회까지 구매할 수 있는지를 거는 캡이다. MD-15는 여기에 프로모션성 일회성 제한을 더한다. 판매 기간을 두고, 업장별 횟수·수량 캡과 전체 선착순 한정 풀을 걸며, 선택적으로 일회성 특가(또는 무상 샘플링)를 붙인다.

핵심은 정상 판매를 방해하지 않는 것이다. 같은 히어로 코드가 정상가로도 계속 노출되고, 조건을 만족할 때만 그 아래에 일회성 카드가 별도 추가로 붙는다. 소진 카운트는 오직 결제완료 시점에만 일어난다 — 입금대기는 세지 않으며, 동시성으로 풀을 넘긴 주문은 발주 확정 단계에서 되돌린다.

왜 새 테이블인가 상시 제한(seller_product_member_limit)은 기간·풀·특가 개념이 없다. 일회성은 원장까지 필요하므로 억지로 확장하기보다 별도 테이블 2종으로 분리했다. 선례로 sample_manage의 기간/풀/노출 패턴을 참조한다.
02

정책 · 정의

용어

용어정의
상시 수량제한현행 기능. 기간 없는 업장별 구매 캡.
일회성 수량제한기간·업장별 횟수/수량·한정 풀을 갖는 프로모션 제한. NEW
별도 노출같은 코드를 정상가 + 일회성 조건 두 채널로 동시 표시.
한정 풀전체 선착순 총량. 소진 시 일회성 노출 자동 종료.
최종 발주 취소동시성으로 풀을 초과한 주문을 발주 확정 단계에서 정정.

정책 규칙

#규칙구분
1정상가 노출은 유지되고, 일회성 조건은 같은 코드에 추가될 뿐 정상 노출을 바꾸지 않는다.NEW
2소진 카운트는 결제완료에서만. 환불/취소는 원장 역분개로 되돌린다.NEW
3업장별 캡 초과분은 발주 확정 단계에서 자동 취소(최종발주취소).NEW
4재고관리 코드는 가용 재고 범위 내에서만 소진한다.재고 연동
5소진 후 동일 업장의 재구매는 차단한다.NEW
6기간 만료 시 상태를 EXPIRED로 자동 전환하고 노출을 멈춘다.NEW
7상시 ↔ 일회성 전환 시 초기화 규칙 적용.미정 (§05-2)
8한정 풀 소진 시 일회성 노출 자동 종료.NEW
9그룹3 가격/이벤트 엔진과의 통합은 미정. DDL은 양방향 수용.미정 (§05-1)
카운팅 엣지 입금대기 → 결제완료 전이 시 그 시점에 풀을 차감한다(선점 아님). 그래서 동시 결제완료가 풀을 넘길 수 있고, 그 초과분만 최종발주취소 대상이 된다.
03

데이터 모델

신규 2 + 기존 2. 상시/일회성을 한 테이블에 섞지 않고, 일회성은 설정 테이블과 소진 원장으로 나눈다.

테이블역할구분
seller_product_onetime_limit일회성 제한 설정(코드·업장·기간·캡·풀·특가·재고플래그·상태)NEW
seller_product_limit_ledger소진 원장(주문·수량·시각·상태·취소플래그)NEW
seller_product_member_limit상시 제한(현행) — 하위호환 유지EXIST
sample_manage기간/풀/노출 패턴 선례 — 참조REF
-- 🆕 일회성 제한 설정 CREATE TABLE seller_product_onetime_limit ( onetime_limit_id BIGSERIAL PRIMARY KEY, hero_product_code VARCHAR -- 정상가 노출은 불변, center_code VARCHAR -- 대상 업장/센터, effective_at TIMESTAMPTZ, due_at TIMESTAMPTZ, per_member_order_count INT -- 업장별 주문 횟수, per_member_qty_limit NUMERIC -- 업장별 누적 수량, total_qty_pool NUMERIC -- 선착순 한정 풀, offer_type VARCHAR -- SPECIAL | SAMPLE | QTY_ONLY, promo_price NUMERIC -- 일회성 특가 (정상가와 별개), stock_bound_flag BOOLEAN, status VARCHAR -- PLANNED|RUNNING|EXPIRED|SOLD_OUT, created_at TIMESTAMPTZ, updated_at TIMESTAMPTZ ); -- 🆕 소진 원장 (결제완료만 +카운트) CREATE TABLE seller_product_limit_ledger ( ledger_id BIGSERIAL PRIMARY KEY, onetime_limit_id BIGINT REFERENCES seller_product_onetime_limit, center_code VARCHAR, member_order_id BIGINT, counted_qty NUMERIC -- 취소 시 음수 역분개, counted_at TIMESTAMPTZ, cancel_flag BOOLEAN -- 환불/취소/최종발주취소 );
그룹3 양방향 수용 offer_type·promo_price는 그룹3 가격엔진으로 이관될 수 있는 후보다. 흡수로 결정되면 이 두 컬럼은 그룹3 참조 FK로 대체될 수 있다. (§05-1)
04

화면 흐름

등록 → 노출 → 소진

  1. 일회성 제한 등록 — 히어로 검색·선택 → 업장·기간·업장별 캡·한정 풀·특가·재고연동 입력.
  2. 이중 노출 — 정상가 카드 유지 + 일회성(선착순/샘플링) 카드 별도 추가. 재고/풀/기간 조건으로 표시.
  3. 소진 카운트 — 결제완료 시 원장 +카운트, 풀 차감. 입금대기는 미카운트.
  4. 정정 — 취소/환불은 역분개, 동시성 초과는 발주 확정 단계 최종발주취소.
  5. 종료 — 풀 소진 또는 기간 만료 시 자동으로 일회성 노출 종료(SOLD_OUT/EXPIRED).

어드민 프로토타입

아래는 등록 모달(우측 번호 핀 설명)·이중 노출 미리보기·소진 원장을 담은 클릭 프로토타입이다.

임베드가 비면 프로토를 새 탭에서 여세요 → app/index.html · 우측 설명 패널은 폭 1130px 이상에서 표시
05

⚠ 미정의 항목

스펙에 확정되지 않은 것. 프로토는 아래 가정대로 구성했으나, 확정 전까지 가정은 가정으로 둔다.

1
그룹3(이벤트 엔진) 흡수 vs 분리 — 최대 미정 일회성 제한을 그룹3 조건별 판매(PLD-900)가 흡수할지, 상품 관리 내 독립 기능으로 분리할지 미확정. 현재 그룹3 자체가 검토 중이라 결정할 수 없다.
분리 시: 상품 관리에 독립 등록, 본 DDL 그대로. 흡수 시: 진입이 이벤트 등록으로 이동, offer_type/promo_price가 그룹3 가격엔진으로 이관.
프로토 가정 = 분리 (상품 관리 내 독립 기능)
2
상시 ↔ 일회성 전환 시 초기화 규칙 기존 상시 소진 실적을 일회성으로 넘길지(carryover) 리셋할지 미정. 프로토 가정 = 별도 레코드라 실적 독립(리셋)
3
업장 그룹 지정 지원 여부 대상 업장을 개별/전체 외에 "업장 그룹(예: 수도권)"으로 걸 수 있는지 미정. 프로토 가정 = 전체/개별/그룹 옵션 노출(그룹은 placeholder)
4
무상 샘플링의 결제 처리 promo_price=0(무상 샘플)일 때 결제완료 이벤트가 어떻게 발생·카운트되는지(0원 결제 vs 별도 플로우) 미정. 프로토 가정 = offer_type=SAMPLE로 구분, 카운팅은 동일 원장 사용
5
한정 풀 단위 — 수량 vs 주문건수 풀을 "총 수량(kg/개)"으로 셀지 "주문 건수"로 셀지 스펙이 혼용. 재고연동과 맞물린다. 프로토 가정 = 수량 단위(counted_qty 합), 캡은 별도로 건수/수량 병행
6
동시성 초과 통지 최종발주취소 발생 시 사장님에게 어떤 통지/대체안(정상가 전환 제안 등)을 줄지 미정. 프로토 가정 = 원장에 "최종발주취소" 상태만 표기, 통지 UX는 후속
주의 위 가정들은 프로토를 굴러가게 하려는 임시 결정이다. 확정처럼 개발에 반영하기 전 그룹3 방향(§05-1)부터 정해야 한다 — 이것이 나머지 절반을 좌우한다.
06

다음 단계

  1. 그룹3 방향 확정 — 흡수/분리 결정. 이 결과로 진입 위치·데이터 소유·특가 계산 주체가 갈린다. (선행 · §05-1)
  2. 카운팅 명세 확정 — 결제완료 훅 지점, 역분개 트리거, 최종발주취소 판정 시점을 결제/발주팀과 합의.
  3. 한정 풀 단위 확정 — 수량 vs 건수, 재고연동 상호작용(§05-5).
  4. DDL 리뷰 — offer_type/promo_price의 그룹3 이관 가능성 반영해 컬럼 확정.
  5. 어드민 등록/원장 화면 개발 — 프로토 기준. 상시 목록과 일회성 레코드 공존 처리.
한 줄 데이터·화면은 준비됐다. 막힌 곳은 정책 한 개 — 그룹3 흡수/분리. 그것만 풀리면 나머지는 직진.

OrderHero · MD-15 · rev 2026-08-21 · 프로토: app/index.html