テックリードとして成果を出しながら、「進捗を止める人」になった理由

初めてテックリードとしてアサインされたので自分のために反省点をまとめてみます。
担当はバックエンドのAPI開発です。
結論から言うと、成果を出すことより、人間の方がはるかに難しいと思いました。


プロジェクトではAPI開発だけでなく、遅れていたフロントエンド開発やデータ移管にも関与しました。

結果として、API開発はおおむねスケジュールを維持し、フロントエンドとの接続問題やデータ移管の問題も、最低限リリース可能な状態まで改善できました。

一方で、プロジェクトが進むほど、私は「進捗を止める人」に近い立場になっていきました。

今振り返ると、問題は他チームへ介入したこと自体ではありません。

プロジェクトに不足していた統合機能を非公式に引き受け、壊れた管理構造を自分の実装と稼働で迂回し続けたことが、本当の問題でした。

この記事では、その経緯と反省を整理します。


正式な責務がないまま、テックリードを担当した

このプロジェクトには、テックリードの責務を定義した資料がありませんでした。

実務上、私はAPI開発について以下を担当していました。

  • データベース設計
  • API設計
  • アーキテクチャ設計
  • 開発計画
  • 工数見積もり
  • 進捗管理
  • 品質管理
  • 人員不足時のエスカレーション
  • 技術的・進行上のリスク共有

一方で、プロダクト仕様の最終決定権はありませんでした。

他チームに対する指揮権もなく、認証・認可や一部のテーブルは別チームの担当でした。

つまり、API開発の結果に対しては責任を求められる一方で、その前提となる仕様やプロジェクト全体の意思決定については、十分な権限を持っていない状態でした。

当時は、この曖昧さを大きな問題として扱っていませんでした。

「必要になったら、その都度調整すればよい」と考えていたからです。

しかし、プロジェクトが不安定になるにつれて、責任と決定権の境界が曖昧なことが、大きな摩擦につながりました。


遅延よりも先に、進捗を判定できない問題があった

特に問題が大きかったのが、データ移管でした。

当時のデータ移管チームには、以下が十分に存在していませんでした。

  • 完了条件
  • 品質基準
  • 作業一覧
  • 明確なスケジュール
  • マイルストーン
  • 成果物を検証する仕組み

開発者本人が「オンスケジュール」と報告すれば、実際の完成度にかかわらず、オンスケジュールとして扱われる状態でした。

しかし、実装内容を確認すると、未完成の部分が多数残っていました。

さらに、チーム内でも以下が整理されていませんでした。

  • 最終的に何が完成すればよいのか
  • 次に何を実装すべきか
  • 仕様について誰に確認すればよいのか
  • 元データに問題があった場合、誰が判断するのか

突然その日に行う作業が変わり、翌日の作業が増え、仕様変更や元データの不備が見つかる状態が続いていました。

これは単純に「開発が遅れていた」という問題ではありません。

そもそも、オンスケジュールかどうかを判定する仕組み自体がなかった。

という状態でした。

それにもかかわらず、データ移管がオンスケジュールであることを前提に、プロジェクト全体のテコ入れ計画が検討されていました。

私は、その前提では計画が成立しないと指摘しました。

内容としては必要な指摘だったと思います。

しかし、周囲からは、既に進めようとしている計画を止める発言として受け取られました。


情報を整理する運用が、情報を遮断する運用になっていた

フロントエンド開発にも、別の問題がありました。

フロントエンド開発者とAPI開発チームの直接的なコミュニケーションが制限され、特定のメンバーだけが両チームの窓口になっていました。

また、APIとの接続で問題が起きても、開発者がIssueを作成することは認められていませんでした。

この運用によって、以下の状態が発生していました。

  • フロントエンド側がどこで困っているのか、API開発者に伝わらない
  • APIとの接続不具合がブラックボックス化する
  • バックエンド側は、必要な情報を提供できない
  • 問題の原因を両チームで直接確認できない

バックエンドではSwaggerのJSONを提供していました。

しかし、フロントエンド側ではそれを開発に利用しておらず、存在しないAPIへリクエストを送っている箇所もありました。

その状態で、接続できない主な原因はバックエンドのドキュメント不足であると判断され、フロントエンドの修正を止めて、バックエンド側の追加ドキュメントを整備する案が出ていました。

私はこの方針に反対しました。

Swaggerを利用していないことが主要因であり、文章によるドキュメントを追加しても、根本的な問題は解決しないと考えたからです。

また、Issueを作成できない運用についても、問題を発見した人から解決できる人へ情報が届かなくなるため、変更するべきだと主張しました。

ここでも、問題の原因に対する認識が異なり、強い摩擦が起きました。

振り返ると、当時の運用では、

コミュニケーション経路を整理することと、必要な情報を担当者から遮断することが混同されていた。

のだと思います。


実装によって問題を迂回した

私は、データ移管とフロントエンドの問題に対して、実装による解決を選びました。

データ移管で行ったこと

まず、未実装の部分を調査し、必要な作業を一覧化しました。

そのうえで、社内や他チームから支援可能な開発者を探し、実装者を集めました。

不足していた部分については、私自身も深夜や休日に実装しました。

また、データ移管の手順は属人化していました。

複数のバッチを決められた順番で手作業実行する必要があり、全手順を理解している担当者も限られていました。

そこで、元データを用意すれば、ボタン操作でデータベースへ投入できる形にワークフローを整理しました。

完成度に課題は残っていましたが、最低限動作する状態にはできました。

フロントエンドで行ったこと

フロントエンドには、SwaggerからTypeScriptの型を生成するライブラリを導入しました。

これにより、APIのパスやリクエスト、レスポンスの型を機械的に利用できるようにしました。

結果として、接続上の問題の大部分が解消しました。

バックエンド側が文章ドキュメントを大量に追加しなくても、Swaggerを基準に開発を進められる状態になりました。

こちらについても、支援可能な開発者を集め、不足していた接続実装の一部は私自身が担当しました。


短期的には成果が出た

これらの対応によって、短期的には以下の結果を得られました。

  • API開発はおおむねスケジュールを維持した
  • データ移管を最低限動作可能な状態にした
  • 属人的だったデータ投入手順を整理した
  • フロントエンドとバックエンドの接続問題の大部分を解消した
  • Swaggerを基準にフロントエンド開発を進められるようにした
  • 各チームの未実装部分やリスクを把握できるようになった

技術的な問題については、必要な情報と時間があれば、分解して実装へ落とし込むことができました。

しかし、実装上の問題を解決するほど、別の問題が大きくなりました。


非公式なプロジェクト統合責任者になっていた

バックエンド、フロントエンド、データ移管の各領域に関与した結果、私は実質的に以下の役割を兼ねる状態になりました。

  • 実装者
  • 技術判断者
  • チーム間調整者
  • 情報統合者
  • 品質確認者
  • 人員調達者
  • 実質的なリカバリー責任者

正式にプロジェクト全体の責任者として任命されたわけではありません。

他チームへの指揮権も、仕様の最終決定権もありませんでした。

それでも、各チームの不足を補い、依存関係を整理し、進捗の実態を確認し、必要な人員を集め、不足実装を担当していました。

そのため、単に「担当範囲を越えて介入した」というより、

プロジェクトに不足していた統合機能を、非公式に引き受ける状態になった。

と整理する方が正確です。

この状態になったことで、プロジェクト全体の情報が自分に集まりました。

  • バックエンドの実装状況
  • フロントエンドの接続状況
  • データ移管の未実装状況
  • 各チームの依存関係
  • リリースまでに必要な残作業
  • 各計画の前提が成立しているか

これらを横断的に確認できるようになったこと自体は、プロジェクトを進めるうえで役立ちました。

一方で、管理側や他チームとの間に、情報の非対称性が生まれました。


なぜ「進捗を止める人」になったのか

私には、複数チームの情報が集まっていました。

そのため、ある計画が成立しない理由や、ある対応が根本解決にならない理由が見えるようになっていました。

しかし、他の人が同じ情報を持っていたわけではありません。

私には成立しないと分かる計画でも、他の人からは問題なく進んでいるように見えていました。

そこで前提の誤りを指摘すると、周囲からは、

  • 計画に反対する人
  • 作業を増やす人
  • 進捗を止める人

として見えるようになりました。

実際には、進捗を止めたかったわけではありません。

成立しない計画や、効果のない対応を止めようとしていました。

ただし、ここには自分側の問題もありました。

自分が判断根拠を持っていることと、その根拠を他者が検証できる形で共有できていることは別だった。

私は全体像を把握していましたが、それを共通の進捗表、依存関係一覧、Issue、意思決定記録などへ、十分に変換できていませんでした。

そのため、自分の反対が正しかったとしても、周囲からは根拠が見えず、単に否定しているように見える余地がありました。


本当の失敗は、介入したことではなかった

当初は、他チームへ介入しすぎたことが問題だったのではないかと考えていました。

しかし、現在は違うと考えています。

当時の状況では、誰かがチームを横断して情報を集め、依存関係を整理し、不足を補わなければ、プロジェクトは成立しませんでした。

介入自体は必要だった可能性が高いです。

問題は、介入の方法でした。

管理構造の問題を、自分の実装で吸収した

データ移管に必要だったのは、単なる実装者の追加だけではありませんでした。

本来は、以下を整備する必要がありました。

  • 責任者
  • 完了条件
  • 品質基準
  • 作業一覧
  • 見積もり
  • マイルストーン
  • 質問先
  • 意思決定方法

しかし、私は不足実装を自分で処理し、最低限動く状態まで持っていきました。

短期的には前進しましたが、プロジェクトを不安定にしていた管理構造自体は残りました。

プロジェクトを救済した一方で、問題を見えにくくした面もあります。

介入の範囲と終了条件を決めなかった

他チームを支援する際、以下を明確にしていませんでした。

  • 誰からの依頼で介入するのか
  • どこまで担当するのか
  • 何をもって完了とするのか
  • 元の責任者は誰か
  • 介入後の運用責任を誰へ戻すのか
  • 自分の本来の業務へどの程度影響するのか

その結果、一時的な支援ではなく、複数チームの恒常的なリカバリー責任者に近い状態になりました。

正しい説明をすれば、意思決定が変わると考えすぎた

私は、合理的な説明を続ければ、相手も方針を変更すると考えていました。

例えば、以下のような主張です。

  • Swaggerを利用していないなら、バックエンドの文章ドキュメントを増やしても解決しない
  • Issueを禁止すると、問題が隠れる
  • オンスケジュールを主張するなら、成果物やマイルストーンが必要
  • 開発が完了すると主張するなら、見積もりか作業一覧が必要
  • 方針を決定する人と、結果責任を負う人を一致させるべき

内容自体は、現在も大きく間違っていたとは考えていません。

しかし、説明を続けることと、組織として意思決定させることは別でした。

一定回数説明しても合意できない場合は、説得を続けるのではなく、以下を記録するべきでした。

  • 自分の推奨案
  • 推奨する根拠
  • 採用しない場合のリスク
  • 代替案
  • 最終判断者
  • 判断期限
  • リスクを受容する責任者

そのうえで、判断を本来の意思決定者へ返す必要がありました。

異常な稼働を、通常の成果に見える形で提供した

私は、不足実装を深夜や休日に対応しました。

結果としてリリースに必要な成果物は作れました。

しかし、これは通常の体制と計画で達成できた成果ではありません。

  • 人員が不足していた
  • 計画に不足があった
  • 他チームの未完了を別チームのテックリードが補った
  • 通常稼働では完了しなかった

これらを明確に分離せずに完了させると、組織には「現在の人員と計画で完了できた」という誤った認識が残ります。

残業したこと自体よりも、異常な追加稼働を、通常のプロジェクト成果に見える形で提供したことが反省点です。


次に同じ状況になったらどうするか

次に同様のプロジェクトを担当する場合は、以下を最初に行います。

責任と権限を明文化する

正式な責務資料がなくても、自分で以下を書き、上位者と認識を合わせます。

  • 自分が決定できる範囲
  • 承認が必要な範囲
  • 結果責任を持つ範囲
  • 他チームとの境界
  • 他者が決定した場合の責任者

進捗を客観的に判定する

「オンスケジュール」という自己申告では判断しません。

以下を基準にします。

  • 成果物
  • 完了条件
  • 品質基準
  • 作業一覧
  • マイルストーン
  • 動作確認結果

判定材料がなければ、「オンスケジュール」ではなく「進捗不明」と扱います。

他チームへの介入条件を決める

支援を開始する際は、最低限以下を記録します。

  • 支援対象
  • 支援理由
  • 支援範囲
  • 予定工数
  • 元の責任者
  • 自分の担当領域への影響
  • 完了条件
  • 終了条件
  • 支援後の運用責任

緊急で事前に決められない場合でも、介入直後には記録します。

情報を個人に集めたままにしない

複数チームの情報が自分に集まった場合は、以下へ変換します。

  • 共通の進捗表
  • 依存関係一覧
  • リスク一覧
  • Issue
  • 意思決定記録
  • マイルストーン
  • 完了条件

自分だけが全体像を知っている状態を作りません。

説得ではなく、意思決定を確定させる

意見が一致しない場合は、無制限に説得を続けません。

推奨案、代替案、リスク、判断期限、最終判断者を明記し、意思決定者へ返します。

回答がない場合も、相手から返信を引き出すことだけに執着せず、「未回答である」という状態自体をリスクとして記録します。

異常稼働を計画成功として扱わせない

深夜や休日の稼働が必要になった時点で、以下を共有します。

  • 通常稼働での完了予測
  • 追加稼働が必要な作業
  • 追加稼働が発生した原因
  • 本来必要だった人員または期間
  • 再発防止策

個人の追加稼働でスケジュールを成立させる前に、スコープ、期限、人員の変更を求めます。


まとめ

このプロジェクトでは、技術的な問題の多くは、情報を集め、分解し、実装することで解決できました。

難しかったのは、技術そのものよりも、以下の問題でした。

  • 現在の進捗を事実として確定できない
  • 完了条件や品質基準がない
  • 必要な情報が担当者へ届かない
  • 責任と決定権が一致していない
  • 誰が最終判断するか分からない
  • 実行可能性より、既存計画の維持が優先される
  • 問題を指摘すると、進捗妨害として扱われる
  • 管理上の不足を、現場の追加稼働で補えてしまう

私は、プロジェクトに不足していた統合機能を非公式に引き受けました。

その結果、短期的にはプロジェクトを前進させることができました。

一方で、壊れた管理構造を直すのではなく、自分の実装と稼働で迂回しました。

本当の反省点は、他チームへ介入したことではありません。

  • 非公式な役割の拡大を明文化しなかったこと
  • 必要な権限を要求しなかったこと
  • 情報を共有可能な仕組みに変換しきれなかったこと
  • 説得を続け、判断を責任者へ返しきれなかったこと
  • 異常な個人稼働で、計画と管理の不足を隠したこと

次に同じ状況になった場合は、成果物を作るだけでなく、誰が判断し、誰が責任を持ち、何をもって完了とするかを先に確定させます。

実装によってプロジェクトを救済する場合も、その救済によって、管理上の問題を見えなくしないようにします。


オマケ

この後、よりボロボロになったデータ移管チームのテックリードを兼任させられることになったのである。
現実は厳しい…。