본 사이트는 파트너스 활동으로 수수료를 받을 수 있으며, 서버 운영과 무료 앱 개발에 사용됩니다. 본 사이트는 파트너스 활동으로 수수료를 받을 수 있으며
서버 운영과 무료 앱 개발에 사용됩니다.
목록으로
바이브 코딩

바이브 코딩 레거시 정리 | 데드코드·스파게티 코드 방지를 위한 실전 정리 전략

최초 발행: 2026년 5월 29일 오전 01:34 | 최종 수정: 2026년 5월 29일 오전 01:34

바이브 코딩(Vibe Coding)은 2025년 2월 Andrej Karpathy가 X에 남긴 짧은 포스트에서 시작된 개념으로, 개발자가 키보드로 코드를 직접 두드리는 대신 자연어로 의도를 전달하고 LLM이 코드를 작성·수정·실행하도록 맡기는 방식을 가리킵니다. 속도는 압도적으로 빠르지만, 한 가지 부작용이 분명하게 따라옵니다. AI는 새 기능을 추가할 때 과거에 만든 코드를 적극적으로 삭제하지 않습니다. 안 쓰는 함수, 더 이상 호출되지 않는 라우트, 진입점이 사라진 UI 컴포넌트, 임시로 남겨둔 디버깅 코드가 그대로 누적됩니다. 사용자가 보기에는 동작하지만, 내부적으로는 찌꺼기가 쌓여 가는 구조입니다.

초보자가 이 상태를 방치하면 결과는 흔히 말하는 스파게티 코드가 됩니다. 어떤 함수가 진짜로 호출되는지, 어떤 변수가 의미 있는지, 어떤 파일이 빌드에 포함되어 있는지조차 파악이 어려워집니다. LLM에게 다시 수정을 맡겨도 같은 위치를 다른 패턴으로 다시 작성하는 일이 반복되고, 결국 코드를 이해하지 못한 채 코드만 늘어나는 상태에 빠집니다. GeekNews에 정리된 한 분석은 이를 가리켜 "바이브 코드는 곧 레거시 코드"라고 표현했고, 실제로 Sean Goedecke 같은 엔지니어도 바이브 코딩은 일정 규모를 넘으면 반드시 "이해하기 위한 리팩토링" 단계가 필요하다고 강조합니다.

이 문서는 바이브 코딩을 롱런하기 위한 코드 정리 전략을 다룹니다. 안 쓰는 코드(데드 코드)의 정의와 식별 방법, 진입점 분석, 정적 분석 도구 활용, 디자인 패턴과 미사용 로직 리팩토링, AI 에이전트를 활용한 정리 워크플로우까지 단계별로 정리합니다. 초보자도 따라 할 수 있도록 도구 이름과 명령, 점검 순서를 구체적으로 적었습니다.

읽고 나면 다음 세 가지를 얻을 수 있습니다. 첫째, 내 프로젝트에 어떤 종류의 찌꺼기가 쌓여 있는지 분류할 수 있는 시각. 둘째, AI에게 정확히 어떤 작업을 시켜야 안전하게 코드가 줄어드는지에 대한 프롬프트 패턴. 셋째, 새 기능을 추가할 때 다시 스파게티가 되지 않도록 막는 운영 루틴입니다.

1. 바이브 코딩에서 "레거시 코드"가 의미하는 것

전통적으로 Michael Feathers는 저서 Working Effectively with Legacy Code에서 레거시 코드를 테스트가 없는 코드라고 정의했습니다. 테스트가 없으면 동작을 보존하면서 구조를 바꾸기 어렵고, 그래서 수정이 두려워지는 코드가 곧 레거시라는 의미입니다. 바이브 코딩에서 이 정의는 그대로 들어맞습니다. AI가 생성한 코드는 대부분 테스트 없이 "일단 돌아가니까" 단계에서 멈춰 있고, 따라서 작성된 순간부터 레거시가 됩니다.

여기에 한 층이 더 쌓입니다. 바이브 코딩의 레거시는 단순히 테스트가 없는 코드가 아니라 작성자도 이해하지 못한 코드입니다. 사용자가 직접 타이핑하지 않았기 때문에 어떤 함수가 어디서 호출되는지, 어떤 분기 조건이 어떤 상황을 위해 들어갔는지를 모르는 채로 다음 기능을 요청하게 됩니다. 그래서 바이브 코딩 환경에서 "레거시 정리"는 두 가지를 동시에 의미합니다. 하나는 불필요한 코드를 줄이는 것, 다른 하나는 남은 코드를 이해 가능한 구조로 재배치하는 것입니다.

1.1. 찌꺼기의 4가지 유형

바이브 코딩 후 쌓이는 찌꺼기는 대체로 네 종류로 분류됩니다.

  1. 데드 코드(Dead Code): 작성되어 있지만 어디서도 호출되지 않는 함수, 클래스, 변수, 파일입니다. import만 되어 있고 사용처가 없는 모듈, 더 이상 라우팅되지 않는 페이지 컴포넌트가 대표적입니다.
  2. 언리처블 코드(Unreachable Code): 컴파일이나 실행 흐름상 도달할 수 없는 코드입니다. return 문 뒤의 명령, 항상 false인 조건문 내부 블록이 여기 해당합니다.
  3. 진입점 없는 UI/라우트: 화면에는 만들어졌지만 어떤 메뉴나 링크에서도 진입할 수 없는 페이지, 어떤 핸들러에서도 호출되지 않는 API 엔드포인트입니다. 사용자 입장에서 존재하지 않는 기능이지만 빌드 산출물에는 포함됩니다.
  4. 중복 로직과 죽은 분기: 같은 일을 하는 함수가 여러 버전으로 공존하거나, A/B 테스트 흔적·기능 플래그가 false로 고정된 분기가 남아 있는 경우입니다. 동작에는 영향이 없지만 가독성과 유지보수성을 크게 떨어뜨립니다.

1.2. 왜 AI는 이걸 알아서 지워주지 않는가

LLM은 본질적으로 추가에 강하고 삭제에 약한 도구입니다. 새 기능 요청을 받으면 기존 코드를 건드리지 않고 옆에 새 코드를 덧붙이는 방식을 선호합니다. 이유는 두 가지인데, 첫째는 학습 데이터에서 "보존하면서 추가하는" 패턴이 훨씬 많기 때문이고, 둘째는 사용자가 명시적으로 "이걸 지워달라"고 말하지 않으면 삭제를 안전하지 않은 선택으로 판단하기 때문입니다. 결과적으로 사용자가 적극적으로 정리를 지시하지 않는 한 코드베이스는 단방향으로 비대해집니다.

핵심 포인트: 바이브 코딩의 레거시 정리는 "AI가 알아서 해주겠지"를 포기하는 데서 시작합니다. 삭제 지시는 사람이 명시적으로 내려야 하며, 그 판단을 도와주는 것이 정적 분석 도구와 진입점 분석입니다.

2. 데드 코드와 진입점 정리, 도구로 자동화하기

초보자가 가장 먼저 손에 쥐어야 할 무기는 정적 분석 도구입니다. 정적 분석은 코드를 실행하지 않고 소스만 보고 어떤 함수가 어디서 호출되는지, 어떤 변수가 어디서 쓰이는지를 그래프로 만들어 줍니다. 이 그래프에서 들어오는 화살표가 없는 노드가 곧 데드 코드 후보입니다.

2.1. 언어·환경별 대표 도구

환경추천 도구잡아내는 것
JavaScript / TypeScriptKnip사용되지 않는 파일, export, 의존성, 누락된 의존성
TypeScriptts-prune사용되지 않는 export 식별
JS/TS 전반ESLint (no-unused-vars, no-unreachable)미사용 변수, 도달 불가 코드
PythonVulture, Ruff (F401, F841)미사용 import, 변수, 함수, 클래스
Gogolangci-lint (deadcode, unused)미사용 함수·타입
Java / KotlinIntelliJ Inspect, SonarQube미사용 메서드, 중복 코드
다언어 통합SonarQube, Qodana코드 스멜, 보안, 중복, 데드 코드

Knip은 특히 바이브 코딩으로 만든 Next.js·Vite·React 프로젝트에 잘 맞습니다. npx knip 한 줄이면 사용되지 않는 파일과 export 목록이 한 번에 나오고, 그중 진짜 안전하게 지울 수 있는 것을 사람이 골라낼 수 있습니다. ts-prune은 더 가볍지만 export 단위만 다루므로 파일 단위 정리에는 Knip이 더 강력합니다.

SonarQube는 규모가 큰 프로젝트나 팀 단위에서 효과가 큽니다. 데드 코드뿐 아니라 인지 복잡도(Cognitive Complexity), 중복 코드 비율, 보안 취약점을 한 화면에서 보여 줍니다. 2025년 들어 SonarQube는 "AI 코드 검증" 기능을 공식 마케팅 포인트로 내세웠고, 바이브 코딩 결과물을 게이트키퍼처럼 거르는 용도로 자주 쓰입니다.

2.2. 진입점(UI/엔트리포인트) 기준으로 자르기

앞서 본 댓글 중 "진입점(ui)이 없는 코드를 삭제해달라고 하라"는 조언이 있었습니다. 이 말은 코드를 정리할 때 사용자가 도달 가능한 경로에서부터 거꾸로 추적하라는 의미입니다. 정리 순서는 다음과 같이 잡으면 안전합니다.

  1. 엔트리포인트 목록화: 웹 프로젝트라면 라우터 설정 파일에서 노출된 페이지 경로와 API 핸들러를 모두 적어둡니다. CLI나 서버라면 main 함수, 등록된 명령, 노출된 포트를 적습니다.
  2. 참조 그래프 생성: 각 엔트리포인트에서 시작해 호출되는 함수와 import되는 파일을 따라가며 "살아 있는 노드" 집합을 만듭니다. Knip이나 madge 같은 도구가 이걸 자동으로 해 줍니다.
  3. 죽은 노드 확인: 전체 파일 목록에서 살아 있는 노드 집합을 빼면 데드 코드 후보가 됩니다.
  4. 수동 검토: 동적으로 호출되는 코드(문자열로 함수명 참조, 리플렉션, i18n 키 등)는 정적 분석이 놓칠 수 있으므로 사람이 한 번 더 확인합니다.
  5. 점진적 삭제: 한 번에 다 지우지 말고 PR 단위로 10~30개 파일씩 나눠 삭제하고, 매번 빌드와 테스트, 수동 스모크 테스트를 돌립니다.

2.3. AI 에이전트에게 시키는 정리 프롬프트

Claude Code, Cursor, Codex 같은 에이전트에게 정리를 맡길 때는 검색 → 보고 → 승인 → 삭제 4단계로 분리하는 것이 안전합니다. 한 번에 "안 쓰는 코드 다 지워줘"라고 하면 동적으로 참조되는 코드까지 같이 사라질 수 있습니다.

프롬프트 예시는 이렇게 구성할 수 있습니다. 첫 턴에서는 npx knip을 실행하고 결과를 표로 정리해달라고 합니다. 두 번째 턴에서는 각 항목이 정말 사용되지 않는지 grep과 라우터 설정으로 교차 검증해달라고 합니다. 세 번째 턴에서 삭제 계획서(Plan)를 작성하게 하고, 사용자가 검토한 뒤 네 번째 턴에서 실제 삭제와 테스트 실행을 시킵니다. 이 흐름은 Claude Code의 Plan 모드(Shift+Tab으로 진입)와 잘 맞습니다.

핵심 포인트: 데드 코드 정리는 도구가 후보를 찾고, 사람이 결정하고, AI가 실행하는 분업이 가장 안전합니다. AI에게 판단까지 맡기면 동적 참조나 외부 진입점을 놓쳐 기능이 사라질 수 있습니다.

3. 스파게티 코드를 막는 설계와 리팩토링 루틴

데드 코드를 지운다고 스파게티 구조가 풀리는 것은 아닙니다. 남은 코드가 여전히 한 파일에 1,500줄짜리 컴포넌트, 10단계 if 중첩, 같은 로직의 세 가지 버전으로 되어 있다면 다음 수정 요청에서 다시 동일한 문제가 반복됩니다. 여기서 필요한 것이 디자인 패턴 적용리팩토링입니다.

3.1. 웹 프로젝트라면 디자인 패턴부터

바이브 코딩으로 만든 웹 프로젝트는 대개 비슷한 문제를 가집니다. 페이지 컴포넌트 안에 데이터 호출, 상태 관리, UI 렌더링, 비즈니스 로직이 한 덩어리로 섞여 있습니다. 이 상태에서는 어떤 줄을 바꿔도 다른 줄이 영향을 받습니다. 정리 순서는 다음과 같이 잡습니다.

  1. 계층 분리(Layered Architecture): 프론트엔드는 보통 표현(UI) / 상태(Store, Hooks) / 데이터 접근(API client) / 도메인 로직(Service) 네 층으로 나눕니다. 백엔드는 컨트롤러 / 서비스 / 리포지토리 / 도메인으로 나눕니다.
  2. 단일 책임 원칙(SRP): 한 파일은 한 가지 이유로만 바뀌어야 합니다. 200줄을 넘어가는 컴포넌트나 함수는 책임이 둘 이상 섞여 있을 가능성이 높습니다.
  3. 공통 패턴 도입: 폼은 React Hook Form 같은 라이브러리로 표준화하고, 데이터 페칭은 TanStack Query·SWR로 통일하며, 상태는 Zustand·Redux Toolkit 중 하나로 일관되게 사용합니다. 한 프로젝트 안에 같은 일을 하는 세 가지 라이브러리가 공존하지 않도록 합니다.
  4. 명명 규칙 통일: 파일명, 함수명, 변수명을 일관된 규칙으로 통일해 두면 LLM이 다음 코드를 생성할 때도 그 규칙을 따라가는 경향이 강해집니다.

3.2. 리팩토링 전 반드시 만들어야 할 것: 안전망

Michael Feathers의 고전적 조언은 바이브 코딩에도 그대로 적용됩니다. 리팩토링 전에 현재 동작을 고정하는 테스트(Characterization Test) 를 먼저 만들어야 합니다. 완벽한 단위 테스트가 아니어도 됩니다. 주요 사용자 흐름을 끝에서 끝까지 돌려보는 E2E 테스트 한두 개, 핵심 API에 대한 통합 테스트 정도면 충분합니다. 이 안전망이 있어야 AI가 "리팩토링" 명목으로 동작을 바꿔도 즉시 잡아낼 수 있습니다.

Claude Code 사용자들 사이에서 5만 줄 규모의 레거시를 안전하게 리팩토링한 사례가 공유된 적이 있는데, 그 과정의 1단계가 바로 특성 테스트 작성, 2단계가 CLAUDE.md로 프로젝트 컨벤션 명시, 3단계가 점진적 리팩토링과 지속적 검증이었습니다. 순서가 중요합니다. 테스트 없이 리팩토링부터 시키면 AI가 행복하게 코드를 바꾸고, 사용자는 한참 뒤에야 결제가 안 되는 것을 발견하게 됩니다.

3.3. Lint와 정적 분석을 CI에 묶기

정리 작업이 한 번의 이벤트가 아니라 지속적인 루틴이 되려면 자동화가 필요합니다. 권장 조합은 다음과 같습니다.

단계도구막아주는 문제
저장 시ESLint, Prettier, Ruff미사용 변수, 포맷 불일치, 단순 버그
커밋 시lint-staged + Husky깨진 코드가 커밋되는 것
PR 시Knip, ts-prune, SonarQube데드 코드, 중복, 복잡도 증가
머지 시단위·통합 테스트, E2E 일부동작 회귀
주간 점검SonarQube 리포트, 코드 커버리지 추이장기적 부패

이 파이프라인이 갖춰져 있으면 바이브 코딩으로 새 기능을 빠르게 추가해도 자동으로 게이트가 닫혀 코드 품질이 일정 수준 아래로 내려가지 않습니다.

3.4. 새 기능 추가 시의 워크플로우

앞에서 본 yamang_dev 댓글에 좋은 조언이 있었습니다. 새 기능을 추가할 때 바로 코드부터 작성하지 말고, 스펙 문서 초안 작성 → 영향도 분석 → 문서 개선 → 구현 → 클린업 순서로 진행하라는 것입니다. 이 흐름을 실제 명령으로 풀면 다음과 같습니다.

  1. AI에게 기능 명세를 자연어로 적게 하고 사람이 검토합니다.
  2. 영향 범위(어떤 파일·모듈·DB 스키마가 바뀌는지)를 미리 보고서 형태로 받습니다.
  3. 누락된 케이스를 사람이 보강해 명세를 확정합니다.
  4. Plan 모드로 구현 계획을 먼저 받고 승인합니다.
  5. 구현 후 마지막에 클린업 단계를 별도로 요청합니다: 미사용 import 제거, 중복 함수 통합, 임시 console.log 삭제, 테스트 추가.

클린업 단계를 매 기능 추가의 마지막 항목으로 고정하면 찌꺼기가 단계적으로 줄어듭니다.

핵심 포인트: 스파게티 코드를 막는 가장 강력한 방법은 "새 기능을 다 만든 다음에 정리"가 아니라 "매 기능 추가의 마지막 5분에 정리" 입니다. 작은 정리가 누적되어야 큰 리팩토링을 피할 수 있습니다.

4. AI 에이전트와 함께 안전하게 정리하는 실전 패턴

도구와 원칙을 알았다면 이제 실제 작업 흐름을 정리할 차례입니다. 초보자가 바로 따라 할 수 있는 4주 루틴을 제안합니다.

4.1. 1주차: 진단

npx knip, ESLint, ts-prune을 돌려 데드 코드 후보 목록을 만듭니다. SonarQube가 가능한 환경이라면 한 번 스캔해 인지 복잡도 상위 10개 파일을 뽑아 둡니다. 이 시점에는 아무것도 지우지 않습니다. 현재 상태를 측정하는 것이 목적입니다. 지표는 다음 정도면 충분합니다. 총 파일 수, 사용되지 않는 파일 수, 미사용 export 수, 100줄 이상 함수 수, 테스트 커버리지.

4.2. 2주차: 안전망 구축

주요 사용자 흐름 3~5개에 대해 E2E 테스트나 통합 테스트를 작성합니다. Playwright, Cypress, Vitest 같은 도구를 사용하면 AI가 테스트 코드도 빠르게 생성해 줍니다. 이 시점에 CLAUDE.md 또는 .cursor/rules/ 같은 규칙 파일에 프로젝트 컨벤션, 금지 사항, 디렉토리 구조 설명을 적어 둡니다.

4.3. 3주차: 데드 코드 삭제

PR 단위로 데드 코드를 삭제합니다. 한 PR당 변경 파일 30개 이내, 변경 라인 1,000줄 이내를 권장합니다. 이 정도 크기여야 리뷰가 가능하고 문제 발생 시 되돌리기 쉽습니다. AI에게 시킬 때는 "이번 PR에서는 X 디렉토리의 미사용 파일만 삭제하고 다른 변경은 하지 말 것"이라고 범위를 명확히 한정합니다.

4.4. 4주차: 구조 리팩토링

인지 복잡도가 높은 파일부터 책임을 분리합니다. AI에게 "이 파일의 책임을 3가지로 나누고, 각각을 어디로 옮길지 계획서를 작성해달라"고 요청한 뒤 사람이 승인합니다. 한 번에 한 파일씩, 테스트를 돌리며 진행합니다.

4.5. 다른 AI에게 비판 맡기기

앞서 본 nomoreannoy 댓글의 "쪼렙이라 다른 AI에게 던져주고 비판하라고 합니다"라는 표현은 농담처럼 들리지만 실제로 유효한 전략입니다. 한 모델이 생성한 코드를 다른 모델에게 리뷰시키면 같은 모델이 놓친 결함을 잡아낼 가능성이 높아집니다. 예를 들어 Claude로 생성한 코드를 GPT-5나 Gemini에게 "보안, 성능, 유지보수성 관점에서 비판해줘"라고 시키거나, 반대 방향으로도 시도할 수 있습니다. 이를 시스템화한 것이 Claude Code의 멀티 퍼소나 리뷰 패턴과 SonarQube의 AI 코드 검증 기능입니다.

4.6. 자주 빠지는 함정

실제 정리 과정에서 흔히 나오는 실수를 표로 정리합니다.

함정증상대응
한 번에 다 지우기PR 변경 5,000줄, 리뷰 불가30파일·1,000줄 이내로 분할
동적 참조 무시문자열로 호출되는 함수 삭제 후 런타임 에러grep과 통합 테스트로 교차 검증
테스트 없이 리팩토링동작 변경을 한참 뒤에 발견특성 테스트를 먼저 작성
AI 단독 판단멀쩡한 코드를 "개선" 명목으로 재작성Plan 모드 + 사람 승인
규칙 문서 부재LLM이 매번 다른 패턴 생성CLAUDE.md, .cursor/rules에 컨벤션 명시
클린업 미루기기능 10개 만든 뒤 한꺼번에 정리 시도매 기능 마지막에 5분 클린업 고정

5. 마무리

위에서 살펴본 바이브 코딩 레거시·데드 코드·스파게티 코드 정리 전략의 핵심 내용을 정리하면 다음과 같습니다.

핵심 요약:

  • 바이브 코딩의 레거시는 테스트 없는 코드 + 작성자도 이해 못 한 코드이며, AI는 삭제보다 추가에 강하므로 사람이 명시적으로 정리를 지시해야 한다.
  • 찌꺼기는 데드 코드, 언리처블 코드, 진입점 없는 UI/라우트, 중복 로직과 죽은 분기의 네 유형으로 나누어 접근한다.
  • 식별은 도구에 맡긴다. JS/TS는 Knip·ts-prune·ESLint, Python은 Ruff·Vulture, 다언어는 SonarQube가 표준 선택지다.
  • 진입점에서 거꾸로 참조 그래프를 따라가며 살아 있는 노드를 정의하고, 그 바깥을 데드 코드 후보로 삼는다.
  • 리팩토링 전 특성 테스트를 먼저 작성해 안전망을 만들고, PR 단위(30파일·1,000줄 이내)로 점진적으로 정리한다.
  • 새 기능은 "스펙 초안 → 영향도 분석 → Plan 승인 → 구현 → 클린업" 순서로 진행하고, 매번 마지막 5분을 정리에 고정한다.
  • 한 AI가 만든 코드를 다른 AI나 SonarQube 같은 정적 분석 도구로 비판하게 해 사각지대를 줄인다.

프로젝트 규모와 단계에 따라 우선순위를 정하면 됩니다. 100파일 미만의 개인 프로젝트라면 Knip + ESLint + Plan 모드 정도로 충분합니다. 팀 단위거나 외부 사용자가 있다면 SonarQube와 E2E 테스트, CI 게이트까지 갖추는 것이 안전합니다. 어느 쪽이든 "한 번의 대청소"가 아니라 "매 기능마다의 작은 정리" 가 바이브 코딩을 롱런시키는 핵심임을 기억하면 됩니다.

자주 묻는 질문

  • 데드 코드와 레거시 코드는 어떻게 다른가요?

    데드 코드는 작성되어 있지만 어디서도 호출되지 않거나 실행 흐름상 도달할 수 없는 구체적인 코드 조각을 의미합니다. 레거시 코드는 더 포괄적인 개념으로, Michael Feathers의 정의에 따르면 테스트가 없어 안전하게 수정하기 어려운 코드 전체를 가리킵니다. 바이브 코딩에서는 작성자도 이해하지 못한 코드까지 포함됩니다. 데드 코드는 레거시 코드 안에 포함되는 한 유형이라고 볼 수 있습니다.

  • 초보자가 가장 먼저 도입할 정리 도구는 무엇인가요?

    JavaScript/TypeScript 프로젝트라면 Knip이 가장 친절한 출발점입니다. `npx knip` 한 줄로 사용되지 않는 파일, export, 의존성을 한 번에 보여 줍니다. Python이라면 Ruff가 ESLint와 Vulture 역할을 한 번에 처리합니다. 여기에 ESLint나 Ruff의 미사용 변수 규칙을 켜 두는 것만으로도 일상적인 찌꺼기는 상당 부분 막을 수 있습니다.

  • AI에게 "안 쓰는 코드 다 지워줘"라고 한 번에 시켜도 되나요?

    권장하지 않습니다. 문자열로 호출되는 함수, 리플렉션, i18n 키, 외부에서 import하는 라이브러리 export 등 정적 분석이 놓치는 동적 참조가 같이 삭제될 수 있습니다. 도구로 후보를 뽑은 뒤 사람이 검토하고, AI에게는 한정된 범위와 명확한 삭제 목록을 주는 분업 방식이 안전합니다. Plan 모드를 활용해 실행 전에 변경 사항을 검토하는 것이 좋습니다.

  • 리팩토링을 시작하기 전에 꼭 해야 하는 일이 있나요?

    현재 동작을 고정하는 테스트를 먼저 만드는 것입니다. 완벽한 단위 테스트가 아니어도 됩니다. 주요 사용자 흐름 3~5개를 끝에서 끝까지 검증하는 E2E 테스트나 핵심 API의 통합 테스트 정도면 충분합니다. 이런 특성 테스트(Characterization Test)가 없으면 리팩토링 과정에서 발생한 동작 변경을 한참 뒤에야 발견하게 되어 복구 비용이 커집니다.

  • 스파게티 코드가 되지 않도록 새 기능을 추가하는 흐름은 어떻게 잡아야 하나요?

    스펙 문서 초안 작성, 영향도 분석, 누락 케이스 보강, Plan 모드로 구현 계획 검토, 구현, 마지막 5분 클린업 단계를 매번 반복하는 흐름이 좋습니다. 특히 클린업 단계를 모든 기능 추가의 마지막 항목으로 고정해 미사용 import 제거, 중복 함수 통합, 임시 로그 삭제, 테스트 추가를 빠뜨리지 않는 것이 핵심입니다.

  • 팀 없이 혼자 개발하는데도 SonarQube까지 필요할까요?

    외부 사용자가 없는 개인 프로젝트라면 SonarQube는 과합니다. Knip 또는 ts-prune에 ESLint, Prettier, 그리고 Husky + lint-staged 정도면 충분합니다. 다만 결제, 인증, 개인정보 처리처럼 보안이 중요한 기능이 들어간다면 SonarQube Community Edition이나 Snyk의 무료 플랜을 추가해 보안 취약점을 자동 점검하는 것을 권장합니다.

  • 한 AI가 만든 코드를 다른 AI에게 검토시키는 게 정말 효과가 있나요?

    효과가 있습니다. 모델마다 학습 데이터와 추론 경향이 다르기 때문에 한 모델이 놓친 결함을 다른 모델이 잡아내는 경우가 많습니다. 특히 보안, 성능, 엣지 케이스 검토에서 차이가 큽니다. 다만 두 AI 모두 같은 종류의 실수를 하는 경우도 있으므로 최종 판단은 사람이 정적 분석 도구의 결과와 함께 내리는 것이 안전합니다.