Skip to content

feat: AccontEntity 생성 및 coin 내용을 user에서 분리#271

Merged
yooooonshine merged 3 commits intodevelopfrom
feature/267-implement-account
Nov 23, 2025
Merged

feat: AccontEntity 생성 및 coin 내용을 user에서 분리#271
yooooonshine merged 3 commits intodevelopfrom
feature/267-implement-account

Conversation

@yooooonshine
Copy link
Contributor

@yooooonshine yooooonshine commented Nov 23, 2025

개요

작업사항

  • user에서 coin 분리

  • Account 엔티티, 서비스, 레포지토리 구현

  • 변경사항에 따라 테스트 변경

  • version 정보는 추후 추가 구현 예정

Summary by CodeRabbit

  • 새로운 기능

    • 계좌 기반 코인 조회 API 추가 (/accounts/coins) 및 코인 이전 API 추가 (/accounts/coins/transfer).
  • 개선 사항

    • 코인 관리가 계정(Account) 중심으로 이전되어 잔액 조회·이전 흐름이 더 명확해짐.
    • 기존 사용자 코인 경로가 계정 경로로 통합되어 API 및 내부 흐름이 정리됨.

✏️ Tip: You can customize this high-level summary in your review settings.

- user에서 coin 분리
- Account 엔티티, 서비스, 레포지토리 구현
- 변경사항에 따라 테스트 변경

- version 정보는 추후 추가 구현 예정
@yooooonshine yooooonshine linked an issue Nov 23, 2025 that may be closed by this pull request
@coderabbitai
Copy link

coderabbitai bot commented Nov 23, 2025

Walkthrough

User의 코인 보관을 UserEntity에서 분리하여 새로운 Account 엔티티/리포지토리/서비스로 이전하고, 관련 컨트롤러·오류 코드·잠금명·테스트 및 호출부를 Account 기반으로 변경했습니다. UserEntity의 coin 필드와 기존 전송 API 일부가 제거되었습니다.

변경 사항

응집(Cohort) / 파일(s) 요약
에러 처리
src/main/java/hanium/modic/backend/common/error/ErrorCode.java
기존 USER coin 관련 에러 3개 제거 및 // Account 섹션으로 ACCOUNT_NOT_FOUND_EXCEPTION, COIN_NOT_ENOUGH_EXCEPTION, COIN_TRANSFER_SAME_USER_EXCEPTION, COIN_TRANSFER_FAIL_EXCEPTION 추가
Account 도메인 (신규)
src/main/java/hanium/modic/backend/domain/transaction/entity/Account.java, src/main/java/hanium/modic/backend/domain/transaction/repository/AccountRepository.java
Account JPA 엔티티 추가 (id, userId, coin) 및 AccountRepository 생성
Account 서비스
src/main/java/hanium/modic/backend/domain/transaction/service/AccountService.java
기존 UserCoinService → AccountService로 리네임·이동, Account 기반 잔액 조회/충전/전송 로직으로 변경(예외·락 키 등도 Account 용으로 전환)
User 도메인 업데이트
src/main/java/hanium/modic/backend/domain/user/entity/UserEntity.java, src/main/java/hanium/modic/backend/domain/user/service/UserService.java
UserEntity에서 coin 필드 및 addCoin 제거. UserService에 AccountRepository 주입해 회원가입 시 Account 생성, 탈퇴 시 Account 삭제로 변경(메서드 인자명 변경 포함)
서비스 호출부 변경
src/main/java/hanium/modic/backend/domain/ai/aiChat/service/AiImagePermissionService.java, src/main/java/hanium/modic/backend/domain/profile/service/ProfileService.java
UserCoinService 의존성 → AccountService/AccountRepository 사용으로 교체, Account 조회(또는 예외)로 coin 취득/소비 처리
컨트롤러·DTO 이동/추가
src/main/java/hanium/modic/backend/web/transaction/controller/AccountController.java, .../web/transaction/dto/.../GetCoinBalanceResponse.java, .../web/transaction/dto/request/TransferCoinsRequest.java, src/main/java/hanium/modic/backend/web/user/controller/UserController.java
AccountController 추가(GET /api/accounts/coins, POST /api/accounts/coins/transfer). DTO 패키지(transaction)로 이동. UserController에서 POST /coins/transfer 제거, GET /coins는 AccountService 사용으로 변경
분산락 인프라
src/main/java/hanium/modic/backend/infra/redis/distributedLock/LockManager.java
userLockaccountLock으로 메서드명 변경 및 잠금 키 프리픽스 ACCOUNT_PREFIX로 변경
테스트 업데이트 — 통합/단위
src/test/.../AccountServiceIntegrationTest.java, .../AiImagePermissionControllerIntegrationTest.java, .../ProfileControllerIntegrationTest.java, .../AiImagePermissionServiceTest.java, .../ProfileServiceTest.java, .../UserServiceTest.java, .../UserControllerTest.java
테스트에서 UserEntity.coin 직접 사용을 Account 엔티티로 대체. UserCoinService mock → AccountService mock. AccountRepository mock/autowired 추가 및 테스트 명/패키지 변경

Sequence Diagram(s)

sequenceDiagram
    autonumber
    actor User
    participant UI as Controller
    participant AS as AccountService
    participant AR as AccountRepository
    participant AE_from as Account(from)
    participant AE_to as Account(to)

    rect rgb(220,255,220)
    Note over UI,AS: 코인 전송 흐름 (변경 후)
    User->>UI: POST /api/accounts/coins/transfer (toId, amount)
    UI->>AS: transferCoin(fromId, toId, amount)
    AS->>AR: findById(fromId)  --(lock account)-->
    AR-->>AS: Account(from)
    AS->>AE_from: addCoin(-amount)  --(validate 잔액)-->
    AS->>AR: findById(toId)
    AR-->>AS: Account(to)
    AS->>AE_to: addCoin(+amount)
    AS->>AR: save(Account(from)), save(Account(to))
    AS-->>UI: 성공
    UI-->>User: HTTP 200
    end
Loading

예상 코드 리뷰 노력

🎯 3 (중간 난이도) | ⏱️ ~25분

주의 깊게 검토할 영역:

  • Account.addCoin의 음수 처리 및 던지는 예외 코드(현재 AppException에 어떤 ErrorCode 사용되는지)
  • AccountService의 락 사용 변경(userLock → accountLock)과 잠금 키 호환성
  • UserService.deleteAndLogout 시그니처 변경(id → userId)과 호출부 영향 범위
  • 마이그레이션: 기존 UserEntity.coin 데이터가 별도 마이그레이션 없이 사라지지 않는지 확인(배포 전략)
  • 테스트 변경: 통합테스트에서 Account 생성/초기화가 실제 시나리오와 일치하는지

Possibly related PRs

개요

사용자의 코인 관리 기능을 User 엔티티에서 분리하여 새로운 Account 엔티티로 이전합니다. Account 엔티티, AccountRepository, AccountService를 도입하고, 관련 서비스 레이어와 컨트롤러를 업데이트하며, UserEntity에서 coin 필드를 제거합니다.

변경 사항 (요약 개정)

응집(Cohort) / 파일 요약
에러 처리
src/main/java/hanium/modic/backend/common/error/ErrorCode.java
USER 코인 관련 에러 삭제 및 ACCOUNT_NOT_FOUND_EXCEPTION, COIN_NOT_ENOUGH_EXCEPTION, COIN_TRANSFER_SAME_USER_EXCEPTION, COIN_TRANSFER_FAIL_EXCEPTION 추가 (ACC → ACC 코드 네이밍 반영)
Account 도메인 (신규)
src/main/java/hanium/modic/backend/domain/transaction/entity/Account.java, src/main/java/hanium/modic/backend/domain/transaction/repository/AccountRepository.java, src/main/java/hanium/modic/backend/domain/transaction/service/AccountService.java
Account JPA 엔티티 및 리포지토리 추가, UserCoinService → AccountService로 리팩터링 및 Account 기반 로직 적용
User 도메인 업데이트
src/main/java/hanium/modic/backend/domain/user/entity/UserEntity.java, src/main/java/hanium/modic/backend/domain/user/service/UserService.java
UserEntity에서 coin 필드 제거, UserService에 AccountRepository 의존성 추가하여 회원가입 시 Account 생성 및 탈퇴 시 Account 삭제
서비스 레이어 업데이트
src/main/java/hanium/modic/backend/domain/ai/aiChat/service/AiImagePermissionService.java, src/main/java/hanium/modic/backend/domain/profile/service/ProfileService.java
UserCoinService 의존성 → AccountService/AccountRepository로 변경, Account 조회 후 coin 사용
REST 컨트롤러 및 DTO
src/main/java/hanium/modic/backend/web/transaction/controller/AccountController.java, src/main/java/hanium/modic/backend/web/transaction/dto/response/GetCoinBalanceResponse.java, src/main/java/hanium/modic/backend/web/transaction/dto/request/TransferCoinsRequest.java, src/main/java/hanium/modic/backend/web/user/controller/UserController.java
AccountController 추가, DTO 패키지 이동, UserController에서 전송 엔드포인트 제거 및 GET /coins는 AccountService 사용
인프라 업데이트
src/main/java/hanium/modic/backend/infra/redis/distributedLock/LockManager.java
userLockaccountLock으로 변경 및 잠금 키 프리픽스 변경
테스트 업데이트
src/test/...
통합/단위 테스트에서 Account 사용으로 전환(명/패키지/목 설정 등 수정)

🐰 새 계좌로 코인이 옮겨갔네, 깡총깡총 용돈 이사했지
User는 가볍게, 계정은 묵직히 지갑을 지키네
락은 이름만 바꿨고 테스트도 따라왔네
함께 뛰는 코드, 버그 없이 굴러가렴 🥕✨

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 25.58% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed 제목은 PR의 주요 변경사항(User에서 coin을 분리하고 Account 엔티티 생성)을 명확하게 요약하고 있습니다.
Description check ✅ Passed PR 설명은 저장소의 필수 템플릿 구조를 따르고 있으며, 개요, 작업사항, 관련 이슈 정보를 포함하고 있습니다.
Linked Issues check ✅ Passed PR의 모든 코드 변경사항이 #267 이슈의 요구사항을 충족합니다. User에서 coin 필드 제거, Account 엔티티/서비스/레포지토리 구현, 관련 테스트 업데이트가 모두 포함되어 있습니다.
Out of Scope Changes check ✅ Passed 모든 변경사항이 #267의 목표(User에서 coin 분리 및 Account 엔티티 구현)와 직접적으로 관련이 있으며, 범위를 벗어난 변경사항이 없습니다.
✨ 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/267-implement-account

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.

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: 3

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/main/java/hanium/modic/backend/infra/redis/distributedLock/LockManager.java (1)

39-44: multipleUserLock 메서드의 락 키 접두사 불일치를 수정하세요.

AccountService의 transferCoin 메서드(68줄)에서 계좌 관련 작업(출금/입금)에 multipleUserLock을 사용하고 있으나, 현재 USER_PREFIX를 사용 중입니다. accountLock이 ACCOUNT_PREFIX로 변경된 반면, multipleUserLock은 여전히 USER_PREFIX를 사용하고 있어 불일치가 발생합니다.

  • AccountService.java 68줄: 계좌 전송 작업에서 multipleUserLock 호출 시 ACCOUNT_PREFIX를 사용하도록 수정하거나, multipleAccountLock으로 메서드명을 변경하여 accountLock과 일관성을 맞춰야 합니다.
🧹 Nitpick comments (7)
src/test/java/hanium/modic/backend/web/profile/controller/ProfileControllerIntegrationTest.java (1)

38-38: 테스트 명확성을 위해 coin 값을 명시적으로 설정하는 것을 권장합니다.

Account 생성 시 coin 필드가 명시적으로 설정되지 않아 기본값에 의존하고 있습니다. 테스트의 가독성과 명확성을 위해 coin 값을 명시적으로 설정하는 것이 좋습니다.

다음과 같이 수정할 수 있습니다:

-		accountRepository.save(Account.builder().userId(user.getId()).build());
+		accountRepository.save(Account.builder().userId(user.getId()).coin(0L).build());
src/test/java/hanium/modic/backend/domain/user/service/UserServiceTest.java (1)

61-62: Account 생성 검증을 추가하는 것을 권장합니다.

AccountRepository가 추가되고 mock 설정이 되어 있지만, Line 84에서 accountRepository.save() 호출을 검증하지 않고 있습니다. UserService.createUser가 이제 Account도 생성한다면, 이를 검증하는 것이 좋습니다.

Line 84 이후에 다음 검증을 추가할 수 있습니다:

 		verify(authService, times(1)).checkEmailCodeAndDelete(email, code);
 		verify(passwordEncoder, times(1)).encode(password);
 		verify(userEntityRepository, times(1)).save(any(UserEntity.class));
+		verify(accountRepository, times(1)).save(any(Account.class));
 		assertNotNull(user);

Also applies to: 76-76

src/main/java/hanium/modic/backend/domain/transaction/service/AccountService.java (1)

68-68: 락 메서드 네이밍 일관성 검토 권장

Line 68의 multipleUserLock은 이제 Account 엔티티를 대상으로 잠금을 수행하고 있습니다. 코드베이스 전체에서 일관성을 위해 accountLock(Line 44, 91)과 같이 multipleAccountLock으로 메서드명 변경을 고려해보시기 바랍니다.

src/main/java/hanium/modic/backend/domain/transaction/entity/Account.java (1)

31-32: 데이터베이스 기본값 설정 검토

코인 필드의 기본값이 Java 필드 초기화(= 0L)로만 설정되어 있습니다. 데이터베이스 레벨에서도 일관성을 보장하려면 @Column(columnDefinition = "BIGINT DEFAULT 0") 추가를 고려하시기 바랍니다.

-	@Column(name = "coin", nullable = false)
+	@Column(name = "coin", nullable = false, columnDefinition = "BIGINT DEFAULT 0")
 	private Long coin = 0L;
src/main/java/hanium/modic/backend/web/transaction/controller/AccountController.java (2)

32-40: 메서드 이름을 Account 도메인에 맞게 변경하는 것을 고려하세요.

메서드 이름이 getUserCoins로 되어 있지만, 이 컨트롤러는 Account 도메인을 다루고 있습니다. getAccountCoins 또는 getCoinBalance와 같이 도메인과 일관된 이름을 사용하면 코드의 가독성이 향상됩니다.

-	public ResponseEntity<AppResponse<GetCoinBalanceResponse>> getUserCoins(@CurrentUser UserEntity user) {
+	public ResponseEntity<AppResponse<GetCoinBalanceResponse>> getCoinBalance(@CurrentUser UserEntity user) {
 		GetCoinBalanceResponse response = accountService.getCoinBalance(user.getId());
 		return ResponseEntity.ok(AppResponse.ok(response));
 	}

52-59: 송금 성공 시 빈 응답 본문을 반환합니다.

현재 구현은 송금 성공 시 빈 응답(ResponseEntity.ok().build())을 반환합니다. 이는 기술적으로 정확하지만, 사용자 경험 향상을 위해 송금 확인 정보(송금 ID, 타임스탬프 등)를 포함하는 것을 고려해볼 수 있습니다.

src/main/java/hanium/modic/backend/web/user/controller/UserController.java (1)

181-190: 중복 API의 마이그레이션 계획을 문서화하세요.

기존 API 호환성을 위해 /api/users/coins 엔드포인트를 유지하는 것은 합리적이지만, 다음 사항을 고려하세요:

  1. Swagger 문서에 @Deprecated 어노테이션을 추가하여 클라이언트가 새로운 /api/accounts/coins 엔드포인트로 마이그레이션하도록 유도하세요.
  2. 향후 제거 계획이 있다면 deprecation 정책을 명확히 하세요.

다음과 같이 deprecation을 명시할 수 있습니다:

 	// 기존 API 호환을 위한 중복 API(AccountController에도 동일한 API 존재)
 	@GetMapping("/coins")
+	@Deprecated
 	@Operation(
 		summary = "유저 코인 조회 API",
-		description = "로그인한 유저의 코인 잔액을 조회합니다."
+		description = "로그인한 유저의 코인 잔액을 조회합니다. (Deprecated: /api/accounts/coins 사용을 권장합니다)"
 	)
 	public ResponseEntity<AppResponse<GetCoinBalanceResponse>> getUserCoins(@CurrentUser UserEntity user) {
 		GetCoinBalanceResponse response = accountService.getCoinBalance(user.getId());
 		return ResponseEntity.ok(AppResponse.ok(response));
 	}
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 5ab5be8 and e0445be.

📒 Files selected for processing (20)
  • src/main/java/hanium/modic/backend/common/error/ErrorCode.java (1 hunks)
  • src/main/java/hanium/modic/backend/domain/ai/aiChat/service/AiImagePermissionService.java (2 hunks)
  • src/main/java/hanium/modic/backend/domain/profile/service/ProfileService.java (5 hunks)
  • src/main/java/hanium/modic/backend/domain/transaction/entity/Account.java (1 hunks)
  • src/main/java/hanium/modic/backend/domain/transaction/repository/AccountRepository.java (1 hunks)
  • src/main/java/hanium/modic/backend/domain/transaction/service/AccountService.java (5 hunks)
  • src/main/java/hanium/modic/backend/domain/user/entity/UserEntity.java (0 hunks)
  • src/main/java/hanium/modic/backend/domain/user/service/UserService.java (4 hunks)
  • src/main/java/hanium/modic/backend/infra/redis/distributedLock/LockManager.java (1 hunks)
  • src/main/java/hanium/modic/backend/web/transaction/controller/AccountController.java (1 hunks)
  • src/main/java/hanium/modic/backend/web/transaction/dto/response/GetCoinBalanceResponse.java (1 hunks)
  • src/main/java/hanium/modic/backend/web/user/controller/UserController.java (3 hunks)
  • src/main/java/hanium/modic/backend/web/user/dto/request/TransferCoinsRequest.java (0 hunks)
  • src/test/java/hanium/modic/backend/domain/ai/service/AiImagePermissionServiceTest.java (9 hunks)
  • src/test/java/hanium/modic/backend/domain/profile/ProfileServiceTest.java (3 hunks)
  • src/test/java/hanium/modic/backend/domain/transaction/AccountServiceIntegrationTest.java (5 hunks)
  • src/test/java/hanium/modic/backend/domain/user/service/UserServiceTest.java (3 hunks)
  • src/test/java/hanium/modic/backend/web/ai/controller/AiImagePermissionControllerIntegrationTest.java (10 hunks)
  • src/test/java/hanium/modic/backend/web/profile/controller/ProfileControllerIntegrationTest.java (2 hunks)
  • src/test/java/hanium/modic/backend/web/user/controller/UserControllerTest.java (2 hunks)
💤 Files with no reviewable changes (2)
  • src/main/java/hanium/modic/backend/domain/user/entity/UserEntity.java
  • src/main/java/hanium/modic/backend/web/user/dto/request/TransferCoinsRequest.java
🧰 Additional context used
🧬 Code graph analysis (7)
src/test/java/hanium/modic/backend/web/profile/controller/ProfileControllerIntegrationTest.java (1)
src/test/java/hanium/modic/backend/base/login/ContextHolderUtil.java (1)
  • ContextHolderUtil (10-25)
src/main/java/hanium/modic/backend/web/transaction/controller/AccountController.java (1)
src/main/java/hanium/modic/backend/web/user/controller/UserController.java (1)
  • RestController (48-204)
src/test/java/hanium/modic/backend/domain/transaction/AccountServiceIntegrationTest.java (1)
src/test/java/hanium/modic/backend/domain/user/factory/UserFactory.java (1)
  • UserFactory (9-29)
src/main/java/hanium/modic/backend/domain/ai/aiChat/service/AiImagePermissionService.java (1)
src/main/java/hanium/modic/backend/domain/transaction/service/AccountService.java (1)
  • Service (22-107)
src/main/java/hanium/modic/backend/domain/transaction/service/AccountService.java (3)
src/main/java/hanium/modic/backend/domain/ai/aiChat/service/AiImagePermissionService.java (1)
  • Service (25-139)
src/main/java/hanium/modic/backend/domain/profile/service/ProfileService.java (1)
  • Service (24-94)
src/main/java/hanium/modic/backend/domain/user/service/UserService.java (1)
  • Service (30-225)
src/main/java/hanium/modic/backend/domain/transaction/entity/Account.java (1)
src/main/java/hanium/modic/backend/domain/user/entity/UserEntity.java (1)
  • Table (21-95)
src/test/java/hanium/modic/backend/domain/ai/service/AiImagePermissionServiceTest.java (2)
src/test/java/hanium/modic/backend/domain/post/entityfactory/PostFactory.java (1)
  • PostFactory (11-97)
src/test/java/hanium/modic/backend/domain/user/factory/UserFactory.java (1)
  • UserFactory (9-29)
🪛 GitHub Actions: compile-test
src/main/java/hanium/modic/backend/web/transaction/controller/AccountController.java

[error] 17-17: package hanium.modic.backend.web.transaction.dto.request does not exist.


[error] 54-54: cannot find symbol: class TransferCoinsRequest

🔇 Additional comments (16)
src/test/java/hanium/modic/backend/web/profile/controller/ProfileControllerIntegrationTest.java (1)

16-17: Account 통합이 적절합니다.

프로필 조회 테스트에 Account 저장소가 올바르게 추가되었습니다.

Also applies to: 30-31

src/main/java/hanium/modic/backend/web/transaction/dto/response/GetCoinBalanceResponse.java (1)

1-1: 패키지 이동이 적절합니다.

GetCoinBalanceResponse DTO가 user 패키지에서 transaction 패키지로 이동되어 코인 관리가 트랜잭션 도메인으로 이관된 것과 일치합니다.

src/main/java/hanium/modic/backend/infra/redis/distributedLock/LockManager.java (1)

33-37: accountLock 메서드 이름 변경이 적절합니다.

userLock에서 accountLock으로 메서드명이 변경되고 ACCOUNT_PREFIX를 사용하여 Account 엔티티 기반의 락 관리로 전환된 것이 적절합니다.

src/test/java/hanium/modic/backend/web/user/controller/UserControllerTest.java (1)

32-32: AccountService로의 전환이 적절합니다.

UserCoinService에서 AccountService로 의존성이 올바르게 변경되어 코인 관리 책임이 트랜잭션 도메인으로 이관되었습니다.

Also applies to: 48-48

src/main/java/hanium/modic/backend/domain/transaction/repository/AccountRepository.java (1)

1-8: LGTM!

Account 엔티티를 위한 표준 JPA Repository가 적절하게 구현되었습니다.

src/main/java/hanium/modic/backend/domain/ai/aiChat/service/AiImagePermissionService.java (1)

18-18: AccountService로의 전환이 적절합니다.

UserCoinService에서 AccountService로 의존성이 올바르게 변경되었으며, consumeCoin 메서드 호출이 적절하게 마이그레이션되었습니다.

Also applies to: 29-29, 51-51

src/main/java/hanium/modic/backend/domain/profile/service/ProfileService.java (1)

50-52: 잘 구현되었습니다

Account 엔티티로부터 코인 잔액을 조회하는 로직이 올바르게 구현되었으며, 적절한 예외 처리가 포함되어 있습니다.

src/main/java/hanium/modic/backend/domain/transaction/entity/Account.java (1)

43-48: 코인 검증 로직 잘 구현되었습니다

addCoin 메서드의 음수 잔액 검증이 올바르게 구현되어 있으며, 적절한 예외 처리가 포함되어 있습니다. 오버플로우와 언더플로우를 모두 방지합니다.

src/main/java/hanium/modic/backend/domain/user/service/UserService.java (2)

99-100: Account 삭제 로직 올바르게 구현되었습니다

회원 탈퇴 시 Account 삭제가 적절하게 처리되고 있으며, 주석으로 향후 동작을 명확히 설명하고 있습니다.


71-75: 트랜잭션 관리 검증 완료 - 코드 정상

검증 결과, createUser 메서드는 50번 줄에 @Transactional 어노테이션이 정확히 적용되어 있습니다.

  • User 저장(72줄) → Account 저장(77줄) 순서로 동일 트랜잭션 내에서 처리
  • Account 저장 실패 시 Spring Data JPA는 전체 트랜잭션을 자동으로 롤백하므로 User 생성도 취소됨
  • 트랜잭션 경계가 올바르게 설정되어 있음

코드 변경사항이 적절히 구현되었습니다.

src/test/java/hanium/modic/backend/domain/profile/ProfileServiceTest.java (1)

65-69: 테스트 목킹이 올바르게 업데이트되었습니다

Account 엔티티를 사용하도록 테스트가 적절하게 수정되었으며, 기본 코인 값(0L)이 정확히 반영되어 있습니다.

src/test/java/hanium/modic/backend/domain/transaction/AccountServiceIntegrationTest.java (1)

36-46: 통합 테스트가 올바르게 마이그레이션되었습니다

Account 엔티티를 사용하도록 테스트 픽스처와 설정이 적절하게 업데이트되었습니다. 동시성 테스트 시나리오가 잘 유지되고 있습니다.

src/test/java/hanium/modic/backend/domain/ai/service/AiImagePermissionServiceTest.java (1)

40-40: 테스트가 AccountService로 올바르게 업데이트되었습니다

의존성이 AccountService로 적절하게 변경되었으며, 모든 검증 구문이 새로운 서비스 메서드를 올바르게 참조하고 있습니다.

Also applies to: 79-79

src/test/java/hanium/modic/backend/web/ai/controller/AiImagePermissionControllerIntegrationTest.java (2)

65-71: 헬퍼 메서드가 깔끔하게 구현되었습니다

createAccountForUser 메서드가 재사용 가능하고 명확하게 구현되어 있습니다. Account 생성 및 초기 코인 설정이 적절합니다.


102-104: Account 기반 검증으로 올바르게 마이그레이션되었습니다

코인 잔액 검증이 Account 엔티티를 사용하도록 정확하게 업데이트되었습니다. 모든 테스트 시나리오가 새로운 모델과 일관되게 동작합니다.

src/main/java/hanium/modic/backend/web/user/controller/UserController.java (1)

26-26: AccountService로의 마이그레이션이 올바르게 적용되었습니다.

UserCoinService에서 AccountService로의 전환과 DTO 패키지 경로 변경이 정확하게 이루어졌습니다. 코인 관리 책임이 Account 도메인으로 적절히 분리되었습니다.

Also applies to: 35-35, 54-54

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: 0

🧹 Nitpick comments (1)
src/main/java/hanium/modic/backend/web/transaction/dto/request/TransferCoinsRequest.java (1)

1-9: 패키지 이동으로 트랜잭션/계정 도메인과 잘 정렬되었습니다.

TransferCoinsRequesthanium.modic.backend.web.transaction.dto.request로 이동한 결정은, 코인 관련 기능을 유저 도메인에서 트랜잭션/Account 도메인으로 분리하려는 PR 목적과 잘 맞습니다. 필드 및 Bean Validation 구성도 현재 요구사항(수신자 ID와 1 이상 코인 금액 검증)에 적절해 보입니다.

한 가지 선택적 의견으로, 코인이 이제 Account 기준으로 관리된다면, 장기적으로는 toUserId 필드명과 "받는 유저 ID" 메시지를 toAccountId / "받는 계좌 ID" 등 Account 중심 용어로 바꿀지 설계 차원에서 한 번 더 논의해 보셔도 좋겠습니다. 다만 이는 퍼블릭 API 변경이므로, 현재 단계에서 유지하고 후속 리팩터링 이슈로 분리하는 것도 충분히 합리적인 선택입니다.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between e0445be and 5097562.

📒 Files selected for processing (1)
  • src/main/java/hanium/modic/backend/web/transaction/dto/request/TransferCoinsRequest.java (1 hunks)

@yooooonshine yooooonshine merged commit 2be5e76 into develop Nov 23, 2025
1 of 2 checks passed
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 (3)
src/main/java/hanium/modic/backend/web/transaction/controller/AccountController.java (2)

47-52: 에러 코드 네이밍이 Account 도메인과 일치하도록 수정되었습니다.

이전 리뷰에서 지적된 USER_COIN_* 접두사 문제가 해결되었습니다. 모든 에러 코드가 이제 COIN_*ACCOUNT_* 접두사를 사용하여 새로운 Account 도메인 구조와 일관성을 유지하고 있습니다.


17-17: TransferCoinsRequest 클래스 존재 여부를 확인해주세요.

이전 리뷰에서 지적된 컴파일 에러 문제입니다. TransferCoinsRequest 클래스가 hanium.modic.backend.web.transaction.dto.request 패키지에 존재하는지 확인이 필요합니다.

다음 스크립트로 해당 클래스의 존재 여부를 확인하세요:

#!/bin/bash
# Description: TransferCoinsRequest 클래스 존재 여부 확인

# 파일 검색
fd -t f "TransferCoinsRequest.java"

# 클래스 선언 검색
rg -n "class TransferCoinsRequest" --type java

Also applies to: 55-55

src/main/java/hanium/modic/backend/common/error/ErrorCode.java (1)

112-116: 에러 코드 중복 문제가 해결되었습니다.

이전 리뷰에서 지적된 에러 코드 중복 문제가 해결되었습니다. ACCOUNT_NOT_FOUND_EXCEPTION이 이제 "ACC-001"을 사용하여 AI_CHAT_ROOM_NOT_FOUND"AC-001"과 충돌하지 않습니다.

🧹 Nitpick comments (1)
src/main/java/hanium/modic/backend/domain/transaction/service/AccountService.java (1)

68-68: 락 메서드 네이밍의 일관성을 고려해보세요.

multipleUserLock 메서드명이 다른 락 메서드들(accountLock)과 일관성이 부족합니다. Account 도메인으로의 전환을 고려할 때, multipleAccountLock으로 이름을 변경하는 것을 검토해보세요.

다만, 이는 LockManager 인터페이스의 메서드명이므로 해당 인터페이스와 모든 사용처에서 함께 변경되어야 합니다.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 5097562 and 602f658.

📒 Files selected for processing (6)
  • src/main/java/hanium/modic/backend/common/error/ErrorCode.java (1 hunks)
  • src/main/java/hanium/modic/backend/domain/transaction/entity/Account.java (1 hunks)
  • src/main/java/hanium/modic/backend/domain/transaction/service/AccountService.java (4 hunks)
  • src/main/java/hanium/modic/backend/web/transaction/controller/AccountController.java (1 hunks)
  • src/test/java/hanium/modic/backend/domain/ai/service/AiImagePermissionServiceTest.java (9 hunks)
  • src/test/java/hanium/modic/backend/web/ai/controller/AiImagePermissionControllerIntegrationTest.java (11 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • src/main/java/hanium/modic/backend/domain/transaction/entity/Account.java
  • src/test/java/hanium/modic/backend/web/ai/controller/AiImagePermissionControllerIntegrationTest.java
🧰 Additional context used
🧬 Code graph analysis (3)
src/test/java/hanium/modic/backend/domain/ai/service/AiImagePermissionServiceTest.java (2)
src/test/java/hanium/modic/backend/domain/post/entityfactory/PostFactory.java (1)
  • PostFactory (11-97)
src/test/java/hanium/modic/backend/domain/user/factory/UserFactory.java (1)
  • UserFactory (9-29)
src/main/java/hanium/modic/backend/domain/transaction/service/AccountService.java (3)
src/main/java/hanium/modic/backend/domain/ai/aiChat/service/AiImagePermissionService.java (1)
  • Service (25-139)
src/main/java/hanium/modic/backend/domain/profile/service/ProfileService.java (1)
  • Service (24-94)
src/main/java/hanium/modic/backend/domain/user/service/UserService.java (1)
  • Service (30-225)
src/main/java/hanium/modic/backend/web/transaction/controller/AccountController.java (1)
src/main/java/hanium/modic/backend/web/user/controller/UserController.java (1)
  • RestController (48-204)
⏰ 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: build
🔇 Additional comments (2)
src/test/java/hanium/modic/backend/domain/ai/service/AiImagePermissionServiceTest.java (1)

22-123: 테스트 코드가 Account 도메인 분리를 올바르게 반영하고 있습니다.

UserCoinService에서 AccountService로의 마이그레이션이 일관되게 적용되었으며, 에러 코드도 USER_COIN_NOT_ENOUGH_EXCEPTION에서 COIN_NOT_ENOUGH_EXCEPTION으로 적절히 변경되었습니다. 모든 검증 호출과 예외 처리가 새로운 Account 도메인 구조와 일치합니다.

src/main/java/hanium/modic/backend/domain/transaction/service/AccountService.java (1)

14-105: Account 도메인 분리가 잘 구현되었습니다.

코인 관련 로직이 UserEntity에서 Account 엔티티로 성공적으로 분리되었습니다:

  • AccountRepository를 통한 계좌 관리
  • 에러 코드가 ACCOUNT_*/COIN_* 접두사로 일관되게 업데이트
  • 락 메커니즘이 accountLock으로 적절히 변경
  • 알림 및 사용자 검증을 위해 UserEntityRepository를 유지하는 것은 적절한 설계입니다

Comment on lines +113 to +115
ACCOUNT_NOT_FOUND_EXCEPTION(HttpStatus.NOT_FOUND, "ACC-001", "해당 계좌을 찾을 수 없습니다."),
COIN_NOT_ENOUGH_EXCEPTION(HttpStatus.BAD_REQUEST, "ACC-002", "코인이 부족합니다."),
COIN_TRANSFER_SAME_USER_EXCEPTION(HttpStatus.BAD_REQUEST, "ACC-003", "자신에게 코인을 송금할 수 업습니다."),
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

에러 메시지의 오타를 수정해주세요.

에러 메시지에 다음과 같은 오타가 있습니다:

  • Line 113: "계좌을" → "계좌를" (올바른 조사 사용)
  • Line 115: "수 업습니다" → "수 없습니다" (오타 수정)

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

-	ACCOUNT_NOT_FOUND_EXCEPTION(HttpStatus.NOT_FOUND, "ACC-001", "해당 계좌을 찾을 수 없습니다."),
+	ACCOUNT_NOT_FOUND_EXCEPTION(HttpStatus.NOT_FOUND, "ACC-001", "해당 계좌를 찾을 수 없습니다."),
 	COIN_NOT_ENOUGH_EXCEPTION(HttpStatus.BAD_REQUEST, "ACC-002", "코인이 부족합니다."),
-	COIN_TRANSFER_SAME_USER_EXCEPTION(HttpStatus.BAD_REQUEST, "ACC-003", "자신에게 코인을 송금할 수 업습니다."),
+	COIN_TRANSFER_SAME_USER_EXCEPTION(HttpStatus.BAD_REQUEST, "ACC-003", "자신에게 코인을 송금할 수 없습니다."),
🤖 Prompt for AI Agents
In src/main/java/hanium/modic/backend/common/error/ErrorCode.java around lines
113 to 115, there are typos in the Korean error messages: change "해당 계좌을 찾을 수
없습니다." to "해당 계좌를 찾을 수 없습니다." on line 113, and change "자신에게 코인을 송금할 수 업습니다." to
"자신에게 코인을 송금할 수 없습니다." on line 115; update the string literals accordingly and
keep rest of the enum entry formatting unchanged.

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.

FEAT: 기존 USER에서 coin을 Account로 분리

1 participant