Skip to content

Commit 0cb84ab

Browse files
authored
Merge pull request #382 from GSM-MSG/feature/377-get-student-authenticationForm-detail
학생이 제출한 폼 상세 조회 기능 개발
2 parents de79bff + 79a8c8c commit 0cb84ab

23 files changed

+265
-23
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
package team.msg.sms.domain.authentication.dto.res
2+
3+
import team.msg.sms.domain.authentication.model.FieldType
4+
import java.util.UUID
5+
6+
data class StudentAuthenticationFormResponseData(
7+
val markingBoardId: UUID,
8+
val title: String,
9+
val content: List<Area>
10+
) {
11+
data class Area(
12+
val areaId: UUID,
13+
val areaTitle: String,
14+
val sections: List<Section>
15+
)
16+
data class Section(
17+
val sectionId: UUID,
18+
val sectionName: String,
19+
val maxCount: Int,
20+
val groups: List<Group>
21+
)
22+
data class Group(
23+
val groupId: UUID,
24+
val maxScore: Double,
25+
val fields: List<FieldSet>
26+
)
27+
28+
data class FieldSet(
29+
val setId: UUID,
30+
val values: List<Field>
31+
)
32+
data class Field(
33+
val fieldId: UUID,
34+
val fieldType: FieldType,
35+
val value: String?
36+
)
37+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
package team.msg.sms.domain.authentication.exception
2+
3+
import team.msg.sms.common.error.SmsException
4+
import team.msg.sms.domain.authentication.exception.error.AuthenticationErrorCode
5+
6+
object MarkingBoardNotFoundException : SmsException(
7+
AuthenticationErrorCode.MARKING_BOARD_NOT_FOUND
8+
)

sms-core/src/main/kotlin/team/msg/sms/domain/authentication/exception/error/AuthenticationErrorCode.kt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,8 @@ enum class AuthenticationErrorCode(
1414
ONLY_ACCESS_MYSELF(ErrorStatus.FORBIDDEN, "자기 자신만 조회할 수 있습니다."),
1515
INVALID_GRADE_CLASS(ErrorStatus.FORBIDDEN, "담임 선생님만 조회할 수 있습니다."),
1616
ALREADY_GIVEN_SCORE(ErrorStatus.CONFLICT, "이미 활동에 점수가 부여되었습니다."),
17-
NO_REQUESTED_ACTIVITY(ErrorStatus.CONFLICT, "활동이 아직 요청되지 않았습니다.")
17+
NO_REQUESTED_ACTIVITY(ErrorStatus.CONFLICT, "활동이 아직 요청되지 않았습니다."),
18+
MARKING_BOARD_NOT_FOUND(ErrorStatus.NOT_FOUND, "학생이 제출한 폼이 조회되지 않습니다.")
1819
;
1920

2021
override fun status(): Int = status

sms-core/src/main/kotlin/team/msg/sms/domain/authentication/model/UserFormValue.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import java.util.UUID
77
@Aggregate
88
class UserFormValue(
99
val id: UUID,
10-
val setId: UUID?,
10+
val setId: UUID,
1111
val authenticationFieldGroupId: UUID,
1212
val authenticationSectionId: UUID,
1313
val authenticationFieldId: UUID,

sms-core/src/main/kotlin/team/msg/sms/domain/authentication/service/GetMarkingBoardService.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
package team.msg.sms.domain.authentication.service
22

33
import team.msg.sms.domain.authentication.dto.res.UserBoardPageResponseData
4+
import team.msg.sms.domain.authentication.model.MarkingBoard
45
import team.msg.sms.domain.authentication.model.MarkingBoardType
56
import java.util.*
67

78
interface GetMarkingBoardService {
9+
fun getMarkingBoardById(id: UUID): MarkingBoard
810
fun getMarkingBoardByStudentIds(
911
studentIds: List<UUID>,
1012
authenticationId: UUID,
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,11 @@
11
package team.msg.sms.domain.authentication.service
22

3+
import team.msg.sms.domain.authentication.model.UserFormValue
4+
import java.util.UUID
5+
36
interface GetUserFormValueService {
7+
fun getUserFormValueListByFieldIdAndStudentId(
8+
fieldId: UUID,
9+
studentId: UUID
10+
): List<UserFormValue>
411
}

sms-core/src/main/kotlin/team/msg/sms/domain/authentication/service/impl/GetAuthenticationSectionServiceImpl.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,8 @@ class GetAuthenticationSectionServiceImpl(
1212
private val authenticationSectionPort: AuthenticationSectionPort
1313
) : GetAuthenticationSectionService {
1414
override fun getAuthenticationSectionByGroupIds(groupIds: List<UUID>): List<AuthenticationSection> =
15-
authenticationSectionPort.getAuthenticationSectionByGroupIds(groupIds)
15+
authenticationSectionPort.queryAuthenticationSectionByGroupIds(groupIds)
1616

1717
override fun getMaxCountById(sectionId: UUID): Int =
18-
authenticationSectionPort.getMaxCountById(id = sectionId) ?: throw InternalServerErrorException
18+
authenticationSectionPort.queryMaxCountById(id = sectionId) ?: throw InternalServerErrorException
1919
}

sms-core/src/main/kotlin/team/msg/sms/domain/authentication/service/impl/GetMarkingBoardServiceImpl.kt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ package team.msg.sms.domain.authentication.service.impl
33
import team.msg.sms.common.annotation.Service
44
import team.msg.sms.domain.authentication.dto.res.UserBoardPageResponseData
55
import team.msg.sms.domain.authentication.dto.res.UserBoardWithStudentInfoResponseData
6+
import team.msg.sms.domain.authentication.exception.MarkingBoardNotFoundException
7+
import team.msg.sms.domain.authentication.model.MarkingBoard
68
import team.msg.sms.domain.authentication.model.MarkingBoardType
79
import team.msg.sms.domain.authentication.service.GetMarkingBoardService
810
import team.msg.sms.domain.authentication.spi.MarkingBoardPort
@@ -12,6 +14,10 @@ import java.util.UUID
1214
class GetMarkingBoardServiceImpl(
1315
private val markingBoardPort: MarkingBoardPort
1416
) : GetMarkingBoardService {
17+
override fun getMarkingBoardById(id: UUID): MarkingBoard {
18+
return markingBoardPort.queryMarkingBoardById(id) ?: throw MarkingBoardNotFoundException
19+
}
20+
1521
override fun getMarkingBoardByStudentIds(
1622
studentIds: List<UUID>,
1723
authenticationId: UUID,
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,15 @@
11
package team.msg.sms.domain.authentication.service.impl
22

33
import team.msg.sms.common.annotation.Service
4+
import team.msg.sms.domain.authentication.model.UserFormValue
45
import team.msg.sms.domain.authentication.service.GetUserFormValueService
56
import team.msg.sms.domain.authentication.spi.UserFormValuePort
7+
import java.util.*
68

79
@Service
810
class GetUserFormValueServiceImpl(
911
private val userFormValuePort: UserFormValuePort
1012
) : GetUserFormValueService {
13+
override fun getUserFormValueListByFieldIdAndStudentId(fieldId: UUID, studentId: UUID): List<UserFormValue> =
14+
userFormValuePort.queryUserFormValueListByFieldIdAndStudentId(fieldId, studentId)
1115
}

sms-core/src/main/kotlin/team/msg/sms/domain/authentication/spi/QueryAuthenticationSectionPort.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,6 @@ import team.msg.sms.domain.authentication.model.AuthenticationSection
44
import java.util.UUID
55

66
interface QueryAuthenticationSectionPort {
7-
fun getAuthenticationSectionByGroupIds(groupIds: List<UUID>): List<AuthenticationSection>
8-
fun getMaxCountById(id: UUID): Int?
7+
fun queryAuthenticationSectionByGroupIds(groupIds: List<UUID>): List<AuthenticationSection>
8+
fun queryMaxCountById(id: UUID): Int?
99
}

sms-core/src/main/kotlin/team/msg/sms/domain/authentication/spi/QueryMarkingBoardPort.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
package team.msg.sms.domain.authentication.spi
22

33
import team.msg.sms.domain.authentication.dto.res.UserBoardPageResponseData
4+
import team.msg.sms.domain.authentication.model.MarkingBoard
45
import team.msg.sms.domain.authentication.model.MarkingBoardType
56
import java.util.UUID
67

78
interface QueryMarkingBoardPort {
9+
fun queryMarkingBoardById(id: UUID): MarkingBoard?
810
fun queryMarkingBoardByStudentIds(
911
studentIds: List<UUID>,
1012
authenticationId: UUID,
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,8 @@
11
package team.msg.sms.domain.authentication.spi
22

3+
import team.msg.sms.domain.authentication.model.UserFormValue
4+
import java.util.UUID
5+
36
interface QueryUserFormValuePort {
7+
fun queryUserFormValueListByFieldIdAndStudentId(fieldId: UUID, studentId: UUID): List<UserFormValue>
48
}

sms-core/src/main/kotlin/team/msg/sms/domain/authentication/usecase/QueryAuthenticationFormUseCase.kt

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,12 @@ class QueryAuthenticationFormUseCase(
2020
private val selectorSectionValueService: SelectorSectionValueService,
2121
private val authenticationFieldService: AuthenticationFieldService,
2222
private val authenticationAreaService: AuthenticationAreaService,
23-
private val authenticationFieldGroupService: AuthenticationFieldGroupService
23+
private val authenticationFieldGroupService: AuthenticationFieldGroupService,
24+
private val authenticationFormService: AuthenticationFormService
2425
) {
2526
@Transactional(readOnly = true)
26-
fun execute(authenticationFormId: UUID): QueryAuthenticationFormResponseData {
27+
fun execute(): QueryAuthenticationFormResponseData {
28+
val authenticationFormId = authenticationFormService.getActiveAuthenticationFormId()
2729
val files = fetchFiles(authenticationFormId)
2830
val groups = fetchAuthenticationGroups(authenticationFormId)
2931
val authenticationSections = fetchAuthenticationSections(groups)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,134 @@
1+
package team.msg.sms.domain.authentication.usecase
2+
3+
import team.msg.sms.common.annotation.UseCase
4+
import team.msg.sms.domain.authentication.dto.res.StudentAuthenticationFormResponseData
5+
import team.msg.sms.domain.authentication.model.*
6+
import team.msg.sms.domain.authentication.service.*
7+
import java.util.UUID
8+
9+
@UseCase
10+
class QueryStudentAuthenticationFormDetailUseCase(
11+
private val markingBoardService: MarkingBoardService,
12+
private val authenticationAreaService: AuthenticationAreaService,
13+
private val authenticationSectionService: AuthenticationSectionService,
14+
private val authenticationFieldGroupService: AuthenticationFieldGroupService,
15+
private val authenticationFieldService: AuthenticationFieldService,
16+
private val userFormValueService: UserFormValueService,
17+
private val selectorSectionValueService: SelectorSectionValueService
18+
) {
19+
fun execute(markingBoardId: UUID): StudentAuthenticationFormResponseData {
20+
val markingBoard = markingBoardService.getMarkingBoardById(id = markingBoardId)
21+
22+
// 채점 전 상태인 학생 폼을 조회할시 채점 중으로 상태 변경
23+
if(markingBoard.markingBoardType == MarkingBoardType.PENDING_REVIEW) {
24+
markingBoardService.save(
25+
markingBoard.copy(
26+
id = markingBoard.id,
27+
markingBoardType = MarkingBoardType.UNDER_REVIEW
28+
)
29+
)
30+
}
31+
32+
val authenticationAreas =
33+
authenticationAreaService.getGroupAuthenticationAreaByAuthenticationFormId(markingBoard.authenticationId)
34+
35+
val authenticationSections =
36+
authenticationSectionService.getAuthenticationSectionByGroupIds(authenticationAreas.map { it.id })
37+
38+
val selectorSectionValues = selectorSectionValueService.getSelectorSectionValue()
39+
40+
return StudentAuthenticationFormResponseData(
41+
markingBoardId = markingBoard.id,
42+
title = markingBoard.title,
43+
content = buildAreas(
44+
authenticationAreas,
45+
authenticationSections,
46+
selectorSectionValues,
47+
markingBoard.studentId
48+
)
49+
)
50+
}
51+
52+
private fun buildAreas(
53+
authenticationAreas: List<AuthenticationArea>,
54+
authenticationSections: List<AuthenticationSection>,
55+
selectorSectionValues: List<SelectorSectionValue>,
56+
studentId: UUID
57+
): List<StudentAuthenticationFormResponseData.Area> {
58+
return authenticationAreas.map { area ->
59+
StudentAuthenticationFormResponseData.Area(
60+
areaId = area.id,
61+
areaTitle = area.title,
62+
sections = buildSections(area.id, authenticationSections, selectorSectionValues, studentId)
63+
)
64+
}
65+
}
66+
67+
private fun buildSections(
68+
areaId: UUID,
69+
authenticationSections: List<AuthenticationSection>,
70+
selectorSectionValues: List<SelectorSectionValue>,
71+
studentId: UUID
72+
): List<StudentAuthenticationFormResponseData.Section> {
73+
return authenticationSections.filter { it.groupId == areaId }
74+
.map { section ->
75+
StudentAuthenticationFormResponseData.Section(
76+
sectionId = section.id,
77+
sectionName = section.sectionName,
78+
maxCount = section.maxCount,
79+
groups = buildGroups(section.id, selectorSectionValues, studentId)
80+
)
81+
}
82+
}
83+
84+
private fun buildGroups(
85+
sectionId: UUID,
86+
selectorSectionValues: List<SelectorSectionValue>,
87+
studentId: UUID
88+
): List<StudentAuthenticationFormResponseData.Group> {
89+
return authenticationFieldGroupService.findAuthenticationFieldGroupBySectionId(sectionId)
90+
.map { fieldGroup ->
91+
StudentAuthenticationFormResponseData.Group(
92+
groupId = fieldGroup.id,
93+
maxScore = fieldGroup.maxScore,
94+
fields = buildFieldSets(fieldGroup.id, selectorSectionValues, studentId)
95+
)
96+
}
97+
}
98+
99+
private fun buildFieldSets(
100+
groupId: UUID,
101+
selectorSectionValues: List<SelectorSectionValue>,
102+
studentId: UUID
103+
): List<StudentAuthenticationFormResponseData.FieldSet> {
104+
return authenticationFieldService.getAuthenticationFieldsByGroupId(groupId)
105+
.flatMap { authenticationField ->
106+
val userFormValues =
107+
userFormValueService.getUserFormValueListByFieldIdAndStudentId(authenticationField.id, studentId)
108+
val setIds = userFormValues.map { it.setId }.distinct()
109+
setIds.map { setId ->
110+
StudentAuthenticationFormResponseData.FieldSet(
111+
setId = setId,
112+
values = buildFields(userFormValues, setId, selectorSectionValues)
113+
)
114+
}
115+
}
116+
}
117+
118+
private fun buildFields(
119+
userFormValues: List<UserFormValue>,
120+
setId: UUID,
121+
selectorSectionValues: List<SelectorSectionValue>
122+
): List<StudentAuthenticationFormResponseData.Field> {
123+
return userFormValues.filter { it.setId == setId }
124+
.map { userFormValue ->
125+
StudentAuthenticationFormResponseData.Field(
126+
fieldId = userFormValue.authenticationFieldId,
127+
fieldType = userFormValue.fieldType,
128+
value = userFormValue.targetId?.let { targetId ->
129+
selectorSectionValues.find { it.id == targetId }?.name
130+
} ?: userFormValue.value
131+
)
132+
}
133+
}
134+
}

sms-core/src/main/kotlin/team/msg/sms/domain/authentication/usecase/SubmitUserFormDataUseCase.kt

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,17 +16,16 @@ import java.util.*
1616
@UseCase
1717
class SubmitUserFormDataUseCase(
1818
private val userFormValueService: UserFormValueService,
19-
private val authenticationSectionService: AuthenticationSectionService,
2019
private val markingBoardService: MarkingBoardService,
2120
private val studentService: StudentService
2221
) {
2322
fun execute(submitDataList: List<SubmitUserFormRequestData>, authenticationFormId: UUID) {
2423
val student = studentService.currentStudent()
2524
val userFormValues = submitDataList.flatMap { submitData ->
26-
val maxCount = authenticationSectionService.getMaxCountById(submitData.sectionId)
27-
val groupId = if (maxCount > 1) UUID.randomUUID() else null
2825

2926
submitData.objects.flatMap { submitValue ->
27+
val groupId = UUID.randomUUID()
28+
3029
submitValue.fields.map { submitFieldValue ->
3130
createUserFormValue(
3231
sectionId = submitData.sectionId,
@@ -54,7 +53,7 @@ class SubmitUserFormDataUseCase(
5453
private fun createUserFormValue(
5554
sectionId: UUID,
5655
submitData: SubmitUserFormRequestData.SubmitFieldValueRequestData,
57-
groupId: UUID?,
56+
groupId: UUID,
5857
authenticationFieldGroupId: UUID,
5958
studentId: UUID,
6059
authenticationFormId: UUID

sms-infrastructure/src/main/kotlin/team/msg/sms/global/security/SecurityConfig.kt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,8 @@ class SecurityConfig(
9595
.antMatchers(HttpMethod.GET, "/authentication/my").hasAuthority(STUDENT)
9696
.antMatchers(HttpMethod.GET, "/authentication/{uuid}").hasAuthority(STUDENT)
9797
.antMatchers(HttpMethod.GET, "/").hasAnyAuthority(STUDENT, TEACHER)
98-
.antMatchers(HttpMethod.GET, "/authentication/form/{uuid}").hasAnyAuthority(STUDENT, TEACHER)
98+
.antMatchers(HttpMethod.GET, "/authentication/form").hasAnyAuthority(STUDENT, TEACHER)
99+
.antMatchers(HttpMethod.GET, "/authentication/{uuid}/form").hasAuthority(TEACHER)
99100
.antMatchers(HttpMethod.GET, "/authentication").hasAuthority(TEACHER)
100101
.antMatchers(HttpMethod.PUT, "/authentication/{uuid}").hasAuthority(STUDENT)
101102
.antMatchers(HttpMethod.POST, "/authentication").hasAuthority(STUDENT)
@@ -118,5 +119,4 @@ class SecurityConfig(
118119

119120
return http.build()
120121
}
121-
}
122-
122+
}

sms-persistence/src/main/kotlin/team/msg/sms/persistence/authentication/AuthenticationSectionPersistenceAdapter.kt

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,11 @@ class AuthenticationSectionPersistenceAdapter(
1414
private val authenticationSectionRepositoryCustom: AuthenticationSectionRepositoryCustom,
1515
private val authenticationSectionJpaRepository: AuthenticationSectionJpaRepository
1616
) : AuthenticationSectionPort {
17-
override fun getAuthenticationSectionByGroupIds(groupIds: List<UUID>): List<AuthenticationSection> =
17+
18+
override fun queryAuthenticationSectionByGroupIds(groupIds: List<UUID>): List<AuthenticationSection> =
1819
authenticationSectionRepositoryCustom.getAuthenticationSectionByGroupIds(groupIds).map { it.toDomain() }
1920

20-
override fun getMaxCountById(id: UUID): Int? = authenticationSectionRepositoryCustom.findMaxCountById(id)
21+
override fun queryMaxCountById(id: UUID): Int? = authenticationSectionRepositoryCustom.findMaxCountById(id)
2122

2223

2324
override fun save(authenticationSection: AuthenticationSection): AuthenticationSection =

0 commit comments

Comments
 (0)