[Feat] 크롬 익스텐션 공고 수집 API 추가#107
Conversation
- 크롬 익스텐션이 크롤링한 공고 원문을 전달하는 ingest API 추가 - 기존 채용 공고 ingest 로직을 재사용해 공고 저장 처리 - 공고 저장 성공 시 모의 서류 지원을 자동 생성하도록 연계 - sourceUrl, sourceSite를 응답에 포함해 프론트/익스텐션에서 원본 출처를 확인할 수 있도록 구성 - 익스텐션 ingest 성공/저장 보류 케이스 단위 테스트 추가
📝 WalkthroughWalkthroughAdds a new job posting extension ingestion endpoint, request and response DTOs, and a service that reuses base job-posting ingestion before optionally creating a mock apply. Tests cover the saved and unsaved service paths. ChangesJob Posting Extension Ingest Flow
Sequence Diagram(s)sequenceDiagram
participant Client
participant JobPostingExtensionController
participant userService
participant jobPostingExtensionIngestService
participant jobPostingIngestService
participant mockApplyService
Client->>JobPostingExtensionController: POST /api/job-postings/extension/ingest
JobPostingExtensionController->>userService: validateUser(user)
JobPostingExtensionController->>jobPostingExtensionIngestService: ingest(user, request)
jobPostingExtensionIngestService->>jobPostingIngestService: ingestAndCreate(request.rawText(), null)
alt savedToDatabase and saved job posting exists
jobPostingExtensionIngestService->>mockApplyService: createMockApplyFromJobPosting(user, jobPostingId)
end
jobPostingExtensionIngestService-->>JobPostingExtensionController: JobPostingExtensionIngestResponse
JobPostingExtensionController-->>Client: ApiResponse.onSuccess(...)
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (1)
src/test/java/com/jobdri/jobdri_api/domain/jobposting/service/JobPostingExtensionIngestServiceTest.java (1)
48-120: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueOptional: add coverage for
savedToDatabase=truebutgetSaved()==null.The service guards on
ingest.isSavedToDatabase() && ingest.getSaved() != null, but tests only exercise (true, non-null saved) and (false, null saved). A test for (true, null saved) would lock in that mock-apply creation is skipped when no saved entity is present.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/test/java/com/jobdri/jobdri_api/domain/jobposting/service/JobPostingExtensionIngestServiceTest.java` around lines 48 - 120, Add a test in JobPostingExtensionIngestServiceTest to cover the branch where JobPostingIngestResponse has savedToDatabase=true but getSaved()==null, since JobPostingExtensionIngestService.ingest currently requires both conditions before calling MockApplyService.createMockApplyFromJobPosting. Reuse the existing setup pattern from ingestCreatesMockApplyWhenJobPostingSaved, but return an ingest response with null saved and verify createMockApplyFromJobPosting is never called. Also assert the response keeps savedToDatabase true and mockApply null to lock in the guard behavior.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In
`@src/main/java/com/jobdri/jobdri_api/domain/jobposting/service/JobPostingExtensionIngestService.java`:
- Around line 20-40: The ingest orchestration in
JobPostingExtensionIngestService.ingest currently performs two writes without a
shared transaction boundary, so make the whole flow transactional by adding a
transaction to the orchestrator and ensuring the downstream calls participate in
it. Review JobPostingIngestService.ingestAndCreate and
MockApplyService.createMockApplyFromJobPosting so they don’t opt out of the
caller’s transaction; in particular, remove the NOT_SUPPORTED behavior if
mock-apply creation should be atomic with the job posting save.
---
Nitpick comments:
In
`@src/test/java/com/jobdri/jobdri_api/domain/jobposting/service/JobPostingExtensionIngestServiceTest.java`:
- Around line 48-120: Add a test in JobPostingExtensionIngestServiceTest to
cover the branch where JobPostingIngestResponse has savedToDatabase=true but
getSaved()==null, since JobPostingExtensionIngestService.ingest currently
requires both conditions before calling
MockApplyService.createMockApplyFromJobPosting. Reuse the existing setup pattern
from ingestCreatesMockApplyWhenJobPostingSaved, but return an ingest response
with null saved and verify createMockApplyFromJobPosting is never called. Also
assert the response keeps savedToDatabase true and mockApply null to lock in the
guard behavior.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro Plus
Run ID: 98cd511c-b2f7-48ba-81b1-a4e1a9298286
📒 Files selected for processing (5)
src/main/java/com/jobdri/jobdri_api/domain/jobposting/controller/JobPostingExtensionController.javasrc/main/java/com/jobdri/jobdri_api/domain/jobposting/dto/request/JobPostingExtensionIngestRequest.javasrc/main/java/com/jobdri/jobdri_api/domain/jobposting/dto/response/JobPostingExtensionIngestResponse.javasrc/main/java/com/jobdri/jobdri_api/domain/jobposting/service/JobPostingExtensionIngestService.javasrc/test/java/com/jobdri/jobdri_api/domain/jobposting/service/JobPostingExtensionIngestServiceTest.java
| public JobPostingExtensionIngestResponse ingest(User user, JobPostingExtensionIngestRequest request) { | ||
| JobPostingIngestResponse ingest = jobPostingIngestService.ingestAndCreate( | ||
| user, | ||
| new JobPostingIngestRequest(request.rawText(), null) | ||
| ); | ||
|
|
||
| MockApplyCreateResponse mockApply = null; | ||
| if (ingest.isSavedToDatabase() && ingest.getSaved() != null) { | ||
| mockApply = mockApplyService.createMockApplyFromJobPosting( | ||
| user, | ||
| ingest.getSaved().getJobPostingId() | ||
| ); | ||
| } | ||
|
|
||
| return JobPostingExtensionIngestResponse.of( | ||
| request.sourceUrl(), | ||
| request.sourceSite(), | ||
| ingest, | ||
| mockApply | ||
| ); | ||
| } |
There was a problem hiding this comment.
🗄️ Data Integrity & Integration | 🟠 Major
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Inspect JobPostingIngestService for `@Transactional` usage and ingestAndCreate signatures
fd JobPostingIngestService.java --exec sh -c 'echo "== {} =="; rg -nP -C3 "`@Transactional`|public .*ingestAndCreate" "{}"'
# Inspect MockApplyService.createMockApplyFromJobPosting transaction semantics
fd MockApplyService.java --exec sh -c 'echo "== {} =="; rg -nP -C3 "`@Transactional`|createMockApplyFromJobPosting" "{}"'Repository: JobDri-Developer/BackEnd
Length of output: 3872
Atomicity risk: Two write operations have no common transaction boundary.
ingest() triggers a persistence action via jobPostingIngestService.ingestAndCreate(...) followed by mockApplyService.createMockApplyFromJobPosting(...).
Verification confirms that neither the orchestrator method nor the callee ingestAndCreate have a @Transactional annotation. Furthermore, createMockApplyFromJobPosting is explicitly annotated with @Transactional(propagation = Propagation.NOT_SUPPORTED), forcing it to execute outside any transaction.
This sequence lacks an atomic context: if the mock-apply creation fails after the job posting is saved, the system is left in an inconsistent state with the posting persisted but no associated mock application.
Enclose the orchestration in @Transactional and ensure the downstream service methods respect the transaction (or remove Propagation.NOT_SUPPORTED if the mock-apply step should participate in the caller's transaction).
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In
`@src/main/java/com/jobdri/jobdri_api/domain/jobposting/service/JobPostingExtensionIngestService.java`
around lines 20 - 40, The ingest orchestration in
JobPostingExtensionIngestService.ingest currently performs two writes without a
shared transaction boundary, so make the whole flow transactional by adding a
transaction to the orchestrator and ensuring the downstream calls participate in
it. Review JobPostingIngestService.ingestAndCreate and
MockApplyService.createMockApplyFromJobPosting so they don’t opt out of the
caller’s transaction; in particular, remove the NOT_SUPPORTED behavior if
mock-apply creation should be atomic with the job posting save.
✨ 어떤 이유로 PR를 하셨나요?
📋 세부 내용 - 왜 해당 PR이 필요한지 작업 내용을 자세하게 설명해주세요
📸 작업 화면 스크린샷
🚨 관련 이슈 번호 [#106 ]
Summary by CodeRabbit
New Features
Bug Fixes