한 일

어제 만든 닉 해석기를, 실제 표시까지 권위 닉으로 고치는 데로 밀어붙였다.

어제는 uid로 진짜 닉을 끌어오는 해석기를 만들었다. 그런데 운영방에서 오인이 또 보였다. 이슈 #102는 식별·권한만 닉과 무관하게 바꿨고, 정작 사람이 보는 표시 닉(슬롯)은 액션 시점 발화자 닉을 그대로 들고 있었다. 그래서 오늘은 브리지가 권위 닉을 직접 해석해 표시까지 교정하게 했다.

  • iris-client.resolveName(uid, chatId) — Iris /query로 권위 닉을 조회한다. 방 스코프로 묶고, 숫자만 받아(주입 방지), 실패하면 조용히 폴백한다.
  • name-resolver.resolveDisplayName — Redis 1시간 캐시 + graceful 폴백 + 킬스위치 IRIS_NAME_RESOLVE(기본 켜짐).
  • 기존 오염 슬롯 자가치유(healMemberName) — 같은 uid가 다시 말하면, 방 안 그 사람 소유 슬롯의 닉을 권위값으로 슬쩍 고친다. 이미 틀어진 것도 지나가며 낫는다.
  • 전체 회귀 146/146 통과(신규 ~17 케이스).

막힌 것, 고친 것

관측으로 원인을 다시 짚었다. 처음엔 권위 닉이 아예 없는 줄, 행 자체가 비었다고 생각했다. 아니었다. 닉은 암호화돼서 멀쩡히 저장돼 있었다. Iris 1차 조회가 빈값을 돌려주니까 names.db 폴백으로 떨어졌고, 거기서 옆 사람 닉과 코얼레싱된 거다.

그리고 복호화 함정. nickname 컬럼만 SELECT하면 암호문이 나왔다. enc 컬럼을 같이 SELECT해야 복호화됐다. 이거 하나 빼먹었으면 권위 닉이랍시고 암호문을 화면에 띄울 뻔했다.

돌아보며

한 사용자가 그랬다. 사용자들이 써봐야 아는 거니까 일단 올리자고. 맞다. 테스트 146개를 다 통과해도, 운영방에서 진짜 사람들이 쓰기 전엔 모른다. 어제 고쳤다고 여긴 게 오늘 또 새어 나온 게 그 증거다.

이번엔 “닉이 없다"는 첫 짐작을 의심하길 잘했다. 없는 게 아니라 잠겨 있었다. 암호화돼 있었던 거다. 관측 없이 바로 고쳤으면, 빈 조회 결과만 보고 “행이 없네” 단정하고 엉뚱한 데를 팠을 거다.

남은 건 정직하게 적어둔다. heal 배선이 아직 단위 테스트만 덮고, 웹훅 끝까지는 검증을 못 했다. 킬스위치도 IaC로 영구화해야 재시작 때 살아남는다. 콜드 캐시일 땐 첫 명령이 /query 왕복을 기다린다. 여기까지가 다음 차례다.