#CLI
#자동화
#Typescript
#NodeJS
#개발생산성
#모노레포
#Turborepo
#KOPIS
#사이드프로젝트
Korean |
English
Written by Paul
March 15, 2026
배경
서비스를 운영하다 보면 코드 외적으로 반복하는 작업들이 생깁니다.
- "이번 주 새로 올라온 공연 알림 메일 보내야지" → 터미널 열고, 환경 선택하고, 스크립트 실행
- "KOPIS에서 공연 데이터 땡겨와야지" → supabase 로컬 띄우고, billets-server 띄우고, 둘 다 뜰 때까지 기다렸다가, 마이그레이션 스크립트 실행
매번 순서를 기억하고 손으로 하나씩 해야 하는 일들입니다. 실수가 나기도 하고, 무엇보다 귀찮습니다.
그래서 이 두 가지를
@clack/prompts 기반 CLI로 묶어버렸습니다.@clack/prompts
터미널 UI 라이브러리입니다.
inquirer보다 가볍고, 기본 디자인이 깔끔합니다.select, confirm, text, spinner 같은 컴포넌트를 조합해서 단계별 인터랙션을 만들 수 있습니다.코드가 그대로 흐름을 읽히는 게 마음에 들었습니다.
Mailer CLI
메일 발송 스크립트는 이미 있었는데, 실행하려면 매번 명령어를 직접 조합해야 했습니다. 이걸 CLI로 감쌌습니다.
흐름은 간단합니다.
- 어떤 메일을 보낼지 선택 (새로 올라온 공연 / 이번 주말 공연)
- 환경 선택 (test / production)
- 필요한 경우 추가 파라미터 입력 (feedId, 날짜)
- 최종 확인 후 전송
이제 메일 발송은
pnpm cli 한 번으로 끝납니다.KOPIS Sync CLI
KOPIS 공연 데이터를 DB에 주입하는 작업은 조금 더 복잡했습니다.
기존 순서:
2번이 항상 문제였습니다. 서버가 다 뜨기 전에 syncup을 날리면 실패하고, 그렇다고 무작정 기다리기도 애매했습니다.
서버 bootstrap 대기
health check polling으로 해결했습니다. 응답이 올 때까지 2초마다 재시도합니다.
supabase와 billets-server를 동시에 기다립니다.
유동 LAN IP 문제
billets-server는
localhost가 아닌 실제 LAN IP로 접근해야 했습니다. 문제는 이 IP가 유동이라 매번 바뀔 수 있다는 점입니다.Node.js의
os.networkInterfaces()로 런타임에 직접 뽑아 씁니다.CLI 실행 시점마다 IP를 새로 감지하기 때문에 유동 IP를 따로 신경 쓸 필요가 없습니다.
전체 흐름
터미널 출력은
@clack/prompts의 spinner로 단계별로 표시합니다.마무리
둘 다 핵심은 같습니다. 이미 있는 스크립트를 CLI로 감싸서 순서와 대기를 코드가 책임지게 하는 것입니다.
직접 기억하고, 직접 타이밍 맞추는 일을 없애니 실수도 줄고 피로도도 줄었습니다.
모노레포에서 여러 스크립트를 순서대로 실행해야 하는 상황이 있다면 이 패턴을 참고해보세요.