【個人開発】メモ帳感覚で使えるGitHub草生やしアプリ「Leaf Record ～大草原不可避～」を作りました【Next.js×Rails】

# はじめに
こんにちは、とぴ（[@topi_log](https://qiita.com/topi_log)）と申します。
オンラインプログラミングスクールにてRuby on Railsをメインに学習しつつ、自主学習としてフロントエンドも勉強しています。
4/26にメモ帳感覚で使えるGitHub草生やしアプリをリリースしたので、アプリ紹介と技術、感想をまとめさせていただきます。

# 目次
1. 作成経緯
1. Webアプリ紹介
1. 技術スタック
1. こだわったところ
   1. UI/UX
   1. 技術面
   1. その他
1. 改善点・不具合
1. 追加したいと考えている機能
1. ブラッシュアップの方針
1. 感想

# 1. 作成経緯
オンラインプログラミングスクールにて、「ミニアプリweek」という短期間でアプリを作るイベントがあります。バグOK、一機能だけでもOKとゆるめのイベントで応募するために作成したものです。
4/22に開発を開始、4/26にリリースしたので制作期間は5日ほどですが、そのあとも順次ブラッシュアップしています。

# 2. Webアプリ紹介
メモ帳のように使える記録アプリで、保存ではなくコミットすることでGitHubにコミットできるアプリです。
プライベートリポジトリの作成からアプリ内で行えるため、GitHub側にリポジトリ作成をする手間を省けます。
<img src="https://i.gyazo.com/c272b1386122ac4162bee32114bae900.png" width="400px" />

サービスURL

https://leaf-record.vercel.app

GitHub

https://github.com/topi0247/leaf-record

### アプリの着想
スクールではMattermostでの交流があり、受講生全員分のtimesチャンネルがあります。
同じ時期に入った受講生（以降同期と表記）がtimesでその日のタスクに「GiHubの草の生やし方を考える」が長らくpendingで投稿されていました。
その投稿から「もっと気軽に草を生やすにはどうしたらよいだろう」と考えたのがきっかけです。草を生やすまでの手順を少なく済むように、あるいはPCを開かずともスマホから学習記録を手軽に取れるように、といったところからこちらのアプリを作成しました。

### 機能紹介
アプリの仕様上、基本機能はすべてログインしなければ使えません。
今回は[前回作成したアプリ](https://qiita.com/topi_log/items/3ef541d490ee4c332752)の反省としてレスポンシブ対応をしています。
PWA対応しているので、ネイティブアプリっぽくも使えます。
| トップ画面PC | トップ画面SP |
| :--: | :--: |
| <img  src="https://i.gyazo.com/7f538705b494fef8cde63f77d06910f9.png" width="600px" /> | <img  src="https://i.gyazo.com/f2250fcbc8794a9398d33be611b94ae5.png" width="155px" /> |
| アプリ説明と仕様上の注意を記載しました。 | メニューボタンは指の届きやすい下側に配置しました |

| リポジトリ一覧画面PC | リポジトリ一覧画面SP |
| :--: | :--: |
| <img  src="https://i.gyazo.com/e9c789d191c61995da0656e12f82b467.png" width="600px" /> | <img  src="https://i.gyazo.com/e993fd440ca9565573eb351e729cb296.png" width="180px" /> |
| すべてのリポジトリではなく、アプリを通じて作成したリポジトリのみ表示しています。 | SP用にレイアウト調整をしました。 |

| 記録画面PC | 記録画面SP |
| :--: | :--: |
| <img  src="https://i.gyazo.com/0a1137679d616f21c54e7de87b7381a5.png" width="500px" /> | <img  src="https://i.gyazo.com/7d48149a5824c192c70eeefa02a00616.png" width="135px" /> |
| 左カラムでファイル作成・選択ができます。記録を上から下に取るので、視線誘導的にファイル削除・ファイル名変更・コミットを下部に配置しています。 | ファイル操作やコミットをすべて下部のボタンから操作できるようにしました。 |

# 3. 技術スタック
### 使用技術
| カテゴリ | 技術 |
| ---- | ---- |
| フロントエンド | Next.js14(App Router), Tailwind CSS, shadcn/ui |
| バックエンド | Rails7.1.3 |
| データベース | PostgreSQL |
| 開発環境 | Windows, WSL2, Docker |
| インフラ | Vercel, Render.com |
| その他（フロントエンド） | Axios, Recoil |
| その他（バックエンド） | Octokit, DeviseTokenAuth, OmniAuth |

### ER図
<img src="https://i.gyazo.com/f1da9e989658599e72c1a6280ac928a1.png" width="400px" />

# 4. こだわったところ
### UI/UX
##### レスポンシブ対応
ページ数が少ない分レスポンシブ対応に力を入れました。
shadcn/uiを使いインタラクティブかつ使いやすさを追求し、開発段階で他の方に触っていただきFBを基に試行錯誤しながら作成しました。
より使いやすさを目指してこれからもブラッシュアップを続ける予定です。
| PC | SP |
| :--: | :--: |
| <img src="https://i.gyazo.com/22984535df7e146042532ec19d5efacc.gif" width="600px" /> | <img src="https://i.gyazo.com/fc12633e04ac38ad5ee1f87e537359e4.gif" width="175px" /> |

##### 読込中の表示
Tailwind CSSをつかいスケルトンローディングを実装しました。
shadcn/uiのスケルトンの挙動が不安定だったため、そちらのコンポーネントは使っていません。
| PC | SP |
| :--: | :--: |
| <img src="https://i.gyazo.com/5b23b0668cdcdd378a6348730920b654.gif" width="600px" /> | <img src="https://i.gyazo.com/30d627faa5b3bdca15fa0588f1064904.gif" width="280px" /> |

##### テキストエリアの表示域を調整
デフォルトのテキストエリアは初期表示域まで入力すると改行と同時にエリアが1行分追加されます。
好みの話になってしまいますが、すれすれで入力するのが好きではないので動的にエリアを調整してめいいっぱい入力できるような見た目にしています。
| PC | SP |
| :--: | :--: |
| <img src="https://i.gyazo.com/eaaf77565b21fa83cddda2fb84da1c0b.gif" width="800px" /> | <img src="https://i.gyazo.com/e8f331e8d8f98792e197bfafa3b27b3b.gif" width="280px" /> |

### 技術面
##### 【フロント】リポジトリ取得は1回のみ
バックエンドへフェッチ⇨バックエンドはOctokitを使ってGitHubAPIを叩くというのが全体の処理の流れです。
GitHubAPIは1時間あたりのレート制限が最大5000回です。コミット回数や利用者が多ければAPIへのアクセスが増えるので、減らすためにリポジトリは最初に1回取得したらRecoilで使い回すようにしています。
後述にある通りリポジトリの削除はGitHub上からのみ行えることからそのようにしております。

##### 【バック】コミットは変更を一括で出来るように
開発初期段階では、1ファイルの変更につき1コミット行っておりました。
GitHubに草を生やす意味では、コミット数が多ければ多いほど鮮やかな草が生えるのでコンセプトにはあっているもの、やはりAPIを叩く回数が増えレート制限にすぐ引っかかる恐れがありました。
Octokitにベースブランチのツリーと最新コミットの情報を取得できるものがあったため、コミットしたら新規ツリーを作成し情報を乗せてまとめてコミットするように修正しました。

### その他
#### リポジトリはアプリ上で作ったもののみ操作可能
他のリポジトリを操作して問題が置きないよう、DBにアプリ上で作ったリポジトリ名を持っておきDBにあるリポジトリのみ操作できる用意にしました。

#### リポジトリ削除はGitHub上からのみ
リポジトリの削除はデリケートな操作なため、削除に関してのみアプリで削除できないようにしています。
少し手間ではありますが、誤操作で削除することがないようにする目的もあります。

#### GitHubのアクセストークンの暗号化
アクセストークンは生のままDBに保存せず、暗号化してから保存しています。
セキュリティ的にもそうした方がいいのではないかと判断し実装しました。

# 5. 改善点・不具合
#### 改行でのテキストエリアの挙動
文章量が長くなったときにエリアの挙動がおかしくなるのを確認しています。
致命的な不具合ではないものの、気になるので修正します。

#### ファイル新規作成 ⇨ 同じファイルを削除などでエラーが出る
コード設計に不足があり、ファイル新規作成から削除、あるいは削除したファイルと同じ名前のファイルを新規作成やフィアル名変更で作ると同じくエラーが出ることを確認しています。
バックエンドの設計がよろしくないだろうと検討はついているので、対応する予定です。

#### 下部に表示されるボタンが見づらい時がある
長文をファイルへ書き込みスクロールすると、ボタンの背景色を透過している関係でファイルの文字とかぶり見づらくなります。
こちらは背景色を固定化するなど修正したいと考えています。

#### ディレクトリが作成できない
たとえば「月ごとにまとめたい」などの対応が現在出来ていない状態です。
UIの設計から考える必要があることから直ぐに対応はできないですが、いずれできるようにしたいと考えています。
そのときはファイルの移動もできるようにしていければと思います。

# 6. 追加したいと考えている機能
現段階（2024/04/30）では下記機能を追加したいと考えています。
- マークダウンプレビュー
   - GitHub用
   - Qiita用
- 草の生え具合をアプリ上からも確認できるようなもの
- ディレクトリ作成可能に
- publicリポジトリでも作成できるように
   - セキュリティ上privateへのアクセスが問題もいるのでそういった方も使えるような方法

# 7. ブラッシュアップの方針
使いやすさを重視したいと考えているので、UI/UXを中心に機能追加していく予定です。
イベント用に作ったミニアプリですが、この記事も下書きをアプリを使って作ったりメモを取りたいときに使ったりと自分も愛用する気がするので、のんびりアップデートしていこうと思います。
就活用PFを別で作っておりしばらくはそちらがメインになりそうなので、気分転換としてブラッシュアップする方針になるかと思います。
ただ長くたくさん使って欲しいと思いますので、アプリ内のお問い合わせページなどからフィードバックいただけましたら小躍りして喜びます。

# 8. 感想
これまで作ってきたアプリはCGM系のアプリが多かったりAPIを叩くこともなかったので、大変勉強になりました。
shadcn/uiの見た目の綺麗さに感動しつつ、拡張性を活かせていないのが反省点。
着想を得たときの同期からも感想いただけたので大変嬉しいです。
個人で開発した5つ目のアプリと初めてアプリ作った頃よりアプリ解像度がますます上がっていくのでアプリ開発楽しいな～と日々思います。

# 終わりに
リリースした時点でこの記事を書こうとしたのですが、気になるところが多すぎて改善していたら少し日が経ってしまいました。
たくさん触っていただけたら嬉しいです。

X（旧Twitter）もやっております！よろしければフォローよろしくお願いいたします！

https://twitter.com/topi_log