Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
2 changes: 1 addition & 1 deletion systems/application/application-adapter-in/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -17,5 +17,5 @@ kt_jvm_test(
javac_opts = "//:javac_options",
kotlinc_opts = "//:kotlinc_options",
test_class = "hs.kr.entrydsm.application.adapterin.ApplicationAdapterInModuleTest",
deps = MODULE_DEPS + TEST_DEPS,
deps = [":main"] + MODULE_DEPS + TEST_DEPS,
)
6 changes: 5 additions & 1 deletion systems/application/application-adapter-in/deps.bzl
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
KOTLIN_DEPS = []
KOTLIN_DEPS = [
"@maven//:org_springframework_boot_spring_boot_starter_web",
"//systems/application/application-application:main",
"//systems/application/application-domain:main",
]
Comment thread
wlyoon921 marked this conversation as resolved.

TEST_DEPS = [
"@maven//:junit_junit",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,210 @@
package hs.kr.entrydsm.application.adapterin.web

import hs.kr.entrydsm.application.adapterin.web.config.LandingScheduleProperties
import hs.kr.entrydsm.application.adapterin.web.dto.common.ApiResponse
import hs.kr.entrydsm.application.adapterin.web.dto.common.toResponse
import hs.kr.entrydsm.application.adapterin.web.dto.request.UpdateFamilyRequest
import hs.kr.entrydsm.application.adapterin.web.dto.request.UpdateIntroductionRequest
import hs.kr.entrydsm.application.adapterin.web.dto.request.UpdateMiddleSchoolRequest
import hs.kr.entrydsm.application.adapterin.web.dto.request.UpdatePersonalRequest
import hs.kr.entrydsm.application.adapterin.web.dto.request.UpdateStudyPlanRequest
import hs.kr.entrydsm.application.adapterin.web.dto.request.UpdateTypeRequest
import hs.kr.entrydsm.application.adapterin.web.dto.response.CreateApplicantResponse
import hs.kr.entrydsm.application.adapterin.web.dto.response.LandingResponse
import hs.kr.entrydsm.application.application.port.`in`.ApplicationPort
import hs.kr.entrydsm.application.application.port.`in`.command.CreateApplicantCommand
import hs.kr.entrydsm.application.application.port.`in`.command.SubmitApplicationCommand
import hs.kr.entrydsm.application.application.port.`in`.command.UpdateFamilyCommand
import hs.kr.entrydsm.application.application.port.`in`.command.UpdateIntroductionCommand
import hs.kr.entrydsm.application.application.port.`in`.command.UpdateMiddleSchoolCommand
import hs.kr.entrydsm.application.application.port.`in`.command.UpdatePersonalCommand
import hs.kr.entrydsm.application.application.port.`in`.command.UpdateStudyPlanCommand
import hs.kr.entrydsm.application.application.port.`in`.command.UpdateTypeCommand
import hs.kr.entrydsm.application.domain.enum.GuardianRelation
import hs.kr.entrydsm.application.domain.enum.SpecialAdmissionType
import java.time.LocalDate
import java.time.YearMonth
import org.springframework.http.HttpStatus
import org.springframework.web.bind.annotation.GetMapping
import org.springframework.web.bind.annotation.PatchMapping
import org.springframework.web.bind.annotation.PathVariable
import org.springframework.web.bind.annotation.PostMapping
import org.springframework.web.bind.annotation.RequestBody
import org.springframework.web.bind.annotation.RequestHeader
import org.springframework.web.bind.annotation.RequestMapping
import org.springframework.web.bind.annotation.ResponseStatus
import org.springframework.web.bind.annotation.RestController

@RestController
@RequestMapping("/api/application/v11/applicants")
class ApplicationController(
private val applicationPort: ApplicationPort,
private val landingScheduleProperties: LandingScheduleProperties,
) {
@GetMapping("/landing")
fun getLanding(
@RequestHeader(USER_ID_HEADER, required = false) userId: Long? = null,
): ApiResponse<LandingResponse> {
val result = applicationPort.getLanding(userId)
return ApiResponse(data = result.toResponse(landingScheduleProperties))
}

@PostMapping
@ResponseStatus(HttpStatus.CREATED)
fun createApplicant(
@RequestHeader(USER_ID_HEADER, required = false) userId: Long? = null,
): ApiResponse<CreateApplicantResponse> {
val result = applicationPort.createApplicant(
CreateApplicantCommand(
userId = userId,
),
)
return ApiResponse(data = result.toResponse())
}

@PatchMapping("/{id}/type")
fun updateType(
@RequestHeader(USER_ID_HEADER, required = false) userId: Long? = null,
@PathVariable id: Long,
@RequestBody request: UpdateTypeRequest,
): ApiResponse<Unit> {
applicationPort.updateType(
UpdateTypeCommand(
userId = userId,
applicantId = id,
admissionType = request.admissionType,
region = request.region,
graduationType = request.graduationType,
graduationDate = request.graduationDate?.let(YearMonth::parse),
),
)
return ApiResponse(data = null)
}

@PatchMapping("/{id}/personal")
fun updatePersonal(
@RequestHeader(USER_ID_HEADER, required = false) userId: Long? = null,
@PathVariable id: Long,
@RequestBody request: UpdatePersonalRequest,
): ApiResponse<Unit> {
applicationPort.updatePersonal(
UpdatePersonalCommand(
userId = userId,
applicantId = id,
photoFileId = request.photoFileId,
name = request.name,
phoneNumber = request.phoneNumber,
gender = request.gender,
birthdate = parseDate(request.birthdate),
specialAdmissionType = request.specialAdmissionType ?: SpecialAdmissionType.NONE,
),
)
return ApiResponse(data = null)
}

@PatchMapping("/{id}/family")
fun updateFamily(
@RequestHeader(USER_ID_HEADER, required = false) userId: Long? = null,
@PathVariable id: Long,
@RequestBody request: UpdateFamilyRequest,
): ApiResponse<Unit> {
applicationPort.updateFamily(
UpdateFamilyCommand(
userId = userId,
applicantId = id,
guardianName = request.guardianName,
guardianPhoneNumber = request.guardianPhoneNumber,
guardianGender = request.guardianGender,
guardianRelation = request.guardianRelation.toGuardianRelation(),
zipCode = request.address.zipCode,
addressBase = request.address.addressBase,
addressDetail = request.address.addressDetail,
),
)
return ApiResponse(data = null)
}

@PatchMapping("/{id}/middle-school")
fun updateMiddleSchool(
@RequestHeader(USER_ID_HEADER, required = false) userId: Long? = null,
@PathVariable id: Long,
@RequestBody request: UpdateMiddleSchoolRequest,
): ApiResponse<Unit> {
applicationPort.updateMiddleSchool(
UpdateMiddleSchoolCommand(
userId = userId,
applicantId = id,
schoolName = request.schoolName,
studentNumber = request.studentNumber,
schoolPhone = request.schoolPhone,
teacherName = request.teacherName,
),
)
return ApiResponse(data = null)
}

@PatchMapping("/{id}/self-introduction")
fun updateIntroduction(
@RequestHeader(USER_ID_HEADER, required = false) userId: Long? = null,
@PathVariable id: Long,
@RequestBody request: UpdateIntroductionRequest,
): ApiResponse<Unit> {
applicationPort.updateIntroduction(
UpdateIntroductionCommand(
userId = userId,
applicantId = id,
introduction = request.introduction,
),
)
return ApiResponse(data = null)
}

@PatchMapping("/{id}/study-plan")
fun updateStudyPlan(
@RequestHeader(USER_ID_HEADER, required = false) userId: Long? = null,
@PathVariable id: Long,
@RequestBody request: UpdateStudyPlanRequest,
): ApiResponse<Unit> {
applicationPort.updateStudyPlan(
UpdateStudyPlanCommand(
userId = userId,
applicantId = id,
studyPlan = request.studyPlan,
),
)
return ApiResponse(data = null)
}

@PatchMapping
fun submit(
@RequestHeader(USER_ID_HEADER, required = false) userId: Long? = null,
): ApiResponse<Unit> {
applicationPort.submit(
SubmitApplicationCommand(
userId = userId,
),
)
return ApiResponse(data = null)
}
Comment thread
wlyoon921 marked this conversation as resolved.

private fun parseDate(value: String): LocalDate {
return if (value.length == 7) {
YearMonth.parse(value).atDay(1)
} else {
LocalDate.parse(value)
}
}

private fun String.toGuardianRelation(): GuardianRelation {
return when (uppercase()) {
"FATHER", "FATHER_RELATION" -> GuardianRelation.FATHER
"MOTHER", "MOTHER_RELATION" -> GuardianRelation.MOTHER
"OTHER" -> GuardianRelation.OTHER
else -> throw IllegalArgumentException("guardianRelation must be FATHER, MOTHER, or OTHER")
}
}

private companion object {
const val USER_ID_HEADER = "user-id"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
package hs.kr.entrydsm.application.adapterin.web

import hs.kr.entrydsm.application.adapterin.web.dto.common.ApiResponse
import hs.kr.entrydsm.application.adapterin.web.dto.common.toResponse
import hs.kr.entrydsm.application.adapterin.web.dto.request.SaveAcademicRecordRequest
import hs.kr.entrydsm.application.adapterin.web.dto.request.SaveCertificatesRequest
import hs.kr.entrydsm.application.adapterin.web.dto.request.SaveGedScoresRequest
import hs.kr.entrydsm.application.adapterin.web.dto.request.SaveSubjectGradesRequest
import hs.kr.entrydsm.application.adapterin.web.dto.response.AcademicRecordResponse
import hs.kr.entrydsm.application.application.port.`in`.EvaluationPort
import hs.kr.entrydsm.application.application.port.`in`.command.CalculateEvaluationCommand
import hs.kr.entrydsm.application.application.port.`in`.command.SaveAcademicRecordCommand
import hs.kr.entrydsm.application.application.port.`in`.command.SaveCertificatesCommand
import hs.kr.entrydsm.application.application.port.`in`.command.SaveGedScoresCommand
import hs.kr.entrydsm.application.application.port.`in`.command.SaveSubjectGradesCommand
import hs.kr.entrydsm.application.domain.enum.SchoolSemester
import hs.kr.entrydsm.application.domain.model.GedScores
import org.springframework.web.bind.annotation.PostMapping
import org.springframework.web.bind.annotation.RequestBody
import org.springframework.web.bind.annotation.RequestHeader
import org.springframework.web.bind.annotation.RequestMapping
import org.springframework.web.bind.annotation.RestController

@RestController
@RequestMapping("/api/evaluation/v11/evaluations")
class EvaluationController(
private val evaluationPort: EvaluationPort,
) {
@PostMapping("/grades/expected")
fun saveExpectedGrades(
@RequestHeader(USER_ID_HEADER, required = false) userId: Long? = null,
@RequestBody request: SaveSubjectGradesRequest,
): ApiResponse<Unit> {
saveSubjectGrades(userId, request)
return ApiResponse(data = null)
}

@PostMapping("/grades/graduated")
fun saveGraduatedGrades(
@RequestHeader(USER_ID_HEADER, required = false) userId: Long? = null,
@RequestBody request: SaveSubjectGradesRequest,
): ApiResponse<Unit> {
saveSubjectGrades(userId, request)
return ApiResponse(data = null)
}

@PostMapping("/ged-scores")
fun saveGedScores(
@RequestHeader(USER_ID_HEADER, required = false) userId: Long? = null,
@RequestBody request: SaveGedScoresRequest,
): ApiResponse<Unit> {
evaluationPort.saveGedScores(
SaveGedScoresCommand(
userId = userId,
gedScores = GedScores(
koreanScore = request.koreanScore,
mathScore = request.mathScore,
englishScore = request.englishScore,
scienceScore = request.scienceScore,
societyScore = request.societyScore,
technologyScore = request.technologyScore,
historyScore = request.historyScore,
),
),
)
return ApiResponse(data = null)
}

@PostMapping("/academic-records")
fun saveAcademicRecords(
@RequestHeader(USER_ID_HEADER, required = false) userId: Long? = null,
@RequestBody request: SaveAcademicRecordRequest,
): ApiResponse<AcademicRecordResponse> {
val result = evaluationPort.saveAcademicRecord(
SaveAcademicRecordCommand(
userId = userId,
absentCount = request.absentCount,
earlyLeaveCount = request.earlyLeaveCount,
lateCount = request.lateCount,
classAbsenceCount = request.classAbsenceCount,
volunteerTime = request.volunteerTime,
),
)
return ApiResponse(data = result.toResponse())
}

@PostMapping("/certificates")
fun saveCertificates(
@RequestHeader(USER_ID_HEADER, required = false) userId: Long? = null,
@RequestBody request: SaveCertificatesRequest,
): ApiResponse<Unit> {
evaluationPort.saveCertificates(
SaveCertificatesCommand(
userId = userId,
isDsmAlgorithmAwarded = request.isDsmAlgorithmAwarded,
isProgrammingCertified = request.isProgrammingCertified,
),
)
return ApiResponse(data = null)
}

@PostMapping("/result")
fun getResult(
@RequestHeader(USER_ID_HEADER, required = false) userId: Long? = null,
): ApiResponse<Unit> {
evaluationPort.calculateResult(
CalculateEvaluationCommand(
userId = userId,
),
)
return ApiResponse(data = null)
}

private fun saveSubjectGrades(
userId: Long?,
request: SaveSubjectGradesRequest,
) {
evaluationPort.saveSubjectGrades(
SaveSubjectGradesCommand(
userId = userId,
schoolSemester = request.schoolSemester.toSchoolSemester(),
subjectGrades = request.subjects.toDomain(),
),
)
}

private companion object {
const val USER_ID_HEADER = "user-id"
}
}

private fun String.toSchoolSemester(): SchoolSemester {
return when (this) {
"2-1" -> SchoolSemester.SECOND_GRADE_FIRST_SEMESTER
"2-2" -> SchoolSemester.SECOND_GRADE_SECOND_SEMESTER
"3-1" -> SchoolSemester.THIRD_GRADE_FIRST_SEMESTER
"3-2" -> SchoolSemester.THIRD_GRADE_SECOND_SEMESTER
else -> throw IllegalArgumentException("schoolSemester must be one of 2-1, 2-2, 3-1, 3-2")
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package hs.kr.entrydsm.application.adapterin.web.config

import java.time.LocalDateTime
import org.springframework.beans.factory.annotation.Value
import org.springframework.stereotype.Component

@Component
class LandingScheduleProperties(
@Value("\${entrydsm.application.schedule.application-start-at}")
val applicationStartAt: LocalDateTime,

@Value("\${entrydsm.application.schedule.application-end-at}")
val applicationEndAt: LocalDateTime,

@Value("\${entrydsm.application.schedule.result-announced-at}")
val resultAnnouncedAt: LocalDateTime,
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package hs.kr.entrydsm.application.adapterin.web.dto.common

data class ApiResponse<T>(
val success: Boolean = true,
val data: T?,
val error: ErrorDetail? = null,
)
Loading
Loading