AI에게 코딩을 맡겨 커뮤니티 서비스를 혼자 만들었습니다. 빨랐습니다. 몇 주 만에 배포까지 갔습니다.
문제는 속도가 아니었습니다. AI가 "적용 완료했습니다"라고 한 것들이 실제로는 안 되어 있던 경우가 꽤 있었다는 겁니다. 그것도 하필 보안과 프라이버시에서요.
세 가지만 적어보겠습니다. 전부 같은 얼굴을 하고 있었습니다.
사용자가 글을 공개/비공개로 쓸 수 있게 만들었습니다. 비공개 필터를 손보려고 현재 상태를 확인하던 중, 제 개발 기록에 이렇게 쓰여 있더군요.
개별 글 상세 페이지: 비공개 게이트 적용 완료
그 기록을 믿고 "그럼 목록 필터만 고치면 되겠네" 하고 넘어갈 뻔했습니다. 확인차 코드를 다시 읽었습니다.
실제로 게이트가 걸려 있던 건 공유용 페이지 하나뿐이었습니다. 정작 글을 불러오는 핵심 API에는 아무 검사가 없었습니다. 글 ID만 알면 남의 비공개 글 본문이 통째로 열렸습니다.
목록 필터만 고치고 만족했다면 이 구멍은 그대로 남았을 겁니다.
출시 후 며칠간 손볼 게 있어서 가입을 닫았습니다. 코드에는 이렇게 되어 있었습니다.
SIGNUP_OPEN = false
저는 이걸 "가입이 닫혔다"는 사실로 믿고 3일간 마음 편히 작업했습니다.
그 상수는 프론트엔드 파일에 있었습니다. 하는 일은 로그인 화면에서 가입 탭을 숨기는 것뿐이었습니다. 서버는 그 존재를 몰랐습니다. curl로 요청 한 번 보내면 계정이 만들어졌습니다. 3일 내내 API로는 누구나 가입할 수 있었습니다.
프론트엔드 플래그는 보안이 아니라는 것. 아는 얘기였는데, 제가 쓴 코드인데도 잊고 있었습니다.
탈퇴 방식을 바꾸면서 약관 문서를 고쳤습니다. 사이트의 약관 페이지가 그 문서를 읽어서 보여준다고 생각했습니다.
실제로는 페이지 안에 문자열이 통째로 하드코딩된 사본이었습니다. 문서만 고치고 페이지는 안 건드렸으니, 구현과 다른 옛날 약관이 그대로 공개되어 있었습니다. "탈퇴 시 개인정보를 지체 없이 파기"라고 적힌 채로요. 실제로는 익명화 방식으로 바꿨는데 말입니다.
세 개의 얼굴이 같습니다. 기록과 의도는 맞았고, 코드는 달랐습니다.
AI는 각 단계를 성실히 처리했고, 저는 그 보고를 성실히 기록했습니다. 문제는 "완료"라고 쓰인 항목을 다시 확인하지 않는 근거로 썼다는 겁니다. 빠르게 진행되니까 검증을 건너뛰게 되고, 그 사이 "됐다고 들은 것"과 "실제로 된 것" 사이에 조용히 간격이 벌어졌습니다.
혼자 만들면 이걸 잡아줄 사람이 없습니다. 리뷰어가 저 하나였습니다.
만든 AI(Claude Code) 말고, 다른 AI(Codex)에게 서비스를 점검시켰습니다. 결과가 나쁘지 않았습니다. 제가 놓친 걸 몇 개 잡아줬습니다. 랜딩 페이지가 검색엔진에 사실상 빈 화면으로 보인다는 것, 공유용 이미지가 없다는 것 - 유입에 직접 걸리는 문제였습니다.
그런데 그 검토 AI도 완벽하진 않았습니다. "생일을 필수로 받지 말라"고 지적했는데, 우리 서비스는 생일로 별자리를 만들어 화면에 배치하는 구조라 생일을 함부로 뺄 수 없었습니다. 검토 AI는 가입 화면만 봤지, 그 뒤의 의존성을 몰랐던 겁니다.
결국 두 AI의 말을 다 받아서, 뭘 받아들이고 뭘 버릴지는 제가 판단해야 했습니다.
AI로 개발하면서 이런 작업 방식이 굳었습니다.
AI로 개발할 때 진짜 위험은 AI가 못 만드는 게 아니라, 안 된 걸 됐다고 말하는데 그게 너무 그럴듯한 것 같습니다. AI는 새롭지만, 거르는 방법은 낡았습니다. 믿지 말고, 확인한다.
혼자 만드는 관심사 커뮤니티를 개발하며 겪은 일들을 기록합니다. → galaxyconstellate.com