➕ 기능 추가
무엇 — 정상판매 라이브를 유지한 채 같은 히어로코드에 일회성·기간·업장별 한정수량 노출을 추가하고, 결제완료 기준으로 소진을 카운팅한다.📍 위치: 상품관리 › 수량 제한 관리
핵심 결정
카운팅 기준
결제완료만 카운트(입금대기 제외), 한도 초과분은 최종 발주 취소
노출 방식
같은 히어로코드를 정상가 라이브 + 일회성 노출로 별도 진열(선착순·샘플링)
제한 축
업장별 횟수·수량 + 전체 한정 풀 + 기간(effective~due)
재고 연동
재고운영 코드는 가용 재고 범위 내에서만 소진 허용
선행 의존
선행A 일회성 특가 가격표와 통합 검토 — 결정 필요
01화면 — 먼저 보기
이 티켓이 실제로 어떤 화면이 되는지부터
🚧 [결정 대기] 본 화면을 독립 운영할지, 선행A(일회성 특가) 가격표에 일회성·기간·한정수량 축으로 흡수할지 미확정 — 스키마는 흡수 가능하도록 설계했다.
현행 화면 · 실제 캡처현행 「고객 노출/제한」 — 일회성 수량제한 추가
변경안 · 이렇게 바뀜
상품관리 › 수량 제한 관리기능 추가
유형 ▾상태 ▾🔍 히어로코드·상품명 검색일회성 제한 등록소진 현황 CSV
▲ 수량 제한 관리 목록 — 바뀌는 컬럼 🆕 강조(실 데이터 예시)
1제한 조건 등록 — 어드민이 히어로코드를 검색해 '일회성 제한 등록'을 연다. 기간·업장별 횟수/수량·한정 풀·일회성 특가·재고연동 여부를 입력한다.
2앱 별도 노출 — 정상가 라이브는 그대로 유지되고, 같은 코드에 일회성 조건(선착순·샘플링)이 별도로 추가 노출된다.
3결제완료 카운팅 — 업장이 결제완료하면 소진 원장에 기록된다. 입금대기 주문은 카운트하지 않는다.
4초과·소진 가드 — 업장 한도 초과분은 최종 발주 확정 단계에서 취소되고, 한정 풀·가용 재고가 소진되면 노출을 close 한다.
5만료·전환 처리 — 기간 만료 시 EXPIRED로 종료하고, 상시↔일회성 전환 시 누적 개수 처리 규칙(이월/초기화)을 적용한다.
6소진 현황 모니터링 — 어드민이 업장별 소진·잔여 풀·close 상태를 목록과 원장 상세에서 확인한다.
seller_product_member_limit READ
hero_product_codePK varchar(20)
limit_countinteger
created_byvarchar(20)
created_attimestamp
현행 상시 고객별 수량제한. 기간·유형·풀 없이 히어로코드당 개수만 처리(이번 기능이 이 한계를 확장).
seller_product_onetime_limit 신규
idPK bigserial
hero_product_codeFK varchar(20)
center_codevarchar(20)
per_member_order_countinteger
per_member_qty_limitinteger
total_qty_poolinteger
promo_priceinteger
stock_bound_flagboolean
effective_datedate
due_datedate
statusvarchar(10)
use_flagboolean
created_byvarchar(20)
created_attimestamp
updated_byvarchar(20)
updated_attimestamp
일회성 수량제한 노출 설정. 기간·업장별 횟수/수량·한정 풀·일회성 특가·재고연동 보유.
seller_product_limit_ledger 신규
idPK bigserial
onetime_limit_idFK bigint
member_idvarchar(20)
member_order_idvarchar(16)
counted_qtyinteger
counted_attimestamp
cancel_flagboolean
created_attimestamp
소진 원장(결제완료 기준). 업장별 누적·한정 풀 소진·재구매 차단·초과 취소 판정의 근거.
sample_manage READ
idPK integer
hero_product_codevarchar(100)
order_limitinteger
effective_datedate
due_datedate
use_flagboolean
기간·한정수량·업장 노출 패턴의 기존 선례(샘플링). 신규 스키마 설계 참고용.
seller_product_onetime_limit.hero_product_code → seller_product_member_limit.hero_product_code (동일 코드에 상시·일회성 공존)
seller_product_limit_ledger.onetime_limit_id → seller_product_onetime_limit.id (N:1, 결제완료 소진)
seller_product_limit_ledger.member_id → member.member_id (업장별 누적 카운트·재구매 차단)
seller_product_onetime_limit.hero_product_code → seller_product.hero_product_code (상품 마스터)
-- ============================================================
-- MD-15 고객별 일회성 수량제한
-- 현행 seller_product_member_limit(상시·개수만)의 한계를 확장:
-- 기간 / 업장별 횟수·수량 / 한정 풀 / 일회성 특가 / 재고연동을 신규 테이블로 관리
-- ============================================================
-- 1) 일회성 수량제한 노출 설정
CREATE TABLE seller_product_onetime_limit (
id BIGSERIAL PRIMARY KEY, -- 일회성 제한 ID
hero_product_code VARCHAR(20) NOT NULL, -- 대상 히어로코드(정상 라이브와 동일 코드)
center_code VARCHAR(20), -- 재고운영 시 대상 센터(성동광진 등, NULL=전체)
per_member_order_count INTEGER NOT NULL DEFAULT 1, -- 업장별 허용 횟수(예: 1회)
per_member_qty_limit INTEGER NOT NULL, -- 업장별 최대 수량(예: 50개)
total_qty_pool INTEGER, -- 전체 선착순 한정 풀(NULL=풀 무제한)
promo_price INTEGER, -- 일회성 특가(NULL=가격 변동 없음, 선행A 통합 대비)
stock_bound_flag BOOLEAN NOT NULL DEFAULT FALSE, -- 재고운영 코드 여부(TRUE=가용 재고 내에서만 소진)
effective_date DATE NOT NULL, -- 적용 시작일
due_date DATE NOT NULL, -- 적용 종료일(경과 시 EXPIRED)
status VARCHAR(10) NOT NULL DEFAULT 'OPEN', -- OPEN / CLOSE(풀·재고 소진) / EXPIRED(기간 만료)
use_flag BOOLEAN NOT NULL DEFAULT TRUE, -- 사용 여부
created_by VARCHAR(20) NOT NULL, -- 등록자
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, -- 등록 시각
updated_by VARCHAR(20), -- 수정자
updated_at TIMESTAMP -- 수정 시각
);
COMMENT ON TABLE seller_product_onetime_limit IS 'MD-15 일회성 수량제한 노출 설정(같은 코드 별도 노출·선착순/샘플링)';
CREATE INDEX ix_onetime_limit_code_status ON seller_product_onetime_limit (hero_product_code, status);
-- 같은 코드·센터·기간이 겹치는 활성 일회성 노출 중복 방지(운영 가드)
CREATE UNIQUE INDEX uq_onetime_limit_active
ON seller_product_onetime_limit (hero_product_code, COALESCE(center_code, ''), effective_date, due_date)
WHERE use_flag = TRUE;
-- 2) 소진 원장(결제완료 기준)
CREATE TABLE seller_product_limit_ledger (
id BIGSERIAL PRIMARY KEY, -- 원장 ID
onetime_limit_id BIGINT NOT NULL
REFERENCES seller_product_onetime_limit(id), -- 대상 일회성 제한
member_id VARCHAR(20) NOT NULL, -- 업장(식당)
member_order_id VARCHAR(16) NOT NULL, -- 주문번호(결제완료 주문)
counted_qty INTEGER NOT NULL, -- 소진 수량
counted_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,-- 결제완료 카운팅 시각(입금대기는 미기록)
cancel_flag BOOLEAN NOT NULL DEFAULT FALSE, -- 취소(한도초과 발주취소/환불)로 소진 원복 여부
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
);
COMMENT ON TABLE seller_product_limit_ledger IS 'MD-15 일회성 수량제한 소진 원장 — 업장별 누적·풀 소진·재구매 차단 근거';
-- 업장별 유효 소진 집계 가속(재구매 차단·한도 판정)
CREATE INDEX ix_ledger_limit_member ON seller_product_limit_ledger (onetime_limit_id, member_id) WHERE cancel_flag = FALSE;
04화면 상세 — 세부 표·규칙
목록 외 품목표·모달·규칙 등 세부 화면
일회성 제한 등록 모달
저장 시 seller_product_onetime_limit 1행 생성. 정상가 라이브 진열에는 영향 없음.
소진 원장 (업장별 상세)
결제완료만 집계(cancel_flag=FALSE). 입금대기·한도초과 취소분은 소진에서 제외 표시.