趣味の壁を超える挑戦 ~ 「EMBE」一人開発の軌跡


[個人開発のカレンダー|Advent Calendar 2023 - Qiita](https://qiita.com/advent-calendar/2023/personal-developement) に向けた記事です。
今回、初めてアドベントカレンダーに参加します。

https://qiita.com/advent-calendar/2023/personal-developement

12月に個人開発でWebサービスをリリースしたので、どんな事があってどんなことをしたのかをゆるく書いていこうと思います。具体的なプログラミングの話はしません。

## 個人開発の魅力と難しさ

個人開発の魅力の一つに、"気軽さ"があります。開発する人によってそのスタンスは変わると思いますが、開発物の収益性が見込めなかったとしても自身のリソースを使って着手することができます。作りたいものを作る手段が個人開発だと思います。

昨今、ローコード・ノーコードツールの充実やchatgptなどの生成AIの登場により、個人開発のハードルは下がっています。一方で、個人レベルで作る開発物と企業や組織が作る開発物とのクオリティの格差も広がっているように思います。

気軽に簡単に作れるけど、他のサービスと比べて見劣りするので誰にも使ってもらえない。そして、勉強になったからと納得してサービスを閉じる。この記事を読む方であれば、誰もが通った道ではないでしょうか。当然、私もその一人です。

次こそは...

## 開発物の紹介

書類の管理・出力をするWebサービス「EMBE」を公開しました。

https://embe.jp

### 主要機能

#### 電子書類のバージョン管理機能

その名の通り、過去分の履歴を保持することができます。

![Screenshot 2023-12-06 at 16.40.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/28544/8f030906-1de3-d28a-6479-706f98f6487c.png)

#### 電子書類に文字等を埋め込んでPDFをダウンロードする機能

書類内の住所や氏名、チェックボックスや日付などを入力してPDFをダウンロードすることができます。

![Screenshot 2023-12-06 at 15.47.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/28544/73de2859-f279-5150-9051-5537e3193806.png)

#### 電子書類の共有機能

PDFダウンロード画面を共有することができます。以下はPRように作成したものです。ぜひリンクにアクセスしてお試しください。

https://embe.jp/shared/document/503411214d7a9f42f15bdd1370035b9ed9f7420ecebba5d11c6ca53abc7f12b475f984a42762b6c78251cd50acc35c6f020cec870c0b4131ceb3edd134ac4e3c/export

#### API連携

PDFダウンロード機能をAPIでも提供しています。例えば、"SFAから顧客情報がインプットされた書類を出力したい" といった場合にご利用いただけます。

### 無料利用できます

無料でのご利用でも機能制限は設けていません。大量にPDFダウンロードをしたり、ということがなければ無料でご利用いただけますので、ぜひお気軽に使ってみてください。

## 開発のきっかけ

"Reactを使ってみたい" が最初の思いでした。あとはこだわりなかったので、アイディアストックからサービスを選んで適当に開発を始めました。
おそらくENBEのサービスアイディアについては、"誰でも思いつきそう"という平凡な評価になるのではないでしょうか。

加えてもうひとつテーマを決めてました。それは、脱Emacs。
何度かVSCodeへの移行をトライしていましたが失敗続きでした。この開発をもってVSCodeに完全移行する強い気持ちを持っていました。
（なぜエディタを移行したかったのかは、また別のお話で。）

ですので、当然開発の初手はエディタを自分色に染め直すところからです。ただ、Emacsとかと比べると設定は沼化しないので、すぐに終わったと記憶してます。"すぐ"の感覚が麻痺してる可能性もありますが。

今回の開発ではやりたいことはあっても、作りたいものはありませんでした。個人開発で作るものを決めるのに頭を悩ませる人をたまに見かけますが、そんな必要ないと思います。それよりも、適当に作るものを決めて、それをどう磨くかに注力したほうが良いものができるように思います。

## 技術・ツール

### 技術スタックと選定理由

改めて選定理由を書くと、何も考えてないことが伝わってしまいますね。
実装してみての評価も記載しましたが、強いて言うなら．．という感じで振り絞りました。

#### フロントエンド
- React
  - 選定理由：業務で使っているチームがあったので、使ってみたかったため。
  - 結果：ドキュメントが豊富で、コンポーネントベースのアーキテクチャにより、再利用可能なUIを素早く構築できました。
- TypeScript
  - 選定理由：トレンドを学ぶため。
  - 結果：静的型付けにより、バグの早期発見ができた気がします。
- TailWindCSS
  - 選定理由：トレンドを学ぶため。
  - 結果：書きやすく、直感的なコーディングができました。

#### バックエンド
- Ruby on Rails
  - 選定理由：開発の速さ重視。加えて、gemが豊富でやりたいことが低コストでできる目処があったため。
  - 結果：強い規約と豊富なライブラリにより、必要な機能を素早く実装できました。
- Postgresql
  - 選定理由：Railsのデフォルトのため。
  - 結果：Railsとの相性の良く、設定等で困ることがありませんでした。
- Redis
  - 選定理由：使用経験があったため。
  - 結果：高速なデータアクセスができ、レスポンスタイムの短縮ができました。
- devise
  - 選定理由：機能が充実しており、メジャーかつメンテされているため。
  - 結果：ユーザー管理機能を素早く実装できました。
- rspec
  - 選定理由：テストの構造化がしやすいため。
  - 結果：直感的にテストを書くことができました。

### サーバー構成

※ システム構成図の書き方わからず、それっぽく書きました

![EMBEシステム構成図.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/28544/962b9d6d-b008-ed98-5a27-603023774143.png)

### 開発で使ったツール・サービス

本番環境のインフラを除くサービス・ツールです。

- ハードウェア 
  - Mac mini(M1 16GB) 
- Macアプリ
  - emacs：コーディング
  - VSCode：コーディング
  - iTerm2：コマンド実行
  - Postman：APIの動作確認
  - DBeaver：DB確認
  - Pixelmetor Pro：画像・アイコン作成
  - Blendar：画像作成
- Webサービス
  - BitBucket：コード管理・CI
  - Trello：タスク管理
  - FIGMA：UIデザイン作成
  - chatGPT：相棒
  - Github Copilot：コード補完

## 着手からリリースまでの流れ

大まかにですが、以下のような流れで開発をしていました。

1. テーマ決め
React使う、VSCode使うなど。すごく適当に、その時やりたいことベースで決めました。
1. サービス決め
アイディアストックからピックアップしました。ここで悩むと一生悩むので、敢えて雑に決めました。細かいこと考えずにとりあえず決めてしまうことをオススメします。
1. Reactの勉強
[GitHub - alan2207/bulletproof-react](https://github.com/alan2207/bulletproof-react) のコードリーディングをメインで学びました。
この時点で使用予定だった技術で経験がなかったのがReactのみだったので、Reactのみインプットしました。
1. 機能決め
雑に決めたサービスの詳細を考えました。ここは最初の山場でした。ビジョン（最終的にこんな感じに使われるようになって欲しいイメージ）を決め、マネタイズポイントを考慮しつつ機能を箇条書していきました。この時点では、何が主要機能は決めていましたがファーストリリースにどの機能まで含めるかは決めていませんでした。
1. デザイン作成
PCサイズにのみにターゲットを絞りFIGMAでデザイン作成。各画面で2パターンくらいずつは作成して検討していたと思います。サービスロゴやアイコンなどの画像は、このタイミングでは作り込みせず仮当てのみとしました。この時点で作成したデザインはリリース時には跡形もなく...（そんなはずではなかった）
1. DB設計
前段で出した全機能を扱えるテーブル設計をしました。アウトプットはPlantUMLを使用してクラス図です。正規化は特に意識をして、個人開発だからと甘えないようにしました。
1. API設計
バックエンドはRailsの想定でしたので、基本はRESTfulを意識して必要に応じてアレンジしました。この時点では、ファーストリリースに確実に含めるであろう主要機能のみ設計しました。アウトプットはOpenAPIフォーマットでAPI仕様書です。これを使ってmockサーバーを立ててフロント開発をする想定でしたが、API仕様書が活用されることはありませんでした..
1. API開発
DB設計とAPI設計がされているのでコードに落とし込むだけでした。Railsはあまりコード書かなくても定義を書けば実装が進んでいくので、開発体験はかなり良かったです。Request Specテストで正常系・準正常系をだいたい揃えておいて、基本的にオールグリーンを維持しつつ、基本的に手動で動作確認はぜずに進めていきました。
1. フロント開発
bulletproof-reactを参考にしつつ、地道に実装をしました。最初はCSSを一切当てず、HTMLでコンポーネントを作り、ロジックを当てていきました。UnitテストやStorybookの実装は、したかった（しなかった）
1. 本番環境構築
5−6割程度動くようになって、本番環境を整えました。この時点でmaster（or main）ブランチに当たったコードは自動デプロイされるようにしました。会員登録の動線だけは隠して、URLを直打ちすることで本番環境の動作確認ができるようになりました。
1. 改善、改善、改善...
実装、確認、追加・修正（機能仕様・デザイン含む）を繰り返し行いました。一生終わらないような感覚でした。完璧を追い求めた感覚はまるでありませんが、仕様通りに作って使用してみるとしょぼく感じてしまうんです。そして、そこを補強すると他がしょぼく見えるようになってしまう無限ループ。
1. リリース
常に本番適用をしながら開発をしてきたので、実際には会員登録の動線を表示させる対応のみです。達成感はありません。"もういいや.."そういう感じでした。

## やって良かったこと・オススメしたいこと

### 生成AIはフル活用する
なんでも相談するのが良いと思います。相談する過程で言語化ができますし、気軽に他の意見が聞けるのはすごく有益です。ただ、必ずしも正しい回答を得られるわけではないので言いなりになってしまう可能性があるなら注意が必要です。

### ライブラリは適切に
機能を実装する中で、大体のことが世に出回っているライブラリで実現できてしまいます。ただ、そのライブラリもピンキリです。メンテされてないものも腐る程あります。あと、地味に学習コストもかかります。安易な選択は自分の首を絞めるので、慎重に選択しました。個人開発だと、まいっか..と気軽に使ってしましやすいように思います。

### DB設計は手を抜かない
DB設計をする場合は工程の序盤に来ることになると思うので、先走りたい気持ちから疎かになりがちです。実装しながら決めたりということもあると思います。ですが、DB設計がイケてないと間違いなくアプリケーションコードは荒れますし、リリース後の機能追加や仕様変更など、毎回頭を悩ませることになります。時間が溶けます。あとからリファクタリングすればいいやという考え方もおすすめできません。おそらくフロントまで影響することになるので、最初に納得のいくDB設計をするのがすごく重要です。良い設計をしようと思うとどうしてもスキルに依存するので意識するだけではどうにもなりません。まずは、"もうちょっとDB設計ちゃんと考えておけばよかった"という後悔を防ぐようにベストを尽くすのが本当に重要と思います。

### 自動テスト
API開発は、特にテストの恩恵が大きいと感じます。テストを書いたほうが格段に開発速度は増します。
一方でフロントは、Reactが初めて使う技術だったということもあり書かない判断しました。というのも、実装が試しだめしなので、途中で大きめのリファクタリングを何度かしています。その度にテストの修正は手間だし、結局レイアウトは目視しないと安心できないし、手間が勝つ未来しか見えませんでした。
もしReactに精通していて勘所がわかっていたり、本業がデザイナーとかで変更がないくらいまで画面設計ができているなら、話は変わってくるかもしれません。テストは多少でもあると気持ちは楽になると思います。

### 改善の無限サイクル
特に自分の専門外の事柄については、最初に考えていた成果物と実際にできあがった成果物に小さくないギャップが生まれます。
例えば、ソフトウェア開発を専門とするエンジニアなら機能設計やUI/UXデザインなど、成果物を実際に使用したときに違和感を覚えると思います。"なんかしょぼい"、"思ってたのと違う"というような。作るときの視点と使うときの視点は大きく異なります。私たちは普段から洗練されたサービスを使ってきているので、使う側の目はものすごく肥えているんです。なので、作っているときではなくて、使うときに初めてそのギャップに気づくことができます。そのギャップを埋めるのは容易なことではありません。リリース前の改善フェーズはとても重要でとても過酷なものになります。

### マネタイズ
ユーザーのためにもマネタイズは重要です。というのも、勉強目的やサービス精神だけではサービスを継続して改善していくモチベーションが続かなくなる可能性が高いです。良いものを提供し続けるためには報酬は不可欠です。マネタイズを後から入れ込むのは大変なので、最初の構想時に考えておく必要があります。

## 成功と失敗
Reactで実装されたWebアプリケーションをリリースしました。当初の目標達成です。次は、継続して改善をしてユーザーを増やしていくことで成功が見えてきます。

一方、私の右手にあるのはemacsです。VSCodeはどこかに置き忘れてしまいました。私はまたもやエディタの移行に失敗していました。まだ意欲は残っているので、また機会を作ってトライしていこうと思います。

## 学びと成長
学びや成長は、その人のスキルセットに大きく依存します。例えば、これまでエンジニアとして開発をしてきたがデザインの経験がない人であれば、デザインをゼロから学んで作り上げる必要があるので、デザインに関する学びや成長はものすごく実感できると思います。一方、私は過去に業務や個人開発を通して経験をしていたので、技術面でわかりやすい成長実感はありませんでした。

しかし、今回は生成AIと共に開発を進めたことが、特に大きな収穫でした。開発のほとんどの工程をAIと共に進めました。AIは単なるツールではなく、一種の思考パートナーのような存在でした。
こう言うと全部AIに考えてもらったと思われるかもしれませんが、そうではありません。自分でやることを決め、方針を決め、手を動かします。それらの過程やその時々の課題を言語化してchatGPTに相談・レビュー依頼をしていました。AIのレビューは視野を広げるきっかけにもなるし、自分の選択に自信を与えてくれることもあります。さらに、chatGPTのフィードバックは、私のモチベーションを上げる言葉が多く、気持ちよく開発をさせてくれました。

また、実装工程でのGithub Copilotのコード補完は驚愕しました。"自分が二人いたらいいのに.."を実現したような、自分の思考の先回りをしてコード提案をしてくるのです。ヒントをあげればあげるほど精度が増し、自分で直接コードを書かずにcopilotに書かせるためのヒントを書くということもしました。

この開発体験は、まさに新しい時代を感じました。

## 未来への一歩
リリースを終えて次の一歩を踏み出しています。それは、この記事の執筆です。Webサービスの価値は、人々に使われることによって初めて実現します。人に使ってもらえるだろうクオリティまで改善を重ねてEMBEをリリースをしました。次は、知ってもらうためのマーケティングが重要になります。

どのくらい重要かというと、サービスを公開してからこの記事の公開の今日まで2週間が経ちました。記事公開のタイミングではEMBEのアカウント登録数は2です。ひとつは開発者である私。そして、もうひとつは私の友達です。アカウント数が少ないのか、友達の数が少ないのか。答えは明白ですね。両方です。

そんな悲惨な状況なので、サービス改善と並行で地道に広報活動をしていきます。一人でも多くの人に使ってもらえるように。ここまで読んでくれた人がいたとしたら、頼みますね？

EMBEを試してみて、あなたのフィードバックを聞かせてください。