개발 slecs

팀 멤버별 Claude Code 사용량 집계 대시보드 구현

목차

팀 단위 사용량 집계 기능을 구현하면서, 멤버별 Claude Code 사용 현황을 한눈에 볼 수 있도록 만들었다. 이 작업의 배경과 설계 의도, 그리고 팀 리딩 관점에서 느낀 부분들을 정리해본다.

팀 단위 사용량 추적의 필요성

개발팀이 성장하면서 멤버들이 각각 Claude Code를 어느 정도나 활용하고 있는지 파악하기 어려워졌다. 개인 단위로는 자신의 사용 현황을 볼 수 있었지만, 팀 전체 입장에서 누가 얼마나 쓰는지, 그리고 팀 전체 예산 대비 어떤 상황인지를 한곳에서 보기 위한 전용 대시보드가 필요했다. 특히 팀 리더로서 리소스 할당, 비용 최적화, 팀원별 생산성 분석 같은 의사결정을 할 때 이런 정보가 있으면 훨씬 수월해진다.

그런데 여러 멤버의 사용 데이터를 한 화면에 모으려면 단순히 개인 데이터를 연결하는 것만으로는 부족했다. 멤버별로 사용량이 분산되어 있었고, 각 사람의 사용 기록들을 시간별로 추적하면서도 팀 전체 관점에서 집계할 수 있는 구조가 필요했다.

데이터 집계 설계

영역 역할 변경 포인트
team-usage.ts 멤버별 사용량 계산 핵심 로직 개인 데이터를 팀 레벨로 aggregation
team-usage.test.ts 집계 로직 검증 멤버 추가/제거 시 올바른 합산, 엣지 케이스 처리
usage-archive.ts 사용량 기록 저장소 팀의 과거 사용 이력을 안정적으로 보관
dashboard.ts 시각화 (웹/UI 대시보드) 집계된 데이터를 사용자 친화적 형태로 표현
usage.ts CLI 명령어 터미널 환경에서도 팀 사용량 조회 가능

코드로 보면, 멤버 단위 사용 이벤트들을 받아서 팀 전체 수준에서 재집계하는 구조다.

// 대략적인 로직 예시
function aggregatePerMember(usageEvents: UsageEvent[]): TeamUsageBreakdown {
  const breakdown = new Map<string, number>();

  for (const event of usageEvents) {
    const current = breakdown.get(event.memberId) || 0;
    breakdown.set(event.memberId, current + event.amount);
  }

  return {
    totalUsage: Array.from(breakdown.values()).reduce((a, b) => a + b, 0),
    byMember: Object.fromEntries(breakdown),
  };
}

가장 신경 쓴 부분은 정확성과 확장성의 균형이었다. 멤버가 추가되고 제거되는 상황에서도 과거 데이터의 일관성이 깨지지 않아야 했고, 새로운 멤버의 첫 사용량이 누락되지 않도록 해야 했다. 그래서 테스트 케이스에 "멤버 온보딩 후 사용량 추가", "멤버 아웃보딩 후 기존 기록 유지" 같은 시나리오를 꼼꼼히 담았다.

CLI와 대시보드의 이중 인터페이스

이 기능을 만들면서 한 가지 중요한 선택이 있었다: CLI 환경에서도 접근 가능하게 하자는 것이었다. 웹 대시보드는 깔끔하고 시각적이지만, 개발팀은 터미널에서 빠르게 정보를 확인하고 싶어 한다. usage.ts 명령어로 CLI에서도 같은 데이터를 조회할 수 있게 하고, index.ts에서 라우팅을 정리했다.

$ team-usage-cli --team [teamId] --format table  # 테이블 형식
$ team-usage-cli --team [teamId] --format json   # JSON 형식 (파이프라인용)

이렇게 이중 인터페이스로 구성하면, 멤버들이 각자 선호하는 환경에서 정보에 접근할 수 있다. 특히 CI/CD 파이프라인이나 자동화된 리포팅에서 JSON 출력을 쉽게 파싱할 수 있다는 장점도 있다.

회고와 배운 점

이 작업을 하면서 깨달은 건, 팀 단위 기능을 만들 때는 개인 단위의 심플한 데이터 모델만으로는 부족하다는 거였다. 처음엔 "그냥 개인 데이터를 다 합산하면 되지 않을까"라고 생각했지만, 멤버 변동, 시간대별 트렌드 분석, 팀별 비교 같은 요구사항들이 속속 나오면서 구조를 다시 설계해야 했다.

또한 테스트 커버리지가 얼마나 중요한지 다시 한번 느꼈다. team-usage.test.ts에서 엣지 케이스를 철저히 다뤘기 때문에, 나중에 멤버 증가/감소 시나리오에서도 버그 없이 릴리즈할 수 있었다. 팀원들도 이 테스트들을 읽으면서 "어떤 상황에서 이 함수가 동작해야 하는가"를 자연스럽게 이해할 수 있었다.

마지막으로, 사용자 입장에서 데이터를 보는 경로를 여러 개 제공하는 것이 좋았다. 어떤 팀원은 웹 대시보드를 좋아하고, 어떤 팀원은 CLI가 더 편하다. 그 선택을 모두 존중할 수 있는 설계 덕분에 도입 저항이 적었던 것 같다.


🛒 이 글과 어울리는 추천 상품

*위 링크는 쿠팡파트너스 활동의 일환이며, 일정액의 수수료를 제공받을 수 있습니다.

댓글 0

첫 댓글 달아줘.