Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
65 commits
Select commit Hold shift + click to select a range
afa78ae
chore ( #10 ) : build-logic 삭제
coehgns Jun 12, 2025
b866526
build ( #10 ) : settings.gradle.kts에 build-logic 삭제
coehgns Jun 12, 2025
2bf1001
build ( #10 ) : Dependencies
coehgns Jun 12, 2025
9fb28fe
build ( #10 ) : Plugin
coehgns Jun 12, 2025
4c200c1
build ( #10 ) : PluginVersion
coehgns Jun 12, 2025
faf70e0
build ( #10 ) : DependencyVersion
coehgns Jun 12, 2025
f15eb86
build ( #10 ) : build.gradle.kts
coehgns Jun 13, 2025
8206fd1
feat ( #9 ) : Equus-Schedule 레거시 코드 적용
coehgns Jun 14, 2025
f968436
feat ( #11 ) : UpdateSchedulesRequest
coehgns Jul 28, 2025
0ab7b82
feat ( #11 ) : SchedulesResponse
coehgns Jul 28, 2025
29641f1
feat ( #11 ) : ScheduleDto
coehgns Jul 28, 2025
62c0f90
feat ( #11 ) : ScheduleWebAdapter
coehgns Jul 28, 2025
eebef8a
feat ( #11 ) : ScheduleJpaEntity
coehgns Jul 28, 2025
4b92ed4
feat ( #11 ) : ScheduleMapper
coehgns Jul 28, 2025
55604f0
feat ( #11 ) : ScheduleRepository
coehgns Jul 28, 2025
5d9a70d
feat ( #11 ) : SchedulePersistenceAdapter
coehgns Jul 28, 2025
3f69b54
feat ( #11 ) : InvalidScheduleRequestException
coehgns Jul 28, 2025
cba56da
feat ( #11 ) : InvalidScheduleSequenceException
coehgns Jul 28, 2025
7e88f0f
feat ( #11 ) : ScheduleNotFoundException
coehgns Jul 28, 2025
ec50213
feat ( #11 ) : ScheduleFacadeUseCase
coehgns Jul 28, 2025
f36d1e1
feat ( #11 ) : ScheduleUseCase
coehgns Jul 28, 2025
3a720db
feat ( #11 ) : FindSchedulePort
coehgns Jul 28, 2025
8000c22
feat ( #11 ) : SaveSchedulePort
coehgns Jul 28, 2025
aac4d6c
feat ( #11 ) : ScheduleService
coehgns Jul 28, 2025
6f9b89f
feat ( #11 ) : ScheduleFacade
coehgns Jul 28, 2025
9b7a1e1
feat ( #11 ) : ConfigurationPropertiesConfig
coehgns Jul 28, 2025
c40f300
feat ( #11 ) : CasperException.kt
coehgns Jul 28, 2025
8c9d530
feat ( #11 ) : ErrorCode
coehgns Jul 28, 2025
8e277df
feat ( #11 ) : ErrorResponse
coehgns Jul 28, 2025
508141d
feat ( #11 ) : GlobalExceptionFilter
coehgns Jul 28, 2025
dc78882
feat ( #11 ) : GlobalExceptionHandler
coehgns Jul 28, 2025
9c8d993
feat ( #11 ) : ExpiredTokenException
coehgns Jul 28, 2025
e997bfd
feat ( #11 ) : InternalServerErrorException
coehgns Jul 28, 2025
35efa8b
feat ( #11 ) : InvalidTokenException
coehgns Jul 28, 2025
aca2836
feat ( #11 ) : JwtFilter.kt
coehgns Jul 28, 2025
c170f56
feat ( #11 ) : JwtProperties
coehgns Jul 28, 2025
ea6c1c2
feat ( #11 ) : FilterConfig
coehgns Jul 28, 2025
2035138
feat ( #11 ) : SecurityConfig
coehgns Jul 28, 2025
d4c3488
docs ( #11 ) : CasperScheduleApplication
coehgns Jul 28, 2025
62425bd
docs ( #11 ) : CasperScheduleApplicationTests
coehgns Jul 28, 2025
b2d2482
feat ( #11 ) : GrpcExceptionHandler
coehgns Jul 28, 2025
8b10cbc
feat ( #11 ) : TypeMappingException
coehgns Jul 28, 2025
7d52098
feat ( #11 ) : ScheduleGrpcMapper
coehgns Jul 28, 2025
24240c7
feat ( #11 ) : ScheduleGrpcService
coehgns Jul 28, 2025
11211ff
feat ( #11 ) : schedule.proto
coehgns Jul 28, 2025
7296dbc
feat ( #11 ) : Type
coehgns Jul 28, 2025
2cc5e61
feat ( #11 ) : Schedule
coehgns Jul 28, 2025
9df3797
chore ( #11 ) : 불필요한 로직 삭제
coehgns Jul 28, 2025
b4b6adf
refactor ( #11 ) : 폴더 구조 리팩토링
coehgns Jul 28, 2025
f09c955
refactor ( #11 ) : 폴더 구조 리팩토링
coehgns Jul 28, 2025
50fc181
chore ( #11 ) : import 수정
coehgns Jul 28, 2025
841e79b
chore ( #12 ) : settings.gradle.kts에 casper-schedule 모듈 정보 추가
coehgns Jul 28, 2025
8fcd4a7
chore ( #12 ) : casper-schedule 모듈 분리
coehgns Jul 28, 2025
376bf5b
chore ( #12 ) : casper-schedule 모듈 분리
coehgns Jul 28, 2025
e5bdd88
refactor ( #11 ) : 폴더 구조 리팩토링
coehgns Jul 28, 2025
a170e80
docs ( #11 ) : kdoc
coehgns Jul 28, 2025
3783448
docs ( #11 ) : kdoc
coehgns Jul 28, 2025
4790955
build ( #11 ) : bootJar
coehgns Jul 28, 2025
dd37d75
build ( #13 ) : gRPC 관련 의존성 추가
coehgns Jul 28, 2025
aa5910d
build ( #11 ) : magicNumber active false
coehgns Jul 28, 2025
912635f
chore ( #11 ) : reset
coehgns Jul 28, 2025
1eaf963
feat ( #13 ) : GrpcExceptionHandler
coehgns Jul 28, 2025
5de2f17
feat ( #13 ) : ScheduleGrpcMapper
coehgns Jul 28, 2025
85f5724
feat ( #13 ) : TypeMappingException.kt
coehgns Jul 28, 2025
925ad6c
feat ( #13 ) : ScheduleGrpcService
coehgns Jul 28, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 0 additions & 11 deletions build-logic/build.gradle.kts

This file was deleted.

17 changes: 0 additions & 17 deletions build-logic/settings.gradle.kts

This file was deleted.

15 changes: 0 additions & 15 deletions build-logic/src/main/kotlin/io/casper/build/TestClass.kt

This file was deleted.

6 changes: 5 additions & 1 deletion build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ plugins {
kotlin("plugin.spring") version "1.9.23"
id("org.springframework.boot") version "3.4.4"
id("io.spring.dependency-management") version "1.1.7"
id("org.jlleitschuh.gradle.ktlint").version("12.1.1")
id("org.jlleitschuh.gradle.ktlint").version("11.5.1")
id("io.gitlab.arturbosch.detekt") version "1.23.6"
id("casper.documentation-convention")
}
Expand Down Expand Up @@ -76,3 +76,7 @@ tasks.withType<io.gitlab.arturbosch.detekt.Detekt>().configureEach {

jvmTarget = ("17") // Detekt가 사용하는 JVM 타겟을 Java 17로 지정
}

tasks.withType<org.springframework.boot.gradle.tasks.bundling.BootJar> {
mainClass.set("hs.kr.entrydsm.schedule.CasperScheduleApplication")
}
7 changes: 7 additions & 0 deletions buildSrc/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
plugins {
`kotlin-dsl`
}

repositories {
mavenCentral()
}
41 changes: 41 additions & 0 deletions buildSrc/src/main/kotlin/Dependencies.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
object Dependencies {
// Spring Boot
const val SPRING_BOOT_STARTER = "org.springframework.boot:spring-boot-starter"
const val SPRING_BOOT_STARTER_WEB = "org.springframework.boot:spring-boot-starter-web"
const val SPRING_BOOT_STARTER_DATA_JPA = "org.springframework.boot:spring-boot-starter-data-jpa"
const val SPRING_BOOT_STARTER_DATA_REDIS = "org.springframework.boot:spring-boot-starter-data-redis"
const val SPRING_BOOT_STARTER_SECURITY = "org.springframework.boot:spring-boot-starter-security"
const val SPRING_BOOT_STARTER_VALIDATION = "org.springframework.boot:spring-boot-starter-validation"
const val SPRING_BOOT_STARTER_TEST = "org.springframework.boot:spring-boot-starter-test"

// Kotlin
const val KOTLIN_REFLECT = "org.jetbrains.kotlin:kotlin-reflect"
const val KOTLIN_TEST_JUNIT5 = "org.jetbrains.kotlin:kotlin-test-junit5"

// Database
const val MYSQL_CONNECTOR = "com.mysql:mysql-connector-j"

// JSON
const val JACKSON_MODULE_KOTLIN = "com.fasterxml.jackson.module:jackson-module-kotlin"
const val ORG_JSON = "org.json:json:${DependencyVersion.ORG_JSON}"

// JWT
const val JWT_API = "io.jsonwebtoken:jjwt-api:${DependencyVersion.JWT}"
const val JWT_IMPL = "io.jsonwebtoken:jjwt-impl:${DependencyVersion.JWT}"
const val JWT_JACKSON = "io.jsonwebtoken:jjwt-jackson:${DependencyVersion.JWT}"

// MapStruct
const val MAPSTRUCT = "org.mapstruct:mapstruct:${DependencyVersion.MAPSTRUCT}"
const val MAPSTRUCT_PROCESSOR = "org.mapstruct:mapstruct-processor:${DependencyVersion.MAPSTRUCT}"

// Test
const val JUNIT_PLATFORM_LAUNCHER = "org.junit.platform:junit-platform-launcher"

// gRPC
const val GRPC_NETTY_SHADED = "io.grpc:grpc-netty-shaded:${DependencyVersion.GRPC}"
const val GRPC_PROTOBUF = "io.grpc:grpc-protobuf:${DependencyVersion.GRPC}"
const val GRPC_STUB = "io.grpc:grpc-stub:${DependencyVersion.GRPC}"
const val GRPC_KOTLIN_STUB = "io.grpc:grpc-kotlin-stub:${DependencyVersion.GRPC_KOTLIN}"
const val PROTOBUF_KOTLIN = "com.google.protobuf:protobuf-kotlin:${DependencyVersion.PROTOBUF}"
const val GRPC_TESTING = "io.grpc:grpc-testing:${DependencyVersion.GRPC}"
}
15 changes: 15 additions & 0 deletions buildSrc/src/main/kotlin/DependencyVersion.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
object DependencyVersion {
const val KOTLIN = "1.9.25"
const val SPRING_BOOT = "3.4.4"
const val SPRING_DEPENDENCY_MANAGEMENT = "1.1.7"
const val DETEKT = "1.23.6"
const val KTLINT = "12.1.1"

const val JWT = "0.11.5"
const val ORG_JSON = "20230227"
const val MAPSTRUCT = "1.6.0"

const val GRPC = "1.61.1"
const val GRPC_KOTLIN = "1.4.1"
const val PROTOBUF = "3.25.3"
}
11 changes: 11 additions & 0 deletions buildSrc/src/main/kotlin/Plugin.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
object Plugin {
const val KOTLIN_JVM = "org.jetbrains.kotlin.jvm"
const val KOTLIN_SPRING = "org.jetbrains.kotlin.plugin.spring"
const val KOTLIN_KAPT = "org.jetbrains.kotlin.kapt"
const val SPRING_BOOT = "org.springframework.boot"
const val SPRING_DEPENDENCY_MANAGEMENT = "io.spring.dependency-management"
const val DETEKT = "io.gitlab.arturbosch.detekt"
const val KTLINT = "org.jlleitschuh.gradle.ktlint"
const val CASPER_DOCUMENTATION = "casper.documentation-convention"
const val PROTOBUF = "com.google.protobuf"
}
8 changes: 8 additions & 0 deletions buildSrc/src/main/kotlin/PluginVersion.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
object PluginVersion {
const val KOTLIN_VERSION = "1.9.23"
const val SPRING_BOOT_VERSION = "3.4.4"
const val SPRING_DEPENDENCY_MANAGEMENT_VERSION = "1.1.7"
const val DETEKT_VERSION = "1.23.6"
const val KTLINT_VERSION = "12.1.1"
const val PROTOBUF_VERSION = "0.9.4"
}
108 changes: 108 additions & 0 deletions casper-schedule/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
import org.gradle.kotlin.dsl.withType
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile

plugins {
id(Plugin.KOTLIN_JVM) version PluginVersion.KOTLIN_VERSION
id(Plugin.KOTLIN_SPRING) version PluginVersion.KOTLIN_VERSION
id(Plugin.KOTLIN_KAPT)
id(Plugin.SPRING_BOOT) version PluginVersion.SPRING_BOOT_VERSION
id(Plugin.SPRING_DEPENDENCY_MANAGEMENT) version PluginVersion.SPRING_DEPENDENCY_MANAGEMENT_VERSION
id(Plugin.CASPER_DOCUMENTATION)
id(Plugin.PROTOBUF) version PluginVersion.PROTOBUF_VERSION
}

repositories {
mavenCentral()
}

dependencies {
// 스프링 부트 기본 기능
implementation(Dependencies.SPRING_BOOT_STARTER)

// 코틀린 리플렉션
implementation(Dependencies.KOTLIN_REFLECT)

// 스프링 부트 테스트 도구
testImplementation(Dependencies.SPRING_BOOT_STARTER_TEST)

// 코틀린 + JUnit5 테스트
testImplementation(Dependencies.KOTLIN_TEST_JUNIT5)

// JUnit5 실행 런처
testRuntimeOnly(Dependencies.JUNIT_PLATFORM_LAUNCHER)

// 웹 관련
implementation(Dependencies.SPRING_BOOT_STARTER_WEB)

// 데이터베이스
implementation(Dependencies.SPRING_BOOT_STARTER_DATA_JPA)
implementation(Dependencies.SPRING_BOOT_STARTER_DATA_REDIS)
runtimeOnly(Dependencies.MYSQL_CONNECTOR)

// 보안
implementation(Dependencies.SPRING_BOOT_STARTER_SECURITY)

// 검증
implementation(Dependencies.SPRING_BOOT_STARTER_VALIDATION)

// JSON 처리
implementation(Dependencies.JACKSON_MODULE_KOTLIN)
implementation(Dependencies.ORG_JSON)

// JWT
implementation(Dependencies.JWT_API)
implementation(Dependencies.JWT_IMPL)
runtimeOnly(Dependencies.JWT_JACKSON)

implementation(Dependencies.MAPSTRUCT)
kapt(Dependencies.MAPSTRUCT_PROCESSOR)

//grpc
implementation(Dependencies.GRPC_NETTY_SHADED)
implementation(Dependencies.GRPC_PROTOBUF)
implementation(Dependencies.GRPC_STUB)
implementation(Dependencies.GRPC_KOTLIN_STUB)
implementation(Dependencies.PROTOBUF_KOTLIN)
testImplementation(Dependencies.GRPC_TESTING)
implementation(Dependencies.GRPC_SERVER_SPRING)
implementation(Dependencies.GOGGLE_PROTOBUF)
}


protobuf {
protoc {
artifact = "com.google.protobuf:protoc:${DependencyVersion.PROTOBUF}"
}
plugins {
create("grpc") {
artifact = "io.grpc:protoc-gen-grpc-java:${DependencyVersion.GRPC}"
}
create("grpckt") {
artifact = "io.grpc:protoc-gen-grpc-kotlin:${DependencyVersion.GRPC_KOTLIN}:jdk8@jar"
}
}
generateProtoTasks {
all().forEach {
it.plugins {
create("grpc")
create("grpckt")
}
}

}

}

kotlin {
jvmToolchain(17)
}

tasks.withType<KotlinCompile> {
kotlinOptions {
freeCompilerArgs += "-Xjsr305=strict"
}
}

tasks.withType<Test> {
useJUnitPlatform()
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package hs.kr.entrydsm.schedule

import org.springframework.boot.autoconfigure.SpringBootApplication
import org.springframework.boot.runApplication

/**
* Casper Schedule 애플리케이션의 진입점입니다.
* Spring Boot 애플리케이션을 부트스트랩하고 실행하는 클래스입니다.
*/
@SpringBootApplication
class CasperScheduleApplication

/**
* 애플리케이션의 진입점입니다.
* Spring Boot 애플리케이션을 실행합니다.
*
* @param args 명령줄 인수 배열
*/
fun main(args: Array<String>) {
runApplication<CasperScheduleApplication>(*args)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
package hs.kr.entrydsm.schedule.domain.schedule.adapter.`in`

import hs.kr.entrydsm.schedule.domain.schedule.adapter.`in`.dto.ScheduleDto
import hs.kr.entrydsm.schedule.domain.schedule.adapter.`in`.dto.request.UpdateSchedulesRequest
import hs.kr.entrydsm.schedule.domain.schedule.adapter.`in`.dto.response.SchedulesResponse
import hs.kr.entrydsm.schedule.domain.schedule.application.port.`in`.QueryScheduleByTypeUseCase
import hs.kr.entrydsm.schedule.domain.schedule.application.port.`in`.QuerySchedulesUseCase
import hs.kr.entrydsm.schedule.domain.schedule.application.port.`in`.UpdateSchedulesUseCase
import jakarta.validation.Valid
import org.springframework.web.bind.annotation.GetMapping
import org.springframework.web.bind.annotation.PatchMapping
import org.springframework.web.bind.annotation.RequestBody
import org.springframework.web.bind.annotation.RequestMapping
import org.springframework.web.bind.annotation.RequestParam
import org.springframework.web.bind.annotation.RestController

/**
* 스케줄 관련 HTTP 요청을 처리하는 REST 컨트롤러입니다.
* 클라이언트의 요청을 적절한 유스케이스에 위임하고 결과를 반환합니다.
*
* @property queryScheduleByTypeUseCase 타입별 스케줄 조회 유스케이스
* @property querySchedulesUseCase 모든 스케줄 조회 유스케이스
* @property updateSchedulesUseCase 스케줄 업데이트 유스케이스
*/
@RestController
@RequestMapping("/schedule")
class ScheduleWebAdapter(
private val queryScheduleByTypeUseCase: QueryScheduleByTypeUseCase,
private val querySchedulesUseCase: QuerySchedulesUseCase,
private val updateSchedulesUseCase: UpdateSchedulesUseCase
) {
@GetMapping(params = ["type"])
fun queryScheduleByType(
@RequestParam type: String
): ScheduleDto = queryScheduleByTypeUseCase.execute(type)

/**
* 모든 일정을 조회합니다.
*
* @return 모든 일정 정보를 담은 응답 객체
*/
@GetMapping
fun querySchedules(): SchedulesResponse = querySchedulesUseCase.execute()

/**
* 일정을 일괄 업데이트합니다.
*
* @param request 업데이트할 일정 목록을 담은 요청 객체
* @return 업데이트된 일정 정보를 담은 응답 객체
*/
@PatchMapping
fun updateSchedules(
@RequestBody @Valid
request: UpdateSchedulesRequest
) = updateSchedulesUseCase.execute(request)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package hs.kr.entrydsm.schedule.domain.schedule.adapter.`in`.dto

import com.fasterxml.jackson.annotation.JsonFormat
import hs.kr.entrydsm.schedule.domain.schedule.model.type.Type
import jakarta.validation.constraints.NotNull
import java.time.LocalDateTime

/**
* 스케줄 정보를 담는 데이터 전송 객체(DTO)입니다.
*
* @property type 스케줄 유형 (START_DATE, FIRST_ANNOUNCEMENT, INTERVIEW, SECOND_ANNOUNCEMENT, END_DATE)
* @property date 스케줄 날짜 및 시간 (Asia/Seoul 시간대, yyyy-MM-dd'T'HH:mm:ss 형식)
*/
data class ScheduleDto(
@field:NotNull
val type: Type,
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'HH:mm:ss", timezone = "Asia/Seoul")
@field:NotNull
val date: LocalDateTime
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package hs.kr.entrydsm.schedule.domain.schedule.adapter.`in`.dto.request

import hs.kr.entrydsm.schedule.domain.schedule.adapter.`in`.dto.ScheduleDto
import jakarta.validation.constraints.NotNull

/**
* 스케줄 목록을 업데이트하기 위한 요청 데이터 클래스입니다.
*
* @property schedules 업데이트할 스케줄 목록 (null 불가능)
*/
data class UpdateSchedulesRequest(
@field:NotNull
val schedules: List<ScheduleDto>
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package hs.kr.entrydsm.schedule.domain.schedule.adapter.`in`.dto.response

import hs.kr.entrydsm.schedule.domain.schedule.adapter.`in`.dto.ScheduleDto

/**
* 스케줄 목록과 현재 상태를 포함하는 응답 데이터 클래스입니다.
*
* @property schedules 스케줄 정보 목록 (null 가능한 ScheduleDto 리스트)
* @property currentStatus 현재 스케줄 상태를 나타내는 문자열
*/
data class SchedulesResponse(
val schedules: List<ScheduleDto?>,
val currentStatus: String
)
Loading
Loading