Cofit は、友人やコミュニティ(パーティー)と協力してフィットネス目標を達成し、健康的な運動習慣を身につけるためのソーシャルフィットネスWebアプリケーションです。
単に運動記録をつけるだけでなく、スマートフォンの内蔵センサーと連動して運動回数を自動カウントする機能や、獲得した実績バッジをインタラクティブな3Dモデルで鑑賞できる機能など、ユーザーのモチベーションを引き出すためのリッチなUX(ユーザーエクスペリエンス)を搭載しています。
本プロジェクトは、フロントエンドとバックエンドの境界を越えて、最新の Web テクノロジー(Next.js 16, Cloudflare Workers, Three.js, Web Sensor API)をフルに活用して構築されています。
本リポジトリは、モノレポ構成を採用しています。
- Framework: Next.js 16 (App Router)
- UI / Styling: React 19 + TailwindCSS v4 + Material UI
- 3D Rendering: Three.js / @react-three/fiber / @react-three/drei
- Animation: Framer Motion
- Authentication Client: Better Auth Client
- Runtime: Cloudflare Workers
- Framework: Hono (Ultra-lightweight Web Framework)
- Database: Cloudflare D1 (Serverless Distributed SQLite)
- ORM: Drizzle ORM
- Authentication: Better Auth (Session-based)
- Object Storage: Cloudflare R2 (バッジ3Dモデルや画像アセット用)
スマートフォンの加速度センサー(DeviceMotionEvent)の生データを高度に処理し、スクワットや腹筋の回数を高精度に自動カウントするアルゴリズムを自作しています(useExerciseCounter.ts)。
- ノイズ除去: ローパスフィルタ(LPF、$\alpha=0.2$)を適用し、端末の細かな手ブレやノイズを除去。
- 重力補正: 3軸加速度ベクトルのノルムを合成し、重力加速度(9.8 m/s²)を減算することで、純粋な運動による加速度のみを抽出。
- 物理シミュレーションによる位置の推定: 加速度を時間積分して速度(Velocity)を求め、さらに速度を積分して位置(Depth)をリアルタイムに推定。
- 状態遷移モデル(FSM): 運動のフェーズを
STANDING(直立)→DESCENDING(下降)→BOTTOM(最下点)→ASCENDING(上昇)の4つの状態に分け、閾値判定と物理的な深さを組み合わせることで、「正しいフォームで行われた運動」のみを識別してカウントします。
ユーザーが獲得した実績バッジは、2Dの静止画ではなく、リアルタイムに3Dレンダリングされます(BadgeCard.tsx)。
- GLTF形式の3Dモデルを動的に読み込み、ふわふわと浮遊するアニメーション(
Float)を適用。 - モーダル画面内では
OrbitControlsを実装し、ユーザーがマウスやタッチ操作で3Dバッジを自由な角度から回転・ズームして鑑賞できるリッチなUI/UXを提供しています。 - 環境光、スポットライト、ポイントライト、ディレクショナルライトを組み合わせ、さらに質感のある影表現(
ContactShadows)を施すことで、ブラウザ上とは思えない高級感のあるビジュアルを実現しています。
バックエンド(Hono)とフロントエンド(Next.js)間で、APIスキーマをシームレスに共有しています(hono-client.ts)。
- HonoのRPC機能(
AppType)を活用することで、APIのエンドポイントパス、リクエストボディ、クエリパラメータ、レスポンスの型定義がフロントエンド側で100%自動補完されます。 - これにより、仕様変更時の不整合をコンパイル時点で検出し、型安全で壊れにくい堅牢なフルスタック開発を実現しています。
バックエンドは Cloudflare Workers 上でエッジ起動するため、ミリ秒未満のコールドスタートとグローバル規模での超高速な応答性を実現しています。
- Cloudflare D1: SQLデータベースとしてネイティブな分散型SQLiteを使用し、Drizzle ORMを組み合わせて型安全なデータベースアクセスと高速なクエリレスポンスを実現。
- Cloudflare Cron Triggers: 定時ジョブ(Scheduled Events)として、毎日自動で新しいグローバルミッションを生成する仕組みを Workers 内に組み込み、サーバー運用のコストを最小限に抑えています。
cofit/
├── api/ # バックエンド (Cloudflare Workers)
│ ├── src/
│ │ ├── db/ # データベース接続、Drizzleテーブルスキーマ定義
│ │ ├── lib/ # Better Auth 設定などの共通ロジック
│ │ ├── routes/ # Hono API 各種ルーティング(ミッション、チャット、フレンド等)
│ │ └── index.ts # エントリーポイント、定期ジョブ定義
│ ├── wrangler.jsonc # Cloudflare Workers 設定ファイル
│ └── package.json
│
├── web/ # フロントエンド (Next.js 16 + React 19)
│ ├── src/
│ │ ├── app/ # App Router(主要画面: 計測画面、プロフィール、バッジ一覧)
│ │ ├── components/ # 再利用コンポーネント (3Dバッジレンダラー、カレンダー等)
│ │ ├── hooks/ # 加速度センサー処理、カウントロジック等のカスタムフック
│ │ └── lib/ # HonoクライアントやAuthクライアントの設定
│ └── package.json
│
└── package.json # ルート(Bun Workspaces 設定、一括フォーマットなど)
- Bun がインストールされていること
プロジェクトのルートディレクトリで以下を実行します。モノレポ全体のパッケージが一括でインストールされます。
bun installapi/.env.example および web/.env.example を参考に、それぞれのディレクトリに .env ファイルを作成してください。
cd api
bun run devcd web
bun run devブラウザで http://localhost:3000 にアクセスします。 ※運動の自動カウント機能(加速度センサー)をテストする際は、同一Wi-Fi環境内のスマートフォンなどの実機ブラウザからアクセスするか、ブラウザの開発者ツールでセンサーのシミュレーションを行う必要があります。
- ミッション & アクティビティ計測: 加速度センサーを用いた回数自動計測(スクワット・腹筋・腕立て伏せに対応)。
- パーティー(コミュニティ)機能: 招待コードを用いて友人とパーティーを結成し、共同でミッション(目標回数)の達成を目指す。
- DM & チャンネルチャット: パーティーメンバーやフレンドとリアルタイムにコミュニケーションが取れるチャット機能。
- フレンドシステム: 他のユーザーを検索・フレンド申請し、お互いのアクティビティを刺激し合うソーシャル機能。
- 3D実績バッジ獲得システム: 特定の目標を達成するとバッジが付与され、獲得バッジはリッチな3Dビューアで回転・拡大しながら鑑賞可能。