얼쑤는 악보에서 음표를 골라 번호를 매기고, 앱이 지정한 시작 번호와 끝 번호로 연습 구간을 자릅니다. 쉼표는 악보의 시간에는 영향을 주지만 번호를 매기는 음표 목록에는 들어가지 않습니다. 저장된 이벤트를 읽을 때는 그래서 kind가 NOTE인 항목만 골랐습니다.

이 필터에는 한 가지 가정이 있었습니다. NOTE가 아닌 항목은 모두 알고 있는 다른 이벤트라는 가정입니다. 실제로는 Note라는 오타도 같은 방식으로 빠집니다. 중간 음표 하나가 빠진 뒤에도 요청 범위가 남은 음표 수 안에 있다면, 뒤의 번호는 하나씩 밀리고 서버는 다른 음을 골라 응답할 수 있습니다.

구간 선택 전 이벤트 종류 확인

변환기에서 이벤트가 배열인지 보고 각 항목의 종류가 NOTE 또는 REST인지 먼저 확인하도록 바꿨습니다. 모르는 종류를 만나면 악보 변환을 중단합니다. 그 뒤에 음표만 골라 요청 구간을 확인합니다.

이 선택은 당시 악보 버전의 계약에 맞춘 것입니다. 앞으로 새로운 이벤트 종류를 도입한다면, 그 종류가 시간과 음표 번호에 미치는 영향을 정한 뒤 읽는 쪽도 함께 바꿔야 합니다. 미리 필터에서 건너뛰면 이전 서버가 새 악보를 해석할 수 있는지 구별하기 어렵습니다.

리뷰에서는 값 검사와 로그, 코드 위치도 논의했습니다. 당시에는 틀린 채점이 정상 결과로 저장될 수 있는 이벤트 종류 검사를 먼저 고쳤습니다. 악보 생성 단계가 보장하거나 이미 오류로 드러나는 조건은 기존 경계에서 처리하기로 했습니다.

쉼표 오타로 종류 검사만 검증

회귀 테스트에는 정상 악보의 REST 하나를 Rest로 바꾼 입력을 넣었습니다. 쉼표는 원래도 음표 수에 들어가지 않으므로 오타가 있어도 요청 구간의 경계는 그대로입니다. 종류를 검사하는 코드가 있어야만 이 입력을 거절할 수 있습니다.

NOTE에 오타를 넣는 방법도 생각했지만, 음표 개수가 줄어 구간 검사에서 먼저 실패할 수 있습니다. 그러면 종류 검사를 지워도 테스트는 여전히 거절을 확인합니다. 쉼표를 REST에서 Rest로 바꾼 회귀 검사는 이 두 원인을 구별합니다. 악보 변환기 검사 6개를 다시 실행해 모두 통과했습니다. 같은 변환기 테스트는 정상 악보에서 쉼표를 음표 번호에 포함하지 않고, 쉼 뒤의 시작 박은 유지하는지도 확인합니다.

이 변환은 채점 서비스에 요청을 보내기 전에 실행됩니다. 구현에서 악보를 변환하다 예외가 나면 채점 서비스 호출 단계에 들어가지 않습니다. 실행 중인 시도와 마감 조건이 맞으면 서버 오류로 실패를 기록하는 경로로 이어집니다. 이 연결은 코드에서 확인한 흐름입니다. 같은 오타를 실제 API에서 제출부터 결과 조회까지 재현했거나 운영 악보에서의 발생 빈도를 측정한 기록은 없습니다. 쉼표의 번호는 빼면서 시작 박을 보존하는 문제는 별도의 시간축 글에서 다뤘습니다. 쉼표가 바꾼 아리랑 음표 45개의 시작 박