Skip to content

feat: 사용자가 음성 분석을 면접당 2번까지 다시 요청할 수 있게 함(D3) - #95

Merged
kimwuju merged 1 commit into
mainfrom
feat/audio-analysis-retry
Oct 14, 2026
Merged

kimwuju merged 1 commit into
mainfrom
feat/audio-analysis-retry

Conversation

@kimwuju

@kimwuju kimwuju commented Oct 14, 2026

Copy link
Copy Markdown
Contributor

개요

영상·음성 분석 인계 문서(10/14)의 B1, D3 음성 재요청입니다. main(da6abbe) 기준입니다. Analysis 서버는 수정하지 않습니다.

인계 문서가 명세에서 먼저 정하라고 한 두 가지는 아래처럼 정했습니다.

  • 재요청 대상: 결과가 없는 답변과, 파일·timing·fluency 오류 중 retryable=true가 있는 답변만 대상입니다.
    • 정상 결과도 말더듬 라인이 없어 늘 partial입니다. 그래서 "partial이면 허용"을 쓰면 모든 면접이 대상이 됩니다.
    • 라인이 partial이거나 retryable=false이면 같은 음성으로는 결과가 같아 대상에서 뺐습니다.
  • 단위: 버튼은 면접 단위로 하나이고, 실제로는 대상 답변만 새 requestId·새 서명 URL로 보냅니다. 면접당 2회까지입니다(영상의 "영상당 2회"와 같은 방식).

변경

1. API

  • POST /api/interviews/{id}/audio-analysis/retry → 202, 본문은 GET과 같은 AudioAnalysisResponse입니다.
  • 받을 수 없으면 409로 사유를 돌려줍니다: 분석 시작 전 / 이미 분석 중 / 채팅 세션 없음 / 다시 분석할 답변 없음 / 면접당 2번까지.
  • GET …/audio-analysis 응답에 canRetry를 추가했습니다.

2. 재요청 처리 (AudioAnalysisService.retry)

  • 트랜잭션 하나로 두 가지를 합니다.
    • 음성 분석 대기 행을 reopenForUserRetry로 되돌립니다. 상태 DONE·FAILED, user_retry_count < 2 조건을 확인하고, 시도 횟수를 0으로, 재요청 횟수를 +1 합니다.
    • 대상 녹음을 jobId 없는 PENDING 요청 행으로 만듭니다.
  • 실제 전송은 기존 대기 스윕이 합니다. confirmAcceptance가 jobId 없는 행을 그 requestId로 보냅니다. 따로 보내는 길은 없습니다.
  • 한도 확인과 상태 변경이 조건부 갱신 한 문장이라, 연달아 누른 요청은 둘째가 409를 받습니다.

3. 조회·재전송 규칙

  • 결과보다 나중 요청이 그 녹음을 다시 분석하는 중이면 그 답변은 PENDING입니다. 앞선 결과를 보여 주면 전체 상태가 PENDING에서 벗어나 웹이 조회를 멈추고 새 결과를 놓칩니다.
  • "이미 맡긴 녹음"의 기준을 녹음을 실은 가장 나중 요청이 FAILED가 아닌 것으로 바꿨습니다.
    • 재요청이 5xx 등으로 닫혀도 그 녹음은 다시 나갑니다. 앞선 결과가 있다고 버려지지 않습니다.
    • 기존 흐름에서는 동작이 같습니다.
  • 요청 행 생성 코드 세 곳을 newRequest로 합쳤습니다.

4. DB

  • V33__add_audio_analysis_user_retry.sql: feedback_dispatch.user_retry_count INTEGER NOT NULL DEFAULT 0

테스트

  • 로컬 Postgres에서 전체 619개 통과했습니다.
  • 추가한 테스트
    • 재요청 대상 판정: 정상 partial 제외, retryable=false 제외, 파일 오류가 retryable=true면 포함
    • canRetry
    • 재요청이 만드는 행과 대기 행 되돌림
    • 409 사유
    • 닫힌 재요청의 재전송
    • 재요청 행의 첫 전송
    • 재분석 중 PENDING 표시
    • 실제 DB에서 reopenForUserRetry: 요청 중이면 0, FAILED도 받음, 한도에서 0
    • 컨트롤러 202

다른 레포

  • Web: 결과 화면에 canRetry일 때만 재요청 버튼을 보여 줍니다. 요청 뒤 PENDING인 동안 다시 조회합니다. docs/interview-recording.md 조회 계약에 canRetry와 재요청 엔드포인트를 추가해야 합니다.
  • Analysis: 변경 없습니다. 새 requestId는 새 작업으로 받습니다(계약 그대로).

리뷰 시 참고

  • 이번 범위 밖의 기존 문제를 발견해 따로 다룹니다. 콜백이 유실된 채 작업이 15분 안에 끝나지 않으면 음성 분석이 PENDING에서 빠져나오지 못합니다.
    • 복구 스윕이 1분마다 대기 행을 되돌리면서 시도 한도(5)를 약 15분 만에 다 씁니다. 그러면 대기 행이 FAILED로 닫혀, 포기 시간 1h에 닿지 못합니다.
    • 그동안 웹은 계속 조회하고, 재요청은 "이미 분석 중"으로 막힙니다.
  • retry가 대기 행의 lastActivityAt을 바꾸지 않습니다. 면접을 마친 지 2분(업로드 유예) 안에 재요청하면 전송이 그만큼 늦습니다.

🤖 Generated with Claude Code

정상 결과도 말더듬 라인이 없어 늘 partial이라, 상태가 아니라 답변 단위로 다시 보낼 만한지 가린다.
결과가 없거나 분석 서버가 retryable=true로 알린 실패가 있는 답변만 새 요청 id로 다시 보낸다.

- POST /api/interviews/{id}/audio-analysis/retry, 조회 응답에 canRetry
- V33: feedback_dispatch.user_retry_count. 한도·중복 클릭을 조건부 갱신 한 문장으로 막는다
- 다시 분석하는 동안 그 답변은 PENDING으로 보여 웹이 새 결과까지 조회한다
- 녹음을 실은 가장 나중 요청이 닫혔으면 앞선 결과가 있어도 다시 보낸다

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

@danjee2009 danjee2009 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

면접 단위 재요청 한도, 조건부 대기 행 갱신, 실패·재분석 중 상태 표시, 기존 요청 재전송 경로와 새 Postgres 테스트를 검토했습니다. 확인한 범위에서 수정이 필요한 정확성·API 호환성·데이터 일관성 문제는 찾지 못했습니다. GitHub Actions의 전체 테스트가 통과했습니다. 별도 로컬 테스트는 실행하지 않았습니다.

@kimwuju
kimwuju merged commit 3d510eb into main Oct 14, 2026
1 check 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.

2 participants