Skip to content

Commit

Permalink
refactor: 멀티 모듈 분리 (#322)
Browse files Browse the repository at this point in the history
* refactor: 입찰 완료 시 거래내역 ID를 반환하기 (#310)

* fix: 경매 식별자를 사용하는 컨트롤러 UUID로 수정

- Response 시에는 PurchaseResponse를 반환합니다

* fix: 기존 거래 내역 식별자 타입을 Long -> UUID 변경

* test: 거래 내역 식별자를 UUID로 타입 변경 시 깨지는 테스트 수정

* docs: index.html 업데이트

* fix: PR 리뷰 사항 반영

- 테스트 등에 UUID 명시 작업 진행

---------

Co-authored-by: HyeonSik Choi <[email protected]>

* refactor: 경매 생성 시 설정 가능한 경매 시간 및 적용할 수 있는 할인 주기를 다양하게 설정할 수 있게 검증을 변경합니다. (#312)

* test: 경매 입찰에 대한 동시성 테스트 추가

- 한정된 재고에서 구매할 수 있는 최대 수량까지만 구매 가능하고, 나머지는 구매하지 못하는 테스트 추가
- 포인트가 부족한 사람과 포인트가 넉넉한 사람이 구매할때, 순서가 섞여있다면, 포인트가 넉넉한 사람의 구매처리가 원자적으로 동작하는지 테스트 추가

* refactor: 기존 1, 5, 10분 경매 시간에서 경매 검증 방식에서 경매시간을 할인 주기로 나누었을때 나누어 떨어질때만 생성할 수 있게 검증을 변경한다.

- 분, 초 상관없이 나누어 떨어지기만 하면 됨

* refactor: 경매 주기 시간에 대한 기준을 분 단위이고, 1시간을 넘지 않도록 검증하게 변경한다.

- 기존에는 10분단위로 최대 60분이었음
- 변경한 부분은 분 단위면 가능하고, 1시간만 넘지 않도록 변경함
- 이에 경매 주기 시간을 더해 할인 주기 시간으로 나누었을때 나누어떨어지는 시간이어야 함

* chore: 테스트 스크립트 실패 확인을 위한 --info 옵션을 추가합니다

* feat: 임베디드 레디스 시작, 종료 시 로깅 추가

* feat: 테스트 마다 레디스 초기화 하도록 변경

* fix(test): 시간 정밀도 차이를 마이크로초까지 제한한 공통 LocalDateTime 필드를 사용하도록 테스트를 수정합니다.

* feat: Entity에서 Enum값 `@Enumerated` 매핑 추가

* fix: 거래내역 ID 변경으로 인한 컴파일 에러 수정

- #310이 반영되면서 컴파일이 깨지는 오류를 수정합니다.

---------

Co-authored-by: 유동근 <[email protected]>
Co-authored-by: yudonggeun <[email protected]>

* feat: core 모듈 추가

* refactor: 도메인, dto 이전

- core module : 도메인과 dto만으로 이루어진 모듈
- test module : 테스트에 필요한 유틸성 클래스를 포함한 모듈

* refactor: 도메인, dto 이전

- core module : 도메인과 dto만으로 이루어진 모듈
- test module : 테스트에 필요한 유틸성 클래스를 포함한 모듈

* refactor: api, redis consumer 모듈 생, 공통 모듈 생성

* refactor: 패키지 구조 개선

* refactor: core 패키지 분리

* refactor: consumer 패키지 분리

* refactor: api 패키지 분리

---------

Co-authored-by: MinSeok Oh <[email protected]>
Co-authored-by: HyeonSik Choi <[email protected]>
Co-authored-by: 이호석 <[email protected]>
  • Loading branch information
4 people authored Aug 27, 2024
1 parent 4375315 commit 6198c4b
Show file tree
Hide file tree
Showing 218 changed files with 2,963 additions and 5,062 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/test_run.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,5 +27,5 @@ jobs:
cache: gradle

- name: Run tests
run: ./gradlew clean test
run: ./gradlew clean test --info

37 changes: 37 additions & 0 deletions api/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
HELP.md
.gradle
build/
!gradle/wrapper/gradle-wrapper.jar
!**/src/main/**/build/
!**/src/test/**/build/

### STS ###
.apt_generated
.classpath
.factorypath
.project
.settings
.springBeans
.sts4-cache
bin/
!**/src/main/**/bin/
!**/src/test/**/bin/

### IntelliJ IDEA ###
.idea
*.iws
*.iml
*.ipr
out/
!**/src/main/**/out/
!**/src/test/**/out/

### NetBeans ###
/nbproject/private/
/nbbuild/
/dist/
/nbdist/
/.nb-gradle/

### VS Code ###
.vscode/
81 changes: 81 additions & 0 deletions api/build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
plugins {
id 'org.asciidoctor.jvm.convert' version '3.3.2'
}

configurations {
compileOnly {
extendsFrom annotationProcessor
}
asciidoctorExt
}

ext {
set('snippetsDir', file("build/generated-snippets"))
}

java {
toolchain {
languageVersion = JavaLanguageVersion.of(17)
}
}

dependencies {
implementation project(":core")
implementation 'org.springframework.boot:spring-boot-starter'
implementation 'org.springframework.boot:spring-boot-starter-web'

// prometheus
implementation 'io.micrometer:micrometer-registry-prometheus'
implementation 'org.springframework.boot:spring-boot-starter-actuator'

// redis
implementation 'org.springframework.boot:spring-boot-starter-data-redis'
implementation 'org.redisson:redisson-spring-boot-starter:3.34.1'

testImplementation project(':test')
testImplementation 'org.springframework.boot:spring-boot-starter-test'
testRuntimeOnly 'org.junit.platform:junit-platform-launcher'

// spring-rest-docs
asciidoctorExt 'org.springframework.restdocs:spring-restdocs-asciidoctor:3.0.1'
testImplementation 'org.springframework.restdocs:spring-restdocs-mockmvc'
testImplementation 'org.springframework.restdocs:spring-restdocs-restassured:3.0.1'
testImplementation 'io.rest-assured:spring-mock-mvc:5.3.2'
}

tasks.named('test') {
outputs.dir snippetsDir
useJUnitPlatform()
}

asciidoctor.doFirst {
delete file('src/main/resources/docs')
}

asciidoctor {
configurations 'asciidoctorExt'
sources {
include("**/index.adoc")
}
baseDirFollowsSourceFile()
inputs.dir snippetsDir

dependsOn test
}

task createDocument(type: Copy) {
dependsOn asciidoctor

from asciidoctor.outputDir
into file("src/main/resources/docs")
}

bootJar {
dependsOn createDocument
}


tasks.named('asciidoctor') {
inputs.dir snippetsDir
dependsOn test
}
Binary file added api/gradle/wrapper/gradle-wrapper.jar
Binary file not shown.
7 changes: 7 additions & 0 deletions api/gradle/wrapper/gradle-wrapper.properties
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.8-bin.zip
networkTimeout=10000
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
13 changes: 13 additions & 0 deletions api/src/main/java/com/wootecam/api/ApiApplication.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package com.wootecam.api;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication(scanBasePackages = {"com.wootecam.core", "com.wootecam.api"})
public class ApiApplication {

public static void main(String[] args) {
SpringApplication.run(ApiApplication.class, args);
}

}
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
package com.wootecam.luckyvickyauction.global.exception;
package com.wootecam.api.advice;


import com.wootecam.core.exception.AuthenticationException;
import com.wootecam.core.exception.AuthorizationException;
import com.wootecam.core.exception.BusinessException;
import com.wootecam.core.exception.ErrorCode;
import com.wootecam.core.exception.ErrorResponse;
import com.wootecam.core.exception.InfraStructureException;
import java.io.PrintWriter;
import java.io.StringWriter;
import lombok.extern.slf4j.Slf4j;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.wootecam.luckyvickyauction.global.config;
package com.wootecam.api.config;

import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.wootecam.luckyvickyauction.global.config;
package com.wootecam.api.config;

import io.micrometer.core.instrument.MeterRegistry;
import org.springframework.boot.actuate.autoconfigure.metrics.MeterRegistryCustomizer;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
package com.wootecam.luckyvickyauction.global.config;
package com.wootecam.api.config;

import com.wootecam.luckyvickyauction.core.auction.controller.CurrentTimeArgumentResolver;
import com.wootecam.luckyvickyauction.core.member.controller.AuthenticationArgumentResolver;
import com.wootecam.luckyvickyauction.core.member.controller.AuthenticationInterceptor;
import com.wootecam.api.controller.CurrentTimeArgumentResolver;
import com.wootecam.api.interceptor.AuthenticationInterceptor;
import com.wootecam.api.util.AuthenticationArgumentResolver;
import java.util.List;
import lombok.RequiredArgsConstructor;
import org.springframework.context.annotation.Configuration;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package com.wootecam.luckyvickyauction.core.member.domain;
package com.wootecam.api.context;

import com.wootecam.luckyvickyauction.core.member.dto.SignInInfo;
import com.wootecam.core.dto.member.info.SignInInfo;
import lombok.Getter;
import org.springframework.stereotype.Component;
import org.springframework.web.context.annotation.RequestScope;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
package com.wootecam.luckyvickyauction.core.member.controller;
package com.wootecam.api.controller;

import com.wootecam.luckyvickyauction.core.member.controller.dto.SignInRequestInfo;
import com.wootecam.luckyvickyauction.core.member.controller.dto.SignInResponseInfo;
import com.wootecam.luckyvickyauction.core.member.controller.dto.SignUpRequestInfo;
import com.wootecam.luckyvickyauction.core.member.dto.SignInInfo;
import com.wootecam.luckyvickyauction.core.member.service.MemberService;
import com.wootecam.core.dto.member.info.SignInInfo;
import com.wootecam.core.dto.member.info.SignInRequestInfo;
import com.wootecam.core.dto.member.info.SignInResponseInfo;
import com.wootecam.core.dto.member.info.SignUpRequestInfo;
import com.wootecam.core.service.member.MemberService;
import jakarta.servlet.http.HttpSession;
import lombok.RequiredArgsConstructor;
import org.springframework.http.ResponseEntity;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,17 +1,16 @@
package com.wootecam.luckyvickyauction.core.auction.controller;
package com.wootecam.api.controller;

import com.wootecam.luckyvickyauction.core.auction.controller.dto.PurchaseRequest;
import com.wootecam.luckyvickyauction.core.auction.dto.AuctionSearchCondition;
import com.wootecam.luckyvickyauction.core.auction.dto.BuyerAuctionInfo;
import com.wootecam.luckyvickyauction.core.auction.dto.BuyerAuctionSimpleInfo;
import com.wootecam.luckyvickyauction.core.auction.service.AuctionService;
import com.wootecam.luckyvickyauction.core.auction.service.Auctioneer;
import com.wootecam.luckyvickyauction.core.member.controller.BuyerOnly;
import com.wootecam.luckyvickyauction.core.member.controller.Login;
import com.wootecam.luckyvickyauction.core.member.dto.SignInInfo;
import com.wootecam.luckyvickyauction.core.payment.service.PaymentService;
import com.wootecam.luckyvickyauction.global.dto.AuctionPurchaseRequestMessage;
import com.wootecam.luckyvickyauction.global.dto.AuctionRefundRequestMessage;
import com.wootecam.api.dto.PurchaseRequest;
import com.wootecam.api.dto.PurchaseResponse;
import com.wootecam.core.dto.auction.condition.AuctionSearchCondition;
import com.wootecam.core.dto.auction.info.BuyerAuctionInfo;
import com.wootecam.core.dto.auction.info.BuyerAuctionSimpleInfo;
import com.wootecam.core.dto.auction.message.AuctionPurchaseRequestMessage;
import com.wootecam.core.dto.auction.message.AuctionRefundRequestMessage;
import com.wootecam.core.dto.member.info.SignInInfo;
import com.wootecam.core.service.auction.AuctionService;
import com.wootecam.core.service.auctioneer.Auctioneer;
import com.wootecam.core.service.payment.PaymentService;
import java.time.LocalDateTime;
import java.util.List;
import java.util.UUID;
Expand All @@ -30,7 +29,6 @@
public class BuyerAuctionController {

private final AuctionService auctionService;
private final PaymentService paymentService;
private final Auctioneer auctioneer;

// 사용자는 경매 목록을 조회한다.
Expand All @@ -52,20 +50,22 @@ public ResponseEntity<BuyerAuctionInfo> getAuction(@PathVariable("auctionId") Lo
// 사용자는 경매에 입찰한다.
@BuyerOnly
@PostMapping("/auctions/{auctionId}/purchase")
public ResponseEntity<Void> submitAuction(@Login SignInInfo signInInfo,
@CurrentTime LocalDateTime now,
@PathVariable(name = "auctionId") Long auctionId,
@RequestBody PurchaseRequest purchaseRequest) {
public ResponseEntity<PurchaseResponse> submitAuction(@Login SignInInfo signInInfo,
@CurrentTime LocalDateTime now,
@PathVariable(name = "auctionId") Long auctionId,
@RequestBody PurchaseRequest purchaseRequest) {
AuctionPurchaseRequestMessage requestMessage = AuctionPurchaseRequestMessage.builder()
.requestId(UUID.randomUUID().toString())
.requestId(UUID.randomUUID())
.buyerId(signInInfo.id())
.auctionId(auctionId)
.price(purchaseRequest.price())
.quantity(purchaseRequest.quantity())
.requestTime(now)
.build();
auctioneer.process(requestMessage);
return ResponseEntity.ok().build();

PurchaseResponse response = new PurchaseResponse(requestMessage.requestId());
return ResponseEntity.ok(response);
}

/**
Expand All @@ -77,7 +77,7 @@ public ResponseEntity<Void> submitAuction(@Login SignInInfo signInInfo,
@BuyerOnly
@PutMapping("/receipts/{receiptId}/refund")
public ResponseEntity<Void> refundAuction(@Login SignInInfo buyerInfo,
@PathVariable("receiptId") Long receiptId,
@PathVariable("receiptId") UUID receiptId,
@CurrentTime LocalDateTime now) {
var message = new AuctionRefundRequestMessage(buyerInfo, receiptId, now);
auctioneer.refund(message);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.wootecam.luckyvickyauction.core.member.controller;
package com.wootecam.api.controller;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.wootecam.luckyvickyauction.core.auction.controller;
package com.wootecam.api.controller;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.wootecam.luckyvickyauction.core.auction.controller;
package com.wootecam.api.controller;

import java.time.LocalDateTime;
import org.springframework.core.MethodParameter;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.wootecam.luckyvickyauction.core.member.controller;
package com.wootecam.api.controller;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
package com.wootecam.luckyvickyauction.core.payment.controller;
package com.wootecam.api.controller;

import com.wootecam.luckyvickyauction.core.member.controller.Login;
import com.wootecam.luckyvickyauction.core.member.controller.Roles;
import com.wootecam.luckyvickyauction.core.member.domain.Role;
import com.wootecam.luckyvickyauction.core.member.dto.SignInInfo;
import com.wootecam.luckyvickyauction.core.payment.dto.BuyerChargePointCommand;
import com.wootecam.luckyvickyauction.core.payment.service.PaymentService;
import com.wootecam.core.domain.entity.type.Role;
import com.wootecam.core.dto.member.info.SignInInfo;
import com.wootecam.core.dto.payment.command.BuyerChargePointCommand;
import com.wootecam.core.service.payment.PaymentService;
import lombok.RequiredArgsConstructor;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PostMapping;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,18 +1,15 @@
package com.wootecam.luckyvickyauction.core.payment.controller;
package com.wootecam.api.controller;

import com.wootecam.luckyvickyauction.core.member.controller.BuyerOnly;
import com.wootecam.luckyvickyauction.core.member.controller.Login;
import com.wootecam.luckyvickyauction.core.member.controller.Roles;
import com.wootecam.luckyvickyauction.core.member.controller.SellerOnly;
import com.wootecam.luckyvickyauction.core.member.domain.Role;
import com.wootecam.luckyvickyauction.core.member.dto.SignInInfo;
import com.wootecam.luckyvickyauction.core.payment.dto.BuyerReceiptSearchCondition;
import com.wootecam.luckyvickyauction.core.payment.dto.BuyerReceiptSimpleInfo;
import com.wootecam.luckyvickyauction.core.payment.dto.ReceiptInfo;
import com.wootecam.luckyvickyauction.core.payment.dto.SellerReceiptSearchCondition;
import com.wootecam.luckyvickyauction.core.payment.dto.SellerReceiptSimpleInfo;
import com.wootecam.luckyvickyauction.core.payment.service.ReceiptService;
import com.wootecam.core.domain.entity.type.Role;
import com.wootecam.core.dto.member.info.SignInInfo;
import com.wootecam.core.dto.receipt.condition.BuyerReceiptSearchCondition;
import com.wootecam.core.dto.receipt.condition.SellerReceiptSearchCondition;
import com.wootecam.core.dto.receipt.info.BuyerReceiptSimpleInfo;
import com.wootecam.core.dto.receipt.info.ReceiptInfo;
import com.wootecam.core.dto.receipt.info.SellerReceiptSimpleInfo;
import com.wootecam.core.service.receipt.ReceiptService;
import java.util.List;
import java.util.UUID;
import lombok.RequiredArgsConstructor;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
Expand Down Expand Up @@ -54,7 +51,7 @@ public ResponseEntity<List<SellerReceiptSimpleInfo>> getSellerReceipts(@Login Si
@Roles({Role.BUYER, Role.SELLER})
@GetMapping("/{receiptId}")
public ResponseEntity<ReceiptInfo> getReceipt(@Login SignInInfo memberInfo,
@PathVariable("receiptId") Long receiptId) {
@PathVariable("receiptId") UUID receiptId) {
ReceiptInfo receiptInfo = receiptService.getReceiptInfo(memberInfo, receiptId);
return ResponseEntity.ok(receiptInfo);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package com.wootecam.luckyvickyauction.core.member.controller;
package com.wootecam.api.controller;

import com.wootecam.luckyvickyauction.core.member.domain.Role;
import com.wootecam.core.domain.entity.type.Role;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
Expand Down
Loading

0 comments on commit 6198c4b

Please sign in to comment.