【個人開発】最寄りの綺麗なトイレを見つけるアプリをリニューアルしました【Next.js×Rails】

# 名称
Quick Clean Restroom Map

# 概要
最寄りの綺麗なトイレの位置をリアルタイムで案内し、トイレの情報を提供します。

# URL
https://quickcleanrestrooms.com/

# 備考
通常時はコスト削減のため、Vercelとsupabaseを利用しています。

# アプリを開発した背景
ある日、小さな子供（長男・次男）を連れてトイレを探していたとき、なかなか清潔なトイレが見つからず、非常に困った経験がありました。Google Mapsで検索しても、見つかるのは公共のトイレばかり。清潔で快適な「綺麗なトイレ」をすぐに見つけることが難しいと感じたことはありませんか？

そんな経験をしたことがある方は少なくないでしょう。実際、私自身も同じ問題に悩まされていました。特に、小さな子供を連れている時や、おしゃれな服を着ている時など、清潔なトイレを使いたい場面で、何度も歩き回ったり、不便な場所で我慢しなければならなかったことが何度もありました。

この問題を解決し、同じ悩みを抱える人たちの助けになりたいと思い、「Quick Clean Restroom Map」を開発しました。このアプリは、ユーザー同士が清潔なトイレの情報を共有することを目的としています。例えば、どのトイレが清潔で、どの施設が快適かを簡単に見つけることができます。

「Quick Clean Restroom Map」を使えば、清潔なトイレを探して右往左往することなく、必要な時にすぐに最適なトイレの情報を手に入れることができるでしょう。私自身が経験した問題から出発し、同じような悩みを持つ人々に役立つアプリケーションを提供するために、「Quick Clean Restroom Map」を開発することにしました。

# 前回作成したアプリ(Javascript✖️Rails)の改良版です
https://qiita.com/JZ8xNeXY/items/d5f66eb1d48689fb4cfc

# アプリをリニューアルした背景


### リニューアル前の課題

リニューアル前のアプリには以下の課題がありました：

#### ユーザー体験の向上

- **ユーザー認証機能の使いづらさ**: トイレを登録したりレビューする際のユーザー認証が煩雑で、新規登録やレビューがされづらかった。
- **多すぎるページ遷移**: ページ遷移が多く、操作が煩わしかった。

#### コードの品質と保守性

- **コードの重複**: JavaScriptで作った画面とHTMLで作った画面が混在しており、コード量が多く、重複が多かった。
- **メンテナンスの難しさ**: 再利用可能なコンポーネントが少なく、変更や修正が多岐にわたり困難だった。

#### データのやり取りの効率化

- **非同期処理の欠如**: 登録やレビューの際にページ遷移が多く、非同期処理が不足していた。
- **セキュリティの懸念**: `gon` を使ってRailsからJavaScriptにデータを渡していたが、必要以上のデータを渡してしまい、クライアント側に過度な情報が露出するリスクがあった。


### リニューアルの方針

#### ユーザー体験の向上

- **ログイン不要でトイレの登録が可能に**: ユーザーの利便性を大幅に向上させる。
- **ユーザーの評価からAIによるトイレ判別の導入**: 登録時にトイレの綺麗さをAIが判別する仕組みを導入し、AIによる客観的評価の仕組を導入する。これにより全ての施設の評価が表示される。

#### コードの品質と保守性

- **ReactのMUIを使用**: 既存のデザインコンポーネントを活用し、開発速度を向上させる。これにより、デザインの一貫性を保つ。
- **TypeScriptの導入**: 型を定義し、コードの可読性と信頼性を向上させる。
- **フォルダ構成の改善**: プレゼンテーションとコンテナのフォルダ構成に分け、コードの整理とメンテナンスをしやすくする。

#### データのやり取りの効率化

- **Next.jsとRails APIの組み合わせ**: 非同期処理を強化し、データの取得や更新をスムーズに行う。これにより、ユーザーの操作に対するレスポンスを向上させる。
- **セキュリティの向上**: Rails APIを使用することで、データのやり取りをAPIエンドポイントを通じて行い、セキュリティを向上させる。また、クライアント側に必要以上のデータが渡されないようにし、情報露出のリスクを軽減する。



# アプリの画像
![localhost8000 0006-06-19 at 5.11.48 AM.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/917693/31dd27cd-6af6-25d5-d390-6ba88c89b22b.jpeg)



# 利用方法①　最寄りのトイレを探す
* 最寄りのトイレを探す: デバイスのGPS機能がオンになっていると、現在地の周辺にある最寄りのトイレがマップ上に表示されます。オフになっていると東京駅がマップ上に表示されます
* トイレ情報の確認する: マップ上に表示されたトイレのアイコンをクリックすると、そのトイレの詳細情報がポップアップで表示されます。情報にはトイレの清潔さ、利用可能な設備などが含まれます

* ルートを検索する: トイレの詳細情報ウィンドウを閉じると、トイレまでの推定徒歩時間とルート案内へのリンクが表示されます

* ルート案内機能を利用する: 表示されたリンクをクリックすると、Google MapsまたはGoogle Mapsアプリが起動し、選択したトイレまでの詳細なルートが案内されます。これにより、スムーズに目的地までの道のりをたどることができます

[![Image from Gyazo](https://i.gyazo.com/fac91fbff432a50a4651c19fed3551b8.gif)](https://gyazo.com/fac91fbff432a50a4651c19fed3551b8)

# 利用方法②　トイレを登録する（地図上を右クリックして緯度経度情報を取得）【PCを想定】
* 登録したい場所を右クリックする
* 画像があれば「画像投稿」ボタンをクリックして画像を選択する。そのほか、名称、コメント、設備情報、入力して、「送信する」をクリック

[![Image from Gyazo](https://i.gyazo.com/2e7190c50e253922749a3d790421106a.gif)](https://gyazo.com/2e7190c50e253922749a3d790421106a)

# 利用方法③　トイレを登録する（写真の緯度経度情報を活用）【スマートフォンを想定】
*　登録したい場所でスマートフォンのGPS機能をオンにしてトイレを撮影する
*　ヘッダー右上の　登録　ボタンをクリックする
*　「画像投稿」ボタンをクリックして画像を選択する。そのほか、名称、コメント、設備情報、入力して、「送信する」をクリック

[![Image from Gyazo](https://i.gyazo.com/996d827e25353f50ac9d5258c1329a3e.gif)](https://gyazo.com/996d827e25353f50ac9d5258c1329a3e)



# 主な使用技術
# 主な使用技術

| カテゴリー      | 使用技術                                      |
|-----------------|-----------------------------------------------|
| フロントエンド  | React 18.3.1<br>Next.js 14.2.3<br>TypeScript 5.4.5  |
| バックエンド    | Ruby 3.2.0 <br> Ruby on Rails 7.0.8.3 (API モード) |
| インフラ        | ECS(Fargate)                                  |
| DB              | RDS(MYSQL)                                    |
| 認証            | devise_token_auth                             |
| CI/CD           | GitHub Actions                                |
| 開発環境        | Docker                                        |
| API             | GoogleMapsAPI <br> OpenAPI                    |





# 技術選定理由
### フロントエンド（Next)
コンポーネント化により、コードの再利用と保守がしやすくなりました。各UI要素を独立した部品として分けることで、複数るファイルを同時に作業しやすくなり、新機能を追加する際の手間が減りました。また、Reactを使うことで、JavaScriptよりもシンプルにコードを書くことができ、開発がスムーズになりました。

### バックエンド（Rails）
「設定より規約」の原則を採用し、ウェブアプリケーションの開発が迅速に行えるようにしました。フロントエンドを重視するため、バックエンドの設定を簡素化し、標準的な構成を利用することで、開発スピードを向上させました。

### 自動デプロイ（Github Actions)
GithubActionsを活用して、ECSへの自動デプロイを実現しました。フロントエンドとバックエンドの2つのコンテナを効率的に管理し、デプロイのプロセスを自動化することで、運用の効率が上がり、信頼性も向上しました。これにより、開発から本番環境への移行がスムーズになりました。

### 開発環境(Docker)
開発環境の一貫性を保つためにDockerを使用しました。Docker Composeを使うことで、複数のコンテナを簡単に管理し、開発環境と本番環境を同じ設定にすることができます。これにより、環境設定の手間が省け、開発者が効率的に作業できるようになりました。


### API（Google Maps／GPT-4o)
マップ機能にはGoogle Maps APIを利用しました。これにより、高精度な地図データを提供し、ユーザーがトイレの場所を簡単に見つけられるようにしました。
また、トイレの画像から清潔度を評価するためにGPT APIを使用しました。AIによる自動評価機能を取り入れることで、客観的で一貫した清潔度評価が可能になり、ユーザーの信頼を得やすくなりました。

### インフラ
![component.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/917693/2f3608a4-89e1-ef99-e336-85ffce70f55b.png)

# 機能要件
* マップ表示機能: ユーザーが現在地周辺（GPSで位置情報を取得）の綺麗なトイレをマップ上で確認
* 施設個別情報表示機能: 各トイレの詳細情報を表示
* ルート案内機能：最寄りのトイレまでの徒歩時間を表示
* ルート案内詳細機能：GoogleMapやGoogleMapアプリを活用して詳細な道案内を表示
* 施設情報登録機能: ユーザーが新たなトイレの情報をマップ上で登録
* 施設個別情報編集機能: 登録されたトイレの情報を更新・編集（管理者のみ）
* 施設情報削除機能: トイレの情報をマップ上で削除（管理者のみ）
* トイレの清潔度の評価機能: トイレの画像から５つ星でAIによる自動評価
* ユーザーログイン機能 :（管理者のみ）
* レスポンシブ対応: スマートフォンやタブレットなど、様々なデバイスでの利用に対応
* 独自ドメイン、HTTPS化: セキュリティと信頼性の向上

# リニューアル時に工夫したポイント
**ユーザーの手間を減らす視点でよりシンプルになるように工夫**

**① 緯度経度情報からサクッと登録できる機能を追加**
　ユーザーがトイレの写真をアップロードするだけで、写真に含まれるGPS情報から自動的に位置情報が取得され、トイレの場所が簡単に登録されます。この機能により、手動で位置情報を入力する必要がなくなり、よりスムーズに情報を提供できます

 緯度経度情報が読み込めない場合
 ![0aef1777e97c5b8d2ca88f2e3d0ee718.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/917693/b715d79c-9191-1cf2-9301-0b4a69468128.jpeg)



**② AIによるトイレの清潔度を自動で評価する機能（５段階）を追加**
　アップロードされたトイレの写真をAIが解析し、清潔度を5段階で自動的に評価します。これにより、ユーザーは客観的な評価を元にトイレを選択することができ、清潔なトイレをより簡単に見つけられるようになりました。

AIへの指示文

 「あなたは画像に基づいてトイレの清潔度を評価するように訓練されたAIです。提供された画像に基づいて、トイレの清潔度を0から5のスケールで非常に厳格に評価してください。トイレでない場合は0と回答してください。説明は不要です。0から5の単一の数字で回答してください。例: 0, 1, 2, 3, 4, 5。」

 なお、コストAPI費用のコストを削減するため下記のような工夫も実施しました。これによりAPIの利用料を抑えることができました。
 
https://qiita.com/JZ8xNeXY/items/0a7d17ad41619f3fb036

なお、下記のような綺麗ではないトイレを登録すると低い評価になります。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/917693/09014933-f4c1-9e7d-1486-67d8ea62485c.jpeg" width="300">

<a href="https://gyazo.com/b06a922e059dcf39bd57c2371071f0e0">
  <img src="https://i.gyazo.com/b06a922e059dcf39bd57c2371071f0e0.jpg" width="300">
</a>



**③ 現在地を表示するボタンを削除**
　ユーザーの現在地を自動的に取得し、マップ上に表示するように変更しました。これにより、ユーザーが自分でボタンを押して現在地を表示する手間が省け、アプリの使いやすさが向上しました。

この他、このアプリの特徴を考慮し、ユーザー管理機能を簡素化し、他のページへの遷移を最小限にするなど、使いやすさを向上させる工夫をしました。

# 参考にしたもの
https://qiita.com/shutooorm02/items/544af0a65de19e3103bd

https://zenn.dev/ddpmntcpbr/books/rna-hands-on

# 大変だったこと

* 新しい技術に挑戦したこと
リニューアルの際には、これまで使用したことのないDocker、ECS、React、TypeScriptといった新しい技術に挑戦しました。これらの技術を学び、実際にアプリに組み込む作業は非常に大変でしたが、結果としてアプリのパフォーマンスが大幅に向上しました。

* よりシンプルになるよう工夫したこと
アプリの使い勝手を向上させるために、ユーザーインターフェースをできるだけシンプルに保つことに注力しました。複雑な機能を削減し、ユーザーが直感的に操作できるようにしました。

* 新しい機能を追加したこと
　ユーザー体験を向上させるために、新しい機能を積極的に追加しました。例えば、AIを活用したトイレの清潔度評価機能や、写真に埋め込まれた位置情報を自動的に取得する機能などです。これらの機能を追加するために、多くの調査と開発作業が必要でしたが、価値のある機能を提供することができました。

 
# おわりに
この記事を読んでいただき、ありがとうございます。アプリのリニューアルにあたり、多くの新しい技術に挑戦し、ユーザー体験を向上させるための工夫を重ねてきました。今回のリニューアルが皆様にとってより快適なトイレ探しのサポートとなることを願っています。

また、これまで相談に乗ってくれた方々や、様々なアドバイスをくださった皆様に心から感謝申し上げます。皆様のご支援がなければ、このリニューアルは実現できませんでした。これからも「Quick Clean Restroom Map」をよろしくお願いいたします。