ADR(Architecture Decision Record) ? 더 나은 설계를 위한 밑거름 작업은 ..?
1. 들어가며: "코드 리뷰 시간에 줄바꿈을 논의하고 있을 필요가 있을까 ?"
현재 팀의 백엔드 시스템은 MSA(마이크로서비스 아키텍처) 및 역할에 따라 여러 개의 레포지토리로 나뉘어 운영되고 있습니다.
신규 피처를 개발하며 여러 레포지토리를 다루다 보니 한 가지 큰 문제점을 발견했습니다.
다른 글에서도 언급했지만 .. 바로 레포지토리마다 TypeScript, ESLint, Prettier 설정이 파편화되어 있다는 점이었습니다.
이로 인해 다음과 같은 비효율이 매일 반복되고 있었습니다.
- 리뷰 리소스 낭비: PR(Pull Request) 리뷰 시, 본질적인 비즈니스 로직이나 아키텍처에 대한 논의보다 코드 스타일 지적이 일부 생기게 된다는 점입니다.
- CI 병목 현상: 로컬에서 놓친 사소한 린트 에러나 포맷팅 누락이 CI 단계에서 뒤늦게 발견되어 빌드가 실패했습니다. 이를 해결하기 위해 fix: lint error 같은 커밋을 추가로 푸시하고 다시 CI가 돌기를 기다려야 하는 시간 낭비가 지속되었습니다.
저는 이 문제를 해결하기 위해,
팀의 개발자 경험(DX)을 해치지 않으면서도 파편화된 스타일을 강제할 수 있는 '가장 가벼운 사전 방어선'을 구축하기로 했습니다.
2. 도입 전략: 무엇을 선택하고, 무엇을 버렸는가 ?
이러한 문제를 해결할 때 가장 경계해야 할 것은 '너무 무거운 규칙을 갑자기 도입하여 lint 지키기에 급급해지고 오히려 더 힘들어지는 것입니다.
따라서 저는 Trade-off를 바탕으로 도입 전략을 세웠습니다.
✅ 우리가 선택한 전략 (What we did)
1. husky + lint-staged 도입
- 근거: 커밋할 때마다 레포지토리 전체 파일을 린트 검사하면 시간이 너무 오래 걸려 개발 흐름이 끊깁니다. lint-staged를 활용해 오직 '이번 커밋에서 변경된 파일(staged)'만 검사하도록 하여 속도를 보장하고 마찰을 최소화했습니다.
2. Prettier + ESLint --fix 옵션 자동화
- 근거: 개발자가 린트 에러를 보고 직접 코드를 수정하게 하는 것도 피로도를 높입니다. 커밋 훅 단계에서 --fix 옵션을 주어, 포맷팅과 간단한 린트 오류는 시스템이 알아서 자동 수정하도록 구성했습니다. 개발자는 비즈니스 로직에만 집중하면 됩니다.
3. 점진적 파일럿 적용 (코어 API 레포지토리 우선)
- 근거: 논의를 통해 전체 일괄 적용 대신 파일럿 테스트를 진행하기로 했습니다. 패키지별 설정 편차가 크고 최근 작업 빈도가 낮은 레포지토리는 보류하고, 구조가 명확하고 팀원들의 작업 빈도가 가장 높은 코어 API 레포지토리 2곳에 우선 적용하여 효용성을 빠르게 증명하기로 했습니다.
❌ 우리가 버린 전략 (What we didn't do)
이 프로젝트의 핵심은 '가벼움'이었습니다. 따라서 좋아 보이지만 현재 단계에서 독이 될 수 있는 전략들은 과감히 배제했습니다.
1. Pre-commit 훅에 tsc --noEmit(타입 체크) 및 테스트(test) 포함 제외
- 제외 근거: 타입 체크나 유닛 테스트는 실행 시간이 깁니다. 커밋을 남길 때마다 수십 초씩 대기해야 한다면 개발자 마찰(저항)이 극심해집니다. 1차 파일럿의 목적은 '사소한 스타일/린트 오류의 빠른 방어'이므로, 무겁고 시간이 걸리는 검증은 여전히 CI/CD 파이프라인에 위임했습니다.
2. 전체 레포지토리 일괄 적용 제외
- 제외 근거: 모든 레포지토리에 훅을 한 번에 적용하면, 각 레포의 숨겨진 레거시 의존성과 충돌하여 예상치 못한 빌드 실패를 야기할 수 있습니다. 점진적 도입을 통해 리스크를 줄이고자 했습니다.
3. Draft PR을 통한 우회 적용 제외
- 제외 근거: 훅 도입에 대해 팀원들과 충분한 공감대와 합의가 이루어졌습니다. 따라서 우회적인 방법으로 조심스럽게 접근하기보다, 각 레포지토리의 통합 브랜치로 바로 PR을 올려 실무 흐름 속에서 빠르게 부딪히며 피드백을 받는 방법을 택했습니다.
3. 목표와 기대 효과: 우리는 무엇으로 성공을 측정할 것인가 ?
아무리 좋은 도구라도 성과를 증명할 수 없으면 의미가 없습니다.
저는 이 작업의 성공 지표를 도입 전/후 1개월 간의 'GitHub CI 성공률'로 설정했습니다.
커밋 직전의 방어선(Pre-commit Hook)이 효과적으로 작동한다면, 사소한 린트나 포맷팅 오류로 인해 CI가 붉은색(Failed)으로 터지는 횟수가 급감할 것입니다. 이는 곧 다음과 같은 긍정적인 스노우볼을 만들어냅니다.
- 불필요한 재빌드 감소 ➔ 팀 전체의 PR 대기 시간 단축
- 스타일 지적 감소 ➔ 본질적인 아키텍처/로직 중심의 코드 리뷰 활성화
- 궁극적으로 ➔ 조직 전체의 개발 생산성(Productivity) 향상
4. 마치며
팀의 코드베이스에 기여하는 방법은 단순히 주어진 비즈니스 피처를 개발하는 것만은 아니라고 생각이 들었습니다.
동료들이 겪고 있는 불편함을 캐치하고, 이를 해결하기 위한 기술적 선택의 장단점을 분석하여,
팀이 수용할 수 있는 가장 안전한 형태로 제안하고 실행하는 것 또한, 개발자 경험(DX)을 개선하고
나아가 안정적인 서비스를 만드는 첫걸음임을 생각해 볼 수 있었습니다.
수집된 CI 성공률 지표를 바탕으로
이 파일럿 프로젝트가 팀 전체 코드 스타일에 어떤 실질적인 변화를 가져왔는지
파악하고 분석하며 작업을 고도화할 예정입니다.