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)은/storelayout 가드가/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 등) → fail — danger 톤 보더·아이콘 + “확인 필요” 배지, 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·헤더·버튼(PrimaryButton — iconRight·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 미구현 → 완료는 localStoragedone으로만 추적(후속 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 측정·경고로 축소했다.
| FR | PRD 요구 | 구현 현황 |
|---|---|---|
| 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) — 현재 localStoragedone만(후속 SPEC).