한 일

파티의 ‘출발시간’을 ‘설명’으로 바꿨다. /생성을 할 때 뒤에 붙이는 선택 항목이 원래는 “출발시간"이었다. 시간만 적게 되어 있어 답답했다. 그래서 자유롭게 적는 “설명"으로 바꿨다.

  • DB 컬럼 이름을 departure_time에서 description으로 바꿈 (기존 데이터는 그대로 보존)
  • API 필드와 출력 라벨도 출발시간에서 설명으로 정리
  • 설명에 공백이 들어간 여러 단어를 쓸 수 있게 함
  • 대시보드 SQL, 테스트, 문서까지 같이 맞춤
  • 검증: 테스트 37개 통과, 마이그레이션을 두 번 돌려도 결과가 같고 기존 데이터가 남는 걸 확인

명령어를 손보고, 여러 명 초대를 넣었다. 코드리뷰에서 나온 제안들을 차례로 반영했다. 데이터가 어긋나지 않게 막는 일이 컸다.

  • 한 사람은 한 파티만 — /생성/참가에도 “이미 다른 파티에 있나” 검사를 넣음. 이미 있으면 막고 “/퇴장 후” 안내
  • /참가를 트랜잭션으로 묶어, 마지막 한 자리에 두 사람이 동시에 들어와 덮어쓰는 일을 막음
  • /생성이 동시에 두 번 들어와도 “이미 존재” 안내로 처리
  • 글자 수 제한 — 파티명 20자, 닉네임 30자, 설명 100자
  • 새 명령: /설명(생성 뒤 설명 수정, 파티장만), /내파티(내가 속한 파티와 역할 보기)
  • /초대 닉1 닉2 닉3 — 한 번에 최대 3명. 빈 자리만큼만 넣고, 안 된 사람은 사유를 같이 알려줌
  • 테스트는 37개에서 58개까지 늘었다

한 서버가 여러 방을 따로 운영하게 만들었다 (멀티룸). 원래는 방이 하나라고 가정하고 짠 봇이었다. 이걸 풀었다. 방마다 파티가 따로 놀게 했다. 방을 구분하는 키는 메신저봇R이 주는 방 고유 ID(channelId)를 썼다.

  • rooms 테이블을 새로 만들고, 파티에 방 ID를 붙임
  • 같은 파티 이름이라도 방이 다르면 별개로 동작하게 복합 인덱스로 바꿈
  • 기존 파티들엔 임시 방 표시를 채워 넣어(센티넬) 마이그레이션이 깨지지 않게 함
  • 봇 쪽도 옛 방식에서 메신저봇R API2로 바꿈 — 모든 요청에 방 ID를 실어 보냄
  • 검증: 테스트 58개 통과. 같은 파티명이 방별로 따로 만들어지는지, 강퇴가 방 안에서만 도는지 같은 격리 케이스를 넣음

막힌 것, 고친 것

실기기로 테스트하고 운영에 올리는 과정에서 두 군데서 막혔다.

  • 봇이 아무 응답이 없었다. staging 봇을 깔았는데 조용했다. 리스너를 등록하는 코드가 컴파일 시점 안쪽에 들어가 있어서, API2가 호출되지 않은 게 원인이었다. 등록을 맨 바깥(top-level)으로 빼서 고쳤다.
  • 마이그레이션이 API를 죽였다. 멀티룸이 되면서 같은 파티 이름이 여러 방에 생겼다. 그런데 옛 마이그레이션 단계가 “파티 이름은 유일해야 한다"는 옛 규칙을 다시 걸려다 실패했다. API가 크래시 났고, 스모크 테스트가 502를 내며 운영 승격을 막았다. 그 단계를 빼고 방+이름 복합 규칙으로 대체해서 풀었다.

돌아보며

이번엔 한 단계씩 끊어서 갔다. 지난번에 하루에 너무 많이 몰아넣고 두 번 넘어졌던 게 떠올랐다. 그래서 작은 필드 하나 바꾸는 일부터 손에 익히고, 명령어, 그다음 큰 구조 순으로 갔다. 순서가 있으니 마음이 덜 급했다.

제일 손이 많이 간 건 멀티룸이었다. “방이 하나"라는 가정이 코드 곳곳에 박혀 있었다. 그걸 하나씩 찾아 “어느 방인지"를 같이 넘기게 바꿨다. 핸들러 열 개를 다 만졌다. 지루한 일이지만, 이걸 해두면 방을 더 늘려도 서버는 하나로 충분하다.

봇이 조용했을 때 잠깐 멍했다. 코드는 다 맞는데 응답이 없으면 어디서 끊겼는지 알기 어렵다. 그래도 “리스너가 정말 등록됐나"부터 짚으니 답이 나왔다. 추측으로 여기저기 만지지 않은 게 좋았다.

기존 운영 파티를 잃지 않으려고 임시로 만들고 지우고 옮기는 잔손질도 했다. 데이터를 안 깨고 넘어가는 게 결국 제일 중요하다. 작은 봇이지만, 누군가의 파티 기록이 거기 있으니까.