실내자전거와 심박계를 잇는 운동 기록 앱과 운영자 콘솔
스마트 트레이너와 심박계에 표준으로 붙어 라이딩 세션을 진행하고, 끝난 뒤 결과를 분석해 보여주는 앱입니다. 기록은 사용자가 이미 쓰던 운동 플랫폼으로 내보내고, 운영자가 사용자와 지표를 보는 관리자 콘솔을 함께 만들었습니다.

과제 배경
실내자전거는 제조사마다 연결 방식이 달라서, 앱이 기기별로 대응하면 지원 기기가 늘 때마다 연동 코드를 다시 씁니다. 운동 기록도 세션이 끝나면 그 자리에서 끝나 사용자가 자기 변화를 이어서 볼 수 없었고, 이미 쓰던 외부 운동 플랫폼과도 기록이 따로 놀았습니다.
주요 설계 결정
기기를 어떻게 붙일 것인가
FTMS 표준을 따랐습니다. 제조사별 연동을 따로 만들지 않았습니다
기기마다 붙이면 지원 목록이 늘 때마다 같은 일을 다시 합니다. 표준을 지키는 트레이너는 같은 경로로 붙고, 부하를 거는 명령도 같은 모양으로 나갑니다.
연결이 끊겼을 때
세션을 끝내지 않고 다시 붙여 이어 갑니다
라이딩 중간에 연결이 떨어지면 그때까지의 기록이 사라집니다. 사용자는 처음부터 다시 타야 하고, 그 한 번으로 앱을 믿지 않게 됩니다. 끊긴 구간을 세션 안에서 다루기로 했습니다.
로그인을 어디에 둘 것인가
클라우드 통합 인증 하나로 묶고 권한을 역할로 나눴습니다
로그인 경로가 흩어지면 사용자가 늘 때 어디서 막혔는지 찾는 데 시간이 걸리고, 운영자와 사용자가 볼 수 있는 범위가 엇갈립니다. 인증을 한 곳에 두면 권한도 한 곳에서 정해집니다.
앱을 몇 벌 만들 것인가
웹 기반 프론트엔드 구조로 한 코드에서 여러 플랫폼을 냅니다
iOS 와 안드로이드와 웹을 따로 만들면 같은 화면을 세 번 고칩니다. 화면이 자주 바뀌는 서비스라 고치는 비용이 만드는 비용보다 큽니다.
운영 지표를 언제 만들 것인가
트래픽과 접속과 신규 가입을 모으는 집계 구조를 처음부터 두었습니다
서비스가 자라는지 사용자가 실제로 쓰는지는 데이터가 쌓여 있어야 답할 수 있습니다. 필요해진 뒤에 붙이면 그 전 기간이 통째로 비고, 비어 있는 구간은 나중에 채울 방법이 없습니다.
제공 기능
| 기능 | 내용 |
|---|---|
| 기기 연동과 부하 제어 | FTMS 표준으로 스마트 트레이너와 심박계에 붙고, ERG 모드에서 목표 출력에 맞춰 부하를 자동으로 조절합니다. |
| 라이딩 세션 운영 | 라이딩 구간을 순서대로 진행하며 강도를 실시간으로 바꾸고, 연결이 끊기면 다시 붙여 세션을 복구합니다. |
| 운동 기록과 분석 | 세션을 기록해 끝난 뒤 결과 리포트로 보여주고, FTP 변동 이력을 이어서 관리합니다. |
| 외부 플랫폼 연동과 알림 | 기록을 Strava 로 내보내고, 운동 결과와 알림을 사용자에게 보냅니다. |
| 운영자 관리 콘솔 | 사용자와 권한을 관리하고, 트래픽과 신규 가입 지표를 화면에서 봅니다. |
수행 결과
- 표준을 지키는 스마트 트레이너는 기기별 연동 없이 같은 경로로 붙습니다.
- 연결이 끊겨도 세션이 끝나지 않고 이어져, 그때까지의 기록이 남습니다.
- 세션이 끝난 뒤에도 기록이 남아 FTP 변동을 이어서 봅니다.
- 기록을 Strava 로 내보내 사용자가 이미 쓰던 플랫폼과 이어집니다.
- 로그인이 한 곳으로 모이고, 운영자와 사용자가 보는 범위가 역할로 나뉩니다.
- 일과 주와 월 단위 트래픽, 신규 가입 추이, 활성 사용자 지표를 운영자가 봅니다.
화면 구성
화면의 구조와 기능을 보여주는 시안이며, 색과 서체를 포함한 디자인은 다음 단계에서 정합니다.
기기 페어링
- 실내자전거
- 심박계
기기 페어링
주변 트레이너와 심박계를 찾아 붙입니다
8:27 / 40:00
84 W
- 심박 140 bpm
- 케이던스 92 rpm
라이딩
구간을 따라가며 강도를 실시간으로 조절합니다
운동 결과
84
- 평균 출력
- 심박 최댓값
- 소요 시간
운동 결과
끝난 세션의 결과를 리포트로 봅니다
MY
MY
달력과 FTP 변동을 이어서 봅니다
시스템 구성도
점선은 외부 서비스를 사용하는 항목입니다.
설계 원칙
| 원칙 | 적용 방법 |
|---|---|
| 기기가 늘어도 연동을 다시 만들지 않는다 | FTMS 표준 프로파일로만 붙습니다. 제조사별 분기를 두지 않습니다 |
| 연결이 끊겨도 세션이 사라지지 않는다 | 다시 붙으면 진행 중이던 구간부터 이어 갑니다 |
| 운영 판단에 쓸 데이터를 나중에 만들지 않는다 | 트래픽과 접속과 신규 가입을 처음부터 집계로 쌓습니다 |


