AI驚き屋が嫌いだったので一次情報だけを取れるエンジニア情報収集アプリを作ろうとした
経緯
早稲田大学のWINCというプログラミングサークルで行われた夏合宿ハッカソンの題材です。
開発期間はおよそ3週間ほどで、前記事の前提のセクションを参照していただけると開発体制が大体分かると思います。ざっくり説明すると自分がPM兼テックリード兼コーダーみたいな感じなのに週45時間アルバイトしてたというとにかくリソースがない状況でした。
このアプリを作ろうとした経緯として設計者がドメイン知識がある領域でないと設計段階で時間がかかりすぎると思ったので、インターンをしていて多少業界の勝手や状況が分かるソフトウェアエンジニアをペルソナとしたアプリを作ろうと思いました。
ここで最初にGithubとの連携をするアプリにすることにしました。Githubはエンジニアの情報を多分に持っており、ほとんどの開発者が触れたことがあるからです。最初はGithubの情報をOAuthで取得し、それをもとにしたSNSアプリを作ろうと考えました。しかしそれではあまりにもふわっとしており、実現可能性が全く議論できないということに1~2週間たって設計をしていて思い至りました。
開発リソースが多くなく、まともな設計をする時間はなかったのでRead Onlyとまではいかずとも、ユーザー操作を最小限に抑える方向を模索し始めます。ここで自分が当時感じていたペインとして、TwitterなどでAI驚き屋なる、AIの新技術が出るたびに過剰反応しインプ稼ぎをしてポジショントークをまき散らす人間がノイジーだったことがあります。今思えばそういう人間を見たくなければフォローリストを作って情報を断捨離すればいいだけだったのですが、無性にイライラしてしまいコードの一次情報のみをFeedできるような情報収集ツールがあればなと思うようになりました。
そういった経緯でこのアプリのコンセプトが決まりました。
技術選定
フロントエンド
- フレームワーク: Next.js
- 状態管理: Zustand
- UIコンポーネントライブラリ(正式には違います): shadcn/ui
- デプロイ: Vercel
バックエンド
- フレームワーク: Ruby on Rails
- RDBMS: PostgreSQL
- デプロイ: Render
- 本番DB: Neon
スキーマ
- OpenAPI
反省点, 課題
ハッカソンの発表後レビューとして以下のような点について指摘をもらいました。
- ただのfeedをみようとは思わない, 何かしら情報の加工がユーザー操作でできるようになってほしい
- 認証ロジックが完成していない
- UIが雑である
- feedで取ってきた情報はbodyそのまま表示するとみにくい
- スクロールしたら新しいものがフェッチできるべき
- 大量のデータをどうさばくんですか
- UXがよくない
正直当初は時間がない上に自分もまだまだ未熟で正しい技術選定なのか検討する時間もないまま、開発は進めつつ、メンバーの技術のキャッチアップも行わなければいけないという状況だったので当初の自分にしてみればよくやったと思っています。そのうえで今の自分ならどうすればよりよく出来たかを技術選定, 開発体制のセクションに分けて整理したいと思います。
技術選定
今回PMをやって強く思ったことが技術選定を行うことの重大さです。技術選定を間違えた場合、それによって起こる損害は計り知れません。以下に変更するべきだった技術選定を列挙します。
-
Next.js App RouterをReact Router v7+Viteにする:
Next.js App Routerの選定については当初特に迷いませんでした。Next.jsがデファクトスタンダードであること、過不足の内、不足が起こることが考えられなかったこと、自分が慣れていたことが主な理由でした。しかし、よくよくアプリの構成を考えると基本的に認証後のCSRしか発生せずSSR, SSG, ISRは使うことがほぼありませんでした。であれば、より軽量なReact Router + Viteで事足ります。Next.jsのレンダリング手法について理解する時間を省き、ピュアなReactのみ理解してもらえば工数をかなり削減できたと思います。
-
Zustand → OpenAPI+TanStack Query:
OpenAPIと組み合わせてTanStack Queryのコードを自動生成し、非同期処理を出来るだけカプセル化してしまうべきでした。Reactの勉強から始めるような層にとって非同期処理は意味不明だったはずです。単純に自分の知識が浅く、このようにする発想が開発初期ありませんでした。途中からこの構成にしようと思い立ち、OpenAPI+OrvalのコードとZustandを使っているコードが悪魔合体し、メンバーを混乱させてしまいました。
開発体制
この点についてはPMをやった話という前記事でも若干触れましたが、マネジメント的なことではなく特に技術的なことについての反省です。自分は学生同士で開発を行うことが当時の段階で3~4回あり、そのどれも当初思い描いていたものと最終的な完成品にかなり大きな乖離がありました、または完成できずプロジェクトが終了しました。なぜこんなことになるかと考えた結果、要件定義、設計のフェーズを端折って実装を始めてしまうからだと考えました。夏季休暇では実際の開発現場(自社開発、受託両方体験できました)で、どのようにそうしたミスマッチ、プロジェクトの炎上を未然に防止するのかという点を念頭に置いて作業していました。ここでたどり着いた結論として、設計段階で自然言語でドキュメントを残しながらコアなビジネスロジックをまとめる、IDL(今回であればOpenAPI.yml, ConnectRPCならprotobuf)で実装前にシステムのI/Oを定義する この二つが出来れば、実装でこける可能性が十分下がると考えました。まず一つ目の自然言語でビジネスロジックをまとめることについては、GitHubのリポジトリ上にmdファイルでWhyを意識しながら書き出しつつ、チーム内で相互フィードバックをしていくと、チーム全体の認識がそろうとともにAIでPoCを行う準備が整うので手間はややかかりますが、実装で大コケする可能性はかなり抑えられると思います。次にシステムのI/Oを定義することに関してこれはAIに食わせる文脈として非常に有用なうえに、IDLの学習コストがかなり低いと思ったためやるべきと感じました。
この体制を組み込んで実装からやらせるのではなく、設計段階からメンバー全員とコンテキストを共有出来れば、自分が逐一指示を出しに行かなくても全員に自律的に動いてもらうことが可能だったと思います。