Skip to content

[Feat] #45 저장된 공고 조회 API 구현#48

Open
jihoonkim501 wants to merge 4 commits into
developfrom
feat/#45
Open

[Feat] #45 저장된 공고 조회 API 구현#48
jihoonkim501 wants to merge 4 commits into
developfrom
feat/#45

Conversation

@jihoonkim501

@jihoonkim501 jihoonkim501 commented Jul 26, 2026

Copy link
Copy Markdown
Member

#️⃣ 관련 이슈

closed #45

PR 유형

어떤 변경 사항이 있나요?

  • 새로운 기능 추가
  • 버그 수정
  • 코드 리팩토링
  • 주석 추가 및 수정
  • 문서 수정
  • 테스트 추가, 테스트 리팩토링
  • 빌드 부분 혹은 패키지 매니저 수정
  • 파일 혹은 폴더명 수정
  • 파일 혹은 폴더 삭제

PR Checklist

PR이 다음 요구 사항을 충족하는지 확인하세요.

  • 커밋 메시지 컨벤션에 맞게 작성했습니다.
  • 변경 사항에 대한 테스트를 했습니다.(버그 수정/기능에 대한 테스트).

🧩 작업 내용

무한스크롤 대응을 위해 page/size 기반 페이지네이션(PageResponse) 사용
sort 쿼리 파라미터로 저장일순/마감임박순 선택 가능하도록 확장 가능한 구조
정렬 옵션과 무관하게 마감/만료된 공고는 항상 목록 하단에 위치 (JPQL CASE WHEN 1순위 정렬)
인증은 기존 JobInteractionController와 동일하게 @AuthenticationPrincipal Jwt 방식 사용 (구식 @RequestParam userId 방식 지양)
company fetch join으로 N+1 방지

📸 스크린샷(선택)

  • 저장된 공고 조회 Request
image
  • 저장된 공고 조회 Response (page = 0 으로 시도 시)
image
  • 저장된 공고 조회 Response
image

📣 To Reviewers

  • Reviewers : 팀 선택
  • Labels : 작업 유형, 자기 자신

Summary by CodeRabbit

  • 새로운 기능
    • 저장한 채용 공고 목록을 조회할 수 있습니다.
    • 페이지 번호, 페이지 크기, 저장일순 또는 마감일순 정렬을 지원합니다.
    • 전체 저장 공고 수와 지원 의도 표시 수를 함께 제공합니다.
    • 각 공고의 기업명, 제목, 근무지, 마감일, 만료 여부 및 지원 의도 표시 여부를 확인할 수 있습니다.

@jihoonkim501 jihoonkim501 self-assigned this Jul 26, 2026
@jihoonkim501 jihoonkim501 added the ✨ Feat 새로운 기능 추가 label Jul 26, 2026
@jihoonkim501 jihoonkim501 linked an issue Jul 26, 2026 that may be closed by this pull request
1 task
@coderabbitai

coderabbitai Bot commented Jul 26, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@jihoonkim501, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 44 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 3e2fd77c-96bf-4599-949b-f48e6f725861

📥 Commits

Reviewing files that changed from the base of the PR and between f2c76e3 and 1f12f47.

📒 Files selected for processing (3)
  • src/main/java/com/leets7th/job_is_be/domain/deck/repository/UserActionRepository.java
  • src/main/java/com/leets7th/job_is_be/domain/job/service/JobService.java
  • src/main/java/com/leets7th/job_is_be/global/status/ErrorStatus.java
📝 Walkthrough

Walkthrough

저장한 공고 목록 조회 기능이 추가되었습니다. GET /api/saves는 JWT 사용자 기준으로 공고를 페이징·정렬하고, 만료 여부·지원 의도 여부와 전체 집계 정보를 반환합니다.

Changes

저장 공고 목록 조회

Layer / File(s) Summary
저장 목록 응답 계약
src/main/java/com/leets7th/job_is_be/domain/job/dto/*, src/main/java/com/leets7th/job_is_be/domain/job/enums/SavedJobSortType.java, src/main/java/com/leets7th/job_is_be/global/status/SuccessStatus.java
저장 공고 항목과 목록 집계 필드, SAVED_DESC·DEADLINE_ASC 정렬 기준 및 성공 상태 코드가 정의되었습니다.
저장 공고 조회 쿼리
src/main/java/com/leets7th/job_is_be/domain/job/repository/SavedJobRepository.java
사용자별 저장 공고를 fetch join으로 페이징 조회하고, 저장·마감일 정렬과 지원 의도 클릭 수 집계를 제공합니다.
저장 목록 서비스 변환
src/main/java/com/leets7th/job_is_be/domain/job/service/JobService.java
1-based 페이지를 Pageable로 변환하고 공고 데이터를 응답 DTO로 매핑하며 만료·지원 의도 상태와 총 집계를 계산합니다.
저장 목록 HTTP 엔드포인트
src/main/java/com/leets7th/job_is_be/domain/job/controller/SaveController.java
GET /api/saves가 JWT subject와 쿼리 파라미터를 서비스에 전달하고 표준 성공 응답을 반환합니다.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Client
  participant SaveController
  participant JobService
  participant SavedJobRepository
  participant UserActionRepository
  Client->>SaveController: GET /api/saves + JWT/page/size/sort
  SaveController->>JobService: getSavedJobs(userId, page, size, sort)
  JobService->>SavedJobRepository: 저장 공고 페이지 및 집계 조회
  JobService->>UserActionRepository: 지원 의도 클릭 여부 조회
  JobService-->>SaveController: SavedJobListResponse
  SaveController-->>Client: ApiResponse 성공 응답
Loading

Possibly related PRs

Suggested reviewers: yukyoungs, yeonjuncho

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed 제목이 저장된 공고 조회 API 구현이라는 주요 변경을 간결하게 잘 요약합니다.
Linked Issues check ✅ Passed 직접 연결된 #45의 /api/saves 저장 공고 조회 API 구현 요구를 컨트롤러·서비스·리포지토리 추가로 충족합니다.
Out of Scope Changes check ✅ Passed 추가된 DTO, 정렬 enum, 상태값, 리포지토리 쿼리는 모두 저장 목록 조회 API를 지원하는 범위입니다.

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🧹 Nitpick comments (1)
src/main/java/com/leets7th/job_is_be/domain/job/repository/SavedJobRepository.java (1)

23-50: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

만료 판정 CASE 절 중복.

findByUserIdOrderBySavedDescfindByUserIdOrderByDeadlineAsc가 동일한 만료 판정 CASE WHEN 블록을 그대로 복제하고 있습니다. 향후 만료 조건(예: 상태값 추가)이 변경될 때 한쪽만 수정되어 두 정렬 결과가 어긋날 위험이 있습니다.

♻️ 공통 상수로 추출하는 예시
+public interface SavedJobRepository extends JpaRepository<SavedJob, Long> {
+
+    String EXPIRED_ORDER_CASE = """
+            CASE WHEN j.status <> com.leets7th.job_is_be.domain.job.enums.JobStatus.ACTIVE
+                 OR (j.deadlineAt IS NOT NULL AND j.deadlineAt <= :now)
+                 THEN 1 ELSE 0 END ASC
+            """;
🤖 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/leets7th/job_is_be/domain/job/repository/SavedJobRepository.java`
around lines 23 - 50, Extract the duplicated expiration CASE WHEN expression in
SavedJobRepository into a shared constant and reuse it in both
findByUserIdOrderBySavedDesc and findByUserIdOrderByDeadlineAsc, keeping each
method’s remaining ORDER BY criteria unchanged.
🤖 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/leets7th/job_is_be/domain/job/service/JobService.java`:
- Line 79: Update the apply-intent calculation in JobService’s
toSavedJobResponse flow to avoid calling
userActionRepository.existsByUserIdAndJobIdAndActionType for each SavedJob.
Collect the page’s job IDs, fetch matching apply-intent IDs once with an
IN-based repository query (returning Set<Long>), and use set membership while
mapping responses at lines 79 and 96–101.
- Around line 68-77: Update JobService.getSavedJobs to validate page and size
before constructing PageRequest: reject page values below 1 and size values
outside the supported positive maximum, throwing the appropriate
GeneralException with an ErrorStatus for each invalid input. Preserve the
existing 1-based-to-0-based page conversion and sorting behavior, and ensure
validation prevents Spring’s PageRequest IllegalArgumentException from reaching
clients.

---

Nitpick comments:
In
`@src/main/java/com/leets7th/job_is_be/domain/job/repository/SavedJobRepository.java`:
- Around line 23-50: Extract the duplicated expiration CASE WHEN expression in
SavedJobRepository into a shared constant and reuse it in both
findByUserIdOrderBySavedDesc and findByUserIdOrderByDeadlineAsc, keeping each
method’s remaining ORDER BY criteria unchanged.
🪄 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: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 106dce53-0733-4617-8360-0df4418e3e83

📥 Commits

Reviewing files that changed from the base of the PR and between 8f564d4 and f2c76e3.

📒 Files selected for processing (7)
  • src/main/java/com/leets7th/job_is_be/domain/job/controller/SaveController.java
  • src/main/java/com/leets7th/job_is_be/domain/job/dto/SavedJobListResponse.java
  • src/main/java/com/leets7th/job_is_be/domain/job/dto/SavedJobResponse.java
  • src/main/java/com/leets7th/job_is_be/domain/job/enums/SavedJobSortType.java
  • src/main/java/com/leets7th/job_is_be/domain/job/repository/SavedJobRepository.java
  • src/main/java/com/leets7th/job_is_be/domain/job/service/JobService.java
  • src/main/java/com/leets7th/job_is_be/global/status/SuccessStatus.java

Comment thread src/main/java/com/leets7th/job_is_be/domain/job/service/JobService.java Outdated

@yukyoungs yukyoungs left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

빠르시당 굿굿

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

✨ Feat 새로운 기능 추가

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Feat] 공고 저장 목록 조회 API 구현

2 participants