EXチームのスクラム開発を支えるNotion活用術
はじめに
どうも、MOSHでプロダクトエンジニアをしているmaedaです。
私の所属しているEXチームでは今年の1月からスクラム開発に挑戦しており、運用はNotionを使用しています。
Notionをカスタマイズしながら運用してきたので、やってよかった・効率が挙がった内容をいくつか紹介したいと思います。
この記事はMOSHアドベントカレンダー2024の21日目の記事です。
データベース構成
ポイントを紹介する前に大まかな構成を説明します。
主に以下3つのデータベースと1つのページを使用しています。
UserStory
- PBIを管理するメインのデータベース
- 優先度順に並んでいる
Tasks
- UserStoryを完成させるために必要なサブタスク群
- だいたい1Taskに1PR、1日で作業が終わる程度に分割
- だいたい1Taskに1人アサインする
- Task単位でポイント見積もりを行う
- Sprint(後述)を紐付け
- 複数Sprintに跨る場合は複数Sprint紐付けされる
Sprints
- スプリントを管理する
- EXチームは1週間スプリントなので1週間に1ページ増えていく
- スプリントゴールやスプリントレビューのFB、レトロスペクティブはこのページに記載
- スプリント単位でベロシティを計測
開発ボードページ
- 開発中1番よく見るページ
- 主に3つのセクションに分かれている
Section 1. スプリントゴール
Section 2. UserStory看板
Section 3. Tasks看板
活用術
同期ブロックでスプリントゴールを常に見える場所に配置
スプリントゴールはSprintsデータベースのページに記載しているのですが、このページはスプリントイベントデー以外はあまり見に行きません。そこで同期ブロック機能を活用して1番よく見る開発ボードページのTOPに配置するようにしました。
同期ブロックにせず転記も可能ですが、二重管理になってしまうのでそこの煩わしさも解消できています。
毎日のStandupMeetingでゴールを検査し、スプリントの健康状態を判断できると共に「ゴール達成するぞ!」というモチベーション維持もしやすいです。
ブロックタイプにコールアウトを使用しているのがミソです。
ベロシティの計算と可視化
Sprintsデータベースの数式プロパティでベロシティを自動計算するようにしています。
実際の計算式は以下です。
prop("Tasks").filter(current.prop("LastSprint").prop("Sprint name") == prop("Sprint name")).filter(current.prop("Status") == "Done").map(current.prop("Estimates").toNumber()).sum()
ちょっと複雑ですが、該当Sprintに紐付いているTaskのうちステータスがDoneのTaskのストーリーポイントの合計を算出しています。
Estimates
がTask単位に見積もりしたストーリーポイントです。
複雑になっているのは複数Sprintが紐付いているTaskがある場合を考慮して、紐付いているSprintのうち1番新しいものを元に算出するようになっているためです。
この判定を行うためにTasksデータベースに LastSprint
という数式プロパティを設けています。計算式は以下です。
prop("Sprint").sort(current.prop("Dates")).last()
また、Notionでグラフ機能がリリースされたのでベロシティの推移をグラフで可視化し、Sprintページ内に配置しています。
主にスプリントプランニング時のキャパシティ決めに使用したり、長い時間軸での開発生産性の振り返りなどに用いています。
(ベロシティの安定・向上は大きな課題です…
Githubプルリクエストの連携
TasksデータベースのプロパティでGithubプルリクエストと連携するようにしています。
PRのステータスに応じてTaskのステータスを更新してくれるのでとても便利です。
残ポイントの自動計算
次スプリントのキャパシティを決める際、Sprintを跨ぐタスクがあるとややこしくなります。
だいたい実装は完了しているがコードレビューが終わらなかったケースなので、コードレビューまで進んでいるTaskは70%完了した扱いで自動計算するようにしています。
実際の数式は以下
(prop("Tasks").map(current.prop("Estimates").toNumber()).sum()) - (prop("Tasks").filter((current.prop("Status") == "Done")).map(current.prop("Estimates").toNumber()).sum()) - (prop("Tasks").filter((current.prop("Status") == "Review")).map(current.prop("Estimates").toNumber()).sum())*0.7
残Taskのポイントをどう扱うかはそれぞれのチームごとに異なると思うので参考程度に。
また、カンバンの各レーンで集計可能なので残ポイントの合計を表示するようにしています。
キャパシティを決めるのに地味に役立っています。
まとめ
私の所属するEXチームでのNotion活用術をいくつか紹介してみました。
参考になるものがあれば幸いです。
Notionの数式やオートメーションなどは非常に強力で、うまく活用しながら価値の最大化に集中できる環境づくりをしていきたいと思います。
MOSHでは一緒に働く仲間を大募集しています!少しでも興味がありましたらお気軽にご連絡ください!
Discussion