Skip to content

Commit

Permalink
merge: (#546) 외출 유형 생성 API
Browse files Browse the repository at this point in the history
  • Loading branch information
alsdl0629 authored Feb 14, 2024
2 parents d56737d + 41679e4 commit 3db916f
Show file tree
Hide file tree
Showing 21 changed files with 318 additions and 193 deletions.
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
package team.aliens.dms.domain.outing.dto

import java.time.LocalDate
import java.time.LocalTime
import java.util.UUID

data class ApplyOutingRequest(
val outAt: LocalDate,
val outingTime: LocalTime,
val arrivalTime: LocalTime,
val destination: String,
val outingTypeTitle: String,
val reason: String,
val companionIds: List<UUID>?,
)
package team.aliens.dms.domain.outing.dto

import java.time.LocalDate
import java.time.LocalTime
import java.util.UUID

data class ApplyOutingRequest(
val outAt: LocalDate,
val outingTime: LocalTime,
val arrivalTime: LocalTime,
val destination: String,
val outingTypeTitle: String,
val reason: String,
val companionIds: List<UUID>?
)
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package team.aliens.dms.domain.outing.dto

import java.util.UUID

data class ApplyOutingResponse(
val outingApplicationId: UUID
)
package team.aliens.dms.domain.outing.dto

import java.util.UUID

data class ApplyOutingResponse(
val outingApplicationId: UUID
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package team.aliens.dms.domain.outing.dto

data class CreateOutingTypeRequest(
val title: String
)
Original file line number Diff line number Diff line change
@@ -1,22 +1,23 @@
package team.aliens.dms.domain.outing.exception

import team.aliens.dms.common.error.ErrorProperty
import team.aliens.dms.common.error.ErrorStatus

enum class OutingErrorCode(
private val status: Int,
private val message: String,
private val sequence: Int
) : ErrorProperty {

OUTING_AVAILABLE_TIME_MISMATCH(ErrorStatus.FORBIDDEN, "Outing Available Time Mismatch", 1),

OUTING_APPLICATION_NOT_FOUND(ErrorStatus.NOT_FOUND, "Outing Not Found", 1),

OUTING_APPLICATION_ALREADY_EXISTS(ErrorStatus.CONFLICT, "Outing Application Already Exists", 1),
;

override fun status(): Int = status
override fun message(): String = message
override fun code(): String = "OUTING-$status-$sequence"
}
package team.aliens.dms.domain.outing.exception

import team.aliens.dms.common.error.ErrorProperty
import team.aliens.dms.common.error.ErrorStatus

enum class OutingErrorCode(
private val status: Int,
private val message: String,
private val sequence: Int
) : ErrorProperty {

OUTING_AVAILABLE_TIME_MISMATCH(ErrorStatus.FORBIDDEN, "Outing Available Time Mismatch", 1),

OUTING_APPLICATION_NOT_FOUND(ErrorStatus.NOT_FOUND, "Outing Not Found", 1),

OUTING_APPLICATION_ALREADY_EXISTS(ErrorStatus.CONFLICT, "Outing Application Already Exists", 1),
OUTING_TYPE_ALREADY_EXISTS(ErrorStatus.CONFLICT, "Outing Type Already Exists", 2)
;

override fun status(): Int = status
override fun message(): String = message
override fun code(): String = "OUTING-$status-$sequence"
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,7 @@ object OutingApplicationNotFoundException : DmsException(
object OutingAvailableTimeMismatchException : DmsException(
OutingErrorCode.OUTING_AVAILABLE_TIME_MISMATCH
)

object OutingTypeAlreadyExistsException : DmsException(
OutingErrorCode.OUTING_TYPE_ALREADY_EXISTS
)
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package team.aliens.dms.domain.outing.service

import team.aliens.dms.domain.outing.model.OutingType
import java.time.LocalDate
import java.time.LocalTime
import java.util.UUID
Expand All @@ -12,4 +13,6 @@ interface CheckOutingService {
outingTime: LocalTime,
arrivalTime: LocalTime
)

fun checkOutingTypeExists(outingType: OutingType)
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,11 @@ package team.aliens.dms.domain.outing.service
import team.aliens.dms.common.annotation.Service
import team.aliens.dms.domain.outing.exception.OutingApplicationAlreadyExistsException
import team.aliens.dms.domain.outing.exception.OutingAvailableTimeMismatchException
import team.aliens.dms.domain.outing.exception.OutingTypeAlreadyExistsException
import team.aliens.dms.domain.outing.model.OutingType
import team.aliens.dms.domain.outing.spi.QueryOutingApplicationPort
import team.aliens.dms.domain.outing.spi.QueryOutingAvailableTimePort
import team.aliens.dms.domain.outing.spi.QueryOutingTypePort
import java.time.LocalDate
import java.time.LocalTime
import java.util.UUID
Expand All @@ -13,6 +16,7 @@ import java.util.UUID
class CheckOutingServiceImpl(
private val queryOutingApplicationPort: QueryOutingApplicationPort,
private val queryOutingAvailableTimePort: QueryOutingAvailableTimePort,
private val queryOutingTypePort: QueryOutingTypePort
) : CheckOutingService {

override fun checkOutingApplicationAvailable(
Expand Down Expand Up @@ -40,4 +44,10 @@ class CheckOutingServiceImpl(
throw OutingApplicationAlreadyExistsException
}
}

override fun checkOutingTypeExists(outingType: OutingType) {
if (queryOutingTypePort.existsOutingType(outingType)) {
throw OutingTypeAlreadyExistsException
}
}
}
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
package team.aliens.dms.domain.outing.service

import team.aliens.dms.domain.outing.model.OutingApplication
import team.aliens.dms.domain.outing.model.OutingType

interface CommandOutingService {

fun apply(outingApplication: OutingApplication): OutingApplication
fun saveOutingApplication(outingApplication: OutingApplication): OutingApplication

fun saveOutingType(outingType: OutingType): OutingType
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,30 +3,39 @@ package team.aliens.dms.domain.outing.service
import team.aliens.dms.common.annotation.Service
import team.aliens.dms.domain.outing.model.OutingApplication
import team.aliens.dms.domain.outing.model.OutingCompanion
import team.aliens.dms.domain.outing.model.OutingType
import team.aliens.dms.domain.outing.spi.CommandOutingApplicationPort
import team.aliens.dms.domain.outing.spi.CommandOutingCompanionPort
import team.aliens.dms.domain.outing.spi.CommandOutingTypePort

@Service
class CommandOutingServiceImpl(
private val commandOutingApplicationPort: CommandOutingApplicationPort,
private val commandOutingCompanionPort: CommandOutingCompanionPort
private val commandOutingCompanionPort: CommandOutingCompanionPort,
private val commandOutingTypePort: CommandOutingTypePort,
) : CommandOutingService {

override fun apply(outingApplication: OutingApplication): OutingApplication {
override fun saveOutingApplication(outingApplication: OutingApplication): OutingApplication {
val savedOutingApplication = commandOutingApplicationPort.saveOutingApplication(outingApplication)
saveAllOutingCompanions(savedOutingApplication)

return savedOutingApplication
}

private fun saveAllOutingCompanions(outingApplication: OutingApplication) {
val companionIds = outingApplication.companionIds
if (!companionIds.isNullOrEmpty()) {
val outingCompanions = companionIds.map {
OutingCompanion(
outingApplicationId = savedOutingApplication.id,
outingApplicationId = outingApplication.id,
studentId = it
)
}

commandOutingCompanionPort.saveAllOutingCompanions(outingCompanions)
}

return savedOutingApplication
}

override fun saveOutingType(outingType: OutingType): OutingType =
commandOutingTypePort.saveOutingType(outingType)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package team.aliens.dms.domain.outing.spi

import team.aliens.dms.domain.outing.model.OutingType

interface CommandOutingTypePort {

fun saveOutingType(outingType: OutingType): OutingType
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package team.aliens.dms.domain.outing.spi

interface OutingTypePort :
QueryOutingTypePort,
CommandOutingTypePort
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package team.aliens.dms.domain.outing.spi

import team.aliens.dms.domain.outing.model.OutingType

interface QueryOutingTypePort {

fun existsOutingType(outingType: OutingType): Boolean
}
Original file line number Diff line number Diff line change
@@ -1,48 +1,48 @@
package team.aliens.dms.domain.outing.usecase

import team.aliens.dms.common.annotation.UseCase
import team.aliens.dms.common.service.security.SecurityService
import team.aliens.dms.domain.outing.dto.ApplyOutingRequest
import team.aliens.dms.domain.outing.dto.ApplyOutingResponse
import team.aliens.dms.domain.outing.model.OutingApplication
import team.aliens.dms.domain.outing.model.OutingStatus
import team.aliens.dms.domain.outing.service.OutingService
import team.aliens.dms.domain.student.service.StudentService
import java.time.LocalDateTime

@UseCase
class ApplyOutingUseCase(
private val outingService: OutingService,
private val studentService: StudentService,
private val securityService: SecurityService,
) {

fun execute(request: ApplyOutingRequest): ApplyOutingResponse {
val student = studentService.getCurrentStudent()

outingService.checkOutingApplicationAvailable(
studentId = student.id,
outAt = request.outAt,
outingTime = request.outingTime,
arrivalTime = request.arrivalTime
)

val outing = outingService.apply(
OutingApplication(
studentId = student.id,
createdAt = LocalDateTime.now(),
outAt = request.outAt,
outingTime = request.outingTime,
arrivalTime = request.arrivalTime,
status = OutingStatus.REQUESTED,
reason = request.reason,
destination = request.destination,
outingTypeTitle = request.outingTypeTitle,
schoolId = securityService.getCurrentSchoolId(),
companionIds = request.companionIds
)
)

return ApplyOutingResponse(outing.id)
}
}
package team.aliens.dms.domain.outing.usecase

import team.aliens.dms.common.annotation.UseCase
import team.aliens.dms.common.service.security.SecurityService
import team.aliens.dms.domain.outing.dto.ApplyOutingRequest
import team.aliens.dms.domain.outing.dto.ApplyOutingResponse
import team.aliens.dms.domain.outing.model.OutingApplication
import team.aliens.dms.domain.outing.model.OutingStatus
import team.aliens.dms.domain.outing.service.OutingService
import team.aliens.dms.domain.student.service.StudentService
import java.time.LocalDateTime

@UseCase
class ApplyOutingUseCase(
private val outingService: OutingService,
private val studentService: StudentService,
private val securityService: SecurityService,
) {

fun execute(request: ApplyOutingRequest): ApplyOutingResponse {
val student = studentService.getCurrentStudent()

outingService.checkOutingApplicationAvailable(
studentId = student.id,
outAt = request.outAt,
outingTime = request.outingTime,
arrivalTime = request.arrivalTime
)

val outing = outingService.saveOutingApplication(
OutingApplication(
studentId = student.id,
createdAt = LocalDateTime.now(),
outAt = request.outAt,
outingTime = request.outingTime,
arrivalTime = request.arrivalTime,
status = OutingStatus.REQUESTED,
reason = request.reason,
destination = request.destination,
outingTypeTitle = request.outingTypeTitle,
schoolId = securityService.getCurrentSchoolId(),
companionIds = request.companionIds
)
)

return ApplyOutingResponse(outing.id)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package team.aliens.dms.domain.outing.usecase

import team.aliens.dms.common.annotation.UseCase
import team.aliens.dms.common.service.security.SecurityService
import team.aliens.dms.domain.outing.dto.CreateOutingTypeRequest
import team.aliens.dms.domain.outing.model.OutingType
import team.aliens.dms.domain.outing.service.OutingService

@UseCase
class CreateOutingTypeUseCase(
private val outingService: OutingService,
private val securityService: SecurityService,
) {

fun execute(request: CreateOutingTypeRequest) {
val outingType = OutingType(
title = request.title,
schoolId = securityService.getCurrentSchoolId()
)

outingService.checkOutingTypeExists(outingType)

outingService.saveOutingType(outingType)
}
}
Original file line number Diff line number Diff line change
@@ -1,29 +1,22 @@
package team.aliens.dms.global.security

import com.fasterxml.jackson.databind.ObjectMapper
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration
import org.springframework.http.HttpMethod
import org.springframework.security.config.Customizer
import org.springframework.security.config.annotation.SecurityConfigurerAdapter
import org.springframework.security.config.annotation.web.builders.HttpSecurity
import org.springframework.security.config.http.SessionCreationPolicy
import org.springframework.security.config.web.server.ServerHttpSecurity.http
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder
import org.springframework.security.web.DefaultSecurityFilterChain
import org.springframework.security.web.SecurityFilterChain
import team.aliens.dms.domain.auth.model.Authority.MANAGER
import team.aliens.dms.domain.auth.model.Authority.STUDENT
import team.aliens.dms.global.filter.FilterConfig
import team.aliens.dms.global.security.token.JwtParser

@Configuration
class SecurityConfig(
private val jwtParser: JwtParser,
private val objectMapper: ObjectMapper,
private val authenticationEntryPoint: CustomAuthenticationEntryPoint,
private val accessDeniedHandler: CustomAccessDeniedHandler,
private val filterConfig: FilterConfig,
private val filterConfig: FilterConfig
) {

@Bean
Expand Down Expand Up @@ -174,6 +167,7 @@ class SecurityConfig(

//outings
.requestMatchers(HttpMethod.POST, "/outings").hasAuthority(STUDENT.name)
.requestMatchers(HttpMethod.POST, "/outings/types").hasAuthority(MANAGER.name)

.anyRequest().denyAll()
}
Expand Down
Loading

0 comments on commit 3db916f

Please sign in to comment.