エンジニア2年目の終わり頃、あるプロダクトの開発を担当しました。
それまでも、フロントエンドの実装、小さめの機能追加、社内ツールの開発は経験していました。でも今回は違いました。最終的に、外部のユーザーがログインして使える状態まで持っていく必要があった。つまり私が初めてちゃんと向き合ったのは、コードを書くことそのものではなく、プロダクトをリリースすることでした。
技術的にすごい話ではありません。むしろ未経験が多すぎて、かなり泥臭く進めた話です。でも、若手が初めて少し大きめの責任範囲を持ったとき、どこで躓きやすいか——という意味では、共有できることがあるかもしれません。
この記事は、いくつかの具体的な失敗を通して、私が「自分のタスクを見る」状態から「リリースを見る」状態に変わっていった話です。個別の失敗(OAuth審査、PoC、AIの使い方)はそれぞれ別記事に書いたので、ここではそれらが一本の線でつながった話を書きます。
それまでの私は「自分のタスク」を見ていた
以前の私が見ていたのは、基本的に「自分に割り当てられたタスク」でした。画面のこの部分を直す、APIのレスポンスに合わせて表示を変える、バグを直す、仕様通りにコンポーネントを作る、レビューに出す。
どれも大事な仕事です。ただ、そのとき私の意識は自然とこうなっていました——自分の担当を実装し、レビューしてもらい、修正し、マージされる。見ていたゴールは「自分のタスクが完了すること」でした。
でも今回は、それでは足りませんでした。誰かが最後に全部をいい感じにまとめてくれるわけではなかったからです。機能の方向性はマネージャーが決めてくれましたが、開発面ではフロントエンド、バックエンド、ローカル環境、認証、外部API、AWS、ビルド、デプロイ、DB、ログ、レビュー、外部審査——これらを一つずつ進めて「ユーザーが使える状態」まで持っていく必要がありました。
そのとき初めて、見る対象が変わりました。自分のタスクが終わったかではなく、このプロダクトは本当にリリースできるのか。そこを見ないといけなかったのです。
リリースを決めるものは、コードの中だけにはなかった
初期の私は単純に考えていました。機能を実装し、画面を作り、APIを作り、データを取得し、動作確認し、最後にデプロイする。多くの開発はこの流れで進むので、間違いではありません。
でも、未経験の領域が多い今回のプロジェクトでは、これだけだと危険でした。リリースできるかを決めるものは、機能実装だけではなかったからです。Google OAuthの審査、外部APIのスコープ確認、ホームページやプライバシーポリシー、他部門との調整、本番に近いデプロイ経路、認証基盤との接続、セキュリティレビュー、運用上の確認。どれも画面上の機能とは別のところにあり、それらが通らなければリリースできません。
これを、私はかなり後になって実感しました。
WBSを作ることと、リスクを見ることは違った
初期に私はWBS(Work Breakdown Structure、作業を分解して並べた計画表)を作りました。技術検証、要件理解、設計、開発、テスト、リリース。期間を置き、タスクを分解し、工程を並べる。ちゃんと計画したつもりでした。
でも、そのWBSには弱点がありました。作業工程としては整理されていたけれど、リスクの順番にはなっていなかったのです。
「設計のあとに開発、開発のあとにテスト、最後にリリース」という工程順は自然です。でも、リリースを左右するリスクは、必ずしもこの順番では現れません。むしろ本当に危ないものほど、最後まで触らないと見えないことがあります。工程順に並べるだけだと、「最後に見つかると詰むもの」が後ろに残ってしまう。
Google OAuthの審査がその典型でした。概要を読んで理解したつもりでいましたが、本当に見るべきだったのは実際の申請フォームで、しかも審査に必要なホームページは別部門の担当——つまり開発タスクではなく部門間の依存関係でした。気づくのが遅れ、リリース直前に急いで前倒し対応をお願いする形になりました。
この審査まわりの失敗そのものは、別記事に詳しく書きました。
👉 Google OAuth審査は、最後に申請するものではなかった
この経験で強く思ったのは、WBSはタスクをきれいに並べる表ではなく、リスクを早く見つけるための道具であるべきだったということです。
「自分が頑張ればなんとかなるもの」と「自分だけでは前倒しできないもの」
プロジェクトのタスクは、2種類に分けられました。
一つは、自分が頑張れば進むもの。コードを書く、調べる、直す、試す、ログを見る、AIに聞く、先輩に相談する。時間はかかっても、手を動かせば少しずつ進みます。
もう一つは、自分だけでは前倒しできないもの。外部サービスの審査、他部門が担当するページや素材、レビュー待ち、返信待ち、社内確認。これらは夜中まで作業しても早くは進みません。
自分が頑張れば巻き返せるものは、後からでも取り返せる可能性がある。でも、自分の作業量だけでは前倒しできないものは、後ろに置くほど危険になる。
今なら、タスクを見たときにまず「これは自分の手を動かせば進むものか」「他者の待ち時間が発生するものか」を分けます。後者は、実装量が小さく見えても、リリースリスクとしては大きい。たとえばGoogle審査は、こちらの作業は申請フォームを埋めるだけでも、返信待ちと他部門依頼で2週間以上動いた——「やることは小さいのに、リリースを左右する」典型でした。この優先順位を、私は後半でようやく実感しました。
機能が完成することと、リリースできることは違う
もう一つ大きかったのが、機能への見方です。
私はフロントエンド出身で、画面の複雑さやUIの量に意識が向きやすいタイプでした。既存プロダクトにはリッチな画面、複雑なメニュー、多くの表示パターンがある。だから自然に「この画面をどこまで再現できるか」を大きなリスクとして見ていました。
でも、最初に見るべきだったのはそこではなく、一番小さい形で、ユーザーが価値を受け取る経路が通るかでした。外部APIからデータを取る→バックエンドで処理→フロントエンドからリクエスト→画面に数字が出る。この一本が通るかを最初に確認すべきだった。
ところが私は、最初の雛形に、表示パターンが多く分岐も多い複雑なメニューを選びました。自分にとって複雑に見えるところが一番危ないと思ったからです。ここで学んだのは、PoCは「小さな完成版」ではない、ということです。PoCはある経路を検証するためのもので、一番難しいのは実装ではなく何を先にやらないかを決めることでした。
このPoCの捉え方は、別記事に詳しく書きました。
👉 PoCって、小さな完成版を作ることじゃないと思った話
デプロイも、最初から理想形でなくてよかった
デプロイも同じでした。もっと早く経路を検証すべきだった一方で、罠もありました。当時の私が「早く検証しよう」と考えていたら、たぶん「どうせならCI/CDまで整えたい」とCodePipelineから作り始め、別の沼にハマっていたはずです。
実際に使ったのはかなり手動の手順でした。ローカルでビルドし、ECRにpushし、image tagを書き換え、ECSを更新する。きれいではないし最終形でもない。でも「リリース経路が通る」ことは確認できた。大事なのは手動が良いという話ではなく、まず手動でも通す → 次に再現性 → その後に自動化、という順番です。動いていないものは、いきなり綺麗に自動化できません。ベストプラクティスも、タイミングを間違えると沼になります。
AIは、理解不足を埋めてはくれなかった
このプロジェクトでは、AIの使い方も大きく反省しました。
既存プロダクトのコードがあったので、「AIに頼めば、古い実装を新しい構成に移してくれるのでは」と楽観的に考えていました。でも、そこには認証の接続、API設計、型の置き場所、ランタイムの違いなど、多くの設計判断が含まれていて、当時の私はそれをレビューできるほどの前提理解を持っていなかった。Agentが一度に十数ファイルを生成すると、どこから見ればいいか分からず圧倒されました。
ここで効いてくるのが、リリースとの関係です。AIが多くのコードを書いてくれるほど、前に進んでいるように見えます。でも、自分がレビューできない差分は、リリース直前に「なぜこう動いているのか説明できない」リスクとして残ります。 その後、AIに渡す仕事を、自分で確認できるサイズまで小さくしました。AIをやめたのではなく、使い方を変えた。
このAIの使い方の話は、別記事に詳しく書きました。
👉 AI Agentに任せる前に、自分がレビューできるサイズまで小さくする
AIがたくさんコードを書いてくれることより、そのコードを自分が責任を持って判断できることの方が、リリースには重要でした。
3つの失敗に共通していたこと
ここまでの3つの失敗——審査、PoC、AI——は、別々の話に見えて、実は同じ一つの傾向から来ていました。
私は「プロジェクトにとって危ないもの」ではなく、「自分にとって見えやすい難しさ」を先に潰そうとしていた。
UIは得意だから複雑さが見える。だから大きなリスクに見えた。でも本当にリリースを止めかねなかったのは、自分が経験の浅い側——外部審査、デプロイ経路、未知の設計判断——でした。複雑なメニューをPoCに選んだのも、Agentに大きく任せたのも、根は同じです。慣れた難点ほど過大評価し、知らないリスクほど過小評価する。 これが、3つの失敗に共通する根っこでした。
自分にとって「リリースを見る」とは何だったか
タイトルに「リリースを見る」と書きましたが、これは全体をぼんやり眺めることではありませんでした。今回の自分にとっては、各タスクを次の観点で見ることでした。
- そのタスクが、ユーザーが使える状態にどうつながるか
- 最後に残ると危険なものは何か
- 自分だけで進められるものと、外部依存があるものは何か
- 動けばいいものと、審査・レビュー・運用まで必要なものは何か
- 今やるべき不確実性と、後で磨けばいい完成度は何か
これらを、実装タスクと同じくらい具体的に見ること。「リリースを見る」を意識だけの言葉で終わらせず、上の5つの問いに落とせたとき、初めて自分のタスクが「リリースのどこに効くのか」が見えました。
工数見積もりと、「見積もれない」を共有すること
このプロジェクトでは、工数見積もりも大きく外しました。当初は自分一人で完了する想定でしたが、最終的に先輩に約2週間入ってもらい、残業もかなり増えました。
正直、未経験のタスクをどう見積もればよかったのか、今でも答えは分かりません。やったことがないことには、実装時間だけでなく、学習・調査・失敗・試行錯誤・人に聞く時間、そして「理解したつもりが実際には動かない」時間がある。これらの見積もりは、今も課題です。
ただ、一つ分かったことがあります。
見積もれないなら、見積もれない状態を共有するべきだった。
一人で作業していると、自分の状態がブラックボックスになります。周りからは、進んでいるのか詰まっているのか分からない。たとえば私は「今週中に終わると思います」と言いがちでしたが、本当はこう言うべきでした。
実装自体は進んでいます。ただ、OAuth審査とデプロイ経路はまだ見えていません。ここは見積もりを出すより先に、確認の時間を取らせてください。
「終わりそう」か「終わらなさそう」かではなく、どこが見えていて、どこが見えていないかを共有する。早く助けを求めるのは能力不足ではありません。むしろ一人で抱え込んでリスクを見えなくする方が、プロジェクトには危険でした。
もし2月に戻れるなら
もし2月に戻れるなら、最初にやるのは「全機能をどう作るか」を考えることではありません。次の3つの経路を、先に通すことを考えます。
- Google審査の経路 — 実際の申請フォームに入り、必要な項目・ホームページの要否・スコープの種類・審査落ち時の制限を確認し、他部門への依頼を早く共有する。
- ビジネス上の最小経路 — 複雑な画面ではなく、シンプルなメニューで「外部API→バックエンド→フロントエンド→表示」を一本通す。
- デプロイの最小経路 — ローカルでビルドし、手動でいいから開発環境に一度通す。
ここで大事なのは、この3つは機能一覧ではないということです。リリースが成立するための最低限の経路です。この3つが通ると、プロジェクトの輪郭が変わります。何が難しいか、何が時間を食うか、どこに外部依存があるか、何を後回しにしてはいけないか——それらが、かなり早い段階で見えてくるはずです。
「タスクを見る」から「リリースを見る」へ
今回一番変わったのは、見る対象でした。
以前は自分のタスクを見ていました。今もタスクは見ます。でも、それだけでは足りない。そのタスクはリリースにどうつながるのか、やらないと何が止まるのか、最後に見つかると危険か、自分だけで進められるか外部に依存しているか——こういう問いを、もっと早く持つべきでした。
オーナーという言葉を使うなら、オーナーは最初から全部を知っている人ではないと思います。むしろ、
どの問題に答えなければならないかを、早く見つけようとする人
なのだと思います。
自分がそのレベルに到達できたとは思っていません。むしろできていなかったから、たくさん躓きました。でもプロジェクトの中で少しずつ、「自分のタスク」ではなく「リリース」を見る感覚が生まれた。それは2年目の自分にとって、とても大きな経験でした。
おわりに
このプロジェクトは、リリースして終わりではありません。デプロイの自動化、レビュー対応、運用、監視、コード構成の見直し。手動で通したものを、再現できる手順にして、自動化していく必要があります。
でも、一度通したことで景色は変わりました。最初は巨大なブラックボックスに見えたものも、一度通せば手順に変わる。手順になれば改善できる。改善できれば、次のプロジェクトで使える自分の判断基準になります。
今回学んだことを一つにまとめると、こうです。
必要な能力は、準備が完了してから手に入るものではありませんでした。
まずその責任範囲に立ってみて、分からないことを小さく分け、周りに共有し、次に使える形で残す。
その過程で、必要な力が少しずつ見えてくるのだと思います。
挑戦をただの無茶で終わらせないために必要だったのは、根性ではなく、この4つの手順だったのだと思います。
この記事で触れた個別の失敗(シリーズ)
このプロジェクトの個別の反省は、それぞれ別記事に書いています。
