From 47690db205971783674e2b35a17f6bfc78a9b6a8 Mon Sep 17 00:00:00 2001 From: RbertKo Date: Fri, 13 Aug 2021 00:12:50 +0900 Subject: [PATCH 01/12] feat: add event.late-diff-minute, event.absent-diff-minute properties --- src/main/resources/application-local.yaml | 5 ++++- src/main/resources/application-prod.yaml | 5 ++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/src/main/resources/application-local.yaml b/src/main/resources/application-local.yaml index 224e377..5fd6cb9 100644 --- a/src/main/resources/application-local.yaml +++ b/src/main/resources/application-local.yaml @@ -17,4 +17,7 @@ spring: format_sql: true jwt: secret: test_QiPScSmMJnGrGCwTm*Xi0m1yAHe3KfAkhH&VpsENjwqfGP%grBdmv4Ee%GYZhNj2S4y6@$8KORZE9dsiw%v*ugKcba9x8CN18!Pl - expires: 31536000000000 \ No newline at end of file + expires: 31536000000000 +event: + late-diff-minute: 10 + absent-diff-minute: 50 \ No newline at end of file diff --git a/src/main/resources/application-prod.yaml b/src/main/resources/application-prod.yaml index 85d0b28..edeedbc 100644 --- a/src/main/resources/application-prod.yaml +++ b/src/main/resources/application-prod.yaml @@ -18,4 +18,7 @@ spring: format_sql: true jwt: secret: ${JWT_SECRET} - expires: ${JWT_EXPIRES} \ No newline at end of file + expires: ${JWT_EXPIRES} +event: + late-diff-minute: ${DDD_LATE_DIFF_MINUTE} + absent-diff-minute: ${DDD_ABSENT_DIFF_MINUTE} \ No newline at end of file From fd59e9cadf9f28cc9fc634e02222b0fb77bfe41f Mon Sep 17 00:00:00 2001 From: RbertKo Date: Fri, 13 Aug 2021 00:13:44 +0900 Subject: [PATCH 02/12] feat: edit Event.kt entity --- .../kotlin/com/example/attendanceapimono/domain/event/Event.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/kotlin/com/example/attendanceapimono/domain/event/Event.kt b/src/main/kotlin/com/example/attendanceapimono/domain/event/Event.kt index ffb1f07..bd8f72d 100644 --- a/src/main/kotlin/com/example/attendanceapimono/domain/event/Event.kt +++ b/src/main/kotlin/com/example/attendanceapimono/domain/event/Event.kt @@ -36,7 +36,7 @@ class Event( var absentDiffMinutes: Int, @Column(nullable = false) - var startAt: LocalDateTime, + var startAt: LocalDateTime? = null, @Column(nullable = false) val createdAt: LocalDateTime, From 935ed709f4508bb6d095837b2e2af3fb1446e926 Mon Sep 17 00:00:00 2001 From: RbertKo Date: Fri, 13 Aug 2021 00:15:48 +0900 Subject: [PATCH 03/12] feat: add entity method for converting --- .../application/dto/event/CreateEventRequest.kt | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/main/kotlin/com/example/attendanceapimono/application/dto/event/CreateEventRequest.kt b/src/main/kotlin/com/example/attendanceapimono/application/dto/event/CreateEventRequest.kt index 6e4f2ba..0f185ef 100644 --- a/src/main/kotlin/com/example/attendanceapimono/application/dto/event/CreateEventRequest.kt +++ b/src/main/kotlin/com/example/attendanceapimono/application/dto/event/CreateEventRequest.kt @@ -1,9 +1,12 @@ package com.example.attendanceapimono.application.dto.event +import com.example.attendanceapimono.domain.event.Event import io.swagger.v3.oas.annotations.media.Schema import org.hibernate.validator.constraints.Length +import org.springframework.beans.factory.annotation.Value import org.springframework.format.annotation.DateTimeFormat import java.time.LocalDateTime +import java.util.* @Schema( title = "이벤트 등록 요청", @@ -26,12 +29,26 @@ class CreateEventRequest( @field:DateTimeFormat val expectedAt: String, + @Value("\${event.late-diff-minute}") @Schema(description = "지각 기준 시간 (분)") val lateDiffMinute: Int, + @Value("\${event.absent-diff-minute}") @Schema(description = "결석 기준 시간 (분)") val absentDiffMinute: Int ) { + fun entity() = Event ( + id = UUID.randomUUID(), + generationID = this.generationID, + title = this.title, + description = this.description, + expectedAt = LocalDateTime.parse(this.expectedAt), + lateDiffMinutes = this.lateDiffMinute, + absentDiffMinutes = this.absentDiffMinute, + createdAt = LocalDateTime.now(), + updatedAt = LocalDateTime.now() + ) + companion object { const val Example = """ { From 93c7f1b68ce4a477d8bb093d0f453bfcf271c74d Mon Sep 17 00:00:00 2001 From: RbertKo Date: Fri, 13 Aug 2021 00:54:17 +0900 Subject: [PATCH 04/12] feat: add createEvent method --- .../attendanceapimono/application/EventService.kt | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/src/main/kotlin/com/example/attendanceapimono/application/EventService.kt b/src/main/kotlin/com/example/attendanceapimono/application/EventService.kt index b9235ae..970f13a 100644 --- a/src/main/kotlin/com/example/attendanceapimono/application/EventService.kt +++ b/src/main/kotlin/com/example/attendanceapimono/application/EventService.kt @@ -1,10 +1,21 @@ package com.example.attendanceapimono.application +import com.example.attendanceapimono.application.dto.event.CreateEventRequest +import com.example.attendanceapimono.application.dto.event.CreateEventResponse +import com.example.attendanceapimono.domain.event.EventRepository +import kotlinx.coroutines.async +import kotlinx.coroutines.runBlocking import org.springframework.stereotype.Service @Service -class EventService { - fun createEvent() { +class EventService ( + private val eventRepository: EventRepository +) { + fun createEvent(dto: CreateEventRequest): CreateEventResponse = runBlocking { + val event = dto.entity() + eventRepository.save(event) + + CreateEventResponse(event) } } \ No newline at end of file From 863d180a6a7969b51b9355155eab1012b92b44f8 Mon Sep 17 00:00:00 2001 From: RbertKo Date: Fri, 13 Aug 2021 01:04:01 +0900 Subject: [PATCH 05/12] feat: add createUser method to EventAPI interface --- .../adapter/present/api/EventAPI.kt | 37 +++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/src/main/kotlin/com/example/attendanceapimono/adapter/present/api/EventAPI.kt b/src/main/kotlin/com/example/attendanceapimono/adapter/present/api/EventAPI.kt index e6ec6a2..229a7d1 100644 --- a/src/main/kotlin/com/example/attendanceapimono/adapter/present/api/EventAPI.kt +++ b/src/main/kotlin/com/example/attendanceapimono/adapter/present/api/EventAPI.kt @@ -1,7 +1,44 @@ package com.example.attendanceapimono.adapter.present.api +import com.example.attendanceapimono.application.dto.event.CreateEventRequest +import com.example.attendanceapimono.application.dto.event.CreateEventResponse +import io.swagger.v3.oas.annotations.Operation +import io.swagger.v3.oas.annotations.media.Content +import io.swagger.v3.oas.annotations.media.ExampleObject +import io.swagger.v3.oas.annotations.media.Schema +import io.swagger.v3.oas.annotations.responses.ApiResponse import io.swagger.v3.oas.annotations.tags.Tag +import org.springframework.http.HttpStatus +import org.springframework.http.MediaType +import org.springframework.web.bind.annotation.PostMapping +import org.springframework.web.bind.annotation.RequestBody +import org.springframework.web.bind.annotation.ResponseStatus +import reactor.core.publisher.Mono +import javax.validation.Valid @Tag(name = "Event 관련 API") interface EventAPI { + @Operation( + summary = "이벤트 생성", + requestBody = io.swagger.v3.oas.annotations.parameters.RequestBody( + content = [ + Content( + mediaType = MediaType.APPLICATION_JSON_VALUE, + schema = Schema(implementation = CreateEventRequest::class), + ) + ] + ) + ) + @ApiResponse( + responseCode = "201", + description = "이벤트 생성", + content = [Content( + mediaType = MediaType.APPLICATION_JSON_VALUE, + schema = Schema(implementation = CreateEventResponse::class), + examples = [ExampleObject(CreateEventResponse.Example)] + )], + ) + @ResponseStatus(HttpStatus.CREATED) + @PostMapping("/event") + suspend fun createUser(@Valid @RequestBody body: Mono): CreateEventResponse } \ No newline at end of file From 048e788388cf5467fb7406d909e84d95fef7cd22 Mon Sep 17 00:00:00 2001 From: RbertKo Date: Fri, 13 Aug 2021 02:33:46 +0900 Subject: [PATCH 06/12] feat: edit startAt --- .../application/dto/event/CreateEventRequest.kt | 1 + .../kotlin/com/example/attendanceapimono/domain/event/Event.kt | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/kotlin/com/example/attendanceapimono/application/dto/event/CreateEventRequest.kt b/src/main/kotlin/com/example/attendanceapimono/application/dto/event/CreateEventRequest.kt index 0f185ef..e3ef4f5 100644 --- a/src/main/kotlin/com/example/attendanceapimono/application/dto/event/CreateEventRequest.kt +++ b/src/main/kotlin/com/example/attendanceapimono/application/dto/event/CreateEventRequest.kt @@ -43,6 +43,7 @@ class CreateEventRequest( title = this.title, description = this.description, expectedAt = LocalDateTime.parse(this.expectedAt), + startAt = LocalDateTime.parse(this.expectedAt), lateDiffMinutes = this.lateDiffMinute, absentDiffMinutes = this.absentDiffMinute, createdAt = LocalDateTime.now(), diff --git a/src/main/kotlin/com/example/attendanceapimono/domain/event/Event.kt b/src/main/kotlin/com/example/attendanceapimono/domain/event/Event.kt index bd8f72d..ffb1f07 100644 --- a/src/main/kotlin/com/example/attendanceapimono/domain/event/Event.kt +++ b/src/main/kotlin/com/example/attendanceapimono/domain/event/Event.kt @@ -36,7 +36,7 @@ class Event( var absentDiffMinutes: Int, @Column(nullable = false) - var startAt: LocalDateTime? = null, + var startAt: LocalDateTime, @Column(nullable = false) val createdAt: LocalDateTime, From 77272d9d12793b9297702bea2476a8f1b62d8945 Mon Sep 17 00:00:00 2001 From: RbertKo Date: Fri, 13 Aug 2021 02:36:10 +0900 Subject: [PATCH 07/12] feat: add createEvent Ctrl --- .../adapter/present/EventController.kt | 13 ++++++++++++- .../adapter/present/api/EventAPI.kt | 2 +- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/src/main/kotlin/com/example/attendanceapimono/adapter/present/EventController.kt b/src/main/kotlin/com/example/attendanceapimono/adapter/present/EventController.kt index 5447b35..d7c0339 100644 --- a/src/main/kotlin/com/example/attendanceapimono/adapter/present/EventController.kt +++ b/src/main/kotlin/com/example/attendanceapimono/adapter/present/EventController.kt @@ -1,8 +1,19 @@ package com.example.attendanceapimono.adapter.present import com.example.attendanceapimono.adapter.present.api.EventAPI +import com.example.attendanceapimono.application.EventService +import com.example.attendanceapimono.application.dto.event.CreateEventRequest +import com.example.attendanceapimono.application.dto.event.CreateEventResponse +import com.example.attendanceapimono.application.exception.handleValidationCatch +import kotlinx.coroutines.reactor.awaitSingle import org.springframework.web.bind.annotation.RestController +import reactor.core.publisher.Mono @RestController -class EventController: EventAPI { +class EventController (private val eventService: EventService): EventAPI { + override suspend fun createEvent(body: Mono): CreateEventResponse { + return body.handleValidationCatch() + .map(eventService::createEvent) + .awaitSingle() + } } \ No newline at end of file diff --git a/src/main/kotlin/com/example/attendanceapimono/adapter/present/api/EventAPI.kt b/src/main/kotlin/com/example/attendanceapimono/adapter/present/api/EventAPI.kt index 229a7d1..e997b56 100644 --- a/src/main/kotlin/com/example/attendanceapimono/adapter/present/api/EventAPI.kt +++ b/src/main/kotlin/com/example/attendanceapimono/adapter/present/api/EventAPI.kt @@ -40,5 +40,5 @@ interface EventAPI { ) @ResponseStatus(HttpStatus.CREATED) @PostMapping("/event") - suspend fun createUser(@Valid @RequestBody body: Mono): CreateEventResponse + suspend fun createEvent(@Valid @RequestBody body: Mono): CreateEventResponse } \ No newline at end of file From 8d891b31021aaf5e054522125371c6ba3d99ce74 Mon Sep 17 00:00:00 2001 From: RbertKo Date: Fri, 13 Aug 2021 02:38:19 +0900 Subject: [PATCH 08/12] feat: add createEvent Svc --- .../application/EventService.kt | 4 +++- .../application/dto/event/CreateEventResponse.kt | 16 +++------------- 2 files changed, 6 insertions(+), 14 deletions(-) diff --git a/src/main/kotlin/com/example/attendanceapimono/application/EventService.kt b/src/main/kotlin/com/example/attendanceapimono/application/EventService.kt index 970f13a..816bb8e 100644 --- a/src/main/kotlin/com/example/attendanceapimono/application/EventService.kt +++ b/src/main/kotlin/com/example/attendanceapimono/application/EventService.kt @@ -6,16 +6,18 @@ import com.example.attendanceapimono.domain.event.EventRepository import kotlinx.coroutines.async import kotlinx.coroutines.runBlocking import org.springframework.stereotype.Service +import org.springframework.transaction.annotation.Transactional @Service class EventService ( private val eventRepository: EventRepository ) { + @Transactional fun createEvent(dto: CreateEventRequest): CreateEventResponse = runBlocking { val event = dto.entity() eventRepository.save(event) - CreateEventResponse(event) + CreateEventResponse(eventId = event.id) } } \ No newline at end of file diff --git a/src/main/kotlin/com/example/attendanceapimono/application/dto/event/CreateEventResponse.kt b/src/main/kotlin/com/example/attendanceapimono/application/dto/event/CreateEventResponse.kt index e97f2ef..a2d8a01 100644 --- a/src/main/kotlin/com/example/attendanceapimono/application/dto/event/CreateEventResponse.kt +++ b/src/main/kotlin/com/example/attendanceapimono/application/dto/event/CreateEventResponse.kt @@ -1,7 +1,7 @@ package com.example.attendanceapimono.application.dto.event -import com.example.attendanceapimono.domain.event.Event import io.swagger.v3.oas.annotations.media.Schema +import java.util.* @Schema( title = "이벤트 등록 후 반환", @@ -10,22 +10,12 @@ import io.swagger.v3.oas.annotations.media.Schema ) data class CreateEventResponse ( @Schema(description = "생성된 event") - val event: Event, + val eventId: UUID, ) { companion object { const val Example = """ { - "id": "123e4567-e89b-12d3-a456-426614174000", - "generationID": 6, - "title": "오리엔테이션", - "description": "함께 모여 앞으로의 방향에 대해 이야기 나눠 보아요.", - "isDone": false, - "expectedAt": "2021-08-21T14:00:00.000", - "lateDiffMinute": 10, - "absentDiffMinute": 60, - "startAt": null, - "createdAt": "2021-08-12T22:13:47.245", - "updatedAt": "2021-08-12T22:13:47.245" + "id": "123e4567-e89b-12d3-a456-426614174000" } """ } From 7e92ae85b2f546f2ce8140912a9339e688b8ddfc Mon Sep 17 00:00:00 2001 From: RbertKo Date: Fri, 13 Aug 2021 02:38:32 +0900 Subject: [PATCH 09/12] feat: edit security for event --- .../attendanceapimono/adapter/infra/config/SecurityConfig.kt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main/kotlin/com/example/attendanceapimono/adapter/infra/config/SecurityConfig.kt b/src/main/kotlin/com/example/attendanceapimono/adapter/infra/config/SecurityConfig.kt index 959abb0..6851c06 100644 --- a/src/main/kotlin/com/example/attendanceapimono/adapter/infra/config/SecurityConfig.kt +++ b/src/main/kotlin/com/example/attendanceapimono/adapter/infra/config/SecurityConfig.kt @@ -22,6 +22,8 @@ class SecurityConfig( private val permitAllUrls = listOf( PermitSet(HttpMethod.GET, "/favicon.ico"), + PermitSet(HttpMethod.POST, "/event"), + PermitSet(HttpMethod.POST, "/user"), PermitSet(HttpMethod.POST, "/user/login"), From 4bcc44d55a198a84219b2811daee2340896ef8dc Mon Sep 17 00:00:00 2001 From: RbertKo Date: Thu, 19 Aug 2021 03:08:40 +0900 Subject: [PATCH 10/12] refactor: change roles visibility public to private --- .../attendanceapimono/adapter/infra/security/UserPrincipal.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/kotlin/com/example/attendanceapimono/adapter/infra/security/UserPrincipal.kt b/src/main/kotlin/com/example/attendanceapimono/adapter/infra/security/UserPrincipal.kt index 228e476..f88cbcb 100644 --- a/src/main/kotlin/com/example/attendanceapimono/adapter/infra/security/UserPrincipal.kt +++ b/src/main/kotlin/com/example/attendanceapimono/adapter/infra/security/UserPrincipal.kt @@ -19,7 +19,7 @@ data class RoleAdapter(val role: UserRole): GrantedAuthority { class UserPrincipal( val id: UUID, - val roles: List + private val roles: List ) : UserDetails { override fun getAuthorities(): MutableCollection { return roles.toMutableList() From 861b35c00b038675ad92189ef97ba0d5dccb1219 Mon Sep 17 00:00:00 2001 From: RbertKo Date: Thu, 19 Aug 2021 03:09:17 +0900 Subject: [PATCH 11/12] feat: remove POST /event --- .../attendanceapimono/adapter/infra/config/SecurityConfig.kt | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/main/kotlin/com/example/attendanceapimono/adapter/infra/config/SecurityConfig.kt b/src/main/kotlin/com/example/attendanceapimono/adapter/infra/config/SecurityConfig.kt index 6851c06..2052acd 100644 --- a/src/main/kotlin/com/example/attendanceapimono/adapter/infra/config/SecurityConfig.kt +++ b/src/main/kotlin/com/example/attendanceapimono/adapter/infra/config/SecurityConfig.kt @@ -6,6 +6,7 @@ import com.example.attendanceapimono.adapter.infra.security.SecurityContextRepos import org.springframework.context.annotation.Bean import org.springframework.context.annotation.Configuration import org.springframework.http.HttpMethod +import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity import org.springframework.security.config.annotation.method.configuration.EnableReactiveMethodSecurity import org.springframework.security.config.annotation.web.reactive.EnableWebFluxSecurity import org.springframework.security.config.web.server.ServerHttpSecurity @@ -22,8 +23,6 @@ class SecurityConfig( private val permitAllUrls = listOf( PermitSet(HttpMethod.GET, "/favicon.ico"), - PermitSet(HttpMethod.POST, "/event"), - PermitSet(HttpMethod.POST, "/user"), PermitSet(HttpMethod.POST, "/user/login"), From f8b8b1e072208050583b05829207a228393134d4 Mon Sep 17 00:00:00 2001 From: RbertKo Date: Thu, 19 Aug 2021 03:09:49 +0900 Subject: [PATCH 12/12] feat: add annotation about authroize --- .../example/attendanceapimono/adapter/present/api/EventAPI.kt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/main/kotlin/com/example/attendanceapimono/adapter/present/api/EventAPI.kt b/src/main/kotlin/com/example/attendanceapimono/adapter/present/api/EventAPI.kt index e997b56..2c9754d 100644 --- a/src/main/kotlin/com/example/attendanceapimono/adapter/present/api/EventAPI.kt +++ b/src/main/kotlin/com/example/attendanceapimono/adapter/present/api/EventAPI.kt @@ -10,6 +10,7 @@ import io.swagger.v3.oas.annotations.responses.ApiResponse import io.swagger.v3.oas.annotations.tags.Tag import org.springframework.http.HttpStatus import org.springframework.http.MediaType +import org.springframework.security.access.prepost.PreAuthorize import org.springframework.web.bind.annotation.PostMapping import org.springframework.web.bind.annotation.RequestBody import org.springframework.web.bind.annotation.ResponseStatus @@ -39,6 +40,8 @@ interface EventAPI { )], ) @ResponseStatus(HttpStatus.CREATED) + @JWTTokenV1 + @PreAuthorize("hasRole('MASTER') or hasRole('STAFF')") @PostMapping("/event") suspend fun createEvent(@Valid @RequestBody body: Mono): CreateEventResponse } \ No newline at end of file