← 기능명세서 아카이브
Functional Specification · v2

IVE로 DIVE — 기능명세서 v2

2026 리뉴얼 — 최신 스택 마이그레이션 · 하이브리드 앱 & 푸시 알림 · 디자인 시스템

문서 버전v2 — Draft (리뉴얼 진행 중)
서비스명IVE로 DIVE (ive-three.vercel.app) · Expo 하이브리드 앱(Android WebView, seokachu/ive-app) 병행
문서 기준2026 리뉴얼 진행 중 — dev 브랜치 커밋 dceff37 (2026-09-07) · 마이페이지 · DIVE 멤버십 · 모바일 대응(반응형 · 드로어 메뉴) · 2026 로고 리브랜딩(REVIVE+) · 테마 반응형 파비콘 · 프로필 수정 안정화(소셜 재로그인 원복 수정) · 이미지 크롭 모달 리뉴얼 · 멤버십 플랜 변경 · 해지 취소(구독 재개) · 해지 예정 표시 · 굿즈샵 배송비 정책 · 배송 상태 표기 · 회원탈퇴(글·댓글 보존) · 웹 푸시(PWA) · 앱 다운로드 페이지(/download) · 자유게시판 자동 포스팅 크론 · 금액 숫자 롤링 · 마이페이지 스켈레톤 · 히어로 영상 재생 안정화 · 히어로 영상 피드 복구(유튜브 RSS 쓰로틀 대응) · 루트 경로 정규화(헤더 아이콘 · 로그인 복귀) · 앱 다운로드 GitHub 직결 복귀 · 모바일 하단 탭바(iOS 글라스 BottomNav) · 히어로 영상 iframe SSR 선로드 · 모바일 캡처 시안 재촬영(새 로고) · 앱 뒤로가기 기준(홈 2회 종료 · 탭 루트 → 홈 · 상세는 히스토리 · 열린 시트는 닫기) · 하단 탭바 앱 내 replace · 라우팅 브리지 · 수록곡 iTunes 스토어프론트 폴백(KR → US) 반영 · 앱은 seokachu/ive-app v1.0.7(뒤로가기 현재 경로 기준 · 오버레이 우선 · 스플래시 2단계 정리 · App Links 범위 축소) 기준
작성일2026-07-29 생성 · 2026-08-17 갱신 (음악 · 소식 · 굿즈샵 상세 · 자유게시판 · 장바구니/결제 · 404 · 마이페이지 리디자인 + DIVE 멤버십 + 모바일 대응 반영) · 2026-08-23 갱신 (앱 다운로드 · 자동 포스팅 · 숫자 롤링 · 스켈레톤 · 히어로 영상 반영) · 2026-08-31 갱신 (히어로 영상 피드 복구 · 앱 다운로드 직결 · 앱 v1.0.5 스플래시 · App Links) · 2026-08-31 2차 갱신 (모바일 하단 탭바 · 히어로 iframe SSR 선로드 · 모바일 캡처 재촬영) · 2026-09-06 갱신 (앱 뒤로가기 기준 · 라우팅 브리지 · 앱 v1.0.6) · 2026-09-07 갱신 (뒤로가기 오버레이 우선 · 수록곡 iTunes 폴백 · 앱 v1.0.7)
범위메인 · 음악 · 소식 · 인증 · 자유게시판 · 굿즈샵 · 장바구니/결제 · 마이페이지 · DIVE 멤버십 · 푸시 알림 · 앱 다운로드 · 디자인 시스템 · 공통 UI · 모바일 대응
기술 스택Next.js 16 (App Router, proxy) · React 19 · Supabase(@supabase/ssr) · Zustand · TanStack Query · Tailwind CSS · lucide-react · Tiptap v3(에디터) · 토스페이먼츠 · Expo Push · web-push(VAPID) · pnpm · Playwright E2E · 외부 API(네이버 API Hub 검색 · KOPIS · iTunes Search · Google News RSS · YouTube RSS) · Vercel Cron · GitHub Actions
권한 표기전체 비로그인 포함 누구나 · 로그인 필요 · 작성자 본인 리소스만 · 하이브리드 앱 환경 필요

1. 리뉴얼 개요 (v1 대비 변경점)

v1(Next.js 14, 2025.05.29 배포분) 대비 이번 리뉴얼에서 달라진 것. 상세 동작은 각 섹션에 반영되어 있다.

구분v1v2 (현재)
프레임워크Next.js 14 · React 18 · middleware.tsNext.js 16 · React 19 — middlewareproxy 전환, 동적 라우트 async params 대응
상태 관리Recoil 단일 스토어Zustand — session / cart / checkout / ui 스토어 분리
인증 클라이언트@supabase/auth-helpers (deprecated)@supabase/ssr — 쿠키 기반 서버 검증
개발 인프라npm · E2E 없음pnpm · Playwright E2E 기준선(프로덕션 빌드 기준 15케이스)
플랫폼웹 전용Expo 하이브리드 앱(Android) + 푸시 알림 3종(댓글·답글·좋아요 — 앱 Expo Push · 웹 브라우저 PWA 두 채널) + 수신 설정 토글 + Android App Links — 10·11장
결제 복귀PG 복귀 시 로그인 검사에 걸려 로그인 페이지로 튕기는 문제수정됨 — 서버는 주문번호 검사만 수행하고 로그인 검사는 클라이언트 가드가 담당 (PAY-02)
로그인 진입헤더에서 2단계 모달(소셜 선택 → 이메일)모달 제거, /login 페이지로 단일화 + 로그인 후 원래 페이지로 복귀(?redirect) — AUTH-07
소셜 로그인카카오 · 구글 · 깃허브 (원형 아이콘 3종)카카오 · 구글 (전체 너비 라벨 버튼 2종) — 깃허브 제거
회원가입약관 동의 없음필수 약관 2건(이용약관 · 개인정보 수집·이용) 동의 시에만 가입 가능 + 약관 전문 모달 — AUTH-10
회원탈퇴미구현 — 버튼이 주석 처리된 상태로만 존재지원 — 계정·개인정보는 즉시 삭제하되 작성한 글·댓글은 “탈퇴한 회원”으로 보존 — MY-26
테마라이트 고정다크모드 지원 — 헤더 토글(기본 라이트, 시스템 미연동), 다크 전용 팔레트, 하이브리드 앱 테마 연동 — COM-16 · PUSH-10
UI 기반하드코딩 hex · 컴포넌트별 개별 버튼/아이콘/스피너디자인 토큰(색상 램프·타이포·스페이싱) + ui/button·ui/input 단일화 + lucide 아이콘 · 공용 Spinner(접근성 role 부여) — 12장
화면 리디자인디자인 파일(design/ive-design-system.pen)의 화면 시안을 기준으로 페이지별 전면 리디자인 — 로그인 · 회원가입 · 메인 · 음악 · 소식 · 굿즈샵(목록/상세) · 자유게시판(목록 · 글쓰기 · 상세 · 댓글) · 장바구니 · 결제 · 404 · 마이페이지 · 모바일 대응(14장)까지 완료. 시안 목록은 디자인 시스템 · 시안 문서 참고.
커뮤니티(게시판)번호 중심 표 목록 · 최신순 고정 · 텍스트 수정/삭제 버튼라운지형 리디자인 — 무대 사진 히어로 + 커뮤니티 통계, HOT 3 사진 카드, 필터 필(전체·인기·공지·내가 쓴 글) + 정렬 3종 + 검색 + 글쓰기 툴바, 썸네일·아바타 카드형 로우, 800px 리딩 칼럼 상세(이전/다음 · ⋯ 메뉴 · 그라데이션 추천 · 작성자 카드) — 6장
본문 에디터react-quillTiptap v3로 교체 — 커스텀 툴바(굵게·기울임·밑줄·취소선·목록·인용·링크·이미지) + 글자 수 카운터. 구 글은 기존 서식 CSS로 계속 렌더 — BRD-13
굿즈샵상품 그리드 + 상세(이미지 나열 · 아코디언 안내)상세 V2 — 브레드크럼, 갤러리(화살표·인덱스·썸네일·모바일 스와이프), 플로팅 구매 카드, 세그먼트 필 탭(상세정보/리뷰 n), 별점 분포 리뷰 탭, 추천 섹션, FAQ 스플릿, 담기 드로어 개편 + 상품 자동 수집(매일 06:15 KST GitHub Actions) — 7장
장바구니 · 결제단일 목록 + 우측 요약, 완료 화면 텍스트 위주주문 플로우 리디자인 — 3단계 진행 인디케이터(01 장바구니 → 02 주문·결제 → 03 주문완료), 상품별 개별 카드 + 필 스테퍼, 결제 금액 플로팅 카드, 주문자 인라인 편집 · 배송지 라디오 선택, 주문번호 복사 칩이 있는 완료 화면 — 8·9장
모바일기본 반응형 + 3분할 시트 메뉴모바일 정비 완료iOS 글라스 스타일 하단 탭바(홈 · 소식 · 음악 · 굿즈샵 · 자유게시판) 도입, 좌측 드로어 메뉴 리디자인(프로필 카드 · 퀵 타일 · 다크 모드 스위치 — GNB는 탭바로 이동), 마이페이지 모바일 IA 재배치(가로 필 탭), 브레이크포인트 정책 문서화와 페이지별 반응형 QA — 2-2 · 14장
유료 멤버십DIVE 멤버십 신규 — 3단 플랜(베이직 무료 / DIVE+ 월 1,900원 / DIVE VIP 월 5,900원), 토스페이먼츠 빌링키 정기결제(구독 · 플랜 변경(업그레이드 즉시 차액 결제 / 다운그레이드 예약) · 해지 · 해지 취소 · 카드 변경 + 매일 자동결제 크론), 티어 뱃지 · 아바타 퍼플 링 — 10-6절
마이페이지좌측 프로필 + 메뉴 리스트, 인라인 닉네임 편집리디자인 완료 — 프로필 밴드(아바타 · 멤버십 뱃지 · 스탯 3종) + 240px 사이드 내비(카운트 · 푸시 카드 · 계정 링크), 카드형 결제 내역 · 주문 상세, 프로필 수정 모달(전용 크롭 모달 — 원형 마스크 · 드래그/줌), 배송지 카드 + 공용 수정/삭제 버튼 — 10장
소식Supabase 수동 입력 기사(news_gallery) + 사진 갤러리자동 수집 피드(네이버 API Hub 뉴스 · 구글 뉴스 RSS · 유튜브 공식 채널 RSS) + 일정 허브(수동 큐레이션 · KOPIS 공연 자동 수집 · 뉴스 일정 자동 추출 크론) — 갤러리·히어로 제거, 4장
앨범 · 메인앨범 정보 + 음원 플랫폼 링크 5종iTunes 30초 미리듣기 + 하단 미니 플레이어 바 + 풀버전 칩(멜론 · Apple Music · Spotify · YouTube Music) + 메인 일정·소식 티저 섹션 — MAIN-03 · 08 · 09

2. 공통 (헤더 · 푸터 · 전역 UI)

모든 화면에 공통 적용되는 레이아웃과 전역 동작.

2-1. 헤더 (데스크톱)

ID기능명상세 설명처리 기준 · 예외권한
COM-01로고 / 홈 이동좌측 로고 클릭 시 메인(/)으로 이동.2026-08 리디자인: 테마·스크롤 상태와 무관하게 브랜드 핑크(#f465a5) 로고로 통일. 2026-08-17 마크를 2026 공식 리브랜딩(REVIVE+) 세로형 로고(V 안 별 커팅)로 교체 — 헤더 30px · 푸터 36px · 드로어 34px 폭.전체
COM-02스크롤 반응 헤더메인 페이지에서는 투명 배경으로 고정(fixed)되며, 앨범 섹션에 도달하면 흰 배경 + 그림자 스타일로 전환.스크롤 감지는 100ms 스로틀. 메인 외 페이지는 항상 흰 배경(relative).전체
COM-03GNB 메뉴소식(/news) · 음악(/discography) · 굿즈샵(/shop) · 자유게시판(/board) 4개 메뉴. 데스크톱(lg 이상)에서만 노출.현재 경로가 해당 메뉴로 시작하면(하위 경로 포함) 굵은 글씨로 활성 표시. 우측 로그인은 보라 pill 버튼(비로그인 시).전체
COM-04장바구니 아이콘 · 뱃지장바구니(/cart) 이동 아이콘. 담긴 상품 종류 수를 브랜드 오렌지 원형 뱃지로 표시. 장바구니 페이지에서는 아이콘이 보라로 활성 표시.수량 합계가 아닌 고유 품목 수. 0개면 뱃지 숨김. 하이드레이션 전에는 미표시. (2026-08 리디자인에서 빨강 → 오렌지)전체
COM-05유저 메뉴 분기비로그인: “로그인” 링크 → 로그인 페이지로 이동(현재 경로를 ?redirect로 첨부, AUTH-07). 로그인: 아바타(멤버십 링 적용, MY-22) → 드롭다운(닉네임 + 티어 뱃지, 이메일 앞 소셜 로그인 아이콘(구글/카카오 — 일반 이메일 가입은 미표시), 마이페이지 · 내가 쓴 글 · 찜 목록, 로그아웃). 모바일 드로어 프로필 카드에도 동일하게 표시.세션 상태에 따라 실시간 전환. v1의 로그인 모달은 제거됨.전체

2-2. 헤더 (모바일) — 하단 탭바 · 드로어 메뉴 2026-08 리디자인

ID기능명상세 설명처리 기준 · 예외권한
COM-06드로어 열기 · 닫기햄버거 버튼 → 좌측 드로어(너비 320px · 최대 화면 85%) 오픈. 로고/메뉴 항목 이동, 우상단 ✕, 딤 영역 클릭으로 닫힘.lg 미만 화면 전용. 구 3분할 퀵 메뉴 · 보더 리스트 UI는 대체됨(.pen “모바일 메뉴 · 라이트/다크/비로그인” · “모바일 메뉴 · 하단 네비 적용 · 라이트/다크”).전체
COM-07프로필 카드 / 로그인 카드로그인 시 연보라 카드에 아바타(구독자는 퍼플 링) · 닉네임 + 멤버십 뱃지 · 이메일을 표시하고, 카드를 누르면 마이페이지로 이동. 비로그인 시 “로그인하고 다이브를 시작해보세요” 카드 — [로그인] 필 버튼 + “아직 계정이 없나요? 회원가입” 링크.로그인 버튼은 현재 경로를 ?redirect로 첨부(AUTH-07). 이동 시 드로어 자동 닫힘.전체
COM-08퀵 타일2열 타일 — ① 장바구니(담긴 품목 수를 보라 원형 뱃지로 표시) ② 멤버십(NEW 라벨, 멤버십 페이지로 이동).장바구니 뱃지는 0개면 숨김(COM-04와 동일 기준).전체
COM-09드로어 하단 유틸하단 고정 영역에 다크 모드 스위치로그아웃(로그인 시).다크 모드 동작은 COM-16과 동일. 2026-08-31까지 있던 “메뉴” GNB 리스트는 하단 탭바(COM-22)로 옮겨져 드로어에서 제거됐다 — 드로어는 프로필 · 퀵 타일 · 유틸만 담는다.전체
COM-22하단 탭바 (모바일 · iOS 글라스)lg 미만에서 화면 하단에 떠 있는 플로팅 캡슐 탭바 — 좌우 16px 인셋 · 높이 64px · rounded-full, 반투명 글라스(bg-glass white 72% / 다크 #1E1E21 78%) + 배경 블러 24px + 1px 하이라이트 보더(border-glass-stroke) + shadow-lg. 홈 · 소식 · 음악 · 굿즈샵 · 자유게시판 5탭 균등 분할(lucide 아이콘 24px + 11px 라벨). 현재 경로 탭은 뒤에 보라 틴트 필(bg-glass-accent, 탭마다 같은 크기)을 깔고 아이콘 · 라벨을 보라(purple-500, 다크 purple-300) + semibold로 표시, aria-current="page".홈은 정확히 /일 때만, 나머지는 하위 경로 포함(startsWith) 활성 — 루트 /index 정규화(useRoutePath) 적용. 캡슐 아래 8px + iOS safe-area(env(safe-area-inset-bottom))를 두고, 캡슐 바깥 여백은 pointer-events를 끊어 밑 콘텐츠를 그대로 누를 수 있다. 본문 하단 여백과 플로팅 요소 정렬은 MOB-09. 앱(WebView)에서도 그대로 노출돼 앱 내비 역할을 한다(앱 셸에 네이티브 탭은 없음). 앱에서는 탭 전환을 replace로 해 히스토리에 쌓지 않고, Android 뒤로가기는 현재 경로 기준 — 홈은 2초 내 두 번 눌러 종료, 탭 루트(소식 · 음악 · 굿즈샵 · 자유게시판)는 홈으로, 그 외 상세는 웹 히스토리(ive-app docs/decisions.md §9, 앱 v1.0.6). 시안 .pen “BottomNav” 컴포넌트(변수 glass-bg · glass-stroke · nav-active · nav-active-bg) · “모바일 · 메인/소식/게시판 · 하단 네비” · “모바일 메뉴 · 하단 네비 적용”.전체

2-3. 푸터 · 404 · 전역 UI

ID기능명상세 설명처리 기준 · 예외권한
COM-10푸터핑크 로고 + 포트폴리오 고지 3줄(비공식 팬 사이트·포트폴리오 목적 / 원저작권 스타쉽 / © 2026 seokachu) + GitHub·포트폴리오 사이트(seokachu.site) 원형 아이콘 버튼(새 창).로그인 상태와 무관하게 항상 동일한 정적 콘텐츠.전체
COM-11404 페이지 2026-08 리디자인존재하지 않는 경로 접근 시 그라데이션 “404” 넘버럴 + “페이지를 찾을 수 없어요” + “요청하신 주소가 변경되었거나 삭제되었어요.”, 접근했던 경로를 취소선 칩으로 표시, [메인으로 가기 · 이전 페이지로] 2단 CTA, 하단 구분선 “이런 페이지는 어때요?” + 퀵링크 필 4종(음악 · 소식 · 게시판 · 굿즈샵).자동 리다이렉트 없음. 헤더/푸터는 함께 표시. 구 안내 이미지 화면은 대체됨(.pen “404 · 라이트/다크”).전체
COM-12최상단 이동 버튼페이지 우하단 고정 버튼. 클릭 시 최상단으로 부드럽게 스크롤.스크롤 200px 이상일 때만 노출. 메인·소식·게시판 상세·마이페이지 등에 배치.전체
COM-13토스트 알림동작 결과를 화면 토스트로 안내. 2026-08 리디자인에서 4종 톤(성공 · 안내 · 경고 · 실패)으로 정리되어 아이콘 + 색으로 구분된다.동시 1개만 표시(신규 발생 시 교체). 실패는 붉은(destructive) 톤.전체
COM-14확인 모달되돌릴 수 없는 동작 전 공통 확인 다이얼로그. 2가지 톤 — ① destructive(게시글·댓글·배송지 삭제, 장바구니 비우기, 멤버십 해지): 빨간 휴지통 서클 + 빨간 확인 버튼 ② primary(구매확정 · 로그아웃 등 기본): 보라 체크 서클 + 보라 솔리드 확인 버튼. 버튼은 [취소 · 실행] 2개 필 버튼.바깥 영역 클릭으로도 닫힘(취소 처리). 호출부에서 제목·설명·버튼 문구를 지정한다.전체
COM-15로딩 표준화로딩 인디케이터는 공용 Spinner로 통일되어 스크린리더에 “로딩 중”으로 읽힘. 마이페이지는 스피너 대신 스켈레톤을 쓴다 — 실제 콘텐츠 골격을 흉내 낸 회색 블록으로 list(썸네일 + 3줄 텍스트 + 우측 버튼, 행 3개)와 grid(정사각 카드 + 2줄 텍스트, 6칸) 두 변형이 있다.화면 타이틀이 이미 있으면 타이틀은 실제 텍스트로 두고 그 아래만 스켈레톤으로 채워, 로딩이 끝나도 레이아웃이 흔들리지 않는다.전체
COM-16다크모드헤더의 달/해 토글 버튼으로 라이트 ↔ 다크 전환(데스크톱·모바일 공통 노출). 선택한 테마는 기기에 저장되어 재방문 시 유지. 전환 시 0.3초 색상 페이드 적용.기본 라이트, 시스템 테마와 미연동(옵트인 방식). 하이브리드 앱에서는 현재 테마가 네이티브 셸로 전달됨(PUSH-10).전체
COM-17정렬 셀렉트 (공통)목록 화면의 정렬 선택을 공통 컴포넌트로 통일 — 라운드 필 트리거(현재 정렬명 + ▾)를 누르면 드롭다운이 열리고, 선택된 항목은 라벨 앞 체크 + 보라 굵은 글씨로 표시된다. 자유게시판(최신순·인기순·댓글순) · 굿즈샵(인기순·최신순·가격 낮은/높은 순) · 음악(최신순·오래된순)에 적용.폼 입력용 셀렉트(배송 요청사항 등)는 별도 컴포넌트를 계속 사용한다.전체
COM-18공유 시트게시글 상세 · 상품 상세의 공유 버튼을 누르면 공유 시트가 열린다: 카카오톡(카카오 SDK 스크랩 공유) · 링크 복사 · 더보기(기기 네이티브 공유) 원형 버튼 3종 + 현재 URL 표시 바(우측 “복사” 필).“더보기”는 네이티브 공유를 지원하는 기기에서만 노출. 링크 복사 성공 시 “링크가 복사되었습니다”, 실패 시 “링크 복사에 실패했습니다”. 카카오 키 미설정 시 “카카오톡 공유를 사용할 수 없습니다” 경고 토스트.전체
COM-19수정 · 삭제 액션 (공통)본인 리소스에 노출되는 [수정 · 삭제] 필 버튼 쌍을 공통화 — 수정은 중립 아웃라인(연필), 삭제는 붉은 틴트(휴지통)이며 삭제 클릭 시 destructive 확인 모달(COM-14)로 연결된다. 댓글·대댓글(작은 사이즈), 마이페이지 배송지 카드(기본 사이즈)에 사용.확인 모달의 제목·설명은 호출부에서 지정(기본값 “삭제할까요? / 삭제한 내용은 되돌릴 수 없어요.”).작성자
COM-20빈 상태 (공통 패턴)목록이 비었을 때 파스텔 원형 아이콘 + 제목 + 설명 + (선택) CTA 버튼 형태로 통일해 안내. 게시판(글 없음·검색 결과 없음·공지 탭·비로그인), 굿즈샵 리뷰, 장바구니, 마이페이지 4개 목록에 각각 다른 문구로 적용.안내·행동 유도는 보라 톤, 검색 결과 없음 같은 중립 상황은 회색 톤.전체
COM-21파비콘 · 브랜드 아이콘REVIVE+ 마크를 담은 스쿼클 파비콘(src/app/icon.svg)이 브라우저 테마에 따라 자동 전환 — 라이트: 핑크→보라 그라데이션 + 화이트 마크, 다크: 다크 배경 + 핑크 마크. 구형 브라우저는 favicon.ico(16/32/48 멀티 사이즈) 폴백.기능명세서 문서(/docs)와 스토리북(manager-head)도 동일 파비콘 사용. 카카오·구글 OAuth 동의 화면 앱 로고도 같은 아이콘으로 등록.전체

3. 메인 페이지 · 음악(디스코그래피)

서비스 첫 화면. 24시간 주기 ISR로 재생성되며 앨범 데이터는 서버에서 미리 조회(prefetch)된다.

3-1. 메인 /

ID기능명상세 설명처리 기준 · 예외권한
MAIN-01비주얼 히어로 (영상)유튜브 공식 채널의 최신 영상(쇼츠 제외)을 전체 화면 배경으로 무음 자동 재생·루프. “OFFICIAL · 최신 영상 자동 재생” 뱃지, 카피·CTA 2종(최신 소식/음악 듣기), 하단 다크 페이드 + 스크롤 인디케이터. 사운드 토글은 없다 — 배경 장식 영상이라 소리를 켤 수단을 두지 않는다.피드 30분 갱신으로 새 영상 자동 교체. 임베드 iframe서버에서 렌더(www.youtube.com/embed + enablejsapi · origin)해 HTML 파싱 시점부터 로드가 시작되고, 유튜브 IFrame Player API는 하이드레이션 뒤 그 iframe에 붙어 재생 상태만 감시한다(API 스크립트는 preload) — 예전엔 하이드레이션 → API 로드 → 플레이어 생성 뒤에야 로드가 시작돼 첫 방문 재생이 늦었다. origin은 Vercel 시스템 env(VERCEL_PROJECT_PRODUCTION_URL)로 잡고 브라우저 origin과 다르면(로컬 · 프리뷰) 클라이언트가 바로잡는다. www.youtube.com을 쓰는 이유는 쿠키 없는 youtube-nocookie 임베드가 반복 접속에서 봇 판정에 걸려 플레이어가 부팅되지 않던 문제 대응. 플레이어 오류(onError)이거나 12초 안에 재생 시작(PLAYING)에 이르지 못하면 iframe을 새로 만들어(key 교체) 최대 3회 재시도하고(버퍼링 중이면 10초씩 연장 — 느릴 뿐인 플레이어를 죽이지 않기 위해), 그래도 실패하면 밑레이어의 유튜브 썸네일 폴백이 그대로 노출된다. 영상 후보는 공식 채널 피드에서만 고르므로 그 피드가 비면 히어로가 정적 이미지로 떨어진다 — NEWS-04의 쓰로틀 대응이 이를 막는다. 앱(WebView)에서는 무음 자동재생을 허용해야 재생된다(PUSH-13).전체
MAIN-12트랙명 마퀴히어로와 앨범 섹션 사이 대표 트랙명 스트립(“IVE ✦ LOVE DIVE ✦ …”)이 우→좌로 무한 순환.28초 주기 CSS 애니메이션, 장식 요소(aria-hidden).전체
MAIN-02앨범 쇼케이스좌측 플랫 3커버 캐러셀(중앙 확대·양옆 축소 40% 투명) + 우측 활성 앨범 정보 패널(제목·발매 정보·수록곡 미리듣기·스트리밍 칩). 앨범 전환 시 우측 패널이 함께 갱신. 하단 ‹ n / 전체 › 페이저.발매일 내림차순. 전환 수단: 페이저·양옆 커버 클릭·드래그·키보드 ←→. 확대는 scale 변환이라 레이아웃 흔들림 없음. 오로라 글로우 배경.전체
MAIN-03수록곡 미리듣기 · 풀버전 링크iTunes Search API로 앨범 수록곡 목록(트랙 번호·곡명·재생시간)을 표시하고, 트랙 행 클릭 시 30초 미리듣기 재생(MAIN-08 플레이어 연동). 하단 “풀버전 듣기” 칩으로 멜론 · Apple Music · Spotify · YouTube Music 이동(새 창).“수록곡 미리듣기” 토글로 접기 가능(기본 펼침). 멜론·Apple은 DB 앨범 링크 우선, 없으면 검색 링크 폴백. Spotify·YouTube Music은 검색 링크. 미리듣기 없는 곡은 흐림 처리·클릭 불가. iTunes 결과 일주일 캐싱. iTunes 검색이 country=KR에서 통째로 0건을 돌려주는 장애가 있어(2026-09-07 확인) 앨범은 아티스트 룩업으로 먼저 찾고, 검색은 KR → US 순으로 처음 비어 있지 않은 결과를 쓴다(앨범 ID · 미리듣기 URL 은 스토어프론트 무관). 빈 결과는 5분만 CDN 캐시(결과 있으면 일주일)라 장애가 풀리면 곧 복구된다.전체
MAIN-04Hot Board (인기 게시글)인기순 6건 — 1위는 대형 피처드 카드(썸네일 배경·1위 뱃지·제목·작성자·좋아요·댓글), 2~6위는 랭킹 리스트(순위 번호·제목·작성자·통계·미니 썸네일). 클릭 시 게시글 상세 이동, 우측 상단 “전체 보기”.정렬: 좋아요 → 댓글 → 최신순. 썸네일 없는 글은 썸네일 영역 미노출(1위는 보라 그라디언트 폴백).전체
MAIN-05굿즈샵 프로모 배너 (삭제됨)2026-08 리디자인에서 제거 — Shop 섹션 “전체 보기”로 이동 경로 단일화.전체
MAIN-06상품 캐러셀 (SHOP)인기 상품 12개를 좌우 화살표 캐러셀로 표시(데스크톱 4카드 정렬). 카드: 이미지 위 배지 오버레이(무료배송 회색·HOT 오렌지·NEW 보라)와 찜 하트(우상단 흰 원형), 상품명·오렌지 할인율·가격·노란 별점 한 줄. 우측 상단 “전체 보기”.리뷰 수 기준 상위 12개. NEW 뱃지 부여 로직은 추후. 찜 동작은 SHOP-05와 동일.전체
MAIN-07로딩 · 오류 처리각 섹션은 로딩 중 스켈레톤 표시, 조회 실패 시 오류 안내(“Oops! 잠시 후 다시 확인해주세요...”)로 대체.재시도 버튼 없음. 상품 캐러셀은 오류 시 별도 안내 없이 미표시.전체
MAIN-08플로팅 플레이어 · 미니 디스크미리듣기 재생 시 화면 하단 중앙에 떠 있는 라운드 플레이어가 나타난다: 앨범아트·곡명(아이브 · 앨범명), 이전/재생·일시정지/다음, 드래그 시킹 진행바(현재/전체 시간), 볼륨 슬라이더·음소거, 닫기(✕). 루트 레이아웃에 전역 마운트되어 메인 · 음악 등 페이지를 이동해도 재생이 끊기지 않는다.페이지를 이동하면 콘텐츠를 가리지 않도록 우하단 미니 디스크(회전하는 커버)로 자동 축소되고, 디스크를 누르면 즉시 재생/일시정지 + 보조 버튼(펼치기 · 종료)이 4초간 노출된다(터치 기기 대응). 곡 종료 시 미리듣기 가능한 다음 곡 자동 재생, 마지막 곡이면 정지. 기본 볼륨 50%, 모바일은 볼륨 슬라이더 숨김. 닫으면 재생 중지·플레이어 제거.전체
MAIN-09일정 · 소식 티저앨범 섹션과 게시판 섹션 사이 “News” 섹션: 다가오는 일정 최대 3건(D-day 배지·카테고리·기간·제목·장소) + 최신 소식 카드 4건 + “소식 전체 보기” 버튼(화살표 좌우 왕복 애니메이션).일정 D-day 뱃지는 공통 컴포넌트(예정 보라·진행 초록·종료 회색). 종료 일정 제외, 최대 3건. 소식 카드는 소식 페이지와 동일 동작(영상 인라인 재생·기사 요약 오버레이). 로딩 중 스켈레톤.전체
MAIN-10앨범 자동 등록매일 06:30(KST) Vercel Cron이 iTunes 아티스트 룩업으로 새 발매반을 감지해 album 테이블에 자동 추가(제목·커버 600px·구분·발매일·곡 수·Apple 링크). 별도 승인 없이 즉시 캐러셀에 노출.4곡 이상 발매반(정규·미니)만 등록 — 1~2곡 싱글·리믹스 제외. 제목 정규화로 기존 행과 중복 방지. CRON_SECRET Bearer 인증. 곡 수 10 이상이면 “정규”, 미만이면 “미니”. 멜론 링크는 수동 보강.전체
MAIN-11타이틀곡 뱃지수록곡 목록에서 활동곡에 보라색 “타이틀” 뱃지 표시.판별 기준: 해당 곡이 아이브 싱글(1~2곡 컬렉션)로도 발매되었거나 곡명이 앨범명과 동일한 경우. 싱글 발매 없이 활동한 타이틀곡은 누락될 수 있음.전체

3-2. 음악(디스코그래피) /discography v2 신규 · GNB “음악” · 2026-08 리디자인

ID기능명상세 설명처리 기준 · 예외권한
DISC-01최신 발매 히어로페이지 최상단에 다크 배경 + 오로라 글로우 히어로: 대형 커버, NEW·구분 뱃지, 제목, 발매일 · 구분 · 곡 수, 대표 수록곡 3곡 미리듣기, “수록곡 전체 보기”(상세 시트 열기), 스트리밍 링크 칩.히어로는 싱글을 건너뛰고 가장 최근의 발매반(정규·미니)을 노출한다 — 리믹스·디지털 싱글이 더 최신이면 표기를 “최신 앨범”으로 바꾼다(전체 기준 최신이면 “최신 발매”).전체
DISC-02전체 발매 목록 · 연도 그룹아이브 전체 발매(정규·미니·싱글, 일본반 포함)를 커버 그리드(2~4열)로 표시: 커버·구분 뱃지·제목·발매일·곡 수. 목록은 발매 연도별로 그룹되어 “2026 ——— n장” 형태의 구분선이 붙는다.DB 미사용(iTunes 직접 조회, 하루 캐싱). 제목 정규화로 중복 제거. 곡 수 10↑ 정규 · 4↑ 미니 · 그 외 싱글로 분류. 모든 연도는 항상 펼쳐진 상태(접기 없음).전체
DISC-03필터 · 정렬“전체 · 정규 · 미니 · 싱글” 필터 필(각 항목에 개수 표기) + 정렬 셀렉트(최신순 · 오래된순, COM-17 공통 컴포넌트).필터를 바꾸면 열려 있던 상세 시트는 닫힌다. 정렬은 연도 그룹 순서와 그룹 내 순서에 함께 적용.전체
DISC-04커버 호버 미리듣기그리드 커버에 마우스를 올리면 재생 FAB이 나타나고, 클릭 시 상세를 열지 않고 해당 앨범의 타이틀곡(없으면 첫 미리듣기 가능한 곡)을 바로 재생한다.터치 기기에서는 FAB이 상시 노출된다. 수록곡은 클릭 시점에 조회되며 미리듣기 가능한 곡이 없으면 재생되지 않는다.전체
DISC-05앨범 상세 시트커버(또는 히어로의 “수록곡 전체 보기”) 클릭 시 우측에서 상세 시트가 열린다: 큰 커버, 구분 뱃지 + 제목, 발매일 · 곡 수, 스트리밍 링크 칩(멜론 · Apple Music · Spotify · YouTube Music), 수록곡 목록(타이틀 뱃지 포함). 트랙 클릭으로 30초 미리듣기.시트를 열거나 닫으면 재생 플레이어는 우하단 미니 디스크로 접힌다(MAIN-08) — 시트와 겹치지 않게 하기 위함. 배경 클릭 · ✕ · Esc로 닫힘. 앱에서는 시트가 열린 동안 Android 뒤로가기가 페이지를 옮기지 않고 시트만 닫는다(PUSH-14).전체

4. 소식 페이지

2026-08 전면 개편 — 수동 입력 기사·갤러리를 걷어내고 일정(Schedule) · 영상(Video) · 기사(News) 3개 섹션의 자동 수집 허브로 재구성. 피드·일정 모두 30분 주기 ISR. 구 사진 갤러리 · 상세 모달은 제거됐고, 2026-08 리디자인으로 블러 사진 히어로 · 캘린더 통합 일정 뷰 · 4열 영상 그리드 · 가로형 기사 로우가 적용됐다.

4-1. 일정 /news #schedule_section

ID기능명상세 설명처리 기준 · 예외권한
NEWS-08페이지 히어로상단에 아이브 사진을 흐리게 깔고 그라데이션 스크림을 덮은 히어로: “NEWS & SCHEDULE” 키커, “소식” 타이틀, 서브카피(“아이브의 일정과 영상, 기사를 한곳에 모아 보여드려요”), “자동 수집” 보라 칩 + “뉴스 · 영상 · 일정을 30분마다 자동으로 업데이트해요” 안내.배경 시안은 A(그라데이션)/B(블러 포토)/C/D 비교 후 B 확정. 다크에서는 스크림이 어두운 톤으로 전환.전체
NEWS-01일정 — 캘린더 통합 뷰좌측 캘린더(월 이동 · 일정 있는 날 점 표시 · 날짜 선택) + 우측 일정 리스트를 한 화면에 나란히 배치. 리스트는 ① 선택한 날짜의 일정(“8월 17일 (일) 일정”) ② 다가오는 일정 ③ 지난 일정 순으로 이어진다. 카드에는 D-day 배지(D-n · D-DAY · 진행중 · 종료), 카테고리 배지, 기간(요일 포함), 제목, 장소가 표시된다.v2 초기의 “다가오는 일정 ↔ 캘린더” 토글은 제거되고 통합 뷰로 대체됨. 지난 일정은 흐림 처리. 선택 날짜 기본값은 오늘.전체
NEWS-09일정 카테고리 필터일정 섹션 상단 필 필터로 카테고리(콘서트 · 컴백 · 방송 · 팬미팅 · 팝업 · 발매 · 기타)를 좁혀 볼 수 있다. 필터는 캘린더와 리스트에 동시에 적용된다.수집된 데이터에 실제로 존재하는 카테고리만 필로 노출된다(빈 필터 없음). 기본값 “전체”.전체
NEWS-02일정 인라인 상세카드 클릭 시 그 자리에서 아래로 펼쳐짐(모달·페이지 이동 없음): 대표 사진, 설명, 기간(연도 포함)·장소, “이 일정 관련 소식”(제목 키워드로 피드에서 자동 매칭, 최대 4건), 원문/예매 외부 링크.대표 사진은 KOPIS 포스터 → 네이버 이미지 검색 → 관련 영상 썸네일 순 폴백. 자동 수집 일정은 “자동 수집” 배지 표시. 정보가 없으면 “아직 등록된 상세 정보가 없어요.”전체
NEWS-03일정 데이터 수집3개 소스 병합: ① Supabase schedules 수동 큐레이션 ② KOPIS 공연 자동 수집 ③ 뉴스 일정 자동 추출(매일 06시 KST Vercel Cron이 일정 키워드+명시적 날짜가 있는 기사에서 초안 생성 후 저장).KOPIS는 31일 단위로 향후 90일 조회, 공연명에 “아이브”/단어 IVE 포함 공연만 매칭(상세 API로 출연·관람연령·티켓 설명 구성). 동일 제목은 수동 입력 우선. 크론은 CRON_SECRET Bearer 인증, 카테고리+시작일 기준 중복 제거.전체

4-2. 영상 · 기사 /news #video_section · #article_section

ID기능명상세 설명처리 기준 · 예외권한
NEWS-04피드 자동 수집네이버 API Hub 뉴스 검색 + 구글 뉴스 RSS + 유튜브 RSS(공식 채널 · 공식 재생목록 4종 “IVE STAGE/LOG/minute/WEEK” · 1theK · Mnet K-POP)를 서버에서 병합 수집. 발행일 내림차순 정렬.30분 캐싱(/api/news/feed). 제목 정규화로 소스 간 중복 제거(썸네일 있는 항목 우선). 총량 컷을 쓰면 영상이 기사에 밀리므로 영상 30건 · 기사 50건 별도 상한. 1theK·Mnet 등 종합 채널은 제목에 아이브/IVE가 포함된 영상만 통과. 특정 소스 실패 시 나머지 소스로 응답, 전부 실패 시 오류 안내. 유튜브 RSS는 같은 IP의 동시 요청을 404/500으로 흘려버리므로(단독 요청은 200인 주소가 7건 동시에는 500) 공식 채널 피드는 단독으로 먼저 받고 실패 시 백오프(1초 · 2.5초) 2회 재시도, 보조 재생목록·채널은 그 뒤 동시 요청 후 1회 재시도. 요청에 브라우저 UA를 붙이고, 실패는 서버 로그에 남겨 조용히 비지 않게 한다(실측: UA 없음 4/8 → UA 6/8 → UA+재시도 8/8).전체
NEWS-05기사 대표 이미지 자동 매칭썸네일이 없는 기사(네이버·구글 출처)는 기사 제목으로 네이버 이미지 검색을 수행해 대표 이미지를 자동으로 채움.검색 결과 썸네일을 400px로 업그레이드해 사용, 하루 캐싱. 결과가 없거나 이미지 로드에 실패하면 브랜드 폴백 카드(딥 퍼플 그라데이션 + 로고 워터마크, 자유게시판 HOT 카드와 동일 시안)로 대체된다.전체
NEWS-06Video 섹션수집된 유튜브 영상을 4열 카드 그리드로 표시(출처·날짜·제목). 카드 클릭 시 페이지 이탈 없이 카드가 임베드 플레이어로 전환되어 자동 재생, ✕로 썸네일 복귀.youtube-nocookie 임베드. 전체화면 해제(ESC) 시 이전 스크롤 위치 복원. 기본 8건, “더 많은 영상 보기”로 8건씩 추가.전체
NEWS-07News(기사) 섹션네이버·구글 수집 기사를 가로형 로우 카드(썸네일 + 출처·날짜 + 제목)로 최대 3열 폭의 리스트에 표시한다. 클릭 시 원문을 새 탭으로 연다.기본 6건, “더 많은 기사 보기”로 6건씩 추가. 썸네일이 없으면 자동 매칭된 대표 이미지(NEWS-05) 사용.전체

5. 인증 (로그인 · 회원가입)

이메일/비밀번호 및 소셜 로그인(카카오·구글)을 지원. v2에서 로그인 모달이 제거되어 /login 페이지로 진입점이 단일화됐고, 로그인 후 원래 보던 페이지로 복귀한다.

5-1. 로그인 페이지 /login

ID기능명상세 설명처리 기준 · 예외권한
AUTH-01로그인 화면 구성로고 → “로그인” 제목 + 서브카피(“다시 만나서 반가워요! 아이브의 모든 소식을 만나보세요”) → 소셜 로그인 버튼 2종 → 구분선(“또는”) → 이메일 로그인 폼(라벨형 필드) → 하단 “아직 계정이 없나요? 회원가입” 링크.로그인 상태로 접근 시 서버에서 메인으로 리다이렉트.전체
AUTH-02가입 축하 화면/login?form=signup 진입 시 “회원이 되신 것을 축하드립니다!” 화면으로 전환. 최초 1회 폭죽(컨페티) 효과 + “회원가입이 완료되었습니다!” 토스트 후 이메일 로그인 폼 제공.가입 직후 발급되는 5분짜리 쿠키가 없으면 일반 로그인으로 리다이렉트(직접 접근 차단). 축하 효과는 1회만 재생. 이 화면에는 소셜 버튼·회원가입 링크 없음.전체
AUTH-03이메일 로그인이메일 + 비밀번호 입력 후 로그인. 각 필드에 라벨 제공, 입력 즉시 실시간 검증(onChange), 유효한 값 입력 전까지 로그인 버튼 비활성.
  • 이메일: 이메일 형식 — “올바른 이메일을 입력해 주세요.”
  • 비밀번호: 영문+숫자+특수문자 포함 8자 이상 (최대 20자 입력 제한) — “비밀번호는 영문, 숫자, 특수문자를 포함하여 8자 이상이어야 합니다.”
비밀번호 표시/숨김 토글은 버튼으로 제공되어 키보드·스크린리더로도 조작 가능. 제출 중에는 “처리 중...” 표시.전체
AUTH-04로그인 성공 처리① 비로그인 상태에서 담아둔 로컬 찜 목록을 계정으로 자동 이관 ② “로그인 되었습니다.” 토스트 ③ 원래 보던 페이지로 복귀 — 헤더에서 진입한 경우 현재 경로가 ?redirect로 전달되어 로그인 후 그 위치로 돌아간다.복귀 경로는 내부 경로(/로 시작)만 허용, 없으면 메인으로 이동.전체
AUTH-05로그인 실패 처리계정 정보 불일치 시 이메일·비밀번호 두 필드에 “이메일 또는 비밀번호가 일치하지 않습니다.” 에러 표시.그 외 오류(네트워크 등)는 별도 안내 없음.전체
AUTH-06소셜 로그인카카오로 시작하기”(카카오 옐로 전체 너비) · “구글로 시작하기”(아웃라인 전체 너비) 버튼으로 OAuth 로그인. 완료 후 저장된 복귀 경로(또는 메인)로 이동하며 “로그인 되었습니다.” 토스트 표시. 로컬 찜 목록도 자동 이관.깃허브 로그인은 v2에서 제거됨. 실패 시 오류 메시지 토스트.전체
AUTH-07로그인 진입점데스크톱 헤더 · 모바일 시트의 “로그인”, 회원가입 페이지 하단 “로그인” — 모두 /login 페이지로 이동(모달 없음). 메인·인증 화면 외에서 진입하면 현재 경로가 ?redirect로 첨부된다. 회원가입 유도는 로그인 화면 하단 링크가 담당.v1의 2단계 로그인 모달(소셜 선택 → 이메일)은 제거됨.전체

5-2. 회원가입 /signup

ID기능명상세 설명처리 기준 · 예외권한
AUTH-08이메일 회원가입 폼로고 → “회원가입” 제목 + 서브카피(“가입하고 아이브 팬 커뮤니티를 시작해 보세요”) → 이메일 · 비밀번호 · 비밀번호 확인 3개 필드(라벨형). 실시간 검증, 입력값이 모두 유효하고 필수 약관에 동의해야(AUTH-09) “가입하기” 활성.
  • 이메일 형식 — “올바른 이메일을 입력해 주세요.”
  • 비밀번호: 영문+숫자+특수문자 8자 이상 — 필드 바로 아래 안내문 “비밀번호 영문, 숫자, 특수문자 포함 8-20자” 상시 노출
  • 확인 미입력 — “비밀번호를 한번 더 입력해주세요.” / 불일치 — “비밀번호가 일치하지 않습니다.”
하단 “이미 계정이 있나요? 로그인” 링크(/login).
비밀번호·확인 각각 표시/숨김 토글. 로그인 상태로 접근 시 메인으로 리다이렉트.전체
AUTH-09가입 약관 동의폼 하단 약관 동의 영역: “약관에 모두 동의합니다” 전체 동의 체크박스 + 필수 2건(“이용약관 동의 (필수)” · “개인정보 수집·이용 동의 (필수)”) 개별 체크. 각 항목의 화살표 버튼으로 약관 전문을 모달로 열람(“확인”으로 닫기).필수 2건 모두 동의해야 “가입하기” 활성. 전체 동의 체크 시 일괄 선택, 개별 2건 모두 선택 시 전체 동의 자동 체크.전체
AUTH-10랜덤 닉네임 자동 부여가입 시 한국어 랜덤 닉네임을 외부 API로 발급받아 초기 닉네임으로 자동 설정.닉네임은 마이페이지에서 변경 가능(MY-03).전체
AUTH-11가입 성공 처리가입 완료 후 자동 로그인되지 않고, 가입 축하 화면(/login?form=signup, AUTH-02)으로 이동해 직접 로그인하도록 유도.축하 화면 접근용 쿠키(5분 유효) 발급.전체
AUTH-12가입 실패 처리실패 시 “회원가입에 실패했습니다. — 이미 등록된 이메일 입니다.” 토스트 표시.실패 원인과 무관하게 동일 문구 사용(중복 이메일 외 원인 포함).전체

5-3. 세션 · 로그아웃

ID기능명상세 설명처리 기준 · 예외권한
AUTH-13세션 유지 · 복원새로고침 시에도 Supabase 쿠키 세션에서 로그인 상태 자동 복원. 서버(proxy)에서도 쿠키 기반으로 사용자를 검증한다(@supabase/ssr). 세션 변화는 전역 구독으로 헤더 등 UI에 즉시 반영.
AUTH-14로그아웃헤더 드롭다운/모바일 시트의 “로그아웃” 클릭 시 세션 종료 후 “로그아웃 되었습니다.” 토스트.로그아웃 시 로컬 장바구니·찜 목록 삭제 및 화면 상태 초기화. 실패 시 “로그아웃 실패, 다시 시도해 주세요.”

6. 자유게시판

회원 커뮤니티 게시판. 조회는 누구나 가능하며 작성·좋아요·댓글은 로그인이 필요하다. v2에서 댓글·답글·좋아요에 푸시 알림 발송이 연동됐고, 2026-08 리디자인으로 “라운지”형 화면(사진 히어로 · HOT 3 · 필터/정렬 툴바 · 카드형 로우 · 800px 리딩 칼럼 상세)으로 전면 개편됐다.

6-1. 게시글 목록 /board

ID기능명상세 설명처리 기준 · 예외권한
BRD-01히어로 · 커뮤니티 통계상단에 아이브 무대 사진을 흐리게 깔고 스크림을 덮은 히어로: “DIVE COMMUNITY” 보라 칩, “자유게시판” 타이틀, 서브카피(“다이브들의 이야기가 모이는 라운지 — 오늘의 수다에 함께 DIVE 🌊”), 우측에 전체 글 · 오늘 새 글 · 누적 댓글 3개 통계.통계는 서버 집계값이며 로딩 중에는 “–”로 표시. 실시간 접속자 표시는 프레즌스 인프라가 필요해 시안 단계에서 제외됨.전체
BRD-02지금 뜨는 글 (HOT 3)히어로 아래 “지금 뜨는 글 — 반응이 가장 뜨거웠던 이야기예요” 섹션에 인기 상위 3건을 사진 배경 카드로 표시: 큰 흰색 순위 숫자, 1위 오렌지 “HOT” 배지, 제목, 작성자 아바타·닉네임, 좋아요·댓글·조회 수. 우측 상단 “인기글 전체 보기”는 인기 필터가 적용된 목록으로 이동.정렬은 인기순(좋아요 → 댓글 → 최신). 썸네일이 없는 글은 딥 퍼플 그라데이션 + 기울어진 로고 워터마크 기본 이미지로 폴백(랭크 숫자 가독을 위해 상단 스크림 유지). 데이터가 없으면 섹션 자체를 숨김.전체
BRD-03필터 필툴바 좌측 필 그룹으로 전체 · 인기 · 공지 · 내가 쓴 글 전환. 선택 상태는 URL 파라미터(?filter=)로 유지되어 HOT 3의 “인기글 전체 보기” 링크와도 자연스럽게 연결된다.“인기”를 고르면 정렬이 인기순으로 강제되고, 인기 필터 상태에서 정렬을 바꾸면 전체 필터로 복귀. “내가 쓴 글”은 비로그인 시 “로그인이 필요합니다.” 토스트 후 차단. 필터 전환 시 스크롤은 유지된다.전체
BRD-04정렬최신순(기본) · 인기순 · 댓글순 3종 정렬 셀렉트(COM-17). 선택값은 URL 파라미터(?sort=)로 유지.정렬 변경 시 1페이지로 리셋.전체
BRD-05제목 검색라운드 검색창에 입력하면 0.5초 디바운스 후 제목 부분일치로 검색. 결과 목록에서 일치 구간을 보라 배경으로 하이라이트.검색 대상은 제목만(본문·작성자 제외). 검색 시 1페이지로 리셋. 검색 중에는 로딩 표시.전체
BRD-06공지 로우리스트 최상단에 보라 배경의 고정 공지 로우(“공지” 칩 + “자유게시판 이용 규칙 & 팬 에티켓 안내 (필독)”)를 표시. 클릭하면 아코디언으로 이용 규칙 본문이 펼쳐진다 — 번호 뱃지가 붙은 4항목(“서로 존중해요” · “스포일러는 제목에 [스포]를 붙여주세요” · “현금 거래(양도·판매) 글은 금지예요” · “광고·도배 글은 정리될 수 있어요”)과 맺음 문구(“즐거운 라운지를 함께 만들어 주셔서 감사해요. 오늘도 편하게 다이브하세요 🌊”). 우측 셰브론이 펼침 상태에 따라 180° 회전.전체 · 공지 필터에서만 노출되고 검색 중에는 숨김. 기본 접힘, aria-expanded로 펼침 상태를 노출. DB에 공지 개념이 없어 상수(BOARD_NOTICE) 기반 정적 문구이며, 공지 탭 자체에는 “등록된 공지는 여기까지예요” 빈 상태가 표시된다.전체
BRD-07게시글 로우 (카드형)한 줄 카드형 로우로 표시: 썸네일(56px, 있을 때만) · 제목 · 댓글 수 보라 칩 · 24시간 내 새 글 오렌지 도트 · 작성자 아바타(없으면 이니셜 서클)와 닉네임 · 상대시간(“10분 전”) · 조회수 · 우측 좋아요 필.좋아요 50개 이상이면 좋아요 필이 오렌지 강조로 바뀐다. v1의 번호 열·표 헤더는 제거됨. 댓글 칩을 누르면 상세의 댓글 영역으로 바로 이동.전체
BRD-08페이지네이션페이지당 10건. 이전/다음 및 페이지 번호(최대 3개 노출, 말줄임 처리)로 이동. 현재 페이지는 URL 쿼리(?page=N)에 유지.전체가 1페이지 이하이면 페이저 미노출. 페이지 이동 시 툴바 상단으로 스크롤 복귀.전체
BRD-09빈 상태 (4종)상황별로 다른 안내(COM-20): ① 글 없음 “아직 게시글이 없어요 / 첫 번째 글로 다이브를 시작해보세요!” + 글쓰기 CTA ② 검색 결과 없음 “검색 결과가 없어요 / 다른 키워드로 다시 검색해보세요” ③ 내가 쓴 글 비로그인 “로그인 후 내가 쓴 글을 볼 수 있어요” + 로그인 CTA ④ 공지 탭 “등록된 공지는 여기까지예요” + 전체 글 보기 CTA.작성자 필터(?author=)로 진입해 글이 없으면 “이 다이브가 남긴 글이 아직 없어요”. 어떤 상태에서도 리스트 영역 최소 높이를 확보해 푸터가 딸려 올라오지 않게 한다.전체
BRD-10글쓰기 진입툴바 우측 “글쓰기” 필 버튼으로 작성 화면 이동.비로그인 시 “로그인이 필요합니다.” 토스트 후 이동 차단.
BRD-11상세 진입 · 조회수로우 클릭 시 상세로 이동하며 이때 조회수 1 증가.같은 글은 기기당 24시간 내 재클릭해도 조회수 중복 증가 없음. 상세 URL 직접 접근으로는 조회수가 증가하지 않음.전체

6-2. 게시글 작성 · 수정 /board/write /board/edit/[id]

ID기능명상세 설명처리 기준 · 예외권한
BRD-12작성 화면 구성상세와 같은 800px 리딩 칼럼: “목록으로” 필 → “자유게시판” 배지 + 타이틀/서브 → 제목 입력(카운터 n/100) → 에디터 카드(툴바 / 본문 300px / 하단 이미지 힌트 · 글자 수) → 커뮤니티 가이드 카드 → [취소 · 등록하기] 액션 로우.제목·본문 모두 필수이며 유효할 때만 “등록하기” 활성. 미입력 시 “제목을 입력해 주세요.” / “내용을 입력해 주세요.” 본문 길이 상한 없음.
BRD-13리치 텍스트 에디터 (Tiptap)에디터를 react-quill → Tiptap v3로 교체하고 시안대로 커스텀 툴바를 구성: 굵게 · 기울임 · 밑줄 · 취소선 · 목록(글머리/번호) · 인용 · 링크 · 이미지.기존 react-quill로 작성된 과거 글은 상세에서 기존 서식 CSS로 계속 정상 렌더된다.
BRD-14본문 이미지 업로드에디터의 이미지 버튼으로 이미지 1장씩 선택 → 스토리지 업로드 후 커서 위치에 삽입.실패 시 “이미지 업로드 실패” 토스트. 파일 크기·개수 제한 없음(브라우저 이미지 형식 필터만 적용).
BRD-15썸네일 자동 지정본문의 첫 번째 이미지를 목록 썸네일 및 공유(OG) 이미지로 자동 사용.이미지가 없으면 목록에서 썸네일 영역이 표시되지 않는다.
BRD-16커뮤니티 가이드폼 하단에 보라 가이드 카드로 작성 규칙 3항목(서로 존중 · 스포일러 주의 · 광고/도배 금지)을 안내.정적 안내(동의 절차 없음).
BRD-17등록 · 수정 처리등록 성공 시 “게시글 등록이 완료되었습니다.” 후 목록으로, 수정 성공 시 “게시글 수정이 완료되었습니다.” 후 상세로 이동.수정 시 변경 사항이 없으면 저장 없이 “수정된 내용이 없습니다.” 안내 후 상세로 이동. 취소는 목록(수정은 상세)으로 복귀.작성자

6-3. 게시글 상세 /board/[id]

ID기능명상세 설명처리 기준 · 예외권한
BRD-18상세 조회 (리딩 칼럼)본문을 800px 리딩 칼럼으로 배치: 제목 → 작성자 아바타 + 상대시간 · 조회수 → 구분선 → 본문(서식·이미지 포함). 상단 좌측에 “목록으로” 필.본문 HTML은 DOMPurify로 소독(sanitize) 후 렌더링(XSS 방어). 본문 이미지는 칼럼 폭에 맞춰 축소된다.전체
BRD-19이전 · 다음 글 이동상단 우측 원형 ▲▼ 버튼과 본문 하단의 이전/다음 글 로우로 인접 글로 이동한다(작성일 기준, “이전”이 더 최신).인접 글이 없으면 버튼은 비활성 표시.전체
BRD-20추천 (좋아요)본문 아래 가운데 그라데이션 “추천 n” 버튼 + 안내 문구(“이 글이 마음에 들었다면 하트로 응원해 주세요”). 누르면 하트가 채워지고 카운트가 갱신되며 “좋아요를 눌렀습니다.” / “좋아요가 취소되었습니다.” 토스트.비로그인 시 로그인 안내 토스트 후 차단. 좋아요 추가 시 작성자에게 푸시 발송(PUSH-03).
BRD-21공유제목 우측 원형 공유 버튼 → 공유 시트(COM-18, 카카오톡 · 링크 복사 · 더보기).전체
BRD-22수정 · 삭제 (작성자)본인 글에만 원형 ⋯ 메뉴가 노출되고, 메뉴에서 [수정하기 · 삭제하기]를 고른다. 삭제는 destructive 확인 모달(“게시글을 삭제할까요? / 삭제한 글은 되돌릴 수 없고, 달린 댓글도 함께 사라져요.”) 통과 시 실행 후 목록 이동 + “게시글이 삭제 되었습니다.”타인 글에는 메뉴 자체가 미노출. 데이터 권한은 서버(RLS) 정책으로 보호. v1의 텍스트형 수정/삭제 버튼은 제거됨.작성자
BRD-23작성자 카드본문 아래 회색 카드로 작성자 아바타 · 닉네임 · “라운지에 남긴 글 n개” 표시 + “이 다이브의 다른 글” 링크 → 해당 작성자의 글만 필터링된 목록(/board?author=…)으로 이동.가입일 표기는 회원 테이블에 가입일이 없어 제공하지 않는다.전체

6-4. 댓글 · 대댓글

ID기능명상세 설명처리 기준 · 예외권한
BRD-24댓글 목록 · 정렬상세 하단에 “댓글 n개” 헤딩과 전체 댓글 표시. 우측 “등록순 ↔ 최신순” 토글로 정렬 전환. 대댓글은 보라 화살표 + 회색 카드로 들여쓰기 표시.서버 조회는 등록순 고정이며 최신순은 클라이언트에서 역순 처리. 페이지네이션 없이 전체 로드. 댓글 앵커(#comments) 진입 시 자동 스크롤.전체
BRD-25댓글 작성아바타 + 라운드 입력 카드 + “등록” 필 폼. 플레이스홀더는 “따뜻한 댓글로 함께 다이브해요 :)”. 성공 시 “댓글 작성에 성공했습니다.” 토스트.빈 내용 차단(“내용을 입력해 주세요.”). 비로그인 제출 시 로그인 안내 토스트. 작성 시 게시글 작성자에게 푸시 발송(PUSH-01). 등록·수정 실패 시 성공 토스트가 뜨던 문제를 바로잡았다mutateawait하던 것을 mutateAsync로 교체해 실패가 실패 토스트로 표시된다(BRD-27 동일).
BRD-26대댓글 작성댓글의 “답글 쓰기” 버튼으로 인라인 답글 폼 토글(열림 시 “닫기”). 등록 성공 시 폼 자동 닫힘.답글 깊이는 2단계까지(대댓글에는 답글 버튼 없음). 작성 시 게시글 작성자·원댓글 작성자에게 푸시 발송(PUSH-02).
BRD-27댓글 수정 · 삭제본인 댓글에만 [수정 · 삭제] 필 버튼 쌍(COM-19) 노출. 수정은 인라인 편집(동시에 1개만), 삭제는 destructive 확인 모달(“댓글을 삭제할까요? / 삭제한 댓글은 되돌릴 수 없어요.”) 후 “댓글이 삭제 되었습니다.”내용 변경 없이 저장 시 “수정된 내용이 없습니다.” 안내.작성자
BRD-28댓글 좋아요 · 작성자 뱃지댓글·대댓글에 하트 좋아요 토글(카운트 표시). 게시글 작성자가 남긴 댓글에는 닉네임 옆에 “작성자” 뱃지가 붙는다.비로그인 차단. 댓글 좋아요는 푸시 알림 미발송.

7. 굿즈샵

굿즈 상품 탐색·찜·구매 진입. 가격은 할인율 적용 후 10원 단위 내림으로 계산해 표시한다. 2026-08 리디자인으로 목록은 페이지 헤드 + 정렬 필로, 상세는 V2 레이아웃(갤러리 + 플로팅 구매 카드 + 세그먼트 탭 + 추천 섹션 + FAQ)으로 개편됐다.

7-1. 상품 목록 /shop

ID기능명상세 설명처리 기준 · 예외권한
SHOP-01페이지 헤드 · 전체 개수“OFFICIAL MD” 오렌지 키커 + “Goods Shop” 타이틀 + 서브카피(“아이브의 공식 굿즈를 한자리에서 만나보세요”)와 좌측 “전체 n개” 표기.개수는 서버 집계값.전체
SHOP-02목록 조회 · 무한 스크롤상품 카드를 12개 단위로 표시하고, 스크롤이 하단에 도달하면 다음 12개 자동 로드.마지막 페이지에서 “더 이상 표시할 상품이 없습니다.” 표시.전체
SHOP-03정렬인기순(기본) · 최신순 · 가격 낮은 순 · 가격 높은 순 4종 — 공통 정렬 셀렉트(COM-17)로 통일.인기순은 리뷰 수 기준, 가격 정렬은 할인 적용가 기준. 카테고리·검색 기능 없음.전체
SHOP-04상품 카드썸네일 위 배지 오버레이 · 우상단 찜 하트(흰 원형) · 상품명 · 오렌지 할인율 · 할인가 · 별점 한 줄. 클릭(또는 Enter/Space) 시 상세 이동.배지 규칙(표시 우선순위 NEW → HOT → 무료배송): 등록 30일 이내면 보라 “NEW”, 최근 90일 리뷰 5건 이상 & 평점 4.0 이상이면 오렌지 “HOT”, 무료배송 상품이면 회색 “무료배송”. HOT은 누적 리뷰가 아니라 최근 반응 기준이라, 오래 팔린 상품이 배지를 영구 점유하지 않고 신상품도 올라올 수 있다.전체
SHOP-05찜(위시리스트) 토글카드의 하트 버튼으로 찜 추가/해제. “찜하기가 추가되었습니다.” / “찜하기가 취소되었습니다.” 토스트.비로그인은 기기(로컬)에 저장되며, 로그인 시 계정으로 자동 이관. 로그인 사용자는 계정에 저장.전체

7-2. 상품 상세 /shop/[id] 2026-08 V2 리디자인

ID기능명상세 설명처리 기준 · 예외권한
SHOP-06브레드크럼상단에 “굿즈샵 › {상품명}” 경로 표시, “굿즈샵”은 목록으로 이동.전체
SHOP-07이미지 갤러리보라 단색 히어로 위에 갤러리를 배치: 큰 이미지 + 좌우 화살표 + 인덱스 필(n / m) + 하단 썸네일 스트립. 모바일은 스와이프로 넘긴다.썸네일과 상세 이미지를 합쳐 구성하며 같은 URL은 중복 제거. 히어로 배경에는 장식 스파클이 얹힌다.전체
SHOP-08구매 카드 (플로팅)갤러리 우측에 떠 있는 흰 카드: “OFFICIAL MD” 키커 + 공유 버튼(COM-18), 배지 필, 상품명, 별점·리뷰 수(누르면 리뷰 탭으로 이동), 원가·할인율·할인가, 배송/포장 아이콘 정보 2줄, 필 스테퍼(수량), 총 상품금액, [장바구니 담기 · 바로 구매] CTA.사이즈·색상은 정보 표시 전용(옵션 선택 기능 없음). 시안의 한정수량 게이지는 재고 데이터가 없어 구현 보류. 총 상품금액과 [바로 구매] 버튼의 금액은 수량을 바꾸면 숫자 롤링 애니메이션으로 굴러 바뀐다(CART-05와 같은 공용 컴포넌트).전체
SHOP-09수량 선택필 스테퍼의 +/− 로 수량 조절, “총 상품금액(할인가 × 수량)” 실시간 표시.최소 1개 ~ 최대 5개. 초과 시 “최대 5개 까지 구매 가능합니다.” 토스트.전체
SHOP-10장바구니 담기 · 드로어담으면 하단 드로어로 안내: 보라 체크 서클 + “장바구니에 담았어요!” + 보조 문구(당일배송 상품이면 “지금 주문하면 오늘 바로 출발해요”, 아니면 “담은 상품은 장바구니에서 확인할 수 있어요”), 담긴 상품 요약 카드(썸네일 · 상품명 · 수량 · 금액), [장바구니 보기](그라데이션) · [계속 쇼핑하기].이미 담긴 수량과 합산해 상품당 5개 초과 시 차단(현재 수량 안내). 비로그인도 가능(기기 저장).전체
SHOP-11바로 구매“구매하기” 클릭 시 장바구니를 거치지 않고 곧바로 토스페이먼츠 결제창 호출.검증: ① 로그인 ② 주문자 정보 · 기본 배송지 존재(누락된 항목을 묶어 하나의 토스트로 안내). 미충족 시 중단.
SHOP-12세그먼트 탭본문 상단에 [상세정보 · 리뷰 n] 세그먼트 필 탭(스티키). 활성 탭은 흰 필 + 그림자, 리뷰 개수는 보라 강조.탭 전환 시 콘텐츠 높이 변화로 스크롤이 아래 섹션에 떨어지지 않도록 탭 상단으로 스크롤 복귀.전체
SHOP-13리뷰 탭상단 요약 카드(큰 평균 별점 · 별 · “리뷰 n개” + 5~1점 분포 게이지) + 리뷰 목록(작성자 프로필 이미지(user.avatar_url · 없으면 이니셜 서클 폴백, 댓글과 동일 규칙) · 작성자 · 별점 · 날짜 · 내용) + 원형 페이지네이션(페이지당 5개).분포는 현재 페이지가 아닌 전체 리뷰 기준. 리뷰가 없으면 빈 상태(“아직 리뷰가 없어요 / 이 상품의 첫 번째 리뷰를 남겨보세요!” + “구매 후 마이페이지 > 주문/배송에서 작성할 수 있어요” 힌트). 리뷰 작성은 구매확정 후 마이페이지 주문 상세에서만 가능(MY-10).전체
SHOP-14추천 섹션탭 콘텐츠와 FAQ 사이에 보라 밴드로 “이런 굿즈는 어때요? — 지금 인기 있는 굿즈를 모았어요” 섹션을 배치(인기순 6개, 우측 “굿즈샵 더보기”).현재 보고 있는 상품은 제외. 추천할 상품이 없으면 섹션 숨김.전체
SHOP-15FAQ (구매 안내)페이지 하단 “궁금한 점이 있나요?” 스플릿 레이아웃 — 좌측 제목/안내, 우측 아코디언(판매자 고객센터 · 배송 정보 · 교환/반품 정책).정적 텍스트. 구 아코디언 컴포넌트는 대체·제거됨.전체

7-3. 상품 데이터 수집

ID기능명상세 설명처리 기준 · 예외권한
SHOP-16상품 자동 수집매일 06:15(KST) GitHub Actions가 공식 스토어에서 아이브 신상품을 감지해 goods 테이블에 등록하고, 이어서 상세 갤러리 이미지를 채운다(수집 → 이미지 보강 2단계).수동 실행(workflow_dispatch)도 가능하며 동시 실행은 1건으로 제한. 서비스 롤 키는 저장소 시크릿으로 주입.전체

8. 장바구니 · 주문서

별도 결제 페이지 없이 장바구니 화면이 곧 주문서(체크아웃) 역할을 한다. 좌측 상품 목록 + 우측 주문 요약(금액·주문자·배송지·약관·결제 버튼) 2단 구성. 장바구니 데이터는 기기(localStorage)에 저장되며 서버 동기화는 없다. 2026-08 리디자인으로 진행 단계 인디케이터 · 상품별 개별 카드 · 요약 3분할이 적용됐다.

8-1. 장바구니 /cart

ID기능명상세 설명처리 기준 · 예외권한
CART-10페이지 헤드 · 진행 단계“SHOPPING CART” 오렌지 키커 + “장바구니” 타이틀 + 서브카피(“담아둔 굿즈를 확인하고 바로 결제까지 진행해요”), 우측에 3단계 인디케이터(01 장바구니 → 02 주문·결제 → 03 주문완료). 현재 단계는 보라 원, 지난 단계는 체크 표시.같은 인디케이터를 주문완료 화면(9장)에서도 3단계 상태로 재사용.전체
CART-01담긴 상품 목록상품마다 개별 카드로 표시: 체크박스 · 썸네일 · 상품명 · 사이즈/색상 · 배송 정보 · 필 스테퍼(수량) · 할인율 · 원가(취소선) · 할인 적용 합계 · 삭제(×). 썸네일 클릭 시 상품 상세 이동. 목록 아래에는 보라 무료배송 스트립(“30,000원 이상 무료배송 · 지금 주문하면 오늘 바로 출발해요”).비어 있으면 원형 카트 아이콘 + “장바구니가 비어 있어요 / 마음에 드는 굿즈를 담아보세요!” + [굿즈샵 구경하러 가기] 버튼.전체
CART-02선택 관리 툴바목록 상단 툴바에 전체선택 체크박스와 “선택 n/전체 m” 카운트, 우측에 [선택삭제 · 전체 비우기] 버튼. 결제·금액 계산은 선택된 상품만 대상.진입 시 전체 자동 선택(장바구니 내용이 변경되면 전체 선택으로 재설정). 결제 실패 후 복귀 시 이전 선택 상태 복원.전체
CART-03수량 변경카드의 필 스테퍼 +/− 로 수량 조절, 합계 즉시 반영.1~5개 제한(초과 시 토스트).전체
CART-04삭제 (3종)① 개별 삭제(× 버튼) ② 선택삭제 — 중립 아웃라인 버튼, 확인 없이 즉시 삭제 후 “선택한 내용이 삭제 되었습니다.” ③ 전체 비우기 — 붉은 틴트 버튼 + destructive 확인 모달(“장바구니를 비울까요? / 담아둔 상품이 모두 삭제돼요. 이 작업은 되돌릴 수 없어요.” · [취소 · 비우기]).선택 0개로 선택삭제 시 “선택한 내용이 없습니다.” 오류 토스트.전체
CART-05결제 금액 요약 (플로팅 카드)우측에 스크롤을 따라오는 카드로 총 결제 금액(상단 강조) / 상품 금액 / 총 할인 금액(− 표시) / 멤버십 할인(DIVE+ 5% · VIP 10%, 구독자만) / 배송비를 표시하고, 약관 동의와 결제 버튼, 하단 안내(“본인은 만 14세 이상이며 주문 내용을 확인했어요”)까지 한 카드에 모은다. 주문자 정보 · 배송 정보는 그 아래 별도 카드로 분리.조건부 무료배송 — 기본 3,000원, 상품 금액(상품 할인까지 적용, 멤버십 할인 전) 30,000원 이상이면 무료. 담긴 상품이 모두 무료배송 상품이거나 VIP 멤버십이면 금액과 무관하게 무료다(우선순위: 전 품목 무료배송 → VIP → 기준 금액). 무료일 때는 이유별 문구(“전 품목 무료배송 상품이에요” / “VIP 멤버십 전 주문 무료배송이 적용됐어요” / “30,000원 이상 구매로 무료배송이에요”)를, 유료일 때는 “N원 더 담으면 무료배송이에요”를 함께 보여준다. 총 결제 금액은 토스식 숫자 롤링 애니메이션으로 표시된다 — 값이 바뀌면 자릿수 기둥이 세로로 굴러 새 숫자에 멈추고(0.7초 ease-out), 자릿수 키를 일의 자리 기준으로 부여해 총액 자릿수가 늘거나 줄어도 기존 기둥이 이어서 구른다. 굴러가는 숫자는 aria-hidden이고 전체 금액을 aria-label로 따로 읽힌다.전체
CART-06주문자 정보로그인 시 [정보 입력/정보 변경] 버튼으로 인라인 폼 오픈: 이름(최대 25자) · 휴대폰(하이픈 없이 숫자 11자리 입력, 저장 시 자동 포맷) · 이메일. 계정당 1건 저장(이후 자동 표시).비로그인 시 “주문자 정보가 없습니다. 로그인 후 정보를 입력해주세요.” 변경 없이 저장 시 “변경된 내용이 없습니다.”
CART-07배송 정보 · 배송지 선택기본 배송지(받는 분 · 휴대폰 · 우편번호+주소 · 요청사항)를 표시하고, [변경]을 누르면 저장된 배송지를 라디오 카드로 인라인 선택할 수 있다(선택된 카드는 보라 보더 + “기본 배송지” 뱃지). 목록 아래 [새 배송지 추가]는 마이페이지 배송지 등록으로 이동하며, “배송지 추가·수정은 마이페이지 배송지 관리에서 진행돼요” 안내가 붙는다.라디오 선택은 곧 기본 배송지 변경이며 성공 시 “기본 배송지가 변경되었습니다.” 토스트(실패 시 “배송지 변경에 실패했습니다.”). 목록은 기본 배송지 우선 정렬이라 선택한 배송지가 맨 위로 올라온다. 주문서에서 배송지 직접 입력은 불가.
CART-08주문 약관 동의요약 카드 안에 한 줄로 배치된 “[필수] 주문 내역에 대한 필수 동의” 부모 체크 + [약관 보기] 토글로 펼치는 자식 2개(개인정보 수집·제3자 제공 / 결제 이후 환불·취소 불가). 부모 체크 시 일괄 동의, 자식 모두 체크 시 부모 자동 체크. 각 항목 상세는 모달로 열람.검증 로직은 리디자인 전과 동일(필수 2건 동의 필요).
CART-09주문하기 (결제 요청)검증 통과 시 토스페이먼츠 결제창 호출. 주문명은 “{첫 상품명} 외 N건” 형식, 주문번호는 YYYYMMDD-랜덤8자리 자동 생성.검증 순서: ① 로그인(“로그인이 필요합니다.”) ② 결제 금액 0원(“결제할 내용이 없습니다.”) ③ 약관 동의(“약관 동의가 필요합니다”) ④ 주문자 정보(“주문자 정보가 없습니다.”) ⑤ 배송 정보(“배송 정보가 없습니다.”). 하나라도 미충족 시 토스트 후 중단.

9. 결제

PG는 토스페이먼츠 단일 연동(결제수단 “카드” 고정, 카드사 간편결제 포함). 결제 완료 후 성공 페이지에서 승인·주문 저장이 이루어진다. v2에서 결제 복귀 시 로그인 페이지로 튕기던 문제가 수정됐다.

9-1. 결제 승인 API POST /api/payment/confirm

ID기능명상세 설명처리 기준 · 예외권한
PAY-01결제 승인 프록시결제창에서 돌아온 paymentKey · orderId · amount를 받아 서버에서 토스페이먼츠 승인 API로 전달(시크릿 키는 서버 보관).세 값 중 누락 시 400 “결제 승인에 필요한 항목이 누락되었습니다.” 토스 승인 실패 시 해당 상태 코드·메시지 그대로 반환.전체

9-2. 결제 성공 /payment/success

ID기능명상세 설명처리 기준 · 예외권한
PAY-02접근 가드orderId 쿼리 없이 접근하면 서버에서 메인으로 리다이렉트. 비로그인 상태면 클라이언트에서 “로그인 후 이용 가능합니다.” 토스트 후 로그인 페이지로 이동.PG(토스) 복귀는 크로스사이트 리다이렉트라 세션 쿠키가 실리지 않으므로, 서버는 로그인 검사를 하지 않고 클라이언트 가드가 담당한다 — v1의 “결제 복귀 시 로그인 페이지로 튕김” 문제를 수정한 지점 (E2E로 검증).
PAY-03결제 승인 · 주문 저장페이지 진입 시 자동으로 ① 승인 API 호출 ② 승인 완료(DONE) 확인 ③ 결제 정보(payments) + 주문 상품(order_items) 저장. 상태는 “결제 완료 / 배송전”으로 기록되고 배송지 정보는 결제 시점 스냅샷으로 함께 저장.동일 주문번호가 이미 저장돼 있으면 승인·저장을 건너뜀(새로고침 중복 방지). 승인 결과가 DONE이 아니면 실패 페이지로 이동.
PAY-04장바구니 정리결제된 상품만 장바구니에서 자동 제거(미선택 상품은 유지).
PAY-05완료 화면 2026-08 리디자인상단에 3단계 인디케이터(03 주문완료 활성) → 그라데이션 체크 서클 → “주문이 완료되었어요!” + “주문하신 굿즈를 정성껏 포장해서 보내드릴게요”주문번호 복사 칩(누르면 클립보드 복사 + “주문번호를 복사했어요.”) → [주문상세 보기 → 마이페이지] · [쇼핑 계속하기 → 굿즈샵] 버튼 → 주문 상품 목록 → 배송 정보 / 결제 정보 / 결제 수단 카드 3분할.결제 조회 실패 시 1초 간격 3회 재시도 후 오류 표시. 결제 진행 중에는 스피너 + “창을 닫지 말아주세요” 안내 화면이 표시된다.

9-3. 결제 실패 /payment/fail

ID기능명상세 설명처리 기준 · 예외권한
PAY-06실패 안내“결제가 실패 되었습니다.” + PG가 전달한 실패 사유(“에러 사유 : …”) 표시.접근 가드는 성공 페이지와 동일.
PAY-07장바구니 복귀[장바구니로 돌아가기] 클릭 시 결제 시도했던 상품들이 선택된 상태로 장바구니 복원.복원 정보가 없으면 일반 장바구니로 이동.

10. 마이페이지

상단 프로필 밴드 + 좌측 사이드 내비(멤버십 · 찜 목록 · 결제 내역 · 내가 쓴 글 · 배송지 관리) + 우측 콘텐츠 구성. /mypage 진입 시 멤버십으로 자동 이동. 전 영역 로그인 필수(서버·클라이언트 이중 가드).

구현 상태 — 마이페이지 리디자인과 DIVE 멤버십(10-6절)은 기준 커밋(595e08c)에 반영 완료. 다만 멤버십은 Supabase에 memberships 테이블 마이그레이션(supabase/memberships.sql)을 먼저 실행해야 구독이 동작하며, 미실행 상태에서는 결제 전에 서버가 차단한다(MY-20).

10-1. 프로필 밴드 · 사이드 내비 (공통)

ID기능명상세 설명처리 기준 · 예외권한
MY-17프로필 밴드페이지 상단 연보라 밴드: 88px 아바타(우하단 카메라 뱃지) + 닉네임(구독 시 티어 뱃지) + [프로필 수정] 필 + 이메일, 우측에 찜한 굿즈 · 주문 내역 · 작성한 글 3개 통계.통계는 각 목록의 실제 개수와 동일.
MY-18사이드 내비좌측 240px 내비: 아이콘 + 라벨 + 개수 배지 형태의 메뉴(멤버십NEW · 찜 목록 · 결제 내역 · 내가 쓴 글 · 배송지 관리), 활성 항목은 연보라 필 + 보라 텍스트. 하단에 푸시 알림 토글 카드, 그 아래 [로그아웃] · [회원탈퇴].하위 경로(주문 상세 · 배송지 추가 등)에 있어도 상위 메뉴가 활성 표시된다. 회원탈퇴는 MY-26.
MY-01콘텐츠 헤더 · 정렬각 목록 화면 상단에 타이틀 + 보라 개수 + (해당 목록의) 정렬 셀렉트(COM-17)를 배치. 배송지 관리 화면은 정렬 대신 [새 배송지 추가] 버튼.
MY-02프로필 수정 (모달)[프로필 수정]을 누르면 모달이 열린다: 아바타 + 카메라 뱃지(사진을 눌러 변경 · 업로드 후 크롭), 닉네임 입력(카운터 n / 6 · 안내 “2~6자, 공백 없이 입력해주세요”), 읽기 전용 이메일(앞에 소셜 로그인 아이콘 — 구글/카카오, 일반 이메일 가입은 미표시. 마이페이지 프로필 밴드 이메일 앞에도 동일 표시), [취소 · 저장하기]. 사진 선택 시 크롭 모달이 열린다: 원형 마스크 · 드래그 이동 · 휠/핀치/슬라이더 줌(1~3배), 안내 “드래그로 위치를, 휠·핀치나 슬라이더로 배율을 조정하세요.”로그인 시 아바타를 public.user.avatar_url동기화한다 — 소셜 프로필은 auth 메타데이터에만 있어 본인 세션에서만 읽히므로, 동기화하지 않으면 리뷰·댓글·게시판처럼 user 테이블을 조인하는 화면에서 남에게는 이니셜 서클로만 보인다. 직접 올린 이미지(custom_avatar_url)가 항상 우선하고 소셜 이미지는 DB가 비어 있을 때만 채우며, 카카오의 http URL은 https로 바꿔 저장한다(실패해도 로그인 흐름은 막지 않음). 크롭 모달은 react-easy-crop 기반으로 재작성(구 react-avatar-editor 대체). 크롭 결과는 최대 512px WebP로 저장하고 헤더 아바타에도 즉시 반영, 업로드 실패 시 크롭 모달을 유지해 재시도할 수 있다. 업로드 이미지는 커스텀 메타데이터 키(custom_avatar_url) + user 테이블에 저장해 소셜 재로그인 시에도 유지(소셜 이미지로 원복되던 버그 수정). 성공 시 “프로필 이미지가 변경되었습니다.”
MY-03닉네임 변경프로필 수정 모달에서 닉네임을 바꾸고 저장. 성공 시 “닉네임이 변경 되었습니다.”2글자 이상(“2글자 이상 입력해 주세요.”) · 6자 이하(“6글자 이하로 입력해 주세요.”) · 공백 불가(“공백 없이 입력해 주세요.”)를 검증 스키마로 강제. 동일 닉네임 저장 시 “변경된 닉네임이 없습니다.” (구 인라인 편집 방식은 모달로 대체) 닉네임은 커스텀 메타데이터 키(nickname) + user 테이블에 저장해 소셜 재로그인 시에도 유지(소셜 이름으로 원복되던 버그 수정).
MY-04푸시 알림 수신 설정사이드 내비 하단 카드의 스위치로 푸시 수신 on/off — 웹 브라우저와 앱을 하나의 스위치로 관리한다. 안내 문구는 상태별로 바뀐다: 켜짐 “댓글·답글 알림을 웹과 앱으로 받아요” / 웹 푸시 가능 “켜면 이 브라우저와 앱에서 알림을 받아요” / 앱 기기만 등록됨 “켜면 앱에서 알림을 받아요”. 웹 브라우저에서 켜면 알림 권한 요청 후 이 브라우저를 수신 기기로 먼저 등록(PUSH-11)하고 켠다. “푸시 알림을 켰습니다/껐습니다.” 토스트.웹 푸시 미지원 브라우저 + 앱 기기 미등록이면 “이 브라우저는 알림을 지원하지 않아요. 앱에서 로그인하면 받을 수 있어요” + 비활성. 브라우저 알림 권한 거부 시 “브라우저 알림 권한이 필요해요. / 주소창 옆 사이트 설정에서 알림을 허용한 뒤 다시 켜 주세요.” 설정은 등록된 모든 기기(웹·앱)에 일괄 적용. 앱 WebView 안에서는 네이티브(Expo) 푸시가 담당하므로 웹 구독을 만들지 않는다.
MY-26회원탈퇴 v2 신규사이드 내비 하단 [회원탈퇴] → destructive 확인 모달(“정말 탈퇴하시겠어요? / 계정과 개인정보는 즉시 삭제되며 되돌릴 수 없어요. 작성한 글과 댓글은 '탈퇴한 회원'으로 남고, 구독 중인 멤버십도 함께 해지돼요.” · [취소 · 탈퇴하기]) → 성공 시 “회원탈퇴가 완료되었습니다. / 그동안 이용해 주셔서 감사합니다.” 토스트와 함께 로컬 세션 · 장바구니 · 찜을 정리하고 메인으로 이동.서버가 프로필을 “탈퇴한 회원”으로 익명화(아바타 제거, 이메일은 재가입 충돌 없는 자리표시자로 교체)해 작성한 글·댓글의 작성자 표시를 보존한 뒤, 개인정보 성격 테이블(배송지 · 주문자 정보 · 찜 · 푸시 수신 기기)을 즉시 삭제하고 auth 계정을 삭제한다(멤버십은 계정 삭제와 함께 연쇄 정리). 실패 시 “회원탈퇴에 실패했습니다. / 잠시 후 다시 시도해 주세요.” 운영 전제: supabase/account-deletion.sql(프로필 → 계정 FK 제거) 실행 필요(적용 완료).

10-2. 찜 목록 /mypage/wishlist

ID기능명상세 설명처리 기준 · 예외권한
MY-05찜 목록 조회찜한 상품을 굿즈샵과 동일한 상품 카드(SHOP-04)로 그리드 표시 — 썸네일 · 배지 · 상품명 · 할인율 · 할인가 · 별점. 카드 클릭 시 상품 상세 이동.최신 찜 순. 비어 있으면 “아직 찜한 굿즈가 없어요 / 굿즈샵에서 마음에 드는 굿즈를 담아보세요” + [굿즈샵 구경 가기].
MY-06찜 해제카드 우상단 하트(채워진 상태)를 누르면 즉시 해제, “찜하기가 취소되었습니다.” 토스트.확인 절차 없이 즉시 삭제.

10-3. 결제 내역 · 주문 상세 /mypage/orders /mypage/orders/[orderId]

ID기능명상세 설명처리 기준 · 예외권한
MY-07결제 내역주문 단위 카드로 표시: 상태 뱃지payments.delivery_status(배송전 보라 · 배송중 주황 · 배송완료 초록)를 표기하되 구매확정이 최종 단계라 우선하고, 배송 정보가 없으면 “결제 완료”로 떨어진다 —, “YYYY.MM.DD 주문”, 72px 썸네일, “{첫 상품명} 외 N건”, 총 결제 금액, 우측 [주문 상세] · [리뷰 쓰기] 버튼.주문일 내림차순. 없으면 “결제한 내역이 없습니다 / 첫 주문을 기다리고 있어요” 빈 상태.
MY-08주문 상세[결제 내역으로] 백 필 → 타이틀 + 상태 뱃지 → “결제 일시 · 주문번호” 메타 → 주문 상품 박스(썸네일 · 상품명 · 옵션/수량 · 금액 · 구매확정 칩 · [리뷰 쓰기/수정] · [구매확정]) → 배송 정보 / 결제 수단 2단 카드 → 결제 정보 합계(상품 금액 · 상품 할인 · 멤버십 할인 · 배송비(주문 시점에 계산해 payments에 저장한 값) · 총 결제 금액 보라 강조).존재하지 않는 주문번호면 “주문을 찾을 수 없습니다.” 상품 클릭 시 상품 상세 이동. 결제 정보 카드는 주문완료 화면(PAY-05)과 공용.
MY-09구매확정미확정 상품의 [구매확정] 버튼 → 확인 모달(primary 톤, “구매를 확정하시겠습니까? 구매 확정 후에는 취소나 변경이 불가능합니다.”) → 확정 시 “구매가 확정되었습니다.” + “구매확정” 칩 표시.확정 후 되돌리기 불가. 주문 취소/환불 기능은 미제공(부록 참고).
MY-10리뷰 작성 · 수정구매확정된 상품의 [리뷰 쓰기](작성 후엔 [리뷰 수정])로 리뷰 모달을 연다: 상품 요약(썸네일 · 상품명 · 옵션) → “굿즈는 만족하셨나요?” 별점 5개(선택 시 “4점 · 마음에 들어요” 등 라벨) → 내용 입력(플레이스홀더 “좋았던 점을 다이브들과 나눠보세요 (최소 10자)” · 카운터 n / 200) → [취소 · 등록하기]. 작성된 리뷰는 상품 상세 리뷰 탭(SHOP-13)에 반영.별점 미선택 시 “별점을 선택해주세요.” 최소 글자 수 미만 차단. 수정 시 변경 없으면 “변경된 내용이 없습니다.” 모달은 가로 스크롤을 막고(overflow-x-hidden) 내용 입력창은 높이 120px 고정 · 크기 조절 손잡이 비활성이라 늘려도 모달 밖으로 삐져나오지 않는다(resize-none은 공용 Textarea 기본값으로 반영).

10-4. 내가 쓴 글 /mypage/posts

ID기능명상세 설명처리 기준 · 예외권한
MY-11내 게시글 목록내가 작성한 글을 로우 카드로 표시: 제목 + “작성일 · 조회 n · 댓글 n” 메타. 클릭 시 게시글 상세로 이동.정렬 셀렉트 제공(최신순 · 인기순). 없으면 “작성한 게시글이 없습니다 / 팬 게시판에 첫 글을 남겨보세요”. 수정·삭제는 게시글 상세에서 수행. 시안에 있던 카테고리 뱃지는 게시판에 카테고리 기능이 없어 제외됨.

10-5. 배송지 관리 /mypage/address /mypage/address/new

ID기능명상세 설명처리 기준 · 예외권한
MY-12배송지 목록배송지마다 카드로 표시: 별칭(우리집 · 회사 등) + “기본 배송지” 뱃지(기본 배송지 카드만 보라 보더) 또는 [기본 배송지로 설정] 아웃라인 필, 받는 분 · 연락처, 주소(우편번호 포함), 우측 [수정 · 삭제] 버튼 쌍(COM-19).기본 배송지가 항상 최상단. 없으면 “등록된 배송지가 없습니다 / 배송지를 등록하면 주문이 빨라져요” + [새 배송지 추가].
MY-13배송지 추가별도 페이지에서 폼 입력: 받는 분 · 연락처(앞자리 셀렉트 + 번호) · 주소(우편번호 + [주소 검색] 버튼으로 다음(Daum) 우편번호 연동, 직접 입력 불가) · 상세 주소 · 배송 요청사항(선택지 + 직접 입력) · 기본 배송지로 저장 체크(안내: “첫 배송지는 자동으로 기본 배송지로 저장돼요”). 모두 유효해야 [배송지 저장] 활성. 성공 시 “배송지 정보가 저장되었습니다.”필수 미입력 시 필드별 안내(“받는 사람을 입력해 주세요.” 등). 첫 배송지는 자동으로 기본 배송지 지정. 상단 [배송지 관리로] 백 필로 복귀.
MY-14배송지 수정카드의 [수정] → 값이 채워진 모달에서 동일 폼으로 수정 후 [수정 완료]. 성공 시 “배송지가 수정되었습니다.”이미 기본 배송지면 “현재 기본 배송지로 설정되어 있습니다.” 안내로 대체.
MY-15배송지 삭제카드의 [삭제] → destructive 확인 모달(“배송지를 삭제할까요? / 삭제한 배송지는 복구할 수 없어요.” · [취소 · 삭제하기]) → 성공 시 “배송지가 삭제 되었습니다.”기본 배송지를 삭제하면 남은 배송지 중에서 기본 배송지가 자동 재지정. 게시글 삭제 모달과 동일한 공용 컴포넌트를 사용한다.
MY-16기본 배송지 설정비기본 배송지 카드의 [기본 배송지로 설정]으로 변경, “기본 배송지가 변경 되었습니다.” 토스트. 기본 배송지는 주문서(CART-07)의 배송 정보로 사용된다.기본 배송지는 계정당 1개.

10-6. DIVE 멤버십 /mypage/membership /mypage/membership/billing v2 신규

운영 전제 — 결제는 토스페이먼츠 빌링키(정기결제) 기반이며, 구독 정보는 memberships 테이블(유저당 1행, RLS로 본인 조회만 허용 · 쓰기는 서버 전용)에 저장된다. 커뮤니티 뱃지용으로는 민감 컬럼을 제외한 공개 뷰만 노출한다. 가격은 초기가이며 혜택 문구는 조정될 수 있다.
ID기능명상세 설명처리 기준 · 예외권한
MY-19멤버십 플랜 (미구독)“DIVE MEMBERSHIP — 최애 활동을 업그레이드해보세요” 히어로 + 3단 플랜 카드: ① 베이직 무료(찜·게시판·리뷰 작성, 댓글·답글 푸시 알림 — “현재 이용 중” 아웃라인) ② DIVE+ 월 1,900원(DIVE+ 뱃지 · 아바타 퍼플 링, 신보·공연 소식 우선 알림, 굿즈샵 상시 5% 할인 — 솔리드 CTA) ③ DIVE VIP 월 5,900원 · BEST 강조(DIVE+ 혜택 전부 + VIP 골드 뱃지, 굿즈샵 상시 10% 할인, 전 주문 무료배송, 신상 굿즈 24시간 우선 구매 — 그라데이션 CTA). 하단 안내 “구독은 매월 자동 결제 · 언제든 해지 가능 · 무료로도 기본 기능은 계속 쓸 수 있어요.” 이전에 구독했다가 혜택이 끝난 회원에게는 상단에 재구독 안내 배너(“{플랜} 혜택이 {종료일}에 종료됐어요 / 아래에서 플랜을 고르면 바로 다시 시작할 수 있어요 · 뱃지와 할인 혜택도 결제 즉시 복구돼요”)와 함께 이전에 쓰던 플랜 카드에 [이전 플랜] 칩“{플랜} 다시 시작하기” CTA가 표시된다.기수제가 아닌 구독 멤버십(유튜브 프리미엄식). 강조 카드는 VIP 하나뿐이며 그라데이션 CTA도 VIP 전용.
MY-20구독 결제 (토스 빌링)플랜 CTA → 구독 모달: 크라운 플랜 카드(플랜명 · 월 요금), “오늘 결제 후 매월 N일 자동 결제” 안내, 필수 약관 2건(정기결제 이용약관 · 멤버십 이용약관) 동의 체크, 오늘 결제 금액, [결제하고 시작하기] + “토스페이먼츠 빌링으로 안전하게 결제돼요”. 카드 등록 창에서 카드 정보를 입력하면 결과 페이지(/mypage/membership/billing)가 빌링키 발급 → 첫 결제 → 구독 저장을 처리하고 “DIVE 멤버십 구독을 시작했어요!” 토스트와 함께 멤버십 화면으로 돌아온다.필수 약관 2건 동의 시에만 진행. 결제 수단은 카드(빌링) 전용. 결제 전에 서버가 구독 테이블 존재를 확인해, 마이그레이션 전이면 결제하지 않고 “멤버십 테이블이 없습니다…” 오류를 반환한다(카드만 결제되는 사고 방지). 실패·취소 시 “카드 등록이 완료되지 않았습니다.”
MY-21구독 관리 · 결제 수단 변경 · 해지구독 중이면 상태 카드(플랜 뱃지 · 구독 중 표기)와 결제 정보(다음 결제일 · 월 요금 · 결제 수단(카드사 + 마스킹 번호) · 구독 시작일), 혜택 이용 현황이 표시된다. [결제 수단 변경] → 카드 목록 모달(선택 카드는 보라 보더 + “사용 중” 뱃지, [새 카드 등록하기]) → 토스 카드 등록 후 “결제 수단이 변경되었습니다. / 다음 결제일부터 새 카드로 결제돼요.” 하단 [멤버십 해지하기] → destructive 모달(“DIVE 멤버십을 해지할까요? / 다음 결제일(N월 N일)까지 혜택은 그대로 유지돼요.” · [유지하기 · 해지하기]) → “멤버십이 해지되었습니다.”해지해도 다음 결제일까지 혜택은 유지되고 해지 예정 상태가 된다(MY-24). 해지 예정 상태에서는 [결제 수단 변경] · [플랜 변경] 버튼과 [멤버십 해지하기] 링크를 감춘다.
MY-25플랜 변경 (업그레이드 · 다운그레이드)구독 중 상태 카드의 [플랜 변경] → 플랜 변경 모달: 유료 플랜 2장을 라디오로 고르고 현재 플랜에는 “현재 플랜”, 고른 플랜에는 “업그레이드”/“변경 예정” 표시가 붙는다. 업그레이드(DIVE+ → VIP)는 “오늘 {금액}원만 결제하면 바로 적용돼요 / 남은 {N}일치 차액이에요. 다음 결제일({날짜})부터는 월 {요금}원이 결제되고, 혜택은 결제 즉시 시작돼요.” 안내 후 [업그레이드하기] → 저장된 빌링키로 남은 기간 차액만 즉시 결제하고 티어를 바로 반영한다(다음 결제일은 그대로) → “{플랜}으로 업그레이드했어요. / 지금부터 바로 혜택이 적용돼요.” 다운그레이드(VIP → DIVE+)는 “다음 결제일부터 {플랜}로 변경돼요 / {날짜}까지는 현재 혜택이 그대로 유지되고, 추가 결제나 환불은 없어요. 그 전까지 언제든 변경을 취소할 수 있어요.” 안내 후 [다음 결제일부터 변경] → 결제 없이 pending_tier예약만 하고 다음 결제일에 크론이 교체 결제한다(MY-23) → “플랜 변경이 예약되었습니다. / {날짜}부터 {플랜}로 변경돼요.” 예약 상태에서는 구독 중 화면에 예약 배너(“{날짜}부터 {플랜}로 변경될 예정이에요 · 그때까지 {현재 플랜} 혜택은 유지돼요”)와 [변경 취소]가 노출되고, 취소하면 “플랜 변경 예약이 취소되었습니다. / {현재 플랜}을 그대로 이용해요.”카드 재등록 없이 기존 빌링키를 재사용한다. 차액이 100원 미만이면 결제 없이 티어만 반영한다. 같은 플랜 선택은 “이미 이용 중인 플랜입니다.”, 해지 예정 상태에서는 “해지 예정 상태에서는 플랜을 변경할 수 없습니다.”로 막는다(해지 취소 후 이용 — MY-24).
MY-24해지 예정 표시 · 해지 취소 (구독 재개)해지하면 구독은 즉시 끊기지 않고 해지 예정 상태가 된다. 멤버십 화면 상태 카드가 오렌지 톤으로 바뀌고 크라운 대신 캘린더 아이콘 · [해지 예정] 칩 · “{종료일}에 혜택이 종료돼요 · {N}일 남음”(당일이면 “오늘까지”)이 표시되며, 그 아래 안내 배너(“해지를 취소하면 지금 플랜 그대로 이어져요” + 되돌리는 법 · 재구독 방법)가 붙는다. 결제 정보는 “다음 결제일” 대신 혜택 종료일(“{날짜} (이후 자동 결제 없음)”)과 해지 신청일 행을 보여준다. 상태 카드의 [해지 취소] → 확인 모달(“해지를 취소할까요? / {플랜} 구독이 그대로 이어지고, {다음 결제일}에 {금액}원이 결제돼요.” · [닫기 · 해지 취소하기]) → “해지가 취소되었습니다.” 토스트와 함께 구독 중 화면으로 돌아온다. 해지 예정은 사이드 내비 멤버십 메뉴(“NEW”/티어명 자리에 주황 “해지 예정”)와 프로필 밴드(뱃지 옆 “해지 예정” 칩 → 멤버십 화면 링크)에도 표시된다. 모바일에서는 상태 카드가 세로로 쌓이고 [해지 취소]가 전폭 버튼이 되며, 필 탭의 멤버십에도 “해지 예정”이 붙는다(MOB-08 시안).해지 취소는 혜택 종료일 전에만 가능하며 추가 결제 없이 status를 되돌린다(다음 결제일 · 카드 · 티어 그대로). 이미 혜택이 끝났으면 “혜택 기간이 끝나 다시 구독해야 합니다.”로 막고 플랜 화면에서 새로 결제해야 한다(MY-19). 해지 예정이 아닌 구독에는 “해지 예정 상태가 아닙니다.”
MY-23월 자동 결제 (크론)매일 07시(KST) Vercel Cron이 결제일이 지난 활성 구독을 빌링키로 자동 결제하고 다음 결제일을 한 달 뒤로 갱신한다.CRON_SECRET Bearer 인증. 결제에 실패하면 해당 구독을 해지 상태로 전환한다(결제일이 이미 지났으므로 혜택도 즉시 종료). 재시도 로직·실패 알림은 없다.전체
MY-22커뮤니티 구독자 표시구독자는 티어 뱃지(DIVE+ 보라 / VIP 골드 그라데이션)와 아바타 링(DIVE+ 보라 / VIP 골드 — 뱃지와 같은 골드 톤)으로 표시된다. 링은 아바타 공통 컴포넌트가 티어를 조회해 전 화면에 자동 적용되며(헤더 · 게시판 목록/상세/댓글 · 리뷰 · 마이페이지), 두께는 아바타 크기에 따라 2~3px. 뱃지는 공용 컴포넌트로 3가지 크기(프로필 밴드 12px · 게시판 닉네임 옆 10px · 댓글 9px)를 제공하며 골드 글로우는 md 이상만(댓글 크기에서는 원이 부풀어 보임), 댓글에서는 “작성자” 뱃지와 함께 표시될 수 있다.무료(베이직) 사용자는 뱃지·링이 표시되지 않는다.

11. 푸시 알림 · 하이브리드 연동

v2 신규. 푸시 알림은 두 채널로 발송된다 — 하이브리드 앱(Android WebView)의 Expo Push와 웹 브라우저(PWA)의 web-push(VAPID). 수신 기기는 push_tokens에 함께 저장되고(platform으로 구분) 같은 스위치(MY-04)로 관리된다. 웹 자체 알림함(인앱 알림 목록)은 없다.

11-1. 알림 종류

ID알림발송 시점 · 수신자제목 · 본문 형식채널
PUSH-01새 댓글내 게시글에 댓글이 달렸을 때 → 게시글 작성자.제목: ““{글 제목 15자}” 글에 새 댓글이 달렸습니다” / 본문: “{작성자명}: {댓글 내용 40자 미리보기}”.앱 · 웹
PUSH-02새 답글내 댓글에 답글이 달렸을 때 → 원댓글 작성자(+ 게시글 작성자에게는 PUSH-01 형식으로 함께 발송).제목: “내 댓글에 답글이 달렸습니다” / 본문: 동일 형식.앱 · 웹
PUSH-03게시글 좋아요내 게시글이 좋아요를 받았을 때(추가 시에만) → 게시글 작성자.제목: ““{글 제목 15자}” 글에 좋아요를 받았습니다” / 본문: “{이름}님이 회원님의 글을 좋아합니다. ❤️”.앱 · 웹

11-2. 발송 규칙 · 인프라

ID기능명상세 설명처리 기준 · 예외채널
PUSH-04발송 제외 규칙본인 행동에 대한 알림은 발송하지 않음(내 글에 내가 단 댓글, 내 댓글에 내가 단 답글, 내 글 좋아요).게시글 작성자 = 원댓글 작성자인 경우 더 구체적인 “답글” 알림 1건만 발송(중복 방지). 댓글 수정·삭제, 댓글 좋아요는 알림 없음. 좋아요 취소 시 미발송.앱 · 웹
PUSH-05알림 탭 이동알림에 해당 게시글 URL이 포함되어, 탭하면 앱/브라우저가 해당 게시글 화면을 연다.웹은 서비스가 열린 창이 있으면 그 창을 게시글로 이동시켜 포커스하고, 없으면 새 창을 연다.앱 · 웹
PUSH-06기기 토큰 등록 (앱)앱이 WebView에 푸시 토큰을 주입하면, 웹이 로그인 사용자와 연결해 서버에 자동 등록(기기당 1건, 계정 전환 시 갱신).비로그인 상태에서는 등록되지 않음. 만료된 토큰은 발송 실패 감지 시 자동 삭제.
PUSH-11웹 푸시 구독 (PWA) v2 신규마이페이지 푸시 스위치(MY-04)를 웹 브라우저에서 켜면 알림 권한 요청 → 서비스 워커(sw.js) 등록 → VAPID 구독 생성 순으로 이 브라우저를 수신 기기로 등록한다(push_tokensplatform="web"으로 저장). 페이지가 닫혀 있어도 브라우저가 워커를 깨워 알림을 표시한다. PWA 매니페스트를 제공해 홈 화면 설치를 지원한다.iOS 사파리는 홈 화면에 설치된 PWA에서만 웹 푸시 수신 가능. 만료된 구독(알림 차단·구독 해제)은 발송 실패(404/410) 감지 시 자동 삭제. VAPID 키(환경 변수) 미설정 시 웹 채널만 건너뛴다(앱 발송 무영향). 서비스 워커는 푸시 수신·클릭 라우팅 전용(오프라인 캐싱 없음).
PUSH-07수신 설정 반영마이페이지 스위치(MY-04)로 끈 사용자는 발송 대상에서 제외(발송 직전 서버에서 필터링).알림 종류별 세분화 설정은 없음(전체 on/off 단일 설정). 설정은 웹·앱 모든 기기에 일괄 적용.앱 · 웹
PUSH-08발송 실패 무영향푸시 발송은 백그라운드로 처리되어, 실패해도 댓글 작성·좋아요 등 원 기능에는 영향 없음. 채널별 발송(Expo · web-push)은 서버 공통 모듈이 담당한다.발송 API는 요청자 세션·소유권을 서버에서 재검증(위조 요청 차단).앱 · 웹
PUSH-09앱 링크 연결도메인-앱 연결 선언 파일(assetlinks.json)을 제공해, 결제 등 외부 앱에서 서비스 주소로 복귀할 때 브라우저 대신 하이브리드 앱이 열리도록 지원. 앱이 받는 경로는 결제 복귀 경로만(/payment/* · /mypage/membership/billing).스토어 배포 시 릴리즈 키 지문으로 교체 필요(현재 개발용). 도메인 전체를 잡으면 README QR의 /download까지 앱 안(WebView)에서 열려 다운로드 알림이 설치로 이어지지 않는다 — 앱 v1.0.4에서 경로를 좁혔다. 앱 안에서 APK 링크를 만나면 시스템 브라우저로 넘긴다.
PUSH-10앱 테마 연동웹의 현재 테마(라이트/다크)가 바뀔 때마다 WebView 메시지로 앱에 전달되어, 네이티브 셸(상태바 · 세이프에어리어)이 웹 테마를 따라간다.웹 단독(브라우저) 사용 시에는 동작하지 않음. COM-16 다크모드와 연동.
PUSH-12앱 오프라인 · 로드 실패 화면 v2 신규앱에서 네트워크가 끊기거나(NetInfo) 페이지 로드에 실패하면(WebView onError) WebView 내장 에러 페이지 대신 앱 자체 화면을 전체 화면으로 덮는다. 구성은 404 화면(COM-11)의 디자인 언어를 그대로 옮겨 브랜드 그라데이션 원 아이콘(wifi-off) + “오프라인이에요” + “인터넷 연결을 확인한 뒤 다시 시도해 주세요.” + 상태 칩 “네트워크에 연결되어 있지 않아요” + [다시 시도] · [홈으로 이동] 2단 CTA + Wi-Fi · 데이터 · 비행기 모드 점검 칩. [다시 시도]는 연결을 다시 확인한 뒤 실패한 페이지를 새로고침하고, [홈으로 이동]은 WebView를 다시 마운트해 첫 화면부터 불러온다.연결이 복구되면 실패했던 페이지를 자동으로 다시 불러온다(NetInfo 이벤트 → reload). 화면 색은 웹 테마(PUSH-10)를 따라 라이트/다크로 바뀌며, 테마 신호를 받기 전(콜드 스타트 오프라인)에는 라이트. 웹 서비스 워커에는 오프라인 캐싱이 없어(PUSH-11) 브라우저 단독 사용 시에는 브라우저 기본 오프라인 페이지가 뜬다. 앱 v1.0.1(versionCode 2)부터.
PUSH-13앱 셸 조작 · 복구네이티브 셸이 담당하는 기본 조작 — Android 당겨서 새로고침(웹 스크롤이 최상단일 때만 활성), iOS 스와이프 뒤로/앞으로 · 당겨서 새로고침, Android 하드웨어 뒤로가기(현재 경로 기준 — PUSH-14), 첫 로딩 동안 브랜드 스플래시 노출 — 시스템 스플래시는 배경색만(아이콘 없음) 보이다가 300ms 페이드로 그라데이션 + 로고 + “IVE FAN COMMUNITY” 오버레이로 이어지고, 웹 첫 로드가 끝나면 걷힌다(아이콘만 먼저 떴다가 로고+타이틀로 바뀌면 위치가 어긋나 보여 2단계를 하나로 합침).스플래시는 페이드 뒤 로고가 최소 1초는 보이도록 유지하고(빠른 회선의 깜빡임 방지, 로드가 그보다 길면 즉시), 10초를 넘기면 스피너를 붙이며, 15초 안전장치로 반드시 걷힌다. 히어로 배경 영상 등 무음 자동재생을 허용한다(WebView 기본값은 사용자 조작 필요). iOS에서 WebView 프로세스가 종료되면 빈 화면이 되므로 자동으로 다시 불러온다. 결제(토스 → 카드사 앱 → 복귀)가 여러 외부 도메인을 경유하므로 http/https는 전부 WebView 안에서 처리하고, intent:// 등 앱 호출 스킴만 밖으로 넘긴다.
PUSH-14앱 뒤로가기 기준 · 라우팅 브리지 v2 신규Android 하드웨어 뒤로가기는 웹 히스토리가 아니라 현재 경로로 판단한다(유튜브 · 인스타 방식) — 홈(/)에서는 “한 번 더 누르면 앱이 종료돼요” 토스트 뒤 2초 안에 한 번 더 누르면 종료, 하단 탭 루트(/news · /discography · /shop · /board)에서는 히스토리와 무관하게 홈으로, 그 외(상세 · 마이페이지 · 결제 · 외부 도메인)는 웹 히스토리를 따르되 뒤가 없으면(알림 딥링크 진입) 홈으로. 어느 화면에서든 “상세 → 탭 루트 → 홈 → 종료” 세 단계 안에 끝난다. 웹 NavigationBridge가 라우트가 바뀔 때마다 WebView 메시지(route)로 현재 경로를 알리고, 셸이 “홈으로”를 요청할 진입점 window.__iveNavigate(href, replace)(Next 라우터)를 열어 전체 리로드 없이 이동한다.셸은 WebView 내비 이벤트의 URL(외부 도메인은 무시)과 route 메시지 중 마지막 값을 쓴다. 진입점이 없는 페이지(외부 결제 도메인 · 구버전 웹)는 location.replace로 홈을 다시 연다. 하단 탭바(COM-22)는 앱 안에서만(window.ReactNativeWebView 감지) 탭 전환을 replace로 해 히스토리를 쌓지 않고, 모바일 브라우저는 push를 유지한다. 탭 루트 목록은 앱 TAB_ROOT_PATHS와 웹 GNB_ARRAY를 같이 바꿔야 한다. 이전(v1.0.5까지)에는 히스토리 우선이라 탭을 오간 만큼 뒤로가기가 이어졌다. 앱 v1.0.6(versionCode 7)부터. 시트 · 모달이 열려 있으면 경로 판단 전에 그것만 닫는다 — 웹이 열린 Radix 오버레이(role="dialog" · data-state="open")를 overlay 메시지로 알리고, 셸이 window.__iveCloseOverlay()(document Escape → 최상위 레이어만 닫힘)를 부른다. 앨범 상세 시트(DISC-05)처럼 URL 이 안 바뀌는 전체 화면 UI 에서 뒤로가기가 홈으로 가 버리던 것의 수정. 앱 v1.0.7(versionCode 8)부터.

11-3. 앱 다운로드 /download

README·QR이 릴리스 파일(APK)을 직접 가리키면 인앱 브라우저에서 설치가 막힌다 — 카카오톡·QR 스캐너 등은 APK를 받아도 설치기로 넘기지 못해 “다운로드 중”에서 멈춘다. 그래서 공유 링크는 이 페이지를 가리키고, 여기서 환경을 갈라 처리한다.

ID기능명상세 설명처리 기준 · 예외권한
APP-01다운로드 페이지 구성핑크 로고 + “IVE DIVE 앱 다운로드” 타이틀 + 환경별 안내 문구(“잠시 후 다운로드가 자동으로 시작돼요” / “외부 브라우저로 여는 중이에요…” / “iPhone·iPad는 APK 없이 웹에서 바로 설치해요”) + [APK 다시 받기] 버튼. 하단에 설치가 막힐 때의 수동 안내 2줄(⋮ 메뉴 → 다른 브라우저(Chrome)로 열기 / “출처를 알 수 없는 앱” 허용).스킴이 무시되는 환경(구버전 · iOS 인앱)이 있어 자동 전환에만 기대지 않고 수동 안내와 다운로드 버튼을 항상 함께 노출한다.전체
APP-02인앱 브라우저 감지 · 외부 전환진입 시 User-Agent로 환경을 4갈래(ready · inapp · ios · loading)로 가른다. 카카오톡kakaotalk://web/openExternal 스킴으로 이 페이지를 외부 브라우저에서 다시 열고, 그 밖의 안드로이드 인앱(네이버 · 인스타그램 · 페이스북 · 라인)은 intent:// 스킴으로 기본 브라우저를 연다. 일반 브라우저와 이름 모를 WebView(카메라 QR 스캐너 등)는 바로 내려받기를 시작한다 — WebView 공통 마커(; wv)까지 인앱으로 잡아 intent://로 넘기던 분기는 일반 WebView가 그 스킴을 처리하지 못해 “외부 브라우저로 여는 중이에요…”에서 멈춰 제거했다(vidding-re · energy-meal과 동일).iOS는 APK가 없어 다운로드 대신 홈 화면 추가(PWA) 2단계 안내와 [서비스 열기] 버튼을 보여준다(아이패드 데스크톱 UA는 maxTouchPoints로 판별). effect 안의 동기 setState가 렌더를 연쇄시키므로 상태 전환과 이동을 한 틱 미룬다.전체
APP-03APK 파일 링크 — GitHub 릴리스 직결내려받기는 github.com/seokachu/ive-app/releases/latest/download/ive-dive.apk를 직접 가리킨다. 릴리스마다 같은 자산명으로 올리면 README·QR·이 페이지 모두 손대지 않아도 최신을 받는다.한때 동일 출처 스트리밍 프록시(/download/ive-dive.apk)를 뒀으나 Range(이어받기) 요청을 처리하지 못해 폰이 네트워크 전환·화면 꺼짐 뒤 이어받기를 시도하는 순간 실패했다(curl -C 재현: 프록시 “byte ranges 미지원”, GitHub 206 정상) — 2026-08-30 제거. GitHub CDN은 Accept-Ranges/206으로 이어받고 MIME도 application/vnd.android.package-archive로 내려준다. 갓 올린 APK는 Chrome 파일 검사에 처음 걸려 커스텀 탭에서 “다운로드 중…”에 머물 수 있다 — Chrome 본체의 다운로드 목록에서 유지하면 통과한다.전체

12. 디자인 시스템

v2 신규. 단일 소스 문서는 public/docs/design-system.md, 디자인 파일은 design/ive-design-system.pen, 한눈에 보는 문서는 디자인 시스템 (/docs/design.html).

ID항목상세 설명처리 기준 · 예외적용
DS-01색상 토큰브랜드 Purple 6단계 램프(기준색 #DB97E9 = purple-300) + Orange 3단계 + Neutral gray 9단계 + 상태색(success · warning · info · error · kakao). shadcn 시맨틱 토큰(--primary · --ring)을 브랜드 보라로 재정의해 버튼·포커스 링·에러 상태가 브랜드색을 따름. 다크모드용 팔레트 별도 정의 — 배경 #1B1B1F · 카드 #1E1E21 · 보더 #2E2E33(zinc 쿨톤) + 다크용 purple 램프.레거시 토큰과 하드코딩 hex 전면 제거. JS 코드(별점·컨페티 등)는 COLORS 상수, Tailwind 밖 CSS는 var(--gray-*) 참조.전체
DS-02타이포 · 간격Pretendard 단일 서체 기준 7단계 타입 스케일(Display 36 / H1 24 / H2 20 / H3 18 / Body 16·14 / Caption 12), 간격은 4px 배수, 라운드 4/6/8/16/full, 그림자 3단계. 컨테이너 폭은 max-w-container/content 토큰으로 통일.전체
DS-03컴포넌트 단일화ui/button variant 9종(브랜드 primary · kakao · outlineBrand · plain 등) + size 5종으로 모든 버튼 통일. ui/input은 h-12 · rounded-lg · 브랜드 포커스 링으로 통일. 아이콘은 lucide-react 단일, 로딩은 공용 Spinner(접근성 role 부여) 단일.react-icons · react-spinners · framer-motion 의존성 제거.전체
DS-04적용 현황토큰·버튼·아이콘·로딩·다크 팔레트는 전 화면 적용 완료. 캐러셀은 swiper로 단일화(embla 제거). 화면 단위 리디자인은 로그인 · 회원가입 → 메인 → 음악 → 소식 → 굿즈샵(목록·상세) → 자유게시판(목록·글쓰기·상세) → 장바구니·결제 → 404 → 마이페이지 · DIVE 멤버십 → 모바일 대응(14장)까지 적용 완료.공용화된 컴포넌트: SectionTitle · MoreLink · DdayBadge · StreamingLinkChips · SortDropdown(COM-17) · ConfirmModal(variant, COM-14) · ShareSheet(COM-18) · EditDeleteActions(COM-19) · 빈 상태 패턴(COM-20) · MembershipBadge(MY-22) · BottomNav(COM-22). 잔여: card/tabs 수제 구현 산재.전체
DS-05리디자인 사용 규칙버튼은 rounded-full 필이 기본(입력 필드는 rounded-lg 유지) ② 그라데이션은 결제 CTA·게시글 추천 등 최상위 액션 전용, 나머지 주요 CTA는 솔리드 브랜드 보라 ③ 파괴적 액션은 붉은 틴트 버튼 + destructive 모달 ④ 상태·강조 색은 팔레트 토큰만 사용(purple 50~500 · orange 100/300/500 · gray 50~900).팔레트에 없는 단계(purple-700 등)는 클래스가 생성되지 않는다. CSS 변수 기반 색은 Tailwind 불투명도 변형(bg-purple-500/90)이 동작하지 않으므로 솔리드로 쓰거나 opacity 유틸을 쓴다. 삭제(destructive) 색은 팔레트에 없어 고정 hex(#E72424)를 사용한다. 구 DS Button 컴포넌트(radius-lg)는 현행 규칙보다 이전 버전이다.전체
DS-06스토리북Storybook 10(@storybook/nextjs-vite)을 도입해 공용 컴포넌트와 파운데이션 문서를 카탈로그로 제공한다. 라이트/다크 테마 전환 애드온을 붙여 두 모드를 한 화면에서 확인할 수 있다.스토리는 컴포넌트 옆에 함께 두고, 파운데이션 문서만 별도 디렉터리에 모은다. 배포는 메인 앱과 분리된 Vercel 프로젝트로 정적 산출물을 업로드한다(pnpm storybook:deploy).전체

13. 접근 제어 정책 요약

서버 가드(proxy)와 클라이언트 가드(화면/액션)의 이중 구조.

구분대상정책
서버 가드/mypage/*비로그인 접근 시 로그인 페이지로 리다이렉트.
/login · /signup로그인 상태로 접근 시 메인으로 리다이렉트.
/login?form=signup가입 직후 발급 쿠키(5분) 없으면 일반 로그인으로 리다이렉트.
/payment/success · fail주문번호 쿼리 없으면 메인으로 리다이렉트. (PG 복귀 특성상 로그인 검사는 클라이언트가 담당 — v1 튕김 문제 수정)
화면 가드마이페이지 · 결제 성공/실패세션 복원 후에도 비로그인이면 “로그인 후 이용 가능합니다.” 토스트 → 로그인 페이지 이동.
액션 가드글쓰기 · 게시글/댓글 좋아요 · 댓글/답글 작성 · 결제하기 · 바로구매비로그인 시 “로그인이 필요합니다.” 토스트 후 동작 차단(리다이렉트 없음).
비로그인 허용메인/소식/게시판/굿즈샵 조회, 게시글 검색, 공유(링크 복사), 장바구니 담기·수량변경·삭제, 찜(기기 저장, 로그인 시 계정 이관).
데이터 권한수정 · 삭제UI는 본인 리소스에만 버튼 노출, 데이터 계층은 Supabase RLS 정책으로 보호.

14. 모바일 대응 (반응형)

별도 모바일 라우트 없이 전 페이지를 반응형으로 대응한다. 기준 뷰포트는 390px(Expo 하이브리드 앱 WebView와 동일)이며, 시안은 마이페이지 · 드로어 메뉴 수작업 시안과 페이지별 390px 실화면 캡처(.pen “모바일 · *” 프레임 8종)를 기준으로 한다. 하단 탭바 · 드로어 메뉴 상세는 2-2(COM-22 · COM-06~09) 참고.

ID기능명상세 설명처리 기준 · 예외권한
MOB-01브레이크포인트 정책커스텀 스케일 — sm 375 · md 768 · lg 1024 · xl 1320, 컨테이너 1320px · 콘텐츠 1280px. 데스크톱 전용 UI(사이드 내비 · GNB 등)는 lg, “모바일은 세로 스택 → 태블릿부터 가로” 분기는 md를 기준으로 한다.sm이 Tailwind 기본(640px)과 달리 375px이므로 세로 스택 의도에 sm을 쓰면 폰에서도 가로로 풀린다 — md 사용이 규칙(2026-08-17 QA에서 오용 4건 교정).전체
MOB-02마이페이지 모바일 IAlg 미만에서 세로 재배치 — 컴팩트 프로필 밴드(아바타 72px · “수정” 축약 버튼 · 스탯 3종 균등 배치) → 가로 스크롤 필 탭(멤버십 NEW · 찜/결제/글/배송지 + 카운트, 활성 탭 자동 스크롤) → 콘텐츠 → 푸시 알림 카드 · 로그아웃/회원탈퇴. 데스크톱은 240px 사이드 내비 유지(MY-18).탭 활성 스타일은 연보라 필 + 보라 텍스트로 데스크톱과 동일.
MOB-03목록 그리드 열 규칙굿즈샵 목록 2열 → 3열(md) → 4열(lg) · 상세 추천 2열 → 3열(md) → 6열(lg) · 소식 영상 1열 → 2열(md) → 4열(lg) · 찜 목록 2열 → 3열(md) · 멤버십 플랜 1열 → 3열(lg). 게시판 목록은 전 구간 단일 칼럼 카드 로우.모바일 3열은 카드 폭 부족으로 뱃지가 깨져 금지(추천 섹션에서 2열로 교정).전체
MOB-04가로 스크롤 패턴마이페이지 필 탭 · 게시판 필터 필 · Tiptap 에디터 툴바는 좁은 폭에서 가로 스크롤로 전체 항목을 유지한다(스크롤바 숨김).우측에 잘린 항목이 스크롤 가능함을 암시한다.전체
MOB-05터치 대응앨범 미리듣기 FAB는 터치 기기에서 상시 노출(pointer: coarse), 미니 디스크는 탭 시 보조 버튼 4초 노출(MAIN-08), 상품 갤러리는 스와이프 넘김(SHOP-07), 플로팅 플레이어의 볼륨 슬라이더는 모바일에서 숨김.hover에만 의존하는 조작 없음.전체
MOB-06도킹 더보기 버튼소식의 “더 많은 영상/기사 보기” 버튼은 목록 스크롤 중 화면 하단에 도킹(sticky)되어 항상 접근 가능하다.실사용 동작이며, 풀페이지 캡처에서는 겹쳐 보일 수 있음.전체
MOB-07좁은 폭 안정화일정 카드의 카테고리 · “자동 수집” 뱃지는 줄바꿈 없이 유지되고 날짜만 다음 행으로 내려간다. 주문 상품 로우의 액션 버튼은 폭이 부족하면 아래 행으로 랩핑된다.2026-08-17 모바일 QA에서 발견된 깨짐(뱃지 두 줄 분리 · 하트 겹침) 수정 반영.전체
MOB-08모바일 시안 소스.pen 수작업 시안 — “마이페이지 · 모바일 · 라이트/다크”, “마이페이지 · 모바일 · 멤버십 해지 예정 · 라이트/다크”, “모바일 메뉴 · 라이트/다크/비로그인”. 캡처 시안 — “모바일 · 메인/소식/음악/굿즈샵/굿즈샵 상세/게시판/게시판 상세/장바구니” 8프레임 — pnpm capture:mobile(Playwright, 로컬 dev 390px · 2x 풀페이지, 탭바 · GoTop · 히어로 iframe은 숨기고 썸네일 폴백으로 캡처)로 뜬다. 2026-08-31 새 로고 기준으로 전부 재촬영(design/assets/mobile/*-3.png). 하단 네비 시안은 이 캡처 위에 BottomNav 컴포넌트를 얹은 “모바일 · 메인/소식/게시판 · 하단 네비” 3프레임과 “모바일 메뉴 · 하단 네비 적용 · 라이트/다크”.같은 파일명으로 덮어쓰면 디자인 도구가 캐시를 잡고 있어 Pen 재시작(또는 파일명 변경)이 필요하다. 이미지 픽셀 높이가 16384를 넘으면 캔버스에서 빈 화면으로 보이므로 스크립트가 배율을 자동으로 낮춘다(ONLY=이름으로 일부만 재촬영 가능).전체
MOB-09하단 탭바 오프셋lg 미만에서 탭바가 차지하는 높이(캡슐 64px + 아래 8px + safe-area)를 --tabbar-h 변수 하나로 관리한다(lg 이상 0). 본문은 bodypb-tabbar로 탭바만큼 여백을 두고, 플로팅 플레이어 바 · 미니 디스크 · GoTop 버튼은 mb-tabbar, 소식의 도킹 더보기(MOB-06)는 bottom-tabbar-10으로 탭바 위에 올라간다.변수가 브레이크포인트에서 0이 되므로 lg: 변형 없이 같은 클래스를 쓴다. 새 하단 고정 요소는 반드시 이 토큰을 써야 하며 bottom-[calc(...)] 임의값은 금지(CLAUDE.md 컴포넌트 규칙).전체

15. 부록

15-1. 데이터 저장소 (Supabase)

구분이름용도
테이블 user회원 프로필(닉네임 · 아바타), Auth 계정과 연동 — 탈퇴 시 삭제되지 않고 “탈퇴한 회원”으로 익명화되어 글·댓글 작성자 표시를 보존(MY-26)
album메인 앨범 캐러셀(발매 정보 · 음원 플랫폼 링크)
schedules일정(제목 · 카테고리 · 기간 · 장소 · 설명 · 링크 · 출처 manual/auto) — 수동 큐레이션 + 크론 자동 추출 초안, 공개 읽기 전용 RLS — v2 신규
news_gallery / gallery(구) 소식 기사 / 사진 갤러리 — 2026-08 소식 개편으로 코드에서 미사용
board게시글(제목 · 본문 · 조회수 · 썸네일)
board_with_meta (뷰)게시글 목록용 집계 뷰(작성자명 · 댓글 수 · 추천 수 포함)
board_comments댓글 · 대댓글(자기참조 parent_id)
board_likes / comment_likes게시글 / 댓글 좋아요
goods굿즈 상품(가격 · 할인율 · 사이즈/색상 · 배송 유형)
goods_reviews상품 리뷰(별점 · 내용)
wish_lists회원 찜 목록
customer_info주문자 정보(계정당 1건)
shipping_addresses배송지(기본 배송지 플래그 포함)
payments결제 레코드(주문번호 · 결제수단 · 상태 · 배송지 스냅샷)
order_items주문 상품(수량 · 구매확정 여부)
push_tokens푸시 수신 기기(기기당 1건 · 수신 on/off) — platform으로 앱(Expo 토큰)/웹(VAPID 구독 JSON) 구분 — v2 신규
memberships + memberships_public(뷰)DIVE 멤버십 구독(유저당 1행 — 등급 · 상태 · 요금 · 빌링키 · 카드 정보 · 다음 결제일). 본인 조회만 허용하는 RLS + 쓰기는 서버 전용, 커뮤니티 뱃지용 공개 뷰는 민감 컬럼 제외 — v2 신규(supabase/memberships.sql 실행 필요)
스토리지boards / avatars게시글 본문 이미지 / 프로필 이미지
DB 함수increment_view_count조회수 증가, 기본 배송지 지정·재지정(set_default_address, update_default_address)

15-2. 클라이언트 저장소 키

저장소용도
shopping_cartlocalStorage장바구니(서버 미저장). 로그아웃 시 삭제
wishlistlocalStorage비로그인 찜 목록. 로그인 시 계정으로 이관 후 삭제
checkout_items / order_namelocalStorage결제 진행 중 주문 상품 · 주문명 임시 보관(완료 시 삭제, 실패 시 복원용 유지)
viewedPostslocalStorage게시글 조회수 24시간 중복 방지
loginEffectlocalStorage가입 축하 연출 1회 재생 플래그
firstSignup쿠키 (5분)가입 축하 화면 접근 허용 티켓
redirectUrlsessionStorage로그인 후 원래 페이지 복귀 경로(내부 경로만 허용) — v2 신규

15-3. 자동화 스케줄

작업실행 주기 (KST)내용
일정 자동 추출 Vercel Cron매일 06:00수집된 기사에서 명시적 날짜가 있는 일정을 초안으로 저장 (NEWS-03)
앨범 자동 등록 Vercel Cron매일 06:30iTunes 신규 발매반 감지 후 album 등록 (MAIN-10)
멤버십 자동 결제 Vercel Cron매일 07:00결제일이 지난 활성 구독을 빌링키로 결제하고 다음 결제일 갱신 (MY-23)
굿즈 자동 수집 GitHub Actions매일 06:15공식 스토어 신상품 수집 + 갤러리 이미지 보강 (SHOP-16)
자유게시판 자동 포스팅 GitHub Actions매일 09:45 · 13:45 · 17:45 · 20:45글 풀에서 하루 2~3건을 시간대를 나눠 등록하고, 최근 글에 예정 시각이 지난 댓글·대댓글을 나눠 달며 좋아요·조회수를 목표치까지 서서히 올린다 (BRD-07)
소식 · 일정 피드30분 캐싱(ISR)뉴스·영상·일정 수집 결과 재생성 (NEWS-04)

Vercel Cron 경로는 CRON_SECRET Bearer 인증으로 보호된다. 이 밖에 수동 실행 데이터 스크립트가 있다 — goods:dedupe(중복 상품 정리) · goods:reprice(상품 메타·가격·배송 타입 재편성) · goods:albums(앨범 라인업 확충) · orders:seed(주문·리뷰 재생성) · shipping:backfill(기존 주문 배송비 되계산) · avatars:sync(소셜 아바타 일괄 동기화) · community:seed(자유게시판 시드 재생성, --append로 기존 데이터를 지우지 않고 DB에 없는 제목의 글만 추가) · community:daily(자동 포스팅 수동 실행, --dry-run으로 계획만 출력).

자유게시판 자동 포스팅 — 같은 입력이면 항상 같은 값이 나오는 결정적 해시로 계획을 세워, 실행 시점이 달라도 결과가 흔들리지 않는다. 글 풀이 소진되면 잡이 exit 1로 실패해 Actions 알림 메일이 온다 — 그때 scripts/data/community-daily-pool.mjs에 글을 이어붙이면 된다.

15-4. 미구현 · 알려진 한계

참고 — 아래는 기준 시점 코드에서 확인된 사실로, 이후 고도화 후보 목록으로 활용할 수 있다.