회사

BTS 리드타임 경과 티켓 알림 자동화

리드타임이 지난 미해결 BTS 티켓을 매일 담당자별로 묶어 Slack으로 알리는 Airflow 파이프라인

수행기간 | 2026.09

  • #Python
  • #Airflow
  • #JIRA REST API
  • #Trino
  • #Slack API
  • #pytest

대시보드에서만 확인하던 리드타임 경과 티켓을 담당자에게 직접 알리기

Problem

  • 미해결 BTS 티켓 약 1만 건 가운데 리드타임이 지난 티켓이 매일 1천 건 안팎 발생
  • 원본 대시보드 SQL이 쓰는 티켓 테이블은 조회 권한이 없어 쿼리를 그대로 자동화할 수 없음
  • 담당자별 경과 건수가 중앙값 4건, 최대 597건으로 치우쳐 한 메시지로 보내면 Slack 글자 수 한도를 넘김

My Role

  • 티켓은 JIRA REST(JQL)로 읽고 SLA 기준·스토어 정보는 Trino로 조인하도록 파이프라인 재구성
  • 경과일수를 영업일 기준으로 계산하고 주말·공휴일에는 발송을 건너뛰어 중복 알림 방지
  • JIRA 이메일과 Slack 유저네임이 같다는 규칙을 활용해 사용자 조회 API 없이 담당자 멘션 연결
  • 부모 메시지와 스레드 답글 구조로 담당자별 알림을 나눠 글자 수 한도 문제 해결

Result

  • 2026.09.30부터 매일 10:00 자동 실행 중이며 실행당 약 1~3분 소요
  • 영업일 기준 적용으로 캘린더 기준 대비 경과 건수 21% 감소(1,239건 → 976건)
  • 배포 코드를 그대로 호출하는 유닛 테스트 21개와 뮤테이션 검사로 핵심 로직 검증

기술적 의사결정

  • 티켓은 JIRA REST(JQL), 기준 테이블은 Trino

    원본 대시보드의 티켓 테이블은 컬럼 권한이 막혀 있어, 티켓만 JQL로 대체하고 SLA 기준·스토어 정보는 Trino로 그대로 조인

  • JQL 상대 날짜 대신 절대 날짜 사용

    이 JIRA 서버에서 월 단위 상대 날짜(-7M)가 일 단위(-7d)보다 적게 반환되는 동작을 확인해 조회 시작일을 직접 계산

  • 영업일 기준 경과 계산과 휴일 미발송

    CS 조직이 주말·공휴일에는 티켓을 처리하지 않으므로 그날을 경과에서 빼고, 쉬는 날 발송하면 직전 영업일과 같은 내용이 중복되어 발송 자체를 생략

  • 사용자 조회 API 없이 멘션

    users:read.email 권한이 없어 조회 API를 쓸 수 없었고, Slack 유저네임이 JIRA 이메일 앞부분과 같다는 규칙으로 API 호출 0회에 전원 멘션

  • 부모 메시지 + 스레드 답글

    담당자별 최대 597건, 62,787자로 Slack 40,000자 한도를 넘으면 조용히 잘리므로 20건 단위 답글로 분할

운영 고려

  • Slack 429(호출 한도) 응답은 내장 재시도 핸들러로 흡수, 대상 증가 시 발송 간격 조정 방안 정리
  • 첫 운영 실행의 발송 실패(검토 기간 중 팀 Slack 봇 교체)를 분석해 배포 전 다른 DAG 설정 변화 점검 절차를 체크리스트에 추가
  • 매 실행이 미해결 백로그 전체를 다시 확인해 휴일로 건너뛴 날의 누락 없이 다음 영업일에 발송
파이프라인 구조: 영업일 판정, 데이터 수집, 경과 판정, 담당자별 Slack 발송
파이프라인 구조: 영업일 판정, 데이터 수집, 경과 판정, 담당자별 Slack 발송