Skip to content
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ data class RoleAdapter(val role: UserRole): GrantedAuthority {

class UserPrincipal(
val id: UUID,
val roles: List<RoleAdapter>
private val roles: List<RoleAdapter>
) : UserDetails {
override fun getAuthorities(): MutableCollection<out GrantedAuthority> {
return roles.toMutableList()
Expand Down
Original file line number Diff line number Diff line change
@@ -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<CreateEventRequest>): CreateEventResponse {
return body.handleValidationCatch()
.map(eventService::createEvent)
.awaitSingle()
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,47 @@
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.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
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)
@JWTTokenV1
@PreAuthorize("hasRole('MASTER') or hasRole('STAFF')")
@PostMapping("/event")
suspend fun createEvent(@Valid @RequestBody body: Mono<CreateEventRequest>): CreateEventResponse
}
Original file line number Diff line number Diff line change
@@ -1,10 +1,23 @@
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
import org.springframework.transaction.annotation.Transactional

@Service
class EventService {
fun createEvent() {
class EventService (
private val eventRepository: EventRepository
) {
@Transactional
fun createEvent(dto: CreateEventRequest): CreateEventResponse = runBlocking {
val event = dto.entity()

eventRepository.save(event)

CreateEventResponse(eventId = event.id)
}
}
Original file line number Diff line number Diff line change
@@ -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 = "이벤트 등록 요청",
Expand All @@ -26,12 +29,27 @@ 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),
startAt = LocalDateTime.parse(this.expectedAt),
lateDiffMinutes = this.lateDiffMinute,
absentDiffMinutes = this.absentDiffMinute,
createdAt = LocalDateTime.now(),
updatedAt = LocalDateTime.now()
)

companion object {
const val Example = """
{
Expand Down
Original file line number Diff line number Diff line change
@@ -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 = "이벤트 등록 후 반환",
Expand All @@ -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"
}
"""
}
Expand Down
5 changes: 4 additions & 1 deletion src/main/resources/application-local.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,7 @@ spring:
format_sql: true
jwt:
secret: test_QiPScSmMJnGrGCwTm*Xi0m1yAHe3KfAkhH&VpsENjwqfGP%grBdmv4Ee%GYZhNj2S4y6@$8KORZE9dsiw%v*ugKcba9x8CN18!Pl
expires: 31536000000000
expires: 31536000000000
event:
late-diff-minute: 10
absent-diff-minute: 50
5 changes: 4 additions & 1 deletion src/main/resources/application-prod.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,7 @@ spring:
format_sql: true
jwt:
secret: ${JWT_SECRET}
expires: ${JWT_EXPIRES}
expires: ${JWT_EXPIRES}
event:
late-diff-minute: ${DDD_LATE_DIFF_MINUTE}
absent-diff-minute: ${DDD_ABSENT_DIFF_MINUTE}