Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
75 commits
Select commit Hold shift + click to select a range
acc06a9
fix: web, doc 의존성 삭제
kamillcream Jan 14, 2026
bfbf000
feat: lombok 추가
kamillcream Jan 14, 2026
491517a
feat: web, doc 의존성 추가
kamillcream Jan 14, 2026
cbcd883
feat: Lombok 추가
kamillcream Jan 14, 2026
24b527c
feat: Lombok 추가
kamillcream Jan 14, 2026
fa3fc9d
feat: 공통 응답 객체 추가
kamillcream Jan 14, 2026
d9a3d8a
feat: BaseEntity 추가
kamillcream Jan 14, 2026
a75167b
feat: 상태코드 인터페이스
kamillcream Jan 14, 2026
142725b
feat: 에러 상세정보 객체
kamillcream Jan 14, 2026
31520cb
feat: 에러 상태코드
kamillcream Jan 14, 2026
35b6f5f
feat: 정상 상태코드
kamillcream Jan 14, 2026
6f93fa0
feat: 전역 예외처리
kamillcream Jan 14, 2026
9e8b2ca
feat: 유저 엔티티
kamillcream Jan 14, 2026
9b64620
feat: 유저 타입 enum
kamillcream Jan 14, 2026
10d2632
feat: exceptionadvice
kamillcream Jan 14, 2026
012e2be
feat: module 간 의존성 추가
kamillcream Jan 15, 2026
6873140
fix: 기본 생성자 protected 삭제
kamillcream Jan 15, 2026
6fe3785
chore: 도메인으로 이동
kamillcream Jan 15, 2026
d06a364
feat: 영속성 어댑터 테스트
kamillcream Jan 15, 2026
d74ecc1
feat: 영속성 어댑터
kamillcream Jan 15, 2026
23a52f2
feat: 유저 아웃포트
kamillcream Jan 15, 2026
8a076f8
feat: lombok 의존성 추가
kamillcream Jan 15, 2026
a29d7e2
feat: lombok 어노테이션 적용
kamillcream Jan 15, 2026
61bbc49
feat: 회원가입 성공 테스트
kamillcream Jan 15, 2026
871d9db
feat: 회원가입 요청 객체
kamillcream Jan 15, 2026
c48e0ad
feat: 유저 영속성 레포
kamillcream Jan 15, 2026
58e5696
feat: 유저 매퍼
kamillcream Jan 15, 2026
2861da9
fix: kotlin 주석 처리
kamillcream Jan 16, 2026
5242af5
feat: 유효하지 않은 요청 객체 예외
kamillcream Jan 16, 2026
d50dbe6
fix: 시큐리티 의존성 비활성화
kamillcream Jan 16, 2026
6f2d09d
feat: lombok 및 테스트 의존성 추가
kamillcream Jan 16, 2026
36ceb60
feat: 회원가입 요청 객체
kamillcream Jan 16, 2026
e9ab22c
feat: 이메일 중복 확인
kamillcream Jan 16, 2026
41e006b
feat: 이메일 중복 확인 인터페이스
kamillcream Jan 16, 2026
b998606
feat: 이메일 중복 확인 구현체
kamillcream Jan 16, 2026
45df738
feat: 영속성 레이어에 맞는 테스트 구현
kamillcream Jan 16, 2026
e0ac51c
feat: 유저 생성 서비스 테스트
kamillcream Jan 16, 2026
70a0195
feat: 유저 조회 서비스 테스트
kamillcream Jan 16, 2026
ed4870b
feat: 유저 조회 유스케이스
kamillcream Jan 16, 2026
c8605f8
feat: 유저 조회 유스케이스 구현체
kamillcream Jan 16, 2026
6c3cba6
feat: 유저 생성 유스케이스
kamillcream Jan 16, 2026
c9835c4
feat: 유저 컨트롤러
kamillcream Jan 16, 2026
4c63527
feat: 유저 컨트롤러 테스트
kamillcream Jan 16, 2026
a27e72a
feat: 유저 도메인 jpa 설정
kamillcream Jan 16, 2026
9d7b14d
fix: getStactTrace() 수정
kamillcream Jan 17, 2026
d7fe9bc
fix: lombok 버전 수정
kamillcream Jan 17, 2026
be19ec9
fix: USER_001 메시지 수정
kamillcream Jan 17, 2026
da7b08f
fix: 테스트 stub 대상 수정
kamillcream Jan 17, 2026
a6ff544
fix: email 길이, isActive 주석 수정
kamillcream Jan 17, 2026
d124720
feat: 조회 대상 사용자가 존재하지 않을 때 예외
kamillcream Jan 17, 2026
86565da
feat: findById가 null일 때 커스텀 예외 던지기
kamillcream Jan 17, 2026
456a6d2
feat: findById가 null일 때 테스트 추가
kamillcream Jan 17, 2026
57f7383
feat: NotNull 추가
kamillcream Jan 17, 2026
9962af4
feat: 시큐리티 의존성 활성화
kamillcream Jan 17, 2026
65e1f02
chore: 어댑터에서 포트로 패키지 이동
kamillcream Jan 17, 2026
d42d599
feat: 비밀번호 암호화해서 저장
kamillcream Jan 17, 2026
818a4ce
feat: 비밀번호 암호화 확인 테스트
kamillcream Jan 17, 2026
2ad7815
chore: SignUpCommand 패키지 이동
kamillcream Jan 17, 2026
ede1490
feat: PasswordEncoder 빈 등록
kamillcream Jan 17, 2026
f0786e2
chore: 테이블 명칭 변경
kamillcream Jan 17, 2026
146e257
chore: checkEmailAvailable -> checkEmailExists
kamillcream Jan 17, 2026
a5de23a
chore: checkEmailAvailable -> checkEmailExists
kamillcream Jan 17, 2026
6e39453
chore: checkEmailAvailable -> checkEmailExists
kamillcream Jan 17, 2026
a9a8725
fix: verify 먼저 실행 후 비교
kamillcream Jan 17, 2026
b5b3632
fix: encoder spy
kamillcream Jan 17, 2026
3129aa2
feat: bootstrap 모듈에서 user 모듈의 인프라 모듈 의존
kamillcream Jan 17, 2026
eee5589
feat: transactional 어노테이션 의존성 추가
kamillcream Jan 17, 2026
f539b31
fix: lombok -> mapstruct 의존성 순서 변경
kamillcream Jan 17, 2026
2dec099
feat: transactional 어노테이션 의존성 추가
kamillcream Jan 17, 2026
5560cbf
feat: 시큐리티 모든 요청 허용
kamillcream Jan 17, 2026
109c08d
feat: Transactional(readonly=false) 추가
kamillcream Jan 17, 2026
4b11ce5
feat: Transactional(readonly=true) 추가
kamillcream Jan 17, 2026
ec482d8
feat: 이메일 중복여부 응답 객체
kamillcream Jan 17, 2026
70a8c67
feat: 이메일 중복여부 응답 객체 반환
kamillcream Jan 17, 2026
a059791
feat: 컨트롤러 테스트에서 시큐리티 설정 off
kamillcream Jan 17, 2026
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
7 changes: 6 additions & 1 deletion gradle/libs.versions.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,22 @@ redisson = "3.52.0"
springdoc = "2.8.4"
connector = "8.3.0"
mapstruct = "1.6.2"
lombok = "1.18.42"
transactional = "6.1.0"

[libraries]

lombok = { module = "org.projectlombok:lombok", version.ref = "lombok" }

jackson-databind = { module = "com.fasterxml.jackson.core:jackson-databind", version.ref = "jackson" }
jackson-datatype-jsr310 = { module = "com.fasterxml.jackson.datatype:jackson-datatype-jsr310", version.ref = "jackson" }
jackson-module-kotlin = { module = "com.fasterxml.jackson.module:jackson-module-kotlin", version.ref = "jackson" }

jwt-api = { module = "io.jsonwebtoken:jjwt-api", version.ref = "jwt" }
jwt-impl = { module = "io.jsonwebtoken:jjwt-impl", version.ref = "jwt" }
jwt-jackson = { module = "io.jsonwebtoken:jjwt-jackson", version.ref = "jwt" }

mapstruct = { module = "org.mapstruct:mapstruct", version.ref = "mapstruct" }
mapstruct-processor = { module = "org.mapstruct:mapstruct-processor", version.ref = "mapstruct" }

org-redisson-starter = {module = "org.redisson:redisson-spring-boot-starter", version.ref = "redisson"}

Expand All @@ -33,6 +37,7 @@ spring-boot-starter-oauth2-client = { module = "org.springframework.boot:spring-
spring-boot-starter-security = { module = "org.springframework.boot:spring-boot-starter-security" }
spring-boot-starter-redis = { module = "org.springframework.boot:spring-boot-starter-data-redis" }
spring-boot-starter-kafka = { module = "org.springframework.kafka:spring-kafka" }
spring-boot-starter-transactional = { module = "org.springframework:spring-tx", version.ref = "transactional" }
spring-boot-spring-doc = { module = "org.springdoc:springdoc-openapi-starter-webmvc-ui", version.ref = "springdoc" }


Expand Down
3 changes: 1 addition & 2 deletions main-modules/bootstrap/build.gradle
Copy link

Choose a reason for hiding this comment

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

아키텍처 구조 파악하면서 하나 궁금한게

application에는 domain, common
Infrastructure에는 domain, common, application 의존성 추가하는데

bootstrap에는 implementation project(:main-modules:user:infrastructure) 이거 추가 안 해도 되나?
implementation project(':main-modules:common')은 추가되어 있길래

Copy link
Contributor Author

Choose a reason for hiding this comment

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

아 넣는 게 맞음.
왜 뺐냐면 헥사고날 아키텍쳐에서는 bootstrap에서 컨트롤러도 포함하는데 모듈리스에서는 도메인 별로 모듈을 갖추니까 어댑터의 일종인 컨트롤러를 bootstrap에 넣는 게 모호하더라고. 그래서 도메인 모듈로 뺐는데 넣는 게 맞는 듯.

Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,10 @@ tasks.named('bootJar') {

dependencies {
implementation project(':main-modules:common')
implementation project(':main-modules:user:infrastructure')

implementation libs.spring.boot.starter.jpa
implementation libs.spring.boot.starter.security
implementation libs.spring.boot.starter.web
implementation libs.spring.boot.spring.doc
implementation libs.bundles.bootstrap
testImplementation libs.bundles.test

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package com.sidework.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.SecurityFilterChain;

@Configuration
@EnableWebSecurity
public class SecurityConfig {

@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http
.csrf(AbstractHttpConfigurer::disable) // CSRF 비활성화
.authorizeHttpRequests(auth -> auth
.anyRequest().permitAll() // 모든 요청 허용
);

return http.build();
}

@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
}
10 changes: 8 additions & 2 deletions main-modules/common/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,24 @@ plugins {
id 'io.spring.dependency-management'
}
tasks.named('jar') {
enabled = false
enabled = true
}

tasks.named('bootJar') {
enabled = true
enabled = false
}

dependencies {
implementation libs.bundles.jackson
implementation libs.spring.boot.starter.logging
implementation libs.spring.boot.starter.web
implementation libs.spring.boot.starter.validation
implementation libs.spring.boot.starter.jpa

compileOnly libs.lombok
annotationProcessor libs.lombok

implementation("jakarta.validation:jakarta.validation-api:3.1.1")
}

repositories {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package com.sidework.common.entity;


import jakarta.persistence.*;
import lombok.Getter;
import org.springframework.data.annotation.CreatedDate;
import org.springframework.data.annotation.LastModifiedDate;
import org.springframework.data.jpa.domain.support.AuditingEntityListener;

import java.time.Instant;

@MappedSuperclass
@EntityListeners(AuditingEntityListener.class)
@Getter
public abstract class BaseEntity {

@CreatedDate
@Column(updatable = false)
private Instant createdAt;

@LastModifiedDate
private Instant updatedAt;

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
package com.sidework.common.response;

import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonPropertyOrder;
import com.sidework.common.response.status.SuccessStatus;


@JsonPropertyOrder({"code", "message", "result", "isSuccess"})
@JsonInclude(JsonInclude.Include.NON_NULL)
public record ApiResponse<T>(boolean isSuccess, String code, String message, T result, String path) {

// 성공 - 데이터 반환
public static <T> ApiResponse<T> onSuccess(T result) {
return new ApiResponse<>(
true,
SuccessStatus.OK.getCode(),
SuccessStatus.OK.getMessage(),
result,
null
);
}

// 성공 - 생성됨 (201)
public static <T> ApiResponse<T> onSuccessCreated() {
return new ApiResponse<>(
true,
SuccessStatus.CREATED.getCode(),
SuccessStatus.CREATED.getMessage(),
null,
null
);
}

// 성공 - void 응답
public static <T> ApiResponse<T> onSuccessVoid() {
return new ApiResponse<>(
true,
SuccessStatus.OK.getCode(),
SuccessStatus.OK.getMessage(),
null,
null
);
}

// 실패 응답
public static <T> ApiResponse<T> onFailure(
String code,
String message,
T data,
String requestUri
) {
return new ApiResponse<>(
false,
code,
message,
data,
requestUri
);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package com.sidework.common.response;

import com.sidework.common.response.status.BaseStatusCode;
import org.springframework.http.HttpStatus;

public record ErrorDetail(HttpStatus httpStatus, String code, String message) {

public static ErrorDetail from(BaseStatusCode code) {
return new ErrorDetail(
code.getHttpStatus(),
code.getCode(),
code.getMessage()
);
}
}
Loading