diff --git a/bitgouel-api/src/main/kotlin/team/msg/domain/auth/presentation/AuthController.kt b/bitgouel-api/src/main/kotlin/team/msg/domain/auth/presentation/AuthController.kt index 63a7f5a67..1936af73a 100644 --- a/bitgouel-api/src/main/kotlin/team/msg/domain/auth/presentation/AuthController.kt +++ b/bitgouel-api/src/main/kotlin/team/msg/domain/auth/presentation/AuthController.kt @@ -21,38 +21,44 @@ class AuthController( private val authRequestMapper: AuthRequestMapper ) { @PostMapping("/student") - fun studentSignUp(@RequestBody @Valid request: StudentSignUpWebRequest): ResponseEntity { - authService.studentSignUp(authRequestMapper.studentSignUpWebRequestToDto(request)) + fun studentSignUp(@RequestBody @Valid webRequest: StudentSignUpWebRequest): ResponseEntity { + val request = authRequestMapper.studentSignUpWebRequestToDto(webRequest) + authService.studentSignUp(request) return ResponseEntity.status(HttpStatus.CREATED).build() } @PostMapping("/teacher") - fun teacherSignUp(@RequestBody @Valid request: TeacherSignUpWebRequest): ResponseEntity { - authService.teacherSignUp(authRequestMapper.teacherSignUpWebRequestToDto(request)) + fun teacherSignUp(@RequestBody @Valid webRequest: TeacherSignUpWebRequest): ResponseEntity { + val request = authRequestMapper.teacherSignUpWebRequestToDto(webRequest) + authService.teacherSignUp(request) return ResponseEntity.status(HttpStatus.CREATED).build() } @PostMapping("/professor") - fun professorSignUp(@RequestBody @Valid request: ProfessorSignUpWebRequest): ResponseEntity { - authService.professorSignUp(authRequestMapper.professorSignUpWebRequestToDto(request)) + fun professorSignUp(@RequestBody @Valid webRequest: ProfessorSignUpWebRequest): ResponseEntity { + val request = authRequestMapper.professorSignUpWebRequestToDto(webRequest) + authService.professorSignUp(request) return ResponseEntity.status(HttpStatus.CREATED).build() } @PostMapping("/government") - fun governmentSignUp(@RequestBody @Valid request: GovernmentSignUpWebRequest): ResponseEntity { - authService.governmentSignUp(authRequestMapper.governmentSignUpWebRequestToDto(request)) + fun governmentSignUp(@RequestBody @Valid webRequest: GovernmentSignUpWebRequest): ResponseEntity { + val request = authRequestMapper.governmentSignUpWebRequestToDto(webRequest) + authService.governmentSignUp(request) return ResponseEntity.status(HttpStatus.CREATED).build() } @PostMapping("/company-instructor") - fun companyInstructorSignUp(@RequestBody @Valid request: CompanyInstructorSignUpWebRequest): ResponseEntity { - authService.companyInstructorSignUp(authRequestMapper.companyInstructorSignUpWebRequestToDto(request)) + fun companyInstructorSignUp(@RequestBody @Valid webRequest: CompanyInstructorSignUpWebRequest): ResponseEntity { + val request = authRequestMapper.companyInstructorSignUpWebRequestToDto(webRequest) + authService.companyInstructorSignUp(request) return ResponseEntity.status(HttpStatus.CREATED).build() } @PostMapping("/login") - fun login(@RequestBody @Valid request: LoginWebRequest): ResponseEntity { - val response = authService.login(authRequestMapper.loginWebRequestToDto(request)) + fun login(@RequestBody @Valid webRequest: LoginWebRequest): ResponseEntity { + val request = authRequestMapper.loginWebRequestToDto(webRequest) + val response = authService.login(request) return ResponseEntity.ok(response) } diff --git a/bitgouel-api/src/main/kotlin/team/msg/domain/lecture/exception/InvalidLectureTypeException.kt b/bitgouel-api/src/main/kotlin/team/msg/domain/lecture/exception/InvalidLectureTypeException.kt new file mode 100644 index 000000000..6a50aee16 --- /dev/null +++ b/bitgouel-api/src/main/kotlin/team/msg/domain/lecture/exception/InvalidLectureTypeException.kt @@ -0,0 +1,8 @@ +package team.msg.domain.lecture.exception + +import team.msg.domain.lecture.exception.constant.LectureErrorCode +import team.msg.global.error.exception.BitgouelException + +class InvalidLectureTypeException( + message: String +) : BitgouelException(message, LectureErrorCode.INVALID_LECTURE_TYPE.status) \ No newline at end of file diff --git a/bitgouel-api/src/main/kotlin/team/msg/domain/lecture/exception/constant/LectureErrorCode.kt b/bitgouel-api/src/main/kotlin/team/msg/domain/lecture/exception/constant/LectureErrorCode.kt new file mode 100644 index 000000000..3e9753ba1 --- /dev/null +++ b/bitgouel-api/src/main/kotlin/team/msg/domain/lecture/exception/constant/LectureErrorCode.kt @@ -0,0 +1,8 @@ +package team.msg.domain.lecture.exception.constant + +enum class LectureErrorCode( + val message: String, + val status: Int +){ + INVALID_LECTURE_TYPE("유효하지 않은 강의 구분입니다.", 400) +} \ No newline at end of file diff --git a/bitgouel-api/src/main/kotlin/team/msg/domain/lecture/mapper/LectureRequestMapper.kt b/bitgouel-api/src/main/kotlin/team/msg/domain/lecture/mapper/LectureRequestMapper.kt new file mode 100644 index 000000000..31dede59f --- /dev/null +++ b/bitgouel-api/src/main/kotlin/team/msg/domain/lecture/mapper/LectureRequestMapper.kt @@ -0,0 +1,8 @@ +package team.msg.domain.lecture.mapper + +import team.msg.domain.lecture.presentation.data.request.CreateLectureRequest +import team.msg.domain.lecture.presentation.data.web.CreateLectureWebRequest + +interface LectureRequestMapper { + fun createLectureWebRequestToDto(request: CreateLectureWebRequest) : CreateLectureRequest +} \ No newline at end of file diff --git a/bitgouel-api/src/main/kotlin/team/msg/domain/lecture/mapper/LectureRequestMapperImpl.kt b/bitgouel-api/src/main/kotlin/team/msg/domain/lecture/mapper/LectureRequestMapperImpl.kt new file mode 100644 index 000000000..2a1818fb0 --- /dev/null +++ b/bitgouel-api/src/main/kotlin/team/msg/domain/lecture/mapper/LectureRequestMapperImpl.kt @@ -0,0 +1,23 @@ +package team.msg.domain.lecture.mapper + +import org.springframework.stereotype.Component +import team.msg.domain.lecture.presentation.data.request.CreateLectureRequest +import team.msg.domain.lecture.presentation.data.web.CreateLectureWebRequest + +@Component +class LectureRequestMapperImpl : LectureRequestMapper{ + /** + * Lecture 개설 Web Request 를 애플리케이션 영역에서 사용될 Dto 로 매핑합니다. + * @param CreateLectureWebRequest + */ + override fun createLectureWebRequestToDto(webRequest: CreateLectureWebRequest) = CreateLectureRequest( + name = webRequest.name, + content = webRequest.content, + startDate = webRequest.startDate, + endDate = webRequest.endDate, + completeDate = webRequest.completeDate, + lectureType = webRequest.lectureType, + credit = webRequest.credit, + maxRegisteredUser = webRequest.maxRegisteredUser + ) +} \ No newline at end of file diff --git a/bitgouel-api/src/main/kotlin/team/msg/domain/lecture/presentation/LectureController.kt b/bitgouel-api/src/main/kotlin/team/msg/domain/lecture/presentation/LectureController.kt new file mode 100644 index 000000000..bc19f9bd1 --- /dev/null +++ b/bitgouel-api/src/main/kotlin/team/msg/domain/lecture/presentation/LectureController.kt @@ -0,0 +1,26 @@ +package team.msg.domain.lecture.presentation + +import javax.validation.Valid +import org.springframework.http.HttpStatus +import org.springframework.http.ResponseEntity +import org.springframework.web.bind.annotation.PostMapping +import org.springframework.web.bind.annotation.RequestBody +import org.springframework.web.bind.annotation.RequestMapping +import org.springframework.web.bind.annotation.RestController +import team.msg.domain.lecture.mapper.LectureRequestMapper +import team.msg.domain.lecture.presentation.data.web.CreateLectureWebRequest +import team.msg.domain.lecture.service.LectureService + +@RestController +@RequestMapping("/lecture") +class LectureController( + private val lectureRequestMapper: LectureRequestMapper, + private val lectureService: LectureService +) { + @PostMapping + fun createLecture(@Valid @RequestBody webRequest: CreateLectureWebRequest): ResponseEntity { + val request = lectureRequestMapper.createLectureWebRequestToDto(webRequest) + lectureService.createLecture(request) + return ResponseEntity.status(HttpStatus.CREATED).build() + } +} \ No newline at end of file diff --git a/bitgouel-api/src/main/kotlin/team/msg/domain/lecture/presentation/data/request/CreateLectureRequest.kt b/bitgouel-api/src/main/kotlin/team/msg/domain/lecture/presentation/data/request/CreateLectureRequest.kt new file mode 100644 index 000000000..4f7459af7 --- /dev/null +++ b/bitgouel-api/src/main/kotlin/team/msg/domain/lecture/presentation/data/request/CreateLectureRequest.kt @@ -0,0 +1,15 @@ +package team.msg.domain.lecture.presentation.data.request + +import team.msg.domain.lecture.enum.LectureType +import java.time.LocalDateTime + +data class CreateLectureRequest ( + val name: String, + val content: String, + val startDate: LocalDateTime, + val endDate: LocalDateTime, + val completeDate: LocalDateTime, + val lectureType: LectureType, + val credit: Int, + val maxRegisteredUser: Int +) \ No newline at end of file diff --git a/bitgouel-api/src/main/kotlin/team/msg/domain/lecture/presentation/data/web/CreateLectureWebRequest.kt b/bitgouel-api/src/main/kotlin/team/msg/domain/lecture/presentation/data/web/CreateLectureWebRequest.kt new file mode 100644 index 000000000..de30963c9 --- /dev/null +++ b/bitgouel-api/src/main/kotlin/team/msg/domain/lecture/presentation/data/web/CreateLectureWebRequest.kt @@ -0,0 +1,47 @@ +package team.msg.domain.lecture.presentation.data.web + +import com.fasterxml.jackson.annotation.JsonFormat +import javax.persistence.EnumType +import javax.persistence.Enumerated +import javax.validation.constraints.Future +import javax.validation.constraints.FutureOrPresent +import javax.validation.constraints.Min +import javax.validation.constraints.NotBlank +import javax.validation.constraints.NotNull +import team.msg.domain.lecture.enum.LectureType +import java.time.LocalDateTime + +data class CreateLectureWebRequest( + @field:NotBlank + val name: String, + + @field:NotBlank + val content: String, + + @field:NotNull + @FutureOrPresent + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:s") + val startDate: LocalDateTime, + + @field:NotNull + @Future + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:s") + val endDate: LocalDateTime, + + @field:NotNull + @Future + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:s") + val completeDate: LocalDateTime, + + @field:NotNull + @Enumerated(EnumType.STRING) + val lectureType: LectureType, + + @field:NotNull + @field:Min(0) + val credit: Int, + + @field:NotNull + @field:Min(1) + val maxRegisteredUser: Int +) diff --git a/bitgouel-api/src/main/kotlin/team/msg/domain/lecture/service/LectureService.kt b/bitgouel-api/src/main/kotlin/team/msg/domain/lecture/service/LectureService.kt new file mode 100644 index 000000000..53adb5ffe --- /dev/null +++ b/bitgouel-api/src/main/kotlin/team/msg/domain/lecture/service/LectureService.kt @@ -0,0 +1,7 @@ +package team.msg.domain.lecture.service + +import team.msg.domain.lecture.presentation.data.request.CreateLectureRequest + +interface LectureService { + fun createLecture(request: CreateLectureRequest) +} \ No newline at end of file diff --git a/bitgouel-api/src/main/kotlin/team/msg/domain/lecture/service/LectureServiceImpl.kt b/bitgouel-api/src/main/kotlin/team/msg/domain/lecture/service/LectureServiceImpl.kt new file mode 100644 index 000000000..e12313f39 --- /dev/null +++ b/bitgouel-api/src/main/kotlin/team/msg/domain/lecture/service/LectureServiceImpl.kt @@ -0,0 +1,47 @@ +package team.msg.domain.lecture.service + +import org.springframework.stereotype.Service +import team.msg.common.util.UserUtil +import team.msg.domain.lecture.enum.LectureType +import team.msg.domain.lecture.exception.InvalidLectureTypeException +import team.msg.domain.lecture.model.Lecture +import team.msg.domain.lecture.presentation.data.request.CreateLectureRequest +import team.msg.domain.lecture.repository.LectureRepository +import java.util.* + +@Service +class LectureServiceImpl( + private val lectureRepository: LectureRepository, + private val userUtil: UserUtil +) : LectureService{ + + /** + * 강의 개설을 처리하는 비지니스 로직입니다. + * @param CreateLectureRequest + */ + override fun createLecture(request: CreateLectureRequest) { + val user = userUtil.queryCurrentUser() + + val credit = when(request.lectureType){ + LectureType.MUTUAL_CREDIT_RECOGNITION_PROGRAM -> request.credit + LectureType.UNIVERSITY_EXPLORATION_PROGRAM -> 0 + else -> throw InvalidLectureTypeException("유효하지 않은 강의 구분입니다. info : [ type = ${request.lectureType} ]") + } + + val lecture = Lecture( + id = UUID.randomUUID(), + user = user, + name = request.name, + startDate = request.startDate, + endDate = request.endDate, + completeDate = request.completeDate, + content = request.content, + lectureType = request.lectureType, + credit = credit, + instructor = user.name, + maxRegisteredUser = request.maxRegisteredUser + ) + + lectureRepository.save(lecture) + } +} \ No newline at end of file diff --git a/bitgouel-api/src/main/kotlin/team/msg/domain/student/presentation/StudentActivityController.kt b/bitgouel-api/src/main/kotlin/team/msg/domain/student/presentation/StudentActivityController.kt index e24ad56be..790f1c647 100644 --- a/bitgouel-api/src/main/kotlin/team/msg/domain/student/presentation/StudentActivityController.kt +++ b/bitgouel-api/src/main/kotlin/team/msg/domain/student/presentation/StudentActivityController.kt @@ -18,8 +18,9 @@ class StudentActivityController( private val studentActivityMapper: StudentActivityMapper ) { @PostMapping - fun createStudentActivity(@RequestBody @Valid request: CreateStudentActivityWebRequest): ResponseEntity { - studentActivityService.createStudentActivity(studentActivityMapper.createStudentActivityWebRequestToDto(request)) + fun createStudentActivity(@RequestBody @Valid webRequest: CreateStudentActivityWebRequest): ResponseEntity { + val request = studentActivityMapper.createStudentActivityWebRequestToDto(webRequest) + studentActivityService.createStudentActivity(request) return ResponseEntity.status(HttpStatus.CREATED).build() } } \ No newline at end of file diff --git a/bitgouel-api/src/main/kotlin/team/msg/global/security/SecurityConfig.kt b/bitgouel-api/src/main/kotlin/team/msg/global/security/SecurityConfig.kt index 7cce2b298..a7175dc3e 100644 --- a/bitgouel-api/src/main/kotlin/team/msg/global/security/SecurityConfig.kt +++ b/bitgouel-api/src/main/kotlin/team/msg/global/security/SecurityConfig.kt @@ -19,8 +19,14 @@ class SecurityConfig( private val jwtTokenParser: JwtTokenParser ) { companion object { + const val USER = "USER" const val ADMIN = "ADMIN" const val STUDENT = "STUDENT" + const val TEACHER = "TEACHER" + const val BBOZZAK = "BBOZZAK" + const val PROFESSOR = "PROFESSOR" + const val COMPANY_INSTRUCTOR = "COMPANY_INSTRUCTOR" + const val GOVERNMENT = "GOVERNMENT" } @Bean @@ -50,6 +56,9 @@ class SecurityConfig( // activity .mvcMatchers(HttpMethod.POST, "/activity").hasRole(STUDENT) + // lecture + .mvcMatchers(HttpMethod.POST, "/lecture").hasAnyRole(PROFESSOR, COMPANY_INSTRUCTOR, GOVERNMENT) + .anyRequest().authenticated() .and()