はじめに
記事を開いていただきありがとうございます。この度、半年強ほど開発していたWebアプリ『ポリ徹 -政治家徹底解剖』をリリースしました。
この記事では、個人開発をしたきっかけ、開発の流れ、及び個人開発の反省点についてそれぞれ書き記していきます。個人開発をしてみたいものの進め方がわからない、どのような効果が得られるのかがわからない、といった方の参考になれば幸いです。
共同開発者が生成AIによるコンテンツ作成部分について記事を書いたのでこちらもぜひ読んでください。
https://zenn.dev/uedakoki/articles/3e035c4e6f78a7
機能紹介
はじめに、Webアプリに実装した機能の一覧をご紹介します。もし気になったらぜひサイトにもアクセスしてみてください。
政治家一覧
国会議員の一覧を表示できます。所属政党・所属議会・任期による絞り込み、名前(ひらがな・漢字)による部分一致検索が可能です。
政治家詳細
政治家の似顔絵や略歴、およびその他詳細情報を閲覧できます。似顔絵についてはChatGPTで、略歴についてはGeminiを使用してWeb検索を走らせた上で自動生成する形としています。画面下までスクロールすると、Geminiで作成した政治家ごとの国会での質疑の議事録要約が表示されます。議事録は、日付を指定して絞り込みが可能です。
国会議事録要約
公開されている国会の議事録を、Geminiを使用して要約したものを委員会ごとに一覧化しています。各委員会については生成AIにキーワードを設定させ、キーワードからも議事録を検索できるようにしています。
政治家レーティングバトル
政治家同士を競わせてランキングをつけられる、新感覚の政治家評価システムとして開発しました。政治家2名をランダムに表示し、ユーザが一方に投票することでEloレーティングに従いレーティングが変動していきます。
この機能で使用することを想定して、各政治家の似顔絵では常にファイティングポーズを取らせるようにしています。
開発のきっかけ
そもそもなぜ個人開発をしようと思い至ったかについて記そうと思います。
私は普段コンサルティング会社で主に上流工程(要件定義)に従事しているのですが、要件の品質に最も関わる部分はその要件がどのように実装されるかが明確にイメージできるか、であると考えています。どのような実装になるかのイメージはついていないが漫然とクライアントの要求を要件に記していってしまうと、共存できない仕様であることに気づかず要件化してしまったり、実装工程にて実装が不可能であると判明してしまったりします。要件定義書は、素人目には低品質であることがわかりにくく、そのような品質のもので進めてしまうと結果として設計・開発にて炎上することになります。
資格試験などの学習を通じて一定イメージを掴むことはできるものの、机上論からは見えてこない注意点は開発をするにあたっては数多く存在します。それらもカバーできるような、一段深い実装のイメージを掴むにはやはり自ら手を動かして開発経験を積むしかないと考え、個人開発をするに至りました。
開発の流れ
ここからは、今回の開発の流れについて備忘録的に記していきます。
開発するアプリの検討
個人開発をするにあたり、①生成AIを使用したコンテンツを有すること(今のテックトレンドであり自分でも触ってみたかった)、②RDBを使用したWebシステムであること(フロントエンド・バックエンド・データベース・ネットワークのすべてについて触ってみたかった)、の2つの条件を満たすものにしようと考えました。
上記を満たしつつ、一定の利用ニーズがあるものとして、データとしては提供されているものの、形式の可読性が極めて低く、一般ユーザには利用されていないものを生成AIで要約するというものがあると考えました。
データとしては提供されているものの可読性が極めて低いもの、と考えると、公共機関が提供しているデータ類が挙げられます。各公共機関が提供しているデータを色々眺めた結果、国会の議事録の要約を提供するのが良いという結論に至りました。
開発体制の構築
個人開発を行うに当たり、最大の課題はモチベーションの維持であると考えました。基本的に金銭的な価値をあまり生まない活動である個人開発のモチベーションを維持するためには、誰かを巻き込んで共同開発するのが良いと考えました。
そこで、まずは自分自身でどのようなシステムを作成したいかを言語化するために、Google Spreadsheet上でUSDM(システム仕様の記述方法の一つ)に従い簡単な仕様をまとめました。当時作成したものを参考までに添付しておきます(最終的なアプリケーションと比較するとかなり簡素なものになっています)。
この仕様を見せながらどのようなシステムを開発したいかを伝え、友人に承諾してもらって2人での開発がスタートしました。
技術選定
私、友人ともに個人開発の最大の目的が自己研鑽を積むことであったため、未経験であるものの、モダン、または一般的に広く使用されている技術を使用したい、という思いがありました。個人開発の最大のメリットは、自身が興味のある技術を使ってみたいから、という理由だけで選定できることにあると思っています。それを踏まえ、以下のように選定しました。
対象 | 仕様技術 |
---|---|
フロントエンド | Next.js + Tailwindcss + DaisyUI |
バックエンド | Go |
データベース | PostgreSQL |
コンテナ | Docker |
Webサーバ | Nginx |
開発
開発手法の選択
個人開発は作業時間が限られるものの、期間をかけすぎるとモチベーションも低下していってしまいます。そこで、(はじめに簡単な仕様書は作ったものの)開発自体はアジャイル的に進めることにしました。
以下アジャイルソフトウェア開発宣言より引用:
プロセスやツールよりも個人と対話を、
包括的なドキュメントよりも動くソフトウェアを、
契約交渉よりも顧客との協調を、
計画に従うことよりも変化への対応を、
価値とする
アジャイル的に進めるにあたり、開発中のドキュメントは最小限で用意することにしました。その最小限のラインが、ER図であると考えました。究極的には、どんなシステムもデータの入力(input)、処理(process)、出力(output)を提供するものであり、その根幹をなすのがDBです。DBスキーマを変更すると開発の手戻りが大きく、機能を追加する際に闇雲にテーブルを追加してしまうと歪なテーブル設計となってしまうと考え、常にER図だけは最新に更新する、というルールを定めました。
ER図は機能追加の際に都度更新していくものであったため、容易に作成できるものが望ましく、mermaidによって作成することにしました。Githubのmdファイルとして用意に確認できるのも評価できるポイントです。mermaidでのER図の書き方はこちらを参考にしました。
タスク分担・コミュニケーション
アジャイル開発におけるチケットの役割として、GithubのIssueを活用することにしました。大体週に2回ほどProjectsのタスクリストを投影しながらdiscordで通話して、どの機能の開発が完了したか及び次に開発する機能をどれにするかなどを話して、また次の会議までに開発して持ち寄る、というサイクルを繰り返していました。
タスクは、各々の興味と適正から分担を行いました。私は幅広く開発をしたかったためフロントエンド、バックエンドのシステムの開発の部分を、友人は生成AIのプロンプトエンジニアリングに取り組みたかったためデータの作成部分を主に担当する、という形にしました。
コーディング
コーディングの際には、可能な限り生成AIを使用して開発工数を削減することにしました。ただ、開発開始時点ではReactは触ったことがあるもののNext.jsは未経験、Goについては触ったこともないという状態でした。そこで、開発に先立ちそれぞれ以下のチュートリアルだけ触って最低限コードが読める状態にしました。
Learn Next.js / A Tour of Go
基本文法を押さえた後、実際の開発に着手しました。まずはChatGPTに作成したい機能を投げてコードを生成してもらい、それを読んで学習しつつ微修正する、ということを繰り返しました。これを続けて、一定理解が深まったら昔のコードを掘り起こしてリファクタリングする、とすることで、コードを読んでインプットした知識をアウトプットする、という活動も行いました。
また、IDEはVSCodeを使用していましたが、Github Copilotが無料で使用できるため、ChatGPTで生成したコードを微修正する際にはコード補完を活用するようにしていました。
生成AIドリブンのコーディングを行うためのプロンプトについてのTipsとして、①当該技術の実装のベストプラクティスに沿うよう開発させる、②一度作成したコードを生成AI自身にレビューさせてみるということを始めてから生産性が上がりコードの品質も高くなったような気がします。Claude Codeなどの登場によりどんどん変わっていく部分かとは思いますが、ぜひ一度試してみてください。
本番環境へのデプロイ
開発が概ね完了したら、本番環境にデプロイすることとなります。当初はクラウドの学習も兼ねてAWS上に構築することを考えていましたが、AWSは個人としては費用的に負担が重い事(RDSの料金が高いため使用を断念した。RDSを使用せずにEC2にRDBMSを入れてDBサーバとして使用することも考えたが、それならもはや1つのEC2にDockerコンテナを立てればよいのでは?となり、結果レンタルサーバで良いという結論に至った)を受けて、XServerのVPS上に構築しました。
開発時からDockerを使用していたのでデプロイ自体はあまり大変な作業とはなりませんでしたが、本格的にWebサービスとして稼働させるには①ドメインの取得・DNSサーバの設定、②SSL化は事実上必須となります。①については、XServerのVPSを契約するとそれについてきたためあまり大変な作業ではありませんでした。②を円滑に行うためにも、もし1台のサーバ上にDockerコンテナをオーケストレーションする構成とすることを考えているのであれば、はじめからリバースプロキシサーバも入れておくのが良いと思います。なお、SSL証明書は無料のものを使用したかったためLet's Encryptを使用しました。
個人開発の反省点
最後に、個人開発を通して感じた反省点についてまとめていきます。
テストの自動化が開発時点でできていなかった
上述したとおり、今回は生成AIによるコード生成を行い、一定の量が溜まったらリファクタリングする、というサイクルで開発をしていました。このリファクタリングを行う際に、あったほうが良いなと思ったものが自動化された単体テストです。
単体テストが自動化されていないと、リファクタリングを行った際にモンキーテスト的に動作確認をしないといけなくなる上に、確認に網羅性がなくなってしまいます。一方で、単体テストが自動化されていれば、リファクタリングや機能追加を行った際に既存の機能に影響を及ぼしていないかを瞬時にテストすることが可能です。
次回以降また個人開発を行う機会があれば、今度はテスト駆動開発にて開発をしたいと考えています。
マネタイズ方法の検討が甘かった
開発当初は学習になればよいと思い、あまりマネタイズの方法を考えずに機能の開発を行いましたが、いざVPSなどを有償で契約すると一定マネタイズを行った上で最低限サーバ代の回収くらいができるととても嬉しいものです。
ポリ徹では、漠然と広告収入が得られるのではないかという甘い考えのもと開発を進めていましたが、一度Google AdSenseの審査に落ち、その考えが甘すぎたことに気づきました。その後、レントラックスさんからアフィリエイトの打診を頂いたり、2回目でGoogle AdSenseの審査に通ったりはしましたが、十分なビューがないとサーバ台には到底及ばない、ということも肌で感じました。
もし可能であれば仕様を検討する際にどのように収益化を見込むかを考えておくと良いと思います。
サイトへの集客方法の検討ができていなかった
開発当初は、サービスが完成したらXでポストしていれば一定数のユーザを誘引することができるのではないかと考えていましたが、これも考えが甘すぎました。よっぽどインパクトのあるアプリを作ってバズったりしない限りは、Xのみでの集客は極めて難しいです。アプリの仕様を検討する際に、利用者のターゲットとどのようにリーチするかは検討しておくと良いと思います。
おわりに
Webアプリ『ポリ徹 -政治家徹底解剖』の開発体験記としては以上になります。
今後も、開発した上で詰まった部分の備忘録的に記事を執筆できればしていきたいと思うので、引き続きよろしくおねがいします。
また、公式Xも作成しているので、そちらもフォローしていただけると喜びます。