Skip to content

feat: 원질문 개편 후속(error.code·사이클 동시 생성)과 영상 분석 기준 시각(D2), 테스트 CI - #92

Merged
kimwuju merged 4 commits into
mainfrom
feat/api-handoff-1014
Oct 14, 2026
Merged

kimwuju merged 4 commits into
mainfrom
feat/api-handoff-1014

Conversation

@kimwuju

@kimwuju kimwuju commented Oct 14, 2026

Copy link
Copy Markdown
Contributor

개요

API 개발 전달 사항(10/14)의 「바로 구현할 것」 중 코드 작업 네 건입니다. #89 병합 뒤 main(de959e2) 기준입니다.

변경

1. 근거 부족 판정을 error.code로 (인계 문서 작업 1)

  • V32__add_analysis_data_error_code.sql: analysis_data.error_code VARCHAR(40)
  • 실패 콜백의 error.code를 저장하고 ProfileStatusResponse.reasonOf가 코드를 우선합니다. 코드가 없거나 모르는 값이면 지금 규칙(상태 코드, 422면 "근거" 문구)입니다.
  • 성공으로 덮을 때와 같은 jobId 재요청(clearPreviousRun) 때 비웁니다. 웹 변경 없음(failureReason 값 그대로).

2. 같은 사이클 동시 생성 500 (인계 문서 작업 2)

  • QuestionCycleRepository.lockCycleCreation: pg_advisory_xact_lock(hashtext(profileJobId), hashtext(mode))
  • prepareCycle이 찾기 전에 겁니다. 늦은 쪽은 앞 커밋을 기다렸다가 만들어진 행을 보고 null을 돌려줍니다.

3. 영상 분석을 켜기 전 영상 제외 (D2)

  • 새 설정 app.video-analysis.analyze-uploaded-after / VIDEO_ANALYSIS_UPLOADED_AFTER (오프셋 포함 ISO-8601, 예: 2026-10-20T09:00:00+09:00)
  • 스윕 uploadedAfter = max(now - 89일, 기준 시각). 기준 이전 영상은 GET …/video-analysis가 NONE, 재분석은 409.
  • VIDEO_ANALYSIS_ENABLED=true인데 비어 있거나 형식이 틀리면 기동 실패.

4. 테스트 CI

  • .github/workflows/test.yml: PR 트리거, Postgres 16 서비스 컨테이너로 ./gradlew test. 실패 시 리포트 업로드.

테스트

  • 로컬 Postgres(16-alpine)에 붙여 전체 606개 통과 (기존 595 + 11)
  • QuestionPoolServiceConcurrencyTest(실제 DB): 두 startCycles를 잠금 앞에 세웠다 함께 출발시켜도 모드당 행 하나, 분석 서버 요청 2번(모드당 1번). 잠금 호출을 빼면 실패하는 것을 확인했습니다. 다른 모드는 서로 기다리지 않음.
  • error.code: 코드 우선, 모르는 코드 대체, 성공 시 비움, camelCase 역직렬화
  • D2: 기준 전·후 영상이 섞인 스윕 쿼리(실제 DB), 스윕 인자, NONE·409, 기동 실패

배포 시 확인

  • 영상 분석을 켤 때 VIDEO_ANALYSIS_UPLOADED_AFTER를 함께 넣어야 합니다. 서버 JVM 시간대가 UTC라 오프셋을 꼭 붙입니다.

🤖 Generated with Claude Code

kimwuju and others added 4 commits October 14, 2026 16:34
/profile 실패 콜백의 code를 analysis_data.error_code(V32)에 남기고, failureReason을 메시지 문구 대신
이 코드로 고른다. 코드가 없거나 모르는 값이면 지금 규칙(상태 코드, 422면 "근거" 문구)을 따른다.
같은 작업을 다시 요청하거나 성공으로 덮을 때 다른 오류 칸처럼 비운다.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
prepareCycle이 행을 찾기 전에 (profile_job_id, mode) 단위로 pg_advisory_xact_lock을 건다.
잠글 행이 없는 순간 두 요청이 둘 다 "없음"을 보고 저장해 늦은 쪽이 유니크 제약에 걸리던 것을 막는다.
늦은 쪽은 앞의 커밋을 기다렸다가 만들어진 행을 보고, 사이클은 한 번만 요청된다.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
VIDEO_ANALYSIS_UPLOADED_AFTER(오프셋을 포함한 ISO-8601)를 두고, 스윕은 max(89일 전, 이 시각) 이후에
올라온 영상만 고른다. 기준 이전 영상은 상태 조회가 NONE, 재분석은 409다.
켰는데 값이 비어 있거나 형식이 틀리면 서버가 뜨지 않는다 -- 빈 값을 "제한 없음"으로 읽으면 결정과 반대로 동작한다.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
배포 워크플로는 테스트를 건너뛰고, DB가 필요한 테스트는 지금까지 로컬에서만 돌았다.
PR 트리거와 Postgres 16 서비스 컨테이너로 ./gradlew test를 돌리고, 실패하면 리포트를 올린다.

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.

변경된 error.code 저장·사유 매핑, 사이클 생성 잠금의 트랜잭션 범위, 영상 업로드 기준 시각 필터와 재시도 응답, 새 Postgres 테스트 워크플로를 검토했습니다. 확인한 범위에서 수정이 필요한 정확성·호환성 문제는 찾지 못했습니다. GitHub Actions의 ./gradlew test는 통과했습니다. 테스트를 별도로 로컬 실행하지는 않았습니다.

@kimwuju
kimwuju merged commit 4010f0e 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.

3 participants