依頼の内容
マンツーマントレーニングジムの会員向け予約管理サイトを、委託を受けて1人で開発しました。半年以上の計画を立てて、必要な機能を順番に実装していく方法で開発を行いました。要件を聞き、画面を作り、サーバー側を書き、運用しながら直すところまですべて一人で担当しています。
この案件で意識していたのは、実際の店舗運用で問題が発生しないようにすることです。ペルソナを策定した際に、このトレーニングジムの主な利用者の年齢層が30~50歳であることから、デジタルネイティブ世代でなくても容易に利用できるUIを心がけて制作を進めました。
予約、キャンセル、決済、会員情報、管理者権限、メール通知のどれか一つでも雑な作りだと、現場の人が手作業で補うことになります。そのようなことが起きないよう、細心の注意を払って開発を行いました。
実装範囲
フロントエンドはNuxtとVuetifyで作り、Cloudflare上で動かす構成にしました。データベースはCloudflare D1(+Drizzle ORM/NuxtHub)、メール送信はResend、Bot対策にはTurnstileを使っています。決済はStripeのサブスクリプションを組み込み、Webhookで決済完了を受け取って会員側の状態を更新する形にしました。
Cloudflare D1はSQLiteであり、トランザクションは使用できないので、代わりにbatchを使用して原子性を保っています。他にもACIDの保証のために複数の施策を講じています。
会員側では、アカウント作成、予約、予約キャンセル、契約中プランの確認などを扱います。管理側では、会員管理、予約枠の管理、商品やプランの管理、注文の確認、各種設定を触れるようにしました。Adminとは別でModeratorも作成可能とし、権限も分けて、誰がどの管理機能を読めるか、書けるかを設定できるようにしています。
予約まわりでは、通常のスケジュールだけでなく、休業日や例外的な枠の調整も必要でした。また、予約をメールで知らせる処理、予約キャンセル時の通知、管理者承認の有無など、店舗側の細かいルールは管理者側の設定で変えられるようにしています。作る前にすべての要件を決定することが難しく、実装後に大きな追加実装や修正が入ることも多々ありました。
1人で進めるということ
1人開発なので、手を動かすのはいくらでも速くできる一方で、判断を後回しにすると、自分が苦しい思いをするだけでなく、クライアントにも大きな負担がかかります。DBの扱い方、画面の分け方、メール文面、決済失敗時の扱い、管理者が見るログの粒度まで、自分で決める必要がありました。誰とも連携せずに開発を行うことは楽でもあり、しんどくもあります。
今回の案件では、最初の要件がそのまま最後まで変わらないことは少なかったです。運用後のフィードバックで仕様変更することもありました。ですから、最小限の機能からはじめて、少しずつ広げていく開発方法をとりました。これは開発コストを削減するうえで大きな助けとなりました。
一方で、頻繁なヒアリングはクライアントにとって負担にもなります。どこまでを自分で進めて、どこまでをクライアントに任せるかのバランス取りは未だに難しく感じています。
所感
個人開発なら気が変われば好きに作り直せはよいですし、作って満足したらあとはポイ、ということも可能です。しかし、業務として受けたものはそうはいきません。動けば終わりではなく、相手が管理できること、困ったときに直せること、費用が膨らみすぎないことまで考慮した実装が必要です。
DB項目から予約の管理方法まで、決めなくてはならない物が非常に多いプロジェクトでしたが、それを1から作った経験は貴重だと感じます。保守管理も請け負っているため、今後も開発に携わることになります。

