Rinda · Beta(Production) Hotfix
만족도 통계 · 시퀀스 진단 500 에러 핫픽스
beta 운영 환경에서 반복 발생하던 HTTP 500 2건의 근본 원인을 제거하고 alpha·beta 양 브랜치에 반영했습니다.
요약
2
해소한 500 에러
3
수정 항목 (버그 2 + 테스트 가드 1)
111
단위테스트 pass / 0 fail
28~36s
로컬 CI (양 브랜치 그린)
해결한 문제
| 엔드포인트 | 증상 | 근본 원인 | 수정 |
|---|---|---|---|
500GET /satisfaction-survey/admin/stats |
reasonRows.map is not a function — 5초간 반복 |
beta postgres 드라이버는 db.execute(sql`…`) 결과를 { rows } 객체로 감싸 반환하는데, getSurveyStats가 배열로 단정하고 .map 호출 → TypeError |
기존 toRows() 헬퍼로 정규화 — 배열·{rows} 양쪽 드라이버 안전 처리 |
500POST /sequences/propose/diagnose |
Aggregated diagnosis failed schema validation | 집계 쿼리는 topBusinessTypes를 LIMIT 10으로 반환하는데 beta 스키마는 .max(5)로 제한 → Zod 검증 실패. alpha는 #8864로 이미 해소된 상태였으나 beta 미반영(22커밋 뒤) |
#8864 체리픽 → 스키마 .max(10) + 대규모 그룹 집계 analyticsDb 라우팅 |
| (가드) 단위테스트 | brochure 섹션 assertion red → 머지 게이트 차단 | prompt-builder가 BROCHURE — MANDATORY로 변경(URL 미주입, 서버가 첨부)됐는데 테스트는 구문구 BROCHURE LINK 기대 → alpha·beta 양쪽 CI red |
테스트 assertion을 신규 동작에 동기화 (실코드 무수정) |
처리 흐름
1
진단 — beta 로그에서 두 500의 정확한 실패 지점 확인.
db-rows.util.ts 정규화 헬퍼가 이미 존재함을 발견(코드베이스 확립 패턴).2
근본 원인 분리 — survey는 드라이버 반환형 차이, diagnose는 alpha엔 이미 있던 #8864가 beta에 미반영. brochure 테스트는 양 브랜치 공통 stale.
3
alpha —
toRows 수정 + brochure 테스트 동기화, 2개 커밋으로 분리 → PR #8893 머지.4
beta — #8864 + survey + brochure 테스트 체리픽 → PR #8894 머지.
5
검증 — 양 브랜치 CI 그린, beta DB에서 reason 분포 SQL 직접 실행(에러 없음 → 버그가 JS 레이어임 확정), beta CD 신규 컨테이너
elysia-server-54 단독 healthy 전환 확인.설계 노트
버그는 SQL이 아니라 JS 레이어에 있었습니다 — db.execute의 드라이버별 반환형 차이(배열 vs {rows})가 환경에 따라 갈렸기 때문에 로컬·alpha에서는 재현되지 않고 beta에서만 터졌습니다.
근본 처방: 케이스별 패치가 아니라 코드베이스에 이미 있던
toRows() 헬퍼를 사용해 모든 드라이버 반환형을 한 곳에서 흡수 — 동일 패턴의 다른 호출부와 일관성 유지(overfitting 회피).