これであなたもムキムキよぉん💪

https://github.com/RiTa-23/Yucchin-s-Muscle-Training

TypeScript

React

Python

Docker

PostgreSQL

ゆっちんのリアルタイムフォーム矯正・筋トレ支援アプリケーション

RiTa

ひろ

ゆっちん

山内雪乃

推しアイデア

リアルタイムフォーム分析、ゆっちんトレーナー、ゲーミフィケーション要素、成長の可視化など機能、要素がモリモリです!

作った背景

ゆっちんという生きる面白素材を活かす+筋トレ

推し技術

・姿勢推定でゆっちんが筋トレアドバイス&応援 ・FastAPI自作認証機能 ・railway一括デプロイ

プロジェクト詳細

これであなたもムキムキよぉん💪

概要

プテラカップ2025テーマ「四年に一度」 四年に一度→オリンピック→スポーツ→体を動かす→筋トレ

「じょぎのおもしれー女」こと ゆっちん をトレーナーキャラとして全面に押し出したリアルタイムフォーム矯正・筋トレ支援アプリです。 カメラ映像からユーザーの姿勢をリアルタイムで分析し、適切なトレーニングフォームを指導します。

デモ動画

MVPのその先へ!

細かいところまでUI/UXを考えてモリモリ実装しました!!! 「最低限必要な機能ができたからOK」「それっぽく動いてるからいいでしょ」の妥協はなし。 実用レベルの完成度を目指して開発しました。 image

主な特徴

  • リアルタイムAIフォーム分析: MediaPipeを活用し、ユーザーの骨格をリアルタイムで検知。「膝が曲がっている」「腰をもっと下げて」といった具体的なアドバイスを即座に提供します。
  • インタラクティブなトレーナー: オリジナルキャラクター「ゆっちん」が、トレーニング中に励ましたり、フォームを指摘したりと、楽しくトレーニングをサポートします。
  • ゲーミフィケーション要素: トレーニングを継続すること新しい「ゆっちん」キャラクターをコレクションできる機能など、継続率を高める仕組みを取り入れています。
  • 成長の可視化: カレンダー機能や統計データにより、日々の努力と成長を一目で確認できます。

画面遷移図

image

各画面説明

トップ

image

ログイン/新規登録

image

ホーム

image

お手本画面

image image

筋トレ画面

画面の様子はデモ動画参照 デモ動画

筋トレ駆動開発💪💪💪 デバッグ作業が筋トレなので身体的に疲れました。 開発での精神的疲れと物理的な身体的疲れのダブルコンボで死にそうでした。 アウトドアの趣味を持っていないプログラマーは運動不足になりがちですが、このプロダクトの開発に関してはその心配はなしですd(^_^o)

頑張りの歴史

image image

ゆっちんゲット画面

image

集めたゆっちん

image

設定

image

使用技術

image

フロントエンド

  • フレームワーク: 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

https://youtu.be/q_g40PFeKFQ

R

https://youtu.be/q_g40PFeKFQ

SR

しか リスカ たまご

UR

https://youtu.be/PTh3KVbpkfI

SECRET

https://youtu.be/fsOmsuOpJ_M

【ゆっちんをゲットできる条件】

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で認証機能自作

ネタアプリなのに結構真面目に認証機能を自前で用意しました。技術の無駄遣いポイントです。

  • 「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で作成し、チームメンバーに共有しました。 image 要件定義や環境構築、技術選定などもいつでも見返して参照できるように都度まとめておきました。

GitHub Projectでタスク管理

使えるものは使っていけ! ということでGitHub Projectの機能を使ってカンバンでタスク管理! ラベルや優先度、担当者など明確にタスクの分類分けをして円滑なチーム開発を図りました! image

mainの間に保険のdevelopブランチを挟む

developの環境でうまく動いて問題ないことが確認された →mainにdevelopをマージして本番環境で動かす というルールにしました。

保険として間にdevelopを挟み、デフォルトブランチをmain→developに変更することで問題のあるコードを本番環境に上げる可能性を下げました。-

RiTa

@rita