Skip to content

[FEAT] : 장부 및 거래 내역 조회 기능 구현#275

Merged
yooooonshine merged 5 commits intodevelopfrom
feature/270-implement-view-ledger
Nov 23, 2025
Merged

[FEAT] : 장부 및 거래 내역 조회 기능 구현#275
yooooonshine merged 5 commits intodevelopfrom
feature/270-implement-view-ledger

Conversation

@yooooonshine
Copy link
Contributor

@yooooonshine yooooonshine commented Nov 23, 2025

개요

작업사항

장부 목록 조회 기능

Account의 잔고와 거래 장부 목록 조회에서 일관성 문제가 발생할 수 있다.

WHERE account_id = 'account_a'
AND effective_at <= 'timestamp_a'
AND (discarded_at IS NULL OR discarded_at >= 'timestamp_a')

이를 해결하기 위해 Account의 version 정보 및 시간 정보를 활용하여 account 잔액 버전에 맞는 거래내역만 조회되게 하였다.

History 목록 조회

거래장부와 별개로 유저들의 쉽게 볼 히스토리가 필요했다.
일관성을 조금 포기하고 편하게 조회할 수 있는 목록 조회 기능을 추가하였다.

우려 사항

다만, History는 일관성을 고려하지 않아 Account 잔액과 틀릴 경우가 발생한다.
추후 사용해보면서 문제가 되면 수정해야겠다.

Summary by CodeRabbit

  • 새로운 기능

    • 거래 내역 조회 API 추가 — 코인 잔액과 함께 거래/이체 내역을 페이지네이션으로 확인 가능.
    • 이체 내역 자동 저장 — 코인 전송 시 상세 기록(유형, 금액, 방향, 타임스탬프)이 생성되어 조회 가능.
    • 별도 이력 조회 엔드포인트 추가 — 개인별 거래 이력을 최신순으로 페이지별 제공.
    • AI 이미지 코인 구매 시 전송 이력 로그가 추가됨.
  • 테스트

    • 관련 서비스 단위 테스트에 이력 저장 모킹이 추가됨.

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

@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

Caution

Review failed

The pull request is closed.

Walkthrough

거래 이력 기능과 조회 API가 도입되었고, History 엔티티/레포지토리/서비스 및 거래 스냅샷 조회가 추가되었습니다. 코인 전송 흐름에 History 저장 호출이 AiImagePermissionService에 삽입되었고 관련 컨트롤러·DTO·테스트가 함께 추가되었습니다.

Changes

Cohort / File(s) Change Summary
Domain Entity & Enum
src/main/java/hanium/modic/backend/domain/transaction/entity/History.java, src/main/java/hanium/modic/backend/domain/transaction/enums/HistoryType.java
새로운 History JPA 엔티티 추가(사용자, 타입, 본문, 방향, 금액, 생성시각 등) 및 HistoryType 열거형(POST_PURCHASE, COIN_TRANSFER) 추가
History Repository
src/main/java/hanium/modic/backend/domain/transaction/repository/HistoryRepository.java
History 엔티티용 JpaRepository 추가 및 findAllByUserIdOrderByCreateAtDesc(Long, Pageable) 페이징 조회 메서드 추가
Coin Transaction Repository
src/main/java/hanium/modic/backend/domain/transaction/repository/CoinTransactionEntityRepository.java
계정·시점·버전 기반 페이징 스냅샷 조회 메서드 findSnapshot(accountId, timestampA, version, pageable) 추가
Service Layer
src/main/java/hanium/modic/backend/domain/transaction/service/HistoryService.java, src/main/java/hanium/modic/backend/domain/transaction/service/AccountService.java
HistoryService 추가(saveTransferHistories, getHistories); AccountService에 CoinTransactionEntityRepository·HistoryService 주입, getTransactions(userId, page, size) API 추가 및 코인 전송 후 이력 저장 호출 통합
AI Purchase Integration & Tests
src/main/java/hanium/modic/backend/domain/ai/aiChat/service/AiImagePermissionService.java, src/test/java/hanium/modic/backend/domain/ai/service/AiImagePermissionServiceTest.java
HistoryService 의존성 주입 및 buyAiImagePermissionByCoin 경로에서 POST_PURCHASE 유형 이력 저장 호출 추가; 테스트에 HistoryService 목/스텁 추가
Controllers / Endpoints
src/main/java/hanium/modic/backend/web/history/controller/HistoryController.java, src/main/java/hanium/modic/backend/web/transaction/controller/AccountController.java
HistoryController 추가(GET /api/history); AccountController에 거래 조회 엔드포인트 GET /api/accounts/transactions 추가(페이지/사이즈 파라미터 및 검증)
Response DTOs
src/main/java/hanium/modic/backend/web/history/dto/response/GetHistoriesResponse.java, src/main/java/hanium/modic/backend/web/history/dto/response/GetHistoryEntityResponse.java, src/main/java/hanium/modic/backend/web/transaction/dto/response/GetTransactionsResponse.java, src/main/java/hanium/modic/backend/web/transaction/dto/response/GetTransactionEntityResponse.java
거래/이력 조회용 응답 레코드 4종 추가 및 엔티티→DTO 매핑 정적 팩토리(from) 구현

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant AiSvc as AiImagePermissionService
    participant AccountSvc as AccountService
    participant HistorySvc as HistoryService
    participant Repo as DB

    rect rgb(245,250,255)
    Note over User,AiSvc: AI 이미지 코인 구매 흐름 (변경된 흐름: 코인 전송 → 이력 저장 → 알림)
    User->>AiSvc: buyAiImagePermissionByCoin(request)
    AiSvc->>AccountSvc: transferCoin(from, to, amount)
    AccountSvc->>Repo: ledger debit/credit
    AccountSvc-->>AiSvc: transferResult
    AiSvc->>HistorySvc: saveTransferHistories(userId, amount, POST_PURCHASE, fromBody, toBody)
    HistorySvc->>Repo: insert History (DEBIT / CREDIT)
    HistorySvc-->>AiSvc: saved
    AiSvc->>User: notification + 200 OK
    end
Loading
sequenceDiagram
    participant User
    participant HistoryCtrl as HistoryController
    participant HistorySvc as HistoryService
    participant Repo as DB

    rect rgb(245,255,245)
    Note over User,Repo: 거래/이력 조회 흐름
    User->>HistoryCtrl: GET /api/history?page=&size=
    HistoryCtrl->>HistorySvc: getHistories(userId, page, size)
    HistorySvc->>Repo: select account by userId
    HistorySvc->>Repo: select histories by userId ORDER BY createAt DESC (page)
    HistorySvc-->>HistoryCtrl: GetHistoriesResponse(coin, pageResponse)
    HistoryCtrl-->>User: 200 OK + payload
    end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

  • 추가 검토 권장 항목:
    • HistoryService.saveTransferHistories의 트랜잭션 범위와 예외 처리(동일성·원자성 보장)
    • CoinTransactionEntityRepository.findSnapshot의 JPQL/조건(타임스탬프·discardedAt·version) 정확성 및 인덱스 활용 여부
    • AiImagePermissionService에서 history 저장 호출 위치(알림·전송 순서)와 테스트 목 설정 일관성

Possibly related PRs

  • #272 — 트랜잭션 모델(코인 트랜잭션 엔티티·버전 등) 도입 PR: snapshot 쿼리와 도메인 모델 변경과 직접 연관됨.
  • #273 — AiImagePermissionService의 코인 구매 흐름 변경 PR: 동일 서비스의 코인 전송/흐름을 수정한 PR로 본 PR의 이력 로깅과 연관.
  • #271 — AiImagePermissionService 관련 의존성/흐름 수정 PR: 같은 서비스에 대한 변경들이 겹치므로 코드 레벨 연관성이 높음.

Poem

🐰 장부에 발자국 하나 남기네
코인 소곤소곤, 숫자도 깜짝이네
보낸 이와 받은 이, 기록이 춤추네
잔액과 함께 이야기가 흐르네 ✨
토끼는 기쁘게 당근을 쪼개네 🥕

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 40.00% 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 제목은 장부 및 거래 내역 조회 기능 구현이라는 주요 변경사항을 명확하게 반영하고 있으며, 전체 changeset의 핵심을 잘 요약하고 있습니다.
Description check ✅ Passed 설명은 템플릿의 필수 섹션(개요, 작업사항)을 포함하고 있으며, 구현된 기능들과 우려사항을 상세히 기술하고 있습니다.
Linked Issues check ✅ Passed PR의 코드 변경사항들이 #270의 거래 장부 조회기능 구현 목표를 충족합니다. Account 버전을 활용한 일관성 보장 로직과 History 조회 기능이 모두 구현되었습니다.
Out of Scope Changes check ✅ Passed 모든 변경사항이 거래 장부 조회 및 History 조회 기능 구현과 관련된 범위 내의 변경입니다. 범위를 벗어난 변경사항은 없습니다.

📜 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 38d1b5a and 287122e.

📒 Files selected for processing (1)
  • src/main/java/hanium/modic/backend/domain/ai/aiChat/service/AiImagePermissionService.java (4 hunks)

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

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 98827df and f6afd40.

📒 Files selected for processing (13)
  • src/main/java/hanium/modic/backend/domain/ai/aiChat/service/AiImagePermissionService.java (4 hunks)
  • src/main/java/hanium/modic/backend/domain/transaction/entity/History.java (1 hunks)
  • src/main/java/hanium/modic/backend/domain/transaction/enums/HistoryType.java (1 hunks)
  • src/main/java/hanium/modic/backend/domain/transaction/repository/CoinTransactionEntityRepository.java (1 hunks)
  • src/main/java/hanium/modic/backend/domain/transaction/repository/HistoryRepository.java (1 hunks)
  • src/main/java/hanium/modic/backend/domain/transaction/service/AccountService.java (4 hunks)
  • src/main/java/hanium/modic/backend/domain/transaction/service/HistoryService.java (1 hunks)
  • src/main/java/hanium/modic/backend/web/history/controller/HistoryController.java (1 hunks)
  • src/main/java/hanium/modic/backend/web/history/dto/response/GetHistoriesResponse.java (1 hunks)
  • src/main/java/hanium/modic/backend/web/history/dto/response/GetHistoryEntityResponse.java (1 hunks)
  • src/main/java/hanium/modic/backend/web/transaction/controller/AccountController.java (2 hunks)
  • src/main/java/hanium/modic/backend/web/transaction/dto/response/GetTransactionEntityResponse.java (1 hunks)
  • src/main/java/hanium/modic/backend/web/transaction/dto/response/GetTransactionsResponse.java (1 hunks)
🧰 Additional context used
🧬 Code graph analysis (2)
src/main/java/hanium/modic/backend/web/history/controller/HistoryController.java (1)
src/main/java/hanium/modic/backend/web/transaction/controller/AccountController.java (1)
  • Tag (28-89)
src/main/java/hanium/modic/backend/domain/transaction/service/AccountService.java (2)
src/main/java/hanium/modic/backend/domain/transaction/service/HistoryService.java (1)
  • Service (26-84)
src/main/java/hanium/modic/backend/domain/transaction/service/LedgerService.java (1)
  • Service (23-80)
⏰ 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 (10)
src/main/java/hanium/modic/backend/domain/transaction/repository/CoinTransactionEntityRepository.java (1)

15-27: 일관성 있는 거래 내역 조회 쿼리 구현이 우수합니다.

계좌 버전(accountVersion)과 타임스탬프(effectiveAt, discardedAt)를 활용한 스냅샷 기반 쿼리가 PR 목표에서 명시한 일관성 요구사항을 정확히 구현하고 있습니다. 페이지네이션 지원도 적절합니다.

src/main/java/hanium/modic/backend/domain/transaction/enums/HistoryType.java (1)

1-6: LGTM!

간단하고 명확한 enum 정의입니다.

src/main/java/hanium/modic/backend/web/history/dto/response/GetHistoriesResponse.java (1)

5-9: LGTM!

DTO 구조가 명확하고 적절합니다.

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

5-9: LGTM!

DTO 구조가 명확하고 적절합니다.

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

9-13: LGTM!

Spring Data JPA 메서드 명명 규칙을 올바르게 따르고 있으며, 최신순 정렬과 페이지네이션이 적절히 구현되었습니다.

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

60-83: 구현이 적절합니다.

거래 내역 조회 로직이 올바르게 구현되어 있습니다. 계좌 조회, 페이지네이션 처리, 응답 생성이 모두 적절합니다.

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

9-23: 구현이 깔끔합니다.

DTO 레코드가 적절하게 정의되어 있으며, from 팩토리 메서드를 통한 엔티티 매핑도 올바릅니다.

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

41-43: direction 필드가 올바르게 구현되었습니다.

TransactionDirection enum을 직접 사용하고 updatable=false 설정으로 변경을 방지한 것이 적절합니다.

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

95-123: 시간 기반 일관성 조회가 적절히 구현되었습니다.

PR 목표에 명시된 대로 Account의 version과 시간 정보를 활용하여 일관성 있는 거래 내역 조회를 구현했습니다. LocalDateTime.now()account.getLedgerVersion()을 함께 사용하여 해당 시점의 스냅샷을 조회하는 방식이 적절합니다.

단, now 시점과 ledgerVersion 읽기 시점 간에 미세한 차이가 있을 수 있으나, 이는 읽기 전용 조회이고 사용자에게 일관된 뷰를 제공하기 위한 것이므로 허용 가능합니다.

src/main/java/hanium/modic/backend/web/transaction/controller/AccountController.java (1)

67-88: 엔드포인트가 잘 구현되었습니다.

새로운 거래 내역 조회 엔드포인트가 적절하게 구현되었습니다:

  • 페이지네이션 검증이 적절함
  • API 문서에 일관성 보장에 대한 명확한 설명 제공
  • 오류 매핑 설정 적절

페이지 크기 최소값이 10으로 설정된 것은 다소 높지만, HistoryController에서도 동일한 규칙을 사용하므로 의도적인 설계로 보입니다.

@yooooonshine yooooonshine merged commit 6bb2165 into develop Nov 23, 2025
1 of 2 checks passed
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: 거래 장부 조회기능 구현

1 participant