MD-20 · 팝업 구좌 관리

팝업 구좌 관리 (스케줄 캘린더 뷰)

건별로 흩어진 팝업을 자리(구좌)별 스케줄 캘린더로 모아, 지금 뜨는 팝업·예약 팝업·기간 겹침을 한눈에 확인한다.

🟡 준비 필요 읽기 중심 뷰 기존 pop_up 재사용 4순위
🆕 신규 화면 개발
무엇 — 건별로 흩어진 팝업을 자리(구좌)별 스케줄 캘린더로 모아, 지금 뜨는 팝업·예약 팝업·기간 겹침을 한눈에 확인한다.📍 위치: 오더히어로 관리 › 팝업 관리

핵심 결정

화면 형태
자리(구좌)별 스케줄 캘린더(간트 표) — 좌측 자리 레인, 상단 날짜, 팝업은 기간 바
구좌 수 제한
없음 (3차 미팅 확정) — 자리당 몇 개든 등록 가능, 겹침은 경고만
지금 뜨는지 판정
usable=true AND (period_flag=false OR now BETWEEN start_date AND end_date)
자동 내림
end_date 경과 시 조회에서 EXPIRED로 계산 — 저장값(usable)은 건드리지 않음
신규 DB
테이블 신규 없음. 상태 계산 뷰 v_pop_up_live + 캘린더 인덱스만 추가
01

화면 — 먼저 보기

이 티켓이 실제로 어떤 화면이 되는지 먼저 봅니다

지금 라이브 뷰가 없어 어떤 팝업이 떠 있는지 목록에서 일일이 기간을 계산해야 했다 — 자리별 캘린더 한 장으로 대체한다.
현행 화면 · 실제 캡처
현행 「팝업 관리」 — 구좌·스케줄 관리 개선
현행 「팝업 관리」 — 구좌·스케줄 관리 개선
변경안 · 제안 화면
오더히어로 관리 › 팝업 관리신규 탭
자리 ▾상태 ▾🔍 제목·히어로코드목록 보기팝업 등록 ▾
자리(구좌)ID · 제목타입상태노출기간(스케줄 바) 🆕센터노출순서
메인1095 · 농부네_애호박_수도권상품🟢 라이브07/20 ▓▓▓▓●▓▓▓ 08/05서부인천 외 111
메인1093 · [공지] 가락시장 경매 휴무 안내일반🔵 예약⋯ 08/01 ▒▒▒▒ 08/10전체(13)2
장바구니1092 · 두부 특가상품🟢 라이브상시 ▓▓▓▓▓▓▓▓▓성동광진 외 91
주문완료1088 · 첫 주문 감사 쿠폰주문완료⚪ 종료06/01 ░░░ 06/30전체1

▲ 팝업 스케줄 캘린더 — 바뀌는 컬럼은 🆕 로 표시(예시 데이터)

1
팝업 관리 → 캘린더 탭 진입 — 오더히어로 관리 › 팝업 관리 상단에 '목록 | 캘린더' 탭 추가. 캘린더가 기본 뷰. 자리(구좌)별 레인이 세로로 쌓여 뜬다.
2
자리 레인에 기간 바 렌더 — 각 팝업이 start_date~end_date 길이의 가로 바로 그려진다. 상시 팝업은 레인 전체를 덮는 연한 바 + '상시' 라벨.
3
오늘 기준선으로 라이브 판별 — 빨간 세로선(오늘)이 지나는 바는 라이브 배지(초록). 앱에 실제로 뜨는 팝업이 한눈에 구분된다.
4
예약 팝업 확인 — 기준선 오른쪽 바 = 예약(파랑). 자리별로 앞으로 뜰 팝업 순서를 미리 본다.
5
겹침·만료 경고 — 같은 자리에서 라이브 기간이 겹치면 겹치는 구간이 노란 해칭으로 표시(경고, 차단 아님). end_date 지난 바는 흐리게 = 자동 내림.
6
바 클릭 → 상세/수정 — 바를 누르면 기존 팝업 상세·수정 모달이 열려 기간·사용여부·순서를 바로 조정. 저장 시 캘린더 즉시 갱신.
02

정책 / 정의

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

용어 정의
용어정의
구좌(자리 · location)팝업이 뜨는 화면 위치. MAIN(메인)·CART(장바구니)·CATEGORY(카테고리)·MYPAGE(마이페이지)·ORDER_COMPLETE(주문완료) — pop_up.location 값.
라이브 팝업지금 이 순간 사장님 앱에 실제로 뜨는 팝업. usable=true 이고 상시(period_flag=false)거나 기간 내인 팝업.
예약 팝업usable=true·기간제이며 start_date가 아직 오지 않은 팝업. 캘린더에서 오늘 기준선 오른쪽 바로 표시.
종료(EXPIRED) 팝업end_date가 지난 기간제 팝업. 자동으로 노출에서 빠지며 캘린더에 흐리게 표시.
노출 순서(sort_order)같은 자리에 여러 팝업이 라이브일 때 뜨는 순서. pop_up.sort_order(정수, 오름차순).
기간사용(period_flag)true=기간제(start~end), false=상시 노출(무기한). false면 라이브 판정에 기간을 보지 않음.
팝업 종류(type)GENERAL(일반)·PRODUCT(상품 선택, hero_product_code 연결)·ORDER_COMPLETE(주문완료). '팝업 등록' 드롭다운과 대응.
정책 (규칙)
#규칙비고
1캘린더는 자리(location)별 레인으로 그룹핑한다레인 5종(메인/장바구니/카테고리/마이페이지/주문완료). 같은 자리 팝업은 노출순서대로 세로 스택.
2라이브 판정 = usable=true AND (period_flag=false OR now∈[start,end])앱 노출 로직과 동일 식을 v_pop_up_live 한 곳에서만 계산 → 어드민·앱 판정 불일치 방지.
3기간이 지나면 자동으로 내려간다end_date 경과 시 조회에서 EXPIRED로 계산해 노출 제외. usable 컬럼을 배치로 false 치환하지 않음(수동 on/off와 분리) — 가정.
4같은 자리·같은 기간 겹침은 '경고'만 한다구좌 수 제한이 없으므로 저장을 막지 않고, 겹치는 라이브 팝업이 있으면 등록/수정 시 노란 경고 배너로 안내 — 가정(미팅: 겹침 막기 요청 있었으나 구좌 수 제한 불필요로 완화).
5구좌(자리) 수 제한을 두지 않는다3차 미팅 확정. 자리당 등록 개수 상한 없음, 초과 등록 차단 로직 미구현.
6상시(period_flag=false) 팝업은 기간 바 대신 '상시' 태그로 표기start/end가 NULL 가능. 캘린더에서는 레인 전체를 채우는 연한 바 + '상시' 라벨.
7센터 미지정 팝업은 전체 센터 노출로 간주한다pop_up_center에 행이 없으면 전체 대상 — 가정(현행 매핑 방식 확인 필요).
8캘린더는 읽기 전용, 편집은 기존 등록/수정 모달 재사용바 클릭 → 기존 팝업 상세/수정 모달 오픈. 신규 편집 UI 만들지 않음.
9기본 조회 범위는 오늘 포함 ±30일상단 기간 네비게이터로 이동. 만료 팝업은 기본 숨김, '종료 포함' 토글로 노출 — 가정.
03

ERD

데이터 구조 · 관계 · DDL

pop_up READ
idPK integer
titlevarchar(255)
locationvarchar(20)
typevarchar(20)
sort_orderinteger
usableboolean
period_flagboolean
start_datetimestamp
end_datetimestamp
hero_product_codevarchar(20)
팝업 본체(기존). 자리·종류·노출순서·사용여부·기간이 모두 여기 있음 — 티켓의 '이미 있음' 항목. 캘린더는 이 테이블을 읽어 렌더.
pop_up_center READ
pop_up_idPK,FK integer
center_codePK varchar(20)
팝업↔센터 매핑(기존, 187행). 캘린더 바에 노출 센터 태그를 뿌리는 근거.
pop_up_schedule READ
idPK bigint
pop_up_idFK integer
start_timetime
end_timetime
하루 중 시간대 노출(기존, 6행). 캘린더 바에 시간대 있으면 참고 아이콘으로만 표기 — 이번 범위 부가.
v_pop_up_live 신규
idinteger
locationvarchar(20)
live_statustext
start_datetimestamp
end_datetimestamp
신규 뷰. usable+기간으로 라이브/예약/종료/미사용을 계산해 캘린더·목록에 공급(저장 없음).
pop_up_center.pop_up_id → pop_up.id (자리에 걸린 팝업의 노출 센터 목록, N:1, ON DELETE CASCADE)
pop_up_schedule.pop_up_id → pop_up.id (선택: 하루 중 시간대 노출, 캘린더에는 참고 표시)
v_pop_up_live ← pop_up (라이브/예약/종료 상태를 계산해 캘린더/목록에 공급)
-- MD-20 팝업 구좌 관리: 신규 테이블은 없음(기존 pop_up / pop_up_center 재사용).
-- "지금 뜨는지 / 예약 / 종료" 상태는 저장하지 않고 조회 시점에 계산하는 뷰로 제공한다.
-- (사장님 앱 노출 판정 로직과 동일한 식을 어드민 캘린더가 그대로 쓰도록 단일화)

CREATE OR REPLACE VIEW public.v_pop_up_live AS
SELECT
    p.id,
    p.title,                      -- 제목
    p.location,                   -- 자리(구좌): MAIN/CART/CATEGORY/MYPAGE/ORDER_COMPLETE
    p.type,                       -- 팝업 종류: GENERAL/PRODUCT/ORDER_COMPLETE
    p.sort_order,                 -- 노출 순서(같은 자리 내)
    p.usable,                     -- 사용여부(수동 on/off)
    p.period_flag,                -- true=기간제, false=상시(무기한)
    p.start_date,                 -- 노출 시작
    p.end_date,                   -- 노출 종료
    -- 계산 상태: 캘린더 배지/색상 근거 (usable=false는 항상 OFF)
    CASE
        WHEN p.usable = false THEN 'OFF'                                           -- 미사용
        WHEN p.period_flag = false THEN 'LIVE'                                     -- 상시 노출
        WHEN now() < p.start_date THEN 'RESERVED'                                  -- 예약(시작 전)
        WHEN now() > p.end_date THEN 'EXPIRED'                                     -- 종료(자동 내림)
        ELSE 'LIVE'                                                                -- 기간 내 = 지금 뜸
    END AS live_status
FROM public.pop_up p;

COMMENT ON VIEW public.v_pop_up_live IS 'MD-20 팝업 구좌 관리: 자리별 라이브/예약/종료 상태를 조회 시점에 계산(usable+기간). 저장값 변경 없음';

-- 캘린더 조회 성능: 자리 레인 + 기간 겹침 탐색용 복합 인덱스(신규)
CREATE INDEX IF NOT EXISTS idx_pop_up_calendar
    ON public.pop_up (location, usable, start_date, end_date, sort_order);

-- 같은 자리 기간 겹침 "경고"는 저장 차단이 아닌 등록/수정 시 조회로 판정한다(가정, 구좌 수 제한 없음).
-- 예: 겹치는 라이브 팝업 존재 여부
--   SELECT count(*) FROM pop_up
--   WHERE location = :loc AND usable = true AND period_flag = true
--     AND id <> :self_id
--     AND start_date <= :new_end AND end_date >= :new_start;
04

화면 상세 — 세부 표·규칙

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

목록 탭 (기존 팝업 표 + 상태 컬럼 추가)
ID타입제목자리센터노출기간상태노출순서
1095상품농부네_애호박_수도권메인서부인천 외 112026-07-20~08-05🟢 라이브1
1093일반[공지] 가락시장 경매 휴무 안내메인전체2026-08-01~08-10🔵 예약2
1094상품농부네_애호박_지방메인대구 외 1상시🟢 라이브3
현행 목록에 계산 컬럼 '상태' 추가(v_pop_up_live.live_status). 기존 URL 링크·이미지 컬럼은 유지, 여기선 생략 표기.
기간 겹침 경고 (등록/수정 모달 배너)
항목
자리메인
겹치는 라이브 팝업1095 · 농부네_애호박_수도권 (07/20~08/05)
겹침 구간08/01 ~ 08/05 (5일)
처리⚠️ 경고만 — 저장 가능 (구좌 수 제한 없음)
저장 차단 아님. 같은 자리 기간 겹침 시 노란 배너로 안내 후 '이대로 저장' 허용 — 가정(미팅 결론: 구좌 수 제한 불필요).