作業項目と作業項目タイプ

課題

イシューはコラボレーションのための一元的なハブになる可能性を秘めています。私たちは、イシューがどのようなジョブを達成するために使われるのかによって、異なるイシュー・タイプが異なるフィールドと異なるコンテキストを必要とするという事実を受け入れる必要があります。例えば

  • バグは再現するためのステップを列挙する必要があります。
  • インシデントには、そのインシデントだけに関連するスタックトレースやその他のコンテキスト情報への参照が必要です。

各オブジェクト・タイプが別々のモデルに分岐する代わりに、ウィジェット(1つまたは複数のアトリビュート)でカスタマイズできる基本的な共通モデルを標準化することができます。

以下は、現在のイシューの使い方の問題点と、作業項目を検討している理由です:

  • ラベルを使ってイシューの種類を表示するのは面倒で、レポーターのビューを複雑にしています。
  • イシュー・タイプはラベルの上位2つの使用例の1つであるため、ファーストクラスのサポートを提供することは理にかなっています。
  • イシューは機能が追加されるにつれて乱雑になり始めており、完璧ではありません:

    • 他のオブジェクトとの関係を表面化する方法について、一貫したパターンがありません。
    • イシューにはラベルを使用するため、異なるタイプのイシュー間で首尾一貫した相互作用モデルがありません。
    • イシュー・タイプのさまざまな実装には柔軟性と拡張性がありません。
  • エピック、イシュー、要件、その他はすべて、共通するインタラクションにおいて類似していますが、微妙な違いがあるため、ユーザーはそれぞれの動作について複雑なメンタル・モデルを保持する必要があります。
  • イシューは、それらが促進する必要があるすべての新しいジョブをサポートするほど拡張性がありません。
  • コードベースのメンテナーと機能開発は、イシュー・タイプを、イシュー追跡という中核的な役割から、さまざまなワークアイテム・タイプのサポートや、ロジックや構造の違いの処理へと成長させるにつれて、より大きな課題となります。
  • 新しい機能は通常、共有された関心事を介してイシューから動作をインポートするファーストクラスのオブジェクトで実装されます。そのため、重複した作業が発生し、最終的には共通のインタラクション間でわずかな違いが生じることになります。これは一貫性のないUXにつながります。

作業項目の用語

混乱を避け、効率的なコミュニケーションを確保するため、ワークアイテムについて議論する際には、以下の用語を排他的に使用します。このリストは、ワークアイテムの用語に関する唯一の真実の情報源(SSoT)です。

用語説明誤用例あるべき姿
ワークアイテムタイプイシュー、要件、テストケース、インシデント、タスクなど。エピックは最終的にイシューになります。エピックは最終的にワークアイテムタイプになります。
作業項目ワークアイテム・タイプのインスタンス  
ワークアイテムビューあらゆるタイプのワークアイテムをレンダリングする新しいフロントエンドビュー新しいビューでレンダリングされます。ワークアイテムビューでレンダリングされます。
レガシーオブジェクトワークアイテム・タイプに変換された、または変換される予定のオブジェクト。エピックは、スタンドアロン/旧/旧オブジェクトからワークアイテム・タイプにマイグレーションされます。エピックは、レガシー・オブジェクトからワークアイテム・タイプに変換されます。
レガシー・イシュー・ビューイシューおよびインシデントのレンダリングに使用される既存のビュー。イシューは引き続き旧ビューでレンダリングされます。イシューは引き続き旧イシュー・ビューでレンダリングされます。
イシュー既存のイシュー・モデル  
発行可能現在issableモジュールを使用しているすべてのモデル(イシュー、エピック、MR)インシデントは発行可能インシデントは作業項目タイプです
ウィジェット特定のワークアイテムデータを表示したり、相互作用を可能にするためのUI要素です。  

過去に使用された用語もありますが、混乱を招くため、現在では推奨されていません。

用語説明誤用例あるべき姿
イシュータイプワークアイテムのクラスを指す以前の方法タスクはイシューの一種タスクはワークアイテムの一種です。

マイグレーション戦略

WIモデルは既存のIssue モデルの Issue上に構築さIssue れ、 IssueモデルコードをIssue 徐々に IssueWIモデルに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

issuesissue_type カラムを通して、WITの概念を テーブル内部ですでに使用しています。issueincidenttest_case イシュー・タイプがあります。これを拡張し、将来的にユーザがカスタムWITを定義できるようにするため、issue_type を別のテーブルwork_item_typesに移行します。issue_type からwork_item_types へのマイグレーション・プロセスでは、すべてのルートレベル・グループのWITセットを作成します。

note
当初、WITの定義はルートレベルのグループでのみ可能で、サブグループに継承されます。サブグループレベルで新しいWITを定義する可能性については、後日調査する予定です。

work_item_types テーブルの導入

例えば、IDを持つルートレベルのグループが3つあるとします:11 12 13の3つのルートレベル・グループがあるとします。また、以下のベース・タイプがあるとします:issue: 0incident: 1test_case: 2

それぞれのwork_item_types レコード:

group_idbase_typetitle
110イシュー
111事件
112テストケース
120イシュー
121事件
122テストケース
130イシュー
131事件
132テストケース

そのために何をするか

  1. issues テーブルにwork_item_type_id カラムを追加します。
  2. 新規または更新されたイシューについて、issues#issue_typeissues#work_item_type_id の両方のカラムに書き込むようにしてください。
  3. work_item_type_id 列を埋め戻して、イシューのプロジェクト・ルート・グループに対応するwork_item_types#id 。例えば

    issue.project.root_group.work_item_types.where(base_type: issue.issue_type).first.id.
    
  4. 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_typebase_type他のタイプのリソース(要件やインシデント)をワークアイテムに変換するのに役立つように追加されました。いずれ(これらのリソースが通常のワークアイテムになったとき)、base_type は削除される予定です。

WITウィジェットのアーキテクチャが確定するまで、新しいワークアイテムタイプの作成は控えています。新しいワークアイテムタイプがどうしても必要な場合は、プロジェクトマネジメントエンジニアリングチームのメンバーまでご連絡ください。

カスタム作業項目タイプ

WITウィジェットのメタデータと、WITを特定のウィジェットにマッピングするワークフローにより、カスタムWITをユーザーに公開できるようになります。ユーザーは、独自のWITを作成し、定義済みのプールからウィジェットを使用してカスタマイズできます。

カスタムウィジェット

最終的な目標は、ユーザーがカスタムウィジェットを定義し、そのカスタムウィジェットをどのWITでも使用できるようにすることです。しかし、これはかなり先の話であり、使用するデータとアプリケーションアーキテクチャの両方を決定するための追加調査が必要です。

要件とエピックから作業項目タイプへのマイグレーション

要件とエピックは、独自のウィジェットを持つワークアイテムタイプにマイグレーションします。そのために、issues テーブルにデータをマイグレーションします。また、すでに存在する参照との後方互換性を確保するために、古い参照のプロキシとして使用される現在のrequirementsepics テーブルを維持します。

要件を作業項目タイプにマイグレーション

現在、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 を追跡する必要があります。

集計カウンタのスキーマ案

graph TD Event[Specific Interaction Counter] --> AC[Aggregate Counters] AC --> Plan[Plan xMAU] AC --> PM[Project Management xMAU] AC --> PP[Product Planning xMAU] AC --> Cer[Certify xMAU] AC --> WI[Work Items Users]

実施

新しいアグリゲートスキーマはすでに実装されており、GitLab.comでワークアイテムのユニークアクションをトラッキングしています。

実装の詳細については、このMRを参考にしてください。この MR は、新しいユニーク・アクションの定義、コードでのイベント追跡、そして必要な集約カウンタへの新しいユニーク・アクションの追加をカバーしています。