본문 바로가기

일 이야기/Trost

[Trost Dev] 사내 데이터 트래킹 정복하기 (2)

1편 에 이어지는 내용입니다.

(properties 를 활용하여 customEvent 를 하는 Mixpanel 부터 진행하였습니다
나머지 이야기는 3편에 다룹니다.)

기존 트래커 목록을 Notion 과 Slack에 일괄적으로 정리했고 ..
신규 트래커는 앞으로 스프린트 전에 미리 전달받도록 정리했다면
이제 개발할 차례입니다.

 

우선 기존 트래커들부터 살펴보았습니다. 그런데 ...

 

그런데?

 

1. 서버에서 화면을 구성하는 데이터를 API Response 를 통해 전달하고

2. 웹에서 해당 데이터를 가공하여

3. 자바스크립트 브릿지를 통해 앱에 전달하여

4. 받아온 데이터를 그대로 앱에서 트래커 업체로 전달합니다.

 

트로스트는 앱의 서비스 화면 중 약 80%가 웹뷰로 작동하기에, 많은 수의 트래커도 웹을 통해서 실질적으로 작동합니다.

그렇기에 프론트엔드 개발자가 유지보수를 담당하여 확인합니다.

서버나 앱에 문제가 있는 것이라면 해당 플랫폼 개발자분들께 확인요청을 드리는 것도 프론트엔드 개발자의 몫입니다.

 

문제가 있는 트래커를 디버깅하는 데에 예상 초과의 시간이 소모되었습니다.

네 .. 힘들었다구요 예 ..

 

아무튼 그렇게 하나 둘 디버깅을 시작했고 많은 것을 깨달았습니다.

 

어떤 것을 깨달으셨나요?

 

기능개발보다 트래커 유지보수가 몇 배는 어렵다는 생각이 많이 들었습니다.
CTA 버튼마다, 혹은 어떤 click 이벤트가 발생할 때마다 트래커 코드를 심어줘야 하는데,
그렇게 하기 위해서는 코드 flow 를 전부 이해하고 있어야 하기 때문이었어요.
수많은 파일에서 legacy 코드를 읽고, 과거의 자신과 싸우고.. 
어떤 코드들은 같은 동작을 하지만 향하는 곳이 한 곳이 아닌 네 곳인 경우도 있었습니다. 😂

구체적으로 들어가기 전에
먼저 쉬운 이해를 위해 기존까지 어떤 코드였는지 짚고 넘어가고자 합니다.

let solutionTypeProperty = '';	// a. 데이터 가공
if (responseSolutionType === 'Program') {
	solutionTypeProperty = '프로그램';
} else if (responseSolutionType === 'Goods') {
	solutionTypeProperty = '유형상품';
} else if (responseSolutionType === 'Promotion') {
	solutionTypeProperty = '프로모션';
}

const properties = {	// b. 데이터 제작
      페이지이름: '상품결제완료',
      프로그램id: solutionID,
      패키지id: packageID,
      상품상세유형: paymethodProperty
		...
};
// 데이터들은 API 를 통해 전달받습니다.

customEvent('결제완료', properties);	// c. 데이터 전송
// customEvent(trackerName, properties)는 네이티브로 데이터를 전달하는 자바스크립트 브릿지입니다.

 

 

먼저 코드 스타일이 눈에 띄었습니다. 


a => 해당 데이터를 속성으로 쓰는 곳마다 심어져 있던 코드들..
라인수를 많이 차지할 뿐더러, 
자주 쓰이는 property 지만 모듈화가 되어있지 않아 해당 트래커에 문제가 생긴 경우 모든 파일을 봐야했습니다.

function solutionTypeCustomEvent(solutionType) {
  switch (solutionType) {
    case 'Promotion' || '프로모션':
      return '프로모션';
    case 'Program' || '프로그램':
      return '프로그램';
    case 'Goods' || '유형상품':
      return '유형상품';
    default:
      return '';	// This means some error has occurred
  }
};


이렇게 분리하여 모듈화 후, 해당 속성을 쓰는 곳에서 참조하였습니다.

b => 재활용 되지 않는 데이터임에도 
라인수를 차지하고 가독성을 해치는 코드여서,
별도 선언 없이 바로 가공된 객체를 함수 파라미터로 전달하였습니다.

customEvent('결제완료', {
    페이지이름: '상품결제완료',
    프로그램id: solutionID,
    패키지id: packageID,
    상품상세유형: solutionTypeCustomEvent(solutionType),
    ...
});

위의 코드와 비교하면 코드스타일이 많이 좋아진 것 같지 않나요?

 

오오 네네 좋아진 것 같아요

 

감사합니다. 다만 여기서 문제가 하나 생겼습니다.

보시다시피 '상품상세유형' 이라는 property 는 '프로그램', '유형상품', '프로모션' 셋 중의 하나가 value 로 전달될 것이며, 
String 타입입니다. 
하지만 프로덕트에서 여러가지 상품이 묶인 패키지를 출시하였고,
'상품상세유형'은 다수개의 상품유형을 포함할 Array 타입이 되어야했습니다.

또한 저 트래커는 여러 곳에서 사용되었고 각각 API 엔드포인트는 달랐습니다.
엎친데 덮친 격으로 API 의 수정이 힘든 상황이라 프론트엔드에서 JS 로 해결하는 방법을 찾아야했습니다.

이런 배경을 바탕으로 타입이 적용된 구조를 연구하게 되었습니다. 

 


< 1안 - interface >

 

타입이 필요하다에 초점을 맞춰 간단히 Typescript를 적용했습니다. 

이벤트마다 interface 를 작성해주는 것이죠

 

interface 상품결제완료 {
	페이지이름: string;
    프로그램id: string;
    패키지id: string;
    상품상세유형: string[];
    ...
};

타입이 명시되어 좋을 수 있겠지만
수많은 파일을 .ts | .tsx 로 변환하여 타입을 적어줘야했고,

백 여개의 달하는 트래커에 인터페이스를 적용해줘야하며,

겹치는 property 가 너무 많았기에 비효율적이었습니다.

 

또한 특정 property 가 변경되면 모든 interface 를 변경해줘야하는 단점이 있었습니다.

 

따라서 property 별로 전부 쪼개어 타입을 명시하는 방식을 적용하고 싶었습니다.

 

< 2안 - 함수형 구조 >

class MixpanelCustomEventDataKey {
      properties: {};

      페이지이름(data: string) {
        this.properties = {
          페이지이름: data ?? '',
          ...this.properties,
        };

        return this;
      }

      상품상세유형(data: string[]) {
        this.properties = {
          상품상세유형: data ?? '',
          ...this.properties,
        };

        return this;
      }
      ...
}

 

제 아이디어와 앱개발자 W님 함수형 구조 아이디어, 프론트엔드 개발자 H님의 코드 도움을 통해서 이러한 함수형 구조를 만들게 되었고

 

TypeError 를 알려주며, 필요한 property 만 복합 객체로 생성

제가 원하는 방향으로 개발되었습니다 !

기존 백 여개의 트래커 코드를 노가다로 대체해야하는 단점이 있지만 .. 더 좋은 방법을 찾지 못했습니다.
이 글을 읽고 계시는 분께서 개선방법을 알고 계시다면 추천 부탁드립니다.

이렇게 2안으로 개발하는 것으로 결정하였고, 노션에 있는 property 를 전부 옮겨와야 했습니다.
여기서 (1)편에 있던 노션으로 트래커 목록을 정리한 것이 큰 도움이 되었습니다.

Notion 페이지에서 DOM 에 접근하여 모든 property 목록을 스크래핑 후 중복제거하여 총 66개의 property 목록을 얻었고,

타입을 명시하여 정리를 완료했습니다.

 

또한 property 는 Web 에만 국한되어 사용되지 않고, 타 플랫폼에서도 동일한 값이 쓰이므로 함수형 구조 시스템을 타 플랫폼과도 공유할 수 있었습니다.

자동화 이야기와 Adjust 이야기는 3편으로 이어집니다 !

* 트로스트의 공식블로그, 공식글이 아닌 개인임을 밝힙니다.
** Notion 및 코드는 가공 혹은 컨펌을 받았습니다.