-
Notifications
You must be signed in to change notification settings - Fork 101
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
feat(mission): support markdown syntax for mission descriptions #762
Changes from 20 commits
7ce97ae
07d808d
b08248f
dc028b7
75c8893
371c953
55d19db
6570b52
c12b6c5
3ae10d3
fdb29b2
1861855
e7174d8
010b2e7
f557d2f
02213d4
e2b13db
e545e26
e4c5038
75b7694
15862ce
4eedac4
01c8230
48a795d
31f49b2
f7e5b18
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
@@ -1,5 +1,9 @@ | ||||||
= 과제 관련 API | ||||||
|
||||||
== 내 과제 조회 | ||||||
== 내 과제 목록 조회 | ||||||
|
||||||
operation::mission-list-me-get[snippets='http-request,http-response'] | ||||||
|
||||||
== 내 과제 상세 조회 | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. c:
Suggested change
|
||||||
|
||||||
operation::mission-me-get[snippets='http-request,http-response'] |
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
|
@@ -95,10 +95,9 @@ data class MissionResponse( | |||||
) | ||||||
} | ||||||
|
||||||
data class MyMissionResponse( | ||||||
data class MyMissionAndJudgementResponse( | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. c: There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 제안주신 클래스명으로 바꿨을 경우 리턴 값이 |
||||||
val id: Long, | ||||||
val title: String, | ||||||
val description: String, | ||||||
val submittable: Boolean, | ||||||
val submitted: Boolean, | ||||||
val startDateTime: LocalDateTime, | ||||||
|
@@ -115,7 +114,6 @@ data class MyMissionResponse( | |||||
) : this( | ||||||
mission.id, | ||||||
mission.title, | ||||||
mission.description, | ||||||
mission.submittable, | ||||||
submitted, | ||||||
mission.period.startDateTime, | ||||||
|
@@ -126,6 +124,28 @@ data class MyMissionResponse( | |||||
) | ||||||
} | ||||||
|
||||||
data class MyMissionResponse( | ||||||
val id: Long, | ||||||
val title: String, | ||||||
val description: String, | ||||||
val submittable: Boolean, | ||||||
val startDateTime: LocalDateTime, | ||||||
val endDateTime: LocalDateTime, | ||||||
val status: MissionStatus, | ||||||
val submitted: Boolean, | ||||||
) { | ||||||
constructor(mission: Mission, submitted: Boolean, formattedDescription: String) : this( | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. a: 사소하지만 부 생성자의 매개 변수 순서를 주 생성자와 동일하게 설정하면 어떨까요?
Suggested change
|
||||||
mission.id, | ||||||
mission.title, | ||||||
formattedDescription, | ||||||
mission.submittable, | ||||||
mission.period.startDateTime, | ||||||
mission.period.endDateTime, | ||||||
mission.status, | ||||||
submitted | ||||||
) | ||||||
} | ||||||
|
||||||
data class JudgmentItemData( | ||||||
var id: Long = 0L, | ||||||
var testName: String = "", | ||||||
|
Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
@@ -12,8 +12,10 @@ import apply.domain.judgmentitem.JudgmentItem | |||||||||||||||||||||||||||||||||||||||||||
import apply.domain.judgmentitem.JudgmentItemRepository | ||||||||||||||||||||||||||||||||||||||||||||
import apply.domain.mission.Mission | ||||||||||||||||||||||||||||||||||||||||||||
import apply.domain.mission.MissionRepository | ||||||||||||||||||||||||||||||||||||||||||||
import apply.domain.mission.getOrThrow | ||||||||||||||||||||||||||||||||||||||||||||
import org.springframework.stereotype.Service | ||||||||||||||||||||||||||||||||||||||||||||
import org.springframework.transaction.annotation.Transactional | ||||||||||||||||||||||||||||||||||||||||||||
import support.markdownToEmbeddedHtml | ||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||
@Transactional(readOnly = true) | ||||||||||||||||||||||||||||||||||||||||||||
@Service | ||||||||||||||||||||||||||||||||||||||||||||
|
@@ -25,12 +27,12 @@ class MyMissionService( | |||||||||||||||||||||||||||||||||||||||||||
private val assignmentRepository: AssignmentRepository, | ||||||||||||||||||||||||||||||||||||||||||||
private val judgmentRepository: JudgmentRepository | ||||||||||||||||||||||||||||||||||||||||||||
) { | ||||||||||||||||||||||||||||||||||||||||||||
fun findAllByMemberIdAndRecruitmentId(memberId: Long, recruitmentId: Long): List<MyMissionResponse> { | ||||||||||||||||||||||||||||||||||||||||||||
fun findAllByMemberIdAndRecruitmentId(memberId: Long, recruitmentId: Long): List<MyMissionAndJudgementResponse> { | ||||||||||||||||||||||||||||||||||||||||||||
val missions = findMissions(memberId, recruitmentId) | ||||||||||||||||||||||||||||||||||||||||||||
if (missions.isEmpty()) return emptyList() | ||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||
val assignments = assignmentRepository.findAllByMemberId(memberId) | ||||||||||||||||||||||||||||||||||||||||||||
if (assignments.isEmpty()) return missions.map(::MyMissionResponse) | ||||||||||||||||||||||||||||||||||||||||||||
if (assignments.isEmpty()) return missions.map(::MyMissionAndJudgementResponse) | ||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||
val judgmentItems = judgmentItemRepository.findAllByMissionIdIn(missions.map { it.id }) | ||||||||||||||||||||||||||||||||||||||||||||
if (judgmentItems.isEmpty()) return missions.mapBy(assignments) | ||||||||||||||||||||||||||||||||||||||||||||
|
@@ -46,23 +48,23 @@ class MyMissionService( | |||||||||||||||||||||||||||||||||||||||||||
return missionRepository.findAllByEvaluationIdIn(targets.map { it.id }).filterNot { it.hidden } | ||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||
private fun List<Mission>.mapBy(assignments: List<Assignment>): List<MyMissionResponse> { | ||||||||||||||||||||||||||||||||||||||||||||
private fun List<Mission>.mapBy(assignments: List<Assignment>): List<MyMissionAndJudgementResponse> { | ||||||||||||||||||||||||||||||||||||||||||||
return map { mission -> | ||||||||||||||||||||||||||||||||||||||||||||
val assignment = assignments.find { it.missionId == mission.id } | ||||||||||||||||||||||||||||||||||||||||||||
MyMissionResponse(mission, assignment != null) | ||||||||||||||||||||||||||||||||||||||||||||
MyMissionAndJudgementResponse(mission, assignment != null) | ||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||
private fun List<Mission>.mapBy( | ||||||||||||||||||||||||||||||||||||||||||||
assignments: List<Assignment>, | ||||||||||||||||||||||||||||||||||||||||||||
judgmentItems: List<JudgmentItem>, | ||||||||||||||||||||||||||||||||||||||||||||
judgments: List<Judgment> | ||||||||||||||||||||||||||||||||||||||||||||
): List<MyMissionResponse> { | ||||||||||||||||||||||||||||||||||||||||||||
): List<MyMissionAndJudgementResponse> { | ||||||||||||||||||||||||||||||||||||||||||||
return map { mission -> | ||||||||||||||||||||||||||||||||||||||||||||
val assignment = assignments.find { it.missionId == mission.id } | ||||||||||||||||||||||||||||||||||||||||||||
val judgmentItem = judgmentItems.find { it.missionId == mission.id } | ||||||||||||||||||||||||||||||||||||||||||||
val judgment = judgments.findLastJudgment(assignment, judgmentItem) | ||||||||||||||||||||||||||||||||||||||||||||
MyMissionResponse( | ||||||||||||||||||||||||||||||||||||||||||||
MyMissionAndJudgementResponse( | ||||||||||||||||||||||||||||||||||||||||||||
mission = mission, | ||||||||||||||||||||||||||||||||||||||||||||
submitted = assignment != null, | ||||||||||||||||||||||||||||||||||||||||||||
runnable = assignment != null && judgmentItem != null, | ||||||||||||||||||||||||||||||||||||||||||||
|
@@ -94,4 +96,23 @@ class MyMissionService( | |||||||||||||||||||||||||||||||||||||||||||
judgmentRecord = judgment?.lastRecord | ||||||||||||||||||||||||||||||||||||||||||||
) | ||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||
fun findByMemberIdAndMissionId(memberId: Long, missionId: Long): MyMissionResponse { | ||||||||||||||||||||||||||||||||||||||||||||
val mission = missionRepository.getOrThrow(missionId) | ||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||
evaluationTargetRepository.findByEvaluationIdAndMemberId(mission.evaluationId, memberId) | ||||||||||||||||||||||||||||||||||||||||||||
?: throw NoSuchElementException("과제가 존재하지 않습니다. id: $missionId") | ||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||
if (!mission.isDescriptionViewable) { | ||||||||||||||||||||||||||||||||||||||||||||
throw NoSuchElementException("과제가 존재하지 않습니다. id: $missionId") | ||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||
val assignment = assignmentRepository.findByMemberIdAndMissionId(memberId, missionId) | ||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||
return MyMissionResponse( | ||||||||||||||||||||||||||||||||||||||||||||
mission = mission, | ||||||||||||||||||||||||||||||||||||||||||||
submitted = assignment != null, | ||||||||||||||||||||||||||||||||||||||||||||
markdownToEmbeddedHtml(mission.description), | ||||||||||||||||||||||||||||||||||||||||||||
) | ||||||||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. c: 아래 코드는 어떨까요? 조건문에 중괄호를 추가하거나, 생성자를 호출할 때 인자에 줄 바꿈을 추가할 수도 있습니다.
Suggested change
|
||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -7,6 +7,7 @@ import java.time.LocalDateTime | |
import javax.persistence.Column | ||
import javax.persistence.Embedded | ||
import javax.persistence.Entity | ||
import javax.persistence.Lob | ||
|
||
@SQLDelete(sql = "update mission set deleted = true where id = ?") | ||
@Where(clause = "deleted = false") | ||
|
@@ -16,6 +17,7 @@ class Mission( | |
val title: String, | ||
|
||
@Column(nullable = false) | ||
@Lob | ||
val description: String, | ||
|
||
@Column(nullable = false) | ||
|
@@ -40,6 +42,9 @@ class Mission( | |
val isSubmitting: Boolean | ||
get() = status == MissionStatus.SUBMITTING | ||
|
||
val isDescriptionViewable: Boolean | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. c: 개인 취향이에요! |
||
get() = !hidden && (status == MissionStatus.SUBMITTING || status == MissionStatus.UNSUBMITTABLE) | ||
woowabrie marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
constructor( | ||
title: String, | ||
description: String, | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
alter table mission | ||
modify description longtext not null; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
a: #553 (comment) 의 스니펫 디렉토리 명명 규칙에 따라 잘 작성하셨네요!