FeaturesStore (매장)Store Env Check (/store/onboarding)

Store Onboarding · Env Check — /store/onboarding (점장 환경 점검)

시안 design_handoff_linkmusic_7/design/screens/onboarding.jsx (골격) + …/onboarding-supplement.jsx (보강 상태: fail·수동확인·스피커 3단계·인터넷 폴백). FE-only · BE 변경 0.

Overview

점장(STORE_MANAGER)이 apps/space /store/onboarding 에서 매장 PC가 음악을 제대로 재생할 수 있는지 4항목을 점검하는 온보딩 화면. 시안 Stepper 4단계(비밀번호 변경=done · 환경 점검= current · 간단 소개=todo · 음악 시작=todo) 중 “환경 점검” 단계다. 4항목 모두 통과해야 다음으로 진행할 수 있다.

선행 단계 — 비밀번호 변경 강제: Stepper “비밀번호 변경=done” 은 실제 구현된 관문이다. 신규 임시 비번 계정(me.passwordMustChange=true)은 /store layout 가드가 /onboarding/change-password(Change Password)로 강제 redirect 하므로, 환경 점검 진입 자체가 비밀번호 변경 완료 후다. 즉 비번 변경이 환경 점검보다 먼저다.

운영사측 매장 등록(/stores/new, SPEC #011)의 “Store Onboarding” 과는 별개 화면이다. 이쪽은 점장이 본인 매장 PC에서 수행하는 재생 환경 점검이다.

범위: 환경 점검 4항목 + 진행 저장 + “다음으로”→/store/onboarding/intro(간단 소개). intro·start 스텝은 SPEC #110 으로 구현됨(/store/onboarding/intro·/store/onboarding/start). 환경 점검 통과 시 “다음으로” 는 곧장 /store 가 아니라 intro 로 체이닝한다(비번변경 → 환경점검 → 간단소개 → 음악시작 풀 플로우). 완료 플래그(done)는 환경 점검이 아니라 마지막 start 화면에서 저장한다.

구성 (server 셸 + client)

  • app/store/onboarding/page.tsx — server 셸(force-dynamic). 본문(OnboardingClient)만 렌더. role 가드는 app/store/layout.tsx(STORE_MANAGER, SPEC #050 §F1)가 담당(추가 가드 없음).
  • app/store/onboarding/onboarding-client.tsx — client. 브라우저 측정·Web Audio·진행 저장 보유.
  • app/store/onboarding/onboarding-shared.tsx공유 atom(SPEC #110): Stepper(4단계 done/current/ todo 파생)·storageKey·진행 저장(readProgress/mergeProgress)·슬림 BrandHeader·PrimaryButton. env-check·intro·start 가 함께 쓴다(atom-grounded 임시 — 시안 부재).
  • useGetStoreMe(GET /api/v1/store/me) — 헤더 매장명(name). 5xx/네트워크 시 “내 매장” 폴백.

환경 점검 4항목

시안의 하드코딩 목업값(Chrome 124.0 · 245Mbps 등)을 실제 브라우저 측정으로 대체했다. 브라우저에서 OS 절전 상태·실제 스피커 출력은 측정 불가이므로 해당 항목은 안내 + 수동 확인으로 처리.

#항목방식판정(시안 보강 상태)
1브라우저 종류자동navigator.userAgent 로 Chromium(Chrome Chrome/ · Edge Edg/) 감지. Chrome/Edge → pass + 버전. 그 외(Safari·Firefox·Opera 등) → faildanger 톤 보더·아이콘 + “확인 필요” 배지, value 에 실제 브라우저명(예 “Safari 17”), “Chrome 또는 Edge에서 열어주세요”. fail 이면 4/4 불가라 진행 차단 + 푸터 danger 안내.
2절전 모드수동 확인OS 절전모드는 브라우저가 측정 불가. value “직접 확인 필요” → 안내(“PC가 자동으로 꺼지지 않게…”) + [확인했어요] 버튼으로 pass(“확인했어요 ✓”). 매장 id 확정 전엔 버튼 라벨 “매장 정보 불러오는 중…” + disabled.
3스피커 연결반자동·3단계idle([소리 테스트]) → playing(“재생 중…” · 아이콘 glow 박동, 버튼 disabled) → confirm([다시]/[소리가 들렸어요]) → pass(“소리 들렸음 ✓”). Web Audio API 로 440Hz 사인파 1초 재생, AudioContext 는 사용자 제스처 안에서 생성·resume(~1.1s 후 confirm 전이). [다시] 는 idle 복귀. AudioContext 미지원(jsdom 등) 시 graceful fallback — 신호음 없이도 단계 전이·확인 버튼 노출.
4인터넷 연결자동(best-effort)navigator.connection 있으면 downlink(Mbps) 표시. downlink < 10 → pass 하되 warn 톤 + “주의” 배지 “연결이 느려요 — 음악이 가끔 끊길 수 있어요”. navigator.connection 미지원이면 value “측정 미지원” · “이 브라우저는 속도 측정을 지원하지 않아요 · 연결 양호로 가정합니다” 로 pass.

권장 다운링크 임계값은 10Mbps(RECOMMENDED_DOWNLINK).

행 톤(data-tone)은 fail(danger·“확인 필요” 배지) > warn(주의 배지) > pass(success) > neutral 순으로 분기하며, fail/warn 등 동적 color-mix 색은 inline style 로 적용(Tailwind arbitrary 회피). “재생 중” glow 는 .lm-onboarding-glow(globals.css · prefers-reduced-motion 시 정지).

진행 동작

  • 통과 게이트: 4항목 모두 pass 여야 푸터 “다음으로” 활성. 미달 시 disabled + “먼저 모든 항목 통과”. 통과 카운트(passed/4)를 푸터에 표시.
  • 진행 저장(localStorage): 매장별 키 lm_space_onboarding:<storeId>(미확정 시 :unknown)에 수동 항목(power·speaker) 통과를 저장. 자동 항목(browser·net)은 마운트 시 재측정하므로 저장하지 않는다. 새로고침 시 수동 항목을 복원해 재개한다. 완료 플래그(done)는 환경 점검이 아니라 마지막 start 화면에서 저장한다(SPEC #110 — 같은 키 done).
  • 다음으로: router.push("/store/onboarding/intro") — 간단 소개로 체이닝(SPEC #110). 환경 점검은 done 을 저장하지 않는다.
  • 이전: /store 로 이동.

간단 소개·음악 시작 (SPEC #110 · intro/start)

환경 점검 다음 두 스텝. design_handoff_linkmusic_10 시안 정합 완료 (design/screens/store-onboarding-intro-start.jsx). 동작·라우팅·완료플래그·testid·접근성은 100% 보존하고 시각만 교체(style(space)). 슬라이드 문구는 시안 INTRO_SLIDES(PRD Page 9) 그대로. onboarding-shared.tsx 의 Stepper·헤더·버튼(PrimaryButtoniconRight·size="lg" 확장)·진행 저장을 재사용.

  • 간단 소개(/store/onboarding/intro, intro-client.tsx) — 4슬라이드 캐러셀(FR-9.3): 점 인디케이터 + [이전](ChevronLeft·첫 슬라이드 disabled)/[다음](primary 그라데이션·ChevronRight) + 헤더 [건너뛰기](저강조 보더 텍스트 버튼·항상 노출). 4슬라이드(🎵 자동 재생 / 🎙 즉시 방송 / 🚨 긴급 체크 / 🔄 재시작), emoji 6480px·제목 2630px·본문 18px(40~50대 가독성). 슬라이드 3(긴급) = warn 톤 차등: warn 보더·배경 + “긴급 상황 한정” StatusPill(warn) + danger 경고 박스(AlertTriangle). 마지막 슬라이드 [시작 준비 완료] 또는 [건너뛰기] → start.
  • 음악 시작(/store/onboarding/start, start-client.tsx) — 준비 완료 확인(FR-9.4): 큰 success 원(120px·glow 박동) + 🎉 PartyPopper + “준비가 끝났어요!”(30~36px) + 체크리스트 3줄 (원형 success 체크 배지). [음악 시작하기](64px 큰 탭·Music 아이콘) → 완료 플래그(done:true) 저장 + router.push("/store")(player 홈 자동재생 진입). 매장 id 미확정 시 버튼 disabled(:unknown 키 desync 방지). Stepper 4단계 current=start.
  • BE 미연동: PATCH /api/store/me/onboarding-complete·환경 체크 이력(FR-9.5)은 BE 미구현 → 완료는 localStorage done 으로만 추적(후속 SPEC 으로 분리).

시안 대비 차이 (목업값 대체 · 브라우저 한계)

  • 시안의 고정 “Chrome 124”/“Safari 17” → 실제 UA 파싱 버전·브라우저명. fail 행도 실제 비-Chromium 브라우저명을 best-effort 추출(Safari·Firefox·Opera, 그 외 generic).
  • 시안의 고정 “245 Mbps · 핑 18ms” → navigator.connection.downlink/effectiveType 실측. 핑(18ms)은 브라우저에서 측정 불가라 표시 생략(effectiveType 로 대체). 미지원 시 “측정 미지원 · 양호 가정” 폴백.
  • 절전 모드는 시안 supplement 와 동일하게 수동 확인 버튼(브라우저가 OS 절전 측정 불가). 시안의 시연 토글(SupToggle·netMode select)은 데모 전용이라 옮기지 않고 실제 측정으로 구동.
  • 스피커 3단계·인터넷 warn/폴백·브라우저 fail 의 시각(톤·배지·glow)은 supplement 시안 정합.
  • 데모용 래퍼(Artboard·BrandLockup·ThemeToggle)는 옮기지 않고 store-player-client 의 슬림 헤더(TopBar) 스타일로 치환. 아이콘은 lucide-react(Chrome·Power·Volume2·Wifi·Check· CheckCircle2·ChevronRight·RefreshCw·AlertTriangle).

인가·세션

/store/*app/store/layout.tsx(server)가 STORE_MANAGER role 가드를 담당(세션 없음→/login, HQ_MANAGER→/admin, 그 외→fail-closed /login). 본 화면은 추가 가드 불필요.

PRD FR-9.2 대비 드리프트(명시)

PRD FR-9.2 / FR-9.2-1 / FR-9.2-2 는 서버 측 device-check 를 요구한다 — POST /api/store/maintenance/device-check(30-TRD §7-7-5)로 RAM·브라우저 종류·해상도·인터넷 속도를 자동 측정하고 기준 미달 시 빨간 배지 + 즉시 차단(브라우저)·경고(RAM·해상도), 온보딩 이력 기록(FR-9.5). 현 구현은 BE device-check 부재로 이를 클라이언트 best-effort 측정·경고로 축소했다.

FRPRD 요구구현 현황
FR-9.2-1 자동 측정(RAM·해상도)device-check 응답 배지미측정(RAM·해상도 항목 없음 — 브라우저 한계)
FR-9.2-1 인터넷 속도서버 측정값navigator.connection.downlink best-effort(미지원 시 양호 가정 pass · 느림 시 warn 배지)
FR-9.2-2 브라우저 자동 차단진행 불가 + Chrome 링크 안내fail 톤(danger 보더·아이콘) + “확인 필요” 배지 + 4/4 불가로 게이트 + 푸터 danger 안내. 단 강제 차단은 클라 측 게이트 수준(서버 enforcement 부재)
FR-9.5 환경 체크 이력서버 기록미기록localStorage 진행 저장만

서버 device-check 도메인 도착 시 자동 차단·RAM/해상도·이력 기록을 후속 SPEC 에서 보강한다. 전 화면 대응은 Store Surface Matrix 참조.

미구현 / 후속

  • Stepper intro(간단 소개)·start(음악 시작) 스텝 화면구현됨(SPEC #110) + design_handoff_linkmusic_10 시안 정합 완료(위 “간단 소개·음악 시작” 섹션).
  • 절전·스피커의 자동 측정(브라우저 한계로 불가 — OS 연동 시 가능).
  • 서버 device-check(POST /api/store/maintenance/device-check) — RAM·해상도·자동 차단·이력 기록(위 드리프트 표).
  • 온보딩 완료 BE 연동(PATCH /api/store/me/onboarding-complete·환경 체크 이력 FR-9.5) — 현재 localStorage done 만(후속 SPEC).