Codex를 활용한 코드 리뷰와 리팩토링

최근 개인 프로젝트의 인증 구조를 NextAuth 중심의 모놀리식 형태에서 별도의 중앙 인증 서버로 분리했다. 처음엔 단순히 로그인 API를 떼어내는 작업이라고 생각했지만, 실제로는 사용자 식별자, 권한 경계, 배포 구조, 운영 환경까지 전부 다시 점검하는 대규모 공사였다.
이 과정에서 AI(Codex)를 단순한 코드 작성 도구로만 쓰지 않고, 깐깐한 코드 리뷰어처럼 활용해 보았다. 결론부터 말하자면, AI 코드 리뷰의 진짜 가치는 코드를 예쁘게 다듬는 것이 아니라 개발자가 놓치기 쉬운 위험한 경계 위반을 날카롭게 짚어내는 데 있었다.

리뷰의 질은 ‘기준’이 결정한다

AI에게 무턱대고 코드를 던져주면 “이 변수명은 어색하네요” 수준의 뻔한 잔소리만 돌아온다. AI 코드 리뷰가 진짜 유용해지려면 먼저 명확한 채점 기준표가 필요했다.
이번 프로젝트에서는 다음 원칙을 문서화하여 AI에게 주입했다.

  • 인증 서버(workspace_auth)만이 유일한 인증 원본이다.
  • 각 서비스는 authUserId를 장기 식별자로 사용해야 한다.
  • 클라이언트가 임의로 보낸 userId를 절대 신뢰해서는 안 된다.

이러한 명확한 기준이 생기자, AI는 단순한 스타일 지적을 넘어 시스템 설계 위반을 선명하게 짚어내기 시작했다.

코드 리뷰 규칙을 크게 3가지로 나누어 항상 참조하도록 했다.

코드보다 ‘경계’가 먼저다

인증 서버를 분리할 때 가장 골치 아팠던 건 JWT 발급 로직이 아니었다. 진짜 난관은 ‘어느 서비스가 무엇을 책임지는가’를 다시 정의하는 일이었다.

  • workspace_auth: 계정, 비밀번호 해시, OAuth 계정 연결, Refresh Token 관리
  • timetable_db: 시간표, 별명 등 앱 도메인 데이터 관리

문제는 기존 앱이 이메일을 기준으로 사용자를 연결하고 있었고, 일부 API는 클라이언트가 넘긴 userId를 맹신하고 있었다는 점이다. 코드를 고치기 전에 데이터와 권한의 경계부터 확실히 정리해야만 했다.

AI가 찾아낸 3가지 치명적 결함

AI는 내가 작성한 코드에서 생각지도 못한 구멍들을 귀신같이 찾아냈다.

  1. 클라이언트 userId 맹신 (권한 우회 취약점)
    가장 먼저 지적받은 건 시간표 API가 요청 바디나 쿼리스트링으로 들어온 userId를 그대로 믿고 처리한다는 점이었다. 이는 단순한 버그가 아니라, 악의적인 사용자가 다른 사람의 시간표를 마음대로 읽고 쓸 수 있는 심각한 권한 우회 취약점이다. 리팩토링의 늪에 빠져 흐름을 놓치기 쉬웠는데, AI가 “설계 기준 위반”이라며 정확히 브레이크를 걸어주었다. 결국 서버가 항상 인증된 토큰을 기준으로 로컬 사용자를 식별하도록 수정했다.
  2. authUserId 전환 중 발생한 동시성 문제 (경쟁 상태)
    이메일 중심 연결을 authUserId 중심 구조로 바꾸면서 기존의 upsert 로직을 풀어썼다. 언뜻 보기엔 문제가 없었지만, AI는 이 로직이 동시에 여러 요청을 받을 경우 치명적일 수 있다고 경고했다. 두 요청이 동시에 “아직 사용자가 없네?”라고 판단하고 각각 create를 시도하다가 고유 키(unique) 충돌이나 500 에러를 뿜어낼 수 있는 구조였다. AI의 지적 덕분에 해당 부분을 트랜잭션과 재시도 로직으로 안전하게 감쌀 수 있었다.
  3. 장애를 인증 실패로 퉁치는 안일한 에러 처리
    또 하나 뼈아팠던 지적은 /auth/verify 호출이 실패했을 때 무조건 “잘못된 토큰”으로 처리하던 로직이었다. 만약 인증 서버가 죽었거나 일시적인 네트워크 장애로 500 에러가 발생해도, 사용자 앱은 “내 토큰이 만료됐나?”라고 오해하고 불필요하게 로그아웃을 시도하게 된다. 이는 운영 단계에서 디버깅을 지옥으로 만드는 원인이 된다. 리뷰를 반영하여 INVALID_ACCESS_TOKENAUTH_SERVER_UNAVAILABLE을 명확히 분리해, 사용자의 인증 문제와 서버 장애를 구분하도록 개선했다.

AI 코드 리뷰 사용 경험

이번 경험을 통해 느낀 AI 코드 리뷰의 장단점은 명확했다.

  • 강점 (설계와 보안의 수호자): 문법이나 포맷 교정보다는 설계 문서와 금지 규칙을 기반으로 보안 경계와 회귀 위험을 빠르게 찾는 데 탁월했다. “이 책임이 정말 여기 있어도 되는가?”, “이 에러 처리가 운영에 어떤 오해를 만들 수 있는가?” 같은 본질적인 질문을 던져주는 훌륭한 러닝 메이트였다.
  • 한계 (운영 환경의 맹점): 반대로, 코드를 벗어난 운영 환경의 문제는 전혀 예측하지 못했다. CORS 설정, 인증서 발급, Docker 내부망 문제(host.docker.internal), GitHub Actions 시크릿 포맷(따옴표 문제) 같은 인프라 이슈는 결국 직접 브라우저 에러 로그를 뒤지며 몸으로 때워야 했다. AI는 강력한 보조 수단일 뿐, 운영 진단까지 대신해주진 않는다.

댓글 달기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다

위로 스크롤