01
アプリケーションの概要
「マソ君の日常」は、筋トレ記録と2Dキャラクター育成を組み合わせたWebアプリです。重量・回数・セット数からトータルボリュームを自動計算し、成果を育成ポイントやアイテムを通じて「マソ君」の成長へ反映します。
ホーム、記録カレンダー、トレーニング入力、履歴分析の画面を用意しています。現在の記録データはブラウザ内に保存しており、Supabaseによる認証とデータベースの下地まで作成済みです。
創った背景
一般的な筋トレ記録アプリは数値管理が中心で、入力そのものが作業になりがちです。特に記録習慣のない人は、重量や回数だけでは成果を実感しにくく、継続する理由を見失いやすいと考えました。
そこで、育成ゲームが持つ成長と報酬の楽しさを筋トレ記録へ取り入れました。自分がトレーニングを続けるほどマソ君も成長する仕組みにし、記録を義務ではなく、次の変化が楽しみになる体験へ変えることを目指しています。
主要機能はWebで公開済みです。記録データのクラウド保存は、次の段階として進めています。
02
主要ユースケースと設計意図
記録を続けたいのに、数字だけでは手応えを得にくい人を中心に据えました。トレーニング直後の短い時間で入力を終え、その場で成長を受け取れる体験を設計しています。
- Who誰が
- 筋トレを習慣にしたい人 始めたばかりの人や、数値の記録だけでは成果を実感しづらい人を想定しています。
- Whenどんな場面で
- 種目を終えた直後に ジムでセットを終えたときや、帰宅後にその日の内容を振り返る場面を想定しています。
- What何をするのか
- 記録し、成長を確かめる 種目・重量・回数・セット数を入力し、自動計算された成果とマソ君の変化を確認します。
Design intent
「記録した直後に、成長が返る」短い循環
入力の先にある報酬を遠ざけないため、記録、計算、育成反映をひと続きにしました。利用者は数値を管理するだけでなく、今日の行動がどんな変化につながったかを、その場で理解できます。
- 迷わせない必須入力を種目・重量・回数・セット数に絞る
- 待たせない入力中からトータルボリュームを自動計算する
- 続けたくなるポイントとキャラクターの変化で努力を可視化する
03
画面と構成
完成時の画面イメージ、体験の変化、データが育成結果へ届くまでの構成を、3つの図でまとめました。
ホーム画面の完成イメージ
今日の状態、マソ君の成長、次の記録操作を一画面で確認できる構成です。ここでは掲載用に再構成したUIモックを示し、実際の動作は公開アプリで確認できます。
今日も積み上げよう
マソ君 Lv.12 次のレベルまで 320 pt数字の保管から、成長を実感する記録へ
同じトレーニング記録でも、入力後に意味と報酬を返すことで、次回も記録する理由をつくります。
数字だけを保存
- 01重量・回数を入力
- 02一覧へ数値を追加
- 03成果は自分で読み取る
入力が作業になり、続ける目的を感じにくい。
行動を成長へ変換
- 01トレーニングを記録
- 022,400kg・24ptへ換算
- 03マソ君の変化を確認
努力と変化が結びつき、次の記録が楽しみになる。
記録から育成反映までの構成
画面、計算ロジック、保存先を分け、現在のローカル保存からSupabaseへ段階的に移行できる構成です。
UI layer
Next.js / React / Tailwind CSS
- ホーム
- 記録入力
- 履歴・分析
Domain logic
TypeScript / Zod / Vitest
- 入力検証
- ボリューム計算
- ポイント・育成判定
Data layer
段階移行できる保存設計
- 現在ブラウザ内保存
- 接続予定Supabase Auth
- 接続予定PostgreSQL / RLS
04
技術スタック
Next.js 16 / React 19
画面表示、ルーティング、アプリ全体の構成
TypeScript
記録や育成状態を型付きで安全に管理
Tailwind CSS 4
スマートフォン中心の画面と操作部品
Supabase
Auth、PostgreSQL、RLSによるユーザーデータ分離
Zod
重量・回数・セット数などの入力検証
Vitest
計算、換算、育成、日付処理の単体テスト
05
技術選定の理由
要件・制約ホーム、カレンダー、入力、分析の4画面で、同じ記録・育成状態を共有する必要がありました。将来の認証・クラウド保存にも無理なく広げられる構成が条件でした。
比較した案単一HTMLとVanilla JavaScript、クライアントだけで完結するReact SPAも検討しました。
選定理由Reactで画面部品を再利用し、Next.jsでルーティングとレイアウトを一貫して管理できるためです。今後サーバー側の処理を追加するときも、同じ基盤のまま拡張できます。
要件・制約重量・回数・単位・日付・50段階の育成状態など、形の異なるデータを複数画面で安全に受け渡す必要がありました。
比較した案JavaScriptとJSDocによる型注釈も候補にしました。
選定理由データ構造を型として共有し、項目の追加や計算ロジックの変更時に不整合を開発中に検出できるためです。記録と育成状態の食い違いを減らせます。
要件・制約ジムでも片手で使えるスマートフォン中心のUIを、画面間で余白や状態表現を揃えながら短い周期で調整する必要がありました。
比較した案プレーンCSSとCSS Modulesを比較しました。
選定理由レスポンシブ指定とデザイン値を画面部品の近くで管理でき、試作中の調整が速いためです。共通の尺度を使うことで、画面ごとの見た目のばらつきも抑えられます。
要件・制約利用者ごとの認証と記録の分離、日付や種目を軸にした集計が必要です。一人で開発するため、認証基盤と独自APIをすべて構築する負担は抑えたいと考えました。
比較した案Firebaseと、独自API+PostgreSQLの構成を比較しました。
選定理由Auth、PostgreSQL、RLSを一つのサービスで扱え、リレーショナルな履歴分析とユーザー単位のアクセス制御を両立しやすいためです。現在はブラウザ内保存で操作を検証し、接続情報がなくても開発を進められるようにしています。
要件・制約重量・回数・セット数の上限や未来日、メモの文字数などを、実行時にも同じ規則で検証する必要がありました。
比較した案画面ごとの手書き条件分岐とYupを比較しました。
選定理由検証ルールをスキーマとして一か所にまとめ、TypeScriptの型とつなげやすいためです。画面ごとの検証漏れを防ぎ、利用者へ返すエラーも揃えられます。
要件・制約ボリューム計算、kg・lb換算、育成ポイント、経験値、日付処理は、小さな変更でも結果が連鎖して変わるため高速な回帰確認が必要でした。
比較した案Jestと、ブラウザ操作だけで確認するE2Eテスト中心の構成を比較しました。
選定理由TypeScriptの設定と合わせやすく、計算ロジックを画面から切り離して素早く実行できるためです。主要な計算18件を単体で確認し、E2Eテストは公開前の次段階に分けています。
06
工夫した点
筋トレの成果を育成体験へ変換
トータルボリュームを表示するだけでなく、育成ポイントやアイテムを介してマソ君の成長につなげました。
スマートフォンで記録しやすい導線
画面下部からホーム、記録、分析へ移動できます。入力中はトータルボリュームをその場で確認できます。
入力ミスと二重保存への対策
未来日の記録、入力値の上限、メモの文字数を検証。リクエストIDを使い、同じ記録の二重保存も防ぎます。
計算処理を画面から分離
ボリューム、kg・lb換算、育成ポイント、経験値、日付処理を分け、単体で検証できる構成にしました。
50段階の変化を視覚化
レベルに応じてキャラクター画像を切り替え、呼吸、まばたき、レベルアップ時の動きをCSSで加えています。
07
現時点の改善点
- 01
トレーニング記録、設定、育成状態をSupabaseへ保存する処理を接続する。
- 02
ブラウザ内の既存データを、ログイン後にクラウドへ移行できるようにする。
- 03
複数ユーザーを使い、RLSによるデータ分離を結合テストで確認する。
- 04
記録の編集・削除と、それに伴う育成ポイントの差分調整を実装する。
- 05
自重種目と有酸素運動の計算、週別・月別の分析を追加する。
- 06
公開版のE2Eテストと性能計測を行う。