This page contains information related to upcoming products, features, and functionality. It is important to note that the information presented is for informational purposes only. Please do not rely on this information for purchasing or planning purposes. The development, release, and timing of any products, features, or functionality may be subject to change or delay and remain at the sole discretion of GitLab Inc.
Status Authors Coach DRIs Owning Stage Created
proposed @vshumilo @vitallium @tgolubeva @jameslopez devops fulfillment 2024-02-07

고객닷 플랜 관리 자동화

요약

GitLab Customers Portal은 GitLab 제품과 별개로 독립적으로 설계된 애플리케이션으로, GitLab 고객이 계정, 구독, 추가 좌석 구매 및 갱신과 같은 작업을 수행할 수 있도록하는 것이 목표입니다. 고객 포털에 대한 자세한 정보는 GitLab 문서에서 찾을 수 있습니다. 내부적으로 이 애플리케이션은 CustomersDot(또는 CDot)으로 알려져 있습니다.

GitLab은 모든 제품 관련 정보를 위한 단일 진실 공급원 소스(SSoT)로 Zuora 플랫폼을 사용합니다. Zuora 제품 카탈로그는 GitLab이 판매하거나 판매된 모든 수익 창출 제품 및 서비스의 전체 디렉터리을 나타내며, 이는 CustomersDot의 결정에 핵심적인 지식입니다. CustomersDot은 현재 IronBank gem 및 그 LocalRecord 확장을 통해 Zuora 제품 카탈로그의 로컬 캐시를 보유하고 있습니다.

CustomersDot은 Plan을 사용하여 제품 카탈로그의 모든 세부 정보에 쉽게 액세스할 수 있도록 설계된 래퍼 클래스로 사용합니다. 제품 이름, 가격, 최소 수량 등은 Zuora::ProductRatePlan, Zuora::ProductRatePlanCharge, Zuora::ProductRatePlanChargeTier 객체에 분산되어 있으며, 이러한 세부 정보에 대한 전통적인 액세스는 번거로울 수 있습니다. 이 클래스는 이러한 세부 정보들을 모두 쿼리하는 필요성을 제거해주어 매우 유용합니다. 또한, 이 클래스는 티어, 배포 유형 등을 기준으로 Zuora::ProductRatePlan을 분류하고 앱 전반에서 사용될 수 있도록 도와줍니다.

현재 CustomersDot의 캐시된 제품 카탈로그는 매뉴얼으로 동기화되며, Plan 클래스의 제한으로 인해 완전히 새로 고쳐지려면 CustomersDot을 다시 시작해야 합니다. 새 제품, 제품 요금제 또는 제품 요금제 계층이 Zuora 제품 카탈로그에 업데이트되거나 추가될 때마다 Plan 클래스에 추가적인 매뉴얼 작업이 필요합니다.

이 설계 문서의 주요 목표는 CustomersDot 내의 Plan 모델의 아키텍처와 유지 관리성을 개선하는 것입니다. Zuora의 제품 카탈로그가 업데이트되면 CustomersDot에서 앱 재시작, 코드 변경 또는 매뉴얼 개입 없이 자동으로 반영되어야 합니다.

동기

현재 CustomersDot에서는 여러 이유로 현재 Zuora 제품 카탈로그의 업데이트가 자동으로 반영되지 않습니다.

  • CustomersDot의 캐시된 제품 카탈로그 동기화에는 Rails 콘솔을 통한 매뉴얼 개입이 필요하며, PlanZuora::ProductRatePlan 분류에 대한 상수 및 클래스 변수를 많이 사용하면서 전체 새로 고침에는 서버 재시작이 필요합니다.
  • 이전 설명한 캐시에 새 제품/SKU가 추가되더라도 갱신되므로 현재 CustomersDot의 코드 변경이 필요합니다. 이는 Plan 클래스가 Zuora::ProductRatePlan id를 상수에 할당하고 그 후 다양한 카테고리를 나타내기 위해 id 그룹을 매뉴얼으로 형성하면서 발생합니다. 예를 들어, Ultimate 티어의 모든 요금제 또는 GitLab.com의 셀프 구매용 추가 기능들과 같은 카테고리를 결정 실행 중에 사용합니다.

코드베이스와 제품 수가 늘어날수록 이러한 매뉴얼 개입은 더욱 부담스러워집니다.

목표

주요 목표는 다음과 같습니다:

  • CustomersDot의 캐시된 제품 카탈로그가 언제든지 Zuora와 동기화되도록 보장합니다.
  • CustomersDot의 Plan 관리를 자동화하되 Zuora의 기본 제품 카탈로그 업데이트를 매뉴얼 개입없이 할 수 있도록합니다. 예를 들어, 새 제품/SKU가 추가되었을 때, 요금제가 업데이트되었을 때 또는 제품이 중단됐을 때입니다. 이를 위해 CustomersDot의 분류 지식을 LocalRecord에서 동적으로 해결할 수 있도록 Zuora 제품 카탈로그에 CustomersDot 메타데이터(사용자 정의 필드 형식)를 추가합니다.

제안

현재 CustomersDot은 IronBank gem과 그 LocalRecord 확장을 통해 Zuora 제품 카탈로그의 로컬 캐시를 사용하고 있습니다. 현재 우리는 우리에게 관심이 있는 Zuora의 새로운 변경 사항이 알려지면 이 캐시를 매뉴얼으로 새로 고칩니다.

sequenceDiagram participant CustomersDot participant Zuora Note left of CustomersDot: ProductCatalog refresh is triggered<br/>via Rails console CustomersDot->>Zuora: GET Product Catalog Zuora->>CustomersDot: Respond with Product Catalog CustomersDot->>CustomersDot: Cache copy of Product Catalog in LocalRecord database Note left of CustomersDot: For future Product Catalog queries<br/>LocalRecords are used. CustomersDot->>CustomersDot: GET Zuora::Product CustomersDot->>CustomersDot: GET Zuora::ProductRatePlan Note right of Zuora: Product information was updated CustomersDot->>CustomersDot: GET Zuora::ProductRatePlanCharge CustomersDot->>CustomersDot: GET Zuora::ProductRatePlanChargeTier Note left of CustomersDot: CustomersDot is unaware of Zuora changes<br/>until next deployment

반복 1

제품 카탈로그를 언제든지 Zuora와 동기화하여 다음과 같이 유지합니다:

sequenceDiagram participant CustomersDot participant Zuora Note right of Zuora: Product information was updated Zuora->>CustomersDot: Notification on Product update CustomersDot->>Zuora: GET Product Catalog Zuora->>CustomersDot: Respond with Product Catalog CustomersDot->>CustomersDot: Refresh Product Catalog cache (LocalRecord database) Note left of CustomersDot: CustomersDot Product Catalog<br/>cache is up to date with Zuora

반복 2

Zuora 제품 카탈로그에 CustomersDot의 분류 지식을 추가하여 LocalRecord에서 ProductRatePlan을 직접 해결할 수 있도록 합니다.

이러한 사용자 지정 필드를 제품 카탈로그에 추가하는 것을 제안합니다:

--- title: Zuora Product Catalog Proposed Additions --- erDiagram "Product" ||--|{ "ProductRatePlan" : "has many" "ProductRatePlan" ||--|{ "ProductRatePlanCharge" : "has many" "ProductRatePlanCharge" ||--|{ "ProductRatePlanChargeTier" : "has many" "Product" { enum Tier__c enum DeploymentType__c } "ProductRatePlan" { boolean WebDirect__c }

반복 3

(반복 2에서 소개된) Zuora 사용자 지정 메타데이터를 사용하여 ProductRatePlan을 Zuora 제품 카탈로그에서 직접 해결하고 완전한 캐시 새로 고침을 방해하는 Plan 상수를 제거합니다.

설계 및 구현 세부 사항

이터레이션 1

(이터레이션 1) 제품 카탈로그를 Zuora와 동기화

  • 매일 제품 카탈로그를 새로 고치는 크론 작업은 첫 번째 이터레이션으로 즉각적인 가치를 추가합니다.
  • Zuora 제품 카탈로그의 레코드에 사용자 정의 필드가 업데이트될 때 사용할 새로운 사용자 정의 이벤트를 요청하는 Finance Systems 이슈를 생성합니다. | 기본 객체 | 사용자 정의 이벤트 이름 | | ————————- | ————————————– | | 제품 | CatalogProductUpdate | | ProductRatePlan | CatalogProductRatePlanUpdate | | ProductRatePlanCharge | CatalogProductRatePlanChargeUpdate | | ProductRatePlanChargeTier | CatalogProductRatePlanChargeTierUpdate |
    • Zuora 제품 카탈로그의 레코드가 추가, 삭제 또는 업데이트될 때 Billing 컴포넌트 하위에 새로운 콜아웃을 생성합니다.
  • CustomersDot에 새 컨트롤러를 생성하여 ActionController::Metal을 기반으로 하되 중복 미들웨어, 콜백, 추가적인 Rails 구성을 포함시키지 않고 가능한 빠르게 만듭니다.

    module Zuora
      class WebHooksController < ActionController::Metal
        feature_category :platform
          
        def create
          # Step 1. 유효성 검사하고 수신 웹훅 페이로드를 데이터베이스에 저장합니다.
          # Step 2. SyncProductCatalogJob을 시작합니다.
          head :ok
        end
      end
    end
    

    짧은 시간 내에 많은 제품 카탈로그 업데이트 알림을 받을 경우를 대비하여 SyncProductCatalogJob에 대한 디바운싱 전략을 구현합니다. 초기에는 실행을 5분 지연시키고, 이미 대기 중인 작업이 있을 경우 새 작업을 대기열에 넣지 않도록 합니다.

(이터레이션 2) CustomersDot의 분류 지식을 Zuora 제품 카탈로그로 이전

모든 변경 사항은 Finance Systems 이슈가 필요합니다.

  • 기존 필드 Zuora::Product#category를 검토하여 모든 제품에 적절히 설정되어 있는지 확인합니다. 가능한 값: [null, "Base Products", "Add On Services", "Miscellaneous Products"].
  • Zuora::ProductRatePlan#web_direct라는 새로운 사용자 정의 필드를 추가하여 boolean 유형으로 만듭니다.
    • true: 해당 계획은 셀프 서비스로 이용 가능
    • false: 해당 계획은 셀프 서비스로 이용 불가
  • Product#tier라는 새로운 사용자 정의 필드를 추가하여 enum (다중 선택) 유형으로 만듭니다. 가능한 값: [premium, ultimate, starter, bronze, silver, gold, free, null]
  • Product#deployment_type라는 새로운 사용자 정의 필드를 추가하여 enum (다중 선택) 유형으로 만듭니다. 가능한 값: [self_managed, dedicated, gitlab_dot_com]

각 추가된 필드에 대해, Zuora의 값은 Zuora::ProductRatePlan에서 제공하는 분류와 일치해야 합니다.

note
Zuora에 이러한 필드를 추가하는 현재 노력이 있으므로 이를 재사용할 수도 있습니다. 이러한 필드를 재사용하는 경우 Zuora와 CustomersDot 분류 값이 일치하는지 반드시 확인해야 합니다.

(이터레이션 3) 이 Zuora 사용자 정의 메타데이터를 사용하여 ProductRatePlan을 Zuora 카탈로그에서 직접 해결

  • 이터레이션 2에서 도입된 메타데이터를 기반으로 Zuora::ProductZuora::ProductRatePlan을 가져오는 스코프를 생성합니다. 가능한 스코프:
    • self_managed
    • dedicated
    • gitlab_dot_com
    • base_products
    • add_ons
    • web_direct
    • sales_assisted
    • ultimate
    • premium
    • active (유효 시작/종료 날짜 기준)
  • 주어진 분류 기준을 충족하는 레코드 모음을 나타내는 Plan 상수의 사용을 스코프를 구현하여 동일한 레코드 모음을 로드하는 메서드 호출로 바꿉니다. 예: ALL_ULTIMATE_SM_PLANSZuora::Product.self_managed.ultimate.flat_map(&:product_rate_plans).map(&:id)로 대체할 수 있습니다. 해당 단계는 모든 상수가 대체될 때까지 반복하여 수행될 수 있습니다. 각 이터레이션이 얼마나 복잡한지에 따라 피처 플래그가 필요한지 여부를 결정할 수 있습니다.