RoomfitV2 B2B — 시나리오 Studio 앱 (트레이너 / 오너용) 전체 흐름 · 2026-04-19 기준

2026-04-19
커밋: bb282e5 (HEAD), a162281, 6613056
브랜치: main · origin보다 14 ahead
2
Apps
7
Shared Packages
11
Studio Screens
97/97
Tests Pass
21
Supabase RLS Policies
2-App 아키텍처 pub workspaces · 듀얼 앱 모노레포

📱 apps/b2c — 회원용

name: roomfit_v2
개인 회원이 자기 운동을 직접 기록 (self 세션). VBT 측정, ROM, RPE/RIR, 세션 히스토리.
member (개인)

🏋️ apps/b2b — Studio (트레이너 / 오너)

name: roomfit_studio
PT 샵 운영 + 트레이너가 회원 수업 기록 (supervised 세션). Stage 1 수동 입력 + Stage 2 BLE-live VBT.
owner trainer shadow (초대만 받음)
공유 패키지 (양쪽 앱이 import)
roomfit_protocol roomfit_device roomfit_ble roomfit_exercise roomfit_workout roomfit_shop roomfit_firmware design_system
4 Persona × 진입 시나리오
Role 진입점 핵심 시나리오
Owner apps/b2b 로그인 → 샵 없음 → CreateShopScreen 샵 1개 생성 (ownership 1:1 보장 — DB CHECK) → ShopHomeScreen에서 trainer / member 초대 → 모든 supervised 세션 기록 열람.
Trainer apps/b2b 초대 수락 → 로그인 → ShopHomeScreen 회원 리스트에서 한 명 선택 → MemberDetail → "수업 시작" → BLE 라이브 또는 수동 기록 선택.
Member (가입) apps/b2c 개인 가입 또는 초대 수락 → 로그인 자기 휴대폰으로 직접 운동 기록 (self 세션). 트레이너가 기록한 supervised 세션도 같은 회원 데이터 owner 로 RLS 통과해서 본다.
Member (shadow) — (미가입) 트레이너가 이메일로 초대만 함 아직 가입 안 한 회원 — DB에 shadow row만 존재. 트레이너는 supervised 기록 가능. 가입 시 shadow → active 전이가 필요 (pending).
Stage 2 BLE-Live Supervised Flow 트레이너가 회원 수업을 실시간 VBT 측정으로 기록
📡 Stage 2 — BLE 라이브 VBT (이번 세션 신규)
📝 Stage 1 — 수동 기록 (대안)
1
회원 선택
MemberDetail
FAB 탭 → "BLE 라이브 수업"
2
기기 스캔
ScanScreen
Roomfit / WeSpion BLE 검색 → 탭 → 연결
3
컨텍스트 시드
LiveWorkoutFlow
member / trainer / center ID 를 liveWorkoutContextProvider 에 주입
4
운동 선택
ExerciseSelect
65개 카탈로그 + 그립 선택. session 시작.
5
실시간 측정
LiveWorkout
20Hz 모션 → FSM rep detection → MCV / ROM / Power 라이브.
6
세트 종료
PostSetSheet
RPE / RIR 입력 (Zourdos auto-pair).
7
세트 요약
SetSummary
VL%, Avg MCV, ROM. "다음 세트" / "수업 종료".
8
세션 마무리
SessionSummary
Foster sRPE + mood. finalizeSession 호출.
BLE 커맨드 시퀀스 (Studio → 기기) — SetExecutor.startSet 실제 순서
t = 0ms → OUT StartReportCommand 20Hz 36B dev report 스트림 시작
+10ms → OUT SetWeightModeCommand(L=mode, R=mode) picker가 normal 외 모드 선택 시 송출 (PR #45)
+20ms → OUT SetAutoWeightCommand(isActive=1) 자동 무게 모드 활성
+30ms → OUT SetWeightPowerCommand(onOff=1) 모터 전류 ON → 사용자 체감 저항 시작
+50ms~ ← IN ReportResponse 0x41 (반복, 50ms 주기 / 36B) position, speed, accel, icmd, ifb, fLoad, region…
세트 중 → OUT AdjustWeightCommand ±0.5/5kg 트레이너가 SetControlBar에서 조정 (PR #46)
완료 시 → OUT StopReport → SetAutoWeight(0) → SetWeightPower(0) graceful 종료 (cutoffTrigger=user/velocity_loss_30/...)
비상정지 → OUT EmergencyStopCommand 0x64 단일 패킷 + forceComplete (cutoffTrigger=timeout)
데이터 플로우 RLS / 컨텍스트 주입 / 누가 owner 인가

📡 BLE 기기

물리 모터
20Hz 36B report
flutter_blue_plus

🏋️ Studio 앱

SessionManager
+ liveWorkoutContext
(member/trainer/center)
supabase-flutter

🗄️ Supabase (7 tables)

workout_sessions ▸
exercise_entries ▸
exercise_sets ▸
reps ▸
rom_estimates ▸
load_velocity_profile ▸
rep_detection_run
DOC-02 정정: Stage 2 finalize 시 위 7개 테이블 모두에 INSERT. PR #41 RLS hardening 으로 LVP / wellness / rep_detection_run 도 supervising trainer write 허용 (이전엔 거부됨).
핵심: 기록자 ≠ owner. 트레이너가 작성하지만 데이터의 user_id는 항상 회원. PR #41 immutable trigger 가 INSERT 후 user_id/trainer_id/center_id/session_type 변조 차단. DB CHECK supervised_requires_trainer 가 supervised 세션에 trainer_id 누락 방지.
실행 모드 실기기 없이도 풀 플로우 검증 가능

🟡 DEV_MODE

--dart-define=DEV_MODE=true
  • MockDeviceGateway 가 실제 BLE 대체 (20Hz 합성 모션)
  • Supabase + auth 우회 → DevHomeScreen 직진입
  • 고정 mock IDs (dev-member-001 / dev-trainer-001 / dev-center-001)
  • 워크아웃 repo 는 InMemoryWorkoutRepository
  • E2E 통합 테스트 (5/5) 가 이 모드에서 실행

🟢 PROD

--dart-define=SUPABASE_ANON_KEY=...
  • 실제 Roomfit / WeSpion BLE 연결 (flutter_blue_plus)
  • 로그인 → role gate → owner / trainer 만 진입
  • SupabaseWorkoutRepository + SupabaseLvpRepository 오버라이드
  • RLS 가 cross-shop 데이터 접근 차단
  • shadow 회원 자동 생성 (이메일 초대로)
완료 / 검증 / 미완료 현황
기능 상태 검증 커밋 / 메모
DB 마이그레이션 + RLS 21정책 ✓ DONE Supabase MCP 20260419004009 + 20260419004112
공유 패키지 추출 (roomfit_workout / roomfit_shop) ✓ DONE 27+90 unit 99d624c · ff47985
Stage 1 수동 supervised 기록 ✓ DONE 2/2 widget f2cc074
Stage 2 BLE-live VBT supervised 흐름 ✓ DONE 5/5 E2E + grep 6613056 · 21 신규 파일
Mock device gateway + DevHome (b2b) ✓ DONE 실기기 없이 가동 a162281
E2E 통합 테스트 (DevMode 기반) ✓ DONE 5/5 Android bb282e5 · Riverpod 위반 1건 수정
Shadow user claim flow ⌛ PENDING Supabase Auth hook 필요. shadow → active 전이.
B2C "Studio 앱 받기" 프로모 배너 ⌛ PENDING 회원 앱 사용자 중 샵 멤버십 없는 케이스 타겟.