Skip to content

Conversation

@kwon204
Copy link
Contributor

@kwon204 kwon204 commented May 19, 2025

#️⃣ 연관된 이슈>

📝 작업 내용> 이번 PR에서 작업한 내용을 간략히 설명해주세요(이미지 첨부 가능)

  • 롱 폴링 응답 데이터를 추가하였습니다.
  • 생성과 수정에 id가 추가되었습니다.
  • 이 과정에서 구글 서버에서 받은 일정을 먼저 데이터베이스에 처리한 후 클라이언트에게 응답하도록 변경하였습니다.
  • 데이터베이스에 처리하는 메소드가 syncPersonalEvent를 반환하도록 수정하였습니다.

추가

  • 클라이언트로의 응답에서 googleEventId를 삭제하였습니다.
  • 일정 상태를 CREATED, UPDATED, DELETED로 구분하였습니다.

🙏 여기는 꼭 봐주세요! > 리뷰어가 특별히 봐주었으면 하는 부분이 있다면 작성해주세요

Summary by CodeRabbit

  • New Features
    • Enhanced personal event synchronization to provide detailed results for each synced event, including event ID, adjustability, and calendar ID.
  • Documentation
    • Updated API documentation to clearly describe the structure of synchronization responses.

kwon204 added 3 commits May 19, 2025 01:30
변경

- 추가적인 정보를 위해 새로운 일정의 경우 디비에 저장한 후에 응답
- 수정의 경우 동일
- 삭제의 경우 추가적인 정보에 null 값을 저장해서 처리
@kwon204 kwon204 self-assigned this May 19, 2025
@kwon204 kwon204 requested a review from efdao as a code owner May 19, 2025 06:40
@kwon204 kwon204 added the 🛠️ BE Backend label May 19, 2025
@coderabbitai
Copy link

coderabbitai bot commented May 19, 2025

## Walkthrough

The synchronization logic for personal events was refactored to return detailed results for each event processed. The service method now returns a list of synchronization results, and a new data structure with additional fields was introduced. API documentation was updated to reflect the new response schema, and handler logic was adjusted to utilize the returned data.

## Changes

| File(s)                                   | Change Summary                                                                                                                                                                                                                         |
|------------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `.../PersonalEventService.java`           | Refactored `syncWithGoogleEvents` to return a `List<SyncPersonalEvent>`; added `syncPersonalEventFromGoogleEvent` method; removed `upsertPersonalEventByGoogleEvent`; changed `createWithRequest` to return entity; updated `deletePersonalEventByGoogleEvent` to return Optional. |
| `.../dto/SyncPersonalEvent.java`          | Replaced `googleEventId` field with `id`, `isAdjustable`, `calendarId`; changed `status` to enum `Status`; replaced static factory method to create from `PersonalEvent` and `Status`.                                            |
| `.../PersonalEventHandler.java`           | Updated `sync` method to capture and use returned sync results from service; removed commented-out code; rearranged variable declarations.                                                                                         |
| `.../PersonalEventController.java`        | Changed `createPersonalEvent` to convert entity to response DTO via static factory; enhanced OpenAPI doc for sync endpoint with explicit 200 response schema `SyncResponse`.                                                        |
| `.../dto/PersonalEventResponse.java`      | Removed `googleEventId` field; updated `fromEntity` factory method accordingly.                                                                                                                                                     |
| `.../entity/PersonalEvent.java`            | Removed static factory method `fromGoogleEvent`.                                                                                                                                                                                   |
| `.../PersonalEventControllerTest.java`    | Modified test to mock and return `PersonalEvent` entity instead of response DTO for creation method.                                                                                                                              |
| `.../PersonalEventServiceTest.java`       | Updated tests to reflect changed return types and usage of getters for `PersonalEvent`; added detailed stubbing for updated personal event in sync tests.                                                                          |

## Sequence Diagram(s)

```mermaid
sequenceDiagram
    participant Client
    participant Controller
    participant Handler
    participant Service
    participant DB

    Client->>Controller: POST /sync-personal-events
    Controller->>Handler: handle sync request
    Handler->>Service: syncWithGoogleEvents(events, user, calendarId)
    loop For each GoogleEvent
        Service->>Service: syncPersonalEventFromGoogleEvent(...)
        alt CONFIRMED
            Service->>DB: find existing PersonalEvent
            alt exists
                Service->>DB: update PersonalEvent
                DB-->>Service: updated PersonalEvent
                Service->>Service: create SyncPersonalEvent with UPDATED status
            else not exists
                Service->>DB: create PersonalEvent
                DB-->>Service: created PersonalEvent
                Service->>Service: create SyncPersonalEvent with CREATED status
            end
        else CANCELLED
            Service->>DB: delete PersonalEvent
            DB-->>Service: deleted PersonalEvent (optional)
            Service->>Service: create SyncPersonalEvent with DELETED status if deleted
        else TENTATIVE
            Service->>Service: no action, returns empty
        end
    end
    Service-->>Handler: List<SyncPersonalEvent>
    Handler->>Controller: set result with List<SyncPersonalEvent>
    Controller-->>Client: Response with SyncResponse schema

Possibly related PRs

Suggested reviewers

  • efdao

Poem

🐇 Hopping through code, I sync and I bind,
Now each event’s result is easy to find!
With new fields and docs, the story is clear—
Every calendar hop brings more cheer.
🐰✨
In the warren of logic, the details align—
Personal events, perfectly in line!


<!-- walkthrough_end -->
<!-- internal state start -->


<!-- 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 -->

<!-- internal state end -->
<!-- finishing_touch_checkbox_start -->

<details open="true">
<summary>✨ Finishing Touches</summary>

- [ ] <!-- {"checkboxId": "7962f53c-55bc-4827-bfbf-6a18da830691"} --> 📝 Generate Docstrings

</details>

<!-- finishing_touch_checkbox_end -->
<!-- tips_start -->

---

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.

<details>
<summary>❤️ Share</summary>

- [X](https://twitter.com/intent/tweet?text=I%20just%20used%20%40coderabbitai%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20the%20proprietary%20code.%20Check%20it%20out%3A&url=https%3A//coderabbit.ai)
- [Mastodon](https://mastodon.social/share?text=I%20just%20used%20%40coderabbitai%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20the%20proprietary%20code.%20Check%20it%20out%3A%20https%3A%2F%2Fcoderabbit.ai)
- [Reddit](https://www.reddit.com/submit?title=Great%20tool%20for%20code%20review%20-%20CodeRabbit&text=I%20just%20used%20CodeRabbit%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20proprietary%20code.%20Check%20it%20out%3A%20https%3A//coderabbit.ai)
- [LinkedIn](https://www.linkedin.com/sharing/share-offsite/?url=https%3A%2F%2Fcoderabbit.ai&mini=true&title=Great%20tool%20for%20code%20review%20-%20CodeRabbit&summary=I%20just%20used%20CodeRabbit%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20proprietary%20code)

</details>

<details>
<summary>🪧 Tips</summary>

### Chat

There are 3 ways to chat with [CodeRabbit](https://coderabbit.ai?utm_source=oss&utm_medium=github&utm_campaign=softeer5th/Team4-enDolphin&utm_content=408):

- Review comments: Directly reply to a review comment made by CodeRabbit. Example:
  - `I pushed a fix in commit <commit_id>, please review it.`
  - `Explain this complex logic.`
  - `Open a follow-up GitHub issue for this discussion.`
- Files and specific lines of code (under the "Files changed" tab): Tag `@coderabbitai` in a new review comment at the desired location with your query. Examples:
  - `@coderabbitai explain this code block.`
  -	`@coderabbitai modularize this function.`
- PR comments: Tag `@coderabbitai` in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
  - `@coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.`
  - `@coderabbitai read src/utils.ts and explain its main purpose.`
  - `@coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.`
  - `@coderabbitai help me debug CodeRabbit configuration file.`

### Support

Need help? Create a ticket on our [support page](https://www.coderabbit.ai/contact-us/support) for assistance with any issues or questions.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

### CodeRabbit Commands (Invoked using PR comments)

- `@coderabbitai pause` to pause the reviews on a PR.
- `@coderabbitai resume` to resume the paused reviews.
- `@coderabbitai review` to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
- `@coderabbitai full review` to do a full review from scratch and review all the files again.
- `@coderabbitai summary` to regenerate the summary of the PR.
- `@coderabbitai generate docstrings` to [generate docstrings](https://docs.coderabbit.ai/finishing-touches/docstrings) for this PR.
- `@coderabbitai generate sequence diagram` to generate a sequence diagram of the changes in this PR.
- `@coderabbitai resolve` resolve all the CodeRabbit review comments.
- `@coderabbitai configuration` to show the current CodeRabbit configuration for the repository.
- `@coderabbitai help` to get help.

### Other keywords and placeholders

- Add `@coderabbitai ignore` anywhere in the PR description to prevent this PR from being reviewed.
- Add `@coderabbitai summary` to generate the high-level summary at a specific location in the PR description.
- Add `@coderabbitai` anywhere in the PR title to generate the title automatically.

### CodeRabbit Configuration File (`.coderabbit.yaml`)

- You can programmatically configure CodeRabbit by adding a `.coderabbit.yaml` file to the root of your repository.
- Please see the [configuration documentation](https://docs.coderabbit.ai/guides/configure-coderabbit) for more information.
- If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: `# yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json`

### Documentation and Community

- Visit our [Documentation](https://docs.coderabbit.ai) for detailed information on how to use CodeRabbit.
- Join our [Discord Community](http://discord.gg/coderabbit) to get help, request features, and share feedback.
- Follow us on [X/Twitter](https://twitter.com/coderabbitai) for updates and announcements.

</details>

<!-- tips_end -->

LocalDateTime endDateTime,
String status
) {

Copy link
Collaborator

Choose a reason for hiding this comment

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

just ask; status를 enum 말고 String으로 했던 이유가 있었던가요?

Copy link
Collaborator

Choose a reason for hiding this comment

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

db를 거쳐도 googleEventId 응답에 포함해야 하나요?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

  • 가독성을 위해 enum으로 수정하겠습니다!
  • 이전 업데이트 때 일정들을 googleEventId로 구분하도록 프론트에서 반영했을거라 googleEventId를 응답에서 빼는 건 프론트와 협의가 필요할 거 같습니다!

Copy link
Contributor Author

Choose a reason for hiding this comment

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

프론트와 협의한 결과, googleEventId를 응답에서 삭제하기로 결정하였습니다.!

yield SyncPersonalEvent.from(googleEvent);
}
}
case TENTATIVE -> SyncPersonalEvent.from(googleEvent);
Copy link
Collaborator

Choose a reason for hiding this comment

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

tentative를 클라이언트에 주기로한건가요?

Copy link
Collaborator

Choose a reason for hiding this comment

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

db 거치는데 confirmed를 그대로 주는 이유가 있을까요?
update와 create 분기하는 건 어떻게 생각하시나요

Copy link
Contributor Author

Choose a reason for hiding this comment

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

  • tentative는 제외하도록 하겠습니다!
  • confirmed를 주는 건 cancelled와 구분하기 위해 필요할 거 같습니다!
  • update와 create를 upsertPersonalEventByGoogleEvent에서 분기하고 있는데 혹시 어떤 걸 의미하는지 궁금합니다!

Copy link
Collaborator

@efdao efdao May 30, 2025

Choose a reason for hiding this comment

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

프론트에서 confirmed를 받고 어떤 동작을 수행하고 있는지는 정확히 모르지만,
백에서 내려주는 응답을 생성, 변경, 삭제 세가지의 상태를 정의해서 주면 더 편한 부분이 있지 않을까 하는 제 생각이었습니다.

백엔드 로직에서도 구글로부터 confirmed를 받으면 해당 id의 일정이 존재하는지 확인 후 update, create로 분기를 하는데요, 프론트도 동일한 방법을 수행해야 한다면 효율성이 떨어지지 않을까 해서요!

Copy link
Contributor Author

Choose a reason for hiding this comment

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

백에서 수행한 로직을 프론트에서도 수행하면 비효율적이긴 하겠네요!
어떤 것이 편한 지 프론트와 협의 후 수정하겠습니다!

Copy link
Contributor Author

Choose a reason for hiding this comment

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

프론트와 협의한 결과, 백엔드에서 생성, 변경, 삭제를 구분해서 응답하는 걸로 수정하였습니다.!

@kwon204 kwon204 requested a review from efdao May 30, 2025 14:12
Copy link

@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

♻️ Duplicate comments (2)
backend/src/main/java/endolphin/backend/domain/personal_event/dto/SyncPersonalEvent.java (1)

15-25: Great improvement using enum for status field!

The change from String to enum for the status field improves type safety and addresses the previous review feedback. The enum values CREATED, UPDATED, and DELETED clearly represent the synchronization states.

backend/src/main/java/endolphin/backend/domain/personal_event/PersonalEventService.java (1)

225-241: Excellent implementation addressing previous feedback!

The refactored method now returns detailed synchronization results as suggested in previous reviews. This allows the client to understand exactly what operations (create, update, delete) were performed for each event, improving the efficiency of client-side processing.

🧹 Nitpick comments (1)
backend/src/test/java/endolphin/backend/domain/personal_event/PersonalEventServiceTest.java (1)

240-248: Consider using a test fixture or builder for cleaner test setup.

While the mocking is correct, stubbing multiple getters creates brittle tests. Consider creating a test fixture method or using a builder pattern to create actual PersonalEvent instances instead of mocks for cleaner and more maintainable tests.

Example approach:

-PersonalEvent updatedPersonalEvent = createWithRequest("new Title");
-given(updatedPersonalEvent.getId()).willReturn(1L);
-given(updatedPersonalEvent.getTitle()).willReturn("new Title");
-given(updatedPersonalEvent.getStartTime()).willReturn(LocalDateTime.of(2024, 3, 10, 10, 0));
-given(updatedPersonalEvent.getEndTime()).willReturn(LocalDateTime.of(2024, 3, 10, 12, 0));
-given(updatedPersonalEvent.getCalendarId()).willReturn("testCalendarId");
-given(updatedPersonalEvent.getIsAdjustable()).willReturn(false);
+PersonalEvent updatedPersonalEvent = PersonalEvent.builder()
+    .id(1L)
+    .title("new Title")
+    .startTime(LocalDateTime.of(2024, 3, 10, 10, 0))
+    .endTime(LocalDateTime.of(2024, 3, 10, 12, 0))
+    .calendarId("testCalendarId")
+    .isAdjustable(false)
+    .user(user)
+    .build();
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 8c4296d and 11806bf.

📒 Files selected for processing (8)
  • backend/src/main/java/endolphin/backend/domain/personal_event/PersonalEventController.java (3 hunks)
  • backend/src/main/java/endolphin/backend/domain/personal_event/PersonalEventService.java (7 hunks)
  • backend/src/main/java/endolphin/backend/domain/personal_event/dto/PersonalEventResponse.java (2 hunks)
  • backend/src/main/java/endolphin/backend/domain/personal_event/dto/SyncPersonalEvent.java (1 hunks)
  • backend/src/main/java/endolphin/backend/domain/personal_event/entity/PersonalEvent.java (0 hunks)
  • backend/src/main/java/endolphin/backend/domain/personal_event/event/handler/PersonalEventHandler.java (1 hunks)
  • backend/src/test/java/endolphin/backend/domain/personal_event/PersonalEventControllerTest.java (2 hunks)
  • backend/src/test/java/endolphin/backend/domain/personal_event/PersonalEventServiceTest.java (2 hunks)
💤 Files with no reviewable changes (1)
  • backend/src/main/java/endolphin/backend/domain/personal_event/entity/PersonalEvent.java
⏰ Context from checks skipped due to timeout of 90000ms (1)
  • GitHub Check: backend
🔇 Additional comments (13)
backend/src/main/java/endolphin/backend/domain/personal_event/PersonalEventController.java (3)

6-6: Import added for entity handling refactor.

The import of PersonalEvent entity is correctly added to support the refactored createPersonalEvent method.


85-86: Excellent separation of concerns improvement.

The refactoring to have the service return a PersonalEvent entity and the controller handle DTO conversion follows good architectural patterns. This separates business logic (service) from presentation concerns (controller).


135-136: API documentation properly updated.

The OpenAPI documentation correctly specifies the SyncResponse schema for the 200 response, providing better API contract clarity for consumers.

backend/src/test/java/endolphin/backend/domain/personal_event/PersonalEventControllerTest.java (3)

9-9: Necessary imports added for test refactoring.

The imports for PersonalEvent entity and Mockito are correctly added to support the updated test logic.

Also applies to: 17-17


52-53: Test properly aligned with controller refactoring.

The test correctly mocks a PersonalEvent entity and updates the service mock to return this entity, properly reflecting the controller's new behavior of converting entities to DTOs.

Also applies to: 58-58


57-57:

Details

✅ Verification successful

Verify PersonalEventResponse constructor consistency.

The PersonalEventResponse constructor is being called with "testCalendarId" as the last parameter, but according to the DTO changes in PersonalEventResponse.java, the googleEventId field was removed. Please verify this constructor call is consistent with the updated DTO structure.


🏁 Script executed:

#!/bin/bash
# Description: Verify PersonalEventResponse constructor parameters
# Expected: Constructor should match the fields in the DTO after googleEventId removal

ast-grep --pattern $'public record PersonalEventResponse(
  $$$
) {
  $$$
}'

Length of output: 2507


PersonalEventResponse constructor invocation matches updated DTO

I’ve confirmed that PersonalEventResponse is defined with fields (Long id, String title, LocalDateTime startDateTime, LocalDateTime endDateTime, Boolean isAdjustable, String calendarId). The test’s call ending in false, "testCalendarId") correctly maps to isAdjustable and calendarId, and there is no googleEventId field. No changes are needed.

backend/src/main/java/endolphin/backend/domain/personal_event/event/handler/PersonalEventHandler.java (2)

29-29: Good improvement in variable positioning.

Moving the googleCalendarId retrieval earlier improves code readability and logical flow.


34-35: Excellent utilization of detailed sync results.

The handler now properly captures and utilizes the List<SyncPersonalEvent> returned by the service, enabling more detailed long polling responses with creation and modification event IDs as mentioned in the PR objectives.

backend/src/main/java/endolphin/backend/domain/personal_event/dto/PersonalEventResponse.java (1)

22-22: fromEntity method correctly updated.

The static factory method properly reflects the removal of the googleEventId field, maintaining consistency between the record structure and the conversion logic.

backend/src/test/java/endolphin/backend/domain/personal_event/PersonalEventServiceTest.java (1)

109-115: LGTM! Test correctly updated for the new return type.

The test has been properly updated to handle the service method returning a PersonalEvent entity instead of a PersonalEventResponse DTO. The assertions correctly use getter methods to validate the entity's properties.

backend/src/main/java/endolphin/backend/domain/personal_event/PersonalEventService.java (3)

69-100: Good change returning the entity directly.

Returning the PersonalEvent entity from the service layer and letting the controller handle the DTO conversion is a cleaner separation of concerns.


243-274: Clean implementation with modern Java features!

The use of switch expressions and Optional makes the code more readable and type-safe. The logic correctly implements the create/update/delete synchronization states as discussed in previous reviews.

However, there's a potential inconsistency: when creating a new event (lines 260-263), the discussions parameter is not used, while updates do process discussions. Consider whether newly created events should also be preprocessed for discussions.


282-291: Good use of Optional pattern for delete operations.

The method correctly returns the deleted event wrapped in Optional, allowing the sync logic to include deletion details in the response. The implementation follows Optional best practices.

Boolean isAdjustable,
String calendarId,
String googleEventId
String calendarId
Copy link

Choose a reason for hiding this comment

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

💡 Verification agent

🧩 Analysis chain

Appropriate removal of Google-specific field.

Removing the googleEventId field from the public API response is a good architectural decision that reduces coupling with Google Calendar implementation details.

Consider if this removal constitutes a breaking change for existing API consumers. Please verify if there are any client applications that depend on this field.


🏁 Script executed:

#!/bin/bash
# Description: Search for usage of googleEventId in client code or documentation
# Expected: Should identify any dependencies on this field

rg -i "googleeventid" --type-add 'docs:*.md,*.txt,*.rst' --type docs
rg -i "google.*event.*id" --type-add 'frontend:*.js,*.ts,*.jsx,*.tsx' --type frontend

Length of output: 454


I’m not finding any occurrences because the previous ripgrep commands were overly restrictive. Let’s search the entire repo for both camelCase and snake_case variants:


🏁 Script executed:

#!/bin/bash
# Search for any references to googleEventId or google_event_id across all files
rg -i "googleEventId" -n .
rg -i "google_event_id" -n .

Length of output: 6031


Breaking Change: Update Front-end Model After Removing googleEventId

The API DTO no longer includes googleEventId, but your front-end schema still expects it—this will break existing clients. Please remove or adapt all references to googleEventId in consumer code:

• frontend/src/features/my-calendar/model/index.ts
– Remove the googleEventId: z.string(), field (line 10)
– Remove googleEventId: true from the selected properties object (line 16)

After updating the front-end, verify end-to-end functionality (e.g., calendar listing, event details) to ensure no runtime errors occur when the field is absent.

🤖 Prompt for AI Agents
In
backend/src/main/java/endolphin/backend/domain/personal_event/dto/PersonalEventResponse.java
at line 12, the googleEventId field was removed, causing a breaking change for
front-end clients. To fix this, update the front-end model by removing the
googleEventId field declaration at line 10 and removing googleEventId: true from
the selected properties object at line 16 in
frontend/src/features/my-calendar/model/index.ts. After these changes, test the
full flow to ensure no runtime errors occur due to the missing field.

@kwon204 kwon204 merged commit 5012a8a into dev Jun 9, 2025
3 checks passed
@kwon204 kwon204 deleted the feature/be/sync-personal-event branch June 9, 2025 01:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

🛠️ BE Backend

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants