diff --git a/simtong-application/src/main/kotlin/team/comit/simtong/domain/schedule/dto/ChangeIndividualScheduleRequest.kt b/simtong-application/src/main/kotlin/team/comit/simtong/domain/schedule/dto/ChangeIndividualScheduleRequest.kt new file mode 100644 index 00000000..3e271314 --- /dev/null +++ b/simtong-application/src/main/kotlin/team/comit/simtong/domain/schedule/dto/ChangeIndividualScheduleRequest.kt @@ -0,0 +1,26 @@ +package team.comit.simtong.domain.schedule.dto + +import java.time.LocalDate +import java.time.LocalTime +import java.util.UUID + +/** + * + * 개인 일정 변경 요청 정보를 전달하는 ChangeIndividualScheduleRequest + * + * @author Chokyunghyeon + * @date 2022/11/27 + * @version 1.0.0 + **/ +data class ChangeIndividualScheduleRequest( + + val scheduleId: UUID, + + val title: String, + + val startAt: LocalDate, + + val endAt: LocalDate, + + val alarm: LocalTime +) \ No newline at end of file diff --git a/simtong-application/src/main/kotlin/team/comit/simtong/domain/schedule/usecase/ChangeIndividualScheduleUseCase.kt b/simtong-application/src/main/kotlin/team/comit/simtong/domain/schedule/usecase/ChangeIndividualScheduleUseCase.kt new file mode 100644 index 00000000..c9219019 --- /dev/null +++ b/simtong-application/src/main/kotlin/team/comit/simtong/domain/schedule/usecase/ChangeIndividualScheduleUseCase.kt @@ -0,0 +1,53 @@ +package team.comit.simtong.domain.schedule.usecase + +import team.comit.simtong.domain.schedule.dto.ChangeIndividualScheduleRequest +import team.comit.simtong.domain.schedule.exception.NotScheduleOwnerException +import team.comit.simtong.domain.schedule.exception.ScheduleNotFoundException +import team.comit.simtong.domain.schedule.spi.CommandSchedulePort +import team.comit.simtong.domain.schedule.spi.QuerySchedulePort +import team.comit.simtong.domain.schedule.spi.ScheduleQueryUserPort +import team.comit.simtong.domain.schedule.spi.ScheduleSecurityPort +import team.comit.simtong.domain.user.exception.UserNotFoundException +import team.comit.simtong.global.annotation.UseCase + +/** + * + * 개인 일정 정보 변경 요청을 담당하는 ChangeIndividualScheduleUseCase + * + * @author Chokyunghyeon + * @date 2022/11/27 + * @version 1.0.0 + **/ +@UseCase +class ChangeIndividualScheduleUseCase( + private val queryUserPort: ScheduleQueryUserPort, + private val querySchedulePort: QuerySchedulePort, + private val commandSchedulePort: CommandSchedulePort, + private val securityPort: ScheduleSecurityPort +) { + + fun execute(request: ChangeIndividualScheduleRequest) { + val currentUserId = securityPort.getCurrentUserId() + val (scheduleId, title, startAt, endAt, alarm) = request + + val schedule = querySchedulePort.queryScheduleById(scheduleId) + ?: throw ScheduleNotFoundException.EXCEPTION + + val user = queryUserPort.queryUserById(currentUserId) + ?: throw UserNotFoundException.EXCEPTION + + if (user.id != schedule.userId) { + throw NotScheduleOwnerException.EXCEPTION + } + + commandSchedulePort.save( + schedule.copy( + title = title, + startAt = startAt, + endAt = endAt, + alarmTime = alarm + ) + ) + } + +} \ No newline at end of file diff --git a/simtong-application/src/main/kotlin/team/comit/simtong/domain/schedule/usecase/ChangeSpotScheduleUseCase.kt b/simtong-application/src/main/kotlin/team/comit/simtong/domain/schedule/usecase/ChangeSpotScheduleUseCase.kt index 5dc00669..65ea49bc 100644 --- a/simtong-application/src/main/kotlin/team/comit/simtong/domain/schedule/usecase/ChangeSpotScheduleUseCase.kt +++ b/simtong-application/src/main/kotlin/team/comit/simtong/domain/schedule/usecase/ChangeSpotScheduleUseCase.kt @@ -1,7 +1,9 @@ package team.comit.simtong.domain.schedule.usecase import team.comit.simtong.domain.schedule.dto.ChangeSpotScheduleRequest +import team.comit.simtong.domain.schedule.exception.NotScheduleOwnerException import team.comit.simtong.domain.schedule.exception.ScheduleNotFoundException +import team.comit.simtong.domain.schedule.model.Scope import team.comit.simtong.domain.schedule.spi.CommandSchedulePort import team.comit.simtong.domain.schedule.spi.QuerySchedulePort import team.comit.simtong.domain.schedule.spi.ScheduleQueryUserPort @@ -36,8 +38,11 @@ class ChangeSpotScheduleUseCase( val schedule = querySchedulePort.queryScheduleById(request.scheduleId) ?: throw ScheduleNotFoundException.EXCEPTION - if (user.spotId != schedule.spotId && user.authority != Authority.ROLE_SUPER) { - throw NotEnoughPermissionException.EXCEPTION + when { + Scope.ENTIRE != schedule.scope -> throw NotScheduleOwnerException.EXCEPTION + + user.spotId != schedule.spotId && + Authority.ROLE_SUPER != user.authority -> throw NotEnoughPermissionException.EXCEPTION } commandSchedulePort.save( diff --git a/simtong-application/src/main/kotlin/team/comit/simtong/domain/schedule/usecase/EntireSpotScheduleUseCase.kt b/simtong-application/src/main/kotlin/team/comit/simtong/domain/schedule/usecase/EntireSpotScheduleUseCase.kt index 24df4ddd..476f3805 100644 --- a/simtong-application/src/main/kotlin/team/comit/simtong/domain/schedule/usecase/EntireSpotScheduleUseCase.kt +++ b/simtong-application/src/main/kotlin/team/comit/simtong/domain/schedule/usecase/EntireSpotScheduleUseCase.kt @@ -2,6 +2,7 @@ package team.comit.simtong.domain.schedule.usecase import team.comit.simtong.domain.schedule.dto.EntireSpotScheduleResponse import team.comit.simtong.domain.schedule.dto.SpotScheduleResponse +import team.comit.simtong.domain.schedule.model.Scope import team.comit.simtong.domain.schedule.spi.QuerySchedulePort import team.comit.simtong.global.annotation.ReadOnlyUseCase import java.time.LocalDate @@ -20,7 +21,7 @@ class EntireSpotScheduleUseCase( ) { fun execute(date: LocalDate): EntireSpotScheduleResponse { - val list = querySchedulePort.querySchedulesByDateContains(date) + val list = querySchedulePort.querySchedulesByMonthAndScope(date, Scope.ENTIRE) val response = list.map { SpotScheduleResponse( diff --git a/simtong-application/src/test/kotlin/team/comit/simtong/domain/schedule/usecase/ChangeIndividualScheduleUseCaseTest.kt b/simtong-application/src/test/kotlin/team/comit/simtong/domain/schedule/usecase/ChangeIndividualScheduleUseCaseTest.kt new file mode 100644 index 00000000..b1d1eb24 --- /dev/null +++ b/simtong-application/src/test/kotlin/team/comit/simtong/domain/schedule/usecase/ChangeIndividualScheduleUseCaseTest.kt @@ -0,0 +1,178 @@ +package team.comit.simtong.domain.schedule.usecase + +import org.junit.jupiter.api.BeforeEach +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.assertDoesNotThrow +import org.junit.jupiter.api.assertThrows +import org.junit.jupiter.api.extension.ExtendWith +import org.mockito.Mock +import org.mockito.kotlin.given +import org.springframework.boot.test.mock.mockito.MockBean +import org.springframework.test.context.junit.jupiter.SpringExtension +import team.comit.simtong.domain.schedule.dto.ChangeIndividualScheduleRequest +import team.comit.simtong.domain.schedule.exception.NotScheduleOwnerException +import team.comit.simtong.domain.schedule.exception.ScheduleNotFoundException +import team.comit.simtong.domain.schedule.model.Schedule +import team.comit.simtong.domain.schedule.model.Scope +import team.comit.simtong.domain.schedule.spi.CommandSchedulePort +import team.comit.simtong.domain.schedule.spi.QuerySchedulePort +import team.comit.simtong.domain.schedule.spi.ScheduleQueryUserPort +import team.comit.simtong.domain.schedule.spi.ScheduleSecurityPort +import team.comit.simtong.domain.user.exception.UserNotFoundException +import team.comit.simtong.domain.user.model.Authority +import team.comit.simtong.domain.user.model.User +import java.time.LocalDate +import java.time.LocalTime +import java.util.UUID + +@ExtendWith(SpringExtension::class) +class ChangeIndividualScheduleUseCaseTest { + + @MockBean + private lateinit var queryUserPort: ScheduleQueryUserPort + + @MockBean + private lateinit var querySchedulePort: QuerySchedulePort + + @MockBean + private lateinit var commandSchedulePort: CommandSchedulePort + + @Mock + private lateinit var securityPort: ScheduleSecurityPort + + private lateinit var changeIndividualScheduleUseCase: ChangeIndividualScheduleUseCase + + @BeforeEach + fun setUp() { + changeIndividualScheduleUseCase = ChangeIndividualScheduleUseCase( + queryUserPort = queryUserPort, + querySchedulePort = querySchedulePort, + commandSchedulePort = commandSchedulePort, + securityPort = securityPort + ) + } + + private val userId = UUID.randomUUID() + + private val spotId = UUID.randomUUID() + + private val scheduleId= UUID.randomUUID() + + private val userStub: User by lazy { + User( + id = userId, + nickname = "test nickname", + name = "test name", + email = "test@test.com", + password = "test password", + employeeNumber = 1234567890, + authority = Authority.ROLE_COMMON, + spotId = UUID.randomUUID(), + teamId = UUID.randomUUID(), + profileImagePath = "test profile image" + ) + } + + private val scheduleStub: Schedule by lazy { + Schedule( + id = scheduleId, + userId = userId, + spotId = spotId, + title = "test title", + scope = Scope.INDIVIDUAL, + startAt = LocalDate.now(), + endAt = LocalDate.now(), + alarmTime = Schedule.DEFAULT_ALARM_TIME + ) + } + + private val requestStub: ChangeIndividualScheduleRequest by lazy { + ChangeIndividualScheduleRequest( + scheduleId = scheduleId, + title = "test title", + startAt = LocalDate.now(), + endAt = LocalDate.now(), + alarm = LocalTime.now() + ) + } + + @Test + fun `개인 일정 변경 성공`() { + // given + given(securityPort.getCurrentUserId()) + .willReturn(userId) + + given(querySchedulePort.queryScheduleById(requestStub.scheduleId)) + .willReturn(scheduleStub) + + given(queryUserPort.queryUserById(userId)) + .willReturn(userStub) + + // when & then + assertDoesNotThrow { + changeIndividualScheduleUseCase.execute(requestStub) + } + } + + @Test + fun `소유자가 아님`() { + // given + val otherScheduleStub = Schedule( + id = scheduleId, + userId = UUID.randomUUID(), + spotId = spotId, + title = "test title", + scope = Scope.INDIVIDUAL, + startAt = LocalDate.now(), + endAt = LocalDate.now(), + alarmTime = Schedule.DEFAULT_ALARM_TIME + ) + + given(securityPort.getCurrentUserId()) + .willReturn(userId) + + given(querySchedulePort.queryScheduleById(requestStub.scheduleId)) + .willReturn(otherScheduleStub) + + given(queryUserPort.queryUserById(userId)) + .willReturn(userStub) + + // when & then + assertThrows { + changeIndividualScheduleUseCase.execute(requestStub) + } + } + + @Test + fun `유저를 찾을 수 없음`() { + // given + given(securityPort.getCurrentUserId()) + .willReturn(userId) + + given(querySchedulePort.queryScheduleById(requestStub.scheduleId)) + .willReturn(scheduleStub) + + given(queryUserPort.queryUserById(userId)) + .willReturn(null) + + // when & then + assertThrows { + changeIndividualScheduleUseCase.execute(requestStub) + } + } + + @Test + fun `일정을 찾을 수 없음`() { + // given + given(securityPort.getCurrentUserId()) + .willReturn(userId) + + given(querySchedulePort.queryScheduleById(requestStub.scheduleId)) + .willReturn(null) + + // when & then + assertThrows { + changeIndividualScheduleUseCase.execute(requestStub) + } + } +} \ No newline at end of file diff --git a/simtong-application/src/test/kotlin/team/comit/simtong/domain/schedule/usecase/ChangeSpotScheduleUseCaseTests.kt b/simtong-application/src/test/kotlin/team/comit/simtong/domain/schedule/usecase/ChangeSpotScheduleUseCaseTests.kt index 1a8c1dca..2278843f 100644 --- a/simtong-application/src/test/kotlin/team/comit/simtong/domain/schedule/usecase/ChangeSpotScheduleUseCaseTests.kt +++ b/simtong-application/src/test/kotlin/team/comit/simtong/domain/schedule/usecase/ChangeSpotScheduleUseCaseTests.kt @@ -9,6 +9,7 @@ import org.mockito.kotlin.given import org.springframework.boot.test.mock.mockito.MockBean import org.springframework.test.context.junit.jupiter.SpringExtension import team.comit.simtong.domain.schedule.dto.ChangeSpotScheduleRequest +import team.comit.simtong.domain.schedule.exception.NotScheduleOwnerException import team.comit.simtong.domain.schedule.exception.ScheduleNotFoundException import team.comit.simtong.domain.schedule.model.Schedule import team.comit.simtong.domain.schedule.model.Scope @@ -88,7 +89,7 @@ class ChangeSpotScheduleUseCaseTests { email = "test@test.com", password = "test password", employeeNumber = 1234567890, - Authority.ROLE_ADMIN, + authority = Authority.ROLE_ADMIN, spotId = spotId, teamId = UUID.randomUUID(), profileImagePath = "test profile image" @@ -109,6 +110,48 @@ class ChangeSpotScheduleUseCaseTests { } } + @Test + fun `지점 일정이 아님`() { + // given + val userStub = User( + id = userId, + nickname = "test nickname", + name = "test name", + email = "test@test.com", + password = "test password", + employeeNumber = 1234567890, + authority = Authority.ROLE_ADMIN, + spotId = spotId, + teamId = UUID.randomUUID(), + profileImagePath = "test profile image" + ) + + val individualScheduleStub = Schedule( + id = scheduleId, + userId = userId, + spotId = spotId, + title = "test title", + scope = Scope.INDIVIDUAL, + startAt = LocalDate.now(), + endAt = LocalDate.now(), + alarmTime = Schedule.DEFAULT_ALARM_TIME + ) + + given(securityPort.getCurrentUserId()) + .willReturn(userId) + + given(queryUserPort.queryUserById(userId)) + .willReturn(userStub) + + given(querySchedulePort.queryScheduleById(requestStub.scheduleId)) + .willReturn(individualScheduleStub) + + // when & then + assertThrows { + changeSpotScheduleUseCase.execute(requestStub) + } + } + @Test fun `권한이 부족함`() { // given @@ -119,7 +162,7 @@ class ChangeSpotScheduleUseCaseTests { email = "test@test.com", password = "test password", employeeNumber = 1234567890, - Authority.ROLE_ADMIN, + authority = Authority.ROLE_ADMIN, spotId = UUID.randomUUID(), teamId = UUID.randomUUID(), profileImagePath = "test profile image" @@ -150,7 +193,7 @@ class ChangeSpotScheduleUseCaseTests { email = "test@test.com", password = "test password", employeeNumber = 1234567890, - Authority.ROLE_SUPER, + authority = Authority.ROLE_SUPER, spotId = UUID.randomUUID(), teamId = UUID.randomUUID(), profileImagePath = "test profile image" @@ -181,7 +224,7 @@ class ChangeSpotScheduleUseCaseTests { email = "test@test.com", password = "test password", employeeNumber = 1234567890, - Authority.ROLE_ADMIN, + authority = Authority.ROLE_ADMIN, spotId = UUID.randomUUID(), teamId = UUID.randomUUID(), profileImagePath = "test profile image" diff --git a/simtong-application/src/test/kotlin/team/comit/simtong/domain/schedule/usecase/EntireSpotScheduleUseCaseTests.kt b/simtong-application/src/test/kotlin/team/comit/simtong/domain/schedule/usecase/EntireSpotScheduleUseCaseTests.kt index ab3e29d8..bf82af80 100644 --- a/simtong-application/src/test/kotlin/team/comit/simtong/domain/schedule/usecase/EntireSpotScheduleUseCaseTests.kt +++ b/simtong-application/src/test/kotlin/team/comit/simtong/domain/schedule/usecase/EntireSpotScheduleUseCaseTests.kt @@ -9,6 +9,7 @@ import org.springframework.boot.test.mock.mockito.MockBean import org.springframework.test.context.junit.jupiter.SpringExtension import team.comit.simtong.domain.schedule.dto.EntireSpotScheduleResponse import team.comit.simtong.domain.schedule.dto.SpotScheduleResponse +import team.comit.simtong.domain.schedule.model.Scope import team.comit.simtong.domain.schedule.spi.QuerySchedulePort import team.comit.simtong.domain.schedule.vo.SpotSchedule import java.time.LocalDate @@ -62,7 +63,7 @@ class EntireSpotScheduleUseCaseTests { @Test fun `전체 지점 일정 조회 성공`() { // given - given(querySchedulePort.querySchedulesByDateContains(date)) + given(querySchedulePort.querySchedulesByMonthAndScope(date, Scope.ENTIRE)) .willReturn(spotScheduleListStub) // when diff --git a/simtong-domain/src/main/kotlin/team/comit/simtong/domain/schedule/error/ScheduleErrorCode.kt b/simtong-domain/src/main/kotlin/team/comit/simtong/domain/schedule/error/ScheduleErrorCode.kt index 9a14d695..a2fc14dd 100644 --- a/simtong-domain/src/main/kotlin/team/comit/simtong/domain/schedule/error/ScheduleErrorCode.kt +++ b/simtong-domain/src/main/kotlin/team/comit/simtong/domain/schedule/error/ScheduleErrorCode.kt @@ -15,7 +15,11 @@ enum class ScheduleErrorCode( private val message: String ) : ErrorProperty { - SCHEDULE_NOT_FOUND(404, "일정을 찾을 수 없습니다."); + // 403 + NOT_SCHEDULE_OWNER(403, "일정의 소유자가 아님"), + + // 404 + SCHEDULE_NOT_FOUND(404, "일정을 찾을 수 없음"); override fun status() = status diff --git a/simtong-domain/src/main/kotlin/team/comit/simtong/domain/schedule/exception/NotScheduleOwnerException.kt b/simtong-domain/src/main/kotlin/team/comit/simtong/domain/schedule/exception/NotScheduleOwnerException.kt new file mode 100644 index 00000000..7d344cc5 --- /dev/null +++ b/simtong-domain/src/main/kotlin/team/comit/simtong/domain/schedule/exception/NotScheduleOwnerException.kt @@ -0,0 +1,20 @@ +package team.comit.simtong.domain.schedule.exception + +import team.comit.simtong.domain.schedule.error.ScheduleErrorCode +import team.comit.simtong.global.error.BusinessException + +/** + * + * Not Schedule Owner Error를 발생시키는 NotScheduleOwnerException + * + * @author Chokyunghyeon + * @date 2022/11/27 + * @version 1.0.0 + **/ +class NotScheduleOwnerException private constructor() : BusinessException(ScheduleErrorCode.NOT_SCHEDULE_OWNER) { + + companion object { + @JvmField + val EXCEPTION = NotScheduleOwnerException() + } +} \ No newline at end of file diff --git a/simtong-domain/src/main/kotlin/team/comit/simtong/domain/schedule/spi/QuerySchedulePort.kt b/simtong-domain/src/main/kotlin/team/comit/simtong/domain/schedule/spi/QuerySchedulePort.kt index bf5256ed..9faa550a 100644 --- a/simtong-domain/src/main/kotlin/team/comit/simtong/domain/schedule/spi/QuerySchedulePort.kt +++ b/simtong-domain/src/main/kotlin/team/comit/simtong/domain/schedule/spi/QuerySchedulePort.kt @@ -1,6 +1,7 @@ package team.comit.simtong.domain.schedule.spi import team.comit.simtong.domain.schedule.model.Schedule +import team.comit.simtong.domain.schedule.model.Scope import team.comit.simtong.domain.schedule.vo.SpotSchedule import java.time.LocalDate import java.util.UUID @@ -17,6 +18,6 @@ interface QuerySchedulePort { fun queryScheduleById(id: UUID): Schedule? - fun querySchedulesByDateContains(date: LocalDate): List + fun querySchedulesByMonthAndScope(date: LocalDate, scope: Scope): List } \ No newline at end of file diff --git a/simtong-domain/src/main/kotlin/team/comit/simtong/global/exception/NotInitializationPropertiesException.kt b/simtong-domain/src/main/kotlin/team/comit/simtong/global/exception/NotInitializationPropertiesException.kt index 8016226a..64c1883f 100644 --- a/simtong-domain/src/main/kotlin/team/comit/simtong/global/exception/NotInitializationPropertiesException.kt +++ b/simtong-domain/src/main/kotlin/team/comit/simtong/global/exception/NotInitializationPropertiesException.kt @@ -11,7 +11,7 @@ import team.comit.simtong.global.error.DomainErrorCode * @date 2022/11/26 * @version 1.0.0 **/ -class NotInitializationPropertiesException private constructor() : BusinessException(DomainErrorCode.NOT_INITIALIZATION_PROPERTIES) { +internal class NotInitializationPropertiesException private constructor() : BusinessException(DomainErrorCode.NOT_INITIALIZATION_PROPERTIES) { companion object { @JvmField diff --git a/simtong-infrastructure/src/main/kotlin/team/comit/simtong/global/security/SecurityConfig.kt b/simtong-infrastructure/src/main/kotlin/team/comit/simtong/global/security/SecurityConfig.kt index 6e35f69e..e65ba6af 100644 --- a/simtong-infrastructure/src/main/kotlin/team/comit/simtong/global/security/SecurityConfig.kt +++ b/simtong-infrastructure/src/main/kotlin/team/comit/simtong/global/security/SecurityConfig.kt @@ -76,6 +76,7 @@ class SecurityConfig( // schedules .antMatchers(HttpMethod.POST, "/schedules").hasRole(ROLE_COMMON.role) + .antMatchers(HttpMethod.PUT, "/schedules/{schedule-id}").hasRole(ROLE_COMMON.role) .antMatchers(HttpMethod.GET, "/schedules/spots").hasAnyRole(ROLE_ADMIN.role, ROLE_SUPER.role) .antMatchers(HttpMethod.POST, "/schedules/spots/{spot-id}").hasAnyRole(ROLE_ADMIN.role, ROLE_SUPER.role) .antMatchers(HttpMethod.PUT, "/schedules/spots/{schedule-id}").hasAnyRole(ROLE_ADMIN.role, ROLE_SUPER.role) diff --git a/simtong-infrastructure/src/main/kotlin/team/comit/simtong/persistence/schedule/SchedulePersistenceAdapter.kt b/simtong-infrastructure/src/main/kotlin/team/comit/simtong/persistence/schedule/SchedulePersistenceAdapter.kt index 366ed4d6..aa8c39de 100644 --- a/simtong-infrastructure/src/main/kotlin/team/comit/simtong/persistence/schedule/SchedulePersistenceAdapter.kt +++ b/simtong-infrastructure/src/main/kotlin/team/comit/simtong/persistence/schedule/SchedulePersistenceAdapter.kt @@ -4,6 +4,7 @@ import com.querydsl.jpa.impl.JPAQueryFactory import org.springframework.data.repository.findByIdOrNull import org.springframework.stereotype.Component import team.comit.simtong.domain.schedule.model.Schedule +import team.comit.simtong.domain.schedule.model.Scope import team.comit.simtong.domain.schedule.spi.SchedulePort import team.comit.simtong.domain.schedule.vo.SpotSchedule import team.comit.simtong.persistence.schedule.mapper.ScheduleMapper @@ -46,7 +47,7 @@ class SchedulePersistenceAdapter( ) } - override fun querySchedulesByDateContains(date: LocalDate): List { + override fun querySchedulesByMonthAndScope(date: LocalDate, scope: Scope): List { val startDate = date.withDayOfMonth(1) val endDate = date.withDayOfMonth(date.lengthOfMonth()) @@ -64,8 +65,9 @@ class SchedulePersistenceAdapter( .join(spot) .on(schedule.spot.eq(spot)) .where( - schedule.startAt.between(startDate, endDate) - .or(schedule.endAt.between(startDate, endDate)) + schedule.scope.eq(scope) + .and(schedule.startAt.between(startDate, endDate) + .or(schedule.endAt.between(startDate, endDate))) ) .orderBy(schedule.startAt.asc()) .fetch() diff --git a/simtong-presentation/src/main/kotlin/team/comit/simtong/domain/schedule/WebScheduleAdapter.kt b/simtong-presentation/src/main/kotlin/team/comit/simtong/domain/schedule/WebScheduleAdapter.kt index 09f17bfd..800dffdc 100644 --- a/simtong-presentation/src/main/kotlin/team/comit/simtong/domain/schedule/WebScheduleAdapter.kt +++ b/simtong-presentation/src/main/kotlin/team/comit/simtong/domain/schedule/WebScheduleAdapter.kt @@ -13,16 +13,19 @@ import org.springframework.web.bind.annotation.ResponseStatus import org.springframework.web.bind.annotation.RestController import team.comit.simtong.domain.schedule.dto.AddIndividualScheduleRequest import team.comit.simtong.domain.schedule.dto.AddSpotScheduleRequest +import team.comit.simtong.domain.schedule.dto.ChangeIndividualScheduleRequest import team.comit.simtong.domain.schedule.dto.ChangeSpotScheduleRequest import team.comit.simtong.domain.schedule.dto.EntireSpotScheduleResponse +import team.comit.simtong.domain.schedule.dto.request.AddIndividualScheduleWebRequest import team.comit.simtong.domain.schedule.dto.request.AddSpotScheduleWebRequest +import team.comit.simtong.domain.schedule.dto.request.ChangeIndividualScheduleWebRequest import team.comit.simtong.domain.schedule.dto.request.ChangeSpotScheduleWebRequest import team.comit.simtong.domain.schedule.usecase.AddIndividualScheduleUseCase import team.comit.simtong.domain.schedule.usecase.AddSpotScheduleUseCase +import team.comit.simtong.domain.schedule.usecase.ChangeIndividualScheduleUseCase import team.comit.simtong.domain.schedule.usecase.ChangeSpotScheduleUseCase import team.comit.simtong.domain.schedule.usecase.EntireSpotScheduleUseCase import team.comit.simtong.domain.schedule.usecase.RemoveSpotScheduleUseCase -import team.comit.simtong.domain.schedule.dto.request.AddIndividualScheduleWebRequest import java.time.LocalDate import java.util.UUID import javax.validation.Valid @@ -39,13 +42,14 @@ import javax.validation.Valid @RequestMapping("/schedules") class WebScheduleAdapter( private val addIndividualScheduleUseCase: AddIndividualScheduleUseCase, + private val changeIndividualScheduleUseCase: ChangeIndividualScheduleUseCase, private val entireSpotScheduleUseCase: EntireSpotScheduleUseCase, private val addSpotScheduleUseCase: AddSpotScheduleUseCase, private val changeSpotScheduleUseCase: ChangeSpotScheduleUseCase, private val removeSpotScheduleUseCase: RemoveSpotScheduleUseCase ) { - @GetMapping + @PostMapping @ResponseStatus(HttpStatus.CREATED) fun addIndividualSchedule(@Valid @RequestBody request: AddIndividualScheduleWebRequest) { addIndividualScheduleUseCase.execute( @@ -58,6 +62,22 @@ class WebScheduleAdapter( ) } + @PutMapping("/{schedule-id}") + @ResponseStatus(HttpStatus.NO_CONTENT) + fun changeIndividualSchedule(@PathVariable("schedule-id") scheduleId: UUID, + @Valid @RequestBody request: ChangeIndividualScheduleWebRequest + ) { + changeIndividualScheduleUseCase.execute( + ChangeIndividualScheduleRequest( + scheduleId = scheduleId, + title = request.title, + startAt = request.startAt, + endAt = request.endAt, + alarm = request.alarm + ) + ) + } + @GetMapping("/spots") fun entireSpotSchedule(@RequestParam date: LocalDate) : EntireSpotScheduleResponse { return entireSpotScheduleUseCase.execute(date) diff --git a/simtong-presentation/src/main/kotlin/team/comit/simtong/domain/schedule/dto/request/ChangeIndividualScheduleWebRequest.kt b/simtong-presentation/src/main/kotlin/team/comit/simtong/domain/schedule/dto/request/ChangeIndividualScheduleWebRequest.kt new file mode 100644 index 00000000..0383002f --- /dev/null +++ b/simtong-presentation/src/main/kotlin/team/comit/simtong/domain/schedule/dto/request/ChangeIndividualScheduleWebRequest.kt @@ -0,0 +1,33 @@ +package team.comit.simtong.domain.schedule.dto.request + +import org.hibernate.validator.constraints.Length +import java.time.LocalDate +import java.time.LocalTime +import javax.validation.constraints.FutureOrPresent +import javax.validation.constraints.NotBlank +import javax.validation.constraints.NotNull + +/** + * + * 개인 일정 변경을 요청하는 ChangeIndividualWebRequest + * + * @author Chokyunghyeon + * @date 2022/11/27 + * @version 1.0.0 + **/ +data class ChangeIndividualScheduleWebRequest( + @field:NotBlank + @field:Length(max = 20) + val title: String, + + @field:NotNull + @field:FutureOrPresent + val startAt: LocalDate, + + // TODO 시작일, 종료일 검증 Resolver 구현 + @field:NotNull + val endAt: LocalDate, + + @field:NotNull + val alarm: LocalTime +) \ No newline at end of file