Repository navigation
fix: #104 자료 저장 API를 main에 반영 (병합 경로 누락) - #105
Conversation
- payload(JSON) + file0~file4 multipart. 저장된 문서는 EXISTING, 새 파일은 NEW - 검증(직무 → 문서 → GitHub → 보완 입력)을 모아 422 MaterialErrorResponse로 돌려준다 - 직무 명세 JobRole(01 §3.1), 개발 3직무 사이만 자료 유지, 직무 없는 옛 사용자는 백엔드로 본다 - PDFBox로 쪽수를 세고 손상·암호화를 가린다. 파일당 50MB, 합계 50쪽, 같은 파일 중복 금지 - 같은 내용이면 저장·분석 없이 analysis: null - 새 파일을 S3에 올린 뒤 인증 서버 PUT /api/v1/auth/materials로 저장하고, 실패하면 올린 파일을 지운다 - 저장 뒤 지금 /profile 요청 모양(첫 문서 + GitHub)으로 분석을 요청한다. 실패해도 저장은 유지하고 status: failed Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- JobRole이 01 §3.1 표와 같은지 - 검증 규칙 20개(06 §3.4 사유별, 직무 변경, 옛 사용자, 모아서 돌려주기) - 저장 흐름(같은 내용, 업로드·저장·분석 요청, 저장 실패 시 파일 정리, 분석 실패) - multipart 바인딩과 200·422 응답 모양, 인증 서버 PUT 본문 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- 쪽수를 세야 하는 옛 PDF는 S3에서 크기를 먼저 보고 50MB를 넘으면 받지 않는다(FILE_TOO_LARGE) - 새 파일 합계가 200MB(가정 A-9)를 넘으면 하나도 읽지 않고 documents에 FILE_TOO_LARGE - 문서 목록이 가리키지 않는 파일 파트가 있으면 400 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- 새 파일은 임시 파일로 옮겨 해시·PDFBox·S3 업로드를 파일로 처리한다(요청 하나가 힙에 200MB를 잡지 않게) - 옛 PDF도 HEAD 뒤 임시 파일로 받고, 받는 동안에도 50MB에서 끊는다 - PDFBox 런타임 예외(ClassCastException 등)도 BROKEN_PDF - 인증 서버 저장이 5xx·타임아웃이면 다시 조회해 저장된 파일은 남기고, 확인하지 못하면 지우지 않는다(4xx·호출 전 실패만 바로 지움) - 비개발 직무는 분석 서버 새 요청 모양(C-3) 전까지 분석을 요청하지 않고 status: skipped - GitHub 주소는 서로 다른 것 10개까지, 같은 저장소는 하나로 합치고, settings·orgs 같은 기능 경로는 거절 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- JobRole.supportsCurrentProfileRequest 하나로 판단: PUT skipped, launchIfMissing 건너뜀, /generate·/dataUpload 422(dataUpload 는 저장 전에) - 인증 서버 응답이 실패여도 다시 조회한 값이 보낸 내용과 같으면 저장 성공으로 보고 분석 요청까지 이어 간다 - S3 에서 받는 도중 상한을 넘으면 닫기 전에 abort 해 남은 본문을 읽지 않는다 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
feat/materials-put
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: dcc2a7b750
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
danjee2009
left a comment
There was a problem hiding this comment.
확인된 문제
- [P1]
src/main/java/repit/repit_api_server/domain/metadata/service/MaterialsService.java:152— 분석에 포트폴리오 대신 첫 번째 문서를 보냅니다. 개발 직군 문서 검증은 필수PORTFOLIO가 목록 어디에든 있으면 통과하고 문서 순서도 유지합니다. 따라서 사용자가 선택 문서에RESUME을PORTFOLIO보다 먼저 두면 이 코드가 이력서 URL을portfolioUrl로 전달해 잘못된 종합 분석을 생성합니다. 첫 문서 인덱스에 의존하지 말고PORTFOLIO타입의 문서를 찾아 전달해 주세요.
PR 설명과 전체 변경 diff, 자료 검증·저장·분석 요청 흐름 및 관련 테스트를 확인했습니다. 별도 테스트 실행과 실제 S3·인증·분석 서버 연동 검증은 수행하지 않았습니다.
개발 직무 검증은 PORTFOLIO가 목록 어디에 있어도 통과하고 순서도 그대로 둔다. 이력서를 포트폴리오보다 앞에 두면 이력서 URL이 portfolioUrl로 넘어가 잘못된 분석이 나왔다. 문서 종류로 PORTFOLIO를 찾아 보낸다. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
리뷰에서 짚어 주신 [P1]
|
- 재분석(POST /ai/generate)과 면접 준비 자동 분석(launchIfMissing)이 옛 metaData의 fileUrl 대신 저장된 자료에서 PORTFOLIO 문서를 골라 보낸다. 자료 저장 뒤 분석도 같은 MaterialsResponse.toAnalysisInput()을 쓴다. - 자료 저장 호출은 재시도하므로 앞 시도가 커밋한 뒤 다음 시도가 4xx를 받을 수 있다. 4xx만 보고 올린 파일을 지우지 않고, 다시 조회해 저장 여부를 확인한다. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- 저장된 PDF를 받다가 연결 끊김·S3 5xx가 나면 EXISTING_NOT_FOUND(422) 대신 다시 시도하라는 503을 던진다. S3에 파일이 없을 때(404, 목록 권한이 없을 때의 403)만 NOT_FOUND로 본다. - PDF 파서가 스택을 넘치면 손상(BROKEN_PDF)으로 보고, 검사가 Error로 끝나도 만든 임시 파일을 지운다. - 0바이트 PDF는 400 대신 그 행에 BROKEN_PDF를 달아 다른 행과 함께 422로 돌려준다. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
[P1] 타임아웃 후 실제 저장될 파일을 삭제할 수 있습니다. |
|
[P2] 비개발 직무로 변경해도 이전 개발 직무의 질문으로 면접이 준비됩니다. |
- 인증 서버를 부른 뒤의 실패는 어떤 것이든 결과가 확실하지 않다. 타임아웃 직후 다시 조회하면 아직 처리 중인 PUT이 커밋되기 전의 옛 값이 보일 수 있어, 조회에 안 보인다고 올린 파일을 지우면 늦게 커밋된 문서가 지운 파일을 가리킨다. 다시 조회해 저장돼 있으면 성공으로 이어 가고, 아니면 파일을 남긴 채 실패를 던진다(정리용으로 주소를 로그에 남긴다). - 비개발 직무로 바꾼 사용자가 면접을 준비하면 개발 직무 때 남은 분석으로 개발 질문이 준비됐다. 면접 준비와 준비 재시도를 422로 막는다(분석 서버 새 요청 모양 C-3 전). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
무엇을 하나
#104(직무·자료 저장
PUT /api/v1/metaData/materials)의 커밋을main에 올리고, 이 PR 리뷰에서 나온 문제를 고칩니다.왜
#103과 #104는 10-17 11:52에 거의 동시에 병합됐습니다.
feat/materials-api→main11:52:08 병합 (ab165ac)feat/materials-put→feat/materials-api11:52:33 병합 (dcc2a7b)#104의 기준 브랜치가
main으로 바뀌기 전에 병합돼서, 아래 커밋 6개가feat/materials-api에만 있고main에는 없습니다. 지금main에는 자료 조회(GET)만 있고 저장(PUT)이 없습니다.이 6개의 내용 리뷰는 #104에서 끝났습니다.
이 PR에서 새로 고친 것 (리뷰 필요)
PR을 올린 뒤 리뷰에서 나온 문제를 고친 커밋 4개가 더 있습니다. 아직 리뷰받지 않은 코드 변경입니다.
d1a5a21분석에 첫 문서 대신 포트폴리오 문서를 보냄 (Codex·자동 리뷰 P1)portfolioUrl로 넘어가던 문제를 고쳤습니다.d7c94c6모든 분석 경로가 저장된 자료의 포트폴리오를 쓰고, 재시도 뒤 4xx에도 저장 여부를 다시 확인POST /api/v1/ai/generate)과 면접 준비 자동 분석(launchIfMissing)이 옛 metaData의fileUrl대신GET /auth/materials에서PORTFOLIO문서를 골라 보냅니다. 분석을 시작하는 세 경로가 모두MaterialsResponse.toAnalysisInput()을 씁니다.analysis.status를failed로 돌려줍니다.ae0edb7에서 한 번 더 보강).dc7df86S3 일시 장애를 파일 없음과 구분하고, PDF 검사 중 Error·빈 파일 처리 보강EXISTING_NOT_FOUND(422) 대신 다시 시도하라는 503을 줍니다. S3에 파일이 없을 때(404, 목록 권한이 없을 때의 403)만EXISTING_NOT_FOUND입니다.BROKEN_PDF로 보고, 검사가 Error로 끝나도 만든 임시 파일을 지웁니다.BROKEN_PDF를 달아 다른 행과 함께 422로 돌려줍니다.ae0edb7결과가 불확실한 자료 저장은 올린 파일을 남기고, 비개발 직무의 면접 준비를 막음 (2-dayeon 리뷰 P1·P2)prepareInterview)와 준비 재시도(retryPreparation)를 422로 막습니다. 면접 생성은 막지 않으므로 비개발 사용자는 면접을 만들 수는 있고 시작할 때 422를 받습니다.리뷰어가 봐 주세요
GET /auth/materials에 기댑니다. 옛 사용자에게도 이 응답에 GitHub 주소가 들어온다고 가정합니다(MaterialsResponseTest가 그렇게 둡니다). 스테이징에서 옛 사용자로 재분석을 한 번 확인하면 좋겠습니다.확인
main과 충돌 없음./gradlew test전체 822개 통과이 PR에서 고치지 않은 것
리뷰에서 나왔지만 따로 확인하거나 나중에 정리할 것입니다.
"")이 저장을 막음 — Web이 빈 칸을 보내는지 확인 필요🤖 Generated with Claude Code