炎上しないプロジェクトの進め方

# whoami
スタートアップに特化してデザインと受託開発をしている会社のCEOです。
https://twitter.com/dowanna6

# この記事の概要
いろんなWEBサービスを開発する中で「こうすればプロジェクトの炎上を防げるのでは？」と感じる行動や考え方が見えてきたので、それをチェックリスト化して社内で運用し始めました。

その一部を紹介してみます。

コメント等で「これもやっておいた方がいいよ！」的な意見をいただけたら嬉しいです。
全ての開発現場が炎上から無縁になりますように。

# 炎上の定義
- 事前に設定した納期に間に合いそうにない
- 納期に間に合わせるために1日8時間を大幅に上回る労働時間が恒常的に発生している
    - 「大幅」の度合いや「恒常的」の期間は組織それぞれなのでここでは割愛

# 炎上チェックシート

## 開発に関する注意点

### 最初から保守性の高いコードを書いているか
**理由：保守性の低いコードが存在していると、後の開発スピードが落ちる**

- 「最初はスピード優先だから」と保守性の低いコードを量産していると、様々な悲劇が起きる
    - 後から入ったエンジニアが「この程度の保守性で構わないのか」と低いスタンダードで開発に着手するようになり、保守性が加速的に悪化する
    - 開発終盤、納期が近づいて、一番しんどい時期に保守性の低いコードに足を引っ張られる
    - 最初だけ進捗が出ているように見えて、後からどんどん進捗が悪化する
- 炎上しない開発の基本は「進捗が安定していること」
    - 最初だけ進捗がよく見えて、後から一気に悪化するのが一番炎上する
    - それなら最初は進捗が悪く見えて、後から巻き返す方がマシ
    - 理想は常に安定した進捗が出ること
    - 最初から保守性を意識して書いておくと、あとで楽ができる

- **開発初期にスピードを優先して保守性を犠牲にするほど、炎上しやすいと考える**

### 最初から単体テストを書いているか

- **理由：開発終盤でデグレによる作業効率の低下が一気に起きるため**
    - 基本的に弊社の開発では単体テストを書くことはMUST
        - バックエンドの単体テストを書かない選択肢はない
        - なのでここでは「テストを書くタイミング」について言及する
    - 最初に書かず、後からテストを書くのはデメリットが多い
        - 開発序盤に実際以上に進捗がよく見えてしまう
            - そもそも開発序盤はコードが少ないので進捗が出やすい
            - テストを書かないことでさらに進捗がよく見える
            - 結果的に
                - クライアントがリリース予定日を早める
                - タスクを追加される
                - など、テストを書く時間が削られていく
            - そして
                - テストを書けないので、デグレが頻発
                - デグレ対応に工数を割かれて実装が進まない
                - プロジェクト終盤で一気に進捗が悪化
                - デスマーチへ
    - 理想はバックエンドをTDDで開発すること
    - どんなに進捗がよくても、波がある状態はよくない（予測しづらいため）
    - 安定した進捗がベスト
    - 案件見合いだけど、場合によってはフロントエンドもテストを書く
    - storybook+jestのスナップショットテストや、cypress/testcafeを使ったe2eテストなど

    - **テストを書き始めるのが遅れるほど、炎上しやすいと考える**

### ドメインモデルなど、大事な設計は開発チーム全員で考えているか
**理由：設計を事前に固めておくと、後の開発がスムーズに進むため**

- よくあるパターン
    - 特に何も決めず各々が開発に着手して、コードレビューで指摘して品質を担保しようとする
        - でもコードレビューで一人に指摘しても、別の人が同じ過ちを繰り返す
        - コードレビューは時間効率が低いことに注意する（注意した相手にしか知見が行き渡らない）
        - コードレビューは明らかなミス、バグを防ぐのが主目的
        - 設計を揃えるのであれば、全員を集めてワークショップを開いたほうがはるかに効率が良い
    - コードレビューすら怠った最悪の場合は、思い思いのコードで溢れて、他人のコードが読みづらくなる。
    - 結果的に開発スピードがどんどん落ちていく
- これを回避するためには、大事な設計を全員でまとめて考えてしまうのが良い
- 例えば
    - ドメインモデル（モデリングを一緒にやる）
    - 設計思想（オニオンアーキテクチャで作ろう、と決めておく）
    - cssフレームワーク（tailwindは、こんな方針で拡張していこう）
    - などなど、大きな影響を与えることを先に決めておく

- 認識違いを個別に指摘していくより、事前に認識違いを予防した方が快適
- **大事な設計を全員で固めないほど、炎上しやすくなると考える**

## コミュニケーションに関する注意点

### 概算の見積もりを前提にビジネスを進めないよう、伝えているか
**理由：雑な見積もりが確定事項になるのを避けるため**

- よくあるケース
    - 「これ、どのぐらいかかる？」「正確な見積もりはちょっと時間がかかります」「じゃあ、ざっとでいいから教えて！」「ざっと・・・1週間ですかね」
    - みたいな会話だったのが、気づいたら決裁者側で1週間を前提にその先の予定を組んでいて
    - 「えっ！1週間は概算って言ったじゃないですか！」「でもプレス用意しちゃったから1週間後に間に合わせてよ」「・・・」

- 問題は、開発者と決裁者の間で見積もりに対する確度が違うこと
- 温度感をすり合わせるのが重要
    - 「1週間ですかね。でも絶対にこの見積もりは外れます。今ざっと考えただけの不正確な見積もりなので、抜け漏れがあるかもしれません。だから、絶対にこの1週間をベースにビジネスの予定を組まないでください。いいですね？」と伝える
- **概算見積もりが「確定見積もり」に変換された数だけ、炎上しやすくなると考える**

### タスクを引き受ける前に、見積もる
- **理由：気づいたらタスクがどんどん増えていくのを避けるため**
    - 「頼まれたタスクはとりあえず全部対応する」はダメ
    - タスクを受ける前に「何時間かかるのか」を見積もる
    - 「追加で30時間かかるので、リリース日は4日遅れます。良いですか？」と確認する
    - 依頼者は（基本的に）開発のプロではない
        - どの作業にどの程度時間がかかるのか、わからないことが多い
        - 向こうは5分で終わると思っているが、実は10時間かかることもある
        - こういう期待値のズレを予防するほど、プロジェクトは円滑に進む
    - ただし、バランスを大事にする事
        - 「文言を変えたい」 → 「リリース30分遅れていいですか？」みたいな事を聞いてると、ただの融通の効かない人になってしまう
    - 要は「安請け合いして、結果的に相手に迷惑をかけることを避けよう」ということ

    - **安請け合いの数だけ、炎上しやすいと考える**


### 全体の開発状況を理解している人が、クライアントにいるか
- **理由：想定以上にタスクが積まれてしまう可能性があるため**
- よくあるパターン
  - マーケ、営業、企画など、色んな部署からそれぞれ要望が飛んでくる
  - トータルで「今どれだけの作業が詰まっているのか」を把握している人がいなくなると、開発ボリュームが膨大になりがち
- クライアントに窓口担当を用意し、開発要望が発生した時は、必ずその人を通るようにする
- そうしないと「企画案件はそこまでお願いしてないから手が空いているはず」と考えているのに、実は営業案件が詰まりまくってる、みたいなことが起きうる

    - **全体の作業量を把握している人が少ないほど、炎上しやすいと考える**

### 対応する実行環境（端末とかブラウザ）を事前に決めているか
- **理由：最後の最後に「あ、IE対応も必要なんです」と言われると炎上するため**
- よくあるパターン
    - 最新のChromeで開発を進めて、問題なく動作することを確認
    - 納品の2週間前に「あれ、IEだと動かないんですか？」と言われる
    - IE対応、つまり地獄が始まる
- これを回避するためには
    - 開発が始まるタイミングで「どの機種、ブラウザに対応する必要があるか」を確認
        - かかる工数
            - 例えばIEなら、下手するとフロントエンドの開発工数が何倍もかかる可能性がある、と伝える
        - シェア
            - でもIEは全体の1%しか使っていません、とか
            - 若い人は基本的に使ってません、とか
        - 工数とシェアの見合いで、IEは排除したほうが良いと考えますが、如何でしょう？
        - と、事前に対応範囲で合意しておく
        - 合意したら、結果を必ず明文化しておく

- **対応環境を決めるのが遅れるほど、炎上しやすくなると考える**

### ROIが低すぎる仕様は相談して変更しているか
- **理由：ROIの低い機能を実装することは、開発者にとってもクライアントにとっても悲劇**
- クライアントは開発のプロではないことが多い
    - 「この機能を作ることにどれだけの工数がかかるか」を把握していない
    - ほんの少し仕様を変える事で膨大な開発時間が省けることもある
- そんな時は積極的に仕様を提案する
- 「なぜ作る必要があるのか」を考える
    - 本当にその機能は必要か？
    - よりROIの高い形で要望を実現できないか？
- 勿論、何でもかんでも疑問を呈していたら「融通が効かない人」と思われる
    - 信頼関係を構築してから提案する
        - 信頼関係が築けていない状態で提案しても、なかなか通らない
    - ROIが著しく低い仕様に限って提案する
- **言われた通りに作るだけだと炎上する事もあると考える**

### 新たな仕様が出来た時は、明文化して残す
- **理由：仕様の認識齟齬による手戻りを防ぐため**
    - プラハの開発は仕様書がないことが多く、ビデオ会議やチャット上で新たな仕様が決まることも多い
    - しかし口頭会話では、お互いの会話を補足し合っているため、異なる前提条件や期待が紛れ込むことが多い
    - 何か仕様が変わったら、必ず明文化して「この理解でよろしいですね？」と確認する
    - 明文化する場所はslackでも良いけど、slackはあくまでチャットツール。会話が流れやすいし、検索性も低いので、知見の管理には向かない
    - [clerk](https://www.clerk.jp/)や[notion](https://www.notion.so/)や[Google Docs](https://www.google.com/docs/about/)など、情報保持に適したツールを活用する
    - 出来るだけバージョンコントロールしやすいツールを選ぶ（どんな経緯でその仕様に至ったのか、あとで振り返ることが多いため）
    - **仕様を明文化しない分だけ、炎上しやすいと考える**

### 相手がすぐ動けるような指示を出しているか
**理由：誰が担当しているのか曖昧な作業が増えると、作業が見落とされるため**

よくあるパターン

- 特におとなしい人、優しい性格の人ほど、明確な指示を出すのを嫌う
- 「あーLP作らないとですねー」とかslackに書いて、誰かが拾ってくれるのを待つ
- 見落とされる
- 公開直前に「あれ、LP誰も作ってないじゃん！」

- 指示を出す時は以下を抑える
    - 誰が
    - いつまでに
    - 何をやるのか

- 指示を出す事を恐れない
    - 「自分がこんな事を指示したら差し出がましいかな」
    - みたいな遠慮は不要

- 注意点
    - プロジェクトには必ず、全体を把握している人がいる
    - その人の指示を上書きするようなことがあってはならない
    - 指示ラインが増えると、逆に混乱を産む

- 自分が指示を出しても構わない事柄か？
    - 例えば開発に関して全く知見のないクライアントなら、自分が別のエンジニアにテーブルスキーマの設計を指示しても、クライアントから開発に関する具体的な指示ラインは存在しないため、問題ない可能性が高い
    - ただ、当該エンジニアがクライアントから別のタスクをステルスで依頼されている可能性もある
    - クライアントにもメンションをつけておく事で、自分からタスクが追加されたことを認識してもらう
- 誰かが別の指示を出している可能性はないか？

- 不安があったら、必ず全体を把握している人に念の為確認しよう

**指示が不明確であるほど、炎上しやすくなると考える**

### 人間関係を軽視しない
**理由：信頼関係のある人間関係を作れるほど、コミュニケーションコストが省け、快適に働ける**

- 信頼関係のある相手なら
    - 提案できる（この仕様こうしません？
    - 調整できる（これこれこうで、納期延ばしません？
    - 仮に失敗があっても、前を向ける（再発しないためにこうしませんか？

- 逆に信頼関係がないと、理詰めで説明するためにロジックを用意したり、とにかくコミュニケーションコストがかかる
- [コミュニケーションコストはバカにならない](https://ja.wikipedia.org/wiki/%E3%83%96%E3%83%AB%E3%83%83%E3%82%AF%E3%82%B9%E3%81%AE%E6%B3%95%E5%89%87)
- 信頼関係を築けない相手と長く働くと、確実にモチベーションが低下する
- それは非常に勿体無いこと

- どうやって信頼関係を作るのか
    - 積極的に自己開示する
    - [接触頻度を増やす](https://ja.wikipedia.org/wiki/%E5%8D%98%E7%B4%94%E6%8E%A5%E8%A7%A6%E5%8A%B9%E6%9E%9C)
        - 積極的に話に加わる
        - 雑談やランチミーティングに参加する
        - 学んだこと、技術的な知見をアウトプットする
    - 相手の事業を知ろうとする
        - どんな競合がいるのか？（競合情報はいつだって嬉しい）
        - 市場全体でどんな動きが生まれているのか？
        - 相手の事業、市場に関する書籍を何冊か読んでみる
    - 相手の事を知ろうとする
        - どんな立場の人なのか？
        - どんな事を喜び、どんな事に怒るのか？
        - 将来どんな事をしたいと考えているのか？
        - どんなことに不安や課題を感じているのか？
    - 自分の仕事をミスなく全うする
    - 適切な報連相
        - 基本的に、相手に進捗を聞かれる = 報告が遅いと考える

- 勿論、人間関係さえよければ炎上しない、ミスがあっても許されるとは限らない
- 良好な人間関係を築くのが不得意な人もいる
- でも人間関係が良好になるほど、自分自身にとっても働きやすい環境になることは理解する

**人間関係を軽視するほど、炎上しやすくなると考える**


## 見積もりに関する注意点

### 開発タスクは1つあたり2時間未満か
- タスクを細かく見積もる
    - **理由：見積もりの荒いタスクに着手している間、その進捗が見えなくなるため**
    - GitHubのissueを作成するときは「2時間以内に終わるタスク」の粒度で作成する
    - 1日とか1週間かかる粒度でissueを作成してはいけない（そのissueを消化している間の進捗がブラックボックス化するため）
    - 仮に「パフォーマンスチューニング」みたいなタスクを作って2週間割り当てたら、その2週間は全く進捗が追えなくなる
    - 納期1日前になって「すみません、パフォーマンスチューニング終わりそうにありません」と言われる可能性がある
    - 2時間ごとにタスクを分割していれば、1日で1件もタスクがcloseしていなければ、異変に気づける
    - **タスクの粒度が荒いほど、炎上しやすいと考える**

### バッファを設ける
- **理由：何もトラブルが起きない事を想定したスケジューリングは悲劇の元**
    - 「90日で作れる」と見積もったサービスは、絶対に90日で仕上がらない
        - クライアントが多忙で、開発成果の確認や、仕様確認が遅れる
        - メンバーが入れ替わり、作業効率が一時的に落ちる
        - 要件がガラリと変わる
        - など、様々な理由で想定外の開発工数は絶対に発生する
    - バッファを置かないのは「絶対にトラブルがおきない」事を前提としている
        - それは危険すぎる賭け
    - 特にプロジェクト経験が少ない人は、想定外の事態に備えてバッファを多めに設けておく
    - [バッファをどれだけ設けるか](https://www.biz.ne.jp/matome/2003229/)は様々な変数を考慮する必要がある
        - 取引相手の開発リテラシー（低いほどバッファを積む）
        - 取引相手との信頼関係、仕事経験（少ないほどバッファを積む）
        - 非機能要件の多さ、難易度（多い、達成が難しいほどバッファを積む）
        - などなど
    - **バッファを減らした分だけ、炎上しやすいと考える**

### 納品の1週間前は、手が空いているか
- **理由：納品の1週間前も作業がみっちり詰まっている予定は、過密すぎる**
- バッファを設けることとほぼ同義。どんな期間のプロジェクトであれ、基本的に納品日の少なくとも1週間前には完全に「手が空いている」状態になっているのが好ましい
- 「相手に申し訳ないから納品日のギリギリまで機能追加しよう」とは考えないこと
    - 直前で焦って追加した機能が原因でデグレが発生することもあり得る
    - 納品日ギリギリまで開発することは、相手に障害発生のリスクを負わせていると考える
- 納品1週間前は「単体テストを追加する」とか「障害発生時の対応マニュアルを用意する」とか「後続の開発者のためにReadmeをメンテナンスする」とか、機能に関わりのない作業に充てる
- **納品の1週間前まで機能開発が予定されていたら、炎上すると考える**


### MVPを定義して、クライアントと共有できているか
- **理由：優先度の高い機能から着手できるため**
- 「最低限ここまでできていたらリリースできますよね」と、MVPを定義する
- そのMVPをクライアントと共有する
- 仮にリリースまでに全機能が間に合わなくても「何もリリースできない」状況、つまり完全な失敗は避けられる
- MVPを定義するのは、要は「優先度の高い機能から開発すること」と同じ
    - 優先度の低い機能に時間をかけすぎて、優先度の高いリリース必達機能が後回しになっていると炎上の元
- **MVPを定義していないと、炎上しやすいと考える**


### 1日8時間働くから、8時間のタスクを消化できるとは考えない
**理由：既存バグ修正、仕様の確認といったコミュニケーションなど、機能開発以外のタスクが必ず発生するため**

- 経験上、1日8時間働くなら、4~5時間の開発タスクを消化できると考えるのが正確
    - 6時間はだいぶ攻めてる
    - 8時間は無理。確実に炎上する

- プロジェクトの立ち上げ初期は負債が少ないため、進捗が出やすい
- その時期は1日6時間ぐらい消化できるかもしれない
- でもそのペースが続くことはないと心得る
- プロジェクトが進むほど、確実にペースは落ちる
- なので全体を通して4~5時間で想定しておくのがベスト

**1日8時間働くから8時間のタスクを消化できる、と考えると炎上する**

### マニュアル作成など、開発以外のタスクを見積もっているか
- **理由：開発以外のタスクなど、思わぬタスクの出現で炎上するため**
- よくあるパターン
    - 無事に納期通りに機能開発が終わったところで
    - 「あれ、マニュアルないんですか？」
    - など、開発以外の新たなタスクが出現して炎上する
- 開発以外に発生しがちなタスクを考慮する
    - マニュアル作成
        - contentfulを使ったCMS案件や、先方の運用が多発するサービスの場合、マニュアル作成を求められることもある
    - README（開発者向けマニュアル）
        - 他の開発者が開発を引き継げるよう、readmeはできる限り丁寧に書いておく
            - ローカル環境での起動方法
            - テスト方法
            - デプロイ方法
            - マイグレーション方法
            - などは最低限書いておく
    - 開発以外に発生しそうなタスクが自分で洗い出せない場合は、周囲に相談してみること
- **開発以外のタスクの見落としが増えるほど、炎上しやすくなると考える**


# 炎上対策に終わりはない
いくつかチェック項目を書き連ねてみましたが、これさえやっておけば100%安全とは言えません。
炎上理由はプロジェクトの数だけあり、ユニークです。

それでもある程度一般化して、こうしたチェックシートを設ける事が何かの参考になれば幸いです。


# 続きはnotionへ
こうしてqiitaに書き始めたものの、ただの文章だとまとまりが認識しづらいのと、チェックシートの体になっていないので、今後は流行りのnotionに追記していきます。

https://www.notion.so/128a7aaa68434230bc5dfce322bd1811