Skip to content

feat: 사용자 설정 정보 저장/변경#132

Merged
jaelyangChoi merged 8 commits intodevelopfrom
feature/#131-userSettings-deleteScreenShot
Oct 21, 2025
Merged

feat: 사용자 설정 정보 저장/변경#132
jaelyangChoi merged 8 commits intodevelopfrom
feature/#131-userSettings-deleteScreenShot

Conversation

@jaelyangChoi
Copy link
Collaborator

@jaelyangChoi jaelyangChoi commented Oct 16, 2025

📌 관련 이슈 (필수)

이 PR이 어떤 이슈를 해결하는지 작성해주세요. 예시: closes #123, resolves #456

📝 작업 내용 (필수)

이번 PR에서 작업한 내용을 간략히 설명해주세요.

  • 회원가입 시 설정 정보 생성
  • 회원탈퇴 시 설정 정보 삭제
  • 설정 정보 변경/조회

💬 리뷰 참고 사항 (선택)

리뷰어가 참고할 만한 사항이나 리뷰어가 특별히 봐주었으면 하는 부분이 있다면 작성해주세요.

Summary by CodeRabbit

  • New Features

    • Retrieve and update personal account settings via new endpoints; screenshot auto-delete toggle persisted
  • Documentation

    • Updated API and error-code docs to use member-centric terminology ("회원") and include settings-related errors and examples
  • Tests

    • Added tests for settings retrieval, update flows, and error-code documentation
  • Chores

    • Database migration added to create user settings storage

@coderabbitai
Copy link

coderabbitai bot commented Oct 16, 2025

Walkthrough

Adds persistent user settings (screenshot auto-delete) with JPA entity, migration, repository, service methods, DTOs, controller endpoints (GET/PUT /v1/user/settings), error code/type entries, tests, and documentation terminology updates replacing "사용자/유저" with "회원".

Changes

Cohort / File(s) Summary
Documentation Terminology Updates
capturecat-core/src/docs/asciidoc/error-codes.adoc, capturecat-core/src/docs/asciidoc/user.adoc
Renamed 사용자/유저 wording to 회원 across headings/anchors and operation names; added 회원 설정 조회/변경 sections and updated error-code references.
DB Migration
capturecat-core/src/main/resources/db/migration/V3__create_user_settings.sql
New Flyway migration creating user_settings table (PK user_id, screenshot_auto_delete_enabled, timestamps, FK to users).
Domain & Persistence
capturecat-core/src/main/java/com/capturecat/core/domain/user/UserSettings.java, .../UserSettingsRepository.java
Added UserSettings JPA entity with init/change methods and UserSettingsRepository extending JpaRepository<UserSettings, Long>.
Service Layer
capturecat-core/src/main/java/com/capturecat/core/service/user/UserService.java
Injected UserSettingsRepository; initialize settings on user creation; delete settings on user removal; added getUserSettings(String), setUserSettings(long, boolean), and setUserSettings(String, boolean).
REST Controller
capturecat-core/src/main/java/com/capturecat/core/api/user/UserController.java
Added GET /v1/user/settings and PUT /v1/user/settings endpoints returning/accepting settings DTOs and delegating to service.
API DTOs
capturecat-core/src/main/java/com/capturecat/core/api/user/dto/UserReqDto.java, .../UserRespDto.java
Added nested UserSettingsReqDto (screenshotAutoDeleteEnabled) and UserSettingsRespDto (userId, screenshotAutoDeleteEnabled) with mapping from domain.
Error Handling
capturecat-core/src/main/java/com/capturecat/core/support/error/ErrorCode.java, .../ErrorType.java
Added NOT_FOUND_USER_SETTINGS ErrorCode and USER_SETTINGS_NOT_FOUND ErrorType (status/log level mapping).
Tests
capturecat-core/src/test/java/com/capturecat/core/api/error/ErrorCodeControllerTest.java, .../api/user/UserControllerTest.java, .../service/user/UserServiceTest.java
Added tests and API docs for settings error codes and controller endpoints; mocked UserSettingsRepository in service tests; updated lifecycle tests to cover settings creation/deletion.

Sequence Diagram(s)

sequenceDiagram
    participant Client
    participant Controller as UserController
    participant Service as UserService
    participant Repo as UserSettingsRepository
    participant DB as Database

    rect rgb(230,250,240)
    Note over Client,Controller: GET /v1/user/settings
    Client->>Controller: GET /v1/user/settings (auth)
    Controller->>Service: getUserSettings(username)
    Service->>Repo: findById(userId)
    Repo->>DB: SELECT user_settings
    DB-->>Repo: row / empty
    Repo-->>Service: UserSettings?
    Service-->>Controller: UserSettings
    Controller-->>Client: ApiResponse<UserSettingsRespDto>
    end

    rect rgb(240,240,255)
    Note over Client,Controller: PUT /v1/user/settings
    Client->>Controller: PUT /v1/user/settings (body, auth)
    Controller->>Service: setUserSettings(userId, enabled)
    Service->>Repo: findById(userId)
    Repo->>DB: SELECT user_settings
    alt exists
        Service->>Repo: save(updated UserSettings)
    else not exists
        Service->>Service: UserSettings.init(userId)
        Service->>Repo: save(new UserSettings)
    end
    Repo->>DB: INSERT/UPDATE user_settings
    DB-->>Repo: saved row
    Repo-->>Service: UserSettings
    Service-->>Controller: UserSettings
    Controller-->>Client: ApiResponse<UserSettingsRespDto>
    end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Suggested reviewers

  • leeedohyun

Poem

🐇 I hop through lines with tiny paws,
A setting added without a pause.
사용자 → 회원, names align,
Screenshots vanish when auto-delete's fine.
Tiny nose, big joy 🥕

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 57.14% 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 Check skipped - CodeRabbit’s high-level summary is enabled.
Title Check ✅ Passed The PR title "feat: 사용자 설정 정보 저장/변경" (User settings save/change) is directly related to the main changes in the changeset. The PR implements a complete user settings feature that includes creating settings during signup, retrieving settings via GET /settings, updating settings via PUT /settings, and deleting settings on account withdrawal. The title specifically highlights the primary user-facing operations (save and change), which are the core functionality being introduced. The title is clear, specific, and appropriately focused on the main change without being vague or misleading, though it doesn't enumerate every operation included in the changeset—which aligns with the guideline that titles don't need to cover all details.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feature/#131-userSettings-deleteScreenShot

📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between b998f5f and cab87b9.

📒 Files selected for processing (1)
  • capturecat-core/src/main/java/com/capturecat/core/service/user/UserService.java (6 hunks)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: deploy-dev
🔇 Additional comments (7)
capturecat-core/src/main/java/com/capturecat/core/service/user/UserService.java (7)

21-22: LGTM! Clean dependency integration.

The new imports and repository injection follow the existing patterns in the class and properly set up the infrastructure for user settings management.

Also applies to: 38-38


60-62: LGTM! Proper settings initialization during signup.

Settings are correctly initialized after the user is saved, with a sensible default (auto-delete disabled). The placement ensures proper data consistency within the transaction.


84-87: LGTM! Consistent settings initialization for social users.

Settings initialization is correctly placed within the new user creation path (orElseGet lambda) and uses the same default value as regular signup, ensuring consistency across authentication methods.


127-134: LGTM! Well-implemented fetch method.

The method correctly handles the lookup chain (username → user → settings) with appropriate error handling for each step. The readOnly transaction annotation is properly applied for this fetch operation.


136-147: LGTM! Proper upsert implementation.

The upsert pattern correctly handles both creation and update scenarios using orElseGet for lazy initialization and always persisting the result. The implementation ensures settings exist and are updated atomically within the transaction.


149-155: LGTM! Useful convenience wrapper.

This overload provides a cleaner API for callers that have a username, properly delegating to the core implementation after user lookup.


165-169: LGTM! Correct deletion order and updated documentation.

UserSettings deletion is correctly placed before user deletion to avoid foreign key constraint issues. The comment numbering has been properly updated to reflect the new cleanup step.


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.

@jaelyangChoi jaelyangChoi changed the title feature/#131-userSettings-deleteScreenShot feat: 사용자 설정 정보 저장/변경 Oct 16, 2025
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: 4

🧹 Nitpick comments (2)
capturecat-core/src/main/java/com/capturecat/core/api/user/dto/UserReqDto.java (1)

15-15: Remove unused import.

The import for UserSettings is not used in this file. The DTO classes don't reference the entity directly.

 import com.capturecat.core.domain.user.User;
 import com.capturecat.core.domain.user.UserRole;
-import com.capturecat.core.domain.user.UserSettings;
capturecat-core/src/test/java/com/capturecat/core/api/user/UserControllerTest.java (1)

163-163: Consider using any(LoginUser.class) instead of nullable(String.class).

Line 163 uses nullable(String.class) for the first parameter of setUserSettings, but based on the pattern in other tests (e.g., line 112: any()), this should likely be any(LoginUser.class) to match the actual method signature.

-		willReturn(userSettings).given(userService).setUserSettings(nullable(String.class), anyBoolean());
+		willReturn(userSettings).given(userService).setUserSettings(any(LoginUser.class), anyBoolean());
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 7d004e4 and a535d30.

📒 Files selected for processing (13)
  • capturecat-core/src/docs/asciidoc/error-codes.adoc (2 hunks)
  • capturecat-core/src/docs/asciidoc/user.adoc (1 hunks)
  • capturecat-core/src/main/java/com/capturecat/core/api/user/UserController.java (4 hunks)
  • capturecat-core/src/main/java/com/capturecat/core/api/user/dto/UserReqDto.java (2 hunks)
  • capturecat-core/src/main/java/com/capturecat/core/api/user/dto/UserRespDto.java (2 hunks)
  • capturecat-core/src/main/java/com/capturecat/core/domain/user/UserSettings.java (1 hunks)
  • capturecat-core/src/main/java/com/capturecat/core/domain/user/UserSettingsRepository.java (1 hunks)
  • capturecat-core/src/main/java/com/capturecat/core/service/user/UserService.java (6 hunks)
  • capturecat-core/src/main/java/com/capturecat/core/support/error/ErrorCode.java (1 hunks)
  • capturecat-core/src/main/java/com/capturecat/core/support/error/ErrorType.java (1 hunks)
  • capturecat-core/src/test/java/com/capturecat/core/api/error/ErrorCodeControllerTest.java (1 hunks)
  • capturecat-core/src/test/java/com/capturecat/core/api/user/UserControllerTest.java (2 hunks)
  • capturecat-core/src/test/java/com/capturecat/core/service/user/UserServiceTest.java (5 hunks)
🧰 Additional context used
🧬 Code graph analysis (6)
capturecat-core/src/main/java/com/capturecat/core/api/user/dto/UserReqDto.java (1)
capturecat-core/src/main/java/com/capturecat/core/api/user/dto/UserRespDto.java (4)
  • Getter (15-27)
  • Getter (30-36)
  • Getter (39-49)
  • Getter (52-61)
capturecat-core/src/main/java/com/capturecat/core/api/user/dto/UserRespDto.java (1)
capturecat-core/src/main/java/com/capturecat/core/api/user/dto/UserReqDto.java (4)
  • Getter (21-46)
  • Getter (49-54)
  • Getter (57-62)
  • Getter (65-69)
capturecat-core/src/test/java/com/capturecat/core/api/user/UserControllerTest.java (2)
capturecat-core/src/main/java/com/capturecat/core/api/user/dto/UserReqDto.java (1)
  • UserReqDto (18-70)
capturecat-core/src/main/java/com/capturecat/core/api/user/dto/UserRespDto.java (1)
  • UserRespDto (12-63)
capturecat-core/src/main/java/com/capturecat/core/domain/user/UserSettings.java (2)
capturecat-core/src/main/java/com/capturecat/core/api/user/dto/UserRespDto.java (4)
  • Getter (15-27)
  • Getter (30-36)
  • Getter (39-49)
  • Getter (52-61)
capturecat-core/src/main/java/com/capturecat/core/api/user/dto/UserReqDto.java (4)
  • Getter (21-46)
  • Getter (49-54)
  • Getter (57-62)
  • Getter (65-69)
capturecat-core/src/main/java/com/capturecat/core/service/user/UserService.java (1)
capturecat-core/src/test/java/com/capturecat/core/api/user/UserApiTest.java (1)
  • Transactional (22-100)
capturecat-core/src/main/java/com/capturecat/core/api/user/UserController.java (2)
capturecat-core/src/main/java/com/capturecat/core/api/user/dto/UserReqDto.java (1)
  • UserReqDto (18-70)
capturecat-core/src/main/java/com/capturecat/core/api/user/dto/UserRespDto.java (1)
  • UserRespDto (12-63)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: build
  • GitHub Check: deploy-dev
🔇 Additional comments (20)
capturecat-core/src/main/java/com/capturecat/core/domain/user/UserSettingsRepository.java (1)

1-6: LGTM!

The repository interface follows Spring Data JPA conventions correctly. The interface is clean and leverages the default CRUD operations provided by JpaRepository.

capturecat-core/src/main/java/com/capturecat/core/support/error/ErrorCode.java (1)

44-45: LGTM!

The new error code NOT_FOUND_USER_SETTINGS is properly added with a clear Korean message, consistent with the existing error code patterns in the codebase.

capturecat-core/src/main/java/com/capturecat/core/api/user/dto/UserReqDto.java (1)

64-69: LGTM!

The UserSettingsReqDto is clean and follows the existing DTO pattern in this file. The boolean field appropriately represents the screenshot auto-delete preference.

capturecat-core/src/docs/asciidoc/error-codes.adoc (1)

77-115: LGTM!

The documentation updates are well-structured:

  • Consistent terminology migration from "유저"/"사용자" to "회원" throughout
  • New sections properly added for user settings retrieval and updates
  • Anchor references align with the new error-code test identifiers
capturecat-core/src/test/java/com/capturecat/core/api/user/UserControllerTest.java (2)

134-155: LGTM!

The test properly validates the GET endpoint for user settings retrieval:

  • Correctly mocks the service response using UserSettings.init(1L)
  • Validates all response fields including userId and screenshotAutoDeleteEnabled
  • Generates proper REST Docs documentation

157-186: LGTM!

The test properly validates the PUT endpoint for updating user settings:

  • Correctly constructs the request DTO with the new setting value
  • Mocks the service to return the updated settings
  • Validates all request and response fields
  • Generates proper REST Docs documentation
capturecat-core/src/test/java/com/capturecat/core/api/error/ErrorCodeControllerTest.java (1)

155-166: LGTM!

The error code documentation tests properly cover the new user settings endpoints:

  • 사용자_설정_정보_조회_에러_코드_문서() includes both USER_NOT_FOUND and USER_SETTINGS_NOT_FOUND
  • 사용자_설정_정보_변경_에러_코드_문서() includes USER_NOT_FOUND
  • Follows the established pattern for error code documentation

Note: Once the HTTP status for USER_SETTINGS_NOT_FOUND is corrected to NOT_FOUND (404) in ErrorType.java as suggested in my earlier comment, these tests will automatically reflect the correct status code in the generated documentation.

capturecat-core/src/test/java/com/capturecat/core/service/user/UserServiceTest.java (5)

60-61: LGTM!

The mock setup for UserSettingsRepository is correct and follows the existing test pattern.


76-76: LGTM!

Mocking findById to return Optional.empty() correctly simulates the case where user settings don't yet exist during the join flow.


117-126: LGTM!

The withdrawal test correctly verifies that user settings are deleted alongside other user-related data.


145-156: LGTM!

The test correctly verifies that getUserSettings returns the expected userId and default screenshotAutoDelete setting (false).


158-170: Test validates domain behavior, not persistence.

The test mocks save() to return the same settings object and then asserts on that object. This validates the domain object's changeAutoDelete method but doesn't verify the full persistence flow. For a unit test, this is acceptable, but consider adding an integration test to verify the end-to-end persistence behavior.

capturecat-core/src/docs/asciidoc/user.adoc (1)

1-129: LGTM!

The documentation updates are consistent and well-structured:

  • Terminology successfully migrated from "사용자"/"유저" to "회원" throughout
  • New sections for user settings (회원-설정-조회, 회원-설정-변경) follow the existing documentation pattern
  • All operations include success/failure blocks and reference appropriate error codes
capturecat-core/src/main/java/com/capturecat/core/api/user/UserController.java (1)

89-97: LGTM!

The GET endpoint for retrieving user settings is correctly implemented:

  • Uses @AuthenticationPrincipal for authentication
  • Delegates to service layer
  • Returns properly mapped DTO
capturecat-core/src/main/java/com/capturecat/core/api/user/dto/UserRespDto.java (1)

51-61: LGTM!

The UserSettingsRespDto is well-designed:

  • Uses @RequiredArgsConstructor(access = PRIVATE) for controlled instantiation
  • Final fields ensure immutability
  • Static factory method of() provides a clean mapping from domain to DTO
  • Simple, clear mapping logic from UserSettings to DTO
capturecat-core/src/main/java/com/capturecat/core/service/user/UserService.java (5)

60-61: LGTM!

User settings are correctly initialized with default values (false) when users are created, both in the regular join flow and the social login flow. Since these calls are within transactional methods, atomicity is guaranteed.

Also applies to: 85-86


136-147: LGTM!

The upsert pattern in setUserSettings is correctly implemented:

  • Uses findById().orElseGet(() -> UserSettings.init(userId)) to handle both new and existing settings
  • Calls save() to ensure persistence for newly created settings
  • The @Transactional annotation ensures atomicity

149-155: LGTM!

The convenience wrapper method correctly validates that the user exists before delegating to the userId-based overload.


168-169: LGTM!

User settings are properly deleted when a user is withdrawn, maintaining referential integrity.


127-134: Confirm migration readiness: both user creation paths initialize UserSettings, but verify no legacy users lack settings.

Both join() and upsertSocialUser() properly initialize UserSettings via setUserSettings(), which uses the defensive orElseGet() pattern. All new users receive settings. However, the concern remains valid if UserSettings was added to an existing system with pre-existing users—those users would fail on getUserSettings() unless setUserSettings() is called first.

Verify: (1) whether UserSettings was added to a live system with existing users, and (2) run a query to confirm no users lack settings records. If legacy users exist without settings, either run a backfill migration or ensure all code paths that read settings use the same orElseGet() defensive pattern.

TOO_MANY_USER_TAGS(HttpStatus.BAD_REQUEST, ErrorCode.EXCEED_MAX_USER_TAG_COUNT, LogLevel.WARN),
USER_TAG_NOT_FOUND(HttpStatus.NOT_FOUND, ErrorCode.NOT_FOUND_USER_TAG, LogLevel.WARN);
USER_TAG_NOT_FOUND(HttpStatus.NOT_FOUND, ErrorCode.NOT_FOUND_USER_TAG, LogLevel.WARN),
USER_SETTINGS_NOT_FOUND(HttpStatus.INTERNAL_SERVER_ERROR, ErrorCode.NOT_FOUND_USER_SETTINGS, LogLevel.ERROR);
Copy link

@coderabbitai coderabbitai bot Oct 16, 2025

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Use HttpStatus.NOT_FOUND for consistency with other "not found" errors.

USER_SETTINGS_NOT_FOUND currently uses HttpStatus.INTERNAL_SERVER_ERROR (500), but all other "not found" errors in the codebase use HttpStatus.NOT_FOUND (404):

  • Line 27: USER_NOT_FOUNDNOT_FOUND
  • Line 33: TAG_NOT_FOUNDNOT_FOUND
  • Line 39: BOOKMARK_NOT_FOUNDNOT_FOUND
  • Line 49: USER_TAG_NOT_FOUNDNOT_FOUND

HTTP 404 is semantically correct for "resource not found" scenarios, while 500 should be reserved for unexpected server errors.

Apply this diff:

-	USER_SETTINGS_NOT_FOUND(HttpStatus.INTERNAL_SERVER_ERROR, ErrorCode.NOT_FOUND_USER_SETTINGS, LogLevel.ERROR);
+	USER_SETTINGS_NOT_FOUND(HttpStatus.NOT_FOUND, ErrorCode.NOT_FOUND_USER_SETTINGS, LogLevel.WARN);
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
USER_SETTINGS_NOT_FOUND(HttpStatus.INTERNAL_SERVER_ERROR, ErrorCode.NOT_FOUND_USER_SETTINGS, LogLevel.ERROR);
USER_SETTINGS_NOT_FOUND(HttpStatus.NOT_FOUND, ErrorCode.NOT_FOUND_USER_SETTINGS, LogLevel.WARN);
🤖 Prompt for AI Agents
In
capturecat-core/src/main/java/com/capturecat/core/support/error/ErrorType.java
around line 50, the USER_SETTINGS_NOT_FOUND entry incorrectly uses
HttpStatus.INTERNAL_SERVER_ERROR; change it to HttpStatus.NOT_FOUND to match
other "not found" error entries (keep the existing
ErrorCode.NOT_FOUND_USER_SETTINGS and LogLevel.ERROR unchanged).

Copy link
Collaborator Author

@jaelyangChoi jaelyangChoi Oct 16, 2025

Choose a reason for hiding this comment

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

@leeedohyun
로컬에서 돌릴 때 flyway 설정 관련해서 오류가 나는데, 뭐 설정 필요한게 있어?
Caused by: org.flywaydb.core.internal.exception.FlywaySqlException: Unable to obtain connection from database:
개발계 배포할 때도 ddl-auto=update로 테이블 생성이 안돼서 실패했네

Copy link

Choose a reason for hiding this comment

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

Seems like the humans are having a chat. I'll hop back into my burrow for now. If you need me again, just tag @coderabbitai in a new comment, and I'll come hopping out!

Copy link
Member

Choose a reason for hiding this comment

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

로컬에서는

  flyway:
    enabled: false

이 설정 추가하면 되고, 테이블 생성은 직접 스크립트 짜야 돼! resources 하위 파일 참고하면 될 듯!

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

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between a535d30 and 20ee912.

📒 Files selected for processing (3)
  • capturecat-core/src/main/java/com/capturecat/core/api/user/UserController.java (4 hunks)
  • capturecat-core/src/main/java/com/capturecat/core/domain/user/UserSettings.java (1 hunks)
  • capturecat-core/src/main/resources/db/migration/V3__create_user_settings.sql (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • capturecat-core/src/main/java/com/capturecat/core/domain/user/UserSettings.java
🧰 Additional context used
🧬 Code graph analysis (1)
capturecat-core/src/main/java/com/capturecat/core/api/user/UserController.java (2)
capturecat-core/src/main/java/com/capturecat/core/api/user/dto/UserReqDto.java (1)
  • UserReqDto (18-70)
capturecat-core/src/main/java/com/capturecat/core/api/user/dto/UserRespDto.java (1)
  • UserRespDto (12-63)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: deploy-dev
🔇 Additional comments (2)
capturecat-core/src/main/java/com/capturecat/core/api/user/UserController.java (2)

89-97: LGTM!

The GET endpoint follows the established controller pattern, properly delegates to the service layer, and uses consistent authentication and response wrapping.


99-109: LGTM! Previous issue resolved.

The @RequestBody annotation is now correctly present on line 104, resolving the critical deserialization issue flagged in the previous review. The endpoint implementation is clean and follows established patterns.

Comment on lines +1 to +8
create table if not exists user_settings
(
user_id BIGINT NOT NULL PRIMARY KEY,
screenshot_auto_delete_enabled BOOLEAN NOT NULL DEFAULT FALSE,
created_date timestamp(6) not null,
last_modified_date timestamp(6) not null,
CONSTRAINT fk_user_settings_user FOREIGN KEY (user_id) REFERENCES users (id)
);
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Add ON DELETE CASCADE to the foreign key constraint.

The PR description states settings should be deleted when a user withdraws. Without ON DELETE CASCADE, if a user row is deleted directly at the database level, the corresponding settings row will become orphaned (causing FK constraint violations).

Apply this diff to ensure settings are automatically deleted when the parent user is removed:

-    CONSTRAINT fk_user_settings_user FOREIGN KEY (user_id) REFERENCES users (id)
+    CONSTRAINT fk_user_settings_user FOREIGN KEY (user_id) REFERENCES users (id) ON DELETE CASCADE
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
create table if not exists user_settings
(
user_id BIGINT NOT NULL PRIMARY KEY,
screenshot_auto_delete_enabled BOOLEAN NOT NULL DEFAULT FALSE,
created_date timestamp(6) not null,
last_modified_date timestamp(6) not null,
CONSTRAINT fk_user_settings_user FOREIGN KEY (user_id) REFERENCES users (id)
);
create table if not exists user_settings
(
user_id BIGINT NOT NULL PRIMARY KEY,
screenshot_auto_delete_enabled BOOLEAN NOT NULL DEFAULT FALSE,
created_date timestamp(6) not null,
last_modified_date timestamp(6) not null,
CONSTRAINT fk_user_settings_user FOREIGN KEY (user_id) REFERENCES users (id) ON DELETE CASCADE
);
🤖 Prompt for AI Agents
In capturecat-core/src/main/resources/db/migration/V3__create_user_settings.sql
around lines 1 to 8, the foreign key constraint on user_id lacks ON DELETE
CASCADE so user_settings won't be removed when a user is deleted; modify the FK
definition to append "ON DELETE CASCADE" after "REFERENCES users (id)" (i.e.,
update the CREATE TABLE FK clause to include ON DELETE CASCADE) so settings are
automatically deleted when the parent user is removed.

# Conflicts:
#	capturecat-core/src/docs/asciidoc/user.adoc
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: 2

🧹 Nitpick comments (2)
capturecat-core/src/test/java/com/capturecat/core/api/error/ErrorCodeControllerTest.java (2)

3-4: Prefer explicit static imports if your style forbids star imports.

Wildcard static imports can hide collisions and reduce grep-ability. Keep if your Checkstyle/Spotless allows it; otherwise switch back to explicit members.


160-171: Unify terminology: '회원' vs '사용자' in test names.

Docs elsewhere use ‘회원’. Consider renaming for consistency.

Apply:

-void 사용자_설정_정보_조회_에러_코드_문서() {
+void 회원_설정_정보_조회_에러_코드_문서() {

-void 사용자_설정_정보_변경_에러_코드_문서() {
+void 회원_설정_정보_변경_에러_코드_문서() {
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 20ee912 and b998f5f.

📒 Files selected for processing (2)
  • capturecat-core/src/docs/asciidoc/error-codes.adoc (2 hunks)
  • capturecat-core/src/test/java/com/capturecat/core/api/error/ErrorCodeControllerTest.java (2 hunks)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: build
  • GitHub Check: deploy-dev
🔇 Additional comments (2)
capturecat-core/src/docs/asciidoc/error-codes.adoc (1)

113-119: Snippet paths verified and aligned with test documentation.

The snippet references in lines 113-119 are confirmed to be generated by corresponding REST documentation tests:

  • {snippets}/errorCode/getUserSettings/error-codes.adoc[] is generated by ErrorCodeControllerTest.java via generateErrorDocs("errorCode/getUserSettings", ...)
  • {snippets}/errorCode/updateUserSettings/error-codes.adoc[] is generated by ErrorCodeControllerTest.java via generateErrorDocs("errorCode/updateUserSettings", ...)

The test infrastructure uses Spring REST Docs (@ExtendWith(RestDocumentationExtension.class), ErrorCodeSnippet, TemplatedSnippet) to generate AsciiDoc snippets during test execution. The pattern is consistent with all 30+ other endpoints documented in the file.

capturecat-core/src/test/java/com/capturecat/core/api/error/ErrorCodeControllerTest.java (1)

160-165: LGTM — GET user settings error-code doc

USER_NOT_FOUND and USER_SETTINGS_NOT_FOUND make sense for retrieval. Identifier path also fits the existing naming pattern.

Comment on lines +81 to +82
[[회원정보조회]]
=== 회원정보조회
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Inconsistent anchor naming convention.

The anchor [[회원정보조회]] on Line 81 lacks hyphens, while all subsequent anchors (회원-태그-, 회원-설정-) use hyphens for word separation. Update to [[회원-정보-조회]] for consistency.

-[[회원정보조회]]
-=== 회원정보조회
+[[회원-정보-조회]]
+=== 회원 정보 조회
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
[[회원정보조회]]
=== 회원정보조회
[[회원-정보-조회]]
=== 회원 정보 조회
🤖 Prompt for AI Agents
In capturecat-core/src/docs/asciidoc/error-codes.adoc around lines 81 to 82, the
anchor [[회원정보조회]] is inconsistent with the repository's hyphenated anchor naming
convention; change it to [[회원-정보-조회]] so it matches the pattern used by
subsequent anchors (회원-태그-*, 회원-설정-*), and update any internal cross-references
in the document to reference the new hyphenated anchor.

Comment on lines +167 to +171
@Test
void 사용자_설정_정보_변경_에러_코드_문서() {
List<ErrorCodeDescriptor> errorCodeDescriptors = generateErrorCodeDescriptors(USER_NOT_FOUND);
generateErrorDocs("errorCode/updateUserSettings", errorCodeDescriptors);
}
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

Confirm UPDATE error cases (legacy users) and document if applicable.

If older accounts might lack settings, UPDATE could return USER_SETTINGS_NOT_FOUND unless the service creates defaults. If create‑if‑missing is guaranteed or a migration backfilled, current docs are fine; otherwise add the missing descriptor.

Run to confirm thrown/used error types around update:


🏁 Script executed:

#!/bin/bash
# Find update endpoint/service and nearby error handling
rg -n --type=java -C3 '(updateUserSettings|class .*UserSettings.*|@PutMapping|@PatchMapping)'

# Check whether USER_SETTINGS_NOT_FOUND appears in update flow
rg -n --type=java -C2 '\bUSER_SETTINGS_NOT_FOUND\b|\bNOT_FOUND_USER_SETTINGS\b'

Length of output: 8621


Add USER_SETTINGS_NOT_FOUND to the updateUserSettings error documentation.

The setUserSettings method in UserService.java:132-133 explicitly throws USER_SETTINGS_NOT_FOUND when user settings are not found. The test method 사용자_설정_정보_변경_에러_코드_문서() currently documents only USER_NOT_FOUND, but should include USER_SETTINGS_NOT_FOUND to match the actual error cases the endpoint can return—consistent with how the corresponding GET endpoint documents both errors at line 162-163.

Update line 169 to:

List<ErrorCodeDescriptor> errorCodeDescriptors = generateErrorCodeDescriptors(USER_NOT_FOUND, USER_SETTINGS_NOT_FOUND);
🤖 Prompt for AI Agents
In
capturecat-core/src/test/java/com/capturecat/core/api/error/ErrorCodeControllerTest.java
around lines 167 to 171, the test that generates error docs for
updateUserSettings only includes USER_NOT_FOUND but the service can also throw
USER_SETTINGS_NOT_FOUND; update the call to generateErrorCodeDescriptors to
include both USER_NOT_FOUND and USER_SETTINGS_NOT_FOUND so the test documents
both error cases (i.e., pass both constants into generateErrorCodeDescriptors).

@jaelyangChoi jaelyangChoi self-assigned this Oct 21, 2025
@jaelyangChoi jaelyangChoi merged commit aad4e48 into develop Oct 21, 2025
6 checks passed
@jaelyangChoi jaelyangChoi deleted the feature/#131-userSettings-deleteScreenShot branch October 21, 2025 14:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

스크린샷 삭제 설정 유저 태그 수정 API

2 participants