Skip to content

feat: 저장된 시뮬레이션 목록 및 상세 조회 API 구현 - #130

Merged
1117mg merged 7 commits into
devfrom
feat/118-my-simulations-api
Aug 7, 2026
Merged

feat: 저장된 시뮬레이션 목록 및 상세 조회 API 구현#130
1117mg merged 7 commits into
devfrom
feat/118-my-simulations-api

Conversation

@1117mg

@1117mg 1117mg commented Aug 6, 2026

Copy link
Copy Markdown
Member

🔗 관련 이슈

Closes #118

📝 작업 내용

  • 내 시뮬레이션 목록 조회 API 추가 (GET /api/v1/simulations)
    • page/size 페이지네이션(기본 5건, 최대 50건)
  • 저장된 시뮬레이션 상세 조회 API 추가 (GET /api/v1/simulations/{simulationId})
  • 시뮬레이션 도메인 에러 코드 추가
  • OpenAPI 스키마 정리: 선택 응답 필드의 nullable = truerequiredMode = NOT_REQUIRED로 교체
  • Swagger 문서 응답 예시 추가, 서비스/컨트롤러 테스트 추가

✅ 체크리스트

  • 로컬에서 빌드 및 테스트가 통과했습니다.
  • 컨벤션(브랜치/커밋 메시지)을 준수했습니다.
  • 관련 문서를 수정했습니다. (필요한 경우)

💬 리뷰 참고 사항

채널 목록은 @SortDefault + Sort로 클라이언트가 정렬을 바꿀 수 있지만, 마이페이지의 예산 시뮬레이션 결과 목록은 최신순 고정이 요구사항이라 레포지토리 메서드에 정렬방식을 고정하고 Sort를 아예 받지 않았습니다.
채널 목록은 page/size를 모두 생략하면 전체 조회이지만, 시뮬레이션은 사용자당 저장 개수 제한이 없어서 전체 조회를 기본값으로 두지 않고 항상 페이지 단위로 끊어 조회합니다.

Summary by CodeRabbit

  • 새 기능
    • 저장된 시뮬레이션 목록을 페이지 단위로 조회할 수 있습니다.
    • 목록에서 예산, 기간, 예상 노출·클릭 수, 매체 수와 매체명 미리보기를 확인할 수 있습니다.
    • 저장된 시뮬레이션의 상세 정보를 조회할 수 있습니다.
  • 개선 사항
    • 페이지 번호와 크기 입력값을 검증하고 최신순으로 제공합니다.
    • 본인 소유 시뮬레이션만 조회되며, 존재하지 않거나 접근할 수 없는 시뮬레이션은 동일한 오류로 안내됩니다.
    • 선택 항목이 없는 응답은 해당 필드를 생략하도록 API 문서를 정리했습니다.

@1117mg 1117mg self-assigned this Aug 6, 2026
@1117mg 1117mg added the feat label Aug 6, 2026
@coderabbitai

coderabbitai Bot commented Aug 6, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

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

Next review available in: 10 minutes

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

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: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 180e4091-a80d-410e-afa5-38c31fd3f422

📥 Commits

Reviewing files that changed from the base of the PR and between c818749 and 7058ab0.

📒 Files selected for processing (6)
  • src/main/java/chaeso/zip/server/simulation/application/SimulationService.java
  • src/main/java/chaeso/zip/server/simulation/application/dto/SimulationItemResponse.java
  • src/main/java/chaeso/zip/server/simulation/application/dto/SimulationSummaryResponse.java
  • src/main/java/chaeso/zip/server/simulation/presentation/SimulationApiDocs.java
  • src/test/java/chaeso/zip/server/simulation/application/SimulationServiceImplTest.java
  • src/test/java/chaeso/zip/server/simulation/presentation/SimulationControllerTest.java
📝 Walkthrough

Walkthrough

저장된 시뮬레이션 목록과 상세 결과 조회 기능을 추가했다. 목록은 페이지네이션과 요약 응답을 사용한다. 상세 조회는 소유권을 검증한다. 관련 저장소 계약, 오류 코드, API 문서와 서비스·컨트롤러 테스트를 추가했다.

Changes

저장 시뮬레이션 조회

Layer / File(s) Summary
조회 계약과 저장소 조회
src/main/java/chaeso/zip/server/simulation/application/SimulationService.java, src/main/java/chaeso/zip/server/simulation/application/dto/SimulationSummaryResponse.java, src/main/java/chaeso/zip/server/simulation/presentation/dto/SimulationPageRequest.java, src/main/java/chaeso/zip/server/simulation/domain/..., src/main/java/chaeso/zip/server/simulation/application/dto/SimulationItemResponse.java, src/main/java/chaeso/zip/server/simulation/application/dto/SimulationResponse.java
SimulationSummaryResponse와 페이지 요청 계약을 추가했다. 사용자별 페이지 조회와 여러 시뮬레이션 항목 일괄 조회 메서드를 추가했다. SIM-001 오류 코드와 예외를 정의했다. 선택 필드의 OpenAPI 표기를 조정했다.
목록 및 상세 조회 서비스
src/main/java/chaeso/zip/server/simulation/application/SimulationServiceImpl.java, src/test/java/chaeso/zip/server/simulation/application/SimulationServiceImplTest.java
사용자별 시뮬레이션을 최신순으로 조회하고 항목과 채널명을 요약 응답으로 변환한다. 상세 조회는 소유자가 다르거나 대상이 없을 때 SimulationNotFoundException을 발생시킨다. 빈 결과와 채널명 미리보기, 저장 스냅샷 복원을 테스트한다.
HTTP 엔드포인트와 API 문서
src/main/java/chaeso/zip/server/simulation/presentation/SimulationController.java, src/main/java/chaeso/zip/server/simulation/presentation/SimulationApiDocs.java, src/test/java/chaeso/zip/server/simulation/presentation/SimulationControllerTest.java
GET /api/v1/simulationsGET /api/v1/simulations/{simulationId}를 추가했다. 페이지 기본값과 검증 규칙을 적용한다. 성공, 빈 목록, SIM-001 오류, /latest 경로 우선순위를 문서와 테스트에 반영했다.

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

Sequence Diagram(s)

sequenceDiagram
  actor 인증된 사용자
  participant SimulationController
  participant SimulationServiceImpl
  participant BudgetSimulationRepository
  participant BudgetSimulationItemRepository
  인증된 사용자->>SimulationController: GET /api/v1/simulations
  SimulationController->>SimulationServiceImpl: findMySimulations(userId, pageable)
  SimulationServiceImpl->>BudgetSimulationRepository: 사용자별 페이지 조회
  BudgetSimulationRepository-->>SimulationServiceImpl: Page<BudgetSimulation>
  SimulationServiceImpl->>BudgetSimulationItemRepository: 항목 일괄 조회
  BudgetSimulationItemRepository-->>SimulationServiceImpl: 정렬된 항목 목록
  SimulationServiceImpl-->>SimulationController: Page<SimulationSummaryResponse>
  SimulationController-->>인증된 사용자: PageResponse<SimulationSummaryResponse>
Loading
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 8.57% 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
Linked Issues check ✅ Passed 목록·상세 조회 API, 최신순 페이지네이션, 소유권 기반 조회, 404 처리 요구사항을 구현했습니다. 관련 테스트와 문서도 추가했습니다.
Out of Scope Changes check ✅ Passed 변경 사항은 이슈 #118의 API 구현, 오류 처리, OpenAPI 정리, 테스트 범위에 포함됩니다. 관련 없는 코드 변경은 확인되지 않습니다.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed 제목이 저장된 시뮬레이션 목록 및 상세 조회 API 구현이라는 변경의 주요 내용을 정확하고 간결하게 설명합니다.
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/118-my-simulations-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.

@codecov-commenter

Copy link
Copy Markdown

Welcome to Codecov 🎉

Once you merge this PR into your default branch, you're all set! Codecov will compare coverage reports and display results in all future pull requests.

Thanks for integrating Codecov - We've got you covered ☂️

@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: 4

🤖 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/chaeso/zip/server/simulation/application/dto/SimulationItemResponse.java`:
- Around line 20-46: Update SimulationItemResponse so optional fields whose
descriptions indicate omission when unavailable are either omitted from JSON via
JsonInclude(NON_NULL) or explicitly represented as nullable in the OpenAPI
schema. Apply this consistently to channelProductId, allocationPct,
estImpressions, estClicks, cpcWon, cpmWon, and the nullable insufficient-budget
field, while preserving requiredMode.REQUIRED for allocatedBudgetWon and
isExecutable.

In
`@src/main/java/chaeso/zip/server/simulation/application/dto/SimulationSummaryResponse.java`:
- Line 53: SimulationSummaryResponse의 channelCount 계산이 문서 의미와 일치하도록 수정하십시오.
items에서 notAllocated처럼 배정 예산이 0원인 항목을 제외하고 실제 예산이 배분된 매체 수만 계산하며, 관련 필드 설명도 해당
의미를 유지하십시오.

In
`@src/main/java/chaeso/zip/server/simulation/application/SimulationServiceImpl.java`:
- Around line 105-110: Update findSimulation in SimulationServiceImpl to first
resolve the simulation by ID, preserving SimulationNotFoundException for missing
records, then compare its userId with the requested userId and throw a
403-specific ownership exception when they differ. Add the corresponding HTTP
403 entry to SimulationErrorCode and cover both ownership failure and
missing-resource behavior in service and controller tests.

In
`@src/main/java/chaeso/zip/server/simulation/presentation/SimulationApiDocs.java`:
- Around line 235-238: Update the 400 ApiResponse example in the relevant
SimulationApiDocs annotation to use a dedicated page/size validation example
instead of VALIDATION_ERROR_EXAMPLE. Define or reuse an example matching
SimulationPageRequest’s actual validation message and ApiResponse response
structure, identifying the invalid page or size field and its range violation.
🪄 Autofix

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: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: ba651539-02e7-4b92-abe3-f6112ec67e4a

📥 Commits

Reviewing files that changed from the base of the PR and between 6d68c8b and c818749.

📒 Files selected for processing (15)
  • src/main/java/chaeso/zip/server/simulation/application/SimulationService.java
  • src/main/java/chaeso/zip/server/simulation/application/SimulationServiceImpl.java
  • src/main/java/chaeso/zip/server/simulation/application/dto/SimulationItemResponse.java
  • src/main/java/chaeso/zip/server/simulation/application/dto/SimulationResponse.java
  • src/main/java/chaeso/zip/server/simulation/application/dto/SimulationSummaryResponse.java
  • src/main/java/chaeso/zip/server/simulation/domain/SimulationErrorCode.java
  • src/main/java/chaeso/zip/server/simulation/domain/SimulationNotFoundException.java
  • src/main/java/chaeso/zip/server/simulation/domain/entity/BudgetSimulationItem.java
  • src/main/java/chaeso/zip/server/simulation/domain/repository/BudgetSimulationItemRepository.java
  • src/main/java/chaeso/zip/server/simulation/domain/repository/BudgetSimulationRepository.java
  • src/main/java/chaeso/zip/server/simulation/presentation/SimulationApiDocs.java
  • src/main/java/chaeso/zip/server/simulation/presentation/SimulationController.java
  • src/main/java/chaeso/zip/server/simulation/presentation/dto/SimulationPageRequest.java
  • src/test/java/chaeso/zip/server/simulation/application/SimulationServiceImplTest.java
  • src/test/java/chaeso/zip/server/simulation/presentation/SimulationControllerTest.java

Comment thread src/main/java/chaeso/zip/server/simulation/presentation/SimulationApiDocs.java Outdated
@claude

claude Bot commented Aug 6, 2026

Copy link
Copy Markdown

머지를 막을 필요가 있는 이슈를 찾지 못했습니다.

@1117mg
1117mg requested a review from SinnoLn August 6, 2026 06:07

@SinnoLn SinnoLn 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.

확인했습니다! 수고하셨습니다

@1117mg
1117mg merged commit 051ee55 into dev Aug 7, 2026
2 checks passed
@1117mg
1117mg deleted the feat/118-my-simulations-api branch August 7, 2026 01:03
SinnoLn added a commit that referenced this pull request Aug 8, 2026
* chore: AWS S3 공개 버킷 추가 (#126)

* feat(infra): add public S3 bucket and upload commands for static assets

* docs: document public static assets S3 bucket

* chore: remove unused region field from onboarding S3 test config

* chore(infra): increase EC2 root volume to 30GB and switch to gp3

* fix: address review feedback on public assets bucket

* fix(infra): scope down public bucket permissions and fix access log delivery

* feat: 저장된 시뮬레이션 목록 및 상세 조회 API 구현 (#130)

* fix(simulation): mark optional response fields NOT_REQUIRED instead of nullable

* feat(simulation): add saved simulation detail API

* feat(simulation): add paginated my-simulations list API

* chore(simulation): drop unused SimulationNotFoundException import

* fix(simulation): omit null fields from simulation item responses

* fix(simulation): count only funded channels in list summaries

* docs(simulation): add a page/size example to the list API 400 response

* feat: 채널 추천 결과 저장 API 구현 (#133)

* fix(security): scope the public recommendations path to GET

* fix(openapi): publish data and error as required on response wrappers

* feat(recommendation): add channel recommendation save API

* fix(recommendation): serialize saves per onboarding

* feat: add flyway migration v16

* feat(channel): filter the channel list by primary category (#134)

* feat: 온보딩 나이대 응답에 "잘 모르겠어요"(UNDECIDED) 추가 (#138)

* feat(infra): disable aws scheduler

* refactor(performance): build AdPerformance via Lombok builder instead of positional constructor

* feat(onboarding): let users answer "don't know" for target age band

* refactor(onboarding): extract OnboardingNotFoundException for id-based lookups

* test(onboarding): cover UNDECIDED-alone and AdPerformance ratio branches

---------

Co-authored-by: Yelim Lee <142207312+1117mg@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants