브리핑 봇을 3주 동안 키우다 보니 코드가 뒤엉켰습니다. 예산 구분을 추가하려고 함수를 열었더니, 그 함수가 시트를 읽고 → 계산하고 → 문장을 만들고 → 텔레그램으로 보내는 것까지 혼자 다 하고 있더군요. 어디를 고쳐야 할지 찾는 시간이 고치는 시간보다 길어졌습니다.
그래서 AI에게 물었습니다. “이거 클린 아키텍처로 바꾸고 싶어.”
교과서 그대로는 답이 아니었다
돌아온 첫 대답이 뜻밖이었어요. “교과서식 클린 아키텍처는 여기엔 안 맞습니다.”
정식 클린 아키텍처는 계층 4개에 의존성 규칙까지 갖춘 구조인데, 제가 쓰는 앱스크립트에는 그걸 지탱할 기능(모듈 분리 같은 것)이 없답니다. 억지로 흉내 내면 이득 없이 코드만 세 배가 된다고요.
대신 핵심 아이디어 하나만 가져왔습니다.
계산하는 코드와 바깥세상(시트·API·메신저)을 만지는 코드를 섞지 않는다.
식당에 비유하면 이렇습니다. 예전 코드는 한 사람이 주문받고 장 보고 요리하고 서빙까지 하는 가게였어요. 바뀐 구조는 역할을 나눈 가게입니다.
① 설정 = 레시피 수첩 (예산 금액, 분류 키워드 — 숫자만 고치는 곳)
② 코어 = 주방 (재료를 받아 요리만. 바깥 접촉 금지)
③ 어댑터 = 장보기·배달 (시트 읽기, API 호출, 메시지 전송)
④ 진입점 = 홀 매니저 ("장 봐와 → 주방에 → 배달 보내" 지시만)
실제 흐름으로 그리면 이렇습니다. 밤 브리핑 하나가 도는 순서예요.
이득은 명확합니다. 고장 나면 볼 곳이 반으로 줄어요. 숫자가 틀렸다 → 주방 문제. 메시지가 안 왔다 → 배달 문제. 예전엔 한 함수 안에서 둘 다 의심해야 했습니다.
진짜 문제: “고치다가 망가뜨리면?”
구조를 바꾼다는 건 결국 잘 돌아가는 코드를 갈아엎는다는 뜻입니다. 그리고 이 봇은 매일 아침저녁으로 실제로 쓰는 물건이에요.
더 무서운 건, 이런 개편에서 생기는 버그는 에러 없이 조용히 틀리는 종류라는 겁니다. 코드를 옮기다 한 줄이 미묘하게 달라져도 브리핑은 멀쩡히 도착합니다. 숫자만 슬쩍 다를 뿐이죠. 며칠씩 모를 수 있습니다.
여기서 배운 게 이번 사례의 핵심입니다. 골든 테스트라는 방법이에요.
골든 테스트: 출력을 얼려놓고 시작한다
순서가 중요합니다. 코드를 고치기 전에:
- 가짜 입력(거래 기록 배열, 가짜 캘린더 일정)을 준비하고
- 지금 코드가 만드는 출력(브리핑 전문)을 파일로 저장합니다 — 이게 “정답지”
- 그다음에 구조를 갈아엎고
- 같은 입력을 넣어 글자 하나까지 같은지 대조합니다
바꾸기 전: 입력 → [옛 코드] → 출력 저장 (정답지)
바꾼 후: 입력 → [새 코드] → 출력 = 정답지 ?
├─ 같다 → 구조만 바뀐 것 ✅
└─ 다르다 → 어딘가 실수함, 몇 번째 줄인지 표시
실제로 대조는 “대충 비슷”이 아니라 바이트 단위로 했습니다. 공백 하나, 쉼표 하나 달라도 실패로 처리했어요. 리팩터링의 성공 기준은 “더 좋아졌다”가 아니라 “달라진 게 없다” 이니까요.
파일 다섯 개를 이 방식으로 하나씩 갈아탔고, 다섯 번 모두 정답지와 일치했습니다.
부수입: 테스트가 정직해졌다
구조를 나누고 나니 예상 못 한 이득이 따라왔습니다.
예전에는 계산 코드가 시트 읽기와 붙어 있어서, 테스트하려면 구글 시트 전체를 흉내(mock) 내야 했습니다. 그 흉내 장치가 진짜 코드보다 자주 깨졌어요.
지금은 주방(코어)이 배열만 받으니, 배열을 넣고 답을 확인하면 끝입니다. 흉내 낼 게 없어요. 심지어 이런 덫도 놓을 수 있게 됐습니다:
// 코어를 테스트할 때 시트 접근을 '지뢰'로 바꿔둔다
SpreadsheetApp = { getActiveSpreadsheet: () => { throw new Error('코어가 시트를 만지면 안 됨!'); } };
코어가 규칙을 어기고 몰래 시트를 만지면 테스트가 그 자리에서 터집니다. “분리했다”는 말을 믿는 게 아니라 어기면 터지게 만든 거예요.
남는 교훈
1. 리팩터링은 “정답지 저장”부터 시작하세요.
바꾸기 전 출력을 얼려두지 않으면, 바꾼 후에 “잘 된 것 같다”는 느낌만 남습니다. 느낌은 조용한 버그를 못 잡습니다.
2. 교과서 구조는 번역해서 쓰는 겁니다.
제 환경(앱스크립트, 혼자 쓰는 자동화)에 4계층은 과했습니다. 핵심 원리 하나만 가져와 축소판을 만드는 게, 형식을 다 갖추는 것보다 나았습니다. AI에게 “이 교과서 개념, 내 상황에는 어디까지가 적당해?”라고 묻는 게 유효했어요.
3. 한 번에 갈아엎지 마세요.
파일 다섯 개를 한꺼번에 바꿨다면 뭐가 잘못됐는지 못 찾았을 겁니다. 하나 바꾸고 → 정답지 대조 → 통과하면 다음. 지루하지만 이게 제일 빨랐습니다.
한계도 적어둡니다
골든 테스트는 정답지를 만들 때 밟은 길만 보증합니다. 가짜 입력이 안 지나간 구석의 실수는 못 잡아요. 그래서 자주 쓰는 기능 위주로 가짜 입력을 짰고, 나머지는 실제 브리핑을 받아보며 확인했습니다. “전부 검증했다”와 “주요 경로를 검증했다”를 구분해서 말하는 것도 이번에 배운 것 중 하나입니다.