Skip to content

feat: 피드백 생성 실패 영속 마커 — 새로고침 클라이언트도 실패 구분 - #210

Merged
Jaeho-Site merged 3 commits into
devfrom
feat/feedback-fail-marker
Aug 22, 2026
Merged

feat: 피드백 생성 실패 영속 마커 — 새로고침 클라이언트도 실패 구분#210
Jaeho-Site merged 3 commits into
devfrom
feat/feedback-fail-marker

Conversation

@Jaeho-Site

Copy link
Copy Markdown
Contributor

변경 사항

PR #206/#207 후속. FAILED 처리가 휘발성 SSE 뿐이라 실패 순간 미접속(새로고침·탭 닫힘) 클라이언트는 GET 피드백에서 "생성 중"(404 FEEDBACK_NOT_READY)과 실패를 구분할 수 없어 폴링 예산(≈2분)을 헛태우던 gap 을 닫는다.

Core (backend/)

  • V29: interview_sessionsfeedback_failed_at/feedback_fail_retriable 추가 (nullable, 기존 행 영향 없음)
  • FAILED 콜백 수신 시 InterviewSession.markFeedbackFailed 로 마커 기록, 성공 콜백·재생성 요청 시 클리어
  • GET 피드백·공유 조회: 피드백 없음 + 마커 존재 시 404 FEEDBACK_GENERATION_FAILED(details.retriable) — FEEDBACK_NOT_READY 와 구분 (ApiErrorCode 신규)
  • 재생성의 generate.feedback 발행을 FeedbackRegenerateRequestedEvent → AFTER_COMMIT 리스너로 이동 — 마커 clear 커밋 전에 발행되는 역전 차단 ("메시지 발행은 commit 이후" 규칙, onSessionEnded 와 동일 패턴)
  • SSE/REST 실패 문구·코드를 ApiErrorCode 단일 출처로 통일, 도달 불가한 DataIntegrityViolationException catch(rollback-only) 제거

Frontend (frontend/)

  • isFeedbackFailed 타입가드 — REST 의 FEEDBACK_GENERATION_FAILED 를 SSE 실패와 같은 failure 복구 UI 로 수렴, 폴링 즉시 중단. 페이지 상태 분기 신설 없음 (PR feat: 피드백 생성 실패 SSE 수신 시 즉시 복구 UI 전환 #207 UI 재사용)
  • SESSION_NOT_FOUND(404) pending 오분류 제외 — 삭제된 세션에 2분 폴링하던 결함 수정
  • 마커 영속화에 맞춰 retriable=false 도 재생성 버튼 유지(문구만 조정 — 숨기면 영구 잠금), failure 해제는 재생성 성공 시점으로 일원화, 실패 settle 후 refetchOnWindowFocus 로 타 기기 재생성 흡수

문서

  • database.md(V29 컬럼), api-conventions.md §5(FEEDBACK_* 카탈로그 — 기존 3종 누락 정정 + 신규), event-stream.md §4, messaging.md §5.11, backend/frontend CLAUDE.md
  • openapi.json diff 없음(에러 코드는 스키마 밖). ai/·infra/ 변경 없음

검증

  • backend: 233 passed (+4 신규 테스트: 마커 기록/클리어, GET 분기 2, regenerate 클리어; 이벤트 발행 검증으로 전환). 로컬 실패 4건은 Docker(Testcontainers) 부재 환경 실패로 baseline 동일, 신규 0
  • frontend: 171 passed (+2: REST 실패 수렴, SESSION_NOT_FOUND 비폴링), build·lint 클린
  • frontend-reviewer Critical/Warning 0. 코드 리뷰 10건 판정 중 8건 반영(발행-커밋 역전, 영구 잠금, 404 오분류, failure 해제 일원화, 문구 단일화, 죽은 catch 등), 1건 이관(시도 attemptId 상관관계 — ai/ 계약 변경 필요, 후속 To-do)

후속 (기록)

  • stale FAILED 재마킹 방지용 attempt 상관관계(ai/ 콜백 계약) — consumer 실패 신호 래퍼 일원화와 함께

FAILED 콜백 처리가 휘발성 SSE 뿐이라 실패 순간 미접속 클라이언트가
'생성 중'과 실패를 구분 못 하던 gap 수정. interview_sessions 에
feedback_failed_at/feedback_fail_retriable(V29) 기록 — FAILED 수신 시 마킹,
성공 콜백·재생성 시 클리어. GET/공유 조회는 피드백 없음+마커 존재 시
404 FEEDBACK_GENERATION_FAILED(details.retriable) 로 응답해 NOT_READY 와 구분.
재생성의 generate.feedback 발행은 FeedbackRegenerateRequestedEvent →
AFTER_COMMIT 리스너로 옮겨 마커 clear 커밋 전 발행 역전을 차단.
SSE/REST 실패 문구·코드는 ApiErrorCode 단일 출처로 통일, 도달 불가한
DataIntegrityViolation catch(rollback-only) 제거.
GET 피드백의 404 FEEDBACK_GENERATION_FAILED 를 SSE 실패와 같은 failure 로
파생(isFeedbackFailed 타입가드) — SSE 를 놓친 새로고침 클라이언트도 폴링
1회 만에 복구 UI 로 수렴. SESSION_NOT_FOUND 는 pending 오분류에서 제외.
마커 영속화에 맞춰 retriable=false 도 재생성 버튼 유지(문구만 조정),
failure 해제는 재생성 성공 시점(per-call onSuccess)으로 일원화, 실패
settle 후 refetchOnWindowFocus 로 타 기기 재생성 흡수.
database.md interview_sessions V29 컬럼, api-conventions §5 FEEDBACK_*
카탈로그(기존 3종 누락 정정 + GENERATION_FAILED), event-stream §4 폴링
fallback 의 실패 구분, messaging §5.11 Core 마커 영속화 서술.
@Jaeho-Site
Jaeho-Site merged commit 19d7c3a into dev Aug 22, 2026
5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant