markdown # 가치 스트림 분석 개발 가이드라인

가치 스트림 분석(VSA)을 구성하는 방법에 대한 정보는 GitLab의 분석 문서를 참조하세요.

가치 스트림 분석이 작동하는 방식

가치 스트림 분석은 두 개의 타임스탬프 열 또는 타임스탬프 표현 사이의 기간을 계산하고 데이터에 대해 다양한 집계를 실행합니다.

예를 들어:

  • Merge Request 생성 시간과 Merge Request Merge 시간 간의 기간.
  • 이슈 생성 시간과 이슈 종료 시간 간의 기간.

이 기간은 다양한 방식으로 노출됩니다:

  • 집계: 중앙값, 평균
  • 디렉터리: 개별 Merge Request 및 이슈 레코드의 기간 나열

기간 외에도 단계 내에서 레코드 수를 노출합니다.

기능 가용성

  • 그룹 레벨(라이선스가 필요함): Ultimate 또는 Premium 구독이 필요합니다. 이 버전이 가장 많은 기능을 제공합니다.
  • 프로젝트 레벨(라이선스가 필요함): 프로젝트 레벨 VSA에 기능을 지속적으로 추가하여 그룹 레벨 VSA와 동일하게 유지하고 있습니다.
  • 프로젝트 레벨(FOSS): 현재 상태를 유지합니다.
기능 그룹 레벨(라이선스가 필요함) 프로젝트 레벨(라이선스가 필요함) 프로젝트 레벨(FOSS)
사용자 정의 가치 스트림 생성 기본 단계를 사용하여 기본값이 하나만 존재합니다. 기본 단계를 사용하여 기본값이 하나만 존재합니다.
사용자 정의 단계 생성 아니요 아니요
필터링(작성자, 라벨, 마일스톤 등)
단계 시간 차트 아니요 아니요
전체 시간 차트 아니요 아니요
유형별 태스크 차트 아니요 아니요
DORA 지표 아니요
사이클 타임 및 리드 타임 요약(수명 주기 지표) 아니요
새 이슈, 커밋 및 배포(수명 주기 지표) 커밋 제외하고 예
집계된 백앤드 사용 아니요 아니요
날짜 필터 동작 날짜 범위 내에서 완료된 항목을 필터링함](https://gitlab.com/groups/gitlab-org/-/epics/6046) 생성 날짜별로 항목을 필터링함 생성 날짜별로 항목을 필터링함
인증 최소한의 기자 이상 최소한의 기자 이상 공개될 수 있음.

VSA 핵심 도메인 객체

단계

단계는 추가 메타데이터(단계의 이름과 같은)와 함께 이벤트 쌍(시작 및 종료 이벤트)를 나타냅니다. 단계는 백앤드에서 정의한 페어링 규칙 내에서 사용자가 구성할 수 있습니다.

예시 단계: 코드 리뷰

  • 시작 이벤트 식별자: Merge Request 생성 시간.
  • 시작 이벤트 열: merge_requests.created_at 타임스탬프 열을 사용합니다.
  • 종료 이벤트 식별자: Merge Request Merge 시간.
  • 종료 이벤트 열: merge_request_metrics.merged_at 타임스탬프 열을 사용합니다.
  • 단계 이벤트 해시 ID: 시작 및 종료 이벤트 식별자의 쌍에 대해 계산된 해시입니다.
    • 두 단계가 시작 및 종료 이벤트의 구성이 동일하면 그들의 단계 이벤트 해시 ID는 동일합니다.
    • 단계 이벤트 해시 ID는 후에 분할된 데이터를 저장하기 위해 사용됩니다.

과거에 가치 스트림 분석은 여섯 단계를 정의했으며, 구독 여부에 관계없이 최종 사용자에게 항상 사용 가능합니다.

가치 스트림

가치 스트림은 단계의 컨테이너 객체입니다. DevOps 수명 주기의 다른 측면에 중점을 둔 여러 개의 가치 스트림이 그룹 내에 있을 수 있습니다.

이벤트

이벤트는 가치 스트림 분석 기능의 가장 작은 컴포넌트입니다. 단계는 두 가지 이벤트로 구성됩니다:

  • 시작 이벤트
  • 종료 이벤트

이러한 이벤트들은 기간 계산에 중요한 역할을 합니다.

수식: 기간 = 종료 이벤트 시간 - 시작 이벤트 시간

기간 계산을 유연하게 만들기 위해 각 이벤트는 별도의 클래스로 구현됩니다. 그들은 계산 쿼리에서 사용되는 타임스탬프 표현을 정의하는 책임을 지고 있습니다.

이벤트 클래스 구현

StageEvent 기본 클래스에서 설명된 몇 가지 메서드를 구현해야 합니다. 가장 중요한 메서드는:

  • object_type
  • timestamp_projection

object_type 메서드는 계산을 위해 쿼리되는 도메인 객체를 정의합니다. 현재 두 모델이 허용됩니다:

  • 이슈
  • Merge Request

기간 계산을 위해 timestamp_projection 메서드가 사용됩니다.

def timestamp_projection
  # 여기에 타임스탬프 표현을 입력하세요
end

보다 복잡한 표현 또한 가능합니다(예: COALESCE 사용). 예제를 보기 위해 기존의 이벤트 클래스를 검토하세요.

경우에 따라 timestamp_projection 메서드를 정의하는 것만으로 충분하지 않을 수 있습니다. 계산 쿼리가 타임스탬프 표현을 포함하는 테이블을 알아야합니다. 각 이벤트 클래스는 timestamp_projection을 작동하게 만들기 위해 계산 쿼리에 수정을 가하는 책임이 있습니다. 이는 일반적으로 추가 테이블을 조인하는 것을 의미합니다.

issue_metrics 테이블을 조인하고 first_mentioned_in_commit_at 열을 타임스탬프 표현으로 사용하는 예제:

def object_type
  이슈
end

def timestamp_projection
  IssueMetrics.arel_table[:first_mentioned_in_commit_at]
end

def apply_query_customization(query)
  # 이 경우 쿼리 속성은 Issue 모델을 기반으로 함: `Issue.where(...)`
  query.joins(:metrics)
end

시작 및 종료 이벤트 유효성 검사

일부 시작/종료 이벤트 쌍은 서로 “호환되지” 않을 수 있습니다. 예를 들어:

  • “이슈 생성”에서 “Merge Request 생성”: 이벤트 클래스가 다른 도메인 모델에 정의되어 있으므로 object_type 메서드가 다릅니다.
  • “이슈 종료”에서 “이슈 생성”: 이슈는 종료되기 전에 생성되어 있어야 합니다.
  • “이슈 종료”에서 “이슈 종료”: 기간은 항상 0입니다.

StageEvents 모듈은 허용된 시작 이벤트종료 이벤트 쌍을 설명합니다(PAIRING_RULES 상수). 새 이벤트를 추가하려면:

  1. Stage 모델에서 enum으로 사용되는 고유한 숫자로 ENUM_MAPPING에 항목을 추가하세요.
  2. PAIRING_RULES 해시에 이벤트와 호환되는 이벤트를 정의하세요.

지원되는 시작/종료 이벤트 쌍:

graph LR; 이슈생성 --> 이슈종료; 이슈생성 --> 첫번째 게시판에 추가된 이슈; 이슈생성 --> 마일스톤과 처음으로 연결된 이슈; 이슈생성 --> 커밋에서 처음 언급된 이슈; 이슈생성 --> 마지막으로 편집된 이슈; 이슈생성 --> 라벨이 추가된 이슈; 이슈생성 --> 라벨이 제거된 이슈; 이슈생성 --> 처음으로 할당된 이슈; Merge요청생성 --> Merge된 Merge Request; Merge요청생성 --> Merge Request 닫힘; Merge요청생성 --> 처음으로 프로덕션에 배포된 Merge Request; Merge요청생성 --> 마지막으로 빌드가 시작된 Merge Request; Merge요청생성 --> 마지막으로 빌드 완료된 Merge Request; Merge요청생성 --> 마지막으로 편집된 Merge Request; Merge요청생성 --> 라벨이 추가된 Merge Request; Merge요청생성 --> 라벨이 제거된 Merge Request; Merge요청생성 --> 처음으로 할당된 Merge Request; 처음으로 할당된 Merge요청 --> Merge Request 닫힘; 처음으로 할당된 Merge요청 --> 마지막으로 빌드가 시작된 Merge Request; 처음으로 할당된 Merge요청 --> 마지막으로 편집된 Merge Request; 처음으로 할당된 Merge요청 --> Merge된 Merge Request; 처음으로 할당된 Merge요청 --> 라벨이 추가된 Merge Request; 처음으로 할당된 Merge요청 --> 라벨이 제거된 Merge Request; 마지막으로 빌드가 시작된 Merge요청 --> 마지막으로 빌드가 완료된 Merge Request; 마지막으로 빌드가 시작된 Merge요청 --> Merge Request 닫힘; 마지막으로 빌드가 시작된 Merge요청 --> 처음으로 프로덕션에 배포된 Merge Request; 마지막으로 빌드가 시작된 Merge요청 --> 마지막으로 편집된 Merge Request; 마지막으로 빌드가 시작된 Merge요청 --> Merge된 Merge Request; 마지막으로 빌드가 시작된 Merge요청 --> 라벨이 추가된 Merge Request; 마지막으로 빌드가 시작된 Merge요청 --> 라벨이 제거된 Merge Request; Merge된 Merge요청 --> 처음으로 프로덕션에 배포된 Merge Request; Merge된 Merge요청 --> Merge Request 닫힘; Merge된 Merge요청 --> 처음으로 프로덕션에 배포된 Merge Request; Merge된 Merge요청 --> 마지막으로 편집된 Merge Request; Merge된 Merge요청 --> 라벨이 추가된 Merge Request; Merge된 Merge요청 --> 라벨이 제거된 Merge Request; 이슈에 라벨이 추가됨 --> 이슈에 라벨이 추가됨; 이슈에 라벨이 추가됨 --> 이슈에 라벨이 제거됨; 이슈에 라벨이 추가됨 --> 이슈종료; 이슈에 라벨이 추가됨 --> 처음으로 할당된 이슈; 이슈에 라벨이 제거됨 --> 이슈종료; 이슈에 라벨이 제거됨 --> 처음으로 할당된 이슈; 처음으로 게시판에 추가된 이슈 --> 이슈종료; 처음으로 게시판에 추가된 이슈 --> 마일스톤과 처음으로 연결된 이슈; 처음으로 게시판에 추가된 이슈 --> 커밋에서 처음 언급된 이슈; 처음으로 게시판에 추가된 이슈 --> 마지막으로 편집된 이슈; 처음으로 게시판에 추가된 이슈 --> 라벨이 추가된 이슈; 처음으로 게시판에 추가된 이슈 --> 라벨이 제거된 이슈; 처음으로 게시판에 추가된 이슈 --> 처음으로 할당된 이슈; 처음으로 할당된 이슈 --> 이슈종료; 처음으로 할당된 이슈 --> 처음으로 게시판에 추가된 이슈; 처음으로 할당된 이슈 --> 마일스톤과 처음으로 연결된 이슈; 처음으로 할당된 이슈 --> 커밋에서 처음 언급된 이슈; 처음으로 할당된 이슈 --> 마지막으로 편집된 이슈; 처음으로 할당된 이슈 --> 라벨이 추가된 이슈; 처음으로 할당된 이슈 --> 라벨이 제거된 이슈; 마일스톤과 처음으로 연결된 이슈 --> 이슈종료; 마일스톤과 처음으로 연결된 이슈 --> 처음으로 게시판에 추가 ## 기본 단계 [원래 구현](https://gitlab.com/gitlab-org/gitlab/-/issues/847)에서 값 스트림 분석의 7단계가 정의되었습니다. 이러한 단계는 항상 각 상위에 대해 사용 가능하지만, 이러한 단계를 변경하는 것은 불가능합니다. 작업을 효율적으로 하고 생성된 레코드 수를 줄이기 위해 기본 단계는 인메모리 객체로 표현됩니다(지속되지 않음). 사용자가 처음으로 사용자 정의 단계를 만드는 경우 모든 단계가 지속됩니다. 이 동작은 값 스트림 분석 서비스 객체에 구현되어 있습니다. 이것의 이유는 나중에 단계를 숨기고 정렬하는 기능을 추가하고자 했기 때문입니다. ## 데이터 수집기 `DataCollector`는 데이터가 데이터베이스에서 쿼리되는 중심 지점입니다. 이 클래스는 항상 단일 단계에서 작동하며 다음 컴포넌트로 구성됩니다. - `BaseQueryBuilder`: - 초기 쿼리 작성을 담당합니다. - `Stage`별 구성: 이벤트 및 사용자 정의 쿼리 구성. - UI에서 오는 매개변수: 날짜 범위. - `Median`: `BaseQueryBuilder`의 쿼리를 사용하여 단계에 대한 중앙값 기간을 계산합니다. - `RecordsFetcher`: `BaseQueryBuilder`의 쿼리 및 가시성 규칙을 적용하기 위해 특정 `Finder` 클래스를 사용하여 단계에 대한 관련 레코드를 로드합니다. - `DataForDurationChart`: 산포도 차트에 마무리 시간(종료 이벤트 타임스탬프)과 함께 계산된 기간을 로드합니다. 새로운 계산 또는 쿼리를 지원하려면 `DataCollector` 클래스에 새로운 메서드 호출로 구현하십시오. 집계 값 스트림 분석 백엔드를 지원하기 위해 이러한 클래스들은 [`집계된`](https://gitlab.com/gitlab-org/gitlab/-/tree/master/lib/gitlab/analytics/cycle_analytics/aggregated) 네임스페이스 내에서 다시 구현되었습니다. ### 데이터베이스 쿼리 백엔드 VSA는 두 가지 백엔드를 지원합니다: [집계](value_stream_analytics/value_stream_analytics_aggregated_backend.md) 및 "라이브". 라이브 쿼리 백엔드는 어느 시점에서 폐기될 것으로 간주될 수 있습니다. - "라이브": 표준 `IssuableFinders`를 사용합니다. - 집계: 사전 집계된 데이터베이스 테이블에서 데이터를 쿼리합니다. ## 상위 수준 개요 - Rails 컨트롤러(`Analytics::CycleAnalytics` 모듈): 값 스트림 분석은 `analytics` 작업 영역 내에 구현된 JSON 엔드포인트를 통해 데이터를 노출시킵니다. 단계 구성 또한 JSON 엔드포인트(CRUD)에서 구현됩니다. - 서비스(`Analytics::CycleAnalytics` 모듈): 모든 `Stage` 관련 작업은 해당 서비스 객체로 위임됩니다. - 모델(`Analytics::CycleAnalytics` 모듈): 모델은 `Stage` 객체를 지속시키는 데 사용됩니다. - 피처 클래스(`Gitlab::Analytics::CycleAnalytics` 모듈): - 쿼리 작성 및 피처별 비즈니스 로직 정의를 담당합니다. - `DataCollector`, `Event`, `StageEvents` 등. ## 프론트엔드 [프로젝트 VSA](../user/group/value_stream_analytics/index.md)는 모든 사용자에게 제공되며 다음을 포함합니다: - 티어에 따라 키 및 DORA 메트릭의 혼합 사용. - [기본 단계](#default-stages) 세트 사용. [그룹 VSA](../user/group/value_stream_analytics/index.md)는 라이선스 사용자에게만 제공되며 다음을 포함합니다: - [개요 단계](https://gitlab.com/gitlab-org/gitlab/-/issues/321438). - 사용자 정의 값 스트림을 만들 수 있는 기능. 그룹 및 프로젝트 레벨 VSA 프론트엔드는 모두 Vue 및 Vuex로 프로덕션되었으며 유사한 패턴을 따릅니다: - `index.js` 파일은 URL 쿼리 매개변수를 추출하고 Vue 앱 및 Vuex 스토어를 생성하여 `initialize` Vuex 액션을 디스패치합니다. - `base.vue` 파일은 각 페이지, 메트릭, 필터, 차트 및 단계 테이블을 렌더링하는 데 사용됩니다. 그룹 VSA Vuex 스토어는 [Vuex 모듈](https://vuex.vuejs.org/guide/modules.html)을 사용하여 차트 렌더링에 사용되는 일부 상태와 로직을 분리합니다. ### 공유 컴포넌트 단계 테이블 및 경로와 같은 일부 UI는 프로젝트 VSA 및 그룹 VSA 간에 공유됩니다. 이러한 공유 컴포넌트는 프로젝트 VSA 디렉터리 `app/assets/javascripts/cycle_analytics/components`에 있으며 필요한 경우 그룹 레벨 VSA에 포함됩니다. 그룹 레벨 기능을 위한 모든 프론트엔드 코드는 `ee/app/assets/javascripts/analytics/cycle_analytics/components`에 위치합니다. ## 테스트 많은 이벤트와 가능한 페어링이 있기 때문에 각 페어링을 테스트하는 것은 불가능합니다. 각 페어링에 대해 한 가지 이상의 테스트 케이스가 있는 것이 규칙입니다. 새로운 `Event`를 사용하여 단계에 대한 테스트 케이스를 작성하는 것은 데이터를 두 번 생성해야 하기 때문에 어려울 수 있습니다. 이를 약간 단순화하기 위해 각 테스트 케이스는 `DataCollector`를 통해 구현되어야 하며 다음 사항을 다루는 여러 테스트로 전환되어야 합니다. - 다른 상위: `그룹` 또는 `프로젝트` - 다른 계산: `중앙값`, `RecordsFetcher` 또는 `DataForDurationChart` VSA 프론트엔드는 두 가지 다른 수준(통합, 단위)에서 철저하게 테스트됩니다. - 캐피바라 및 RSpec을 통해 실제 백엔드를 사용한 종단간 통합 테스트. - 사전 생성된 데이터 픽스처를 사용한 Jest 프론트엔드 테스트. ## 개발 설정 및 테스트 값 스트림 분석 실행은 [GDK](https://gitlab.com/gitlab-org/gitlab-development-kit)를 통해 수행할 수 있습니다. 기본적으로 프로젝트-레벨(FOSS) 버전의 기능을 볼 수 있습니다. GDK가 실행 중인 경우 시드 스크립트를 실행하여 일부 데이터를 생성할 수 있습니다: ```shell SEED_CYCLE_ANALYTICS=true SEED_VSA=true FILTER=cycle_analytics rake db:seed_fu

데이터 생성기 스크립트는 이슈 및 Merge Request 데이터가 있는 새로운 그룹 및 프로젝트를 만듭니다(스크립트의 출력 참조). 기능의 그룹-레벨 버전을 보려면 GDK 인스턴스에 라이선스를 요청해야 합니다.

이 단계 이후에 단계 및 값 스트림을 만들 수 있는 그룹 레벨 값 스트림 분석 페이지에 액세스할 수 있습니다. 데이터 집계가 지연될 수 있기 때문에, 단계 생성 후에는 데이터를 바로 볼 수 없을 수 있습니다. 이 프로세스를 가속화하기 위해 Rails 콘솔(rails c)에서 다음 명령을 실행할 수 있습니다:

Analytics::CycleAnalytics::ReaggregationWorker.new.perform

시드 데이터

값 스트림 분석

값 스트림 분석을 위한 데이터를 생성하는 방법에 대한 지침은 개발 시드 파일을 참조하십시오.