見積とスケジュールを作るときに気を付けたいこと

プロジェクトが始まるときに、見積をして、その見積もりをベースにスケジュールを立てても、無理が生じて炎上してしまう、という経験を持つ方も多いと思います。
私も、納期近くなって炎上することが何度もありました。
そして、プロジェクトが終わった後の反省会で、「見積の精度が甘かったよね」なんていう言葉が出たりします。

見積の精度を向上しようとする姿勢は必要です。
「こういう機能を作るんだったら、最低○○日は必要じゃない？」のように、過去の経験則から考えることもあるでしょう。

でも、それとは別に、経験の有無にかかわらずに改善できることもあるんじゃないかな、とも思っています。

今まで私が関わってきたプロジェクトで、私が見積もってスケジュールを立てて、炎上した経験から、考えてみたいと思います。

## 前提

- 契約形態は請負契約を前提としています。
- ここでは、プロジェクト途中での仕様変更などは考えないこととします。
- 最低2人以上のプロジェクトを想定します。
- PL（プロジェクトリーダー）は他のメンバー（一般メンバー）のソースコードの実装や変更に対してコードレビューをしてから開発ブランチにマージすることとします。

## 見積
### 成果物（設計書）

成果物として、何が必要か、お客様やプロジェクトによっても異なってくることがあります。

たとえば、

- とにかく短期でリリースしてほしいので設計書類は最低限で作ってほしい
    - モックアップを作成しながら画面項目や挙動を決めていくので、画面設計書はいらない
    - 内部の演算や、その演算の結果に応じたメッセージ仕様書などは作ってほしい

というケースや、その逆に、

- リリース後にお客様の社内の方も保守することがあるので設計書はしっかり作ってほしい

というケースもあるでしょう。

たとえば、画面設計書が不要なケースであっても、実装する人が頭の中で設計を考えながら実装していくと思いますが、その設計をドキュメントにする必要があるかどうかで、1つの画面を実装するのにかかる時間も変わってきますよね。

納期直前になって、あるいは、納品した後になって、「○○設計書が納品物に入ってないんだけど、なんで？」などと指摘が来るのは避けたい。
そのためにも、見積の段階で、設計書類として、何を作成するのか、明確にしておきたいですね。

見積書を作るときは、

- 要件定義書
- 概要設計書
- 詳細設計書
- 試験仕様書

などと、ざっくりしたものではなく、具体的に決めておくことも必要だと思います。
パッと思いつくものを挙げてみると、

- 要件定義書
    - 用語集
        - 業務領域用語集
        - 技術用語集
    - 業務フロー
    - ユースケース
    - データエンティティ
    - 状態遷移図
    - 機能一覧
        - 画面機能一覧（機能名、URL、HTTPメソッド、表示・処理内容など）
        - 帳票機能一覧（機能名、形式、記載内容など）
        - バックエンド機能一覧（機能名、起動方法・スケジュール、処理内容など）
    - 非機能要件
        - 構築先（お客様先オンプレ、AWS、Azure、GCP、さくらクラウドなど）
        - ステージング環境要否、構築先（開発元でクラウドを契約・用意する場合は、クラウドの利用料金も別途見積もることになります。）
        - 検証環境要否、構築先（同上）
        - 想定ユーザー（お客様社内、お客様サービス利用者、不特定多数など）
        - 利用規模（ユーザー数、データ数、同時接続数、時間あたりリクエスト数など）
        - セキュリティ要件（アクセス制御、認証・認可、暗号化、鍵管理、ウィルス対策、侵入検知など）
        - ログ要件（ログ種別、保存先、保存期間、ローテート、保存内容など）
- 概要設計書
    - デザイン（画面数を元に全体で見積もるケースと、機能・画面ごとに詳細に見積もるケースがあります。）
    - モックアップ（同上）
    - 画面設計（画面項目、DBのCRUD、イベント定義など。イベントの詳細は詳細設計の範囲になることも。）
    - 帳票設計（帳票項目、DB参照項目、演算等定義など）
    - バックエンド設計（入力、処理、出力など）
    - 外部I/F設計（連携先、入力フォーマット、処理、出力フォーマットなど）
- 詳細設計書
    - データベースER図（O/Rマッパーのフレームワークを使うことが多いのでリバースエンジニアリングで自動生成することも多い）
    - テーブル設計書（同上）
    - ファイル設計（ディレクトリ構成、命名規則、形式、フォーマットなど）
    - シーケンス図
    - クラス図
    - コーディング規約
    - インフラ設計（ネットワーク設計、AWSなどのクラウドの構成など）
    - 機能ごと
        - 画面項目詳細、イベント詳細
        - ビジネスロジック定義（フローチャート、SPDなど）
- 試験仕様書
    - 単体試験仕様書・兼・結果報告書（UnitTestのテストコードで書く場合も）
    - 結合試験仕様書・兼・結果報告書
    - 運用試験仕様書・兼・結果報告書
    - お客様受入試験仕様書・兼・結果報告書（結合試験仕様書、運用試験仕様書とは別に求められることも）

見積の段階で、成果物として、どの設計でどのドキュメントを成果物として納品するかを取り決めることも有効だと考えています。

さらに、それぞれのドキュメントのサンプルを提示できると、成果物をイメージしてもらいやすくなると思います。
「実際問題、そんなサンプル誰が作るんだよ？」という声も聞こえてきそうですが（私もそんな気持ちもありますが）、できるところから少しずつでもやっていけば、改善につながるのではないでしょうか。

### 成果物（マニュアル）

私自身、誰向けのドキュメントを誰が作るか（あるいは更新するか）を明確にせずにプロジェクトを進めてしまい、納品後になって「マニュアルが古いんだけど？」とツッコミを頂いてしまい、モメたことがあります。

また、以前の見積でも、

- 要件定義
- 設計
- 実装
- 試験
- リリース
- ドキュメンテーション

とざっくり見積もっても、その「ドキュメンテーション」を「設計書類の作成」（あるいは「最新化」）としているだけで、マニュアルの作成（あるいは更新）が入っていないことが多々ありました。

このままだと、

- お客様・・・ドキュメンテーションの中にマニュアルが含まれると認識していた
- 開発側・・・ドキュメンテーションは「設計書」としか書いてないからマニュアルは含まれない。またヒアリングの時に「マニュアルを作ってほしい」とは言われていない

と認識の齟齬が生じてしまい、最終的にどちらかに不利益が生じてしまいます。（私も自社に不利益を生じさせてしまったことがあります。）
それを避けるために、

- 誰向けのマニュアルなのか？（ユーザー向け、管理者向け、お客様向け）
- どのような形式？（オンラインマニュアル、Word、PDF、PowerPoint）
- 必要な内容
    - 使い始め方（初期設定、ユーザ登録、パスワード初期化など）
    - 各機能を使った業務の流れ
    - 各機能の詳細
    - エラーコード、トラブルシューティング
- 提出納期（お客様受入試験開始前、リリース前、最終納品時）

のようなことを、見積時に提示し、認識の齟齬が発生するのを防ぐことが大切になります。

### 機能ごとに見積もること

各機能ごとに工数を見積もるとき、

- 詳細設計
- 実装
- 単体試験

くらいしか見ていなかったのですが、チーム開発、オフショア開発などで進めていくことを考えて、機能単位で

- 詳細設計（画面項目詳細、イベント詳細、ビジネスロジック定義など）
- 画面ごとデザイン
- モックアップ作成
- 機能実装
- UnitTestコード作成、実施、デバッグ
- コードレビュー

などのように、機能ごとに挙げていくことで、見積項目の漏れを防ぐのに役立つかと思います。
それぞれの項目は、項目の多さ、バリデーションの複雑さ、更新処理の複雑さ・難易度などをもとに個別に見積もっていきます。

### 管理工数

私の職場では、管理工数を見積の中に入れるのですが、「管理工数って何を入れるの？開発全体の10%くらい入れとけばいいの？」という疑問があり、PM・PLが進捗確認したり担当の割り振りを変えるくらいしか考えていませんでした。

しかし、これまでのプロジェクトを思い出してみると、プロジェクトを進める上で、成果物を作る以外に、立ち上げ（キックオフ）、定例打合せや問い合わせ対応、リリース・納品などにも工数がかかってきました。

そこで、このような工数を「管理工数」として見積もっていくよう考えています。

- 立ち上げ
    - 初回訪問（顔合わせ・ヒアリングなど）　※こちらが必要な場合は、工数とは別に旅費も見積に入れましょう
    - キックオフミーティング
    - 開発ルール決定（コード規約、マージリクエスト等運用上ルールなど）
    - 開発ルール周知（ミーティング）
- 案件進行中
    - 内部定例（開発者全員による週次定例など）
    - 進捗まとめ・稼働調整（PM・PLが進捗を確認し、必要に応じて担当の割り振りを変えるなど）
    - お客様との定例（週次など定期的なもの）
    - お客様問合せ・連絡対応（定例以外の突発的なもの）
    - コードレビュー（機能ごとに見積もった工数の合計を入れる）
- リリース・納品
    - リリース現地作業　※こちらが必要な場合は、工数とは別に旅費も見積に入れましょう
    - 納品物整理
    - 納品時お客様先訪問　※こちらが必要な場合は、工数とは別に旅費も見積に入れましょう
    - 納品説明（オンライン）

## スケジュール
### 請求日から逆算

見積を提示して、お客様から受注すると、スケジュールを考えていくことになります。

ですが、スケジュールを考えるときに、

- 請求は3月末
- 3月末までにリリースすればいいよね？
- お客様には3月の1か月間、受入試験してもらえばいいよね？
- 2月末にテスト環境に反映できればいいよね？

と考えてしまうケースがありました。

ところが、実際の案件では、リリースすれば終わり、というものはほとんどないですよね。

3月末請求だとして、逆算して考えてみましょう。
リリース前のお客様検証で1か月、納品物（ドキュメント等）まとめで2週間、納品物お客様確認で1か月必要だとすると、

- 社内テスト～1月中旬
- お客様検証（1か月）・・・1月中旬～2月中旬
- 本番リリース・・・2月中旬
- 納品物まとめ（2週間）・・・2月中旬～2月末
- 納品・・・2月末
- 納品物お客様確認（1か月）・・・2月末～3月末
- お客様検収、請求・・・3月末

のようになり、年末年始の稼働日が少ない状況も考えると、年越しの前に社内テストがほぼ終わっていないといけません。
2月末までにテスト環境に反映できればいいと思っていたのが、実際には年越しの前にはめどが立っていないといけない、ということで、ここを見誤ると、3月末に請求させて頂けなくなることがあります。

### 1日の中の稼働時間について

たとえば、1人月の工数のタスクがあったとします。
見積上、20人日で1人月として計算するとします。

さて、この1人月のタスクは、稼働日20日で完了できるでしょうか？

結論から言いますと、「NO」です。
理由を考えてみましょう。

具体的な例を挙げると、案件にかかわる時間のほかに

- 週次で30分、部署の定例会がある
- 週次で1時間、チームでの定例がある
- 日次で30分、チームの夕会・進捗報告がある。ただし週次のチーム定例の日は除く（週合計2時間）
- 週次で1時間、社内改善の取り組みがある
- 1日あたり30分、改善のためのタスクを進める必要がある（合計2.5時間）

のように、いろいろなタスクがありますよね。

上記の時間を合計すると、週当たり単純計算で7時間必要となります。
1日8時間で月～金曜で合計40時間のうち、7時間が必要になるということで、単純計算で17.5%は空けておかなければいけません。

さらに、

- 開発途中の不具合の対応やコードレビューの指摘への対応
- 突発的な事象の対応のための余裕
- 月～金の中での祝日
- 有給休暇

を考えると、案件のための稼働率を70%くらいにはしておきたいですね。

そして、さらに、不測の事態に対応するための予備日も確保しておきたいです。

# さいごに

私自身が今まで見積やスケジュールで失敗し、炎上させてしまった経験から書いてみました。

上記で挙げた以外にも、まだまだ出てくるかもしれません。
それでも、単純にシステムを作り上げるのにかかる時間・日数とは別に、意外と時間や日数を取られることが多いことがわかってきます。

おそらく、見積やスケジュールの精度向上が課題になっている方も多いと思いますが、その前に、上記のようなことを考え、仕組みを作って改善していく方法もあるので、日々悩む方が考える角度を変えてみるキッカケになると嬉しいです。