2026-07-30 PulseUp 작업일지입니다. 오늘은 1건의 작업을 진행했습니다.
Electron 디바이스 웹 연동 선택 불가
현상/기능
- 서버에서 Electron 실행 시 DB device는 등록되나 웹에서 연동 선택이 안 됨 — 서버 확인 로그 유무
- 서버 로그/원인 후속 확인
- 오늘 오후 1시 이후 연동 관련 로그 확인
- pulsebox-api-out.log로 연동 로그 재확인
- 등록은 되는데 웹에서 연동 선택이 안 되는 근본 원인 수정
- WS 연결 실패 원인을 서버 로그로 판별 가능하게
- 서버 재시작·프록시 오류 후 영구 오프라인이 되는 문제와 진단 불가 문제 해결
- 등록/삭제 반복(재등록 루프)을 유발하는 UI 개선
- 재연결 정책 회귀 방지
작업
- 웹 선택은 DB 등록이 아니라 `/electron-relay/connected`(WebSocket 실시간 연결) 기준. 서버 stdout에서 `🔗 디바이스 연결됨`, `📡 [connected] 연결된 디바이스 수=` 로그로 확인 가능. WS 토큰 거부(401)는 서버에 로그가 거의 없음
- nginx 설정에 `/api/`만 있고 `/ws/` location이 없음. Electron은 `wss://…/ws/electron`으로 붙이므로 도메인 경유 시 WS가 SPA로 떨어져 연결 실패 → 웹 선택 불가 가능성이 큼
- PM2 로그에 시각 스탬프 없어 workout UUID로 추정. 13시 이후 확인된 건 14:20경 `Pulse Up(4add8068…)` WS 재연결 및 `start-workout-play` 1건. 선택 다이얼로그 `[connected] 수=0` 기록은 해당 구간에서 없음
- 파일 전체에 `🔗 디바이스 연결됨` 0건. DB 등록(동래점 storeId=3, device `4add8068…`)은 되나 `[connected] 수=0`만 116회. HTTP 등록과 WS 미접속이 분리된 상태로, 웹 선택 불가 원인과 일치
- `map $http_upgrade $connection_upgrade` 추가 후 8080·443 블록에 `location /ws/`(Upgrade 프록시, read/send timeout 3600s)를 신설. 기존 `/api/`의 `Connection 'upgrade'` 하드코딩도 조건부 변수로 교체
- upgrade 핸들러에 경로 불일치·`deviceToken` 누락·토큰 무효·검증 예외 4갈래 로그(토큰 마스킹)를 추가하고, pong 수신 시 60초 스로틀로 `last_seen_at`을 갱신. `/connected`는 매장별 결과가 바뀔 때만 로그를 남겨 PM2 out 폭주를 차단
- 연결 수명주기 로그를 `DEBUG` 무관하게 상시 기록, 재시도 상한(10회) 제거 후 30초 상한 무한 백오프로 변경(중복 예약 방어 포함), `unexpected-response`로 401·403은 등록 초기화+인증 코드 흐름 / 그 외는 재시도로 분기. `POST /api/devices/heartbeat` 30초 주기 전송기를 분리 모듈로 추가하고 등록 폴링 인터벌 누수도 정리
- 등록 디바이스가 있는데 온라인이 0인 경우 "앱이 서버에 연결되지 않음 · 재등록으로는 해결되지 않음" 안내 블록을 노출하고, 새로고침 버튼에 `aria-label` 부여 및 소스 상단 요약 주석 추가
- 지수 백오프 증가·30초 상한·비정상 입력 처리와 401/403→`reauth`, 404/502/503→`retry` 분류 단위 테스트 5건 추가(electron-app 50파일 170건 전체 통과)
- **분석**
- **서버**
- **API**
- **Web**
- **Test**