作業項目と作業項目タイプ
課題
イシューはコラボレーションのための一元的なハブになる可能性を秘めています。私たちは、イシューがどのようなジョブを達成するために使われるのかによって、異なるイシュー・タイプが異なるフィールドと異なるコンテキストを必要とするという事実を受け入れる必要があります。例えば
- バグは再現するためのステップを列挙する必要があります。
- インシデントには、そのインシデントだけに関連するスタックトレースやその他のコンテキスト情報への参照が必要です。
各オブジェクト・タイプが別々のモデルに分岐する代わりに、ウィジェット(1つまたは複数のアトリビュート)でカスタマイズできる基本的な共通モデルを標準化することができます。
以下は、現在のイシューの使い方の問題点と、作業項目を検討している理由です:
- ラベルを使ってイシューの種類を表示するのは面倒で、レポーターのビューを複雑にしています。
- イシュー・タイプはラベルの上位2つの使用例の1つであるため、ファーストクラスのサポートを提供することは理にかなっています。
-
イシューは機能が追加されるにつれて乱雑になり始めており、完璧ではありません:
- 他のオブジェクトとの関係を表面化する方法について、一貫したパターンがありません。
- イシューにはラベルを使用するため、異なるタイプのイシュー間で首尾一貫した相互作用モデルがありません。
- イシュー・タイプのさまざまな実装には柔軟性と拡張性がありません。
- エピック、イシュー、要件、その他はすべて、共通するインタラクションにおいて類似していますが、微妙な違いがあるため、ユーザーはそれぞれの動作について複雑なメンタル・モデルを保持する必要があります。
- イシューは、それらが促進する必要があるすべての新しいジョブをサポートするほど拡張性がありません。
- コードベースのメンテナーと機能開発は、イシュー・タイプを、イシュー追跡という中核的な役割から、さまざまなワークアイテム・タイプのサポートや、ロジックや構造の違いの処理へと成長させるにつれて、より大きな課題となります。
- 新しい機能は通常、共有された関心事を介してイシューから動作をインポートするファーストクラスのオブジェクトで実装されます。そのため、重複した作業が発生し、最終的には共通のインタラクション間でわずかな違いが生じることになります。これは一貫性のないUXにつながります。
作業項目の用語
混乱を避け、効率的なコミュニケーションを確保するため、ワークアイテムについて議論する際には、以下の用語を排他的に使用します。このリストは、ワークアイテムの用語に関する唯一の真実の情報源(SSoT)です。
用語 | 説明 | 誤用例 | あるべき姿 |
---|---|---|---|
ワークアイテムタイプ | イシュー、要件、テストケース、インシデント、タスクなど。 | エピックは最終的にイシューになります。 | エピックは最終的にワークアイテムタイプになります。 |
作業項目 | ワークアイテム・タイプのインスタンス | ||
ワークアイテムビュー | あらゆるタイプのワークアイテムをレンダリングする新しいフロントエンドビュー | 新しいビューでレンダリングされます。 | ワークアイテムビューでレンダリングされます。 |
レガシーオブジェクト | ワークアイテム・タイプに変換された、または変換される予定のオブジェクト。 | エピックは、スタンドアロン/旧/旧オブジェクトからワークアイテム・タイプにマイグレーションされます。 | エピックは、レガシー・オブジェクトからワークアイテム・タイプに変換されます。 |
レガシー・イシュー・ビュー | イシューおよびインシデントのレンダリングに使用される既存のビュー。 | イシューは引き続き旧ビューでレンダリングされます。 | イシューは引き続き旧イシュー・ビューでレンダリングされます。 |
イシュー | 既存のイシュー・モデル | ||
発行可能 | 現在issableモジュールを使用しているすべてのモデル(イシュー、エピック、MR) | インシデントは発行可能 | インシデントは作業項目タイプです |
ウィジェット | 特定のワークアイテムデータを表示したり、相互作用を可能にするためのUI要素です。 |
過去に使用された用語もありますが、混乱を招くため、現在では推奨されていません。
用語 | 説明 | 誤用例 | あるべき姿 |
---|---|---|---|
イシュータイプ | ワークアイテムのクラスを指す以前の方法 | タスクはイシューの一種 | タスクはワークアイテムの一種です。 |
マイグレーション戦略
WIモデルは既存のIssue
モデルの Issue
上に構築さIssue
れ、 Issue
モデルコードをIssue
徐々に Issue
WIモデルにIssue
マイグレーションして Issue
いきます。
ひとつのアプローチ方法としては
class WorkItems::WorkItem < ApplicationRecord
self.table_name = 'issues'
# ... all the current issue.rb code
end
class Issue < WorkItems::WorkItem
# Do not add code to this class add to WorkItems:WorkItem
end
issues
、issue_type
カラムを通して、WITの概念を テーブル内部ですでに使用しています。issue
、incident
、test_case
イシュー・タイプがあります。これを拡張し、将来的にユーザがカスタムWITを定義できるようにするため、issue_type
を別のテーブルwork_item_types
に移行します。issue_type
からwork_item_types
へのマイグレーション・プロセスでは、すべてのルートレベル・グループのWITセットを作成します。
work_item_types
テーブルの導入
例えば、IDを持つルートレベルのグループが3つあるとします:11
12
13
の3つのルートレベル・グループがあるとします。また、以下のベース・タイプがあるとします:issue: 0
incident: 1
、test_case: 2
。
それぞれのwork_item_types
レコード:
group_id | base_type | title |
---|---|---|
11 | 0 | イシュー |
11 | 1 | 事件 |
11 | 2 | テストケース |
12 | 0 | イシュー |
12 | 1 | 事件 |
12 | 2 | テストケース |
13 | 0 | イシュー |
13 | 1 | 事件 |
13 | 2 | テストケース |
そのために何をするか
-
issues
テーブルにwork_item_type_id
カラムを追加します。 - 新規または更新されたイシューについて、
issues#issue_type
とissues#work_item_type_id
の両方のカラムに書き込むようにしてください。 -
work_item_type_id
列を埋め戻して、イシューのプロジェクト・ルート・グループに対応するwork_item_types#id
。例えばissue.project.root_group.work_item_types.where(base_type: issue.issue_type).first.id.
-
issues#work_item_type_id
が入力された後、クエリをissue_type
の使用からwork_item_type_id
の使用に切り替えることができます。
新しいWITを導入するには、2つのオプションがあります:
- 上記のプロセスの最初のステップに従います。すべてのユーザーがWITを利用できるようにするには、すべてのルートレベルのグループに新しいWITを追加するマイグレーションを実行する必要があります。マイグレーションを長時間実行することに加え、
work_item_types
に数百万レコードを挿入する必要があります。これは、ワークフローにWITを追加したくない、または必要としないユーザーにとっては望ましくないかもしれません。 - オプトイン・フローを作成し、顧客がオプトインした場合にのみ、特定のルートレベル・グループのレコードが
work_item_types
に作成されるようにします。ただし、この場合、新しく導入されたワークアイテム・タイプの検出性が低下します。
作業項目タイプウィジェット
ウィジェットは、ワークアイテム上に存在できる単一のコンポーネントです。このコンポーネントは、1つまたは複数のワークアイテムタイプで使用することができ、実装の時点で軽くカスタマイズすることができます。
ウィジェットには、フロントエンドUI(存在する場合)と、ウィジェットで使用されるデータを表示および管理するための関連ロジックの両方が含まれます。データモデルとウィジェットは一対多の接続が可能です。つまり、同じデータを使用または管理する複数のウィジェットが存在する可能性があり、同時に存在する可能性があります (たとえば、読み取り専用のサマリウィジェットと編集可能な詳細ウィジェット、または同じモデルの 2 つの異なるフィルタされたビューを表示する 2 つのウィジェット)。
ウィジェットは目的によって区別されるべきです。可能であれば、再利用性を最大化するために、この目的は合理的な最高レベルまで抽象化されるべきです。例えば、”タスク “を管理するウィジェットは “子アイテム “として構築されています。1つのタイプの子を管理するのではなく、任意の子を管理するように抽象化されています。
すべてのWITは、定義済みのウィジェットの同じプールを共有し、特定のWITでどのウィジェットがアクティブかによってカスタマイズされます。すべての属性(カラムやアソシエーション)は、それがどのWITに属しているかに関係なく、自己カプセル化された機能を持つウィジェットになります。どのWITもどのウィジェットも持つことができるため、特定のWITでどのウィジェットがアクティブになるかを定義するだけでよいのです。したがって、特定のワークアイテムのタイプを切り替えた後、異なるウィジェットのセットを表示します。
ウィジェットのメタデータ
各WITを対応するアクティブなウィジェットでカスタマイズするには、各WITを特定のウィジェットにマッピングするデータ構造が必要です。
GitLabが顧客のために様々なワークアイテムスキーム(GitLabのワークフローやSAFe 5など)を実装するため、そして最終的には顧客が自身のワークフローをカスタマイズするために、ワークアイテムの種類を高度に設定できるようにすることが意図されています。
この場合、ワークアイテムのスキームは、エピック、ストーリー、バグ、タスクなど、特定の特性(ウィジェットが有効なものとそうでないもの)を持つタイプのセットとして定義されます。
新しいワークアイテムアーキテクチャを構築するにあたり、これらの様々なタイプを非常に柔軟に定義できるようにしたいと考えています。GitLabが最初にこのシステムを使うことで、(顧客のカスタマイズを導入することなく)最初のシステムをよりよく構築することができます。
ワークアイテムは、base_type
それぞれのタイプ(現在のステータス)に対してどのウィジェットが利用可能か、という静的なマッピングを定義するために使わ base_type
れます。base_type
WITウィジェットのメタデータの正確な base_type
構造は、base_type
まだ定義 base_type
されていませんbase_type
。 base_type
他のタイプのリソース(要件やインシデント)をワークアイテムに変換するのに役立つように追加されました。いずれ(これらのリソースが通常のワークアイテムになったとき)、base_type
は削除される予定です。
WITウィジェットのアーキテクチャが確定するまで、新しいワークアイテムタイプの作成は控えています。新しいワークアイテムタイプがどうしても必要な場合は、プロジェクトマネジメントエンジニアリングチームのメンバーまでご連絡ください。
カスタム作業項目タイプ
WITウィジェットのメタデータと、WITを特定のウィジェットにマッピングするワークフローにより、カスタムWITをユーザーに公開できるようになります。ユーザーは、独自のWITを作成し、定義済みのプールからウィジェットを使用してカスタマイズできます。
カスタムウィジェット
最終的な目標は、ユーザーがカスタムウィジェットを定義し、そのカスタムウィジェットをどのWITでも使用できるようにすることです。しかし、これはかなり先の話であり、使用するデータとアプリケーションアーキテクチャの両方を決定するための追加調査が必要です。
要件とエピックから作業項目タイプへのマイグレーション
要件とエピックは、独自のウィジェットを持つワークアイテムタイプにマイグレーションします。そのために、issues
テーブルにデータをマイグレーションします。また、すでに存在する参照との後方互換性を確保するために、古い参照のプロキシとして使用される現在のrequirements
とepics
テーブルを維持します。
要件を作業項目タイプにマイグレーション
現在、Requirement
属性は、Issue
属性のサブセットであるため、マイグレーションは主に以下の内容で構成されます:
- データのマイグレーション。
- APIレベルでの後方互換性の維持。
- 古いリファレンスが引き続き動作するようにします。
異なるデータ構造へのマイグレーションは、エンドユーザーにとってシームレスでなければなりません。
エピックから作業項目タイプへのマイグレーション
Epic
には、Issue
WITが現在持っていない追加機能があります。そのため、エピックを作業項目タイプにマイグレーションするには、現在のEpic
オブジェクトとWITの間に機能パリティを提供する必要があります。
欠けている主な機能は以下の通りです:
- ワークアイテムをグループレベルに。これは、グループとプロジェクトの統合イニシアチブに依存します。
- 階層ウィジェット:ワークアイテムを階層構造化する機能。
- 継承された日付ウィジェット。
すでにエピックを使っているユーザーのワークフローを混乱させないために、Feature
という新しいWITを導入し、プロジェクトレベルでエピックと同等の機能を提供する予定です。グループとプロジェクトの統合(Consolidate Groups and Projects)の進捗と組み合わせることで、ユーザーのワークフローへの混乱を最小限に抑えながら、エピックからWITへのスムーズなマイグレーションを実現します。
ワークアイテム、ワークアイテムタイプ、ウィジェットのロードマップ
私たちは、ワークアイテム、ワークアイテムタイプ、カスタムウィジェット(CW) に向けて、反復プロセスで進んでいきます。今後の作業の大まかなアウトラインは、エピック6033を参照してください。
Redis HLLカウンタースキーマ
Plan xMAU、Project Management xMAU、Certify xMAU、Product Planning xMAUを含む、ワークアイテム用のスケーラブルなRedisカウンタースキーマが必要です。現在の Redis スロット・スキーマでは、グループ内またはステージ・レベルでフィーチャー間のイベントを集約およびデデュープすることができません。
3つのプラン製品グループはすべて、同じベースオブジェクト (work item
) を使用します。各製品グループは依然として MAU を追跡する必要があります。
集計カウンタのスキーマ案
実施
新しいアグリゲートスキーマはすでに実装されており、GitLab.comでワークアイテムのユニークアクションをトラッキングしています。
実装の詳細については、このMRを参考にしてください。この MR は、新しいユニーク・アクションの定義、コードでのイベント追跡、そして必要な集約カウンタへの新しいユニーク・アクションの追加をカバーしています。