FeaturesStore (매장)Store Onboarding (/stores/new)

Store Onboarding — /stores/new (3-step)

SPEC #011 정합. v0.4.0 도입.

Overview

운영사가 매장을 등록 — 두 갈래:

  • INDEPENDENT — 개인 매장. 가상 본사 산하 (hqId = IndependentHqIds.SINGLETON). POST /api/v1/admin/stores/independent (SPEC #011 v0.6.0).
  • DIRECT / FRANCHISE — 가맹 본사 산하 매장. POST /api/v1/admin/hq/{hqId}/stores (SPEC #011 v0.6.0~v0.6.1). FE /stores/new 의 affiliation 라디오로 분기.

두 endpoint 모두 backend 도입 완료. plan·billingAnchorDay 는 HQ 소속 매장의 경우 HQ 에서 자동 상속.

Spec

Step 구조

Step내용
1. 기본 정보매장명 · 주소 · 점장명 · 점장 이메일 · 점장 전화 · plan(AI/TRUST) · billingAnchorDay
2. 약관 동의활성 TermsDocument · PrivacyPolicy 본문 + 체크 + 서명자명
3. 완료확인 요약 + [등록]

State shape

type StoreOnboardingState = {
  step: 0 | 1 | 2;
  affiliation: "INDEPENDENT" | "HQ";   // step1 라디오로 분기
  store: {
    name: string;
    address?: string;
    managerName?: string;
    managerEmail?: string;
    managerPhone?: string;
    plan: "AI" | "TRUST";          // INDEPENDENT 분기 전용 (HQ 소속은 HQ 에서 상속)
    billingAnchorDay: number;      // INDEPENDENT 분기 전용
  };
  hqAffiliation: {                 // affiliation === "HQ" 일 때만 사용
    hqId: string;
    storeType: "DIRECT" | "FRANCHISE" | "";
  };
  consent: {
    termsAgreed: boolean;
    privacyAgreed: boolean;
    signerName: string;
  };
};

manager 정보는 모두 optional (#011 결정 — 점장 계정 발급 흐름은 후속 SPEC).

Endpoint

step 3 “등록” 시 affiliation 에 따라 단일 POST 로 분기:

INDEPENDENTPOST /api/v1/admin/stores/independent (StoreOnboardingRequest):

  • request: { store: {...plan, billingAnchorDay}, consent: {termsVersion, privacyPolicyVersion} }
  • 단일 transaction:
    1. Store INSERT (type=INDEPENDENT, hqId=SINGLETON)
    2. StoreConsent INSERT
    3. StorePrivacyConsent INSERT
  • response 200: { storeId }

HQ 소속POST /api/v1/admin/hq/{hqId}/stores (HqAffiliatedStoreOnboardingRequest):

  • request: { store: {...storeType}, consent: {...} } — plan·billingAnchorDay 없음 (HQ 상속)
  • response 200: { storeId }

STORE_MANAGER 계정은 생성하지 않음 — 후속 SPEC.

States & Edge Cases

상태처리
활성 약관 부재진입 차단 + Banner
필수 필드 미입력다음 step disabled
잘못된 약관 version”페이지 새로고침 후 다시 시도”
5xx”잠시 후 다시 시도”
새로고침state 소실

Constraints

  • INDEPENDENT 분기: 가상 본사 (SINGLETON) 가 자동 hqId — UI 가 본사 선택 안 함
  • HQ 분기: hqId + storeType(DIRECT/FRANCHISE) 선택, plan·billingAnchorDay 는 HQ 상속 (UI 미입력)
  • manager 정보 nullable (점장 계정 흐름 미정)

Roadmap

  • 점장 계정 발급 (STORE_MANAGER) — 후속
  • CSV 일괄 등록

References

  • SPEC #011
  • linkmusic-frontend-space/apps/admin/src/app/(protected)/stores/new/