협력사 Testlify

Timesheets by Appforest - Jira 플러그인

회사 전체와 Atlassian Marketplace에서 사용되는 Jira 근무시간 관리 플랫폼을 구축해 서드파티 도구를 대체하고 연간 9,000달러 이상의 라이선스 비용을 절감했다.

Testlify에서 엔지니어링 근무시간 관리는 일상적인 Jira 워크플로우와 단절된 값비싼 서드파티 애플리케이션에 의존하고 있었다. 나는 근무시간 관리, 팀 역량 계획, 프로젝트 비용 배분을 위한 통합 Jira 애플리케이션인 Timesheets by Appforest의 프론트엔드 개발을 리드했다. 이 제품은 Atlassian Marketplace에 게시되어 있으며 회사 전체에 사내 배포되어 있다.

Timesheets by Appforest - 개요

내가 구축한 것

  • Atlassian Marketplace 통합: 자체 호스팅 백엔드 대신, Atlassian의 샌드박스 서버리스 앱 런타임인 Atlassian Forge 위에 엄격하게 범위가 지정된 최소 권한 Jira 읽기/쓰기 권한으로 구축했다.
  • 내장형 Jira 인터페이스: 빠른 입력을 위해 Jira 이슈에 직접 내장된 근무시간 기록 패널과, 컨텍스트 전환 없이 캘린더 뷰 및 일간/주간 타임시트 제출을 위한 완전한 대시보드 앱.
  • 리포팅 및 분석: 스프린트 회계와 프로젝트 비용 추적을 위해 Jira 데이터와 내부 근무시간 기록 데이터를 결합한 리포트 뷰.

Timesheets by Appforest - 근무시간 기록

왜 중요했는가

외부 고객을 위해 Atlassian Marketplace에 게시된 이 플러그인은 사내에서도 기존의 근무시간 관리 소프트웨어를 대체해 연간 9,000달러 이상의 라이선스 비용을 절감했고, 경영진에게 엔지니어링 리소스 배분에 대한 실시간 가시성을 제공했다.

팀과 오너십

나는 소규모 팀에서 프론트엔드 개발을 리드했다: 2024년 중반 이후 4명의 기여자가 397건의 커밋을 남겼고, 지금도 활발히 유지보수되고 있다. 이것은 혼자 만든 제품이 아니라 여러 해에 걸친, 여러 사람이 참여한 제품이며, 내 역할은 풀스택 소유가 아니라 프론트엔드로 한정되어 있었다.

Connect가 아니라 Forge

이 앱은 iframe과 웹훅을 통해 Jira와 통신하는 자체 백엔드를 가진 구형 Connect 프레임워크가 아니라, 샌드박스화된 서버리스 런타임인 Atlassian Forge 위에서 동작한다. Forge를 쓴다는 것은 Jira 쪽 표면을 위한 서버를 우리가 직접 운영하거나 패치할 필요가 없다는 뜻이다. Atlassian이 실행 환경을 호스팅하고, 매니페스트에 선언된 권한 범위를 강제하며, 서버리스 특유의 제약(ARM64 상의 Node 22, 1024MB 메모리, 호출당 제한된 실행 시간)을 부과한다. 이 인프라를 우리가 직접 구축할 필요가 없다.

서로 다른 두 목적을 위한 두 개의 화면

이 제품은 하나가 아니라 의도적으로 두 개의 UI로 나뉘어 있다. 이슈 컨텍스트 패널은 흔한 경우를 처리한다: 이미 보고 있는 티켓에서 벗어나지 않고 클릭 한 번으로 근무시간을 기록한다. 별도의 완전한 대시보드 앱(캘린더 뷰, 리포트, 관리자 설정, 비용 추적)은 계획과 감독, 즉 사이드바 패널이 아니라 진짜 작업 공간이 필요한 작업을 처리한다. 각 화면은 하나의 인터페이스에 두 가지 역할을 강제로 떠맡기는 대신, 자신이 맡은 일에 맞게 만들어져 있다.

진짜 프로젝트 간 통합

이것은 고립된 앱이 아니다. 리졸버 함수들은 Google 캘린더, Outlook 캘린더, 그리고 자매 제품인 Appforest Timetracker VS Code 확장에서 온 근무시간 제안을 명시적으로 수집하고 지운다. 그래서 개발자가 VS Code에서 한 코딩 활동이 수동으로 다시 입력할 필요 없이 이곳에서 제안된 타임시트 항목으로 나타날 수 있다.

데이터 모델과 규모

  • Forge 권한 범위는 좁고 명시적이다(read:jira-work, write:jira-work, manage:jira-configuration, 그리고 사용자/토큰 읽기), 광범위한 포괄적 권한이 아니다.
  • UI 컴포넌트는 Atlassian 자체의 디자인 토큰(@atlaskit)을 사용하므로, 플러그인은 나중에 덧붙인 서드파티가 아니라 시각적으로 네이티브 Jira와 일치한다.
  • 대시보드 앱은 상태 관리에 Pinia를 사용하는 Vue 3로, 46개의 컴포넌트로 구성되어 있으며 React 기반 이슈 컨텍스트 패널과 분리되어 있다. 하나의 제품 안에 두 개의 프론트엔드 스택이 있는 것이지, 두 화면 모두에 인위적으로 늘려 쓴 하나의 공유 코드베이스가 아니다.
  • Forge 함수의 메모리 할당은 초기 기본값으로 1024MB가 설정된 것이 아니라, 실제 성능 문제가 발생한 후 256MB에서 1024MB로 늘어난 것이다.

이 비용/스프린트 뷰를 뒷받침하는 리포팅 엔진은 자체 쿼리 전략을 스케일링한다: 이슈마다 하나씩 요청을 보내거나 대형 스프린트에서 타임아웃 위험이 있는 단일 무제한 쿼리를 보내는 대신, 리포트 규모에 따라 Jira JQL 검색 요청을 호출당 25건, 50건, 또는 100건 단위로 나누고 이슈당 16개 필드를 가져온다.

Build vs. Buy

자체 호스팅 Connect 앱 대신 Forge: Atlassian의 런타임과 권한 모델이, 그렇지 않았다면 이 팀이 직접 구축하고 보안을 책임져야 했을 인프라를 대체한다. 커스텀 UI 키트 대신 네이티브 Atlassian 디자인 토큰: 플러그인은 이 앱만을 위한 병렬 디자인 시스템을 유지하는 대신 Jira 자체의 룩앤필과 상호작용 패턴을 그대로 물려받는다.

Stack

Atlassian Forge(Node 22, ARM64), 이슈 컨텍스트 패널용 React 18, 대시보드 앱용 Pinia를 사용한 Vue 3, Atlassian Design System 토큰과 프리미티브, Atlassian Marketplace를 통해 배포.