Skip to content
This repository was archived by the owner on Nov 21, 2023. It is now read-only.

Commit 6219617

Browse files
authored
[#27] user entity 생성 (#34)
1 parent ec53d1b commit 6219617

File tree

15 files changed

+178
-5
lines changed

15 files changed

+178
-5
lines changed

build.gradle.kts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ subprojects {
2626
dependencies {
2727
// spring base
2828
implementation("org.springframework.boot:spring-boot-starter-web")
29+
implementation("org.springframework.boot:spring-boot-starter-validation")
2930

3031
compileOnly("org.projectlombok:lombok")
3132
annotationProcessor("org.projectlombok:lombok")

user-api/src/main/kotlin/com/sns/user/UserApplication.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,10 @@ package com.sns.user
22

33
import org.springframework.boot.autoconfigure.SpringBootApplication
44
import org.springframework.boot.runApplication
5+
import org.springframework.data.jdbc.repository.config.EnableJdbcAuditing
56

67
@SpringBootApplication
8+
@EnableJdbcAuditing
79
class UserApplication
810

911
fun main(args: Array<String>) {
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
package com.sns.user.component.user.application
2+
3+
import com.sns.user.component.user.domains.User
4+
import com.sns.user.component.user.repositories.UserRepository
5+
import org.springframework.data.repository.findByIdOrNull
6+
import org.springframework.stereotype.Service
7+
8+
@Service
9+
class UserQueryService(
10+
private val userRepository: UserRepository
11+
) {
12+
fun getById(id: String): User? = userRepository.findByIdOrNull(id)
13+
}
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
package com.sns.user.component.user.domains
2+
3+
import java.time.Instant
4+
import javax.validation.constraints.Max
5+
import javax.validation.constraints.NotBlank
6+
import org.springframework.data.annotation.CreatedDate
7+
import org.springframework.data.annotation.Id
8+
import org.springframework.data.annotation.LastModifiedDate
9+
import org.springframework.data.annotation.Transient
10+
import org.springframework.data.domain.Persistable
11+
12+
data class User(
13+
@Id
14+
@NotBlank
15+
@Max(50)
16+
@JvmField
17+
val id: String, // email
18+
19+
@NotBlank
20+
@Max(100)
21+
var password: String,
22+
23+
@NotBlank
24+
@Max(50)
25+
val name: String,
26+
27+
@NotBlank
28+
var infoEmailAddress: String = id, // 서비스 정보 수신 이메일주소. 기본값은 id
29+
30+
@CreatedDate
31+
val createdAt: Instant = Instant.MIN,
32+
33+
@LastModifiedDate
34+
var updatedAt: Instant = Instant.MIN,
35+
) : Persistable<String> {
36+
@Transient
37+
private var new: Boolean = false
38+
39+
override fun getId() = this.id
40+
override fun isNew() = new
41+
42+
companion object {
43+
fun create(
44+
id: String,
45+
password: String,
46+
name: String,
47+
infoEmailAddress: String? = null
48+
): User {
49+
// TODO validation
50+
return User(
51+
id = id,
52+
password = password, // TODO encrypt
53+
name = name,
54+
infoEmailAddress = infoEmailAddress ?: id,
55+
).apply { new = true }
56+
}
57+
}
58+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
package com.sns.user.component.user.repositories
2+
3+
import org.springframework.stereotype.Repository
4+
5+
@Repository
6+
class DefaultUserRepository(
7+
userCrudRepository: UserCrudRepository
8+
) : UserRepository,
9+
UserCrudRepository by userCrudRepository
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
package com.sns.user.component.user.repositories
2+
3+
import com.sns.user.component.user.domains.User
4+
import org.springframework.data.repository.CrudRepository
5+
import org.springframework.stereotype.Repository
6+
7+
@Repository
8+
interface UserCrudRepository : CrudRepository<User, String>
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
package com.sns.user.component.user.repositories
2+
3+
import com.sns.user.component.user.domains.User
4+
import org.springframework.data.repository.CrudRepository
5+
import org.springframework.data.repository.NoRepositoryBean
6+
7+
@NoRepositoryBean
8+
interface UserRepository : CrudRepository<User, String>
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
package com.sns.user.endpoints.user
2+
3+
import com.sns.user.component.user.application.UserQueryService
4+
import com.sns.user.component.user.domains.User
5+
import org.springframework.web.bind.annotation.GetMapping
6+
import org.springframework.web.bind.annotation.PathVariable
7+
import org.springframework.web.bind.annotation.RequestMapping
8+
import org.springframework.web.bind.annotation.RestController
9+
10+
@RestController
11+
@RequestMapping("/api/v1/users")
12+
class UserController(
13+
private val userQueryService: UserQueryService
14+
) {
15+
@GetMapping("/ids/{id}")
16+
fun getUser(@PathVariable id: String): User? = userQueryService.getById(id)
17+
}

user-api/src/main/resources/application-dev.yml

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,11 @@ server:
22
port: 10001
33
logging:
44
level: info
5-
pattern:
6-
console: %d{HH:mm:ss} [%t][%-5level] %msg \\(%F:%L\\)%n
5+
org.springframework.jdbc.core.JdbcTemplate: debug
76
spring:
87
datasource:
98
driver-class-name: com.mysql.cj.jdbc.Driver
10-
url: jdbc:mysql://${DDD_DB_URL}?autoReconnect=true&useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC&tinyInt1isBit=false
9+
url: jdbc:mysql://${DDD_DB_URL}/users?autoReconnect=true&useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC&tinyInt1isBit=false
1110
username: ${DDD_DB_ID}
1211
password: ${DDD_DB_PW}
1312
hikari:
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
package com.sns.user
2+
3+
import java.util.*
4+
import java.util.function.Consumer
5+
import org.assertj.core.api.Assertions.assertThat
6+
7+
infix fun <T : Any> T.isEqualTo(other: T) = assertThat(this).isEqualTo(other)
8+
9+
infix fun <T : Any> T.isNotEqualTo(other: T) = assertThat(this).isNotEqualTo(other)
10+
11+
infix fun <T : Any> T.satisfies(requirements: Consumer<T>) = assertThat(this).satisfies(requirements)
12+
13+
infix fun <T : Any, R : Optional<T>> R.hasValueSatisfying(requirements: Consumer<T>) = assertThat(this).hasValueSatisfying(requirements)

user-api/src/test/kotlin/com/sns/user/components/test/TestUserRepositoryTest.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ class TestUserRepositoryTest @Autowired constructor(
3232
@ValueSource(strings = ["hyounglin", "Chanhyeong Cho", "y2o2u2n", "youngvly"])
3333
fun insert(name: String) {
3434
Assumptions.assumeThat(name).isNotEmpty
35-
assertThat(repository.save(name)).isPositive
35+
assertThat(repository.save(TestUser(name))).isNotNull
3636
assertThat(repository.findByNickName(name)).isNotNull
3737
}
3838

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
package com.sns.user.components.user.repositories
2+
3+
import com.sns.user.component.user.domains.User
4+
import com.sns.user.component.user.repositories.UserRepository
5+
import com.sns.user.hasValueSatisfying
6+
import com.sns.user.isEqualTo
7+
import com.sns.user.isNotEqualTo
8+
import java.time.Instant
9+
import org.junit.jupiter.api.Test
10+
import org.springframework.beans.factory.annotation.Autowired
11+
import org.springframework.boot.test.context.SpringBootTest
12+
13+
@SpringBootTest
14+
class UserRepositoryTest {
15+
@Autowired
16+
lateinit var userRepository: UserRepository
17+
18+
@Test
19+
fun save() {
20+
val id = "[email protected]"
21+
val name = "TESTER"
22+
23+
val user = User.create(id, "1235", name)
24+
25+
userRepository.save(user)
26+
27+
userRepository.findById(id) hasValueSatisfying { savedUser ->
28+
savedUser.id isEqualTo id
29+
savedUser.name isEqualTo name
30+
savedUser.infoEmailAddress isEqualTo id
31+
savedUser.createdAt isNotEqualTo Instant.MIN
32+
savedUser.updatedAt isNotEqualTo Instant.MIN
33+
}
34+
}
35+
}

user-api/src/test/resources/application.properties

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ spring.sql.init.mode=always
1010
spring.sql.init.schema-locations=classpath*:db/*/*schema.sql
1111
spring.sql.init.data-locations=classpath*:db/*/*data.sql
1212
spring.sql.init.continue-on-error=false
13+
logging.level.org.springframework.jdbc.core=debug
1314
# h2
1415
#spring.h2.console.enabled=true
1516
#spring.h2.console.path=/h2-console

user-api/src/test/resources/db/test/schema.sql

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,4 @@ CREATE TABLE IF NOT EXISTS test_user
22
(
33
id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
44
`nick_name` VARCHAR(30) NOT NULL
5-
);
5+
);
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
CREATE TABLE IF NOT EXISTS `user`
2+
(
3+
id VARCHAR(50) NOT NULL PRIMARY KEY COMMENT '아이디 (이메일)',
4+
password VARCHAR(100) NOT NULL COMMENT '비밀번호',
5+
`name` VARCHAR(50) NOT NULL COMMENT '이름',
6+
info_email_address VARCHAR(50) NOT NULL COMMENT '서비스 정보 수신 이메일주소',
7+
created_at DATETIME NOT NULL COMMENT '생성 시간',
8+
updated_at DATETIME NOT NULL COMMENT '마지막 수정 시간'
9+
);

0 commit comments

Comments
 (0)