[AI와 같이 고친 에러들] 문자 중복차단이 새 주문까지 막던 이유

자동화는 잘 돌아갈 때보다 조용히 멈출 때가 더 무섭습니다. 이번 작업도 그랬습니다. 문자로 들어온 주문 알림을 받아 사내 알림으로 넘기는 흐름이 있었는데, 어느 순간부터 특정 주문 이후의 문자가 들어오지 않는 문제가 생겼습니다.

처음에는 “웹훅 수신 자체가 죽었나?”라고 생각했습니다. 비개발자인 김부장 입장에서는 웹훅, 라우트, 중복 차단 같은 말이 다 비슷하게 들립니다. 그런데 AI와 함께 로그와 최근 수정 이력을 따라가 보니 서버가 완전히 멈춘 것은 아니었습니다. 더 정확히는 ‘너무 잘 막아서’ 생긴 문제였습니다.

중복을 막으려다 새 주문도 막았다

이 자동화에는 같은 문자가 여러 번 들어왔을 때 중복 발송을 막는 장치가 있었습니다. 서버리스 환경에서는 요청이 매번 다른 인스턴스로 갈 수 있어서 메모리에만 기록해 두는 방식을 믿기 어렵습니다. 그래서 DB에 fingerprint를 남겨 ‘오늘 이미 처리한 메시지인지’ 확인하도록 바꿔 둔 상태였습니다.

방향은 맞았습니다. 문제는 fingerprint를 만들 때 메시지 전체가 아니라 앞부분 일부만 사용했다는 점이었습니다. 앞부분은 같고 뒤쪽의 배송지나 연락처 같은 정보만 다른 주문 문자가 여러 개 오면, 시스템은 둘을 서로 다른 주문으로 구분하지 못했습니다. 결국 두 번째 주문을 ‘오늘 이미 처리한 중복’으로 오해하고 조용히 건너뛰었습니다.

에러가 아니라 ‘스킵’이었다

이런 문제는 더 헷갈립니다. 프로그램이 멈추면 에러라도 보입니다. 그런데 이번에는 실패가 아니라 정상적인 중복 차단 로직으로 분류되어 지나갔습니다. 사용자는 “문자가 안 들어온다”고 느끼지만, 코드 입장에서는 “이미 처리한 것을 잘 막았다”고 생각한 셈입니다.

AI와 함께 확인한 것은 세 가지였습니다. 첫째, 최근 중복 발송을 막기 위해 어떤 커밋이 들어갔는지 살폈습니다. 둘째, 실제 중복 판정에 어떤 문자열을 쓰는지 확인했습니다. 셋째, 같은 앞부분을 가진 서로 다른 주문이 충돌할 수 있는지 따져봤습니다. 그 결과 원인은 꽤 단순했습니다. 메시지 앞 120자만 잘라 fingerprint를 만들고 있었던 것입니다.

일부가 아니라 전체 메시지로 판단하기

수정은 크지 않았습니다. 중복 판정용 key를 앞 120자에서 메시지 전체로 바꿨습니다. 그리고 빌드를 돌려 전체 프로젝트가 깨지지 않는지 확인했습니다. 여기서 제가 배운 점은 ‘코드 한 줄’보다 ‘어떤 기준으로 같은 것이라고 판단할지’가 더 중요하다는 것이었습니다.

중복 차단은 꼭 필요합니다. 자동화가 같은 알림을 두 번 보내면 현장은 바로 불편해집니다. 하지만 중복을 막는 기준이 너무 거칠면 이번처럼 진짜 새 데이터까지 사라집니다. 비개발자인 저는 이 일을 겪으며 자동화에서 가장 무서운 실수는 대놓고 실패하는 것이 아니라, 그럴듯한 성공처럼 보이는 누락이라는 생각을 했습니다.

김부장이 배운 점

이번 기록을 계기로 앞으로 자동화를 고칠 때 ‘막는다, 보낸다’만 보지 않기로 했습니다. 무엇을 같은 것으로 볼지, 같은 날 여러 건이 들어오면 어떤 값까지 비교해야 하는지, 조용히 건너뛰는 경우도 로그에 남는지까지 함께 봐야 합니다.

AI가 코드를 대신 고쳐주는 것도 도움이 되지만, 더 큰 도움은 질문의 순서를 잡아주는 데 있었습니다. “웹훅이 죽었나?”에서 시작해 “중복 판정 기준이 너무 좁은가?”로 범위를 좁혀 간 과정이 이번 작업의 핵심이었습니다.

다음 편에서는 같은 긴 작업 세션 안에 있던 인쇄 양식 개선 이야기를 이어서 적어볼 생각입니다. 현장에서 손으로 확인해야 하는 값과 시스템이 미리 채워줄 수 있는 값을 어떻게 구분했는지에 대한 기록입니다.

댓글 남기기