Skip to content

Commit

Permalink
feat: Survey 도메인을 kotlin으로 리팩토링한다
Browse files Browse the repository at this point in the history
  • Loading branch information
devxb committed Mar 6, 2024
1 parent 71637d1 commit ec32d3b
Show file tree
Hide file tree
Showing 19 changed files with 449 additions and 0 deletions.
11 changes: 11 additions & 0 deletions survey/build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
repositories {
mavenCentral()
}

dependencies {
implementation project(":core:data")

implementation "org.springframework.boot:spring-boot-starter-data-jpa"

testRuntimeOnly "com.h2database:h2"
}
19 changes: 19 additions & 0 deletions survey/src/main/kotlin/me/nalab/survey/domain/feedback/Bookmark.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package me.nalab.survey.domain.feedback

import java.time.Instant
import javax.persistence.Column
import javax.persistence.Embeddable

@Embeddable
class Bookmark(
@Column(name = "is_bookmarked", nullable = false)
var isBookmarked: Boolean = BOOKMARK_DEFAULT_STATE,

@Column(name = "bookmarked_at", columnDefinition = "TIMESTAMP(6)", nullable = false)
var bookmarkedAt: Instant,
) {

companion object {
private const val BOOKMARK_DEFAULT_STATE = false
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package me.nalab.survey.domain.feedback

import javax.persistence.*

@Entity
class ChoiceFormQuestionFeedback(
id: Long? = null,
formQuestionId: Long,
isRead: Boolean = false,
bookmark: Bookmark,
feedback: Feedback,

@ElementCollection
@Column(name = "selects")
@CollectionTable(name = "selects", joinColumns = [JoinColumn(name = "form_feedback_id")])
private val selectedChoiceIds: MutableSet<Long>,
) : FormQuestionFeedbackable(id, formQuestionId, isRead, bookmark, feedback)
50 changes: 50 additions & 0 deletions survey/src/main/kotlin/me/nalab/survey/domain/feedback/Feedback.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package me.nalab.survey.domain.feedback

import me.nalab.core.data.common.TimeBaseEntity
import javax.persistence.*

@Entity(name = "feedback")
@Table(name = "feedback")
class Feedback(
@Id
@Column(name = "feedback_id")
private var id: Long? = null,

@JoinColumn(name = "survey_id", nullable = false)
private val surveyId: Long,

@OneToMany(
mappedBy = "feedback",
fetch = FetchType.LAZY,
cascade = [CascadeType.PERSIST, CascadeType.MERGE]
)
private val allQuestionFeedbacks: MutableList<FormQuestionFeedbackable>,

@Column(name = "is_read", nullable = false)
private var isRead: Boolean = false,

@JoinColumn(name = "reviewer_id", nullable = false)
@OneToOne(fetch = FetchType.LAZY, cascade = [CascadeType.PERSIST, CascadeType.MERGE])
private val reviewer: Reviewer,
) : Comparable<Feedback>, TimeBaseEntity() {

fun read(read: Boolean) {
isRead = read
}

override fun compareTo(other: Feedback): Int {
if (updatedAt.isAfter(other.updatedAt)) {
return -1
}
if (updatedAt.isBefore(other.updatedAt)) {
return 1
}
if (createdAt.isAfter(other.createdAt)) {
return -1
}
if (createdAt.isBefore(other.createdAt)) {
return 1
}
return 0
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package me.nalab.survey.domain.feedback

import java.time.Instant
import javax.persistence.*

@Entity
@Table(name = "form_feedback")
abstract class FormQuestionFeedbackable(
@Id
@Column(name = "form_feedback_id")
protected open var id: Long? = null,

@Column(name = "form_question_id")
@JoinColumn(name = "form_question_id", nullable = false)
protected open val formQuestionId: Long,

@Column(name = "is_read")
protected open var isRead: Boolean = false,

@Embedded
protected open val bookmark: Bookmark,

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "feedback_id")
private var feedback: Feedback,
) {

fun bookmark() {
bookmark.isBookmarked = true
bookmark.bookmarkedAt = Instant.now()
}

fun cancel() {
bookmark.isBookmarked = false
bookmark.bookmarkedAt = Instant.now()
}
}
44 changes: 44 additions & 0 deletions survey/src/main/kotlin/me/nalab/survey/domain/feedback/Reviewer.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package me.nalab.survey.domain.feedback

import me.nalab.core.data.common.TimeBaseEntity
import javax.persistence.Column
import javax.persistence.Entity
import javax.persistence.Id
import javax.persistence.Table

@Entity(name = "reviewer")
@Table(name = "reviewer")
class Reviewer(
@Id
@Column(name = "reviewer_id")
private var id: Long? = null,

@Column(name = "nick_name", nullable = false)
private var nickName: String,

@Column(name = "collaboration_experience", nullable = false)
private val collaborationExperience: Boolean,

@Column(name = "position", nullable = false)
private var position: String? = null,
) : TimeBaseEntity() {

fun generateFirstReviewerNickName() {
nickName = "A"
}

fun generateNickName(lastName: String) {
nickName = getNextNickName(lastName)
}

private fun getNextNickName(lastName: String): String {
for (i in lastName.length - 1 downTo 0) {
if (lastName[i] != 'Z') {
return lastName.substring(0, i) + (lastName[i].code + 1).toChar() + "A".repeat(
lastName.length - (i + 1)
)
}
}
return "A".repeat(Math.max(0, lastName.length + 1))
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package me.nalab.survey.domain.feedback

import javax.persistence.*

@Entity
class ShortFormQuestionFeedback(
id: Long? = null,
formQuestionId: Long,
isRead: Boolean = false,
bookmark: Bookmark,
feedback: Feedback,

@ElementCollection
@CollectionTable(name = "reply", joinColumns = [JoinColumn(name = "form_feedback_id")])
@Column(name = "replies")
private val replies: MutableList<String>,
) : FormQuestionFeedbackable(id, formQuestionId, isRead, bookmark, feedback)
28 changes: 28 additions & 0 deletions survey/src/main/kotlin/me/nalab/survey/domain/survey/Choice.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package me.nalab.survey.domain.survey

import javax.persistence.*

@Entity(name = "choice")
@Table(name = "choice")
class Choice(

@Id
@Column(name = "choice_id")
private var id: Long? = null,

@Column(name = "content", length = 18, nullable = false)
private val content: String,

@Column(name = "orders", nullable = false)
val order: Int,

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "form_question_id", nullable = false)
private val choiceFormQuestion: ChoiceFormQuestion,
) : Comparable<Choice> {

override fun compareTo(other: Choice): Int {
return Comparator.comparingInt { obj: Choice -> obj.order }
.compare(this, other)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package me.nalab.survey.domain.survey

import me.nalab.survey.domain.survey.exception.DuplicatedOrderException
import javax.persistence.*

@Entity
class ChoiceFormQuestion(
id: Long? = null,
title: String,
order: Int,
questionType: QuestionType,
survey: Survey,

@OneToMany(
mappedBy = "choiceFormQuestion",
fetch = FetchType.LAZY,
cascade = [CascadeType.PERSIST, CascadeType.MERGE],
)
private val choices: MutableList<Choice>,

@Column(name = "max_selection_count")
private val maxSelectableCount: Int,

@Enumerated(EnumType.STRING)
@Column(name = "choice_question_type")
private val choiceFormQuestionType: ChoiceFormQuestionType,
) : FormQuestionable(id, title, order, questionType, survey) {

init {
choices.sorted()
validNoDuplicatedChoiceOrder(choices)
}

private fun validNoDuplicatedChoiceOrder(choiceList: List<Choice>) {
val orders = HashSet<Int>()
choiceList.forEach { choice ->
val order: Int = choice.order
if (orders.contains(order)) {
throw DuplicatedOrderException(order, orders)
}
orders.add(order)
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package me.nalab.survey.domain.survey

enum class ChoiceFormQuestionType {
TENDENCY,
CUSTOM,
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package me.nalab.survey.domain.survey

import me.nalab.core.data.common.TimeBaseEntity
import java.util.function.LongSupplier
import javax.persistence.*

@Entity
@Table(name = "form_question")
abstract class FormQuestionable(
@Id
@Column(name = "form_question_id")
open var id: Long? = null,

@Column(name = "title", nullable = false, length = 45)
protected open val title: String,

@Column(name = "orders", nullable = false)
open val order: Int,

@Enumerated(EnumType.STRING)
@Column(name = "question_type")
protected open val questionType: QuestionType,

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "survey_id", nullable = false)
open val survey: Survey,
) : Comparable<FormQuestionable>, TimeBaseEntity() {

protected open fun cascadeId(idSupplier: LongSupplier) {
return
}

override fun compareTo(other: FormQuestionable): Int {
return Comparator.comparingInt { obj: FormQuestionable -> obj.order }
.compare(this, other)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package me.nalab.survey.domain.survey

enum class QuestionType {
CHOICE,
SHORT,
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package me.nalab.survey.domain.survey

import javax.persistence.*

@Entity
class ShortFormQuestion(
id: Long? = null,
title: String,
order: Int,
questionType: QuestionType,
survey: Survey,

@Enumerated(EnumType.STRING)
@Column(name = "short_form_question_type")
private val shortFormQuestionType: ShortFormQuestionType,
) : FormQuestionable(id, title, order, questionType, survey)
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package me.nalab.survey.domain.survey

enum class ShortFormQuestionType {
STRENGTH,
WEAKNESS,
CUSTOM,
}
41 changes: 41 additions & 0 deletions survey/src/main/kotlin/me/nalab/survey/domain/survey/Survey.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package me.nalab.survey.domain.survey

import me.nalab.core.data.common.TimeBaseEntity
import me.nalab.survey.domain.survey.exception.DuplicatedOrderException
import javax.persistence.*

@Table(name = "survey")
@Entity(name = "survey")
class Survey(
@Id
@Column(name = "gallery_id")
private var id: Long? = null,

@OneToMany(
mappedBy = "survey",
fetch = FetchType.LAZY,
cascade = [CascadeType.PERSIST, CascadeType.MERGE]
)
private val formQuestionables: MutableList<FormQuestionable>,

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "target_id")
private val target: Target,
) : TimeBaseEntity() {

init {
formQuestionables.sorted()
validNoDuplicatedFormOrder()
}

private fun validNoDuplicatedFormOrder() {
val orders = HashSet<Int>()
this.formQuestionables.forEach { formQuestion ->
val order: Int = formQuestion.order
if (orders.contains(order)) {
throw DuplicatedOrderException(order, orders)
}
orders.add(order)
}
}
}
Loading

0 comments on commit ec32d3b

Please sign in to comment.