Skip to content

feat/#KD-48 : Schedule API 구현#286

Merged
dkdltm221 merged 8 commits intodevelopfrom
feat/KD-48-api
Nov 21, 2025
Merged

feat/#KD-48 : Schedule API 구현#286
dkdltm221 merged 8 commits intodevelopfrom
feat/KD-48-api

Conversation

@dkdltm221
Copy link
Copy Markdown
Contributor

Summary

논문 페이지에 들어갈 일정 관련 api 구현 했습니다.

Tasks

  • schedule 조회 api 구현
  • schedule 관리용 api구현

To Reviewer

  • 일정 타입으로 본문 내용을 조회하고
    본문 내용을 수정하도록 기존에 구현 되었다고 해서 일정 타입이 중복 생성되는 것을 막았습니다.
  • 일정 조회시 시작일자와 종료 일자,일정 타입, 일정 이름이 조회됩니다.

@dkdltm221 dkdltm221 self-assigned this Nov 16, 2025
@dkdltm221 dkdltm221 added the ✨feature create new feature label Nov 16, 2025
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Nov 16, 2025

Important

Review skipped

Auto incremental reviews are disabled on this repository.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Walkthrough

스케줄 관리를 위한 관리자 API와 일반 사용자 API를 추가합니다. 관리자 API는 스케줄 생성/수정/삭제를 지원하고, 일반 API는 스케줄 조회를 제공합니다. Facade 패턴으로 구현되며 기존 서비스에 예외 처리 로직이 추가되었습니다.

Changes

Cohort / File(s) 요약
관리자 스케줄 애플리케이션 계층
aics-admin/src/main/java/kgu/developers/admin/schedule/application/ScheduleAdminFacade.java
스케줄 생성, 수정, 컨텐츠 업데이트, 삭제 기능을 제공하는 Facade 컴포넌트 추가
관리자 스케줄 프레젠테이션 계층
aics-admin/src/main/java/kgu/developers/admin/schedule/presentation/ScheduleAdminController.java, aics-admin/src/main/java/kgu/developers/admin/schedule/presentation/ScheduleAdminControllerImpl.java
스케줄 CRUD 엔드포인트를 정의하는 인터페이스 및 구현체 추가 (/api/v1/admin/schedules)
관리자 스케줄 요청 DTO
aics-admin/src/main/java/kgu/developers/admin/schedule/presentation/request/ScheduleCreateRequest.java, aics-admin/src/main/java/kgu/developers/admin/schedule/presentation/request/ScheduleUpdateRequest.java, aics-admin/src/main/java/kgu/developers/admin/schedule/presentation/request/ScheduleContentUpdateRequest.java
스케줄 생성, 수정, 컨텐츠 업데이트를 위한 요청 DTO 추가, 날짜 범위 유효성 검사 포함
관리자 스케줄 응답 DTO
aics-admin/src/main/java/kgu/developers/admin/schedule/presentation/response/SchedulePersistResponse.java
스케줄 생성 후 반환되는 응답 DTO (scheduleId 포함)
일반 사용자 스케줄 애플리케이션 계층
aics-api/src/main/java/kgu/developers/api/schedule/application/ScheduleFacade.java
스케줄 조회 기능을 제공하는 Facade 컴포넌트 추가
일반 사용자 스케줄 프레젠테이션 계층
aics-api/src/main/java/kgu/developers/api/schedule/presentation/ScheduleController.java, aics-api/src/main/java/kgu/developers/api/schedule/presentation/ScheduleControllerImpl.java
스케줄 조회 엔드포인트를 정의하는 인터페이스 및 구현체 추가 (/api/v1/schedules)
일반 사용자 스케줄 응답 DTO
aics-api/src/main/java/kgu/developers/api/schedule/presentation/response/ScheduleListResponse.java, aics-api/src/main/java/kgu/developers/api/schedule/presentation/response/ScheduleSummaryResponse.java, aics-api/src/main/java/kgu/developers/api/schedule/presentation/response/ScheduleTypeContentResponse.java
스케줄 목록, 요약, 타입별 컨텐츠 조회용 응답 DTO 추가
도메인 서비스
aics-domain/src/main/java/kgu/developers/domain/schedule/application/command/ScheduleService.java
스케줄 수정 시 중복 타입 검사, 삭제 시 존재 여부 검증 로직 추가

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

  • 주의 필요 영역:
    • ScheduleCreateRequest, ScheduleUpdateRequest의 날짜 범위 유효성 검사 로직 (isValidDateRange()) 확인 필요
    • ScheduleService의 updateSchedule에서 중복 SubmissionType 검사 로직 및 deleteSchedule의 예외 처리 동작 확인
    • ScheduleAdminController와 ScheduleController의 API 경로, HTTP 메서드, 상태 코드 일관성 검증
    • ScheduleSummaryResponse의 날짜 포매팅("yyyy-MM-dd")과 상태 결정 로직 (determineStatusAt()) 검증

Possibly related PRs

  • PR #277: ScheduleService와 ScheduleQueryService의 도메인 서비스 구현 관련으로, 본 PR이 추가하는 Admin/User Facade에서 이들 서비스를 활용합니다.
  • PR #167: 컨트롤러 추상화 패턴(Swagger 인터페이스 vs @RestController 구현체 분리)을 동일하게 적용하고 있습니다.

Suggested reviewers

  • LeeHanEum
  • JangYeongHu

Pre-merge checks and finishing touches

❌ 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%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Description check ✅ Passed PR 설명이 일정 조회 및 관리 API 구현과 관련 있으며, 구체적인 구현 내용과 검토 사항을 포함하고 있습니다.
Title check ✅ Passed PR 제목은 Schedule API 구현이라는 주요 변경사항을 명확하게 반영하고 있으며, 제공된 파일 요약과 PR 목표와 일치합니다.

Tip

📝 Customizable high-level summaries are now available in beta!

You can now customize how CodeRabbit generates the high-level summary in your pull requests — including its content, structure, tone, and formatting.

  • Provide your own instructions using the high_level_summary_instructions setting.
  • Format the summary however you like (bullet lists, tables, multi-section layouts, contributor stats, etc.).
  • Use high_level_summary_in_walkthrough to move the summary from the description to the walkthrough section.

Example instruction:

"Divide the high-level summary into five sections:

  1. 📝 Description — Summarize the main change in 50–60 words, explaining what was done.
  2. 📓 References — List relevant issues, discussions, documentation, or related PRs.
  3. 📦 Dependencies & Requirements — Mention any new/updated dependencies, environment variable changes, or configuration updates.
  4. 📊 Contributor Summary — Include a Markdown table showing contributions:
    | Contributor | Lines Added | Lines Removed | Files Changed |
  5. ✔️ Additional Notes — Add any extra reviewer context.
    Keep each section concise (under 200 words) and use bullet or numbered lists for clarity."

Note: This feature is currently in beta for Pro-tier users, and pricing will be announced later.


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 and usage tips.

@dkdltm221 dkdltm221 linked an issue Nov 16, 2025 that may be closed by this pull request
2 tasks
@github-actions
Copy link
Copy Markdown

github-actions bot commented Nov 16, 2025

Test Coverage Report

Overall Project 91.98% -0.68% 🍏
Files changed 85.29% 🍏

Module Coverage
aics-admin 100% 🍏
aics-api 94.21% -5.41%
aics-domain 89.28% -0.07% 🍏
Files
Module File Coverage
aics-admin ScheduleAdminFacade.java 100% 🍏
aics-api ScheduleFacade.java 0%
aics-domain ScheduleCommandService.java 98.9% -1.1% 🍏

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (12)
aics-domain/src/main/java/kgu/developers/domain/schedule/application/command/ScheduleService.java (1)

30-35: 중복 필터 제거를 고려하세요.

32번 줄의 .filter(other -> !other.getId().equals(schedule.getId()))는 기술적으로 불필요합니다. 30번 줄의 조건문이 이미 현재 스케줄의 submission type이 새로운 type과 다름을 보장하므로, findBySubmissionType(submissionType) 쿼리는 현재 스케줄을 절대 반환하지 않습니다.

다음 diff를 적용하여 불필요한 필터를 제거할 수 있습니다:

 if(!schedule.getSubmissionType().equals(submissionType)) {
     scheduleRepository.findBySubmissionType(submissionType)
-            .filter(other -> !other.getId().equals(schedule.getId()))
             .ifPresent(existing -> {
                 throw new DuplicateScheduleTypeException();});
 }
aics-admin/src/main/java/kgu/developers/admin/schedule/presentation/request/ScheduleCreateRequest.java (1)

27-27: 코드 스타일 개선 제안

null 비교 연산자 앞의 공백이 일관되지 않습니다 (startDate ==null).

-                if (startDate ==null || endDate == null) {
+                if (startDate == null || endDate == null) {
aics-api/src/main/java/kgu/developers/api/schedule/presentation/response/ScheduleTypeContentResponse.java (1)

9-16: @builder 사용이 불필요할 수 있습니다.

간단한 record의 경우 생성자를 직접 사용하는 것이 더 간결할 수 있습니다. 현재 팩토리 메서드에서만 사용되고 있어 빌더 패턴의 이점이 크지 않습니다.

-@Builder
 public record ScheduleTypeContentResponse(
     @Schema(description = "제출 유형", example = "MIDTHESIS", requiredMode = REQUIRED)
     String submissionType,
 
     @Schema(description = "일정 본문 내용", example = "매학기 개강 후 2주 이내에 신청서를 작성하여 접수해야 합니다.",requiredMode = REQUIRED)
     String content
 ) {
     public static ScheduleTypeContentResponse from(Schedule schedule) {
-        return ScheduleTypeContentResponse.builder()
-                .submissionType(schedule.getSubmissionType().name())
-                .content(schedule.getContent())
-                .build();
+        return new ScheduleTypeContentResponse(
+                schedule.getSubmissionType().name(),
+                schedule.getContent()
+        );
     }
 }
aics-admin/src/main/java/kgu/developers/admin/schedule/presentation/request/ScheduleUpdateRequest.java (2)

29-35: 날짜 범위 검증 로직이 중복됩니다.

ScheduleCreateRequest와 동일한 isValidDateRange() 메서드가 중복되어 있습니다. 공통 유틸리티 클래스나 인터페이스로 추출하는 것을 고려해보세요.

예시 (공통 인터페이스 추출):

public interface DateRangeValidatable {
    LocalDateTime getStartDate();
    LocalDateTime getEndDate();
    
    @AssertTrue(message = "종료 일시는 시작 일시 이후여야 합니다.")
    default boolean isValidDateRange() {
        if (getStartDate() == null || getEndDate() == null) {
            return true;
        }
        return !getEndDate().isBefore(getStartDate());
    }
}

31-31: 코드 스타일 개선 제안

null 비교 연산자 앞의 공백이 일관되지 않습니다 (startDate ==null).

-                if (startDate ==null || endDate == null) {
+                if (startDate == null || endDate == null) {
aics-api/src/main/java/kgu/developers/api/schedule/presentation/ScheduleControllerImpl.java (1)

38-42: 경로 변수 검증 추가를 고려해보세요.

id 파라미터에 대한 검증 어노테이션(예: @Positive)을 추가하면 잘못된 입력을 조기에 차단할 수 있습니다.

     @Override
     @GetMapping("/{id}")
-    public ResponseEntity<ScheduleSummaryResponse> getScheduleById(@PathVariable Long id){
+    public ResponseEntity<ScheduleSummaryResponse> getScheduleById(@PathVariable @Positive Long id){
         LocalDateTime referenceTime = LocalDateTime.now();
         return ResponseEntity.ok(ScheduleSummaryResponse.from(scheduleFacade.findById(id), referenceTime ));
     }
aics-admin/src/main/java/kgu/developers/admin/schedule/presentation/response/SchedulePersistResponse.java (1)

8-18: @builder 사용이 불필요합니다.

단일 필드를 가진 record에 빌더 패턴을 사용하는 것은 과도합니다. 직접 생성자를 사용하는 것이 더 간결합니다.

-@Builder
 public record SchedulePersistResponse(
     @Schema(description = "일정 id", example = "1", requiredMode = REQUIRED)
     Long scheduleId
 ) {
     public static SchedulePersistResponse from(Long scheduleId) {
-        return SchedulePersistResponse.builder()
-                .scheduleId(scheduleId)
-                .build();
+        return new SchedulePersistResponse(scheduleId);
     }
 }
aics-admin/src/main/java/kgu/developers/admin/schedule/application/ScheduleAdminFacade.java (1)

44-47: 코드 포맷팅을 개선하세요.

Line 45와 46에 공백이 누락되어 있습니다:

  • Line 45: = 연산자 뒤에 공백 필요
  • Line 46: 메서드 호출 시 쉼표 뒤에 공백 필요

다음 diff를 적용하여 포맷팅을 개선하세요:

     public void updateScheduleContent(SubmissionType submissionType, ScheduleContentUpdateRequest request) {
-        Schedule schedule =scheduleQueryService.getBySubmissionType(submissionType);
-        scheduleService.updateScheduleContent(schedule,request.content());
+        Schedule schedule = scheduleQueryService.getBySubmissionType(submissionType);
+        scheduleService.updateScheduleContent(schedule, request.content());
     }
aics-api/src/main/java/kgu/developers/api/schedule/presentation/response/ScheduleListResponse.java (2)

28-34: 메서드 시그니처 포맷팅을 개선하세요.

Line 28에서 매개변수 사이의 쉼표 뒤에 공백이 누락되었습니다.

다음 diff를 적용하세요:

-    public static ScheduleListResponse from(List<Schedule> schedules,LocalDateTime referenceTime) {
+    public static ScheduleListResponse from(List<Schedule> schedules, LocalDateTime referenceTime) {
         return ScheduleListResponse.builder()
                 .contents(schedules.stream()
                         .map(schedule -> ScheduleSummaryResponse.from(schedule,referenceTime))

31-31: 람다 표현식 포맷팅을 개선하세요.

Line 31에서도 메서드 호출 시 쉼표 뒤에 공백이 누락되었습니다.

다음 diff를 적용하세요:

                 .contents(schedules.stream()
-                        .map(schedule -> ScheduleSummaryResponse.from(schedule,referenceTime))
+                        .map(schedule -> ScheduleSummaryResponse.from(schedule, referenceTime))
                         .toList())
aics-api/src/main/java/kgu/developers/api/schedule/presentation/response/ScheduleSummaryResponse.java (1)

24-30: 불필요한 @DateTimeFormat 애노테이션을 제거하세요.

Line 25와 29의 @DateTimeFormat 애노테이션은 응답 DTO에서는 효과가 없습니다. 이 애노테이션은 주로 요청 파라미터 바인딩에 사용되며, 응답 직렬화는 Jackson이 처리합니다. 필드가 이미 String 타입이고 DATE_FORMATTER를 통해 포맷팅되므로 이 애노테이션은 혼란을 야기할 수 있습니다.

다음 diff를 적용하여 불필요한 애노테이션을 제거하세요:

     @Schema(description = "시작일", example = "2025-05-01", requiredMode = REQUIRED)
-    @DateTimeFormat(pattern = "yyyy-MM-dd")
     String startDate,

     @Schema(description = "종료일", example = "2025-12-31", requiredMode = REQUIRED)
-    @DateTimeFormat(pattern = "yyyy-MM-dd")
     String endDate,
aics-admin/src/main/java/kgu/developers/admin/schedule/presentation/ScheduleAdminController.java (1)

44-54: API 설명을 올바른 위치로 이동하세요.

Line 46의 @Parameter description에 "이 API는 제출 유형/제목/기간을 수정합니다."라는 내용이 있는데, 이는 파라미터 설명이 아닌 API 전체 기능에 대한 설명입니다. 이미 Line 40-41의 @Operation description에 동일한 내용이 있으므로 파라미터 설명은 실제 파라미터(scheduleId)에 대한 설명이어야 합니다.

다음 diff를 적용하여 설명을 수정하세요:

 	ResponseEntity<Void> updateSchedule(
 			@Parameter(
-					description = "이 API는 제출 유형/제목/기간을 수정합니다.",
+					description = "수정할 일정의 ID 입니다.",
 					example = "1",
 					required = true
 			)@Positive @PathVariable Long scheduleId,
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 7bdf45c and 8023816.

📒 Files selected for processing (14)
  • aics-admin/src/main/java/kgu/developers/admin/schedule/application/ScheduleAdminFacade.java (1 hunks)
  • aics-admin/src/main/java/kgu/developers/admin/schedule/presentation/ScheduleAdminController.java (1 hunks)
  • aics-admin/src/main/java/kgu/developers/admin/schedule/presentation/ScheduleAdminControllerImpl.java (1 hunks)
  • aics-admin/src/main/java/kgu/developers/admin/schedule/presentation/request/ScheduleContentUpdateRequest.java (1 hunks)
  • aics-admin/src/main/java/kgu/developers/admin/schedule/presentation/request/ScheduleCreateRequest.java (1 hunks)
  • aics-admin/src/main/java/kgu/developers/admin/schedule/presentation/request/ScheduleUpdateRequest.java (1 hunks)
  • aics-admin/src/main/java/kgu/developers/admin/schedule/presentation/response/SchedulePersistResponse.java (1 hunks)
  • aics-api/src/main/java/kgu/developers/api/schedule/application/ScheduleFacade.java (1 hunks)
  • aics-api/src/main/java/kgu/developers/api/schedule/presentation/ScheduleController.java (1 hunks)
  • aics-api/src/main/java/kgu/developers/api/schedule/presentation/ScheduleControllerImpl.java (1 hunks)
  • aics-api/src/main/java/kgu/developers/api/schedule/presentation/response/ScheduleListResponse.java (1 hunks)
  • aics-api/src/main/java/kgu/developers/api/schedule/presentation/response/ScheduleSummaryResponse.java (1 hunks)
  • aics-api/src/main/java/kgu/developers/api/schedule/presentation/response/ScheduleTypeContentResponse.java (1 hunks)
  • aics-domain/src/main/java/kgu/developers/domain/schedule/application/command/ScheduleService.java (3 hunks)
🧰 Additional context used
🧬 Code graph analysis (2)
aics-domain/src/main/java/kgu/developers/domain/schedule/application/command/ScheduleService.java (1)
aics-domain/src/main/java/kgu/developers/domain/schedule/exception/ScheduleNotFoundException.java (1)
  • ScheduleNotFoundException (7-9)
aics-admin/src/main/java/kgu/developers/admin/schedule/presentation/ScheduleAdminControllerImpl.java (1)
aics-common/src/main/java/kgu/developers/common/auth/filter/TokenAuthenticationFilter.java (1)
  • RequiredArgsConstructor (16-41)
🔇 Additional comments (7)
aics-domain/src/main/java/kgu/developers/domain/schedule/application/command/ScheduleService.java (1)

8-8: LGTM!

ScheduleNotFoundException import가 적절하게 추가되었으며 deleteSchedule 메서드에서 올바르게 사용되고 있습니다.

aics-admin/src/main/java/kgu/developers/admin/schedule/presentation/request/ScheduleContentUpdateRequest.java (1)

1-14: LGTM!

심플하고 명확한 DTO 구현입니다. 필수 validation과 Swagger 문서화가 적절히 적용되어 있습니다.

aics-admin/src/main/java/kgu/developers/admin/schedule/presentation/request/ScheduleCreateRequest.java (1)

25-31: 날짜 범위 검증 로직이 올바릅니다.

null 체크를 먼저 수행하고 날짜 순서를 검증하는 로직이 적절합니다. @NotNull 검증과 분리되어 있어 각 validation의 책임이 명확합니다.

aics-api/src/main/java/kgu/developers/api/schedule/presentation/response/ScheduleTypeContentResponse.java (1)

17-22: LGTM!

도메인 객체를 응답 DTO로 변환하는 팩토리 메서드가 잘 구현되어 있습니다.

aics-api/src/main/java/kgu/developers/api/schedule/presentation/ScheduleController.java (1)

1-43: LGTM!

일정 조회 API 인터페이스가 잘 설계되어 있습니다. 각 엔드포인트의 목적이 명확하고 Swagger 문서화가 충실합니다.

aics-api/src/main/java/kgu/developers/api/schedule/application/ScheduleFacade.java (1)

13-32: LGTM!

Facade 패턴이 적절히 적용되어 있으며, 읽기 전용 트랜잭션 설정이 올바릅니다. 각 메서드가 query service로 명확하게 위임하고 있습니다.

aics-api/src/main/java/kgu/developers/api/schedule/presentation/ScheduleControllerImpl.java (1)

17-43: LGTM!

Controller 구현이 깔끔하며 facade를 통해 비즈니스 로직과 적절히 분리되어 있습니다. 현재 시간을 기준으로 일정 상태를 계산하는 로직이 올바릅니다.

Copy link
Copy Markdown
Contributor

@JangYeongHu JangYeongHu left a comment

Choose a reason for hiding this comment

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

전체적으로 잘 해주신 것 같습니다!
리뷰만 확인해주세요
그리고 테스트 코드도 필요할 것 같습니다.
securityConfig의 갱신도 필요할 것 같습니다.

Copy link
Copy Markdown
Member

@LeeHanEum LeeHanEum left a comment

Choose a reason for hiding this comment

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

확인했고 영후님 리뷰랑 코드래빗 확인해주시면 될것 같아요~

@dkdltm221 dkdltm221 changed the title feat/KD-48 : Schedule API 구현 feat/#KD-48 : Schedule API 구현 Nov 18, 2025
@codecov
Copy link
Copy Markdown

codecov bot commented Nov 18, 2025

Codecov Report

❌ Patch coverage is 86.36364% with 3 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
...opers/api/schedule/application/ScheduleFacade.java 0.00% 3 Missing ⚠️

Impacted file tree graph

@@              Coverage Diff              @@
##             develop     #286      +/-   ##
=============================================
- Coverage      99.27%   97.48%   -1.79%     
- Complexity        42       46       +4     
=============================================
  Files             16       18       +2     
  Lines            137      159      +22     
  Branches           1        1              
=============================================
+ Hits             136      155      +19     
- Misses             0        3       +3     
  Partials           1        1              
Files with missing lines Coverage Δ Complexity Δ
...dmin/schedule/application/ScheduleAdminFacade.java 100.00% <100.00%> (ø) 4.00 <4.00> (?)
...opers/api/schedule/application/ScheduleFacade.java 0.00% <0.00%> (ø) 0.00 <0.00> (?)

Continue to review full report in Codecov by Sentry.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 7bdf45c...0d5c7b4. Read the comment docs.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@dkdltm221 dkdltm221 merged commit 31b80e1 into develop Nov 21, 2025
5 checks passed
@dkdltm221 dkdltm221 deleted the feat/KD-48-api branch November 21, 2025 09:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

✨feature create new feature

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Schedule API 구현

3 participants