UiTrainingStyleScreen props (운동 타입 변경)
2026-09-15 개정(이슈 #1633): 사용자 문구 "직업" → "운동 타입". 진입점은 메뉴 드로어의 "직업 변경" 행에서 내 정보 화면 PROFILE 그룹의 "운동 타입" 행으로 옮겼고, 유형은 8종 → 9종(그래플러 추가), "기능성 트레이너"는 "스트렝스 훈련가"로 개명(id
functional유지). 선택 화면 상단 설명 두 줄은 삭제.
화면 픽스처(앱 저장소):
src/react/ui/mobile/fixtures/TrainingStyleScreen.fixture.ts
내 정보 화면 PROFILE 그룹의 "운동 타입 · 현재 운동 타입명 · ›" 행(hook mobileProfileTrainingStyle, 내 정보 화면 props onOpenTrainingStyle)에서 연 탭 위에 쌓는 전체 화면이다. 구 메뉴 드로어 ACCOUNT 그룹의 "직업 변경" 행과 드로어 onTrainingStyle 계약은 2026-09-15에 삭제됐다. recordsTool 스택 항목의 tool="trainingStyle"로 관리하고 공용 스택 셸이 뒤로가기·스와이프·퇴장을 맡는다. 온보딩과 같은 9종 카드·자산·표시 순서를 사용한다(그래플러는 마지막). 화면 상단에는 제목 "운동 타입"만 있고 설명 문단은 없다. 선택·확인 모달 상태는 화면, 저장·프로필 갱신·기준표 재적재는 controller가 소유한다.
저장과 등급
- 2026-09-08 사용자 확정:
powerlifter,olympic,bulkup,bodyweight,gymnast,metcon,ironman,functional8종을 온보딩 및 완료 후 직업 변경에서 실제 저장한다. 2026-09-15(이슈 #1633)grappler추가로 9종 — DBprofiles.primary_training_styleCHECK 와update_profile_settings_v1·complete_onboarding_v4의 허용 목록을 같은 마이그레이션(20260915220100_training_style_grappler.sql)으로 확장했다(기존 값 보존·추가만). 이름·설명(앱 카피 원본): 아이언맨 "러닝, 수영, 사이클 같은 유산소 훈련의 보조 운동으로써 중량 운동을 진행합니다." · 스트렝스 훈련가(구 기능성 트레이너, idfunctional) "주로 하는 종목의 퍼포먼스 향상을 위해 중량 훈련을 진행합니다." · 그래플러 "그래플링 종목의 보조운동으로서 중량 운동을 진행합니다." PrimaryTrainingStyle과MOBILE_EXPERIENCE_COPY.onboarding.trainingStyles가 canonical id·이름·설명을 소유한다.trainingStylesForView는 건강한 운동인을 첫 번째로 표시하며trainingStyleArt는 각 id의 자산을 공급한다. 알려지지 않은 id는 사용자에게 노출하지 않는다.- 카드 선택 → 확인 모달 → 변경 버튼 →
profileController.saveProfileTrainingStyle→BarbelicApi.updateProfileSettings({ primaryTrainingStyle })→update_profile_settings_v1순서다. 성공 응답의 본인 profile만 적용하고 기존 기록 기준표를 다시 읽는다. - 저장 완료 전에는 현재 카드를 낙관적으로 바꾸지 않는다. 저장 중 버튼을 잠그며 null/false 응답 또는 reject는 오류로 처리한다. (2026-09-14 개정) 성공 시 확인 모달은 즉시 닫히고 완료 알림은 컨테이너 토스트 1회(kind
save, 문구 "운동 타입을 변경하였습니다" — 2026-09-15 개명 전 "직업을 변경하였습니다")가 맡는다 — 구 "변경했습니다" 완료 단계(같은 모달 1.4초 자동 닫힘)와 "컨테이너 성공 토스트 생략"은 폐지(완료 피드백 공통 규칙: 질문 = 모달, 결과 = 토스트).saveProfileTrainingStyle성공 경로가 이 토스트를 발행한다. 실패 응답에는 성공 토스트를 발행하지 않는다. - 운동 타입 변경은 기존 공통 레벨·XP와 기록 등급 정책을 그대로 유지한다. 아이언맨·스트렝스 훈련가·그래플러의 별도 등급 공식, 수영·러닝·사이클 기준표는 만들지 않는다. 아이언맨·스트렝스 훈련가의 온보딩 1RM 목록은 비어 있고 그래플러는 바벨 4종(전제, 2026-09-15)이며, 운동 기록은 기존 종목 기록 기능을 사용한다. UI 문구도 등급 재산정을 약속하지 않는다.
- 서버 입력·권한·부분 저장 의미론은 프로필 원자 저장 계약을 따른다.
화면 props
| prop | 형태 | 설명 |
|---|---|---|
profile? | { name? } | 제목의 사용자 이름 |
trainingStyle? | PrimaryTrainingStyle | "" | null | 현재 저장된 운동 타입. 현재 배지와 선택 상태의 기준 |
onChangeTrainingStyle?(id) | (id: PrimaryTrainingStyle) => Promise<unknown> | 변경 확인 후 호출. 없으면 카드 disabled |
error? | string | null | 컨테이너 오류. 로컬 오류보다 우선 표시 |
onBack? | () => void | 공용 스택 셸의 뒤로가기. 있으면 다른 기록 도구와 같은 워드마크 행 버튼을 표시 |
mobileApp.tsx는 trainingStyle={profileProps.primaryTrainingStyle}, onChangeTrainingStyle={saveProfileTrainingStyle}를 공급한다. 내 정보 화면의 onOpenTrainingStyle(컨테이너 MobileProfileBinding)이 스택 항목을 연다 — 2026-09-15부터 드로어에는 이 항목이 없다. 이동 규칙은 화면 스택 계약을 따른다.
홈 연동
홈의 trainingStyle도 같은 profile prop을 받아 운동 타입명을 표시한다(알려지지 않은 id 의 표시명은 "운동 타입"). 레벨은 기존 공통 XP 계산, 기록 등급은 기존 종목별 기준을 사용한다. prDisciplines[].styleId가 제공되면 해당 기록 보드를 선택하며, 별도 운동 타입 기준표가 없는 경우 기존 공통 기록 보드를 유지한다. 운동 타입 선택이 기록 원본·등급 정책·기존 레벨을 재작성하지 않는다.
마커
hook mobileTrainingStyle·mobileTrainingStyleConfirm, 카드 role="radio", 현재 data-lg-state="selected", data-lg-option-value는 canonical id. action profile.trainingStyle.open·profile.trainingStyle.save를 사용한다.