화면 두 개를 따로 만들었는데, 알고 보니 쌍둥이였습니다 👯

돈독(제가 혼자 만드는 자산관리 앱, https://don-doc.com )에는 화면이 두 개 있습니다. 하나는 홈 화면 대시보드 — 로그인하면 바로 보이는 계좌 요약과 자산 비중 도넛차트. 다른 하나는 자산현황 화면 — 부동산까지 포함한 순자산 전체를 보는 상세 화면입니다.
두 화면은 만들 때부터 다른 화면이라고 생각했습니다. 대시보드는 “한눈에 요약”, 자산현황은 “부동산까지 다 넣은 상세”니까요. 그래서 API 라우트도 각각 따로 짰습니다. /api/dashboard와 /api/wealth, 이름부터 다르게요.
코드를 점검하는 AI가 두 파일을 나란히 놓고서야
돈독 코드를 매일 훑는 AI 에이전트가 있습니다. 8월 26일부터 대시보드 쪽 계좌 처리 코드가 너무 길다며 “함수 두 개로 분리하자”는 제안을 반복해서 올렸고, 8월 30일엔 팀이 “다음 코드 세션에 바로 착수, 더 이상 승인 안 물어봄”으로 정리했습니다. 여기까지는 흔한 리팩토링 이야기입니다.
그런데 8월 31일, 같은 에이전트가 착수 준비를 하려고 코드를 다시 훑다가 자산현황 화면의 /api/wealth도 함께 열어보게 됐습니다. 그리고 두 파일을 나란히 놓고 비교해보니, 계좌 잔액을 계산하는 로직과 마스킹 처리 로직이 변수명 포맷팅만 다르고 사실상 똑같았습니다.

뭐가 얼마나 겹쳤나
구체적으로 이렇습니다. 두 라우트 모두 계좌마다 이런 처리를 각자 갖고 있었습니다.
- 증권계좌처럼 보유종목이 있으면 평가액 합계 + 예수금을 더하고, 없으면 옛날 방식의 하위계좌 합계나 단독 잔액을 쓰는 3분기 잔액 계산
- 열람 권한에 따라 계좌를 통째로 숨기거나(
PRIVATE), 이름만 가리고 금액만 보여주거나(BALANCE_ONLY), CFO 등급이면 전부 보여주는 3단계 마스킹 - 자산 종류별로 묶어서 비중을 계산하는 도넛차트 집계
로직 이름도, 분기 순서도, 변수를 다루는 방식도 거의 한 몸이었습니다. 다른 점은 딱 두 가지였어요. 자산현황 화면만 부동산 상세 정보(단지명·면적·층수)를 추가로 들고 있었고, 개인 자산 합계를 따로 더 계산하고 있었습니다. 그러니까 두 화면은 “같은 엔진에 옵션 두 개가 더 붙은 것”에 가까웠습니다.
화면이 다르게 보인다고, 그 뒤 로직까지 다른 건 아니었습니다.
계획을 다시 짰다 — 아직 실행 전이지만
이 발견 전까지 리팩토링 계획은 “대시보드 먼저 정리하고(중간 크기 작업), 자산현황은 나중에 따로(작은 작업)” 순서였습니다. 두 벌을 순차로 만드는 계획이었죠.
겹침을 확인한 뒤엔 계획이 바뀌었습니다. computeAccountSummaries(계좌, 권한, 사용자, 옵션)와 buildAssetsByType(...)라는 공유 함수를 하나 만들고, 옵션 하나(부동산 상세 포함 여부)로 두 화면의 차이를 흡수한 뒤, 각 라우트는 이 공유 함수를 불러 쓰는 아주 작은 코드로 교체하는 쪽으로요. 작업량으로 치면 “중간+작은 것 두 벌”에서 “중간 것 한 벌 + 아주 작은 것 두 벌”로 줄어드는 셈입니다.
다만 여기서 정직하게 적어야 할 게 있습니다. 이 글을 쓰는 지금(9월 1일)까지 실제 코드 교체는 아직 안 됐습니다. 8월 30일에 “착수 대기”로 넘어간 뒤, 8월 31일에 계획이 바뀌었고, 9월 1일 점검에서도 여전히 “다음 세션에 착수”로 3라운드째 이월 중입니다. 발견과 설계는 끝났는데, 실행은 아직입니다.
따라 하기
비슷해 보이는 화면 두 개가 있다면, 감으로 “합쳐도 되겠다”고 판단하지 말고 아래 순서로 직접 대조해보시길 권합니다.
1. 두 코드 블록을 실제로 나란히 놓고 diff 떠보기
이름이 다른 파일이라도, 의심 가는 블록만 잘라서 비교하면 됩니다.
diff <(sed -n '146,231p' app/api/dashboard/route.ts) \
<(sed -n '61,142p' app/api/wealth/route.ts)
sed -n 'X,Yp' 파일— 파일 전체가 아니라 의심되는 줄 범위만 뽑습니다. 파일이 길수록 전체 비교는 노이즈만 늘어납니다.diff <(...) <(...)— 두 결과를 바로 견줘서, 다른 줄만</>로 보여줍니다. 다른 줄이 거의 없다면 겹침을 의심할 근거가 생깁니다.
✅ 이렇게 되면 성공 — 변수명 몇 개 말고는 거의 그대로 겹쳐 나옵니다. 다른 줄이 나오면 그게 진짜 차이(위 사례에서는 부동산 필드)입니다.
⚠️ 막히면 — 줄 번호를 몰라 어디를 잘라야 할지 모르겠다면, 먼저 grep -n "계좌\|account" 파일명으로 관련 함수의 시작 줄부터 찾으세요.
2. 겹침을 공유 모듈 설계로 바꾸는 프롬프트
diff로 겹침을 확인했으면, 합치는 설계는 AI에게 초안을 시키는 게 빠릅니다.
📋 프롬프트 — 복사해서 AI에 붙여넣으세요
아래 두 코드 블록은 로직이 거의 같고 일부만 다르다.
<블록 A: 파일경로:줄범위>
<블록 B: 파일경로:줄범위>
- 두 블록에 공통인 부분과, B에만 있는 추가 부분을 각각 짚어줘.
- 공통 부분을 함수 하나로 뽑고, B에만 있는 부분은
옵션 매개변수로 켜고 끌 수 있게 설계 초안을 제안해줘.
- 이 함수를 쓰도록 원래 자리를 바꾸면 파일별로
몇 줄이나 줄어드는지도 같이 계산해줘.
✅ 이렇게 되면 성공 — 공통 함수 시그니처(매개변수 포함)와, 각 라우트가 얼마나 짧아지는지가 함께 나옵니다.
⚠️ 막히면 — 옵션 매개변수가 3개를 넘어가면 오히려 더 헷갈리는 함수가 됩니다. 그럴 땐 “차이가 이렇게 많으면 합치지 말고 그냥 따로 둬도 되는지”부터 다시 물어보세요.
배운 것

화면 기획을 다르게 하면, 코드도 자연스럽게 다르게 짜게 됩니다. 저도 “요약 화면”과 “상세 화면”이라는 이름만 보고 처음부터 따로 만들었어요. 문제는 그 뒤에 사람이 짜는 처리 로직(잔액 계산, 마스킹, 집계)까지 매번 다시 새로 생각한다는 겁니다.
이번에 배운 건, 새 화면을 만들기 전에 “이거 이미 있는 계산 아닌가”부터 한 번 물어봐야 한다는 것이었습니다. 그리고 리팩토링 계획도 한 번 세웠다고 끝이 아니라, 겹치는 부분을 새로 발견하면 순서 자체를 다시 짤 여지가 있다는 것도요. 다만 계획을 다시 짜는 것과 실제로 코드를 바꾸는 것은 다른 일이라, 이번 건 아직 후자가 남아 있습니다.
오늘도 한 걸음. 🐴
이 글은 산업 구조와 만드는 과정을 정리한 개인 기록입니다.
특정 종목의 매수·매도 추천이 아니며, 투자 판단과 그 결과는 독자 본인에게 있습니다.