5.8 KiB
5.8 KiB
tags
| tags | ||||||
|---|---|---|---|---|---|---|
|
260309 9시 네이버 이메일 분석 실패 은닉 해결 계획
상위 원칙
- Infra Project Identity
- Core Infrastructure Principles
- Operational Guardrails
- 공통 작성 원칙: 0_VALUE Writing Principles
관련 문서
목표
- 네이버 이메일 분석 브리핑에서
메일 조회 실패와실제 메일 0건을 분리한다. rb8001스케줄러가 실패를 성공처럼 기록하지 않도록 한다.- 재발 시
auth refresh 지연인지NAVER WORKS 외부 API 지연인지 로그만으로 구분 가능하게 만든다. expires_at시간대 정합성 위험을 별도 판단 가능한 상태로 만든다.
문제 정의
- 현재
rb8001/app/services/skills/naverworks_briefing.py는skill-email /messages호출 실패를return []로 삼킨다. - 그 결과
process_briefing()는 실패를No emails in the last 24 hours로 오인하고 종료한다. - 이 구조는 상위 SSOT의
Truth First,근본 원인 직접 수정 우선,광범위 예외 폴백 금지원칙과 충돌한다.
범위 고정
1차 수정 대상
rb8001/app/services/skills/naverworks_briefing.pyskill-email/main.pyskill-email/services/naverworks_provider.py
1차 검증 대상
rb800109:00 스케줄 실행 경로skill-email /messages?provider=naverworksauth-server /auth/naverworks/passport/refresh
2차 판단 대상
main_db.naverworks_token.expires_at컬럼 타입 변경 필요 여부- 컨테이너 시간대 통일 여부 또는 만료 판단 로직의 시간대 명시 처리
실행 원칙
- 실패를
메일 0건으로 대체하지 않는다. except Exception으로 원인성 실패를 일괄 래핑하지 않는다.timeout,비200 응답,응답 구조 이상,토큰 갱신 실패를 구분해 기록한다.- 수정 후에는 로그, 헬스체크, 재현 테스트로 실제 실패 표현이 교정됐는지 확인한다.
단계별 계획
1. rb8001에서 실패 은닉을 제거한다
_fetch_recent_emails()가[]대신 원인성 예외를 올리도록 바꾼다.- 최소 분기 대상:
httpx.ReadTimeouthttpx.ConnectError비200 응답- 응답 JSON 구조 이상
process_briefing()는실제 0건일 때만No emails로 처리하고, 조회 실패는 스케줄러 실패로 남기게 바꾼다.
2. skill-email 단계별 원인 로그를 보강한다
/messages경로에서provider=naverworks처리 시 다음 단계 로그를 남긴다.- DB 토큰 조회 시작/종료
- 만료 판단 결과
- refresh 호출 여부와 응답 코드
- NAVER WORKS 외부 API 호출 시작/종료와 소요시간
- 로그는 성공/실패 모두 같은 요청 흐름에서 이어서 대조 가능해야 한다.
3. expires_at 정합성 위험을 코드와 데이터 기준으로 판단한다
- 현재
naverworks_token.expires_at가timestamp without time zone인 상태를 전제로, 실제 만료 판단이 어떤 시간대 기준으로 이뤄지는지 명시한다. skill-email의 만료 비교 시각과 DB 기록 시각이 같은 시간대 기준으로 비교되도록 정리한다.- 선택지는 둘 중 하나로 고정한다.
- 컬럼 타입을
timestamptz로 승격 - 비교 전후를 모두 명시 timezone 기준으로 변환
- 컬럼 타입을
- 이 단계는 폴백 추가가 아니라, 판단 기준을 하나로 고정하는 작업이어야 한다.
4. 재현 검증으로 닫는다
- 정상 케이스:
- 현재와 같은
/messages요청이 정상 응답하고 브리핑이 실제 전송되는지 확인한다.
- 현재와 같은
- 실패 케이스:
- 내부적으로 timeout 또는 비정상 응답을 재현했을 때 스케줄러가 실패로 남는지 확인한다.
- 토큰 만료 케이스:
- 만료 상태에서 refresh가 정상 수행되면 성공으로 이어지고, refresh 실패 시 원인성 실패로 남는지 확인한다.
검증 계획
1. 코드 검증
rb8001에return []기반 실패 은닉 경로가 남아 있지 않은지 확인한다.skill-email로그가 단계별로 남는지 확인한다.
2. 로그 검증
- 성공 케이스에서는
메일 0건과조회 성공 0건이 구분된다. - 실패 케이스에서는
No emails대신timeout,refresh failed,works api failed같은 원인 로그가 남는다. - 스케줄러 로그에는 실패 시
completed successfully가 남지 않는다.
3. 실행 검증
rb8001에서 수동 브리핑 실행 시 정상 메일 조회와 Slack 전송이 통과한다./messages단건 호출로 성공/실패 응답 시간이 확인된다.auth-server /refresh와skill-email /messages를 같은 시각대에 대조해 병목 위치를 구분할 수 있다.
완료 조건
- 네이버 이메일 조회 실패가 더 이상
No emails로 표시되지 않는다. - 9시 브리핑 실패 시 스케줄러와 로그가 모두 실패로 기록된다.
skill-email로그만으로도DB/refresh/외부 API중 어느 단계에서 지연됐는지 구분 가능하다.expires_at만료 판단 기준이 시간대 혼선 없이 하나로 설명 가능하다.