OPEN BETA EVENT

2026.5.1 (금) ~ 5.31 (일)

IRON ARM x 아이코치
부문별 최고의 선수를 선발합니다!
분석왕
분석 횟수 1위
타자왕
타격 점수 1위
투수왕
투구 점수 1위
수비왕
수비 점수 1위
제보왕
버그제보 1위
훈련왕
능력 상승 1위

프로야구 선수 싸인볼

원하는 선수에 원하는 이름으로
받아서 선물로 드립니다!

🏆 오픈베타 이벤트 수상자 발표 🏆

🎉 축하합니다!

수상 상품(프로야구 선수 싸인볼)을 받으시려면
아래 연락처 정보를 입력해주세요

아이코치 β 1.4.68

AI BASEBALL FORM COACH

업데이트 노트

β 1.4.68 2026.05.16
  • 모드 헤더 배너 추가 — 투구·타격 분석 안내 화면 상단에 모드별 일러스트 배너 노출. 사용자가 지금 어떤 모드에 들어왔는지 시각적으로 즉각 인지 가능 → 모드 혼동(글러브 영상을 타격에 올리는 등) 사전 방지에도 도움.
  • 이미지 최적화 — 원본 PNG 7.5MB → WebP 1200px polish 80KB대로 압축. 모바일 데이터 부담 없음. images/headers/ 폴더로 정리.
  • 적용 범위 — 투구·타격 모드만 노출. 수비(내야/외야/포수) 모드는 배너 숨김 처리.
  • 서비스 워커sw.js ASSETS_TO_CACHE에 헤더 이미지 2장 추가, CACHE_NAME icoach-v207icoach-v208 갱신.
β 1.4.67 2026.05.11
DRILL VERIFY · CRITICAL BUG FIX
  • 훈련 인증 "0/6프레임" 오류 근본 원인 수정preVerifyDrillVideoLocal() 이 VIDEO 모드로 생성된 poseLandmarker 에 IMAGE-모드 전용 메서드 .detect() 를 호출해서 매 프레임 silent failure 발생. try/catch 가 에러를 삼키고 결과를 null 로 처리 → 검출 0건 → "0/6프레임. 전신이 보이도록 다시 촬영" 오해 유발.
  • 같은 패턴 버그 2곳 추가 수정quickDrillAnalysis() (드릴 영상에 즉시 관절각도 표시) · analyzeDrillVideo() (다중 프레임 드릴 폼 분석) 도 동일하게 .detect() 잘못 호출. 두 함수 모두 silent failure 로 항상 null 반환 → 드릴 폼 분석 결과 미표시 버그가 있었으나 오류 메시지 없이 묻혀 있었음. 이번 릴리스에서 함께 수정.
  • 증상 조건 — 같은 세션에서 영상 분석(폼 분석)을 한 번이라도 돌린 다음 드릴 인증을 시도할 때 100% 발생. 앱을 새로 켜고 바로 드릴 인증을 시도하면 poseLandmarkernull 이라 사전검증을 스킵해서 통과됨(그래서 일관성 없게 보이는 버그였음).
  • 해결 방식 — landmarker 생성 3곳(영상 분석 2곳·실시간 1곳)에 window._poseLandmarkerMode 추적 변수 도입. 사전검증에서 모드를 읽고 분기: VIDEO 모드면 detectForVideo(canvas, ts) 호출(단조증가 ms 타임스탬프 전달), IMAGE 모드면 detect(canvas), LIVE_STREAM 모드면 사전검증을 스킵하고 Gemini 검증으로 위임.
  • 타임스탬프 안전성performance.now() 를 베이스로 사용, 프레임마다 +100ms 증가. 페이지 로드 후 항상 증가하는 값이라 영상 분석이 이미 사용한 어떤 타임스탬프 범위와도 충돌하지 않음.
  • 진단 로그 추가catch(e) 블록에 console.error 추가. 같은 종류의 silent failure 가 다시 생기면 콘솔에서 즉시 식별 가능 (이전엔 영구히 묻혀 있었음).
  • 분석 점수에 영향 없음 — 이 수정은 드릴 인증 사전검증만 손대고 메인 분석 흐름은 그대로 유지.
  • 캐시 버전 v206→v207 — 배포 후 PWA 강제 업데이트 권장.
β 1.4.66 2026.05.11
ANALYSIS · MODE MISMATCH
  • 글러브 끼고 던지는 영상에 "스윙(타격) 감지" 오탐 제거checkModeMismatch() 의 투구 모드 검증을 4-조건 AND 로 강화. 기존 (swingR>0.3, oneArmR<0.1) 두 조건만으로는 측면 카메라 와인드업이 양손 중심점을 어깨너비 1.5배 넘게 이동시켜 오탐 발생.
  • 배트 휘두르는 영상에 "투구 동작 감지" 오탐 제거 — 타격 모드 검증에 손목 X 이동 비대칭 게이트 추가. 배트로 풀스윙하면 양손이 함께 회전 → 비대칭 낮음 → 경고 스킵.
  • 신규 지표 2개 도입 — (1) peakArmExtension: 영상 전체에서 한 팔이 어깨너비 대비 가장 멀리 뻗은 비율 (피크값). 한 프레임이라도 어깨×2 이상 뻗어지면 투구로 인정. (2) wristAsymmetryX: 좌·우 손목 X 이동 범위의 비대칭도(0~1). 0에 가까우면 배트 그립처럼 두 손이 함께 움직임, 1에 가까우면 던지는 팔만 멀리 이동.
  • 새 임계값 — 투구 모드 스윙 경고: swingR>0.5 & oneArmR<0.05 & peakArmExtension<2.0 & wristAsymmetryX<0.35. 타격 모드 투구 경고: oneArmR>0.35 & swingR<0.05 & wristAsymmetryX>0.4. 모두 AND.
  • 크롭(_icoachCropActive) 임계값 — 0.5 → 0.7 로 더 보수적으로 조정. 줌인 영상에서 false-positive 가능성을 추가로 낮춤.
  • 분석 점수에는 영향 없음 — 이 변경은 모드 불일치 안내 경고만 강화한 것. 점수 산출 로직은 그대로.
  • 캐시 버전 v205→v206 — 배포 후 PWA 강제 업데이트 권장.
β 1.4.65 2026.05.01
SETTINGS · CLEANUP
  • 설정 화면 "이벤트 안내 다시 보기" 카드 제거 — 새 픽셀 아트 아이콘 적용 검증용으로 추가했던 임시 카드를 정리. 이벤트 팝업은 정상 작동 중이며 자정 지나면 자동 재노출되므로 영구 카드는 불필요.
  • 관련 함수는 보존showEventPopupForce(), _isEventPeriod()는 코드에 남겨둠. 향후 동일 카드 재추가 시 즉시 활용 가능.
  • 캐시 버전 v204→v205 — 배포 후 PWA 강제 업데이트 권장.
β 1.4.64 2026.05.01
UI · EVENT POPUP ICONS
  • OPEN BETA EVENT 팝업 7개 아이콘 — 픽셀 아트 전용 이미지로 전면 교체 — 부문별 의미가 직접적으로 보이도록 16-bit 픽셀 아트 전용 이미지를 새로 생성해서 7개 모두 교체. 분석왕(트로피+차트), 타자왕(스윙 임팩트), 투수왕(화염구), 수비왕(다이빙 캐치), 제보왕(돋보기+버그), 훈련왕(덤벨+레벨업), 싸인볼(사인 야구공).
  • 이미지 최적화 — 4MB+ 원본을 256×256 PNG로 리사이즈 + 압축 → 각 평균 70KB. 7개 합쳐 약 510KB.
  • 아이콘 사이즈 확대 36→48px — 픽셀 아트 디테일이 잘 보이도록 키움. 싸인볼 20→24px.
  • iconMap 신규 키 7개EVENT_ANALYST · EVENT_BATTER · EVENT_PITCHER · EVENT_DEFENDER · EVENT_BUG · EVENT_TRAINER · EVENT_SIGNBALL. 기존 TROPHY · BATTING · FIRE 등은 다른 화면에서 그대로 사용.
  • sw.js 캐시 자산 7개 추가 — PWA 오프라인에서도 정상 표시.
  • 캐시 버전 v203→v204 — 배포 후 PWA 강제 업데이트 권장.
β 1.4.63 2026.05.01
SETTINGS · EVENT REPLAY
  • 설정 화면에 "이벤트 안내 다시 보기" 카드 추가 — 한 번 닫은 OPEN BETA EVENT 팝업을 다시 띄우려면 콘솔 명령이나 자정까지 대기가 필요했습니다. 이번 버전부터 설정 → "이벤트 안내 다시 보기" 버튼 하나로 바로 재노출.
  • 이벤트 기간 중에만 표시 — 2026.5.1 ~ 5.31 기간 동안에만 카드 노출. 기간 외엔 자동 숨김 (코드는 그대로 유지하되 미표시).
  • showEventPopupForce() 신규 함수 — today 차단 키를 제거한 뒤 showEventPopup() 호출. 일회성 강제 표시이지만 닫을 때는 다시 일반 동작.
  • 캐시 버전 v202→v203 — 배포 후 PWA 강제 업데이트 권장.
β 1.4.62 2026.05.01
UI · EVENT POPUP UX
  • 이벤트 팝업 "확인" 버튼이 "오늘 그만 보기"와 동일 동작하던 버그 수정 — 기존 closeEventPopup()이 "확인"·"오늘 그만 보기" 어느 쪽으로 닫혀도 무조건 today 키를 localStorage에 저장 → 한 번이라도 확인을 누르면 그날은 팝업이 다시 안 뜸. 사용자 의도는 "확인=일단 닫기, 다음 진입 시 또 보기" / "오늘 그만 보기=오늘은 더 안 보기" 가 분리되어야 정상.
  • 함수 분리closeEventPopup(): 단순 닫기(키 저장 X) · dismissEventPopupForToday(): 오늘 그만 보기 전용(키 저장 O). "확인" 버튼은 단순 닫기, "오늘 그만 보기" 버튼만 today 키 저장.
  • 이전 버전에서 저장된 키 정리 안내 — β 1.4.62 이전에 "확인"을 눌러 차단된 사용자는 콘솔에서 Object.keys(localStorage).filter(k=>k.startsWith('icoach_event_popup_')).forEach(k=>localStorage.removeItem(k)) 입력해 키 제거 가능 (또는 자정 지나면 자동 해제).
  • 캐시 버전 v201→v202 — 배포 후 PWA 강제 업데이트 권장.
β 1.4.61 2026.05.01
UI · EVENT POPUP
  • OPEN BETA EVENT 팝업 7개 이모지 → 앱 아이콘 교체 — 기존 시스템 이모지(🏆⚾🔥🧤🐛💪🏅)는 OS·기기마다 모양이 달라 일관된 느낌이 없었습니다. 이번 버전부터 앱 내에서 사용하는 전용 생성 이미지 아이콘으로 교체해서 브랜드 톤이 통일됐습니다.
  • 매핑: 분석왕→TROPHY, 타자왕→BATTING, 투수왕→FIRE, 수비왕→HOME_FIELDING, 제보왕→bug_report, 훈련왕→MUSCLE, 싸인볼→GIFT.
  • iconMap 확장BUG_REPORT 신규 키 추가(./icon_bug_report.png 매핑). sw.js 캐시 자산 목록에 이미 등록돼 있어 PWA 오프라인에서도 정상 표시.
  • 캐시 버전 v200→v201 — 배포 후 PWA 강제 업데이트 권장.
β 1.4.60 2026.05.01
UI · COPY
  • OPEN BETA EVENT 팝업 안내 문구 줄바꿈 적용 — 프로야구 선수 싸인볼 안내 문구가 한 줄로 길게 흘러 가독성이 떨어졌습니다. "원하는 선수에 원하는 이름으로" / "받아서 선물로 드립니다!" 두 줄로 정리.
  • 캐시 버전 v199→v200 — 배포 후 PWA 강제 업데이트 권장.
β 1.4.59 2026.04.29
DATA · AGE EXPANSION (PREP)
  • 14~19세 평균 데이터·보정 비율 사전 정의 (드롭다운은 13세까지 유지) — 현재 "아이코치"는 컨셉상 만 7~13세(초1~중1)만 다루지만, 향후 확장 시 즉시 작동하도록 로직과 데이터를 미리 깔아 두었습니다. 드롭다운에 14세 이상 옵션을 추가하기만 하면 별도 코드 수정 없이 정확한 평균 비교와 점수 보정이 적용됩니다.
  • getAgeAvg — 14~19세 평균 데이터 추가 — 사춘기 급성장(중2~중3) → 고등학생(고1~고3) → 성인(19세) 진입까지 6개 항목(힘·속도·정확도·밸런스·유연성·폼완성도) 평균을 점진 곡선으로 정의. 예: 만 14세 힘=82(13세 78), 만 18세 힘=94, 19세 힘=95.
  • scoreRange — 보정 비율 점진 감소 곡선 — 기존 7~9세 25% / 10~11세 15% / 12~13세 8% 에 더해 14~15세 4% / 16~18세 2% 추가. 19세 이상은 성인 기준 그대로(보정 없음). 13→14세 경계에서 점수가 급격히 떨어지지 않게 부드러운 곡선 유지.
  • 주의 — UI에서는 13세까지만 노출 — "아이코치" 정체성을 신중히 유지. 향후 14세 이상 확장이 결정되면 inp-age 드롭다운에 옵션만 추가.
  • 캐시 버전 v198→v199 — 배포 후 PWA 강제 업데이트 권장.
β 1.4.58 2026.04.29
SETTINGS · SOUND
  • 효과음 볼륨 슬라이더 + BGM 별도 토글 추가 — 그동안 설정 화면에서는 효과음 ON/OFF 토글 하나뿐이라 볼륨이 고정(30%)이었습니다. 이번 버전부터 효과음 볼륨 슬라이더(0~100%)로 직접 조절할 수 있습니다. 또한 분석 중 재생되는 배경음(BGM)을 효과음과 별도로 토글할 수 있고, BGM 전용 볼륨 슬라이더(기본 15%)도 추가됐습니다.
  • 설정 자동 저장 — 슬라이더 값을 움직이면 즉시 localStorage에 저장 (icoach_sound_volume, icoach_bgm_volume, icoach_bgm_enabled). 다음 실행에도 자동 적용.
  • UX 디테일 — 효과음 OFF 상태에서는 슬라이더가 비활성화(흐릿하게) 표시되어 상태가 명확. 슬라이더 조정 시 tap 효과음이 바로 재생되어 볼륨 미리듣기 가능.
  • 캐시 버전 v197→v198 — 배포 후 PWA 강제 업데이트 권장.
β 1.4.57 2026.04.29
DETECTION · THROWING ARM
  • V5 outlier 케이스 — 던지는 팔 자동 판별 강화 — β 1.4.39 분류기에서 마지막까지 남아 있던 V5 outlier(peakUp=170° 케이스)는 측정 자체는 정확했지만 "던지는 팔"을 잘못 선택해 글러브 팔의 코킹·정지 자세를 분석하면서 사이드암으로 오분류되던 문제였습니다. 기존엔 좌·우 손목의 x축 이동 범위 한 가지만 비교했기 때문에 글러브 팔이 코킹 자세에서 좌우로 흔들리면 던지는 팔로 오선택되는 케이스가 있었습니다.
  • 5개 지표 가중 합산 방식으로 교체 — (a) x 이동 범위 [가중 1.0] (b) y 이동 범위 [1.0] (c) 손목 최고 속도 = Δ(프레임 간 거리) 최대값 [1.5] (d) 어깨 위로 올라간 프레임 비율 [1.0] (e) 손목 visibility 평균 [0.5] 을 정규화 후 가중 합산. 종합 점수가 더 높은 쪽이 던지는 팔. 글러브 팔의 좌우 흔들림이 일부 점수에 영향을 줘도 피크 속도와 어깨 위 프레임 수에서 던지는 팔이 압도적이어서 거의 모든 케이스에서 정확히 선택됩니다.
  • 가시성 노이즈 차단 — visibility < 0.3 인 프레임은 측정에서 제외. 한 쪽 손목이 거의 가려진 영상에선 자동 fallback (반대 쪽 점수로 결정).
  • 관리자 진단 강화window.__icoach_throwarm_debug 글로벌에 종합 점수와 5개 raw 지표를 모두 노출. 관리자 콘솔에서 던지는 팔 오선택 의심 시 즉시 수치 확인 가능.
  • 캐시 버전 v196→v197 — 배포 후 PWA 강제 업데이트 권장.
β 1.4.56 2026.04.28
AI · DETECTION
  • 원거리 인물 감지 대폭 강화 — 자동 크롭 타일 9개→20개 확장 (3x줌 소형 타일 11개 추가). 극소 인물도 감지 가능. 관절 인식 임계값 완화로 먼 거리에서도 감지율 향상.
  • 저장 공간 경고 오탐 수정 — SW캐시가 포함되던 용량 계산을 localStorage 전용으로 변경. 저장 실패 시 자동 정리 후 재시도. 앱 시작 시 50%+ 자동 정리.
β 1.4.55 2026.04.28
STORAGE
  • 저장 공간 관리 대폭 개선 — 버전 백업 히스토리를 요약본으로 저장하여 용량 90% 절감. 오래된 분석 기록 자동 압축, 앱 시작 시 자동 정리, 더 공격적인 긴급 정리 로직.
β 1.4.54 2026.04.28
STABILITY
  • 점수 결정성 완전 확보 — 이중 시크 + 캔버스 스냅샷으로 프레임 디코딩 비결정성까지 제거. 모든 분석에서 캔버스에 먼저 그린 뒤 감지하여 동일 입력 보장.
β 1.4.53 2026.04.28
STABILITY
  • 점수 결정성 대폭 개선 — 같은 영상을 반복 분석해도 동일한 점수가 나오도록 타임스탬프 체계 전면 개편. poseLandmarker 재생성 + 고정 타임스탬프로 비결정성 제거.
β 1.4.52 2026.04.28
AI · DETECTION
  • 원거리 촬영 자동 크롭 — 사람이 작게 찍힌 영상에서 자동으로 인물 영역을 탐색하고 확대하여 분석. 실내 연습장 원거리 촬영 지원.
β 1.4.51 2026.04.28
AI MODEL
  • 포즈 감지 모델 업그레이드 — MediaPipe Lite → Full 모델로 변경. 원거리 촬영 영상에서도 인물 감지 정확도 대폭 향상.
β 1.4.50 2026.04.28
PROFILE
  • 가입 대상 연령 확장 — 만 13세(중1)까지 선택 가능. 연령별 평균 능력치 기준표에 13세 데이터 추가.
β 1.4.49 2026.04.27
SOUND · UX
  • 효과음 시스템 추가 — Web Audio API 기반 32종 효과음을 탭 전환·분석·훈련·채팅 등 주요 인터랙션에 매핑. 설정에서 ON/OFF 가능.
  • 저장공간 토스트 폭주 수정 — _lsEmergencyCleanup 세션당 1회 제한 + 토스트 대신 콘솔 로깅으로 변경.
β 1.4.48 2026.04.27
STORAGE · CRITICAL FIX
  • localStorage 용량 초과 크래시 수정 — 주간 스케줄 저장 시 QuotaExceededError가 발생하면 드릴이 아예 안 뜨던 치명적 버그. 저장 실패해도 드릴은 정상 표시되도록 수정.
  • 자동 공간 정리 — 용량 초과 감지 시 오래된 백업·채팅·훈련 데이터를 자동 축소하고 재저장 시도.
β 1.4.47 2026.04.27
DIAG · DRILL FIX
  • 드릴 미표시 진단 기능 — 훈련 드릴 0개 시 파이프라인 상태(FP/스케줄/DayIdx 등) 진단 정보 + "스케줄 초기화" 버튼 표시
  • 에러 가시화 — renderTodayDrills 예외 시 화면에 에러 메시지 표시 (기존: 콘솔만)
β 1.4.46 2026.04.27
DATE · UTC FIX
  • 자정~오전9시 훈련 드릴 0개 표시 버그 수정 — β1.4.45에서 todayKey()를 로컬 전환했지만, startDate를 new Date("YYYY-MM-DD")로 파싱하면 UTC 자정으로 해석되어 한국 시간 자정~9시 사이에 dayIndex가 -1이 되는 문제 발견. _parseLocalDate() 헬퍼 도입으로 해결.
  • getScheduleDayIndex() 음수 인덱스 방지 — Math.max(0,...) 가드 추가. schedule.days[-1] 참조로 인한 빈 배열 반환 차단.
  • getWeeklySchedule() 유효성검사 강화 — daysSince≥0 가드 추가. 미래 날짜 startDate가 유효 판정되는 edge case 차단.
  • 잔여 toISOString().slice(0,10) 일괄 로컬 전환 — calcStreak, renderGoalSection, renderWeeklyReport, 주간 진행 도트, renderTrainingCompare, autoDailyBackup, 스크립트블록[4] 분석 통계까지 총 9곳 수정.
  • 캐시 버전 v185→v186 — 배포 후 PWA 강제 업데이트 필요. localStorage의 icoach_weekly_schedule은 자동 재생성됨.
β 1.4.45 2026.04.26
TRAINING · DATE FIX
  • 훈련 탭 드릴 목록이 안 뜨던 버그 수정todayKey() 가 UTC 기준 날짜를 반환해 한국(UTC+9) 사용자의 로컬 날짜와 불일치, 주간 스케줄·커스텀 드릴 모두 "오늘" 을 찾지 못해 빈 화면이 되던 문제. 로컬 시간 기반으로 전환.
  • 분석 후 "훈련에 담기" 버튼이 작동 안 하던 버그 수정 — 채팅 코치에서 드릴 추가 시 저장되는 dateKey 도 UTC 기준이라 getCustomDrillsForToday() 와 날짜 불일치. todayKey() 통일.
  • 주간 스케줄 캐시 손상 시 크래시 방지getWeeklySchedule()JSON.parse 에 try/catch 추가. 손상된 캐시는 자동 삭제 후 재생성.
  • DRILL_VIDEO_MAP 참조 안전 체크 — 스크립트 블록 간 로드 순서에 의한 ReferenceError 방지를 위해 typeof 가드 추가.
  • 드릴 0개 상태에서 "완료" 가능하던 허점 차단 — 빈 배열의 every() 가 vacuous truth 를 반환하는 JS 특성 때문에 드릴 없이도 완료 판정. drills.length>0 가드 추가.
  • 홈·히스토리 "+" 버튼 UTC 날짜 수정_added / _addedH 함수의 dateKey 도 todayKey() 로 통일.
  • 캐시 버전 v184→v185 — 배포 후 PWA 강제 업데이트 권장.
β 1.4.44 2026.04.23
PWA · INSTALL UX
  • PWA 설치 안내가 영영 안 뜨던 문제 근본 해결 — 사용자(특히 테스트 참여자)가 매번 링크로만 접속하던 불편을 해결하기 위해 5가지 개선을 한 번에 적용했습니다. "다시 알리지 않기" 한 번에 영구 차단되는 정책 + 노출 동선 부재 + iOS 5초 대기 등 누적된 UX 문제를 통합 정리.
  • (A) 설정 탭에 "📱 홈 화면에 앱 설치" 카드 항상 노출 — 설치 안 된 상태면 설정 진입 시 항상 보임. 브라우저 자동 감지 → Chrome/안드로이드/삼성 인터넷/iOS/데스크톱 별로 안내 문구와 버튼 동작이 자동 분기. 설치 완료 시 카드 자동 사라짐.
  • (B) "다시 알리지 않기" 정책 영구→7일 — 영영 차단되던 icoach_install_dismissed_forever 정책 폐기. 새 정책 icoach_install_dismissed_at 타임스탬프 기반 — 7일 경과 시 자동 재노출. 기존 사용자의 영구 차단 키는 마이그레이션으로 제거되어 다음 방문 시 다시 안내받습니다.
  • (C) iOS 가이드 5초 → 1초 — 사용자가 페이지 떠나기 전에 안내가 보이도록 노출 지연 단축. setTimeout(...5000)1000ms.
  • (D) 첫 분석 완료 후 자연스러운 권유 토스트 — 분석 1회를 마쳤지만 아직 설치 안 한 사용자에게 "💡 앱으로 설치하면 매번 빠르게 시작할 수 있어요. 설정 → 📱 홈 화면에 앱 설치" 토스트 (분석 완료 4초 후, 6.5초 노출).
  • (E) 우측 하단 플로팅 📱 앱 설치 버튼 — 설치 안 된 상태에서 모든 화면 우측 하단에 골드 그라디언트 라운드 버튼이 항상 떠 있음 (탭 살짝 위로 흔들리는 펄스 애니메이션). 누르면 즉시 브라우저 맞춤 안내. 설치 완료 시 자동 숨김.
  • appinstalled 이벤트 핸들러 추가 — 사용자가 설치를 완료하면 window.appinstalled 이벤트가 발생, 모든 안내 UI 즉시 숨김 + "🎉 홈 화면에 추가됐어요!" 성공 토스트.
  • 스토어 차단 가능성은 무관 — 아이코치는 PWA(웹 앱) 라 Play Store/App Store 정책과 무관. "안전하지 않은 앱" 경고는 일부 안드로이드에서 PWA 설치 시 정상적으로 뜨는 표준 동작이며, "세부정보 → 무시하고 설치" 로 진행하면 됨 (기존 설치 배너 안내 그대로 유지).
  • 캐시 버전 v183→v184 — 배포 후 PWA 강제 업데이트 권장. 이번 업데이트 이후 영구 차단 상태가 자동 해제되어 사용자 폰에서 다시 안내가 보이기 시작합니다.
β 1.4.43 2026.04.23
SETTINGS · POLISH
  • 과거로 되돌리기 — 버튼 1줄 단순화 — 수동 백업 2줄 스택 대신 더 간결하게 "백업" 한 단어 1줄로 통일. 펼치기도 같은 사이즈로 맞춰 시각적 균형 확보.
  • 두 버튼 공통 스타일: padding:6px 12~14px · font-size:11px · white-space:nowrap · line-height:1. 폰트 두께는 골드 강조(백업: 700) / 중립(펼치기: 600) 로 차등해 시선 유도 유지.
  • 캐시 버전 v182→v183 — 배포 후 PWA 강제 업데이트 권장.
β 1.4.42 2026.04.23
SETTINGS · LAYOUT
  • "과거로 되돌리기" 헤더 영역 줄바꿈 정리 — β 1.4.41 의 새 데이터 보관 카드에서 "(최근 14일)" 텍스트가 "14"와 "일)"로 쪼개지고, "▼ 펼치기"가 "펼치"/"기"로, "수동 백업"이 "수동 백"/"업"으로 어색하게 줄바꿈되던 문제 해결.
  • 3가지 세부 수정:
    • 타이틀 "(최근 14일)" 을 <br> 으로 아래 줄로 내려 깔끔한 2줄 레이아웃
    • "▼ 펼치기" 버튼에 white-space:nowrap 추가 → 항상 1줄 유지
    • "수동 백업" 버튼을 <span display:block> 2개로 의도적으로 "수동" / "백업" 2줄 스택
  • 플렉스 비율 조정 — 타이틀 영역 flex:1 min-width:0, 버튼 영역 flex-shrink:0 으로 모바일 폭이 좁아도 버튼이 찌그러지지 않음.
  • 캐시 버전 v181→v182 — 배포 후 PWA 강제 업데이트 권장.
β 1.4.41 2026.04.23
SETTINGS · UX
  • 설정 → 데이터 보관 섹션 통합 — "데이터 관리" / "클라우드 동기화" / "날짜별 롤백" / "JSON 가져오기" 가 설정 화면에 나란히 놓여 있어 사용자가 "어떤 걸 눌러야 하나" 혼란을 겪던 UX 를 정리. 단일 "데이터 보관" 카드로 묶고 내부에 3 개의 독립 섹션으로 시각적으로 분리했습니다.
  • 용도 중심 재배치 — 상단부터 (1) ☁️ 기기 간 동기화 — 기기 변경·캐시 삭제 대비 / (2) 📅 과거로 되돌리기 — 최근 14일 데이터 타임머신 / (3) ⚙️ 고급 — JSON 내보내기·가져오기 (기본 접힘). 각 섹션에 "언제 쓰나요?" 한 줄 안내를 붙여 목적을 즉시 파악 가능하게 함.
  • 초보자 동선 최적화 — 가장 자주 쓰는 클라우드 동기화가 맨 위로, JSON 은 <details> 접힘으로 숨김. 일반 사용자에게는 2개만 보이고 고급 옵션은 필요할 때만 열림. 기능은 그대로 유지되지만 "어디서 시작해야 하는지" 명확해짐.
  • 기능 변경 없음 — 코드 수준에서 syncHistoryBoth(), manualSaveVersionBackup(), exportData(), importData() 는 모두 기존 동작 그대로. 순수 UI 재구성.
  • 캐시 버전 v180→v181 — 배포 후 PWA 강제 업데이트 권장.
β 1.4.40 2026.04.23
PITCHING · USER CHOICE
  • 암슬롯 사용자 선택 UI 도입 — 초보 오버핸드 오분류 근본 해결 — 투구 분석 전 오버핸드 · 사이드암 · 언더핸드 · 🤖 자동 감지 4개 pill 버튼을 표시합니다. 사용자가 의도한 폼을 직접 선택하면 그 값이 자동 감지를 덮어쓰고 분석 기준으로 적용됩니다. 아직 폼이 완성되지 않은 초보 오버핸드 친구가 수치상 사이드암으로 측정되더라도 사용자가 '오버핸드' 를 선택했다면 오버핸드 전용 기준(팔꿈치 각도 80~120°, 몸통 틸트 20~40° 등) · 오버핸드 롤모델 · 오버핸드 드릴 로 분석됩니다.
  • 왜 사용자 선택이 필요한가 — 2D 랜드마크 분석은 "지금 이 영상에서 팔이 어떻게 움직였는가" 만 측정 가능. "의도한 폼" 과 "실제 역학" 이 다른 초보 선수(대부분의 어린 오버핸드 선수) 는 수치만 보면 사이드암처럼 보입니다. 하지만 사용자(부모·코치) 는 선수의 의도를 알고 있으므로, 그 지식을 분석에 반영하는 게 훨씬 정확한 결과로 이어집니다.
  • UI·UX — 영상 업로드 후 미리보기 바로 아래에 골드 테두리 카드로 4개 pill 버튼이 노출. 선택은 localStorage.icoach_user_armslot 에 저장되어 다음 번에도 유지. 기본값은 '오버핸드' (한국 초중등 야구에서 가장 흔함). 투구 모드에서만 표시되고 타격·수비에는 영향 없음.
  • 자동 감지의 새로운 역할 — β 1.4.39 의 classScore 분류기는 이제 사용자가 '🤖 자동 감지' 를 명시적으로 선택한 경우에만 작동. 평소에는 관리자 진단 참고용 데이터로만 수집됨 — 사용자가 신경 쓸 필요 없이 본인이 선택한 폼으로 안정적으로 분석받을 수 있습니다. 관리자 카드에는 사용자=overhand · 적용=overhand · 원판정(자동)=sidearm 처럼 3개 값이 모두 표시되어 경계 케이스 데이터 계속 수집 가능.
  • Gemini API 는 현재 불필요 — 이 문제를 AI 비전으로 해결하려면 영상당 수백 원의 API 비용·네트워크 지연이 발생합니다. 사용자 선택 한 번으로 UX·정확도 양쪽을 해결하므로 API 의존 없이 동작. 장기적으로 Gemini 선택적 통합은 '자동 감지' 내부 개선 방향으로 유보.
  • 캐시 버전 v179→v180 — 배포 후 PWA 강제 업데이트 권장.
β 1.4.39 2026.04.23
DETECTION · DATA-CALIBRATED
  • 사이드암 자동 분석 부활 — 실측 데이터 기반 재보정 — β 1.4.32 에서 SAFE MODE 로 암슬롯 자동 감지를 전면 비활성화했던 기능이 실제 사용자 영상 11개(오버핸드 6 + 사이드암 5) 의 진단 수치를 기반으로 튜닝되어 돌아왔습니다. 이제 친구들이 사이드암으로 영상을 분석받을 때 사이드암 전용 기준(팔꿈치 각도 75~110°, 몸통 틸트 25~45° 등) + 롤모델(정대현·김병현·야마다 히사시) + 전용 드릴 이 정상 작동합니다.
  • classScore — 단일 연속 점수 분류기 — 기존엔 peakUpAng · peakElev · avgElev · 각종 각도 조합 12단계 if 체인으로 분기했는데, 경계 케이스마다 한두 조건이 어긋나 오탐이 속출했습니다. 11건 실측 분포를 분석해 classScore = peakUpAng/200 + (-avgElev) × 1.5 단일 스칼라를 도출 — 오버핸드 최고 1.05, 사이드암 최저 1.18 로 자연스러운 경계 1.15 발견. 기존 수많은 임계값을 이 한 줄로 대체.
  • 분류 규칙:
    classScore < 1.15오버핸드 (V1~V7 케이스 커버)
    classScore ≥ 1.15사이드암 (S1~S5 케이스 커버)
    classScore ≥ 1.80 AND avgElev < -0.55언더핸드 (극단적 케이스만, 거의 사용 X)
  • SAFE MODE 자동 해제 + 카메라 각도 연동 — 이제 기본값은 분류기 ON. 단 detectCameraView()(β 1.4.38) 가 'side' 를 반환한 경우에만 분류기 가동. 정면/뒷면/사선/불명 카메라는 측정값 자체가 왜곡되므로 자동으로 오버핸드 고정 — 별도 사용자 조작 없이 안전하게 보호됩니다. 명시적 강제 OFF 가 필요하면 콘솔에서 window.__icoach_detect_armslot = false.
  • 관리자 진단 카드 개선 — 타이틀에 classScoreview 추가. 한눈에 "분류 근거 점수" 와 "카메라 각도" 를 확인 가능. text 영역에는 새 공식과 임계값을 명시.
  • 예상 적중률 (실측 11건 기준): 오버핸드 5/5(100%) · 사이드암 5/5(100%) · V5(outlier) 는 수치상 사이드암으로 분류됨 (던지는 팔 오감지 의심). 실제 서비스에서 앞으로 새 영상을 축적하며 경계 케이스 튜닝 예정.
  • 캐시 버전 v178→v179 — 배포 후 PWA 강제 업데이트 권장.
β 1.4.38 2026.04.23
ANALYSIS · CAMERA GUIDE
  • 카메라 촬영 각도 자동 감지 + 안내 카드 — 앞에서 찍은 영상을 투구 분석하면 스트라이드 7% · 몸통 회전 1° · 코킹 팔꿈치 3° 같은 "무동작" 수치가 나오는 구조적 문제가 있었습니다. 사용자 촬영 미숙이 아니라 AI 분석의 근본적 한계 — 투구의 핵심 동작(스트라이드·회전·분리·코킹)이 카메라 축 방향(깊이) 으로 일어나 2D 프레임에선 납작해져 측정되기 때문입니다. 이제 AI 가 촬영 각도를 자동 감지해 사용자에게 알려줍니다.
  • 판별 원리 — 어깨폭 / 몸 높이 비율|LS.x - RS.x| / |avgShoulderY - avgAnkleY| 의 중앙값을 계산. 측면 촬영은 어깨가 카메라 기준 edge-on 이라 비율 < 0.20, 정면/뒷면은 양 어깨가 다 드러나 비율 > 0.30, 그 사이는 사선으로 분류. 연산은 프레임당 O(1) 이라 전체 오버헤드 무시 가능.
  • 🎥 촬영 각도 안내 카드 — 측면이 아닌 영상이면 분석 결과 맨 위에 노란 안내 카드가 뜹니다. 정면/뒷면: "스트라이드·몸통 회전·어깨 분리 등 카메라 축 방향으로 일어나는 동작은 실제보다 훨씬 작게 측정될 수 있어요." 사선: "살짝 비스듬한 각도. 90° 측면 촬영을 권장." 상세 영역에는 촬영 팁(선수 옆면·5~8m·수평) 수록.
  • 투구·타격·수비 3 모드 전부 적용pitchA, batA, fieldA(땅볼), fieldA_fly(플라이), catcherA(포수), outfield(외야) 6개 분석기 모두에 카메라 안내 카드 인젝션. 진단 덤프는 window.__icoach_view_debug 에 중앙값·샘플 수 저장.
  • SAFE MODE 진단 연결 — 이전 사용자 영상에서 peakUpAng=163° 같은 극단값이 나온 원인을 "앞에서 찍힌 초보 투구" 로 설명하는 데이터 기반 근거 확보. 측면 촬영으로 다시 분석하면 정상 범위 수치가 나올 가능성이 높고, 그때 SAFE MODE 해제 조건 논의로 이어갈 수 있습니다.
  • 캐시 버전 v177→v178 — 배포 후 PWA 강제 업데이트 권장.
β 1.4.37 2026.04.23
DETECTION · SAFE MODE BUG
  • SAFE MODE 우회 버그 근본 수정 — 언더핸드 오탐 발생 — β 1.4.32 에서 SAFE MODE 를 도입했는데 설계 결함이 있었습니다. 언더핸드 판정 경로(peakUpAng > 120°)가 SAFE MODE 검사보다 먼저 return 'underhand' 해버려 자동 감지 OFF 상태임에도 언더핸드 라벨이 튀어나오는 버그. 오버핸드 투구 영상을 "언더핸드 투구폼 감지"로 오분류하는 리포트 재발.
  • 문제 구조detectArmSlot() 의 12단계 캐스케이드에서 (4)~(9) 오버핸드 확정과 (10) 언더핸드 확정은 조기 return, (11) 사이드암만 wouldBe 변수 경유 → SAFE MODE 적용을 받았습니다. 즉 SAFE MODE 는 사이드암은 막았지만 언더핸드는 못 막는 비대칭 구조였습니다. 또한 조기 return 으로 인해 진단 카드의 원판정 필드가 언더핸드 케이스에서 n/a 로 찍혔습니다 (wouldBe 를 저장하는 코드에 도달하기 전에 함수 종료).
  • 수정 — 단일 return 지점으로 리팩터 — (4~9) 오버핸드 확정 / (10) 언더핸드 확정 / (11) 사이드암 확정 조건을 모두 개별 boolean 식으로 평가하고 wouldBe 변수에 누적, 맨 마지막에 SAFE MODE 체크 한 곳에서만 최종 return. 모든 분류 결과가 SAFE MODE 를 반드시 통과.
  • 진단 카드 개선 — 덤프 위치를 분류 로 이동해 wouldBe 가 항상 window.__icoach_armslot_debug 에 포함됨. 이제 관리자 카드 제목에 원판정=overhand / sidearm / underhand 가 실제 판정대로 찍혀 SAFE MODE 가 어떤 내부 판정을 차단했는지 확인 가능.
  • 사용자 영상 실측값(참고) — peakUp=163.2° / minUp=158.6° / pE=-0.378 / aE=-0.465 / aboveShoulder=0/23. 진짜 오버핸드임에도 팔이 단 한 프레임도 어깨 위로 안 올라옴. 가장 유력한 가설은 "던지는 팔 자동 판별"에서 글러브 팔이 잘못 선택됐거나, 영상이 릴리스~팔로스루 구간만 담겨 코킹 전반을 놓친 케이스. 실측 데이터 축적 중.
  • 캐시 버전 v176→v177 — 배포 후 PWA 강제 업데이트 권장.
β 1.4.36 2026.04.23
CHAT · CONVERSATION
  • 앵무새 응답 근본 수정 — 대화처럼 느끼도록 재설계 — "고맙습니다" 든 "스윙 준비 스트레칭도 매번 해야하나요?" 든 뭘 물어봐도 코치가 같은 문구 + 동일 드릴 카드로만 답하던 문제 해결. 3가지 근본 원인 모두 손봤습니다.
  • 원인 1: 사교적 의도에도 드릴 카드가 붙었음getRuleBasedResponse 의 switch 문이 default 로 먼저 떨어지면서 drills=getGeneralDrills(...) 로 드릴이 세팅되고, 그 뒤의 thanks/encouragement 처리는 response 만 덮어쓰고 drills 는 그대로 두는 구조였습니다. 이제 thanks/encouragement/affirm/negate/warmup_q/frequency_q/why_q 분기에서 모두 drills=[] 로 초기화.
  • 원인 2: 같은 응답 템플릿이 한 개씩 — 점수대별로 한 문장만 있어 매번 똑같이 반복. getGeneralBattingResponse/PitchingResponse/FieldingResponse 를 모두 점수대 × 4개 템플릿 풀로 확장하고 icoach_chat_rot_<key> localStorage 카운터로 순차 로테이션. 같은 점수대여도 매번 다른 멘트.
  • 원인 3: 드릴이 무조건 따라붙었음 — 직전 코치 메시지에 이미 드릴 카드가 있었으면 이번 턴에서는 드릴 생략(명시적 "드릴 추천해줘" 의도만 예외). 연속 3턴 내내 동일 드릴 4개 재노출되던 현상 차단.
  • 의도 인식 확장recognizeIntentwarmup_q(스트레칭/준비운동/웜업) · frequency_q(매번/매일/자주/얼마나/몇 번) · why_q(왜/이유/어째) · affirm(네/응/오케이) · negate(아니/안/싫어) 5종 추가. "스윙 준비 스트레칭도 매번 해야되나요?" → warmup_q + frequency_q 범위로 들어와 실제 준비운동 빈도 지침을 응답하도록 함.
  • Gemini API 키 연결 시 계속 AI 채팅 사용 — 규칙 기반 응답은 폴백. 설정에서 Gemini API 키를 넣으면 대화 맥락(최근 6턴)과 분석 점수를 바탕으로 진짜 대화형 코치가 작동합니다. 현재 앵무새 현상이 심하다면 Gemini 키 연동을 먼저 추천.
  • 캐시 버전 v175→v176 — 배포 후 PWA 강제 업데이트 권장.
β 1.4.35 2026.04.23
CHAT · LAYOUT
  • 채팅 스크롤·입력창 소실 근본 수정 — CSS 특수성 충돌 — β 1.4.34 에서 rAF + 이미지 로드 리스너까지 달아 스크롤 로직을 강화했음에도 "스크롤이 안 내려가고 더 채팅을 할 수가 없다"는 리포트. 근본 원인은 전혀 다른 곳 — CSS 선택자 특수성 충돌이었습니다.
  • 버그 구조.screen.active(선택자 2개, 특수성 0,0,2,0) 가 display:block 을 강제, .chat-screen(0,0,1,0) 의 display:flex특수성 밀려서 덮어쓰지 못했습니다. 결과적으로 채팅 화면이 실제로는 block 으로 렌더링되어 .chat-messagesflex:1 이 무력화됨. 메시지가 쌓이면 컨테이너 높이가 내용만큼 계속 늘어나고, 그만큼 전체 스크린 높이도 늘어나 chat-input-area 가 뷰포트 밖으로 밀려난 것. 스크롤 JS 는 정상 동작해도 입력창이 눈에 안 보이니 채팅을 이어갈 수 없었습니다.
  • 수정 — 특수성 0,0,2,0 의 .screen.chat-screen 선택자로 display:flex + padding-bottom:0 + height:calc(100dvh - 65px) 재선언. .screen.chat-screen.active(0,0,3,0) 에도 display:flex 명시로 최종 확정. 안전장치로 !important 병행. 이제 chat-header/chat-messages/chat-input-area 가 제대로 flex 기반으로 배치되어 chat-messages 만 내부 스크롤되고 input 은 항상 바닥에 고정.
  • 100dvh 적용 — 기존 100vh 는 모바일 브라우저의 URL 바 표시/숨김에 따라 값이 요동쳐 가상 키보드 띄웠을 때 입력창이 사라지는 부수 문제가 있었는데, 100dvh(dynamic viewport height) 로 교체해 안정화. 구형 브라우저는 기존 100vh 규칙이 폴백으로 남아있습니다.
  • 캐시 버전 v174→v175 — 배포 후 PWA 강제 업데이트 권장.
β 1.4.34 2026.04.23
CHAT · UX
  • 채팅 자동 스크롤 근본 수정 — 질문을 보내고 코치 응답(또는 추천 훈련 카드)이 도착해도 채팅 화면이 맨 아래로 내려가지 않던 문제 해결. 기존 scrollChatToBottom()scrollTop = scrollHeight동기적으로 한 번만 호출했는데, 코치 아바타나 드릴 아이콘 <img>비동기로 로드되면서 실제 높이는 그 뒤에 확정 → 최초 스크롤 시점에는 아직 늘어나지 않은 높이만 반영돼 중간쯤에서 멈췄습니다.
  • 5단 스크롤 보장 — (1) 즉시 1회 (2) requestAnimationFrame 중첩 2회 (레이아웃 반영 후) (3) 200ms · 600ms 지연 타이머 (4) 로드되지 않은 <img>load·error 리스너 부착해 실제 이미지 로드 시 재스크롤. 모바일의 느린 네트워크에서도 확실히 바닥에 붙습니다.
  • "드릴 정보를 찾을 수 없습니다" 토스트 UX 개선 — β 1.4.28 의 4중 폴백으로도 제목을 뽑지 못하는 극히 드문 레거시 채팅 히스토리에서 오류 토스트가 떠 혼란을 줬습니다. 이제 해당 케이스에서는 에러 대신 정보 토스트("이 드릴은 이전 버전 포맷이에요. 새 분석의 추천 드릴은 바로 담을 수 있어요") + 버튼만 비활성화. 동시에 콘솔에 버튼/부모 DOM 을 덤프해 다음 추적을 위한 근거 확보.
  • 캐시 버전 v173→v174 — 배포 후 PWA 강제 업데이트 권장.
β 1.4.33 2026.04.23
DIAGNOSTIC · UI
  • 관리자 진단 카드 전용 디버그 레이아웃 분리 — β 1.4.32 에서 추가한 🔧 관리자 진단 카드가 일반 피드백 카드 렌더러를 타면서 "현상 / 원인 / 교정" 3단 템플릿에 억지로 끼워맞춰져, 원인·교정 자리에 "이 부분을 개선하면 부상 예방..." 같은 상용구가 자동 생성되고 있었습니다. 진단 정보가 코칭 피드백처럼 표시돼 혼란을 줬습니다.
  • 간결한 모노스페이스 단일 블록으로 교체 — 카드 제목이 🔧 로 시작하면 렌더러가 이를 감지해 3단 템플릿을 건너뛰고, 제목 / text / detail 을 모노스페이스 한 블록으로 표시합니다. 접힘 토글과 화살표를 제거해 항상 펼친 상태로 노출 — 관리자가 스크린샷 한 장으로 모든 수치를 캡처할 수 있도록. 메인 분석 결과 렌더러와 히스토리 상세 렌더러 양쪽에 동일하게 적용.
  • 감지 판정에 영향 없음 — 이번 변경은 순수 렌더링 레이어. β 1.4.32 의 SAFE MODE (암슬롯 자동 감지 OFF 기본값) 는 그대로 유지되어 "사이드암 투구폼 감지" 오탐은 계속 차단됩니다.
  • 캐시 버전 v172→v173 — 배포 후 PWA 강제 업데이트 권장.
β 1.4.32 2026.04.23
DETECTION · SAFE MODE
  • 암슬롯 자동 감지 기본 비활성화 — 사이드암 오탐 완전 차단 — β 1.4.29/1.4.31 에서 비율 기반 임계값 완화 → 각도 기반 판정기 추가까지 시도했지만, 특정 카메라 구도에서는 오버핸드 영상이 계속 사이드암으로 오분류돼 잘못된 롤모델(김병현/정대현)이 추천되는 문제가 해결되지 않았습니다. 측정 지표가 아무리 정교해져도 카메라 각도·피사체 구도에 따른 노이즈가 근본적으로 남아, 임계값 조준 튜닝만으로는 안전하게 분류할 수 없다고 판단했습니다.
  • 안전 모드 전환 — 모든 투구를 오버핸드로 분석detectArmSlot() 의 측정·분류 코드는 그대로 유지한 채, 최종 리턴 직전에 window.__icoach_detect_armslot === true 플래그가 없으면 항상 'overhand' 로 오버라이드. 결과적으로 "사이드암 투구폼 감지" 카드와 사이드암·언더핸드 롤모델 추천이 더 이상 나타나지 않습니다. 원래 내부 판정 결과(wouldBe)는 진단에 보존되므로 나중에 실측 데이터로 재조정 가능.
  • 관리자 진단 카드 타이틀에 핵심 수치 상시 노출 — 기존에는 접힌 상태에서 제목만 보이고 수치는 열어야 확인 가능했습니다. 이제 타이틀에 🔧 원판정=overhand/sidearm/underhand · peakUp=XX° · minUp=XX° · pE=X.XX · aE=X.XX 형태로 핵심 4개 값을 직접 노출해 스크린샷 한 장으로 상태 파악 가능. 세부는 접은 상태로 유지.
  • 자동 감지 재활성화 경로 — 관리자 브라우저 콘솔에서 window.__icoach_detect_armslot = true 입력 후 재분석하면 β 1.4.31 의 12단계 캐스케이드 판정기가 다시 작동합니다. 실제 사이드암/언더핸드 투수 영상의 진단 값을 수집해 임계값을 실측 기반으로 재설정한 뒤 전체 재활성화 여부 결정 예정.
  • 캐시 버전 v171→v172 — 배포 후 PWA 강제 업데이트 권장.
β 1.4.31 2026.04.23
DETECTION · ANGLE-BASED
  • 사이드암 오탐 2차 수정 — 생체역학적 각도 판정기 도입 — β 1.4.29 의 peakElev/keyElev 이중 기준으로도 여전히 오버핸드 투구를 사이드암으로 오분류하는 영상이 있었습니다. 비율 기반 지표(elev = (sh.y - el.y) / torso) 는 카메라 각도·거리·피사체 줌에 의해 분모가 요동쳐 근본적으로 불안정한 스칼라였습니다.
  • 새 PRIMARY 판정기 — 어깨→팔꿈치 벡터의 수직각upAng = atan2(|el.x - sh.x|, sh.y - el.y) × 180/π. 0°=팔꿈치가 어깨 바로 위(팔 수직), 90°=어깨와 같은 높이(팔 수평), 180°=바로 아래(팔 수직 아래). 프레임 스케일·줌에 완전히 독립이라 훨씬 안정적. 오버핸드 코킹 10~45°, 사이드암 65~105°, 언더핸드 120°~.
  • 12단계 캐스케이드 판정 — (4) peakUpAng < 55° → 오버핸드 / (5) minUpAng < 45° (단 한 프레임이라도 팔이 분명히 위쪽) → 오버핸드 / (6~9) 기존 비율 기반 백업 체크들 / (10) 언더핸드는 peakUpAng > 120° AND 삼중 조건 / (11) 사이드암은 네 조건 모두 충족(peakUpAng 65~110° AND releaseUpAng ≥ 60° AND peakElev < 0.02 AND avgElev < -0.15) / (12) 나머지는 전부 오버핸드 기본값. 애매한 경계에서 오버핸드로 쏠리는 구조.
  • 수집 창 확장 — 기존 [release-12, release+2] → [release-20, release+3]. 느린 와인드업의 코킹 피크가 창 밖으로 밀려 peakElev 가 과소 측정되던 문제 보정. 팔로스루 배제 상한(+3)은 유지해 오염 원천 차단.
  • 관리자 진단 카드 추가 — 관리자 모드일 때 분석 결과 상단에 🔧 관리자 진단 (암슬롯) 노란색 카드가 뜹니다. 판정에 쓰인 실제 수치 — armSlot, isRight(R/L), releaseF(프레임%), 수집창 범위, aboveShoulder 프레임 수, peakElev/releaseElev/avgElev, peakUpAng/releaseUpAng/minUpAng — 를 한 줄로 노출해 다음 오탐 발생 시 정확한 수치 기반으로 임계값을 조준 튜닝할 수 있습니다. 콘솔에서도 window.__icoach_armslot_debug 로 접근 가능.
  • 캐시 버전 v170→v171 — 배포 후 PWA 강제 업데이트 권장.
β 1.4.30 2026.04.23
ADMIN · QA
  • 관리자 모드에서 같은 영상 반복 분석 허용 — 기존에는 관리자 모드로 일일 제한이 풀려도, "이 영상은 이미 분석한 적이 있습니다" 중복 영상 다이얼로그가 여전히 떠서 QA·회귀 테스트 시 동일 영상으로 재분석을 반복할 수 없었습니다. onVideoSelected 의 중복 체크 호출부를 관리자 상태 확인 후 우회하도록 수정 — _adminUnlocked === true 또는 localStorage.icoach_admin === '1' 이면 다이얼로그 없이 바로 진행합니다.
  • 시각적 피드백 — 관리자 모드에서 중복 영상이 감지되면 (차단하지 않고) 🔓 관리자 모드: 같은 영상 재분석 허용 토스트를 띄워 우회 동작이 일어났음을 알려줍니다. 영상 지문(fingerprint) 자체는 계속 저장되므로 관리자 모드를 해제하면 일반 사용자 흐름(중복 경고 다이얼로그)이 그대로 돌아옵니다.
  • 일일 제한 해제 패턴 재사용checkDailyLimit() 에서 이미 검증된 관리자 판정 로직(_adminUnlocked 변수 + icoach_admin localStorage) 을 동일하게 적용. 추후 isAdminUnlocked() 헬퍼로 통합 여지 있음.
  • 캐시 버전 v169→v170 — 배포 후 PWA 강제 업데이트 권장.
β 1.4.29 2026.04.23
DETECTION · ROOT-CAUSE FIX
  • 사이드암 오탐 근본 수정 — 오버핸드 투구 영상에서 반복적으로 사이드암 투구폼 감지 라벨이 잘못 붙던 문제를 해결했습니다. 기존 분류는 keyElev > -0.05 단 한 줄로 "팔꿈치가 어깨 기준 몸통 길이의 5% 이하로만 내려가도 사이드암" 으로 취급했는데, 실제 정상 오버핸드 릴리스에서도 팔꿈치가 어깨보다 살짝 아래(-0.07~-0.15)에 위치하는 경우가 흔해 지속적으로 오분류됐습니다. Safety Net 들도 있었지만 단일 프레임 keyElev 한 번만 임계값 밑으로 떨어지면 즉시 사이드암 라벨이 찍히는 구조적 약점이 있었습니다.
  • 이중 기준 분류로 교체 — (A) peakElev 오버핸드 확정 임계값 0.08→0.04, (B) 어깨 위 프레임 절대수 3→2 로 완화해 정상 오버핸드는 Safety Net 단계에서 빠르게 확정. (C) 경계 구간 진입 시 peakElev < 0.05 AND keyElev ≤ -0.18 두 조건을 동시에 요구해야만 사이드암 — 피크가 어깨 근처까지라도 올라왔으면 오버핸드. (D) keyElev > -0.15 면 오버핸드(정상 오버핸드 릴리스의 자연스러운 하강 포용). (E) 언더핸드 기준 -0.30→-0.38 로 엄격화. (F) 애매한 중간 구간은 기본값 오버핸드 — 가장 흔한 폼이므로 오분류 비용이 최소.
  • 크라우칭(포수) 오탐 근본 수정 — 투구/타격 분석에서 ⚠️ 크라우칭(포수) 자세가 많이 감지 경고가 잘못 뜨던 문제 해결. 기존 조건 hipY > kneeY * 0.82 는 이미지 절대 좌표 비율이라 피사체가 프레임에 어떻게 잡혔느냐(크게/작게/위쪽/아래쪽)에 따라 값이 요동쳤습니다. 투수가 프레임 중상단에 잡히면 hipY/kneeY 가 자연스레 0.82 를 넘어 상시 오탐.
  • 신체 정규화 깊이 + 무릎 각도 이중 조건 — 새 지표는 (ankleY - hipY) / (ankleY - shoulderY) — 발목-어깨 축에서 엉덩이가 얼마나 아래쪽에 위치하는지를 몸 전체 길이로 정규화합니다. 서 있으면 0.5, 크라우칭이면 0.45 미만. 여기에 무릎 각도 < 115° (실제 굽혀진 상태) 조건을 AND 로 결합해, 두 지표 모두 만족해야만 크라우칭으로 카운트. 경고 발동 임계값도 crouchR > 0.4 → 0.55 로 상향해 잔존 노이즈를 한 번 더 거릅니다.
  • 파싱 버그 동시 수정(lk?.y||1+rk?.y||1)/2 는 연산자 우선순위 때문에 lk?.y || (1 + rk?.y) || 1 / 2 로 해석되어 kneeY 가 쓸모없는 값(2 또는 NaN)이 되던 숨은 버그를 함께 고쳤습니다.
  • 캐시 버전 v168→v169 — 배포 후 PWA 강제 업데이트 권장.
β 1.4.28 2026.04.23
TRAINING · ROOT-CAUSE FIX
  • 채팅 코치의 "+ 추가" 토스트 "드릴 정보를 찾을 수 없습니다" 근본 수정 — β 1.4.26 의 DOM-First 폴백이 .drill-suggest-title-line / .drill-suggest-desc 클래스명에만 의존하고 있었습니다. 하지만 이전 버전(β 1.4.17 이하)의 채팅 히스토리는 <span>아이콘 제목<span>설명</span></span> 형태라 두 클래스가 존재하지 않았고, 결과적으로 "+ 추가" 클릭 시 제목·설명을 전혀 뽑아내지 못해 토스트만 떴습니다. addChatDrill()3-tier 폴백 체인(①data-* 속성 → ②새 클래스 파싱 → ③레거시 중첩 span 파싱 → ④button/img 제거 후 textContent)을 심어 모든 히스토리 포맷에서 복원되도록 했습니다.
  • 채팅 추천 훈련이 매번 같은 3종(티 배팅 50회 / 드라이 스윙 30회 / 공 추적 연습)이던 문제 해결 — 기존 getGeneralDrills(mode) 는 모드별로 하드코딩된 3개 드릴만 반환해 대화가 단조로웠습니다. 새 버전은 (1) 분석 페이즈가 있으면 gBD/gPD/gFD/gCD/gOD/gFD_fly 분석기를 재사용해 실제 사용자 폼 약점에 맞춘 드릴을 우선 내놓고, (2) 페이즈가 없으면 모드별 8종 풀에서 3종씩 회전(icoach_drill_rot_<mode> localStorage 카운터) 합니다. 투구·타격·수비 채팅 모두 동일 구조로 적용.
  • 분석 결과 추천 훈련 카드에 "+ 훈련에 담기" 버튼 신설 — 홈 화면의 분석 결과 .drill-card 에는 영상 보기 버튼만 있고 커스텀 드릴에 추가할 버튼이 없어, 채팅으로 다시 물어봐야 훈련 메뉴에 반영되는 흐름이었습니다. 이제 각 드릴 카드 하단에 drill-card-add-btn 이 노출되어 한 번의 탭으로 오늘의 커스텀 훈련에 담깁니다. 이미 담긴 드릴은 "추가됨" (비활성) 라벨로 표시.
  • 히스토리 상세 페이지에도 동일 버튼 적용 — 과거 분석을 다시 열어볼 때도 같은 경로로 추천 훈련을 훈련 메뉴에 담을 수 있게 drill-card-add-btn 을 동일하게 배치. 내부적으로는 addChatDrill(btn, mode) 를 공유해 저장 경로가 한 군데로 수렴합니다.
  • 캐시 버전 v167→v168 — 배포 후 PWA 강제 업데이트 권장.
β 1.4.27 2026.04.22
STORAGE · ROOT-CAUSE FIX
  • "저장 공간 107% 사용 중" 처럼 100% 를 넘는 비정상 경고가 뜨던 문제 근본 수정 — 기존 로직은 icoach_* 키의 문자열 길이를 합쳐 임의의 4.5MB 가상 상한 으로 나눠 퍼센트를 계산했습니다. 실제 브라우저가 허용하는 localStorage 한도는 보통 5~10MB 이상이라, 데이터가 가상 상한만 넘으면 브라우저에서는 멀쩡히 저장되는데 화면에는 107%·120%·150% 같은 말이 안 되는 수치가 찍혔습니다. 분석 24~30건만 쌓여도 매번 경고가 떠 불필요한 불안을 줬습니다.
  • 개선 (1) 브라우저의 진짜 quota 사용navigator.storage.estimate() 를 호출해 실제 usage/quota 비율을 계산합니다. 이 API 는 Chrome·Safari·삼성인터넷 모두 지원.
  • 개선 (2) 100% 하드캡 — API 사용 경로든 레거시 폴백 경로든 최종 퍼센트는 항상 0~99 로 제한되어 "107%" 가 원천적으로 발생하지 않습니다.
  • 개선 (3) 임계값·스로틀 — 경고 임계값 80% → 90% 로 상향, 한 번 경고가 뜨면 24시간 동안 재표시 억제 (icoach_storage_warn_at). 단, safeSave 에서 실제로 저장 실패가 일어난 경우는 force 로 스로틀 우회.
  • 캐시 버전 v166→v167 — 배포 후 PWA 강제 업데이트 권장.
β 1.4.26 2026.04.21
TRAINING · ROOT-CAUSE FIX
  • 코치 채팅의 "+ 추가" 버튼이 "드릴 정보를 찾을 수 없습니다" 토스트만 띄우던 문제 근본 수정 — β 1.4.25 까지는 버튼의 onclick 이 메모리 상의 chatSuggestedDrills[idx] 배열 인덱스를 참조하는 구조였는데, 이 배열은 실제로는 한 번도 채워지지 않고 있었고, 채팅 히스토리는 HTML 문자열로 localStorage 에 저장되기 때문에 페이지를 새로고침하거나 세션을 다시 열면 메모리 배열이 항상 비어 있어서 모든 인덱스가 undefined 가 되는 구조적 결함이 있었습니다. β 1.4.25 에 추가한 가드가 이 결함을 표면화시켜 매번 "드릴 정보를 찾을 수 없습니다" 가 뜬 것입니다.
  • DOM-First 아키텍처로 전환 — 드릴 페이로드(제목·설명·모드)를 버튼의 data-drill-title / data-drill-desc / data-mode 속성에 HTML 엔티티 이스케이프(&·"·<·>)로 내장하도록 바꿨습니다. 속성이 비어 있는 구버전 히스토리의 버튼을 만나더라도 부모 .drill-suggest-item 요소의 .drill-suggest-title-line / .drill-suggest-desc 텍스트를 직접 파싱해 폴백합니다. 두 경로 모두 완전히 DOM 기반이라 리로드 · 히스토리 복원 · 다른 탭 재열기 이후에도 항상 동작.
  • 시그니처 하위호환addChatDrill(btnEl, mode) 신형과 addChatDrill(idx, mode, this) 구형을 첫 인자 타입(HTMLElement 여부)으로 자동 감지해 처리합니다. 이미 localStorage 에 남아 있는 예전 채팅 HTML 이라도 곧바로 새 로직을 타고 정상 추가됩니다.
  • 캐시 버전 v165→v166 — 배포 후 PWA 강제 업데이트 권장.
β 1.4.25 2026.04.21
TRAINING · BUGFIX
  • 코치 채팅에서 "+ 추가" 누른 훈련이 훈련 메뉴에 반영되지 않던 문제 수정 — 기존에는 버튼이 "추가됨" 으로 바뀌고 훈련이 추가되었습니다 토스트까지 뜨지만, 실제로는 icoach_custom_drills 라는 별도 로컬 버킷에만 저장될 뿐 어느 화면도 그 버킷을 읽지 않아서 훈련 메뉴에는 아무것도 뜨지 않았습니다. 이번 릴리즈에서 getTodayDrillListGrouped() 가 오늘 날짜로 필터한 커스텀 드릴을 해당 모드(투구/타격/수비) 그룹 끝에 자동으로 합류 시키도록 고쳤습니다. 채팅에서 "+ 추가" 를 누르면 → 토스트 + 훈련 메뉴의 해당 섹션 맨 아래에 체크박스/훈련방법 버튼까지 포함해 즉시 표시됩니다. 훈련 탭이 열려 있으면 재렌더까지 바로 수행.
  • 날짜 스코프 저장 + 30일 자동 프루닝 — 커스텀 드릴은 dateKey(YYYY-MM-DD) 를 함께 저장하므로 추가한 그 날의 훈련 리스트에만 나타나고, 자정이 지나면 자동으로 사라집니다. 로컬 스토리지 누적 방지를 위해 30일 초과 엔트리는 저장 시점에 프루닝. 같은 날/같은 모드/같은 제목 중복 입력은 1회만 반영.
  • 캐시 버전 v164→v165 — 배포 후 PWA 강제 업데이트 권장.
β 1.4.24 2026.04.21
DATA-ROLLBACK · POLISH
  • "날짜별 롤백" 이지만 리스트는 β 1.4.14 같은 버전 번호가 메인 라벨이던 문제 수정 — β 1.4.23 에서 dedupe 키를 날짜로 바꿨지만 라벨 포맷 은 "날짜 엔트리면 날짜, 레거시 버전 엔트리면 버전" 식으로 분기되어 있어서, 실제 사용자의 목록에는 β 1.4.23 이전에 쌓인 레거시 엔트리가 대부분이라 화면에는 여전히 버전 번호가 크게 보였습니다. 이번 릴리즈에서 모든 엔트리는 예외 없이 날짜(2026.4.21 (수))를 메인 라벨 로, 버전 번호(있다면)와 시각·분석 횟수는 작은 부제로 표시하도록 통일했습니다.
  • 1일 1엔트리 강제 마이그레이션 — 기존 저장소에는 같은 날짜에 여러 개(예: 2026.4.21 에만 β 1.4.14·1.4.13·1.4.10·1.4.9·0.9.5 총 5개)가 쌓여 있어 "날짜별 롤백" 이라는 이름과 맞지 않았습니다. 앱 실행 시 _vb_migrate()한 번 돌며 (1) 레거시 엔트리의 date ISO 문자열에서 dateKey(YYYY-MM-DD)를 파생하고, (2) 같은 dateKey 에 속한 엔트리 중 타임스탬프가 가장 최신인 1개만 남기며, (3) 최근 14일 범위로 잘라 저장합니다. 따라서 2026.4.21 자리에는 당일 마지막에 저장된 스냅샷만 남고 나머지는 정리됩니다.
  • 페이지네이션 추가 (5개/페이지, 최대 14일 = 3페이지) — 14일치가 전부 쌓여도 설정 화면이 세로로 길게 늘어지지 않도록, 리스트를 한 페이지 5개 로 자르고 하단에 ← 이전 / N·M / 다음 → 버튼을 추가했습니다. 페이지가 1장(엔트리 ≤ 5개) 이면 컨트롤은 숨김. 수동 백업을 누르면 첫 페이지(가장 최신 쪽)로 점프합니다.
  • 캐시 버전 v163→v164 — 배포 후 PWA 강제 업데이트 권장.
β 1.4.23 2026.04.21
DATA-ROLLBACK · REDESIGN
  • "버전별 롤백" 을 "날짜별 롤백" 으로 재설계 — 기존 설계는 "앱 버전이 바뀔 때마다 직전 버전 데이터를 1회 스냅샷" 이라 같은 버전에 머무르는 동안 은 수동으로 누르지 않으면 백업이 아예 생기지 않는 구조였고, β 1.4.22 에서 dedupe 를 도입한 뒤로는 한 버전당 1장만 보존되어 "어제 삭제한 기록을 복구" 같은 실제 수요를 전혀 못 막았습니다. 애초에 "롤백" 이라는 이름도 사용자에게 앱 기능 자체의 롤백으로 오해되기 쉬웠고, 실제로는 기능 롤백이 필요한 상황이 거의 발생하지 않으므로, 남겨야 할 진짜 기능은 데이터 타임머신 이었습니다. 이번 릴리즈에서 dedupe 키를 versiondateKey (YYYY-MM-DD) 로 바꾸고, 앱 실행 시점에 오늘 날짜의 스냅샷이 없으면 자동으로 1장을 저장 하는 정책으로 교체했습니다.
  • 하루 1회 자동 백업 + 최근 14일 FIFO 보존 — 앱이 실행될 때 checkDailyBackup()icoach_version_backups 배열을 스캔해서 오늘 날짜(dateKey) 항목이 없으면 즉시 한 장을 저장합니다. 기존 버전 기반 체크 (checkVersionAndBackup) 는 제거했습니다. 백업 상한은 10개 → 14일 로 상향해 "지난 2주 내 어느 날로도 복구 가능" 을 보장하고, 이 상한을 넘으면 가장 오래된 엔트리부터 드롭됩니다. 수동 수동 백업 버튼은 오늘 날짜 스냅샷을 최신 데이터로 덮어쓰기 (같은 날 여러 번 눌러도 리스트가 불지 않음) 하며, 완료 토스트는 2026.04.21 백업 완료 형태로 날짜를 노출합니다.
  • 기존 버전별 백업 엔트리는 그대로 유지(공존) — β 1.4.22 이하에서 만들어진 version 키 엔트리는 마이그레이션/삭제 없이 목록에 그대로 남고, 라벨만 다르게 렌더됩니다: 날짜 엔트리는 2026.04.21 (수) 를 메인 라벨로, β 1.4.23 을 작은 부제로 표시하고, 레거시 버전 엔트리는 기존처럼 β 1.4.22 를 메인 라벨로 유지합니다. 사용자가 과거 롤백 기록을 "잃어버렸다" 고 오인하는 일이 없도록 하는 것이 목적입니다.
  • 캐시 버전 v162→v163 — 배포 후 PWA 강제 업데이트 권장.
β 1.4.22 2026.04.21
SETTINGS · UX · POLISH
  • 수동 백업을 눌러도 현재 버전(β 1.4.21)이 리스트에 안 보이던 문제 수정 — 기존 saveVersionBackup() 은 매 클릭마다 append 만 했기 때문에, 브라우저가 이전 캐시된 JS 를 쓰거나 또는 이미 "최신" 으로 표시되던 다른 버전이 있으면 사용자가 추가된 항목을 인지하기 어려웠습니다. 이번 릴리즈에서는 저장 시 같은 버전의 기존 항목을 제거(dedupe)한 뒤 새로 push 하도록 변경했고, 확인 토스트에도 β X.Y.Z 백업 완료 처럼 버전을 명시해 실제 저장 여부를 즉시 확인할 수 있게 했습니다.
  • 버전별 롤백 리스트 접기/펼치기 추가 — 업데이트를 오래 쓴 사용자의 백업이 5개 이상 쌓이면서 설정 화면이 세로로 길게 늘어져 가독성을 해치는 문제가 있었습니다. 기본은 접힘 상태(현재 최신 버전 요약 한 줄만 표시)이고, ▼ 펼치기 버튼으로 전체 목록을 열 수 있습니다. 펼친 상태는 섹션 재진입 시 유지되지 않고 항상 접힘으로 리셋됩니다(사용자가 필요할 때만 연다는 철학).
  • 중복된 ↑올리기 / ↓내려받기 버튼 제거 — "☁ 클라우드 동기화" 블록 안의 파란 지금 동기화 버튼이 이미 syncHistoryBoth()(내려받기 → 올리기) 를 수행하고, 새 분석 시 자동 업로드 · 앱 실행 시 자동 다운로드도 별도로 돌고 있어서 아래 두 방향 버튼은 거의 사용되지 않으면서 UI 만 어지럽혔습니다. 두 버튼은 ▸ 고급: 한 방향만 동기화 토글 뒤로 숨겨, 평상시에는 한 개의 지금 동기화 버튼만 보이게 정리했습니다.
  • 캐시 버전 v161→v162 — 배포 후 PWA 강제 업데이트 권장.
β 1.4.21 2026.04.21
VERIFY · TRAINING · CRITICAL
  • 드릴과 전혀 무관한 영상을 올려도 "인증 완료"가 뜨던 버그 수정 — 훈련 탭에서 드릴 인증 시, 예컨대 "쿠션 캐치 연습" 드릴에 풍경/셀카/무관한 영상 등을 업로드해도 곧바로 인증 완료 로 처리되던 치명적 오류였습니다. 원인은 3중 구조적 허점: (A) Gemini API 키가 없는 사용자는 즉시 pass:true 로 통과. (B) Gemini 프롬프트가 "관대하게 판별해. 야구 관련 동작이면 대부분 pass:true"라고 명시적으로 느슨하게 지시되어 있음. (C) 응답 파싱 실패·네트워크 오류·JSON 포맷 오류 등 모든 예외가 pass:true 로 폴백 — 즉 기본값이 통과. 3개 중 하나라도 걸리면 이후 검사는 무의미했습니다.
  • 수정안 — 이중 검증(로컬 MediaPipe + Gemini) + fail-closed 기본값 — (1) 로컬 1차 검증 (preVerifyDrillVideoLocal): API 호출 전 단계에서 브라우저 내장 MediaPipe 포즈 추정기로 6 프레임을 샘플링 → "사람이 실제로 움직이는가?" 확인. 사람 감지 프레임이 절반 미만이거나 총 이동량이 0.05 아래면 즉시 차단. 정지 화면·풍경·반려동물 영상을 API 비용 없이 거름. (2) Gemini 2차 검증 강화: 프레임 2장→4장, 해상도 384px→480px, temperature 0.2→0.1, 드릴 제목/태그에서 핵심 동작 키워드를 추출해 프롬프트에 주입(투구/타격/수비/워밍업/체력), 프롬프트 어조를 "엄격하게 판별한다. 기본값은 pass:false" 로 반전. (3) fail-closed 정책: 파싱 실패·JSON 포맷 오류·pass 가 boolean 이 아닐 때 모두 pass:false. 진짜 네트워크 에러만 skipped:true 로 사용자 편의상 통과 허용.
  • 영향 — 무관한 영상 업로드 시 "영상에서 사람의 움직임을 확인할 수 없습니다" 또는 "이 드릴과 맞지 않는 영상입니다" 메시지와 함께 차단. 실제 해당 드릴을 촬영한 영상은 기존처럼 통과됩니다. 로컬 검증 단계가 추가되어 업로드 직후 1~2초 지연이 생길 수 있으나, 그 대신 Gemini API 호출 비용은 무효 영상에서 절감됩니다.
  • 캐시 버전 v160→v161 — 배포 후 PWA 강제 업데이트 권장.
β 1.4.20 2026.04.21
PITCH · ARM-SLOT · CRITICAL
  • 오버핸드 투구가 언더핸드로 오분류되던 문제 수정 — 팔이 위에서 아래로 내리꽂히는 확연한 오버핸드 투구인데도 분석 결과가 "언더핸드" 로 뜨고, 그에 맞춰 정대현·김병현·야마다 히사시 같은 사이드암/잠수함 투수가 롤모델로 추천되던 치명적 오류였습니다. 원인은 detectArmSlot() 이 투구 전체 30~85% 구간을 스캔하는 과정에서 팔로스루(릴리스 이후 팔이 몸 반대쪽 무릎까지 크게 휘둘려 내려가는 구간) 프레임이 분석에 섞여 들어갔기 때문입니다. 오버핸드 투수의 팔로스루는 팔꿈치가 어깨보다 한참 아래로 떨어지므로, 여기서 손목 속도가 재상승해 릴리스 프레임이 팔로스루 후반으로 잘못 잡히면 keyElev 가 깊은 음수(-0.30 미만) → "언더핸드" 로 결론 나는 회로가 있었습니다.
  • 수정안 — 분석 구간을 "팔 스윙"에만 엄격히 한정 — (A) 릴리스 탐색 구간을 30~85% → 40~75% 로 축소해 팔로스루 대역(75~100%)을 원천 배제. (B) 팔꿈치 높이(elev) 수집 창을 "릴리스 전후의 팔 스윙 윈도우"로 락([release-12, release+2]). ★ 릴리스 이후는 최대 2 프레임까지만 허용 → 팔로스루 프레임이 통계를 오염할 수 없음. (C) 오버핸드 확정 임계치 peakElev 를 0.12 → 0.08 로 하향(창이 좁아 노이즈 없음). (D) 어깨 위 프레임 비율 20% 방식을 절대 3장 이상 방식으로 전환(짧은 스윙에서도 안정적으로 트리거). (E) 릴리스 값이 없고 피크가 양수면 오버핸드 고정(폴백 경로 보강).
  • 영향 — 오버핸드 투구 영상에서 언더핸드/사이드암 롤모델(정대현·김병현·야마다 히사시 등)이 추천되는 일이 사라집니다. 실제 사이드암/언더핸드 투구는 팔꿈치가 어깨 위로 올라가는 프레임이 거의 없으므로 기존처럼 올바르게 분류됩니다.
  • 캐시 버전 v159→v160 — 배포 후 PWA 강제 업데이트 권장.
β 1.4.19 2026.04.21
PDF · RENDER · CRITICAL
  • PDF 마지막 페이지에 HTML 코드/base64 데이터가 그대로 노출되던 문제 수정 — "코치 한마디" 섹션이 last.coachComment 의 인-앱 HTML 문자열(<span class="coach-good">, <b>, <img src="data:image/png;base64,..."> 등)을 그대로 splitTextToSize 에 넘겨 렌더하다 보니, 화면에서는 보이지 않던 태그/긴 base64 문자열이 PDF 본문에 통째로 출력되었습니다. 신규 헬퍼 stripHtmlForPDF() 를 도입해 이미지·태그·HTML 엔티티를 정리한 평문만 PDF 로 출력하도록 변경.
  • "프로선수 롤모델" 카드와 다음 섹션 줄겹침 수정 — 카드 높이 계산식 needH=6+5+reasonLines×4+strengthLines×4+6 이 카드 맨 아래 "유튜브 검색: ..." 라인의 baseline(+3) 과 폰트 descender·하단 패딩을 빠뜨려, 다음 섹션 헤더가 카드 위로 올라타며 가독성을 망가뜨리는 현상이 있었습니다. +12 로 보정하고 ensureSpace 도 여유분 +3 추가.
  • 본문 여백 정리 — "코치 한마디" 카드 내부 텍스트 시작 y 위치를 5→6 으로 내리고, 라인 폭을 W-M*2-10 으로 살짝 좁혀 좌측 골드 테두리(0.5pt) 와 글자 충돌 제거. 빈 코멘트일 경우 섹션 자체를 그리지 않도록 가드 추가.
  • 캐시 버전 v158→v159 — 배포 후 PWA 강제 업데이트 권장.
β 1.4.18 2026.04.21
LABEL · UX POLISH
  • 투구 분석 라벨 오타 수정 — 프로 비교 지표에서 보폭(%신장) · 어깨 MER 처럼 내부 유닛 표기/영문 약어가 사용자 화면에 그대로 노출되던 문제를 고쳤습니다. 각각 보폭, 어깨 외회전 으로 정리.
  • 영향 범위 — 오버핸드·사이드암·언더핸드 3종 투구 폼 모두 동일하게 적용. getProIdealAngles()label 필드 6곳 + getProCoachComment() 의 코멘트 테이블 key 2곳을 동시 수정해 분석 결과 카드와 코치 코멘트가 일치하도록 맞췄습니다.
  • 전체 스캔 결과 — app.html 에 있는 60+ 개 label: 필드를 전수 검사했고, 다른 영문 약어/내부 단위 표기는 확인되지 않았습니다.
  • 캐시 버전 v157→v158 — 배포 후 PWA 강제 업데이트 권장.
β 1.4.17 2026.04.21
TRAINING · PRIORITY · ALL MODES
  • 투구·수비 추천 훈련도 약점 중심으로 통일 — β 1.4.16 에서 타격(gBD) 에 적용한 약점 우선순위 알고리즘을 투구(gPD) · 내야땅볼(gFD) · 내야플라이(gFD_fly) · 포수(gCD) · 외야(gOD) 전 영역에 동일하게 이식. warmup 1 + 점수<75 인 phase 상위 3개(낮은 점수 우선) + 실전 기본 연습 1 + (평균<60 시 코어 1) 구조로 통일.
  • 수정 포인트별 상세 — (1) gPD: 6 phase(코킹·스트라이드·와인드업·가속·릴리스·팔로스루) 중 약점 상위 3개만, avg<85 무조건 심화 드릴 제거. (2) gFD: 5 phase(준비자세·어프로치·글러브·트랜지션·송구) 중 상위 3개. (3) gFD_fly: 5 phase + 베이스 실전 연습 1개만 유지, 선라이트 드릴 제거. (4) gCD: base drill 전체를 채워 넣던 fallback 제거 — 점수와 무관하게 8개 고정되던 문제 해결. (5) gOD: 인접 드릴 자동 push 로직 제거.
  • 결과 — 투구 최대 13종 → 6종, 수비 최대 8종 → 5종으로 압축. 모두 우수(avg≥75) 인 경우 최소 2~3개만 뜨도록 깔끔해짐.
  • 캐시 버전 v156→v157 — 배포 후 PWA 강제 업데이트 권장.
β 1.4.16 2026.04.21
TRAINING · PRIORITY
  • 타격 추천 훈련 폭주 해결 — gBD() 약점 중심 재설계 — 기존 로직은 phase 점수가 낮을수록 같은 phase 에 2~3개 드릴을 한꺼번에 밀어넣고, 평균<85 이면 심화 실전 드릴 4개를 무조건 추가해 최대 13개까지 추천 목록이 부풀어 올랐습니다. 비슷한 드릴이 중복 노출되어 "어디부터 손대야 할지" 혼란.
  • 수정안 — (1) warmup 1개 고정 + 가장 약한 phase 3개(점수<75)만 선정해 각 phase 당 난이도에 맞춘 드릴 1개씩. (2) 점수 낮은 phase 가 앞으로 오도록 정렬 → 우선순위가 한눈에 보임. (3) 티 배팅 1개 고정(가장 범용 실전). (4) 코어 강화는 평균<60 일 때만. (5) 기존 자동 심화 드릴 4종(연속 티·카운트 시뮬·워킹 스윙 등) 삭제.
  • 결과 — 추천 훈련이 최대 6개로 압축 (warmup 1 + 약점 3 + 티 배팅 1 + 코어 최대 1). 평균 ≥75 인 경우 최소 2개(warmup + 티 배팅)까지 깔끔해짐.
  • 캐시 버전 v155→v156 — 배포 후 PWA 강제 업데이트 권장.
β 1.4.15 2026.04.21
CRITICAL · DETECTION
  • 투구폼 오감지 근본 재수정 — detectArmSlot 3차 개편 — β 1.2.9 수정 이후에도 명백한 오버핸드 투구가 언더핸드로 오분류되던 사례가 재발. 원인은 릴리스 프레임 탐색 로직이 "손목-어깨 거리 최대" 방식이라 팔로스루에서 손이 몸통 반대편으로 크게 돌 때 팔로스루 프레임을 릴리스로 오판하고, 그 ±3 프레임 평균이 이미 팔꿈치가 내려온 구간 중심으로 잡히면서 음수 elev 가 나오는 것이었습니다.
  • 수정안 — (1) 릴리스 프레임 탐색을 "손목 속도 최대" 기준으로 전환 (생체역학적으로 공이 손을 떠나는 순간이 손목 속도 피크). (2) SAFETY NET: 투구 중 팔꿈치 피크 높이가 어깨보다 확실히 위 (0.12 × torso 이상) 또는 어깨 위 프레임이 전체 20% 이상이면 릴리스 계산과 무관하게 무조건 오버핸드로 고정. (3) 언더핸드 문턱을 -0.15 → -0.30으로 2배 엄격히 (팔꿈치가 몸통의 1/3 이상 아래로 내려갈 때만). (4) 탐색 구간 60~85%30~85%로 확장하여 코킹 피크 포착. (5) 애매한 경우 오버핸드 default 원칙 유지.
  • 캐시 버전 v154→v155 — 배포 후 PWA 강제 업데이트 권장.
β 1.4.14 2026.04.21
TRAINING · CLEANUP
  • 추천 훈련 목록 정리 — 분석 결과 화면의 추천 훈련 리스트에서 ① 가볍게 캐치볼 (교정 목적이 약한 일반 캐치볼), ② 슬라이드 스텝 드릴 (주자 견제) (유소년 투구 분석 범위와 어긋남), ③ 프로선수 롤모델 카드 (하단 프로선수 롤모델 섹션과 중복) 세 가지를 제거했습니다. 이제 훈련 카드는 실제 교정에 직결되는 단계별 드릴만 남습니다.
  • 타격 6-cap 로직 단순화 — 기존에는 롤모델 카드를 고정 마지막에 유지하기 위한 splice/re-push 처리가 들어가 있었는데, 롤모델이 리스트에서 빠지면서 단순 sort + _extra 플래그만 남겨 가독성을 개선했습니다.
  • 캐시 버전 v153→v154 — 배포 후 PWA 강제 업데이트 권장.
β 1.4.13 2026.04.21
PDF · REPORT
  • 분석 결과 PDF 저장이 이제 전체 내용을 담습니다 — 지금까지는 1페이지짜리 요약(피드백 4개 + 드릴 3개)만 저장되던 것을, 분석 화면에 표시되는 모든 코칭 피드백 · 모든 추천 훈련(기본 + 더보기 포함) · 프로선수 롤모델 · 코치 한마디 까지 자동으로 여러 페이지에 걸쳐 저장하도록 재작성했습니다.
  • 코칭 피드백 3단 구성 그대로 — 각 피드백 카드의 현상 → 원인 → 교정 라벨링을 PDF에도 그대로 기재하고, 앵글 측정 뱃지도 카드 우측에 표시됩니다.
  • 페이지 자동 분할 + 페이지 번호 — 내용이 한 페이지를 넘으면 새 페이지가 자동 생성되며, 하단에 페이지 번호가 찍힙니다. 공유·출력 시에도 잘림이 없도록 여백 계산을 개선했습니다.
  • 캐시 버전 v152→v153 — 배포 후 PWA 강제 업데이트 권장.
β 1.4.12 2026.04.21
TRAINING · UX
  • 추천 훈련 카드 기본 노출 6개로 축소 — 타격 분석 이후 추천 훈련 카드가 최대 9개까지 한 번에 노출되어 스크롤이 지나치게 길어지던 문제를 해결했습니다. 이제 핵심 6개 + 프로선수 롤모델 만 기본 노출되며, 약점 구간이 많아 기획된 드릴이 6개를 초과하면 하단에 + 드릴 더 보기 (N개) 버튼이 나타나 원하는 선수만 나머지 드릴을 펼쳐볼 수 있습니다.
  • 성장 기록 상세 화면에도 동일 적용 — 과거 분석 상세에서도 6개 + 더보기 버튼 방식으로 통일해, 긴 드릴 리스트를 빠르게 훑고 필요할 때만 펼쳐볼 수 있습니다.
  • 프로선수 롤모델은 항상 고정 노출 — 약점 참고용 롤모델 카드는 cap 로직과 무관하게 항상 마지막에 표시됩니다.
  • 캐시 버전 v151→v152 — 배포 후 PWA 강제 업데이트 권장.
β 1.4.11 2026.04.21
TRAINING · CONTENT
  • 타격 심화 드릴 6종 추가 — 기존 타격 훈련 모듈에 새로운 심화 드릴이 탑재되어, 약점 구간 점수가 낮은 선수에게 더 구체적인 페어 드릴이 제안됩니다: ① 바텀핸드 원핸드 스윙 (탑핸드 드릴과 한 쌍), ② 아웃사이드 반대 방향 타격 (인사이드 풀과 한 쌍), ③ 하이 티 드릴 · ④ 로우 티 드릴 (높은 공 · 낮은 공 대응 페어), ⑤ 힙 퍼스트 로드 드릴 (하체 선행 감각), ⑥ 워킹 스윙 드릴 (걸으며 스윙 — 체중 이동 연결).
  • 훈련 영상 맵 정리DRILL_VIDEO_MAP 에서 푸시 타이틀과 맵 키의 괄호 suffix 불일치로 영상이 연결되지 않던 5건(런지 워크, 스트라이드 연습, 스텝 드릴, 드라이 스윙, 하프 스쿼트 드릴)에 짧은 별칭 엔트리를 추가했습니다. 이제 훈련 카드에서 동영상이 정상적으로 나옵니다.
  • 파일 끝 재잘림 긴급 복구 — β 1.4.10 배포 과정에서 재발한 app.html 끝부분 truncation (DRILL_VIDEO_MAP 중간에서 잘림 → </script></body></html> 누락)을 bak_histdet 꼬리 splice 로 복구. 5개 스크립트 블록 node --check 통과 확인.
  • 캐시 버전 v150→v151 — 배포 후 PWA 강제 업데이트 권장.
β 1.4.10 2026.04.21
CRITICAL · DATA-SAFETY
  • init 크래시 긴급 핫픽스 — β 1.4.9 배포 이후 icoImg is not defined 참조 에러로 앱이 시작 단계에서 튕기는 현상 보고. applyIcons()를 try/catch로 격리하고, 하위 스크립트 블록이 파싱 실패해도 icoImg가 정의되지 않은 상태에서 호출되지 않도록 얼리 스텁을 삽입했습니다.
  • 파일 끝 잘림 복구 — 배포본 app.html 의 2번째 스크립트 블록이 잘려 있어 전체 스크립트 파싱이 실패하던 문제를 백업 splice로 복구했습니다. 이로 인해 일부 사용자가 경험한 "데이터 소실" 체감은 실제 데이터 삭제가 아니라 localStorage 에서 읽기 실패로 화면만 비어 보이던 증상이었음을 확인했습니다.
  • 캐시 버전 v149→v150.
β 1.4.9 2026.04.21
CRITICAL · RANKING · CLOUD
  • 랭킹보드 "내 것만 보이던 버그" 수정 — 타자왕/투수왕/수비왕 탭을 눌러도 자기 기록 1개만 뜨던 심각한 버그를 수정했습니다. 원인은 fetchLeaderboard()rankings.orderBy('score','desc').limit(50)전체 모드의 상위 50명만 받은 뒤 클라이언트에서 모드 필터를 적용하던 구조였습니다. 상위 50이 특정 모드(예: 분석왕) 에 편중되면, 다른 모드 탭에는 내 문서 말고 아무것도 남지 않았습니다. 이번 릴리즈에서 서버측 where('mode','==',X) 필터를 쓰도록 바꾸고, 복합 인덱스가 없으면 limit(300) 폴백으로 받아와 클라이언트에서 거르도록 이중 안전장치를 넣었습니다. 전체 모드 리밋도 50 → 200, 최종 슬라이스도 20 → 50 으로 상향했습니다.
  • ☁ 히스토리 클라우드 동기화 (users/{uid}/history) — 지금까지 분석 기록이 브라우저 localStorage 에만 있어, 기기를 바꾸거나 캐시를 지우면 데이터가 사라지는 구조적 위험이 있었습니다. 이번 릴리즈부터 모든 분석 기록이 Firestore users/{uid}/history/{date} 에 자동 저장됩니다. 분석 완료 시 자동 업로드, 앱 시작 시 자동 다운로드(기존 사용자만), 설정 → ☁ 클라우드 동기화 메뉴에서 수동으로 올리기/내려받기/양방향 동기화 가능.
  • 버전 백업 자동화checkVersionAndBackup()importData() 안에서만 호출되던 버그를 수정. 앱 시작 시 init() 에서 자동 호출되도록 바꿔, 업데이트만 받은 사용자도 이전 버전의 분석 기록이 자동으로 버전 백업 리스트에 남도록 보강했습니다.
  • 관리자 도구 — 📊 랭킹 진단 버튼 — 관리자 모드에서 rankings 컬렉션의 모드별 문서 수, 고유 UID 수, 점수 분포, 최근 등록 10건을 한눈에 확인. "실제로 다른 사용자 데이터가 있는지 / 내 필터 버그인지" 빠른 판별용.
  • ⚠ 보안 규칙 추가 필요users/{uid}/history/{docId} 에 대한 Firestore 규칙이 아직 없으면 동기화가 실패할 수 있습니다. FIRESTORE_AUTH_SETUP.md 에 추가된 규칙 블록을 Firebase Console → Rules 에 반영해주세요.
  • 캐시 버전 v148→v149 — 배포 후 PWA 강제 업데이트 권장.
β 1.4.8 2026.04.21
CRITICAL · PDF
  • PDF 리포트 한글 깨짐 수정 — 성장기록에서 [PDF] 버튼으로 내려받은 리포트에서 "아이코치", 선수 이름, "타격 분석", "능력치 분석" 등 모든 한글이 네모/물음표로 깨져서 출력되던 치명적 버그를 수정했습니다.
  • 원인 — jsPDF 라이브러리가 기본으로 쓰는 내장 폰트(Helvetica 등 Type 1 14종)는 WinAnsi 인코딩(Latin-1) 만 지원하며 한글 글리프 자체가 존재하지 않습니다. 한글 유니코드(U+AC00~U+D7A3)를 이 폰트로 그리라고 넘기면 테이블에 없는 코드포인트라 깨진 글자로 렌더됐습니다.
  • 해결Spoqa Han Sans Neo Regular/Bold TTF 2종을 앱의 ./fonts/ 폴더에 배치하고, PDF 버튼을 누른 순간 fetch → base64 인코딩 → doc.addFileToVFS() + doc.addFont() 로 jsPDF 에 주입하는 로직을 loadPDFKoreanFonts() 헬퍼로 구현했습니다. 첫 호출 이후에는 window.__pdfKoreanFonts 에 캐시되어 재호출 시 fetch 하지 않습니다.
  • Spoqa Han Sans Neo 선택 이유 — Noto Sans CJK 를 기반으로 제작된 오픈 라이선스(OFL) 한글 폰트로, Regular + Bold 둘 다 제공되어 섹션 타이틀/점수를 강조할 수 있고, KS X 1001 + 추가 한글 2,574자 를 500KB 미만으로 커버합니다. Noto Sans KR 의 공식 TTF는 단일 파일이 4MB 이상이라 PDF 임베딩용으로는 과도합니다.
  • 렌더링 품질 향상 — "아이코치" 로고, "능력치 분석"/"단계별 점수"/"코칭 피드백"/"추천 훈련" 섹션 타이틀, 종합 점수 숫자에 Bold 가중치가 적용되어 가독성이 확연히 개선됩니다.
  • 기타 정리 — 훈련 추천 리스트의 불릿 가 Spoqa 폰트에 없어 로 대체했습니다. 오프라인 PWA 도 정상 작동하도록 서비스워커 ASSETS_TO_CACHE 에 TTF 2종을 프리캐시 목록에 추가했습니다.
  • 캐시 버전 v147→v148 — 배포 후 PWA 강제 업데이트 또는 홈 화면에서 다시 설치 권장.
β 1.4.7 2026.04.21
UX · HISTORY
  • 성장기록 → 분석기록 상세화면 전면 개편 — 분석 직후 보던 모든 내용을 그대로 복원 — 기존에는 성장기록 탭에서 과거 분석을 눌렀을 때 점수·능력치·단계별 점수만 요약해서 보여줬습니다. 그래서 "이 분석에서 AI 가 뭐라고 피드백 줬는지", "어떤 훈련을 추천했는지", "코치 코멘트는 뭐였는지" 가 전혀 보이지 않아, 사용자가 다시 확인하려면 또 분석을 돌려야 하는 불편이 있었습니다. 이번 릴리즈에서는 분석 직후에 보이는 전체 결과 화면과 동일한 내용이 상세화면에 그대로 나타나도록 바꿨습니다. 점수·능력치·단계별 점수에 더해 AI 피드백(이유/개선 방법 토글 포함), 추천 훈련 드릴 카드, 암슬롯 정보(투구), 코치 코멘트 까지 전부 확인 가능합니다.
  • 신규 분석은 풀 데이터 저장 — 분석 완료 시점에 feedback, drills, armSlot, coachComment, fieldingTypeicoach_history localStorage 에 함께 저장하도록 addHistory() 호출부 두 곳을 모두 보강했습니다. 앞으로 기록되는 모든 분석은 상세화면에서 원본 전체를 바로 복원합니다.
  • 레거시 기록도 자동 복원 — β 1.4.7 이전에 저장된 기존 분석 기록들은 feedback/drills 가 비어 있지만, 저장된 phases(단계별 점수) 와 mode/fieldingType 을 기반으로 gPD·gBD·gFD·gFD_fly·gCD·gOD 드릴 생성 함수를 재호출해 추천 훈련 카드를 실시간 재구성합니다. 피드백이 완전히 없는 초기 기록에는 "이 분석은 피드백/훈련 추천이 저장되기 전 기록입니다" 안내가 표시됩니다.
  • 훈련 카드 서브라인 방어적 폴백d.tag/d.cat 이 비어 있는 드릴(특히 gFD_fly() 팝플라이 드릴 7종) 에서 "undefined · 훈련" 으로 표시되던 현상이 있었습니다. catcategory 순서로 조회하고, 없을 때는 {warmup:'쉬움', form:'기본', strength:'보통', practice:'실전', advanced:'심화'} 매핑으로 자동 폴백되도록 렌더러를 보강했습니다.
  • 캐시 버전 v146→v147 — 배포 후 PWA 강제 업데이트 또는 홈 화면에서 다시 설치 권장.
β 1.4.6 2026.04.20
ACCURACY · UX
  • 경기 분석에 "우리 아이 식별 정보" 입력 추가 — 기존에는 Gemini 가 프레임과 상황 설명 텍스트만으로 타겟 선수를 추정해야 해서, 여러 야수가 한 프레임에 같이 찍히는 수비 영상에서 엉뚱한 선수를 분석할 위험이 있었습니다. 이번 릴리즈에서 각 역할(투구/타격/수비)별 영상 업로드 카드 아래에 등번호 · 유니폼 상의 색 · 포지션 세 칸을 추가했고, 입력값은 AI 프롬프트에 [타겟 선수 식별 정보] 블록으로 자동 삽입됩니다.
  • AI 프롬프트 규칙 강화 — "위 정보와 일치하는 선수만 분석 대상으로 삼고, 다른 선수의 동작은 참고용으로만 사용할 것. 일치하는 선수를 특정할 수 없으면 observations 첫 항목에 식별 실패를 명시하고 score=0" 지침이 함께 전달됩니다. 수비처럼 타겟 구분이 어려운 장면에서 오분석 위험이 크게 줄어듭니다.
  • 역할별 안내 문구 차등화 — 투구/타격 카드에는 "한 명만 주인공이라 선택 입력이지만 채우면 정확도↑", 수비 카드에는 "필수에 가깝습니다" 경고 문구를 자동 표시합니다.
  • 상황 설명 가이드 카피 보강 — "좋은 분석 결과를 받으려면?" 접힘 카드의 상황 설명 팁에 "여러 선수가 함께 찍힌 수비 영상은 식별 정보도 꼭 채워주세요" 안내를 추가했습니다.
  • 캐시 버전 v144→v145 — 배포 후 PWA 강제 업데이트 또는 홈 화면에서 다시 설치 권장.
β 1.4.4 2026.04.20
UX · 안내
  • 경기 분석 화면 상단에 API 키 상태 배너 추가 — "AI 경기 분석"은 유일하게 Gemini API 키가 반드시 필요한 기능입니다. 이전까지는 영상과 상황 설명을 다 입력한 뒤 [분석 시작] 버튼을 누른 순간에야 "키 필요" 토스트로 차단돼 헛수고가 많았습니다. 이제 경기 분석 화면에 들어오자마자 상단에 빨간 배너로 "API 키가 필요해요 · 설정에서 무료 등록 →" 가 표시되고, 바로 설정 화면의 키 입력란으로 포커스가 이동합니다.
  • 키가 등록되어 있으면 "AI 경기 분석 준비 완료" 녹색 배지로 전환 — 언제든 "변경" 버튼으로 키를 수정할 수 있습니다. 설정에서 키를 저장/삭제하는 즉시 배너도 자동 갱신됩니다.
  • 키 없을 때 "AI 경기 분석이란?" 가이드 기본 펼침 — 키 등록이 필요한 이유와 흐름을 바로 보여드립니다. 키가 있는 사용자는 기존처럼 접힌 상태로 유지돼 공간을 차지하지 않습니다.
  • 투구·타격·수비 폼 분석은 API 키 없이도 그대로 사용 가능 — 온디바이스(MediaPipe) 로 기기 안에서만 처리되므로 영상이 서버로 나가지 않습니다. 훈련 드릴 영상 인증도 키가 없으면 "자동 검증만 생략" 하고 분석·적립은 정상 진행됩니다.
  • 캐시 버전 v143→v144 — 배포 후 PWA 강제 업데이트 또는 홈 화면에서 다시 설치 권장.
β 1.4.3 2026.04.20
CRITICAL · HOTFIX
  • ⚠️ 치명적 버그 수정: app.html 파일 끝부분 잘림 복구 — 이전 배포본(β 1.4.0~1.4.2)의 app.html 이 파일 끝(약 8.72MB, 11,907줄)에서 UTF-8 문자 중간에 잘린 채로 올라가 있었습니다. 이 때문에 거대한 인라인 스크립트 블록의 </script> 닫힘 태그와 </body></html> 이 전부 사라져, DRILL_YOUTUBE 정의 이후 openDrillGuide/closeDrillGuide 같은 보조 함수가 실행되지 못했습니다. 그 결과 홈 탭의 총 분석 수·점수, 전국 랭킹 리스트, 성장기록 화면이 모두 빈 상태로 나타나던 것입니다. 이번 릴리즈에서 최종 완전본 백업(app_20260419_060149_pre_analyst_img.html)의 꼬리 블록을 이어 붙여 파일을 복구했고, JS 구문 검사(node --check)도 통과했습니다.
  • 훈련 탭 "투수/타격/수비 코치에게 질문" 버튼 아이콘 깨짐 수정 — 거대한 인라인 스크립트가 파싱되는 동안 DOMContentLoaded 이벤트가 이미 발생해, 아이콘을 채워주는 initializeIcons() 의 리스너가 한 박자 늦게 등록되면서 한 번도 실행되지 않던 문제가 원인이었습니다. 이제 스크립트 끝에서 document.readyState 를 확인해 이미 DOM 이 준비되어 있으면 즉시 initializeIcons() 를 실행하도록 보강했습니다.
  • 함께 개선된 아이콘 영역 — 촬영 가이드 4칸(각도/거리/환경/길이), 영상 업로드 아이콘, 분석 결과의 "능력치/단계별 점수", 추천 훈련, 안전 안내, 랭킹 뱃지 등 ID 기반으로 로드되던 모든 아이콘도 동일한 타이밍 이슈의 영향을 받고 있었는데 이번 패치로 함께 안정화됩니다.
  • 캐시 버전 v142→v143 — 배포 후 PWA 강제 업데이트(F12 → Application → Service Workers → Update) 또는 홈 화면에서 다시 설치 권장.
β 1.4.2 2026.04.20
POLISH · UI
  • 설정 화면 기본 이모지 아이콘 5종을 전용 아이콘 PNG로 교체 — "버그 제보 & 기능 제안", "법적 정보", "지원·문의", "문의하기(구글 폼)", "이메일로 문의" 항목의 📄💬📮✉️ 이모지를 나노바나나로 생성한 128×128 네이비·골드 톤 아이콘으로 대체했습니다. OS별 이모지 편차가 사라져 브랜드 톤이 일관됩니다.
  • 서비스 워커 프리캐시 목록 확장 — 신규 아이콘 5종(icon_bug_report / legal / support / form / email)을 ASSETS_TO_CACHE 에 추가해 오프라인에서도 깨지지 않도록 했습니다.
  • 캐시 버전 v141→v142
β 1.4.1 2026.04.20
FIX
  • 추천 훈련 카드 줄바꿈 교정 — 챗 버블 안 "추천 훈련" 리스트에서 제목(예: "기본스윙연습")과 설명이 같은 줄에 붙어 흘러 가독성이 떨어지던 문제를 고쳤습니다. drill-suggest-item 레이아웃을 flex + 스택 제목/설명 구조로 바꾸고 word-break:keep-all을 적용해 한글 단어가 어색하게 잘리지 않도록 했습니다.
  • 캐시 버전 v140→v141
β 1.4.0 2026.04.20
SECURITY · EVENT
  • 계정 보호 시스템 도입 — 5월 오픈베타 이벤트 공정성 확보 — 같은 선수인데 아빠/아들 폰에서 각각 가입되어 중복 계정이 생기거나, 이름만 알면 남의 계정으로 기록을 등록할 수 있던 구조적 취약점을 해소했습니다.
  • 이름 + 생년월일 + 4자리 PIN — 신규 가입 시 생년월일(YYYY-MM-DD)과 4자리 PIN을 등록합니다. PIN은 SHA-256 + 생년월일 salt 로 해싱되어 Firestore 에는 평문이 저장되지 않습니다. 3회 실패 시 24시간 잠금으로 무차별 시도를 차단합니다.
  • 가족 폰 자동 연결 — 다른 폰에서 같은 이름·생년월일 입력 시 "이미 가입된 계정이에요" 안내 후 PIN 확인만으로 기존 계정에 연결됩니다. 아빠·엄마·본인 폰이 하나의 icoach_uid 를 공유합니다.
  • 소속 분리 — 학교 / 야구클럽팀 — 기존 단일 "소속" 필드를 학교 + 야구클럽팀 두 필드로 분리하고, Firestore 에 이미 등록된 값을 모아 <datalist> 자동완성을 제공합니다. "군베이스볼" / "군 베이스볼" / "군BB" 같은 표기 차이로 인한 오인식이 크게 줄었습니다.
  • 기존 사용자 강제 마이그레이션 — β 1.4.0 첫 실행 시 기존 사용자에게 1회성 모달이 뜨고 생년월일 + PIN 을 등록해야 앱 사용이 가능합니다. 기존 icoach_uid 는 그대로 유지되어 분석 히스토리·랭킹 기록은 보존됩니다.
  • 계정 보호 없이는 랭킹 등록 불가autoSubmitRanking()birth + pinHash 존재 여부를 선검사하고, 미보호 계정은 즉시 마이그레이션 모달로 안내합니다.
  • Firestore 보안규칙 추가 (accounts 컬렉션) — 문서 ID = uid, pinHash 변경 금지, 이름/생년월일 변경 금지, 삭제 금지. 자세한 내용은 프로젝트 루트의 FIRESTORE_AUTH_SETUP.md 참조.
  • 캐시 버전 v136→v140
β 1.3.2 2026.04.19
SUPPORT · OPS
  • 파일럿 운영 Phase 2 완료 — 지원·배포 인프라 정비 — 단톡방 100명 파일럿을 본격 돌릴 수 있도록 문의 창구·긴급 롤백·홍보 자료를 한 번에 정비했습니다.
  • 설정 → 💬 지원·문의 카드 신설 — "문의하기(구글 폼)" + "이메일로 문의" 버튼 추가. 버전·UID가 자동으로 prefill 되어 제보 처리가 빨라집니다.
  • 긴급 점검 모드 (Kill-switch) — Firestore config/maintenance 문서를 관리자가 켜면, 앱 진입 시 즉시 점검 안내 모달이 뜨고 필요 시 전면 차단도 가능합니다. 클라이언트 재배포 없이 실시간 대응이 가능해졌습니다.
  • 파일럿 FAQ 1페이지 + 단톡방 홍보 문구 2종 + QR — 학부모 배포용 외부 자료 일괄 준비 (FAQ_파일럿.md, 홍보문구_단톡방.md, QR_icoach_ai_kr.png).
  • 동의 마이그레이션 모달 CSS 클래스 불일치 후속 정리 — β 1.3.1 hotfix(.active → .show) 상시화 및 모달 문구 버전 표기 보정.
β 1.3.1 2026.04.19
LEGAL · OPS
  • 출시 전 블로커 해소 — 100명 파일럿 준비 — 군베이스볼 학부모 단톡방 비공식 파일럿 출시를 위한 법적·운영 요건을 일괄 반영했습니다.
  • 개인정보 처리방침 / 이용약관 고지 — 앱 하단 법적 정보 카드 + 최초 가입 시 체크박스 3개(약관·방침·법정대리인 동의). 기존 사용자에게는 접속 시 마이그레이션 모달을 1회 표시합니다.
  • 닉네임 금칙어 필터 + 관리자 차단 — 한글 우회(ㅅㅂ, ㅂㅅ 등) 대응 정규화 + 50개 이상 금칙어. 관리자 도구에 "닉네임 관리" 탭 추가 — 부적절한 닉네임 삭제 + UID 블랙리스트로 재가입 차단.
  • Firestore 한도 방어 — 랭킹 쿼리 limit(100)→limit(50), 새로고침 버튼 추가 + 5초 쿨다운, 30초 메모리 캐시로 중복 호출 차단. 예상 DAU 30명 기준 Spark 무료 한도의 15% 내에서 운영.
  • 영상 기기 저장 검증 완료 — 코드 grep으로 Firebase Storage SDK 미사용 확정. Gemini Vision에는 정지 이미지(JPEG 프레임) 최대 20장만 전송되며 영상 원본은 기기 밖으로 나가지 않습니다.
β 1.3.0 2026.04.19
FEAT
  • 랭킹 공식 전면 개편 — 점수 "지키기" 방지 — 타자왕·투수왕·수비왕의 점수를 최고점에서 "최근 7회 중 상위 5회 평균"으로 교체했습니다. 기존 시스템은 한 번 좋은 기록이 나오면 점수 하락이 두려워 분석을 기피하게 만드는 구조였습니다. 새 공식은 부진한 2회까지 "용서"하되 최근 폼에 민감하게 반응합니다.
  • 랭킹 진입 기준 상향 — 최소 분석 횟수 3회 → 5회, 20점 이상 유효 분석 2회 → 3회. 상위 5회 평균을 산출하기 위한 표본 요건입니다.
  • 분석왕 공식 — 최근 활동 가중 — 누적 분석 횟수만 세던 방식에서 총 분석 × 0.5 + 최근 30일 분석 × 2.0 으로 변경. "과거 한 달에 수십 회 찍고 방치" 보다 "꾸준히 분석하는 선수"가 우대됩니다.
  • 훈련왕 공식 — 최근3 vs 최초3 상승폭 — 그동안 임시로 score desc 였던 훈련왕 기준을 실제 "최근 3회 평균 − 최초 3회 평균"의 성장 곡선으로 바꿨습니다 (표본 6회 이상 필요).
  • 오픈베타 이벤트(5/1~5/31) 참여 패널티 레이어 — 점수 "지키기"를 원천 차단. 이벤트 기간 동안
    · 해당 모드 주간 미분석 1주당 −3점
    · 일일 훈련 미완료 1일당 −1점
    이 기본 점수에서 차감됩니다. 평상시 상시 랭킹에는 적용되지 않습니다.
  • 랭킹 탭 UI — 자동 등록 카드에 이벤트 패널티 배지(주간 미참여 × 일일 미완료)와 "이벤트 점수 = 기본 − 패널티" 라인을 추가. 리더보드도 이벤트 기간엔 eventNetScore 기준으로 재정렬됩니다.
  • Firestore 스키마 확장recent30Count · improvementDelta · eventWeeklyMisses · eventDailyMisses · eventPenalty · eventNetScore · scoreFormula 필드 추가. 구버전 문서는 하위 호환(분석왕은 0.5× 대체, 훈련왕은 자연 배제).
  • 캐시 버전 v132→v133
β 1.2.9 2026.04.19
FIX
  • 투구폼 오감지 버그 수정 — detectArmSlot 재작성 — 명확한 오버핸드 투구가 "사이드암"으로 잘못 분류되던 문제를 해결. 기존 알고리즘은 (a) 50~85% 구간 전체를 평균내어 코킹 단계의 음수 각도와 릴리스 단계의 양수 각도가 상쇄되어 중간값이 나오고, (b) Math.abs()로 앞뒤 방향 정보가 소실되며, (c) 우완 투수만 처리하여 좌완은 오분류되는 구조적 결함이 있었습니다.
  • 단일 릴리스 프레임 + 상완 높이 비율 — 탐색 구간을 60%~88%(팔로스루 배제)로 좁히고, 던지는 팔 손목이 어깨에서 가장 먼 릴리스 프레임을 찾아 ±3 프레임 평균으로 (어깨-팔꿈치)/몸통길이 비율을 계산합니다. 양수(어깨 위)는 오버핸드, 0 근처(어깨 레벨)는 사이드암, 음수(어깨 아래)는 언더핸드.
  • 좌투수 자동 판별 — 좌·우 손목의 x 이동 범위를 비교해 던지는 팔 자동 감지. 좌완 투수도 같은 알고리즘으로 정확히 분류됩니다.
  • 단위 테스트 4/4 통과 — 우투 오버핸드·사이드암·언더핸드 + 좌투 오버핸드 시나리오를 mock 랜드마크로 검증.
  • 캐시 버전 v131→v132
β 1.2.8 2026.04.19
FEAT
  • 보너스 훈련 카드 기능 강화 — "새 분석 기반 보너스 훈련" 카드가 체크박스만 있던 문제를 해결. 이제 일반 훈련 카드와 동일하게 시범 영상 버튼훈련방법 모달을 제공해 "목적 · 방법 · 횟수 · 주의점" 전체 가이드를 바로 볼 수 있습니다.
  • showDrillGuide 리팩터링source 인자('bonus' | 기본) 추가. 보너스 드릴은 window.__bonusDrills 캐시를 참조해 오늘의 훈련 목록과 인덱스 충돌 없이 독립적으로 동작합니다.
  • 보너스의 "가벼움" 유지 — 레벨 배지·즐겨찾기·인증영상·타이머는 의도적으로 제외. 정규 훈련 완료 후 이라는 보너스 맥락은 그대로입니다.
  • 캐시 버전 v130→v131
β 1.2.7 2026.04.19
FEAT
  • 랭킹 진입 최소 기준 도입 — 1~2회만 분석하고 떠나는 사용자가 상위 랭킹을 왜곡하는 문제를 해결했습니다. 이제 3회 이상 분석 + 그 중 20점 이상 분석이 2회 이상인 사용자만 공식 랭킹에 표시됩니다.
  • "랭킹 도전 중" 섹션 신설 — 기준 미달 사용자는 별도 섹션에 점수·분석 횟수·남은 횟수 와 함께 노출되어, 완전히 숨겨지지 않고 진행 상황을 볼 수 있습니다.
  • 내 랭킹 진입 진행 UI — 자동 등록 카드에 ●●○ 진행 도트와 "랭킹까지 N회 더!" 안내 문구를 추가했습니다. 재방문 동기부여를 위한 UX.
  • 저장 데이터 확장 — Firestore 문서에 validAnalysisCount 필드 추가 (20점 이상 분석 수). 기존 데이터는 analysisCount 로 대체 계산하여 하위 호환성 유지.
  • 캐시 버전 v129→v130
β 1.2.6 2026.04.19
FIX
  • PC 관리자 모드 입력 시 화면 멈춤 최종 해결 — β 1.2.5의 SW 패치로도 남아 있던 PC 고유 freeze 를 해결했습니다. 크롬 비밀번호 매니저 / 1Password / LastPass / Bitwarden 등의 확장프로그램이 <input type=password> 를 가로채 Enter 시점에 페이지를 멈추게 하던 것을 차단 속성(autocomplete=off · data-lpignore · data-1p-ignore · data-bwignore)으로 막고, DOM 토글을 requestAnimationFrame 으로 비동기화했습니다.
  • 관리자 모드 콘솔·URL 백도어 — UI 로 못 들어갈 때 쓰는 보조 경로를 추가했습니다.
    • 콘솔: adminOn('ironarm0529') / adminOff()
    • URL: ?admin=ironarm0529 를 주소 끝에 붙이면 자동 진입
  • 진단 로그unlockAdmin() 진행 단계마다 [admin] unlock 타임 마커가 콘솔에 찍혀 혹시 또 멈추더라도 정확한 freeze 지점을 식별할 수 있습니다.
  • 캐시 버전 v128→v129
β 1.2.5 2026.04.19
FIX
  • 랭킹 크로스 디바이스 동기화 복구 — PC에서 만든 계정이 모바일 랭킹에 안 뜨던 문제 해결. Firestore 보안 규칙의 uid == docId 검사가 실제 문서ID 스키마(uid + '_' + mode)와 일치하지 않아 모든 쓰기가 Missing or insufficient permissions 로 거부되던 것을 수정했습니다.
  • 수비 모드 랭킹 저장 가능 — 규칙에 'defense' mode 허용값을 추가. 이전에는 수비 분석 결과가 Firestore에 전혀 저장되지 않았습니다.
  • 관리자 모드 — 일일 분석 제한 해제 — 랭킹 탭 하단 "관리자 도구"에서 비밀번호 입력 시 일일 1회 제한이 풀려 테스트·QA 용으로 여러 번 분석이 가능합니다. 새로고침해도 유지되며, "모드 해제" 버튼으로 끌 수 있습니다. 분석 화면 상단에 🔓 배지로 현재 상태가 표시됩니다.
  • 점수 타입 완화 — Firestore 규칙 score is intis number (소수점 평균 점수 허용)
  • [PATCH] Service Worker 프리즈 버그 수정 — PC에서 관리자 모드 진입 시 화면이 멈추던 현상 해결. Chrome 확장프로그램이 보내는 chrome-extension:// 스킴 요청을 SW가 캐시하려다 TypeError 가 폭주해 메인 스레드를 막던 것을 차단했습니다.
  • 캐시 버전 v126→v128
β 1.2.4 2026.04.19
UPDATE
  • 프로 선수 비교 — 숫자 대신 한글 코치 코멘트 — 기존에는 "팔꿈치 131/95 (+36)" 같은 숫자를 보여줬는데, 부모나 아이가 숫자만 보고 판단하기 어려워 "릴리스 때 팔이 너무 펴져 있어요. 살짝 더 굽혀서 채찍처럼 가속해보세요." 처럼 코치가 말해주는 한 줄 피드백 으로 바꿨습니다. 분석 로직(몸통 기울기 포함)은 그대로 유지됩니다.
  • 상태 아이콘 — 각 항목 옆에 ✓(범위 안) · !(교정 필요) 아이콘과 색(초록/금/빨강)으로 한눈에 상태를 파악할 수 있습니다.
  • 투구·타격 11개 지표 코멘트 세트 내장 — 팔꿈치, 앞·뒷무릎, 보폭, 몸통 틸트, 분리각, 어깨 MER, 힙턴, 헤드스테이, 배트 앵글, 웨이트 시프트 모두 상황별(too-high / too-low / good) 3단계 코멘트를 준비했습니다.
  • 캐시 버전 v125→v126
β 1.2.3 2026.04.19
FIX
  • 프로 고스트·궤적·관절 표시가 영상에 안 보이던 문제 수정 — 두 가지 원인이 겹쳐 있었습니다. ① 재생 중 오버레이 갱신이 ontimeupdate(약 4회/초)에만 의존해 프레임 간 공백이 생겼고, ② 와이드샷·모션블러로 특정 프레임에서 MediaPipe 검출이 실패하면 해당 프레임이 통째로 비어 있었습니다.
    수정: requestAnimationFrame 기반 상시 렌더 루프(재생 중 60회/초) + 가까운 유효 프레임(±30) 으로 자동 폴백.
  • 모드별 목표각 분기 — 프로 고스트 교정 각도를 종목에 맞게 차별화. 투구: 팔꿈치 95° · 무릎 135°, 타격: 100° · 135°, 수비: 110° · 120°.
  • 캐시 버전 v124→v125
β 1.2.2 2026.04.19
UPDATE
  • 프로 고스트 — 이상적 자세 오버레이 실구현 — 기존에는 체크박스만 있고 실제로는 동작하지 않던 "프로 고스트" 를 각도 교정 방식으로 구현했습니다. 사용자 어깨·엉덩이·팔꿈치·무릎의 위치와 뼈 길이는 그대로 유지한 상태에서, 팔꿈치 각도 95° · 무릎 각도 135°(프로 범위 중앙값) 로 교정된 손목·발목 위치를 초록 점선으로 겹쳐 표시합니다. "내 지금 자세에서 손목·발목이 여기 있어야 했어" 가 한눈에 보이도록 설계했습니다.
  • 범례 표시 — 고스트가 켜지면 캔버스 좌상단에 "프로 고스트 — 이상적 자세" 라벨이 함께 표시돼 아이들도 뭘 보는지 바로 이해합니다.
  • 캐시 버전 v123→v124
β 1.2.1 2026.04.19
UPDATE
  • 수비 분석 — 다중 인물 추적(수비수 자동 선택) — 코치가 펑고를 쳐주고 이용자가 수비하는 상황에서 코치가 아닌 수비수(공을 받는 사람)를 자동으로 추적하도록 개선했습니다. 수비 모드에서는 카메라에서 더 먼 쪽(= 작은 바운딩박스)을 수비수로 선택하고, 프레임 간에는 이전 인물과의 중심점 거리로 동일 인물을 추적합니다.
  • "다른 사람 선택" 수동 override — 자동 선택이 틀렸을 때 결과 화면의 👥 다른 사람 선택 버튼으로 원하는 인물을 직접 지정할 수 있습니다. (수비 모드 + 2명 이상 감지된 경우에만 노출)
  • 궤적 / 프로 고스트 재생중 표시 버그 수정 — 재생·스크럽 중에는 궤적/프로고스트 체크박스를 켜도 캔버스에 그려지지 않던 문제를 수정했습니다. drawSkel 렌더 경로를 단일화해서 정지·재생·토글 어디에서든 동일하게 표시됩니다.
  • 캐시 버전 v122→v123
β 1.2 2026.04.19
UPDATE
  • 세로 영상(9:16) 완벽 지원 — 스마트폰 세로 촬영 영상도 비율을 유지한 채 분석합니다. 기존에는 512×384 고정으로 인해 세로 영상이 가로로 찌그러지던 문제를 해결했습니다.
  • 영상 처리 무한 대기 방지 — 프레임 추출 단계에서 5초 타임아웃을 적용해 손상·호환성 영상에서 진행률 바가 멈추는 현상을 방지합니다.
  • 연습 vs 경기 능력치 일관성 강화 — AI 경기 분석의 능력치 평가 기준을 연습 분석과 동일한 6개 항목(힘/속도/정확도/밸런스/유연성/폼완성도)으로 통일해 시계열 비교 정확도를 향상시켰습니다.
  • 캐시 버전 v115→v116
β 1.1.1 2026.04.19
FIX
  • AI 경기 분석 품질 개선 — Gemini AI에 전달하는 핵심 장면을 4장 → 8장으로 확대해 분석 정확도를 높였습니다.
  • 영상 처리 안정성 강화 — 손상·미지원 형식 영상 업로드 시 불필요한 AI 호출을 차단하고 명확한 안내 메시지를 표시하도록 수정했습니다.
  • PWA 설치 안내 정리 — 매니페스트에서 누락된 스크린샷 참조를 제거해 앱 설치 프롬프트 경고를 해결했습니다.
  • 캐시 버전 v114→v115
β 1.1 2026.04.19
NEW
  • 심화 드릴 21종 신규 탑재 — 투구 심화 8종(PA1~PA5, PA8, PA9, PA11) · 타격 심화 13종(BA1~BA12, BA14)을 훈련 시스템에 추가했습니다. (미완성 7종: PA6/PA7/PA10/PA12/PA13/PA14/BA13 — 추후 업데이트)
  • 점수 55점 미만 심화 티어 신설 — 기본(85점 미만) / 추가(70점 미만) 2단계였던 드릴 추천 로직에 심화(55점 미만) 단계를 추가했습니다. 폼 점수가 매우 낮을 때 더 세밀하고 교정 강도 높은 드릴이 자동 처방됩니다.
  • 심화 실전 훈련 블록 추가 — 투구·타격 평균 점수가 85점 미만일 때 프로선수 롤모델 섹션 직전에 "심화 실전" 드릴 블록이 노출되어 실전 감각과 교정을 동시에 연결합니다.
  • 캐시 버전 v113→v114 — 새 드릴 영상 21개가 즉시 반영되도록 서비스워커 캐시를 갱신했습니다.
β 1.0 2026.04.16
NEW
  • 56개 훈련 드릴 시범 영상 탑재 — 투구(P1~P11), 타격(B1~B10), 포수(C1~C8), 외야(OF1~OF8), 내야(IF1~IF10) 전 포지션 드릴 영상을 앱 내에서 바로 재생할 수 있습니다.
  • 로컬 영상 플레이어 도입 — 기존 YouTube 검색 연결 방식을 제거하고, 전용 비디오 플레이어로 드릴 시범 영상을 앱 안에서 직접 시청합니다.
  • TTS 음성 발음 개선 — 훈련 영상 내 "글러브" 발음 오류(글러드)를 수정하여 자연스러운 음성 안내를 제공합니다.
  • 투구·타격 심화 드릴 28종 프롬프트 제작 — PA1~PA14(투구 심화), BA1~BA14(타격 심화) 추가 드릴 영상 생성용 프롬프트를 완성했습니다.
β 0.9.5 2026.04.12
NEW
  • AI 경기 분석 시스템 전면 개편 — 기존 밝기 감지 방식을 제거하고, Gemini Vision AI 기반 영상 분석으로 교체했습니다. 영상 클립 + 상황 설명을 입력하면 AI가 직접 동작을 분석합니다.
  • 음성 입력 지원 — 상황 설명 입력 시 마이크 버튼을 눌러 음성으로 입력할 수 있습니다. (Web Speech API)
  • AI 경기 분석 가이드 추가 — 경기 등록 화면에 "AI 경기 분석이란?" 가이드와 영상 업로드 화면에 "좋은 분석 결과를 받으려면?" 팁 카드를 추가했습니다.
  • 경기 화면 아이콘 전면 교체 — 경기 분석 관련 모든 화면의 기본 이모지를 생성 아이콘 이미지로 교체하여 앱 전체 디자인 통일성을 높였습니다.
β 0.9.4 2026.04.12
NEW
  • 다크 배경 캐릭터 이미지 적용 — 투구·타격·수비·경기 분석 카드와 아이콘에 프리미엄 다크 배경 캐릭터 이미지가 적용되었습니다.
  • 56명 레전드 프로 선수 초상화 — 롤모델 카드에 선수별 카툰 초상화가 표시됩니다. (오타니 쇼헤이, 류현진, 추신수 등)
  • 훈련 드릴 코치 아이콘 개선 — 드릴 카드 아이콘이 현재 분석 모드(투구/타격/수비)에 맞는 코치 이미지로 표시됩니다.
  • 레벨 프로필 이미지 업데이트 — 레벨별 프로필 아이콘이 새로운 캐릭터 이미지로 교체되었습니다.
β 0.9.3 2026.04.09
NEW
  • 훈련방법 가이드 팝업 — 각 드릴의 훈련방법 버튼을 누르면 목적, 방법(단계별), 횟수, 주의사항을 팝업으로 확인할 수 있습니다.
β 0.9.2 2026.04.09
NEW
  • 아이코치 브랜드 로고 적용 — 앱 헤더, 랜딩페이지, 홈화면 아이콘에 새로운 아이코치 로고가 적용되었습니다.
  • 관리자 도구 접근성 개선 — 랭킹 탭에서 또래비교 전환 시에도 관리자 다운로드 버튼이 표시됩니다.
  • 업데이트 노트 아이콘 수정 — 업데이트 노트 및 결과 공유 팝업의 아이콘이 정상 표시됩니다.
β 0.9.1 2026.04.06
NEW
  • 훈련 영상 자세 분석 — 인증 영상을 올리면 MediaPipe로 자세를 분석하고, 드릴별 체크포인트를 기준으로 피드백을 제공합니다.
  • 훈련 시범 영상 — 각 훈련 드릴 옆 ▶️ 버튼으로 AI 코치의 시범 영상을 바로 볼 수 있습니다.
  • 코치 조언 팝업 — 분석 결과를 좋음/보통/조정필요로 등급화하고, 드릴별 맞춤 코칭 조언과 교정 포인트를 안내합니다.
  • 분석 결과 기록 — 영상 분석 결과(등급, 체크 통과 수)가 훈련 기록에 저장되어 드릴 목록에 표시됩니다.
β 0.9 2026.04.06
NEW
  • 실전 경기 분석 — 대회나 연습경기 영상을 올리면 구간을 자동 감지하고, 투구/타격/수비별로 분석합니다.
  • 연습 vs 실전 비교 — 평소 연습 점수와 실전 경기 점수를 능력치별로 나란히 비교해볼 수 있습니다.
  • 종합 경기 리포트 — 평균 점수, 일관성 등급, 코칭 가이드, 아빠 대화 가이드를 한눈에 확인합니다.
  • 시즌 기록 관리 — 모든 경기 기록이 저장되어 시즌 평균, 최고 점수, 성장 추세를 추적합니다.
β 0.8 2026.04.06
NEW
  • 드릴 3단계 성장 시스템 — 초급→중급→고급으로 드릴이 자동 승급되어 아이의 실력에 맞게 훈련 난이도가 올라갑니다.
  • 매일 다른 드릴 조합 — 같은 분석 결과라도 날마다 다른 드릴 조합이 나와 지루하지 않게 훈련할 수 있습니다.
  • 드릴 즐겨찾기 — 자주 하고 싶은 드릴에 별표를 눌러두면 다음 날 우선 추천됩니다.
  • 타이머 인증 — 워밍업과 체력 드릴은 영상 대신 타이머로 간편하게 인증할 수 있습니다.
  • 훈련 영상 AI 코칭 — 폼 교정 드릴 영상을 올리면 관절 각도를 분석해서 간단한 코칭 피드백을 줍니다.
  • 영상 썸네일 미리보기 — 인증 영상을 올리면 첫 장면이 썸네일로 표시되어 확인이 쉬워졌습니다.
  • 오늘의 미션 — 매일 1개의 특별 미션이 주어지고 달성하면 보너스 스탯 +2를 받습니다.
  • 칭호 성장 시스템 — 훈련 일수에 따라 루키→수습선수→정규선수→주전선수→에이스→레전드로 칭호가 성장합니다.
  • 가족 응원 메시지 — 훈련 완료 시 아빠의 이름으로 된 격려 메시지가 나와 아이에게 동기부여를 줍니다.
  • 주간 훈련 리포트 — 이번 주 훈련 현황과 코칭 메시지를 한눈에 확인할 수 있습니다.
FIX
  • 연속 훈련 마일스톤 확대 — 3일/5일/10일/21일/30일/50일/100일 등 더 다양한 연속 훈련 배지가 추가되었습니다.
  • 드릴 완료 즉시 피드백 — 드릴을 체크하면 카테고리별 응원 메시지가 바로 표시됩니다.
  • 훈련 효과 하이라이트 — 훈련 완료 시 최근 분석 점수 변화를 보여줘 훈련 효과를 실감할 수 있습니다.
β 0.7 2026.04.05
NEW
  • 외야수 수비 분석 추가 — 준비자세, 이동/추적, 캐치, 트랜지션, 송구 5단계 분석. 크로스오버 스텝, 드롭 스텝, 크로우 홉 등 전용 드릴 8종 포함.
  • 외야수 프로 롤모델 — 마이크 트라웃, 이치로, 무키 베츠(MLB), 이종범, 나성범, 박건우(KBO) 등 단계별 추천.
  • 외야수 AI 코치 채팅 — 준비자세, 이동, 포구, 트랜지션, 송구, 포지셔닝 6개 주제로 상세 코칭 제공.
  • 나노바나나 배지 이미지 완성 — 30개 배지 전부 고급 골드 메달 디자인으로 교체. 13개 신규 배지 이미지 추가.
FIX
  • 수비 분석 영상 선택 버그 수정 — 수비 하위 유형별(땅볼/플라이/포수/외야) 일일 제한을 독립 적용하여 영상 선택이 차단되던 문제 해결.
  • 데이터 복원 아이콘 수정 — 기본 이모지 대신 커스텀 아이콘으로 교체.
  • 촬영 팁 한 줄 표시 — 홈 화면 촬영 팁이 줄바꿈 없이 한 줄로 표시되도록 수정.
β 0.6 2026.04.04
FIX
  • 랭킹 화면 데이터 미표시 수정 — renderCompare 에러가 switchRankTab 실행을 차단하던 문제를 분리 처리했습니다.
  • fetchLeaderboard null 참조 오류 수정 — DOM 요소 존재 여부를 확인하는 안전장치를 추가했습니다.
  • 랭킹 스켈레톤 비동기 처리 수정 — async/await 패턴으로 변경하여 로딩 애니메이션이 정상 동작합니다.
  • 랭킹 렌더링 에러 핸들링 강화 — renderRankingTab, switchRankMode에 try-catch 및 재시도 버튼을 추가했습니다.
  • 훈련 드릴 제목 2줄 표시 수정 — 모바일에서 드릴 이름이 한 줄로 표시되도록 폰트 크기와 굵기를 조정했습니다.
  • 커스텀 아이콘 추가 — 선물, 금/은/동 메달 아이콘을 커스텀 디자인으로 교체했습니다.
β 0.5 2026.04.03
NEW
  • 사이드암 / 언더핸드 분석 지원 — 투구폼을 자동 감지하여 오버핸드·사이드암·언더핸드 각각에 맞는 전용 기준으로 분석합니다.
  • 사이드암/언더핸드 레전드 롤모델 추가 — 정대현(KBO), 김병현(MLB), 야마다 히사시(NPB) 선수가 추천 롤모델에 등장합니다.
  • 투구/타격 랭킹 분리 — 전국 랭킹이 투구·타격 별도 탭으로 분리되어 더 공정한 비교가 가능합니다.
  • 소속 자동 입력 — 랭킹 등록 시 프로필의 소속(학교/클럽)이 자동으로 채워집니다.
FIX
  • 랭킹 등록 오류 수정 — Firebase 보안 규칙과 코드 간 문서 ID 불일치 문제를 해결했습니다.
  • 타격 분석 진행 불가 오류 수정 — 영상 선택 후 분석이 멈추는 문제를 여러 방면에서 개선했습니다.
  • 프로필 화면 체크박스 오류 수정 — 프로필 입력 화면에 잘못 배치된 체크박스를 올바른 위치로 이동했습니다.
  • 훈련 코칭 플랜 오류 수정 — 타격 분석 후에도 투구 드릴만 추천되던 문제를 수정했습니다.
β 0.4 2026.03
NEW
  • 전국 랭킹 시스템 (Firebase Firestore 연동)
  • 프로 선수 롤모델 추천 및 유튜브 영상 연결
  • 프로 비교 차트 (관절 각도 비교)
  • PDF 리포트 생성
  • 뱃지 / 레벨 시스템
β 0.3 2026.02
NEW
  • 5단계 구간 분석 (와인드업~팔로스루 / 준비자세~임팩트)
  • 맞춤형 훈련 드릴 추천
  • 성장 기록 및 또래 비교
  • 실시간 카메라 감지 모드
β 0.2 2026.01
NEW
  • AI 투구 분석 (MediaPipe Pose)
  • AI 타격 분석
  • PWA 지원 (홈 화면 설치)

사진을 탭하여 업로드

아이코치에 오신 걸 환영합니다!

아이 정보를 입력하면 맞춤 분석이 가능합니다

아빠 폰 / 아들 폰에서 같은 계정으로 로그인할 때 사용합니다.
이벤트 공정성을 위한 본인 확인용이에요.

아이코치

AI가 자세를 분석하고 맞춤 훈련을 추천합니다

0
총 분석
-
⚾투구 최고
평균 -
-
🏏타격 최고
평균 -
-
🧤수비 최고
평균 -
루키
야구의 첫 걸음!
0 / 50 XP
🏅 뱃지
투구

투구 분석

던지기 자세

타격

타격 분석

스윙 자세

수비

수비 분석

수비 자세

실시간

경기 분석

실전 영상 분석

📱촬영 팁전신이 보이도록, 밝은 곳에서 3~5m 거리로 촬영해 주세요.
← 처음으로
모드 헤더

투구 분석

1

촬영각도 촬영 각도

측면에서 전신이 보이도록 촬영하세요.

2

거리 거리

3~5m, 머리~발끝

3

환경 환경

밝은 곳, 단순 배경, 720p+

4

길이 길이

한 동작, 3~10초

업로드

영상 선택

촬영한 영상 분석

실시간 분석

라이브 카메라

AI 모델 로딩 중
잠시만 기다려주세요

처음 실행 시 AI 모델 다운로드에
30초~1분 정도 소요됩니다

← 홈으로

분석 결과

--종합 점수

능력치 능력치
단계별점수 단계별 점수
자세 분석 영상
0:00
⭐ 프로 선수 비교
분석 결과
추천훈련 추천 훈련
⭐ 프로선수 롤모델
안전 안전 안내AI 참고 자료이며 전문 코치를 대체하지 않습니다. 통증 시 즉시 중단하세요.
↓ 당겨서 새로고침
성장 기록
비교 & 랭킹
또래 비교
전국 랭킹
← 처음으로

📹 실시간 분석

카메라를 사용할 준비가 되셨나요?

실시간으로 자세를 분석합니다

  • 밝은 곳에서 촬영해주세요
  • 전신이 보이도록 3~5m 거리
  • 측면에서 촬영하면 정확도 UP
  • 안정적인 곳에 기기를 고정
← 뒤로

📊 분석 비교

분석 1

분석 2

능력치 비교
단계별 점수 비교
경기 등록
AI 경기 분석이란?
경기 정보
투수
타자
수비
경기 영상 & 상황 설명
좋은 분석 결과를 받으려면?
AI 경기 분석
경기 종합 리포트
시즌 기록
⚙️설정
🔊 효과음 설정
버튼 효과음
효과음 볼륨 30%

분석 중 배경음(BGM)
BGM 볼륨 15%

탭 전환·분석 시작·훈련 완료 등 주요 동작에 효과음이 재생됩니다. BGM은 분석 진행 중에만 재생됩니다.

AI 코치 AI 코치 설정

AI 코치란?

아이코치 앱에는 기본 코치 기능이 들어있어서 바로 질문할 수 있어요. 여기에 Google의 AI(Gemini)를 연결하면, 코치가 우리 아이의 분석 결과를 더 깊이 이해하고 진짜 대화하듯이 맞춤 조언을 해줘요.

API 키는 Google AI 서비스를 사용하기 위한 일종의 비밀번호예요. 한 번만 발급받아 아래에 붙여넣으면 끝! 발급도 사용도 완전 무료이고, 개인정보는 수집되지 않아요.

💡 API 키가 없어도 기본 코치 기능은 사용할 수 있어요.
키를 입력하면 더 자연스럽고 상세한 AI 대화가 가능합니다.

💾 데이터 보관

분석 기록을 안전하게 지키는 3가지 방법입니다. 아래 두 가지는 자동으로 동작하므로 평소에는 신경 쓸 필요가 없어요.

☁️ 기기 간 동기화

언제 쓰나요? 휴대폰을 바꾸거나 브라우저 캐시를 지웠을 때. 새 기기에서 앱을 열면 자동으로 복원돼요.

✓ 새 분석할 때 자동 업로드 · 앱 열 때 자동 다운로드 — 평소엔 버튼 안 눌러도 됨

▸ 고급: 한 방향만 동기화
📅 과거로 되돌리기
(최근 14일)

언제 쓰나요? 실수로 기록을 지웠거나 데이터가 이상해졌을 때 어제 이전 상태로 되돌릴 수 있어요.

✓ 하루 1회 자동 저장 · 최근 14일 보존 — 같은 기기 내 타임머신

⚙️ 고급 — JSON 파일로 내보내기·가져오기

언제 쓰나요? 클라우드 계정 없이 전체 데이터를 수동 파일로 보관하거나, 다른 사람에게 전달할 때. 대부분은 위 두 기능으로 충분해요.

⚠️ 가져오기는 현재 로컬 데이터를 덮어쓰기합니다. 신중히 사용하세요.

버그 제보 & 기능 제안

버그를 발견하셨거나 새로운 기능 아이디어가 있으시면 알려주세요!
오픈베타 이벤트 기간(5.1~5.31) 동안 가장 많이 제보한 분에게 제보왕 상을 드립니다.

법적 정보

아이코치 이용과 개인정보 처리에 관한 방침입니다. 이용 전 반드시 한 번 읽어주세요.

운영: 김아빠 · 연락처: 2026icoach@gmail.com

지원 · 문의

오류 제보·기능 제안·이용 문의를 한 곳에서 받아요. 답변은 이메일 또는 단톡방 공지로 드립니다.

2026icoach@gmail.com

훈련 관리
연속 훈련
0일

연속 훈련일수

📅 훈련 캘린더
🎯 목표 설정
오늘의 훈련 체크리스트

각 훈련을 완료하고 인증 영상을 올려주세요. 꾸준한 훈련에 보너스 스탯이 부여됩니다!

📊 훈련 효과 분석

이전 분석 대비 어떤 부분이 좋아졌는지, 추가로 어떤 훈련이 필요한지 확인하세요.

훈련 보상 현황
코치
● 온라인
투구

아이코치 앱 설치

홈 화면에 추가하면 앱처럼 빠르게 실행할 수 있어요!

설치 시 "안전하지 않은 앱" 경고가 뜰 수 있습니다. 아이코치는 웹사이트 바로가기(PWA)로 설치되며, 개인정보 수집이나 악성코드가 없으니 안심하세요. "세부정보 더보기" → "무시하고 설치하기"를 눌러 진행하면 됩니다.

iPhone에 설치하기

1

하단의 ⬆️ 공유 버튼을 탭하세요

2

스크롤하여 "홈 화면에 추가"를 선택하세요

3

오른쪽 상단 "추가"를 탭하면 완료!