Skip to content

계좌 이체를 진행한다. #2

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 32 commits into
base: feature/spear
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
3b205f3
chore : 모델링 진행
this-is-spear Feb 17, 2024
e3d2258
chore : fixture monkey 의존성 추가
this-is-spear Feb 17, 2024
ddb5912
chore : gitignore 파일 수정
this-is-spear Feb 17, 2024
f7382bc
feature : Money 구현
this-is-spear Feb 17, 2024
9e35dcb
chore : 모델링 수정
this-is-spear Feb 17, 2024
15f5217
refactor : Money data 클래스로 변경
this-is-spear Feb 17, 2024
ae54557
feature : AccountNumber 구현
this-is-spear Feb 17, 2024
c1667c1
feature : TransferHistory 구현
this-is-spear Feb 17, 2024
e98e4c2
feature : TransferHistories 구현
this-is-spear Feb 17, 2024
29e39f2
feature : Account 구현
this-is-spear Feb 17, 2024
a6def22
test : 테스트 코드 리팩토링
this-is-spear Feb 17, 2024
073affb
feature : AccountTransaction 구현
this-is-spear Feb 17, 2024
4ba8fc5
refactor : 중복 검증 로직 제거
this-is-spear Feb 17, 2024
4e45527
test : FixtureMonkeyUtil 코드 추가 및 테스트 코드 리팩토링
this-is-spear Feb 17, 2024
8dd5047
feature : Deposit 추가
this-is-spear Feb 17, 2024
0728d6f
feature : Withdrawal 구현
this-is-spear Feb 17, 2024
d28ac46
feature : Transfer 구현
this-is-spear Feb 17, 2024
861b5e6
chore : gitignore 수정
this-is-spear Feb 17, 2024
46c15dd
feature : usecase 작성
this-is-spear Feb 17, 2024
d9837e5
test : fixture monkey build 사용법 수정
this-is-spear Feb 18, 2024
000aecf
chore : mockk 의존성 추가
this-is-spear Feb 18, 2024
c47b355
feature : CreateAccountService 구현
this-is-spear Feb 18, 2024
f8c63e6
feature : DepositService 구현
this-is-spear Feb 18, 2024
1aec614
feature : WithdrawService 구현
this-is-spear Feb 18, 2024
8cfb750
feature : TransferService 구현
this-is-spear Feb 18, 2024
ab85479
test : 테스트 코드 리팩토링
this-is-spear Feb 18, 2024
74f1d21
feature : 영속화 구현
this-is-spear Feb 18, 2024
1664295
refactor : 계좌 현금 변동 후 잔액 반환하도록 수정
this-is-spear Feb 18, 2024
dcc4708
fix : 중복된 컬럼 필드로 인한 테스트 실패 수정
this-is-spear Feb 18, 2024
4d535b3
refactor : 엔티티 블록 제거
this-is-spear Feb 18, 2024
8766e68
feature : AccountController 구현
this-is-spear Feb 18, 2024
99e4024
refactor : 메서드 경량화
this-is-spear Feb 18, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
155 changes: 153 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,154 @@
.DS_Store
.idea
# Created by https://www.toptal.com/developers/gitignore/api/intellij+all,gradle,kotlin
# Edit at https://www.toptal.com/developers/gitignore?templates=intellij+all,gradle,kotlin

### Intellij+all ###
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider
# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839

# User-specific stuff
.idea/**/workspace.xml
.idea/**/tasks.xml
.idea/**/usage.statistics.xml
.idea/**/dictionaries
.idea/**/shelf

# AWS User-specific
.idea/**/aws.xml

# Generated files
.idea/**/contentModel.xml

# Sensitive or high-churn files
.idea/**/dataSources/
.idea/**/dataSources.ids
.idea/**/dataSources.local.xml
.idea/**/sqlDataSources.xml
.idea/**/dynamic.xml
.idea/**/uiDesigner.xml
.idea/**/dbnavigator.xml

# Gradle
.idea/**/gradle.xml
.idea/**/libraries

# Gradle and Maven with auto-import
# When using Gradle or Maven with auto-import, you should exclude module files,
# since they will be recreated, and may cause churn. Uncomment if using
# auto-import.
# .idea/artifacts
# .idea/compiler.xml
# .idea/jarRepositories.xml
# .idea/modules.xml
# .idea/*.iml
# .idea/modules
# *.iml
# *.ipr

# CMake
cmake-build-*/

# Mongo Explorer plugin
.idea/**/mongoSettings.xml

# File-based project format
*.iws

# IntelliJ
out/

# mpeltonen/sbt-idea plugin
.idea_modules/

# JIRA plugin
atlassian-ide-plugin.xml

# Cursive Clojure plugin
.idea/replstate.xml

# SonarLint plugin
.idea/sonarlint/

# Crashlytics plugin (for Android Studio and IntelliJ)
com_crashlytics_export_strings.xml
crashlytics.properties
crashlytics-build.properties
fabric.properties

# Editor-based Rest Client
.idea/httpRequests

# Android studio 3.1+ serialized cache file
.idea/caches/build_file_checksums.ser

### Intellij+all Patch ###
# Ignore everything but code style settings and run configurations
# that are supposed to be shared within teams.

.idea/*

!.idea/codeStyles
!.idea/runConfigurations

### Kotlin ###
# Compiled class file
*.class

# Log file
*.log

# BlueJ files
*.ctxt

# Mobile Tools for Java (J2ME)
.mtj.tmp/

# Package Files #
*.jar
*.war
*.nar
*.ear
*.zip
*.tar.gz
*.rar

# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
hs_err_pid*
replay_pid*

### Gradle ###
.gradle
**/build/
!src/**/build/

# Ignore Gradle GUI config
gradle-app.setting

# Avoid ignoring Gradle wrapper jar file (.jar files are usually ignored)
!gradle-wrapper.jar

# Avoid ignore Gradle wrappper properties
!gradle-wrapper.properties

# Cache of project
.gradletasknamecache

# Eclipse Gradle plugin generated files
# Eclipse Core
.project
# JDT-specific (Eclipse Java Development Tools)
.classpath

### Gradle Patch ###
# Java heap dump
*.hprof

# Fixture Monkey

.jqwik-database

# out package exclusion

!src/main/kotlin/com/example/estdelivery/application/port/out
!src/test/kotlin/com/example/estdelivery/application/port/out

# End of https://www.toptal.com/developers/gitignore/api/intellij+all,gradle,kotlin
180 changes: 175 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,13 +1,183 @@
# 2주차
# 2주차

## 이츠 페이먼츠 ( EST's-Payments )
이스트소프트는 최근 금융사업과 관련하여 송금 서비스를 제공하기로 결정되었다. 각 서비스들은 MSA로 분리되어있다.
<br>

베타서비스를 위해, A2개발팀은 송금과 관련된 요구사항이 부여되었고 개발자들은 해당 요구사항을 토대로 개발을 진행해야한다.
이스트소프트는 최근 금융사업과 관련하여 송금 서비스를 제공하기로 결정되었다. 각 서비스들은 MSA로 분리되어있다.
<br>

베타서비스를 위해, A2개발팀은 송금과 관련된 요구사항이 부여되었고 개발자들은 해당 요구사항을 토대로 개발을 진행해야한다.

## 요구사항

## 요구사항
1. 사용자는 돈이 없으면 송금할 수 없다.
2. 동일한 송금은 두번 요청할 수 없다.
3. 송금 후에는 계좌잔액을 노출해야 한다.
4. 송금 내역은 5개월동안 보장되고 그 이후의 내역은 삭제되어야 한다.

> 송금 이력이 사라지기 때문에 계좌 잔액을 영속화하거나 송금 기록을 제외한 입출금 내역만을 관리해 계좌 잔액을 계산해야 한다.

## 요구사항 정제

- `계좌 번호`를 입력해 `계좌`를 생성한다.
- `계좌 번호`는 10자리로 구성되어있다.
- `계좌 번호`는 중복되어서는 안된다.
- `자신 계좌 번호`와 `상대방 계좌 번호` 그리고 `돈의 수량`을 입력해 송금을 진행 한 후 계좌 잔액을 노출한다.
- `상대방 계좌 번호`가 존재하지 않으면 안된다.
- `자신 계좌 번호`가 존재하지 않으면 안된다.
- `자신 계좌 번호`와 `상대방 계좌 번호`가 동일하면 안된다.
- `돈의 수량`은 0보다 커야한다.
- `자신 계좌`에 잔액이 입력한 `돈의 수량`보다 많아야 한다.
- 동일한 송금은 두번 요청할 수 없다.
- `자신 계좌`에서 `상대방의 계좌`로 돈을 전달한다.
- 송금한 기록을 남긴다. 송금 기록에는 `자신의 계좌 번호`, `상대방 계좌 번호`, `송금한 돈의 수량`, `송금한 일자`가 포함된다.
- 송금 후 `자신 계좌` 잔액을 노출한다.
- `계좌 번호`, `돈의 수량`를 입력해 돈을 입급한다.
- `계좌 번호`가 존재하지 않으면 안된다.
- `돈의 수량`은 0보다 커야한다.
- `계좌 번호`, `돈의 수량`를 입력해 돈을 출금한다.
- `계좌 번호`가 존재하지 않으면 안된다.
- `돈의 수량`은 0보다 커야한다.
- `계좌`에 잔액이 입력한 `돈의 수량`보다 많아야 한다.

## 모델링

| 한글 | 영어 | 설명 |
|-----------|--------------------|-----------------------------------------------------------------|
| 송금 | Transfer | 송금에는 `송금한 계좌`, `송금받은 계좌`, `송금한 돈의 수량`, `송금한 일자`가 포함된다. |
| 송금한 계좌 | sourceAccount | 송금하려는 계좌 정보. |
| 송금받은 계좌 | targetAccount | 송금받는 계좌 정보. |
| 송금한 돈의 수량 | transferMoney | 송금할 돈의 수량. |
| 송금한 일자 | transferDate | 송금한 일자는 송금한 날짜. |
| 계좌 | Account | 계좌에는 `계좌 번호`, `생성 일자 정보`, `잔액 정보`, `송금 이력`을 포함한다. |
| 계좌 번호 | AccountNumber | 10자리로 구성된 고유한 값. |
| 생성 일자 | createDate | 계좌를 생성한 날짜. |
| 잔액 | balance | 계좌에 남은 돈의 수량. |
| 송금 이력 | transferHistories | 송금 이력에는 `송금한 계좌 번호`, `송금받은 계좌 번호`, `송금한 돈의 수량`, `송금한 일자`가 포함된다. |
| 돈 | Money | 주고받는 돈의 기본 단위. 돈의 수량은 0 이상이어야 한다. |
| 입출금 이력 | transactionHistory | 입출금 이력에는 `계좌 번호`, `입출금 타입`, `돈의 수량`, `입출금 일자`가 포함된다. |

### 입금

- `계좌 번호(AccountNumber)`와 `돈의 수량(Money)`을 입력해 돈을 입금한다.
- `계좌 번호(AccountNumber)`가 존재하지 않으면 안된다.
- `돈의 수량(Money)`은 0보다 커야한다.
- `입출금 이력(transactionHisotry)`에 `입금 기록(DEPOSIT)`을 추가한다.

### 출금

- `계좌 번호(AccountNumber)`와 `돈의 수량(Money)`을 입력해 돈을 출금한다.
- `계좌 번호(AccountNumber)`가 존재하지 않으면 안된다.
- `돈의 수량(Money)`은 0보다 커야한다.
- `계좌`에 잔액이 입력한 `돈의 수량(Money)`보다 많아야 한다.
- `입출금 이력(transactionHisotry)`에 `출금 기록(WITHDRAW)`을 추가한다.

### 송금

- `자신 계좌(sourceAccount)`와 `상대방 계좌(targetAccount)`, `송금 일자(transferDate)` 그리고 `돈의 수량(transferMoney)`을 입력해 송금한다.
- `상대방 계좌(targetAccount)`가 존재하지 않으면 안된다.
- `자신 계좌(sourceAccount)`가 존재하지 않으면 안된다.
- `자신 계좌(sourceAccount)`와 `상대방 계좌(targetAccount)`가 동일하면 안된다.
- `돈의 수량(transferMoney)`은 0보다 커야한다.
- `자신 계좌(sourceAccount)`의 `입출금 이력(transactionHisotry)`에는 `출금 기록(WITHDRAW)`을 추가한다.
- `상대방 계좌(targetAccount)`의 `입출금 이력(transactionHisotry)`에는 `입금 기록(DEPOSIT)`을 추가한다.

### 계좌

- 계좌에는 `계좌 번호(AccountNumber)`, `생성 일자 정보(createDate)`, `잔액 정보(balance)`, `송금 이력(transferHistories)`, `입출금 이력(transactionHisotry)`를 포함한다.
- `입출금 이력(transactionHisotry)` 에는 `계좌 번호(AccountNumber)`, `입출금 타입(type)`, `돈의 수량(Money)`, `입출금 일자(transactionDate)`가 포함된다.
- `입출금 이력(transactionHisotry)`으로 `잔액 정보(balance)`를 계산한다.
- `계좌 번호(AccountNumber)`는 10자리로 구성되어있다.
- `잔액 정보(balance)`는 0 이상이어야 한다.
- `송금 이력(transferHistories)` 에는 `송금한 계좌(sourceAccountNumber)`, `송금받은 계좌(targetAccountNumber)`, `송금한 돈의 수량(transferMoney)`, `송금한 일자(transferDate)`가 포함된다.

### 돈(Money)

- `금액 정보(amount)`가 포함된다.

### 클래스 다이어그램

```mermaid
classDiagram
class Withdraw {
- Account targetAccount
- Money withdrawMoney
- Date withdrawDate
}

class Deposit {
- Account targetAccount
- Money depositMoney
- Date depositDate
}

class Transfer {
- Account sourceAccount
- Account targetAccount
- money transferMoney
- Date transferDate
}

class Account {
- AccountNumber number
- Money balance
- List~TransferHistory~ transferHistories
- Date createdDate
}

class AccountNumber {
- String number
}

class TransferHistory {
- AccountNumber sourceAccountNumber
- AccountNumber targetAccountNumber
- Money transferMoney
- TransferDate transferDate
}

class Money {
- int amount
}

Withdraw *-- Account
Withdraw *-- Money
Deposit *-- Account
Deposit *-- Money
Account *-- AccountNumber
Account *-- Money
Account *-- TransferHistory
Transfer *-- Money
Transfer *-- Account
TransferHistory *-- Money
TransferHistory *-- AccountNumber
```

## erd

```mermaid
erDiagram
transfer_history {
id long pk
source_account_number varchar(200)
target_account_number varchar(200)
transfer_money int
trasfer_date date
}

account {
id long pk
account_number varchar(200)
created_date date
}

account_transaction {
id long pk
account_id long fk
type enum "WITHDRAW, DEPOSIT"
money int
transaction_date date
}

account ||--o{ transfer_history: has
account ||--o{ account_transaction: contains
```
4 changes: 4 additions & 0 deletions build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,16 @@ dependencies {
implementation("org.springframework.boot:spring-boot-starter-web")
implementation("com.fasterxml.jackson.module:jackson-module-kotlin")
implementation("org.jetbrains.kotlin:kotlin-reflect")
implementation("org.springframework.boot:spring-boot-starter-validation")
runtimeOnly("com.h2database:h2")

testImplementation("org.springframework.boot:spring-boot-starter-test")
testImplementation("org.junit.jupiter", "junit-jupiter", "5.8.2")
testImplementation("org.assertj", "assertj-core", "3.22.0")
testImplementation("io.kotest", "kotest-runner-junit5", "5.4.0")
testImplementation("com.navercorp.fixturemonkey:fixture-monkey-starter-kotlin:1.0.13")
testImplementation("com.navercorp.fixturemonkey:fixture-monkey-jakarta-validation:1.0.0")
testImplementation("io.mockk:mockk:1.13.9")
}

tasks.withType<KotlinCompile> {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package com.example.estdelivery.application

import com.example.estdelivery.application.port.`in`.CreateAccountUseCase
import com.example.estdelivery.application.port.`in`.command.CreateAccountCommand
import com.example.estdelivery.application.port.out.CreateAccountPort
import com.example.estdelivery.application.port.out.GenerateAccountNumberPort
import com.example.estdelivery.domain.Account
import com.example.estdelivery.domain.AccountTransactions
import com.example.estdelivery.domain.TransferHistories
import org.springframework.stereotype.Service

@Service
class CreateAccountService(
private val createAccountPort: CreateAccountPort,
private val generateAccountNumber: GenerateAccountNumberPort,
) : CreateAccountUseCase {
/**
* 1. 계좌를 생성한다.
* 2. 계좌 정보를 저장한다.
*/
override fun createAccount(command: CreateAccountCommand) {
val accountNumber = generateAccountNumber.generate()
val newAccount =
Account(accountNumber, TransferHistories(), AccountTransactions(), command.createTime)
createAccountPort.create(newAccount)
}
}
Loading