これであなたもムキムキよぉん💪
じょぎ(所属している情報系サークル)の後輩からの誘いで、後輩3人と4人チームでハックツハッカソン プテラカップ2025に出場してきました。
そこで、リアルタイムフォーム矯正・筋トレ支援アプリ「これであなたもムキムキよぉん💪」を開発し、見事最優秀賞を取ってきました!!やったー!!😆
というわけで本記事では開発した筋トレ支援アプリとハッカソンでの開発についてまとめています。
概要
プテラカップ2025のテーマは「四年に一度」でした。
四年に一度→オリンピック→スポーツ→体を動かす→筋トレという連想ゲームで筋トレアプリを作ることにしました。
チームの後輩の1人、「じょぎのおもしれー女」こと ゆっちん をトレーナーキャラとして全面に押し出したリアルタイムフォーム矯正・筋トレ支援アプリです。
カメラ映像からユーザーの姿勢をリアルタイムで分析し、適切なトレーニングフォームを指導します。
MVPのその先へ!
細かいところまでUI/UXを考えてモリモリ実装しました!!!
「最低限必要な機能ができたからOK」「それっぽく動いてるからいいでしょ」の妥協はなし。
実用レベルの完成度を目指して開発しました。

主な特徴
- リアルタイムAIフォーム分析: MediaPipeを活用し、ユーザーの骨格をリアルタイムで検知。「膝が曲がっている」「腰をもっと下げて」といった具体的なアドバイスを即座に提供します。
- インタラクティブなトレーナー: オリジナルキャラクター「ゆっちん」が、トレーニング中に励ましたり、フォームを指摘したりと、楽しくトレーニングをサポートします。
- ゲーミフィケーション要素: トレーニングを継続すること新しい「ゆっちん」キャラクターをコレクションできる機能など、継続率を高める仕組みを取り入れています。
- 成長の可視化: カレンダー機能や統計データにより、日々の努力と成長を一目で確認できます。
画面遷移図
各画面
トップ
ログイン/新規登録
ホーム
お手本画面
筋トレ画面
画面の様子はデモ動画参照
デモ動画
筋トレ駆動開発💪💪💪
デバッグ作業が筋トレなので身体的に疲れました。
開発での精神的疲れと物理的な身体的疲れのダブルコンボで死にそうでした。
アウトドアの趣味を持っていないプログラマーは運動不足になりがちですが、このプロダクトの開発に関してはその心配はなしですd(^_^o)
頑張りの歴史
ゆっちんゲット画面
集めたゆっちん
設定
使用技術
フロントエンド
- フレームワーク: React 19 (Vite)
- 言語: TypeScript
-
スタイリング:
- Tailwind CSS (v4)
- shadcn/ui (Radix UI base)
- Lucide React (アイコン)
- 状態管理: React Context API
- ルーティング: React Router DOM (v7)
- ネットワーク通信: Axios
- AI/機械学習: MediaPipe Pose (クライアントサイド推論)
バックエンド
- フレームワーク: FastAPI
- 言語: Python 3.12+
- パッケージマネージャー: uv
- データベース: PostgreSQL
- ORM: SQLAlchemy (w/ Asyncpg)
- 認証: JWT (JSON Web Tokens)、HttpOnly Cookie
- セキュリティ: Bcrypt (パスワードハッシュ化)
インフラ / DevOps
- コンテナ化: Docker、Docker Compose
- デプロイ: Railway
推しポイント
姿勢推定(自動カウント+アドバイス機能)
姿勢推定にはMediaPipe Poseを使用しています。 Webカメラの映像からユーザーの身体にある33箇所のランドマーク(関節などの特徴点)の3次元座標をリアルタイムに検出します。
仕組み
座標系と角度計算の基本
判定には主に、3つのランドマーク(点A, 点B, 点C)が成す角度を使用します。
- 計算: 3点の座標から Math.atan2 を用いてラジアンを求め、角度(0°〜180°)に変換して評価
- 利点: カメラとの距離や画角が変わっても、「関節の角度」は不変であるため、安定した判定が可能です。
機能
上記の姿勢推定を活用して正しい姿勢か判定し、アドバイスや応援をトレーナーキャラのゆっちんが行ってくれます。
また、姿勢推定による自動カウント機能も全種目で搭載!
横/正面の切り替え
プランクに関しては横からの角度のみの判定ですが、スクワットと腕立て伏せは正面/横での二つの角度からの判定が可能。
また、横角度の判定は右左どちらでも可能にしています。(より明確に判定できる方を採用)
- 横:正確な姿勢アドバイス重視(正しい姿勢を習得する目的)
- 正面:利便性、操作性重視(カウントや応援機能重視、正面を向いての操作ができる利便性目的)
fpsの切り替え
設定画面 or 筋トレ画面内にfps切り替え機能を搭載。
デバイスのスペックに応じて切り替えることが可能です。
レスポンシブ対応
スマホでのログイン、アプリ利用が可能
UIもモバイル対応のものを用意。
素材の豊富さ
なんと28枚のオリジナル画像素材+43種類のオリジナルボイス素材!!!!!
計71種類のオリジナル素材を使用しております!
筋トレのアドバイス、応援のほか、画面遷移や設定変更でも元気が出るゆっちんボイスを聞くことができます!
ゆっちんゲット演出
レアリティ(Normal,Rare,SR,UR,Secret)ごとに変化するゆっちんゲット演出を実装(かなり凝った演出を実装しています)
レアリティ高いものだとソシャゲ風にセリフが出てからキャラが出現する演出を実装しています。
技術の無駄遣いポイントが高い
ゲット演出動画
Normal
R
SR
UR
SECRET
【ゆっちんをゲットできる条件】
N:筋トレ累計30(回+秒)を超えるたびにランダム取得
R:筋トレ累計100(回+秒)を超えるたびにランダム取得
SR(リスカゆっちん):スクワット10ターン(30×10=300回)
SR(たまごゆっちん):腕立て10ターン(30×10=300回)
SR(鹿ゆっちん【神鹿】):プランク10ターン(30×10=300秒)
UR:筋トレ累計回数1000(回+秒)
シークレット:筋トレ総回数100(3000回+秒)ターン
Railwayでモノレポ一括デプロイ
- 2サービス管理の手間、環境変数同期作業の煩わしさ解消
- モノレポの方がAIフレンドリー
- Railwayならモノレポのディレクトリ指定でバック、フロントを別々に建てる
- API負荷が高いReact+FastAPIのようなモノレポではデプロイ先を分けるよりRailway一括がレスポンス安定性とデプロイ簡易性で勝る
FastAPIで認証機能自作
ネタアプリなのに結構真面目に認証機能を自前で用意しました。これまではPaasの認証機能をお借りする形で実装していたので、初めての自作認証機能でした。
- 「HttpOnly Cookie」と「Bearer Token」を併用
- HttpOnly Cookie: ブラウザのJavaScriptからアクセス不可能な、セキュリティ強度の高いクッキーとしてトークンを保存(PCブラウザ用)。XSS攻撃によるトークン漏洩リスクを抑えています。
- Response Body (JSON): 同じトークンをレスポンスボディにも含めて返却(モバイルフォールバック用)。モバイルブラウザのサードパーティクッキーへの制限が厳しく、Cookieがブロックされてログインできない問題への対処で使用しているが、将来的には同一ドメインにしてHttpOnly Cokkieのみ採用にしたい。
- パスワードはプレーンテキストではなく、bcrypt アルゴリズムを用いてハッシュ化
- 永続化セッション:リロードしてもログイン状態が維持されるよう、アプリ起動時に /users/me エンドポイントを叩いてセッションの有効性を確認し、ユーザー情報を再取得する仕組みを実装しています。
- 401エラーの自動ハンドリング: response インターセプターで 401 Unauthorized(認証切れ)エラーを監視。セッションが切れた場合は、ユーザーを即座にログイン画面へリダイレクトさせます。
仕組み
ログイン時: バックエンドはJWT (JSON Web Token) を生成し、HttpOnly CokkieとBearerTokenの2つの形式でクライアントに渡す
↓
通信時: フロントエンド(Axios)は、リクエストヘッダーにトークンを付与して送信
↓
検証時: バックエンドは「Cookie」と「Authorizationヘッダー」のどちらか一方でも有効なトークン(JWT)があれば、正規のユーザーとして認証する
開発メンバー
ジョジョジョの最高にお淑やかなメンバーを紹介するぜ!!!ヘェッ!!!!!
- ゆっちん:フロントエンド&素材提供担当(素材作成、レスポンシブ対応)
- ゆっきー:フロントエンド担当(UI実装、レスポンシブ対応)
- ひろ:バックエンド担当(DB周り+ゲット演出実装)
- リタ:バックエンド&インフラ担当(認証、姿勢推定、デプロイ)
- うさぎ:コードレビュー担当
「情報工学部情報工学科情報技術研究部所属」なので略して「ジョジョジョ」チームです。
チームメンバーの3/4がハックツ初参戦の開発初心者
- フロントエンド担当の2人は初React
(フロントエンドのフレームワーク触ること自体も初) - バックエンド担当1人は初めてのバックエンド開発
→ ということで開発の進め方は工夫しました
開発経験者のみのチームであれば割と雑に、ノリで進めても上手くいく場合が多いが、今回はそうではない。
リタ1人が3人にフロントとバックをつきっきりで教えながら、3人分のコードレビューを普通にするのは流石に辛い...
開発の進め方
初心者が多いチームということで開発の進め方に関しては出来るだけ安全に、楽に、円滑に進められるように、開発ルールの明確な定義やツール導入、ドキュメント整理など事前に入念な準備をしておきました
CodeRabbit🐇にレビューしてもらう
1人で3人のコードレビューをするのはさすがに辛い...
ということでチームメンバーにコードレビュー担当のうさぎさん🐇を加入させました。
修正してもいいレビューかどうかはチェックする必要はありますが、3人のコードを一行ずつチェックしてレビューする労力は必要なくなったのでかなり助かりました。うさぎさんありがとう!!!
ドキュメントを入念に事前準備
開発中、3人にずっとつきっきりで教えて自分の開発時間が激減するのは辛い...
ということでこれさえ見ればある程度自力で開発できる開発マニュアルをNotionで作成し、チームメンバーに共有しました。

要件定義や環境構築、技術選定などもいつでも見返して参照できるように都度まとめておきました。
GitHub Projectでタスク管理
使えるものは使っていけ!
ということでGitHub Projectの機能を使ってカンバンでタスク管理!
ラベルや優先度、担当者など明確にタスクの分類分けをして円滑なチーム開発を図りました!

mainの間に保険のdevelopブランチを挟む
developの環境でうまく動いて問題ないことが確認された
→mainにdevelopをマージして本番環境で動かす
というルールにしました。
保険として間にdevelopを挟み、デフォルトブランチをmain→developに変更することで問題のあるコードを本番環境に上げる可能性を下げました。
まとめ
今回のハッカソンは、チーム「ジョジョジョ」にとって、まさに「筋トレ駆動開発💪」を地で行く熱い数日間となりました。
「四年に一度」というテーマから「筋トレ」へと結びつけ、単なるネタアプリに留まらない、本格的なリアルタイム姿勢推定や、セキュアな認証基盤、そしてこだわりのUI/UXを実装できました。
最優秀賞という最高の結果を得られたのは、強烈な個性を放つトレーナー「ゆっちん」の素材力と、それを支える技術力、そして何よりチームの結束力があったからこそです。
これからも、この「筋トレ駆動開発」で培った筋肉と技術を武器に、さらなる高み(とマッチョ)を目指して開発を続けていきます!
「これで、あなたもムキムキよぉん💪✨」











