InfoGrab DocsInfoGrab Docs

작업 항목 및 작업 항목 유형

요약

작업 항목은 GitLab의 이슈 추적 기능을 표준화하고 확장하는 유연한 모델을 도입합니다. 이슈는 협업의 중앙 허브가 될 가능성이 있습니다. 각 객체 유형이 별도의 모델로 갈라지는 대신, 포함하는 위젯(하나 이상의 속성)으로 커스터마이즈할 수 있는 공통 기반 모델로 표준화할 수 있습니다.

작업 항목은 GitLab의 이슈 추적 기능을 표준화하고 확장하는 유연한 모델을 도입합니다. 작업 항목에서는 여러 위젯으로 커스터마이즈할 수 있는 다양한 유형을 정의하여, 버그나 인시던트, 테스트 케이스 등 어떤 작업 단위를 추적하든 특정 요구를 충족할 수 있습니다. 이 아키텍처 문서는 작업 항목과 작업 항목 유형의 개발 세부 사항과 구현 전략을 다룹니다. 앞으로 진행할 작업의 대략적인 개요는 에픽 6033을 참고합니다.

과제#

이슈는 협업의 중앙 허브가 될 가능성이 있습니다. 각기 다른 이슈 유형은 어떤 작업을 수행하는 데 쓰이는지에 따라 서로 다른 필드와 서로 다른 컨텍스트가 필요하다는 사실을 받아들여야 합니다. 예를 들면 다음과 같습니다.

  • 버그에는 재현 단계를 나열해야 합니다.
  • 인시던트에는 스택 트레이스에 대한 참조와 해당 인시던트에만 관련된 그 밖의 컨텍스트 정보가 필요합니다.

각 객체 유형이 별도의 모델로 갈라지는 대신, 포함하는 위젯(하나 이상의 속성)으로 커스터마이즈할 수 있는 공통 기반 모델로 표준화할 수 있습니다.

현재 이슈 사용 방식의 문제점과 작업 항목을 검토하는 이유는 다음과 같습니다.

  • 레이블로 이슈 유형을 표시하는 방식은 번거롭고 보고 뷰를 더 복잡하게 만듭니다.

  • 이슈 유형은 레이블의 주요 사용 사례 두 가지 중 하나이므로, 이슈 유형에 일급 지원을 제공하는 것이 합리적입니다.

  • 이슈에 더 많은 기능을 추가하면서 이슈가 혼잡해지기 시작했고, 이슈는 완벽하지도 않습니다.

    • 다른 객체와의 관계를 표면화하는 방법에 일관된 패턴이 없습니다.
    • 이 부분에 레이블을 사용하기 때문에 서로 다른 이슈 유형 간에 일관된 상호작용 모델이 없습니다.
    • 이슈 유형의 여러 구현은 유연성과 확장성이 부족합니다.
  • 에픽, 이슈, 요구사항 등은 공통 상호작용에서 서로 비슷하지만 미묘하게 달라서, 사용자가 각각이 어떻게 동작하는지에 대한 복잡한 멘탈 모델을 유지해야 합니다.

  • 이슈는 이슈가 지원해야 하는 새로운 작업을 모두 수용할 만큼 확장 가능하지 않습니다.

  • Issue 유형을 이슈 추적이라는 핵심 역할을 넘어 여러 작업 항목 유형을 지원하고 로직과 구조의 차이를 처리하는 방향으로 키우면서, 코드베이스 유지 관리와 기능 개발이 더 큰 과제가 됩니다.

  • 새 기능은 보통 공유 관심사를 통해 이슈의 동작을 가져오는 일급 객체로 구현됩니다. 이는 중복된 노력으로 이어지고 결국 공통 상호작용 사이에 작은 차이를 만듭니다. 그 결과 UX가 일관되지 않습니다.

작업 항목 용어#

혼란을 방지하고 효율적인 커뮤니케이션을 보장하기 위해, 작업 항목을 논의할 때는 다음 용어만 사용합니다. 이 목록은 작업 항목 용어의 단일 진실 공급원(Single Source Of Truth, SSOT)입니다.

용어 설명 잘못된 사용 예 올바른 표현
work item type 작업 항목의 클래스입니다. 예: 이슈, 요구사항, 테스트 케이스, 인시던트, 태스크 에픽은 결국 이슈가 됩니다 에픽은 결국 work item type 이 됩니다
work item work item type의 인스턴스
work item view 모든 유형의 작업 항목을 렌더링하는 새 프론트엔드 뷰 이 항목은 새 뷰에서 렌더링되어야 합니다 이 항목은 work item view에서 렌더링되어야 합니다
legacy object 작업 항목 유형으로 전환되었거나 전환될 객체 에픽은 독립형·구형·이전 객체에서 work item type으로 마이그레이션됩니다 에픽은 legacy object에서 work item type으로 전환됩니다
legacy issue view 이슈와 인시던트를 렌더링하는 데 쓰이는 기존 뷰 이슈는 계속 구 뷰에서 렌더링됩니다 이슈는 계속 legacy issue view에서 렌더링됩니다
issue 기존 이슈 모델
issuable 현재 issuable 모듈을 사용하는 모든 모델(이슈, 에픽, MR) 인시던트는 issuable 입니다 인시던트는 work item type 입니다
widget 특정 작업 항목 데이터를 표시하거나 조작할 수 있게 하는 UI 요소

일부 용어는 과거에 사용했지만 이후 혼란을 일으켜 현재는 사용을 권장하지 않습니다.

용어 설명 잘못된 사용 예 올바른 표현
issue type 작업 항목의 클래스를 가리키던 이전 표현 태스크는 issue type 입니다 태스크는 work item type 입니다

마이그레이션 전략#

WI 모델은 기존 Issue 모델 위에 구축하며, Issue 모델 코드를 WI 모델로 점진적으로 마이그레이션합니다.

접근 방법 중 하나는 다음과 같습니다.

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 세트를 만드는 작업이 포함되며, 자세한 내용은 이 에픽에 설명되어 있습니다.

Note

처음에는 WIT 정의가 루트 수준 그룹에서만 가능하며, 이후 하위 그룹에 상속됩니다. 이후 반복에서 하위 그룹 수준에서 새 WIT를 정의할 수 있는지 검토할 예정입니다.

작업 항목 유형 아키텍처#

GitLab은 시스템 정의 유형과 커스텀 작업 항목 유형을 모두 지원하는 유연한 유형 시스템을 사용합니다. 이 아키텍처는 Cells 이니셔티브의 요구 사항을 충족하도록 설계되어, 셀 간 데이터베이스 쿼리 없이 효율적으로 유형을 조회할 수 있습니다. 아키텍처 배경은 구성 가능한 작업 항목 유형 설계 문서를 참고합니다.

시스템 정의 유형#

시스템 정의 유형은 GitLab에 내장된 사전 정의 작업 항목 유형입니다. 이 유형들은 코드에서 Ruby 모듈로 정의되며 시작 시 메모리에 로드됩니다.

사용 가능한 유형:

유형 ID 기본 유형 가용성 비고
Issue 1 issue CE + EE
Incident 2 incident CE + EE 전체 WIT로 전환 중
Test Case 3 test_case EE only 전체 WIT로 전환 중
Requirement 4 requirement EE only 전체 WIT로 전환 중
Task 5 task CE + EE
Objective 6 objective EE only 제거 예정
Key Result 7 key_result EE only 제거 예정
Epic 8 epic EE only
Ticket 9 ticket CE + EE

구현 세부 사항:

  • 모델: WorkItems::TypesFramework::SystemDefined::Type
  • 위치: app/models/work_items/types_framework/system_defined/
  • 각 유형은 definitions/에 정의 모듈이 있습니다(예: definitions/issue.rb)
  • 데이터베이스 쿼리 없이 ActiveRecord와 유사한 API를 제공하기 위해 ActiveRecord::FixedItemsModel을 사용합니다

유형 정의 예시:

module WorkItems::TypesFramework::SystemDefined::Definitions::Issue
  def self.configuration
    { id: 1, name: 'Issue', base_type: 'issue', icon_name: 'work-item-issue' }
  end

  def self.widgets
    %w[assignees description labels milestone notes ...]
  end

  def self.supports_move_action?
    true
  end
end

커스텀 작업 항목 유형#

커스텀 유형을 사용하면 조직과 네임스페이스가 자체 워크플로에 맞춘 작업 항목 유형을 만들 수 있습니다. 이 기능은 FY27 Q1에 제공될 예정입니다.

커스텀 유형은 다음 두 가지 방법으로 만들 수 있습니다.

  1. 완전히 새로운 커스텀 유형 - 시스템 정의 유형처럼 동작하지만 고유한 개념을 나타내는 완전히 새로운 유형(예: "Pizza")을 만듭니다. 이 유형은 기본적으로 Issue처럼 동작하지만 자체 정체성을 가집니다.
  2. 전환된 유형 - 기존 시스템 정의 유형을 전환해 커스텀 유형을 만듭니다. 커스텀 유형은 원래 시스템 정의 유형을 참조하고, 달라지는 속성(이름, 아이콘, 보관 상태)만 저장합니다. 그 밖의 동작과 위젯은 모두 참조한 시스템 정의 유형에서 상속됩니다.

구현 세부 사항:

  • 모델: WorkItems::TypesFramework::Custom::Type
  • 테이블: work_item_custom_types
  • 범위:
    • Self-Managed: 조직 수준(장기 타깃 범위)
    • SaaS (GitLab.com): 루트 그룹 수준(조직 수준 기능을 사용할 수 있게 될 때까지의 임시 방안)
  • 한도: 상위 범위당 한도이며, WorkItems::TypesFramework::Custom::Type::MAX_TYPE_PER_PARENT에 저장됩니다
Note

GitLab.com에서는 현재 모든 루트 그룹이 같은 조직에 속하므로 커스텀 유형의 범위가 루트 그룹으로 지정됩니다. SaaS에서 조직 수준 기능을 완전히 사용할 수 있게 되면, Self-Managed와 맞추기 위해 커스텀 유형이 조직 범위로 이동합니다.

전환된 유형:

시스템 정의 유형을 전환하면 커스텀 유형은 원본을 참조해 동작을 상속하면서 특정 항목을 커스터마이즈할 수 있습니다.

커스터마이즈 가능한 속성:

  • name - 커스텀 표시 이름(최대 48자)
  • icon_name - 커스텀 아이콘 선택
  • archived - 보관 상태

상속되는 속성:

  • 위젯 구성(향후 유형별 커스터마이즈 가능)
  • 기본 유형 동작
  • 계층 제한

예시:

조직이 시스템 정의 "Issue" 유형을 전환해 커스텀 "Bug" 유형을 만드는 경우입니다.

  • Issue의 모든 위젯과 동작을 상속합니다
  • 이름을 "Bug" 로 재정의합니다
  • 선택적으로 다른 아이콘을 사용합니다
  • converted_from_system_defined_type_identifier 칼럼을 통해 Issue 유형을 참조합니다

Provider 인터페이스#

WorkItems::TypesFramework::Provider 클래스는 작업 항목 유형에 접근하는 단일 진입점입니다. 모든 코드는 유형 클래스에 직접 접근하지 않고 Provider를 사용해야 합니다.

네임스페이스 컨텍스트:

Provider에 네임스페이스를 전달하는 일은 사용할 수 있는 유형을 결정하므로 매우 중요합니다.

  • 네임스페이스가 없는 경우: 시스템 정의 유형만 반환합니다(전역 유형 9개)
  • 네임스페이스가 있는 경우: 시스템 정의 유형과 함께, 다음에 대해 정의된 커스텀 유형(전환된 유형 또는 완전히 새로운 유형)을 반환합니다
    • Self-Managed: 해당 네임스페이스의 조직
    • SaaS (GitLab.com): 해당 네임스페이스를 포함하는 루트 그룹

Provider는 단일 요청 안에서 빠르게 조회하기 위해 요청 저장소에 유형을 캐시하므로, 커스텀 유형을 반복해서 쿼리하지 않습니다.

사용법:

# Initialize with namespace context
provider = WorkItems::TypesFramework::Provider.new(namespace)

# Fetch types
provider.all                           # All available types
provider.filtered_types                # Types available to namespace
provider.find_by_base_type(:issue)     # Find by base type
provider.find_by_id(1)                 # Find by ID
provider.default_issue_type            # Get default issue type

관련 파일:

이전 배경#

GitLab 18.1 이전에는 작업 항목 유형을 work_item_types 데이터베이스 테이블에 저장했습니다. 이 방식은 Cells 이니셔티브를 지원하기 위해 현재의 시스템 정의 유형 아키텍처로 대체되었습니다.

작업 항목 유형 위젯#

위젯은 작업 항목에 존재할 수 있는 단일 컴포넌트입니다. 이 컴포넌트는 하나 또는 여러 작업 항목 유형에서 사용할 수 있고, 구현 지점에서 가볍게 커스터마이즈할 수 있습니다.

위젯에는 프론트엔드 UI(있는 경우)와 위젯이 사용하는 데이터를 표시하고 관리하는 관련 로직이 모두 들어 있습니다. 데이터 모델과 위젯 사이에는 일대다 연결이 있을 수 있습니다. 즉 같은 데이터를 사용하거나 관리하는 위젯이 여러 개 있을 수 있고, 이들이 동시에 존재할 수도 있습니다(예: 읽기 전용 요약 위젯과 편집 가능한 세부 정보 위젯, 또는 같은 모델의 서로 다른 필터링 뷰 두 개를 보여 주는 위젯 두 개).

위젯은 목적에 따라 구분해야 합니다. 가능하다면 이 목적은 재사용성을 극대화하기 위해 합리적인 범위에서 가장 높은 수준으로 추상화해야 합니다. 예를 들어 "태스크" 를 관리하는 위젯은 "하위 항목" 으로 구축했습니다. 한 가지 유형의 자식을 관리하는 대신, 모든 자식을 관리하도록 추상화한 것입니다.

모든 WIT는 사전 정의된 위젯 풀을 공유하며, 특정 WIT에서 어떤 위젯이 활성화되어 있는지에 따라 커스터마이즈됩니다. 모든 속성(칼럼 또는 연관)은 속한 WIT와 무관하게 자체 캡슐화된 기능을 갖는 위젯이 됩니다. 어떤 WIT 든 어떤 위젯이든 가질 수 있으므로, 특정 WIT에서 어떤 위젯이 활성화되는지만 정의하면 됩니다. 따라서 특정 작업 항목의 유형을 전환하면 다른 위젯 세트가 표시됩니다.

작업 항목 위젯과 새 위젯을 만드는 방법을 자세히 참고합니다.

위젯 메타데이터#

각 WIT를 해당 활성 위젯으로 커스터마이즈하려면 각 WIT를 특정 위젯에 매핑하는 데이터 구조가 필요합니다.

작업 항목 유형은 고도로 구성 가능해야 합니다. GitLab 이 고객을 위해 여러 작업 항목 체계를 구현할 때도(의견이 반영된 GitLab 워크플로, SAFe 5 등), 그리고 궁극적으로 고객이 자체 워크플로를 커스터마이즈할 때도 그렇습니다.

이 경우 작업 항목 체계는 에픽, 스토리, 버그, 태스크처럼 특정 특성을 갖는(일부 위젯은 활성화되고 일부는 활성화되지 않는) 유형의 집합으로 정의됩니다.

새 작업 항목 아키텍처를 구축하면서, 이러한 여러 유형을 매우 유연하게 정의하는 기능도 만들려고 합니다. GitLab 이 이 시스템을 먼저 사용하면(고객 커스터마이즈를 도입하지 않고) 초기 시스템을 더 잘 구축할 수 있습니다.

base_type 속성은 작업 항목의 근본적인 유형 분류(이슈, 에픽, 태스크 등)를 식별합니다. 이 속성이 기본 위젯 구성과 동작을 결정합니다.

커스텀 작업 항목 유형은 시스템 정의 유형의 base_type에 위임해 위젯 구성과 동작을 상속합니다. 이후 반복에서는 커스텀 유형에 대한 커스텀 위젯 선택을 지원할 예정입니다.

시스템 정의 작업 항목 유형 추가#

GitLab에 새 시스템 정의 작업 항목 유형을 추가하려면 다음 단계를 수행합니다.

  1. app/models/work_items/types_framework/system_defined/definitions/에 유형 구성, 위젯, 동작을 정의하는 정의 모듈을 만듭니다.
  2. 애플리케이션 시작 시 로드되도록 WorkItems::TypesFramework::SystemDefined::Type에 정의를 포함합니다.
  3. 가시성 상수에 추가 - UI와 API에서 해당 유형이 표시되는 위치를 제어하는 프론트엔드 및 백엔드 상수에 기본 유형을 추가합니다.

구체적인 구현 세부 사항은 Slack의 #g_project-management에서 Plan Project Management 팀에 문의합니다.

Warning

다음 예시 MR은 레거시 데이터베이스 기반 방식을 사용하므로 현재 구현과 다를 수 있습니다. 시스템 정의 유형 추가에 대한 최신 지침은 Slack의 #g_project-management에서 Plan Project Management 팀에 문의합니다.

이전 참조 MR:

유형 관계 정의#

유형 관계 정의(어떤 유형이 자식을 가질 수 있는지, 어떤 유형이 다른 유형과 연결될 수 있는지 등)는 유형 모듈 자체에 정의합니다. 모든 구성이 한곳에 있고 코드로 정의됩니다.

새 시스템 정의 유형을 만들 때는 다음 정의를 유형 모듈에 포함합니다.

  • 위젯 구성 - 이 유형에서 사용할 수 있는 위젯입니다.
  • 계층 제한 - 이 유형의 부모 또는 자식이 될 수 있는 유형과 최대 중첩 깊이입니다.
  • 연결 항목 제한 - 이 유형이 관련될 수 있거나 이 유형을 차단할 수 있는 유형입니다.

현재 관계 규칙은 app/models/work_items/types_framework/system_defined/definitions/의 개별 유형 정의 모듈을 참고합니다.

커스텀 위젯#

최종 목표는 사용자가 커스텀 위젯을 정의하고 이 커스텀 위젯을 어떤 WIT 에서든 사용할 수 있게 하는 것입니다. 다만 이는 훨씬 뒤의 반복이며, 사용할 데이터 아키텍처와 애플리케이션 아키텍처를 결정하기 위한 추가 조사가 필요합니다.

요구사항과 에픽을 작업 항목 유형으로 마이그레이션#

요구사항과 에픽을 자체 위젯 세트를 갖는 작업 항목 유형으로 마이그레이션합니다. 이를 위해 데이터를 issues 테이블로 마이그레이션하고, 이미 존재하는 참조와의 하위 호환성을 보장하기 위해 현재의 requirements 및 epics 테이블은 이전 참조용 프록시로 유지합니다.

요구사항을 작업 항목 유형으로 마이그레이션#

현재 Requirement 속성은 Issue 속성의 하위 집합이므로, 마이그레이션은 주로 다음으로 구성됩니다.

  • 데이터 마이그레이션.
  • API 수준에서 하위 호환성 유지.
  • 기존 참조가 계속 동작하도록 보장.

기반 데이터 구조를 바꾸는 마이그레이션은 최종 사용자가 알아차리지 못하게 이루어져야 합니다.

에픽을 작업 항목 유형으로 마이그레이션#

Epic에는 Issue WIT에 현재 없는 추가 기능이 일부 있습니다. 따라서 에픽을 작업 항목 유형으로 마이그레이션하려면 현재의 Epic 객체와 WIT 사이에 기능 동등성을 제공해야 합니다.

주요 누락 기능은 다음과 같습니다.

  • 작업 항목을 그룹 수준으로 올리기. 이는 그룹 및 프로젝트 통합 이니셔티브에 의존합니다.
  • 계층 위젯: 작업 항목을 계층 구조로 구성하는 기능.
  • 상속된 날짜 위젯.

이미 에픽을 사용하는 사용자의 워크플로를 방해하지 않기 위해, 프로젝트 수준에서 에픽과 기능 동등성을 제공하는 Feature라는 새 WIT를 도입합니다. 이를 그룹 및 프로젝트 통합 진행 상황과 결합하면, 사용자 워크플로 방해를 최소화하면서 에픽을 WIT로 원활하게 마이그레이션하는 경로를 제공하는 데 도움이 됩니다.

작업 항목 계측#

작업 항목 상호작용은 GitLab 내부 이벤트 시스템으로 추적되며, 이 데이터는 분석을 위해 Snowplow로 전달됩니다. 중앙화된 계측 아키텍처는 모든 작업 항목 유형과 상호작용에 걸쳐 일관된 추적을 제공합니다.

아키텍처 개요#

계측 시스템은 세 가지 주요 컴포넌트로 구성됩니다.

Mermaid 다이어그램 (21줄)
소스 코드 보기
graph LR
    accTitle: Work Items Instrumentation
    accDescr: Visualization of the flow between work item services and instrumentation.
    subgraph Services
        US[UpdateService]
        CS[CreateService]
        Other[Other Services]
    end
subgraph Instrumentation
    TS[TrackingService]
    EM[EventMappings]
    EA[EventActions]
end

US --&gt;|old_associations| TS
CS --&gt;|explicit event| TS
Other --&gt;|explicit event| TS
TS --&gt; EM
EM --&gt; EA
TS --&gt;|track_internal_event| IE[Internal Events]</code></pre></details></div>
컴포넌트 목적
EventActions 추적 가능한 모든 이벤트 상수를 정의합니다(예: work_item_create, work_item_title_update)
TrackingService 추적을 위한 통합 진입점입니다. 명시적 이벤트를 받거나 변경 사항에서 이벤트를 도출합니다
EventMappings 속성과 연관의 변경을 이벤트로 연결하는 선언적 매핑입니다

이벤트 속성#

모든 작업 항목 이벤트에는 세분화를 위한 표준 속성이 포함됩니다.

속성 설명
user 해당 액션을 수행하는 사용자
namespace 작업 항목이 속한 네임스페이스
project 작업 항목이 속한 프로젝트(해당하는 경우)
label 작업 항목 유형 이름(예: Issue, Epic, Task)
property 네임스페이스에서 해당 사용자의 권한

통합 패턴#

명시적 이벤트 추적#

생성, 삭제, 복제처럼 개별적인 액션에서는 이벤트를 직접 전달합니다.

Gitlab::WorkItems::Instrumentation::TrackingService.new(
  work_item: work_item,
  current_user: current_user,
  event: Gitlab::WorkItems::Instrumentation::EventActions::CREATE
).execute

파생 이벤트 추적#

여러 필드가 변경될 수 있는 업데이트에서는 이전 상태를 전달하고, 어떤 이벤트를 내보낼지는 EventMappings가 결정하게 합니다.

# In associations_before_update, capture state before changes
def associations_before_update(work_item)
  super.merge(
    confidential: work_item.confidential,
    # ... other associations
  )
end

# In after_update, track with old_associations
Gitlab::WorkItems::Instrumentation::TrackingService.new(
  work_item: work_item,
  current_user: current_user,
  old_associations: old_associations
).execute

현재 이벤트#

추적 가능한 작업 항목 이벤트의 전체 목록은 EventActions를 참고합니다.

새 이벤트 추가#

새 작업 항목 이벤트를 추가하려면 다음 단계를 수행합니다.

  1. 내부 이벤트 CLI로 이벤트와 메트릭을 정의합니다. 필요한 YAML 정의를 생성하려면 빠른 시작 가이드를 참고합니다.

  2. lib/gitlab/work_items/instrumentation/event_actions.rb에 이벤트 상수를 추가합니다.

    NEW_ACTION = 'work_item_new_action'
    
    ALL_EVENTS = [
      # ... existing events
      NEW_ACTION
    ].freeze
    
  3. (업데이트에서 파생된 이벤트만 해당) lib/gitlab/work_items/instrumentation/event_mappings.rb에 매핑을 추가합니다.

    속성이 변경되는 경우:

    ATTRIBUTE_MAPPINGS = [
      # ... existing mappings
      { event: EventActions::NEW_ACTION, key: 'attribute_name' }
    ].freeze
    

    연관이 변경되고 커스텀 비교 로직을 사용하는 경우:

    ASSOCIATION_MAPPINGS = [
      # ... existing mappings
      {
        event: EventActions::NEW_ACTION,
        key: :association_name,
        compare: ->(old, new) { old != new }
      }
    ].freeze
    
  4. 관련 서비스 클래스에서 추적 서비스를 호출합니다.

  5. 공유 예시를 사용해 스펙을 추가합니다.

    it_behaves_like 'tracks work item event', :work_item, :user, 'work_item_new_action'
    

YAML 정의가 준비된 뒤 새 이벤트 계측을 추가하는 최소 예시는 변경된 파일 5개와 +28줄만으로 이벤트 두 개를 추가한 MR !215447을 참고합니다.

관련 파일#

관련 주제#

작업 항목 및 작업 항목 유형

GitLab v19.4
원문 보기

요약

작업 항목은 GitLab의 이슈 추적 기능을 표준화하고 확장하는 유연한 모델을 도입합니다. 이슈는 협업의 중앙 허브가 될 가능성이 있습니다. 각 객체 유형이 별도의 모델로 갈라지는 대신, 포함하는 위젯(하나 이상의 속성)으로 커스터마이즈할 수 있는 공통 기반 모델로 표준화할 수 있습니다.

작업 항목은 GitLab의 이슈 추적 기능을 표준화하고 확장하는 유연한 모델을 도입합니다. 작업 항목에서는 여러 위젯으로 커스터마이즈할 수 있는 다양한 유형을 정의하여, 버그나 인시던트, 테스트 케이스 등 어떤 작업 단위를 추적하든 특정 요구를 충족할 수 있습니다. 이 아키텍처 문서는 작업 항목과 작업 항목 유형의 개발 세부 사항과 구현 전략을 다룹니다. 앞으로 진행할 작업의 대략적인 개요는 에픽 6033을 참고합니다.

과제#

이슈는 협업의 중앙 허브가 될 가능성이 있습니다. 각기 다른 이슈 유형은 어떤 작업을 수행하는 데 쓰이는지에 따라 서로 다른 필드와 서로 다른 컨텍스트가 필요하다는 사실을 받아들여야 합니다. 예를 들면 다음과 같습니다.

  • 버그에는 재현 단계를 나열해야 합니다.
  • 인시던트에는 스택 트레이스에 대한 참조와 해당 인시던트에만 관련된 그 밖의 컨텍스트 정보가 필요합니다.

각 객체 유형이 별도의 모델로 갈라지는 대신, 포함하는 위젯(하나 이상의 속성)으로 커스터마이즈할 수 있는 공통 기반 모델로 표준화할 수 있습니다.

현재 이슈 사용 방식의 문제점과 작업 항목을 검토하는 이유는 다음과 같습니다.

  • 레이블로 이슈 유형을 표시하는 방식은 번거롭고 보고 뷰를 더 복잡하게 만듭니다.

  • 이슈 유형은 레이블의 주요 사용 사례 두 가지 중 하나이므로, 이슈 유형에 일급 지원을 제공하는 것이 합리적입니다.

  • 이슈에 더 많은 기능을 추가하면서 이슈가 혼잡해지기 시작했고, 이슈는 완벽하지도 않습니다.

    • 다른 객체와의 관계를 표면화하는 방법에 일관된 패턴이 없습니다.
    • 이 부분에 레이블을 사용하기 때문에 서로 다른 이슈 유형 간에 일관된 상호작용 모델이 없습니다.
    • 이슈 유형의 여러 구현은 유연성과 확장성이 부족합니다.
  • 에픽, 이슈, 요구사항 등은 공통 상호작용에서 서로 비슷하지만 미묘하게 달라서, 사용자가 각각이 어떻게 동작하는지에 대한 복잡한 멘탈 모델을 유지해야 합니다.

  • 이슈는 이슈가 지원해야 하는 새로운 작업을 모두 수용할 만큼 확장 가능하지 않습니다.

  • Issue 유형을 이슈 추적이라는 핵심 역할을 넘어 여러 작업 항목 유형을 지원하고 로직과 구조의 차이를 처리하는 방향으로 키우면서, 코드베이스 유지 관리와 기능 개발이 더 큰 과제가 됩니다.

  • 새 기능은 보통 공유 관심사를 통해 이슈의 동작을 가져오는 일급 객체로 구현됩니다. 이는 중복된 노력으로 이어지고 결국 공통 상호작용 사이에 작은 차이를 만듭니다. 그 결과 UX가 일관되지 않습니다.

작업 항목 용어#

혼란을 방지하고 효율적인 커뮤니케이션을 보장하기 위해, 작업 항목을 논의할 때는 다음 용어만 사용합니다. 이 목록은 작업 항목 용어의 단일 진실 공급원(Single Source Of Truth, SSOT)입니다.

용어 설명 잘못된 사용 예 올바른 표현
work item type 작업 항목의 클래스입니다. 예: 이슈, 요구사항, 테스트 케이스, 인시던트, 태스크 에픽은 결국 이슈가 됩니다 에픽은 결국 work item type 이 됩니다
work item work item type의 인스턴스
work item view 모든 유형의 작업 항목을 렌더링하는 새 프론트엔드 뷰 이 항목은 새 뷰에서 렌더링되어야 합니다 이 항목은 work item view에서 렌더링되어야 합니다
legacy object 작업 항목 유형으로 전환되었거나 전환될 객체 에픽은 독립형·구형·이전 객체에서 work item type으로 마이그레이션됩니다 에픽은 legacy object에서 work item type으로 전환됩니다
legacy issue view 이슈와 인시던트를 렌더링하는 데 쓰이는 기존 뷰 이슈는 계속 구 뷰에서 렌더링됩니다 이슈는 계속 legacy issue view에서 렌더링됩니다
issue 기존 이슈 모델
issuable 현재 issuable 모듈을 사용하는 모든 모델(이슈, 에픽, MR) 인시던트는 issuable 입니다 인시던트는 work item type 입니다
widget 특정 작업 항목 데이터를 표시하거나 조작할 수 있게 하는 UI 요소

일부 용어는 과거에 사용했지만 이후 혼란을 일으켜 현재는 사용을 권장하지 않습니다.

용어 설명 잘못된 사용 예 올바른 표현
issue type 작업 항목의 클래스를 가리키던 이전 표현 태스크는 issue type 입니다 태스크는 work item type 입니다

마이그레이션 전략#

WI 모델은 기존 Issue 모델 위에 구축하며, Issue 모델 코드를 WI 모델로 점진적으로 마이그레이션합니다.

접근 방법 중 하나는 다음과 같습니다.

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 세트를 만드는 작업이 포함되며, 자세한 내용은 이 에픽에 설명되어 있습니다.

Note

처음에는 WIT 정의가 루트 수준 그룹에서만 가능하며, 이후 하위 그룹에 상속됩니다. 이후 반복에서 하위 그룹 수준에서 새 WIT를 정의할 수 있는지 검토할 예정입니다.

작업 항목 유형 아키텍처#

GitLab은 시스템 정의 유형과 커스텀 작업 항목 유형을 모두 지원하는 유연한 유형 시스템을 사용합니다. 이 아키텍처는 Cells 이니셔티브의 요구 사항을 충족하도록 설계되어, 셀 간 데이터베이스 쿼리 없이 효율적으로 유형을 조회할 수 있습니다. 아키텍처 배경은 구성 가능한 작업 항목 유형 설계 문서를 참고합니다.

시스템 정의 유형#

시스템 정의 유형은 GitLab에 내장된 사전 정의 작업 항목 유형입니다. 이 유형들은 코드에서 Ruby 모듈로 정의되며 시작 시 메모리에 로드됩니다.

사용 가능한 유형:

유형 ID 기본 유형 가용성 비고
Issue 1 issue CE + EE
Incident 2 incident CE + EE 전체 WIT로 전환 중
Test Case 3 test_case EE only 전체 WIT로 전환 중
Requirement 4 requirement EE only 전체 WIT로 전환 중
Task 5 task CE + EE
Objective 6 objective EE only 제거 예정
Key Result 7 key_result EE only 제거 예정
Epic 8 epic EE only
Ticket 9 ticket CE + EE

구현 세부 사항:

  • 모델: WorkItems::TypesFramework::SystemDefined::Type
  • 위치: app/models/work_items/types_framework/system_defined/
  • 각 유형은 definitions/에 정의 모듈이 있습니다(예: definitions/issue.rb)
  • 데이터베이스 쿼리 없이 ActiveRecord와 유사한 API를 제공하기 위해 ActiveRecord::FixedItemsModel을 사용합니다

유형 정의 예시:

module WorkItems::TypesFramework::SystemDefined::Definitions::Issue
  def self.configuration
    { id: 1, name: 'Issue', base_type: 'issue', icon_name: 'work-item-issue' }
  end

  def self.widgets
    %w[assignees description labels milestone notes ...]
  end

  def self.supports_move_action?
    true
  end
end

커스텀 작업 항목 유형#

커스텀 유형을 사용하면 조직과 네임스페이스가 자체 워크플로에 맞춘 작업 항목 유형을 만들 수 있습니다. 이 기능은 FY27 Q1에 제공될 예정입니다.

커스텀 유형은 다음 두 가지 방법으로 만들 수 있습니다.

  1. 완전히 새로운 커스텀 유형 - 시스템 정의 유형처럼 동작하지만 고유한 개념을 나타내는 완전히 새로운 유형(예: "Pizza")을 만듭니다. 이 유형은 기본적으로 Issue처럼 동작하지만 자체 정체성을 가집니다.
  2. 전환된 유형 - 기존 시스템 정의 유형을 전환해 커스텀 유형을 만듭니다. 커스텀 유형은 원래 시스템 정의 유형을 참조하고, 달라지는 속성(이름, 아이콘, 보관 상태)만 저장합니다. 그 밖의 동작과 위젯은 모두 참조한 시스템 정의 유형에서 상속됩니다.

구현 세부 사항:

  • 모델: WorkItems::TypesFramework::Custom::Type
  • 테이블: work_item_custom_types
  • 범위:
    • Self-Managed: 조직 수준(장기 타깃 범위)
    • SaaS (GitLab.com): 루트 그룹 수준(조직 수준 기능을 사용할 수 있게 될 때까지의 임시 방안)
  • 한도: 상위 범위당 한도이며, WorkItems::TypesFramework::Custom::Type::MAX_TYPE_PER_PARENT에 저장됩니다
Note

GitLab.com에서는 현재 모든 루트 그룹이 같은 조직에 속하므로 커스텀 유형의 범위가 루트 그룹으로 지정됩니다. SaaS에서 조직 수준 기능을 완전히 사용할 수 있게 되면, Self-Managed와 맞추기 위해 커스텀 유형이 조직 범위로 이동합니다.

전환된 유형:

시스템 정의 유형을 전환하면 커스텀 유형은 원본을 참조해 동작을 상속하면서 특정 항목을 커스터마이즈할 수 있습니다.

커스터마이즈 가능한 속성:

  • name - 커스텀 표시 이름(최대 48자)
  • icon_name - 커스텀 아이콘 선택
  • archived - 보관 상태

상속되는 속성:

  • 위젯 구성(향후 유형별 커스터마이즈 가능)
  • 기본 유형 동작
  • 계층 제한

예시:

조직이 시스템 정의 "Issue" 유형을 전환해 커스텀 "Bug" 유형을 만드는 경우입니다.

  • Issue의 모든 위젯과 동작을 상속합니다
  • 이름을 "Bug" 로 재정의합니다
  • 선택적으로 다른 아이콘을 사용합니다
  • converted_from_system_defined_type_identifier 칼럼을 통해 Issue 유형을 참조합니다

Provider 인터페이스#

WorkItems::TypesFramework::Provider 클래스는 작업 항목 유형에 접근하는 단일 진입점입니다. 모든 코드는 유형 클래스에 직접 접근하지 않고 Provider를 사용해야 합니다.

네임스페이스 컨텍스트:

Provider에 네임스페이스를 전달하는 일은 사용할 수 있는 유형을 결정하므로 매우 중요합니다.

  • 네임스페이스가 없는 경우: 시스템 정의 유형만 반환합니다(전역 유형 9개)
  • 네임스페이스가 있는 경우: 시스템 정의 유형과 함께, 다음에 대해 정의된 커스텀 유형(전환된 유형 또는 완전히 새로운 유형)을 반환합니다
    • Self-Managed: 해당 네임스페이스의 조직
    • SaaS (GitLab.com): 해당 네임스페이스를 포함하는 루트 그룹

Provider는 단일 요청 안에서 빠르게 조회하기 위해 요청 저장소에 유형을 캐시하므로, 커스텀 유형을 반복해서 쿼리하지 않습니다.

사용법:

# Initialize with namespace context
provider = WorkItems::TypesFramework::Provider.new(namespace)

# Fetch types
provider.all                           # All available types
provider.filtered_types                # Types available to namespace
provider.find_by_base_type(:issue)     # Find by base type
provider.find_by_id(1)                 # Find by ID
provider.default_issue_type            # Get default issue type

관련 파일:

이전 배경#

GitLab 18.1 이전에는 작업 항목 유형을 work_item_types 데이터베이스 테이블에 저장했습니다. 이 방식은 Cells 이니셔티브를 지원하기 위해 현재의 시스템 정의 유형 아키텍처로 대체되었습니다.

작업 항목 유형 위젯#

위젯은 작업 항목에 존재할 수 있는 단일 컴포넌트입니다. 이 컴포넌트는 하나 또는 여러 작업 항목 유형에서 사용할 수 있고, 구현 지점에서 가볍게 커스터마이즈할 수 있습니다.

위젯에는 프론트엔드 UI(있는 경우)와 위젯이 사용하는 데이터를 표시하고 관리하는 관련 로직이 모두 들어 있습니다. 데이터 모델과 위젯 사이에는 일대다 연결이 있을 수 있습니다. 즉 같은 데이터를 사용하거나 관리하는 위젯이 여러 개 있을 수 있고, 이들이 동시에 존재할 수도 있습니다(예: 읽기 전용 요약 위젯과 편집 가능한 세부 정보 위젯, 또는 같은 모델의 서로 다른 필터링 뷰 두 개를 보여 주는 위젯 두 개).

위젯은 목적에 따라 구분해야 합니다. 가능하다면 이 목적은 재사용성을 극대화하기 위해 합리적인 범위에서 가장 높은 수준으로 추상화해야 합니다. 예를 들어 "태스크" 를 관리하는 위젯은 "하위 항목" 으로 구축했습니다. 한 가지 유형의 자식을 관리하는 대신, 모든 자식을 관리하도록 추상화한 것입니다.

모든 WIT는 사전 정의된 위젯 풀을 공유하며, 특정 WIT에서 어떤 위젯이 활성화되어 있는지에 따라 커스터마이즈됩니다. 모든 속성(칼럼 또는 연관)은 속한 WIT와 무관하게 자체 캡슐화된 기능을 갖는 위젯이 됩니다. 어떤 WIT 든 어떤 위젯이든 가질 수 있으므로, 특정 WIT에서 어떤 위젯이 활성화되는지만 정의하면 됩니다. 따라서 특정 작업 항목의 유형을 전환하면 다른 위젯 세트가 표시됩니다.

작업 항목 위젯과 새 위젯을 만드는 방법을 자세히 참고합니다.

위젯 메타데이터#

각 WIT를 해당 활성 위젯으로 커스터마이즈하려면 각 WIT를 특정 위젯에 매핑하는 데이터 구조가 필요합니다.

작업 항목 유형은 고도로 구성 가능해야 합니다. GitLab 이 고객을 위해 여러 작업 항목 체계를 구현할 때도(의견이 반영된 GitLab 워크플로, SAFe 5 등), 그리고 궁극적으로 고객이 자체 워크플로를 커스터마이즈할 때도 그렇습니다.

이 경우 작업 항목 체계는 에픽, 스토리, 버그, 태스크처럼 특정 특성을 갖는(일부 위젯은 활성화되고 일부는 활성화되지 않는) 유형의 집합으로 정의됩니다.

새 작업 항목 아키텍처를 구축하면서, 이러한 여러 유형을 매우 유연하게 정의하는 기능도 만들려고 합니다. GitLab 이 이 시스템을 먼저 사용하면(고객 커스터마이즈를 도입하지 않고) 초기 시스템을 더 잘 구축할 수 있습니다.

base_type 속성은 작업 항목의 근본적인 유형 분류(이슈, 에픽, 태스크 등)를 식별합니다. 이 속성이 기본 위젯 구성과 동작을 결정합니다.

커스텀 작업 항목 유형은 시스템 정의 유형의 base_type에 위임해 위젯 구성과 동작을 상속합니다. 이후 반복에서는 커스텀 유형에 대한 커스텀 위젯 선택을 지원할 예정입니다.

시스템 정의 작업 항목 유형 추가#

GitLab에 새 시스템 정의 작업 항목 유형을 추가하려면 다음 단계를 수행합니다.

  1. app/models/work_items/types_framework/system_defined/definitions/에 유형 구성, 위젯, 동작을 정의하는 정의 모듈을 만듭니다.
  2. 애플리케이션 시작 시 로드되도록 WorkItems::TypesFramework::SystemDefined::Type에 정의를 포함합니다.
  3. 가시성 상수에 추가 - UI와 API에서 해당 유형이 표시되는 위치를 제어하는 프론트엔드 및 백엔드 상수에 기본 유형을 추가합니다.

구체적인 구현 세부 사항은 Slack의 #g_project-management에서 Plan Project Management 팀에 문의합니다.

Warning

다음 예시 MR은 레거시 데이터베이스 기반 방식을 사용하므로 현재 구현과 다를 수 있습니다. 시스템 정의 유형 추가에 대한 최신 지침은 Slack의 #g_project-management에서 Plan Project Management 팀에 문의합니다.

이전 참조 MR:

유형 관계 정의#

유형 관계 정의(어떤 유형이 자식을 가질 수 있는지, 어떤 유형이 다른 유형과 연결될 수 있는지 등)는 유형 모듈 자체에 정의합니다. 모든 구성이 한곳에 있고 코드로 정의됩니다.

새 시스템 정의 유형을 만들 때는 다음 정의를 유형 모듈에 포함합니다.

  • 위젯 구성 - 이 유형에서 사용할 수 있는 위젯입니다.
  • 계층 제한 - 이 유형의 부모 또는 자식이 될 수 있는 유형과 최대 중첩 깊이입니다.
  • 연결 항목 제한 - 이 유형이 관련될 수 있거나 이 유형을 차단할 수 있는 유형입니다.

현재 관계 규칙은 app/models/work_items/types_framework/system_defined/definitions/의 개별 유형 정의 모듈을 참고합니다.

커스텀 위젯#

최종 목표는 사용자가 커스텀 위젯을 정의하고 이 커스텀 위젯을 어떤 WIT 에서든 사용할 수 있게 하는 것입니다. 다만 이는 훨씬 뒤의 반복이며, 사용할 데이터 아키텍처와 애플리케이션 아키텍처를 결정하기 위한 추가 조사가 필요합니다.

요구사항과 에픽을 작업 항목 유형으로 마이그레이션#

요구사항과 에픽을 자체 위젯 세트를 갖는 작업 항목 유형으로 마이그레이션합니다. 이를 위해 데이터를 issues 테이블로 마이그레이션하고, 이미 존재하는 참조와의 하위 호환성을 보장하기 위해 현재의 requirements 및 epics 테이블은 이전 참조용 프록시로 유지합니다.

요구사항을 작업 항목 유형으로 마이그레이션#

현재 Requirement 속성은 Issue 속성의 하위 집합이므로, 마이그레이션은 주로 다음으로 구성됩니다.

  • 데이터 마이그레이션.
  • API 수준에서 하위 호환성 유지.
  • 기존 참조가 계속 동작하도록 보장.

기반 데이터 구조를 바꾸는 마이그레이션은 최종 사용자가 알아차리지 못하게 이루어져야 합니다.

에픽을 작업 항목 유형으로 마이그레이션#

Epic에는 Issue WIT에 현재 없는 추가 기능이 일부 있습니다. 따라서 에픽을 작업 항목 유형으로 마이그레이션하려면 현재의 Epic 객체와 WIT 사이에 기능 동등성을 제공해야 합니다.

주요 누락 기능은 다음과 같습니다.

  • 작업 항목을 그룹 수준으로 올리기. 이는 그룹 및 프로젝트 통합 이니셔티브에 의존합니다.
  • 계층 위젯: 작업 항목을 계층 구조로 구성하는 기능.
  • 상속된 날짜 위젯.

이미 에픽을 사용하는 사용자의 워크플로를 방해하지 않기 위해, 프로젝트 수준에서 에픽과 기능 동등성을 제공하는 Feature라는 새 WIT를 도입합니다. 이를 그룹 및 프로젝트 통합 진행 상황과 결합하면, 사용자 워크플로 방해를 최소화하면서 에픽을 WIT로 원활하게 마이그레이션하는 경로를 제공하는 데 도움이 됩니다.

작업 항목 계측#

작업 항목 상호작용은 GitLab 내부 이벤트 시스템으로 추적되며, 이 데이터는 분석을 위해 Snowplow로 전달됩니다. 중앙화된 계측 아키텍처는 모든 작업 항목 유형과 상호작용에 걸쳐 일관된 추적을 제공합니다.

아키텍처 개요#

계측 시스템은 세 가지 주요 컴포넌트로 구성됩니다.

Mermaid 다이어그램 (21줄)
소스 코드 보기
graph LR
    accTitle: Work Items Instrumentation
    accDescr: Visualization of the flow between work item services and instrumentation.
    subgraph Services
        US[UpdateService]
        CS[CreateService]
        Other[Other Services]
    end
subgraph Instrumentation
    TS[TrackingService]
    EM[EventMappings]
    EA[EventActions]
end

US --&gt;|old_associations| TS
CS --&gt;|explicit event| TS
Other --&gt;|explicit event| TS
TS --&gt; EM
EM --&gt; EA
TS --&gt;|track_internal_event| IE[Internal Events]</code></pre></details></div>
컴포넌트 목적
EventActions 추적 가능한 모든 이벤트 상수를 정의합니다(예: work_item_create, work_item_title_update)
TrackingService 추적을 위한 통합 진입점입니다. 명시적 이벤트를 받거나 변경 사항에서 이벤트를 도출합니다
EventMappings 속성과 연관의 변경을 이벤트로 연결하는 선언적 매핑입니다

이벤트 속성#

모든 작업 항목 이벤트에는 세분화를 위한 표준 속성이 포함됩니다.

속성 설명
user 해당 액션을 수행하는 사용자
namespace 작업 항목이 속한 네임스페이스
project 작업 항목이 속한 프로젝트(해당하는 경우)
label 작업 항목 유형 이름(예: Issue, Epic, Task)
property 네임스페이스에서 해당 사용자의 권한

통합 패턴#

명시적 이벤트 추적#

생성, 삭제, 복제처럼 개별적인 액션에서는 이벤트를 직접 전달합니다.

Gitlab::WorkItems::Instrumentation::TrackingService.new(
  work_item: work_item,
  current_user: current_user,
  event: Gitlab::WorkItems::Instrumentation::EventActions::CREATE
).execute

파생 이벤트 추적#

여러 필드가 변경될 수 있는 업데이트에서는 이전 상태를 전달하고, 어떤 이벤트를 내보낼지는 EventMappings가 결정하게 합니다.

# In associations_before_update, capture state before changes
def associations_before_update(work_item)
  super.merge(
    confidential: work_item.confidential,
    # ... other associations
  )
end

# In after_update, track with old_associations
Gitlab::WorkItems::Instrumentation::TrackingService.new(
  work_item: work_item,
  current_user: current_user,
  old_associations: old_associations
).execute

현재 이벤트#

추적 가능한 작업 항목 이벤트의 전체 목록은 EventActions를 참고합니다.

새 이벤트 추가#

새 작업 항목 이벤트를 추가하려면 다음 단계를 수행합니다.

  1. 내부 이벤트 CLI로 이벤트와 메트릭을 정의합니다. 필요한 YAML 정의를 생성하려면 빠른 시작 가이드를 참고합니다.

  2. lib/gitlab/work_items/instrumentation/event_actions.rb에 이벤트 상수를 추가합니다.

    NEW_ACTION = 'work_item_new_action'
    
    ALL_EVENTS = [
      # ... existing events
      NEW_ACTION
    ].freeze
    
  3. (업데이트에서 파생된 이벤트만 해당) lib/gitlab/work_items/instrumentation/event_mappings.rb에 매핑을 추가합니다.

    속성이 변경되는 경우:

    ATTRIBUTE_MAPPINGS = [
      # ... existing mappings
      { event: EventActions::NEW_ACTION, key: 'attribute_name' }
    ].freeze
    

    연관이 변경되고 커스텀 비교 로직을 사용하는 경우:

    ASSOCIATION_MAPPINGS = [
      # ... existing mappings
      {
        event: EventActions::NEW_ACTION,
        key: :association_name,
        compare: ->(old, new) { old != new }
      }
    ].freeze
    
  4. 관련 서비스 클래스에서 추적 서비스를 호출합니다.

  5. 공유 예시를 사용해 스펙을 추가합니다.

    it_behaves_like 'tracks work item event', :work_item, :user, 'work_item_new_action'
    

YAML 정의가 준비된 뒤 새 이벤트 계측을 추가하는 최소 예시는 변경된 파일 5개와 +28줄만으로 이벤트 두 개를 추가한 MR !215447을 참고합니다.

관련 파일#

관련 주제#