Skip to content

Conversation

@birdieHyun
Copy link
Member

@birdieHyun birdieHyun commented Jun 1, 2025

🟢 구현내용

🧩 고민과 해결과정

Summary by CodeRabbit

  • New Features

    • User information now includes creation, update, and deletion timestamps for enhanced tracking.
    • Soft deletion is supported, allowing user records to be marked as deleted without permanent removal.
    • User creation date is now displayed in user info responses.
  • Bug Fixes

    • Improved reliability by ensuring user lists do not contain null entries.

@birdieHyun birdieHyun requested a review from Copilot June 1, 2025 06:12
@birdieHyun birdieHyun self-assigned this Jun 1, 2025
@coderabbitai
Copy link

coderabbitai bot commented Jun 1, 2025

Walkthrough

The changes introduce JPA auditing for automatic timestamp management in the application. A new BaseTimeEntity abstract class is added to provide auditing fields (createdAt, updatedAt, deletedAt) and soft deletion support. The User entity now inherits from this base class. Related DTOs and database schema are updated to include and expose these new timestamp fields. Additionally, user decryption logic is refactored to mutate instances in place, and some test code and service logic are adjusted accordingly.

Changes

File(s) Change Summary
src/main/kotlin/upbrella/be/BeApplication.kt Enabled JPA auditing by adding @EnableJpaAuditing annotation.
src/main/kotlin/upbrella/be/util/BaseTimeEntity.kt Introduced BaseTimeEntity abstract class for auditing fields and soft deletion support.
src/main/kotlin/upbrella/be/user/entity/User.kt Made User inherit from BaseTimeEntity; refactored decryptData to mutate instance in place.
src/main/kotlin/upbrella/be/user/dto/response/SingleUserInfoResponse.kt Added createdAt property; updated factory method to map it from User.
src/main/kotlin/upbrella/be/user/dto/response/AllUsersInfoResponse.kt Changed fromUsers to accept non-nullable List<User> and removed non-null assertions.
src/main/kotlin/upbrella/be/user/service/UserService.kt Updated user decryption logic to mutate in place; refactored user retrieval and decryption flow; hashed socialId.
src/main/resources/db/add_time.sql Added created_at, updated_at, and deleted_at columns to user table for auditing and soft deletion.
src/test/kotlin/upbrella/be/user/controller/UserControllerTest.kt Adjusted tests to reflect in-place decryption and added createdAt field to user info responses.
src/test/kotlin/upbrella/be/user/entity/UserTest.kt Updated test to check mutated User instance after decryption instead of a returned instance.
src/test/kotlin/upbrella/be/user/service/UserServiceTest.kt Removed entire nested test class FindUsersTest and its test methods.

Sequence Diagram(s)

sequenceDiagram
    participant Client
    participant UserService
    participant UserRepository
    participant User (Entity)
    participant BaseTimeEntity

    Client->>UserService: findUsers()
    UserService->>UserRepository: findAll()
    UserRepository-->>UserService: List<User>
    loop For each User
        UserService->>User: decryptData(aesEncryptor)
        User->>BaseTimeEntity: Access auditing fields (createdAt, updatedAt, deletedAt)
    end
    UserService-->>Client: AllUsersInfoResponse (with auditing fields)
Loading

Poem

In the warren of code, new timestamps appear,
Created and updated, now crystal clear.
Soft deletes hop in, with a gentle touch,
Auditing magic—thank you so much!
🕰️🐇
Now every bunny knows just when
A user hopped out, or in again!

✨ Finishing Touches
  • 📝 Generate Docstrings

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
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • 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 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 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 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 for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link
Contributor

@Gwonwoo-Nam Gwonwoo-Nam left a comment

Choose a reason for hiding this comment

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

LGTM

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull Request Overview

Adds timestamp tracking for users and integrates JPA auditing.

  • Introduce created_at, updated_at, deleted_at columns in the users table
  • Create BaseTimeEntity superclass with auditing fields and soft-delete support
  • Wire auditing into entities, services, and DTOs to expose time fields in responses

Reviewed Changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
src/main/resources/db/add_time.sql Add created_at, updated_at, deleted_at columns
src/main/kotlin/upbrella/be/util/BaseTimeEntity.kt New mapped superclass for audit timestamps and soft-delete
src/main/kotlin/upbrella/be/user/service/UserService.kt Adjust login lookup, decrypt user data in place
src/main/kotlin/upbrella/be/user/entity/User.kt Extend BaseTimeEntity, revise decryptData logic
src/main/kotlin/upbrella/be/user/dto/response/SingleUserInfoResponse.kt Include timestamp fields in single-user response
src/main/kotlin/upbrella/be/user/dto/response/AllUsersInfoResponse.kt Update list mapping signature to non-null users
src/main/kotlin/upbrella/be/BeApplication.kt Enable JPA auditing
Comments suppressed due to low confidence (2)

src/main/kotlin/upbrella/be/util/BaseTimeEntity.kt:23

  • There’s no test coverage for the softDelete method or the auditing fields. Consider adding unit tests to verify that deletedAt is set and that createdAt/updatedAt behave as expected.
fun softDelete() {

src/main/kotlin/upbrella/be/user/service/UserService.kt:34

  • Using socialId.hashCode().toLong() alters the original identifier and will cause lookups to fail. Please pass socialId directly to findBySocialId.
val foundUser = userReader.findBySocialId(socialId.hashCode().toLong())

accountNumber = aesEncryptor.decrypt(accountNumber),
id = id
)
fun decryptData(aesEncryptor: AesEncryptor) {
Copy link

Copilot AI Jun 1, 2025

Choose a reason for hiding this comment

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

[nitpick] decryptData now mutates the existing User rather than returning a new instance. Consider renaming it to indicate in-place mutation (e.g., decryptDataInPlace) or documenting its side effects.

Suggested change
fun decryptData(aesEncryptor: AesEncryptor) {
fun decryptDataInPlace(aesEncryptor: AesEncryptor) {

Copilot uses AI. Check for mistakes.
Comment on lines 19 to 20
var updatedAt: LocalDateTime? =null

Copy link

Copilot AI Jun 1, 2025

Choose a reason for hiding this comment

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

The updatedAt and deletedAt fields lack @Column annotations. Adding @Column (with appropriate properties) will make the schema mapping explicit and improve readability.

Suggested change
var updatedAt: LocalDateTime? =null
@Column(nullable = false)
var updatedAt: LocalDateTime? = null
@Column

Copilot uses AI. Check for mistakes.
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)
src/main/resources/db/add_time.sql (1)

1-4: Database schema correctly implements auditing columns.

The SQL implementation properly adds the necessary columns for JPA auditing:

  • created_at with appropriate default value
  • updated_at with automatic update trigger
  • deleted_at for soft deletion support

Consider using TIMESTAMP instead of DATETIME for better timezone handling:

-    ADD COLUMN created_at DATETIME NOT NULL DEFAULT NOW() COMMENT '생성일',
-    ADD COLUMN updated_at DATETIME NOT NULL DEFAULT NOW() ON UPDATE NOW() COMMENT '수정일',
-    ADD COLUMN deleted_at DATETIME NULL COMMENT '삭제일';
+    ADD COLUMN created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '생성일',
+    ADD COLUMN updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '수정일',
+    ADD COLUMN deleted_at TIMESTAMP NULL COMMENT '삭제일';
src/main/kotlin/upbrella/be/util/BaseTimeEntity.kt (1)

11-26: Excellent JPA auditing implementation with minor formatting fix needed.

The BaseTimeEntity class is well-designed with proper JPA auditing annotations and soft deletion support. The implementation follows best practices for auditing timestamps.

Fix the spacing issue on line 19:

-    var updatedAt: LocalDateTime? =null
+    var updatedAt: LocalDateTime? = null
📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 8cef33f and c06787d.

📒 Files selected for processing (7)
  • src/main/kotlin/upbrella/be/BeApplication.kt (1 hunks)
  • src/main/kotlin/upbrella/be/user/dto/response/AllUsersInfoResponse.kt (1 hunks)
  • src/main/kotlin/upbrella/be/user/dto/response/SingleUserInfoResponse.kt (3 hunks)
  • src/main/kotlin/upbrella/be/user/entity/User.kt (3 hunks)
  • src/main/kotlin/upbrella/be/user/service/UserService.kt (3 hunks)
  • src/main/kotlin/upbrella/be/util/BaseTimeEntity.kt (1 hunks)
  • src/main/resources/db/add_time.sql (1 hunks)
🔇 Additional comments (6)
src/main/kotlin/upbrella/be/BeApplication.kt (1)

5-7: LGTM! JPA auditing correctly enabled.

The addition of @EnableJpaAuditing and corresponding import properly enables JPA auditing features for automatic timestamp management.

src/main/kotlin/upbrella/be/user/dto/response/AllUsersInfoResponse.kt (1)

7-9: Excellent improvement in type safety!

Changing from List<User?> to List<User> and removing the non-null assertion operator (!!) significantly improves type safety and makes the code more robust.

src/main/kotlin/upbrella/be/user/service/UserService.kt (2)

59-59: LGTM - In-place decryption aligns with updated User entity.

The forEach approach with in-place decryption is efficient and aligns well with the updated User entity's decryptData method that now mutates the entity directly.


103-109: LGTM - Simplified user retrieval with in-place decryption.

The refactored approach is cleaner and more efficient, leveraging the updated decryptData method that mutates the entity in-place rather than creating new instances.

src/main/kotlin/upbrella/be/user/dto/response/SingleUserInfoResponse.kt (1)

14-16: Well-structured timestamp fields for auditing support.

The addition of auditing timestamp fields properly supports the new BaseTimeEntity functionality. The nullable deletedAt field correctly represents optional soft deletion timestamps.

src/main/kotlin/upbrella/be/util/BaseTimeEntity.kt (1)

23-25: Well-implemented soft deletion method.

The softDelete() method provides a clean API for marking entities as deleted without physical removal from the database, which is a good practice for data retention and audit trails.

import upbrella.be.user.dto.request.JoinRequest
import upbrella.be.user.dto.response.KakaoLoginResponse
import upbrella.be.util.AesEncryptor
import upbrella.be.util.BaseTimeEntity
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

Verify BaseTimeEntity implementation and ensure auditing fields are properly configured.

The inheritance from BaseTimeEntity is a good approach for adding auditing capabilities. However, I need to verify the implementation details.

Also applies to: 24-24


🏁 Script executed:

#!/bin/bash
# Description: Verify BaseTimeEntity implementation and its JPA auditing configuration

# Find and examine BaseTimeEntity class
fd -e kt BaseTimeEntity --exec cat {} \;

# Search for any other entities extending BaseTimeEntity to ensure consistency
ast-grep --pattern 'class $_ : BaseTimeEntity'

Length of output: 819


Audit fields verified – BaseTimeEntity is properly implemented

The BaseTimeEntity superclass is correctly defined with @MappedSuperclass, @EntityListeners(AuditingEntityListener::class), and JPA auditing annotations (@CreatedDate, @LastModifiedDate). No further changes needed for auditing.

Breaking change: decryptData now mutates the instance

The switch from returning a new User to in-place mutation is a breaking API change. Please:

  • src/main/kotlin/upbrella/be/user/entity/User.kt: Review all call sites of decryptData to ensure callers expect the method to modify the current instance.
  • Update any tests or documentation that assume decryptData returns a fresh User rather than mutating it.
🤖 Prompt for AI Agents
In src/main/kotlin/upbrella/be/user/entity/User.kt at lines 6 and 24, the
BaseTimeEntity inheritance is correctly implemented with proper auditing
annotations, so no changes are needed there. However, the decryptData method now
mutates the current User instance instead of returning a new one, which is a
breaking change. Review all usages of decryptData throughout the codebase to
confirm they expect in-place mutation, and update any tests or documentation
that assume it returns a new User object accordingly.

Comment on lines +68 to 71
fun decryptData(aesEncryptor: AesEncryptor) {
this.bank = aesEncryptor.decrypt(bank)
this.accountNumber = aesEncryptor.decrypt(accountNumber)
}
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

Breaking change: decryptData method now mutates instance in-place.

The decryptData method has been changed from returning a new User instance to mutating the current instance in-place. This is a breaking change that affects the method's API contract.

Verify that all usages of decryptData in the codebase have been updated to handle the new in-place mutation behavior:


🏁 Script executed:

#!/bin/bash
# Description: Find all usages of decryptData to ensure they handle in-place mutation

# Search for all calls to decryptData method
rg -A 5 -B 2 'decryptData'

# Look for any assignments that might expect a return value
rg -A 3 -B 1 '\.decryptData\s*\('

Length of output: 8585


Ensure tests accommodate decryptData’s in-place mutation

The decryptData method now returns Unit and mutates the User instance directly. Existing tests still treat it as a factory (expecting a returned User), causing compile/runtime errors. Update the following:

  • src/test/kotlin/upbrella/be/user/service/UserServiceTest.kt
    Replace

    .map { user -> user.decryptData(aesEncryptor) }
    .map { decrypted -> SingleUserInfoResponse.fromUser(decrypted) }

    With either:

    // Option A: apply mutation, then map
    .onEach { it.decryptData(aesEncryptor) }
    .map { SingleUserInfoResponse.fromUser(it) }

    Or:

    .map { user -> user.apply { decryptData(aesEncryptor) } }
          .map { SingleUserInfoResponse.fromUser(it) }
  • src/test/kotlin/upbrella/be/user/controller/UserControllerTest.kt
    Update its .map { user -> user.decryptData(aesEncryptor) } in the same way as above so that you’re mapping User objects, not Unit.

  • src/test/kotlin/upbrella/be/user/entity/UserTest.kt
    Change

    val decryptedUser = user.decryptData(aesEncryptor)

    To:

    user.decryptData(aesEncryptor)
    val decryptedUser = user

After these adjustments, tests will correctly reflect the new in-place behavior of decryptData.

🤖 Prompt for AI Agents
In src/main/kotlin/upbrella/be/user/entity/User.kt around lines 68 to 71, the
decryptData method was changed to mutate the User instance in-place and return
Unit instead of a new User. To fix related issues, update all usages of
decryptData to no longer expect a returned User. In test files like
UserServiceTest.kt and UserControllerTest.kt, replace map calls that invoke
decryptData with onEach or map using apply to perform mutation and then map the
User objects. In UserTest.kt, call decryptData on the user instance without
assignment, then use the original user variable as the decrypted user. This
ensures all code and tests handle the new in-place mutation correctly.


fun login(socialId: Long): SessionUser {
val foundUser = userReader.findBySocialId(socialId)
val foundUser = userReader.findBySocialId(socialId.hashCode().toLong())
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

Verify consistent hashing implementation across the codebase.

The socialId is being hashed before querying. Ensure this hashing approach is consistent with how socialId is stored and used throughout the application, particularly in the join method and other query operations.


🏁 Script executed:

#!/bin/bash
# Description: Verify consistent usage of socialId hashing across the codebase
# Expected: All socialId operations should use consistent hashing

# Search for socialId usage patterns
rg -A 3 -B 3 "socialId.*hashCode|findBySocialId|existsBySocialId" --type kotlin

Length of output: 12146


Align socialId hashing consistently across the codebase

The login method is hashing its incoming socialId again (socialId.hashCode().toLong()), which leads to a different value than the one stored by join/User.ofEncryptJoin (which only hashes the original provider ID once). This double-hashing will break your tests and any lookups.

• In src/main/kotlin/upbrella/be/user/service/UserService.kt (line 34), change:

val foundUser = userReader.findBySocialId(socialId.hashCode().toLong())

to:

val foundUser = userReader.findBySocialId(socialId)

• In your tests (src/test/kotlin/upbrella/be/user/service/UserServiceTest.kt), make sure you’re stubbing and verifying findBySocialId with the same single-hashed value (or pass the raw Kakao ID into login and stub with rawId.hashCode().toLong()).

• Confirm that FixtureBuilderFactory (src/main/kotlin/upbrella/be/config/FixtureBuilderFactory.kt) generates socialId exactly as your production code expects (i.e., one .hashCode().toLong()).

This will ensure all findBySocialId/existsBySocialId calls use the same hashed key.

🤖 Prompt for AI Agents
In src/main/kotlin/upbrella/be/user/service/UserService.kt at line 34, the
socialId is being hashed again before querying, causing inconsistency with how
socialId is stored and used elsewhere. To fix this, remove the extra hashing and
pass the socialId directly to userReader.findBySocialId. Also, update related
tests and FixtureBuilderFactory to ensure they use the same single-hashed or raw
socialId consistently across the codebase.

Comment on lines 28 to 30
createdAt = user.createdAt!!,
updatedAt = user.updatedAt!!,
deletedAt = user.deletedAt
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

Potential null pointer risk with non-null assertions.

The non-null assertions (!!) on createdAt and updatedAt could cause runtime exceptions if JPA auditing fails to populate these fields. Consider using safe calls or ensuring these fields are properly initialized.


🏁 Script executed:

#!/bin/bash
# Description: Verify BaseTimeEntity fields are properly initialized by JPA auditing
# Expected: Confirm that @CreatedDate and @LastModifiedDate annotations ensure non-null values

# Check for any existing null checks or initialization in User entity
rg -A 5 -B 5 "createdAt|updatedAt" src/main/kotlin/upbrella/be/user/entity/User.kt

# Look for JPA auditing configuration
rg -A 3 -B 3 "@EnableJpaAuditing|AuditingEntityListener" --type kotlin

Length of output: 1855


🏁 Script executed:

#!/bin/bash
# Display the BaseTimeEntity class to inspect field definitions
sed -n '1,200p' src/main/kotlin/upbrella/be/util/BaseTimeEntity.kt

Length of output: 792


Handle potential null values for createdAt and updatedAt
The BaseTimeEntity declares both createdAt and updatedAt as LocalDateTime? and relies on JPA auditing to populate them. While @EnableJpaAuditing with @CreatedDate/@LastModifiedDate generally sets these on persist, they can still be null (e.g., before first save, in tests, or if auditing isn’t triggered). Using !! here will lead to an NPE.

• File: src/main/kotlin/upbrella/be/user/dto/response/SingleUserInfoResponse.kt
Replace these lines:

- createdAt = user.createdAt!!,
- updatedAt = user.updatedAt!!,

With a null-safe mapping, for example:

createdAt = user.createdAt 
    ?: throw IllegalStateException("createdAt must not be null"),
updatedAt = user.updatedAt 
    ?: user.createdAt 
    ?: throw IllegalStateException("updatedAt must not be null")

• Alternatively, enforce non-nullability at the entity level by changing the fields in BaseTimeEntity to non-null (lateinit var createdAt: LocalDateTime and lateinit var updatedAt: LocalDateTime with @Column(nullable = false)), so that JPA auditing populates them and the compiler guarantees their presence.

🤖 Prompt for AI Agents
In src/main/kotlin/upbrella/be/user/dto/response/SingleUserInfoResponse.kt
around lines 28 to 30, the use of non-null assertions (!!) on user.createdAt and
user.updatedAt risks runtime exceptions if these fields are null. Replace the !!
with safe calls and provide fallback logic that throws an IllegalStateException
with a clear message if createdAt or updatedAt are null, for example, assign
createdAt as user.createdAt ?: throw IllegalStateException("createdAt must not
be null") and updatedAt as user.updatedAt ?: user.createdAt ?: throw
IllegalStateException("updatedAt must not be null"). This ensures null safety
without risking NPEs.

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 c06787d and 376d307.

📒 Files selected for processing (6)
  • src/main/kotlin/upbrella/be/user/dto/response/SingleUserInfoResponse.kt (3 hunks)
  • src/main/kotlin/upbrella/be/util/BaseTimeEntity.kt (1 hunks)
  • src/main/resources/db/add_time.sql (1 hunks)
  • src/test/kotlin/upbrella/be/user/controller/UserControllerTest.kt (3 hunks)
  • src/test/kotlin/upbrella/be/user/entity/UserTest.kt (1 hunks)
  • src/test/kotlin/upbrella/be/user/service/UserServiceTest.kt (0 hunks)
💤 Files with no reviewable changes (1)
  • src/test/kotlin/upbrella/be/user/service/UserServiceTest.kt
🚧 Files skipped from review as they are similar to previous changes (3)
  • src/main/kotlin/upbrella/be/user/dto/response/SingleUserInfoResponse.kt
  • src/main/kotlin/upbrella/be/util/BaseTimeEntity.kt
  • src/main/resources/db/add_time.sql
⏰ Context from checks skipped due to timeout of 90000ms (1)
  • GitHub Check: test
🔇 Additional comments (5)
src/test/kotlin/upbrella/be/user/entity/UserTest.kt (2)

113-113: LGTM: Correct adaptation to in-place mutation.

The test correctly reflects the change in decryptData method behavior from returning a new User instance to mutating the existing instance in place.


117-118: LGTM: Test assertions properly updated.

The assertions correctly validate the decrypted fields directly on the original user object, which aligns with the new in-place mutation behavior of decryptData.

src/test/kotlin/upbrella/be/user/controller/UserControllerTest.kt (3)

81-81: LGTM: Correct adaptation to in-place mutation.

The test correctly calls decryptData without capturing a return value, reflecting the new in-place mutation behavior.


84-84: LGTM: Mock setup properly updated.

The mock now returns the original user object instead of a separately assigned decrypted user, which is consistent with the in-place mutation approach.


464-466: LGTM: Test setup correctly handles auditing fields.

The test properly sets the createdAt field and applies in-place decryption to each user before constructing the response. This aligns with the new auditing functionality.

Comment on lines +505 to +507
.description("관리자 여부"),
fieldWithPath("users[].createdAt").type(JsonFieldType.ARRAY)
.description("사용자 생성일")
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

Verify the field type in API documentation.

The createdAt field is documented as JsonFieldType.ARRAY, but based on the context of timestamp auditing, this should likely be JsonFieldType.STRING or a date/time type.


🏁 Script executed:

#!/bin/bash
# Description: Check how createdAt is defined in the User entity and DTOs to verify correct field type
# Expected: createdAt should be a timestamp/datetime field, not an array

# Check User entity definition
echo "=== User entity definition ==="
rg -A 5 -B 5 "createdAt" --type kotlin

# Check DTO definitions 
echo "=== DTO definitions ==="
ast-grep --pattern 'class $_ {
  $$$
  createdAt: $TYPE
  $$$
}'

# Check if there are any LocalDateTime imports or usages
echo "=== LocalDateTime usage ==="
rg "LocalDateTime" --type kotlin -A 2 -B 2

Length of output: 70329


Change users[].createdAt to use JsonFieldType.STRING

The createdAt field is a LocalDateTime and will be serialized as a JSON string, not an array.

• File: src/test/kotlin/upbrella/be/user/controller/UserControllerTest.kt
• Around line 506, update the field descriptor:

- fieldWithPath("users[].createdAt").type(JsonFieldType.ARRAY)
+ fieldWithPath("users[].createdAt").type(JsonFieldType.STRING)
📝 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
.description("관리자 여부"),
fieldWithPath("users[].createdAt").type(JsonFieldType.ARRAY)
.description("사용자 생성일")
.description("관리자 여부"),
fieldWithPath("users[].createdAt").type(JsonFieldType.STRING)
.description("사용자 생성일")
🤖 Prompt for AI Agents
In src/test/kotlin/upbrella/be/user/controller/UserControllerTest.kt around
lines 505 to 507, the field descriptor for "users[].createdAt" is incorrectly
set as JsonFieldType.ARRAY. Since createdAt is a LocalDateTime and serialized as
a JSON string, change the field type from JsonFieldType.ARRAY to
JsonFieldType.STRING to accurately reflect the data type in the API
documentation.

@birdieHyun birdieHyun merged commit 86a6fb7 into dev Jun 1, 2025
2 checks passed
@coderabbitai coderabbitai bot mentioned this pull request Nov 29, 2025
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.

3 participants