금요일에 만들었는데 수요일에 등록되는 시간표
아들 앞에서 시연하다 발견한 요일 버그. 출근길이 길었습니다.
금요일에 만들었는데 수요일에 등록되는 시간표
오늘 아침, 밥을 먹고 있는데 아들이 물었습니다.
“아빠, 이거 시간표 기능도 있어?”
Fecit에는 시간표 기능이 있습니다. 매일, 매주, 매월 반복되는 일을 시간대별로 등록해 두면 자동으로 태스크가 생성되는 기능입니다. 아들한테 보여주기 딱 좋은 기능이라 바로 시연했습니다. Weekly Routine을 열고, 금요일을 선택하고, 시간을 지정하고, 등록.
그런데 등록된 루틴의 요일이 수요일이었습니다.
분명히 금요일을 눌렀습니다. 화면에도 금요일이 선택되어 있었습니다. 그런데 저장된 건 수요일. 아들 앞에서 “이거 되는 건데…” 하면서 한 번 더 해봤지만 결과는 같았습니다. 출근 시간이라 더 확인할 수 없었고, 그냥 나왔���니다.
출근길 내내 마음이 좋지 않았습니다. 아들이 관심을 보인 건 처음이었는데, 하필 그 순간에 버그가 터졌습니다. “아빠가 만든 거 좀 이상한데?” 같은 말은 안 했지만, 그게 더 신경 쓰였습니다.
원인
회사에 도착하자마자 코드를 열었습니다. 의심가는 곳은 하나였습니다. 서버에서 Weekly Routine을 등록할 때 요일을 어떻게 저장하는지.
day = get_create_reservation_day(
to_local(ticket.start_reference_date, ticket.timezone)
) if ticket.period_type == CreateReservationPeriodType.WEEKLY else ticket.day
이 한 줄이 전부였습니다.
앱은 사용자가 선택한 요일을 ticket.day에 담아서 보냅니다. 금요일을 선택하면 FRI(4)가 들어갑니다. 그런데 서버는 Weekly 타입일 때 이 값을 무시하고, start_reference_date에서 요일을 직접 계산하고 있었습니다.
start_reference_date는 사용자가 시간을 선택할 때 생성되는 Date 객체입니다. 시간만 의미 있고 날짜는 “오늘”이 들어갑니다. 오늘은 수요일. weekday()를 호출하면 WED(2).
금요일을 선택했지만, 서버는 “오늘이 수요일이니까 수요일”이라고 저장한 겁니다.
왜 이렇게 되어 있었나
한 달 전에 비슷한 버그를 고친 적이 있습니다. 그때는 Weekly 알림이 아예 발동하지 않는 문제였는데, 원인은 앱이 요일 값을 보내지 않아서 서버에 빈 칸으로 저장된 거였습니다.
그때의 수정이 “앱이 보내는 값을 믿지 말고, 서버가 직접 계산하자”였습니다. start_reference_date에서 요일을 뽑으면 앱이 값을 안 보내도 괜찮으니까요. 알림 Job은 UTC 기준으로 동작하고, start_reference_date도 UTC로 저장되어 있으니 타임존 문제도 없었습니다.
그 수정은 맞았습니다. 알림 Job 쪽에서는요.
문제는 같은 패턴을 등록 쪽에도 적용한 겁니다. 알림 Job에서는 start_reference_date의 날짜가 의미 있습니다. 실제 루틴이 등록된 시점의 날짜니까요. 하지만 등록 화면에서 start_reference_date는 시간만 의미 있고, 날짜는 그냥 오늘입니다. 여기서 요일을 계산하면 항상 “오늘의 요일”이 됩니다.
이전 수정의 의도는 좋았지만, 적용 범위가 잘못됐습니다.
수정
day = (
ticket.day if ticket.day is not None
else get_create_reservation_day(
to_local(ticket.start_reference_date, ticket.timezone)
)
) if ticket.period_type == CreateReservationPeriodType.WEEKLY else ticket.day
사용자가 요일을 선택했으면 그 값을 쓰고, 선택하지 않았을 때만 start_reference_date에서 계산합니다. 앱이 값을 보내면 존중하고, 안 보내면 서버가 보완하는 구조입니다.
저녁에 할 이야기
퇴근하면 아들한테 이야기해 줘야겠습니다. 아침에 이상했던 거, 아빠가 고쳤다고. 금요일을 누르면 이제 금요일로 들어간다고.
그리고 솔직히 말해 줘야 할 것 같습니다. 네가 물어봐서 열어 본 거였는데, 네 덕분에 버그를 찾았다고. 아들이 관심을 안 가졌으면 이 버그는 더 오래 숨어 있었을 겁니다. 누군가 “이거 되나?”라고 물어보는 게 가장 좋은 테스트라는 걸, 오늘 다시 배��습니다.
출근길은 좀 무거웠지만, 퇴근길은 가벼울 것 같습니다.