From 5e33f6dcdad7c76cfdaa174b56d3a9fe0c70abd3 Mon Sep 17 00:00:00 2001 From: dae won <eodnjs01477@gmail.com> Date: Tue, 11 Mar 2025 22:43:56 +0900 Subject: [PATCH 1/9] =?UTF-8?q?feat:=20admin=20domain=20repository=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80=20=EB=B0=8F=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../admin/domain/crag/ColorAdminRepository.kt | 12 +++++++++ .../admin/domain/crag/CragAdminRepository.kt | 12 +++++++++ .../admin/domain/crag/GradeAdminRepository.kt | 11 ++++++++ .../global/properties/KakaoMapProperties.kt | 9 +++++++ clog-infrastructure/build.gradle.kts | 1 + .../infrastructure/admin/ColorAdminAdapter.kt | 25 ++++++++++++++++++ .../infrastructure/admin/CragAdminAdapter.kt | 26 +++++++++++++++++++ .../infrastructure/admin/GradeAdminAdapter.kt | 23 ++++++++++++++++ .../infrastructure/crag/ColorJpaRepository.kt | 5 +++- 9 files changed, 123 insertions(+), 1 deletion(-) create mode 100644 clog-admin/src/main/kotlin/org/depromeet/clog/server/admin/domain/crag/ColorAdminRepository.kt create mode 100644 clog-admin/src/main/kotlin/org/depromeet/clog/server/admin/domain/crag/CragAdminRepository.kt create mode 100644 clog-admin/src/main/kotlin/org/depromeet/clog/server/admin/domain/crag/GradeAdminRepository.kt create mode 100644 clog-global-utils/src/main/kotlin/org/depromeet/clog/server/global/properties/KakaoMapProperties.kt create mode 100644 clog-infrastructure/src/main/kotlin/org/depromeet/clog/server/infrastructure/admin/ColorAdminAdapter.kt create mode 100644 clog-infrastructure/src/main/kotlin/org/depromeet/clog/server/infrastructure/admin/CragAdminAdapter.kt create mode 100644 clog-infrastructure/src/main/kotlin/org/depromeet/clog/server/infrastructure/admin/GradeAdminAdapter.kt diff --git a/clog-admin/src/main/kotlin/org/depromeet/clog/server/admin/domain/crag/ColorAdminRepository.kt b/clog-admin/src/main/kotlin/org/depromeet/clog/server/admin/domain/crag/ColorAdminRepository.kt new file mode 100644 index 00000000..b7d23548 --- /dev/null +++ b/clog-admin/src/main/kotlin/org/depromeet/clog/server/admin/domain/crag/ColorAdminRepository.kt @@ -0,0 +1,12 @@ +package org.depromeet.clog.server.admin.domain.crag + +import org.depromeet.clog.server.domain.crag.domain.Color + +interface ColorAdminRepository { + + fun save(color: Color): Color + + fun findAll(): List<Color> + + fun findByNameAndHex(name: String, hex: String): Color? +} diff --git a/clog-admin/src/main/kotlin/org/depromeet/clog/server/admin/domain/crag/CragAdminRepository.kt b/clog-admin/src/main/kotlin/org/depromeet/clog/server/admin/domain/crag/CragAdminRepository.kt new file mode 100644 index 00000000..07fb203c --- /dev/null +++ b/clog-admin/src/main/kotlin/org/depromeet/clog/server/admin/domain/crag/CragAdminRepository.kt @@ -0,0 +1,12 @@ +package org.depromeet.clog.server.admin.domain.crag + +import org.depromeet.clog.server.domain.crag.domain.Crag + +interface CragAdminRepository { + + fun save(crag: Crag): Crag + + fun findById(id: Long): Crag? + + fun findAll(): List<Crag> +} diff --git a/clog-admin/src/main/kotlin/org/depromeet/clog/server/admin/domain/crag/GradeAdminRepository.kt b/clog-admin/src/main/kotlin/org/depromeet/clog/server/admin/domain/crag/GradeAdminRepository.kt new file mode 100644 index 00000000..ead15377 --- /dev/null +++ b/clog-admin/src/main/kotlin/org/depromeet/clog/server/admin/domain/crag/GradeAdminRepository.kt @@ -0,0 +1,11 @@ +package org.depromeet.clog.server.admin.domain.crag + +import org.depromeet.clog.server.domain.crag.domain.Crag +import org.depromeet.clog.server.domain.crag.domain.Grade + +interface GradeAdminRepository { + + fun save(grade: Grade): Grade + + fun findByCrag(crag: Crag): List<Grade> +} diff --git a/clog-global-utils/src/main/kotlin/org/depromeet/clog/server/global/properties/KakaoMapProperties.kt b/clog-global-utils/src/main/kotlin/org/depromeet/clog/server/global/properties/KakaoMapProperties.kt new file mode 100644 index 00000000..74874743 --- /dev/null +++ b/clog-global-utils/src/main/kotlin/org/depromeet/clog/server/global/properties/KakaoMapProperties.kt @@ -0,0 +1,9 @@ +package org.depromeet.clog.server.global.properties + +import org.springframework.boot.context.properties.ConfigurationProperties + +@ConfigurationProperties(prefix = "kakao.map") +data class KakaoMapProperties( + val restApiKey: String, + val localSearchBaseUrl: String +) diff --git a/clog-infrastructure/build.gradle.kts b/clog-infrastructure/build.gradle.kts index d5a9b76c..ce50517c 100644 --- a/clog-infrastructure/build.gradle.kts +++ b/clog-infrastructure/build.gradle.kts @@ -1,6 +1,7 @@ dependencies { implementation(project(":clog-global-utils")) implementation(project(":clog-domain")) + implementation(project(":clog-admin")) implementation("org.springframework.boot:spring-boot-starter-data-jpa") implementation("com.github.gavlyukovskiy:p6spy-spring-boot-starter:1.10.0") diff --git a/clog-infrastructure/src/main/kotlin/org/depromeet/clog/server/infrastructure/admin/ColorAdminAdapter.kt b/clog-infrastructure/src/main/kotlin/org/depromeet/clog/server/infrastructure/admin/ColorAdminAdapter.kt new file mode 100644 index 00000000..8ce2f69a --- /dev/null +++ b/clog-infrastructure/src/main/kotlin/org/depromeet/clog/server/infrastructure/admin/ColorAdminAdapter.kt @@ -0,0 +1,25 @@ +package org.depromeet.clog.server.infrastructure.admin + +import org.depromeet.clog.server.admin.domain.crag.ColorAdminRepository +import org.depromeet.clog.server.domain.crag.domain.Color +import org.depromeet.clog.server.infrastructure.crag.ColorEntity +import org.depromeet.clog.server.infrastructure.crag.ColorJpaRepository +import org.springframework.stereotype.Component + +@Component +class ColorAdminAdapter( + private val colorJpaRepository: ColorJpaRepository +) : ColorAdminRepository { + + override fun save(color: Color): Color { + return colorJpaRepository.save(ColorEntity.fromDomain(color)).toDomain() + } + + override fun findAll(): List<Color> { + return colorJpaRepository.findAll().map { it.toDomain() } + } + + override fun findByNameAndHex(name: String, hex: String): Color? { + return colorJpaRepository.findByNameAndHex(name, hex).toDomain() + } +} diff --git a/clog-infrastructure/src/main/kotlin/org/depromeet/clog/server/infrastructure/admin/CragAdminAdapter.kt b/clog-infrastructure/src/main/kotlin/org/depromeet/clog/server/infrastructure/admin/CragAdminAdapter.kt new file mode 100644 index 00000000..21bf79bc --- /dev/null +++ b/clog-infrastructure/src/main/kotlin/org/depromeet/clog/server/infrastructure/admin/CragAdminAdapter.kt @@ -0,0 +1,26 @@ +package org.depromeet.clog.server.infrastructure.admin + +import org.depromeet.clog.server.admin.domain.crag.CragAdminRepository +import org.depromeet.clog.server.domain.crag.domain.Crag +import org.depromeet.clog.server.infrastructure.crag.CragEntity +import org.depromeet.clog.server.infrastructure.crag.CragJpaRepository +import org.springframework.data.repository.findByIdOrNull +import org.springframework.stereotype.Component + +@Component +class CragAdminAdapter( + private val cragJpaRepository: CragJpaRepository +) : CragAdminRepository { + + override fun save(crag: Crag): Crag { + return cragJpaRepository.save(CragEntity.fromDomain(crag)).toDomain() + } + + override fun findById(id: Long): Crag? { + return cragJpaRepository.findByIdOrNull(id)?.toDomain() + } + + override fun findAll(): List<Crag> { + return cragJpaRepository.findAll().map { it.toDomain() } + } +} diff --git a/clog-infrastructure/src/main/kotlin/org/depromeet/clog/server/infrastructure/admin/GradeAdminAdapter.kt b/clog-infrastructure/src/main/kotlin/org/depromeet/clog/server/infrastructure/admin/GradeAdminAdapter.kt new file mode 100644 index 00000000..042cb7a4 --- /dev/null +++ b/clog-infrastructure/src/main/kotlin/org/depromeet/clog/server/infrastructure/admin/GradeAdminAdapter.kt @@ -0,0 +1,23 @@ +package org.depromeet.clog.server.infrastructure.admin + +import org.depromeet.clog.server.admin.domain.crag.GradeAdminRepository +import org.depromeet.clog.server.domain.crag.domain.Crag +import org.depromeet.clog.server.domain.crag.domain.Grade +import org.depromeet.clog.server.infrastructure.crag.CragEntity +import org.depromeet.clog.server.infrastructure.crag.GradeEntity +import org.depromeet.clog.server.infrastructure.crag.GradeJpaRepository +import org.springframework.stereotype.Component + +@Component +class GradeAdminAdapter( + private val gradeJpaRepository: GradeJpaRepository +) : GradeAdminRepository { + + override fun save(grade: Grade): Grade { + return gradeJpaRepository.save(GradeEntity.fromDomain(grade)).toDomain() + } + + override fun findByCrag(crag: Crag): List<Grade> { + return gradeJpaRepository.findByCrag(CragEntity.fromDomain(crag)).map { it.toDomain() } + } +} diff --git a/clog-infrastructure/src/main/kotlin/org/depromeet/clog/server/infrastructure/crag/ColorJpaRepository.kt b/clog-infrastructure/src/main/kotlin/org/depromeet/clog/server/infrastructure/crag/ColorJpaRepository.kt index 237f5660..406f5962 100644 --- a/clog-infrastructure/src/main/kotlin/org/depromeet/clog/server/infrastructure/crag/ColorJpaRepository.kt +++ b/clog-infrastructure/src/main/kotlin/org/depromeet/clog/server/infrastructure/crag/ColorJpaRepository.kt @@ -2,4 +2,7 @@ package org.depromeet.clog.server.infrastructure.crag import org.springframework.data.jpa.repository.JpaRepository -interface ColorJpaRepository : JpaRepository<ColorEntity, Long> +interface ColorJpaRepository : JpaRepository<ColorEntity, Long> { + + fun findByNameAndHex(name: String, hex: String): ColorEntity +} From 74840f66d4c00feb8bd8b8b2d999fce599e792f4 Mon Sep 17 00:00:00 2001 From: dae won <eodnjs01477@gmail.com> Date: Tue, 11 Mar 2025 22:49:38 +0900 Subject: [PATCH 2/9] =?UTF-8?q?feat:=20=EB=A1=9C=EA=B7=B8=EC=9D=B8=20secur?= =?UTF-8?q?ity=20=EC=B6=94=EA=B0=80=20-=20=EA=B8=B0=EB=B3=B8=20session=20?= =?UTF-8?q?=EC=82=AC=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../admin/common/AdminUserDetailsService.kt | 27 +++++++++++ .../admin/common/config/SecurityConfig.kt | 47 +++++++++++++++++++ 2 files changed, 74 insertions(+) create mode 100644 clog-admin/src/main/kotlin/org/depromeet/clog/server/admin/common/AdminUserDetailsService.kt create mode 100644 clog-admin/src/main/kotlin/org/depromeet/clog/server/admin/common/config/SecurityConfig.kt diff --git a/clog-admin/src/main/kotlin/org/depromeet/clog/server/admin/common/AdminUserDetailsService.kt b/clog-admin/src/main/kotlin/org/depromeet/clog/server/admin/common/AdminUserDetailsService.kt new file mode 100644 index 00000000..5f5f22d3 --- /dev/null +++ b/clog-admin/src/main/kotlin/org/depromeet/clog/server/admin/common/AdminUserDetailsService.kt @@ -0,0 +1,27 @@ +package org.depromeet.clog.server.admin.common + +import org.depromeet.clog.server.domain.user.domain.Provider +import org.depromeet.clog.server.domain.user.domain.UserRepository +import org.springframework.security.core.authority.SimpleGrantedAuthority +import org.springframework.security.core.userdetails.User +import org.springframework.security.core.userdetails.UserDetails +import org.springframework.security.core.userdetails.UserDetailsService +import org.springframework.security.core.userdetails.UsernameNotFoundException +import org.springframework.stereotype.Service + +@Service +class AdminUserDetailsService( + private val userRepository: UserRepository +) : UserDetailsService { + + override fun loadUserByUsername(username: String): UserDetails { + val user = userRepository.findByLoginIdAndProvider(username, Provider.LOCAL) + ?: throw UsernameNotFoundException("User not found with username: $username") + + return User.builder() + .username(user.loginId) + .password(user.name) + .authorities(listOf(SimpleGrantedAuthority("ROLE_USER"))) + .build() + } +} diff --git a/clog-admin/src/main/kotlin/org/depromeet/clog/server/admin/common/config/SecurityConfig.kt b/clog-admin/src/main/kotlin/org/depromeet/clog/server/admin/common/config/SecurityConfig.kt new file mode 100644 index 00000000..e8e39ebb --- /dev/null +++ b/clog-admin/src/main/kotlin/org/depromeet/clog/server/admin/common/config/SecurityConfig.kt @@ -0,0 +1,47 @@ +package org.depromeet.clog.server.admin.common.config + +import org.springframework.context.annotation.Bean +import org.springframework.context.annotation.Configuration +import org.springframework.security.config.annotation.web.builders.HttpSecurity +import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity +import org.springframework.security.core.userdetails.UserDetailsService +import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder +import org.springframework.security.crypto.password.PasswordEncoder +import org.springframework.security.web.SecurityFilterChain + +@Configuration +@EnableWebSecurity +class SecurityConfig( + private val userDetailsService: UserDetailsService +) { + + @Bean + @Throws(Exception::class) + fun securityFilterChain(http: HttpSecurity): SecurityFilterChain { + http + .userDetailsService(userDetailsService) + .authorizeHttpRequests { requests -> + requests + .requestMatchers("/", "/css/**", "/js/**", "/images/**").permitAll() + .anyRequest().authenticated() + } + .formLogin { form -> + form + .loginPage("/admin/login") + .defaultSuccessUrl("/admin/index", true) + .permitAll() + } + .logout { logout -> + logout + .logoutSuccessUrl("/admin/login?logout") + .permitAll() + } + + return http.build() + } + + @Bean + fun passwordEncoder(): PasswordEncoder { + return BCryptPasswordEncoder() + } +} From 5409574194bbcfdde17a33ae90ec285cd242a4aa Mon Sep 17 00:00:00 2001 From: dae won <eodnjs01477@gmail.com> Date: Tue, 11 Mar 2025 23:19:00 +0900 Subject: [PATCH 3/9] =?UTF-8?q?feat:=20=EC=96=B4=EB=93=9C=EB=AF=BC=20API?= =?UTF-8?q?=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../clog/server/admin/ClogAdminApplication.kt | 10 +- .../admin/api/application/AdminService.kt | 87 +++++++++++++++++ .../admin/api/presentation/AdminController.kt | 97 +++++++++++++++++++ .../admin/api/presentation/dto/ColorResult.kt | 18 ++++ .../admin/api/presentation/dto/CragResult.kt | 26 +++++ .../admin/api/presentation/dto/GradeResult.kt | 20 ++++ .../admin/api/presentation/dto/SaveCrag.kt | 23 +++++ .../api/presentation/dto/SaveCragColor.kt | 14 +++ .../api/presentation/dto/SaveCragGrade.kt | 16 +++ clog-admin/src/main/resources/application.yml | 10 +- .../clog/server/api/ClogApplication.kt | 10 +- 11 files changed, 328 insertions(+), 3 deletions(-) create mode 100644 clog-admin/src/main/kotlin/org/depromeet/clog/server/admin/api/application/AdminService.kt create mode 100644 clog-admin/src/main/kotlin/org/depromeet/clog/server/admin/api/presentation/AdminController.kt create mode 100644 clog-admin/src/main/kotlin/org/depromeet/clog/server/admin/api/presentation/dto/ColorResult.kt create mode 100644 clog-admin/src/main/kotlin/org/depromeet/clog/server/admin/api/presentation/dto/CragResult.kt create mode 100644 clog-admin/src/main/kotlin/org/depromeet/clog/server/admin/api/presentation/dto/GradeResult.kt create mode 100644 clog-admin/src/main/kotlin/org/depromeet/clog/server/admin/api/presentation/dto/SaveCrag.kt create mode 100644 clog-admin/src/main/kotlin/org/depromeet/clog/server/admin/api/presentation/dto/SaveCragColor.kt create mode 100644 clog-admin/src/main/kotlin/org/depromeet/clog/server/admin/api/presentation/dto/SaveCragGrade.kt diff --git a/clog-admin/src/main/kotlin/org/depromeet/clog/server/admin/ClogAdminApplication.kt b/clog-admin/src/main/kotlin/org/depromeet/clog/server/admin/ClogAdminApplication.kt index 57e8f0fb..222a67e7 100644 --- a/clog-admin/src/main/kotlin/org/depromeet/clog/server/admin/ClogAdminApplication.kt +++ b/clog-admin/src/main/kotlin/org/depromeet/clog/server/admin/ClogAdminApplication.kt @@ -2,8 +2,16 @@ package org.depromeet.clog.server.admin import org.springframework.boot.autoconfigure.SpringBootApplication import org.springframework.boot.runApplication +import org.springframework.context.annotation.ComponentScan +import org.springframework.context.annotation.FilterType -@SpringBootApplication(scanBasePackages = ["org.depromeet.clog.server"]) +@SpringBootApplication +@ComponentScan( + basePackages = ["org.depromeet.clog.server"], + excludeFilters = [ + ComponentScan.Filter(type = FilterType.REGEX, pattern = ["org\\.depromeet\\.clog\\.server\\.api\\..*"]) + ] +) class ClogAdminApplication fun main(args: Array<String>) { diff --git a/clog-admin/src/main/kotlin/org/depromeet/clog/server/admin/api/application/AdminService.kt b/clog-admin/src/main/kotlin/org/depromeet/clog/server/admin/api/application/AdminService.kt new file mode 100644 index 00000000..9d6f4654 --- /dev/null +++ b/clog-admin/src/main/kotlin/org/depromeet/clog/server/admin/api/application/AdminService.kt @@ -0,0 +1,87 @@ +package org.depromeet.clog.server.admin.api.application + +import jakarta.persistence.EntityNotFoundException +import org.depromeet.clog.server.admin.api.presentation.dto.* +import org.depromeet.clog.server.admin.domain.crag.ColorAdminRepository +import org.depromeet.clog.server.admin.domain.crag.CragAdminRepository +import org.depromeet.clog.server.admin.domain.crag.GradeAdminRepository +import org.depromeet.clog.server.domain.crag.domain.Color +import org.depromeet.clog.server.domain.crag.domain.Coordinate +import org.depromeet.clog.server.domain.crag.domain.Crag +import org.depromeet.clog.server.domain.crag.domain.Grade +import org.springframework.stereotype.Service + +@Service +class AdminService( + private val cragAdminRepository: CragAdminRepository, + private val colorAdminRepository: ColorAdminRepository, + private val gradeAdminRepository: GradeAdminRepository +) { + + fun getAllCrag(): List<Crag> { + return cragAdminRepository.findAll() + } + + fun createCrag( + request: SaveCrag.Request + ) { + val coordinate = Coordinate(request.longitude.toDouble(), request.latitude.toDouble()) + val crag = Crag(null, request.name, request.roadAddress, coordinate, request.kakaoPlaceId.toLong()) + + cragAdminRepository.save(crag) + } + + fun getCrag( + id: Long + ): CragResult { + val crag = cragAdminRepository.findById(id) + ?: throw EntityNotFoundException("Crag with ID $id not found") + + return CragResult.from(crag) + } + + fun getAllColor(): List<ColorResult> { + return colorAdminRepository.findAll().map { ColorResult.from(it) } + } + + fun createColor( + request: SaveCragColor.Request + ): SaveCragColor.Response { + val color = Color(null, request.name, request.hex) + val res = colorAdminRepository.save(color) + + return SaveCragColor.Response( + name = res.name, + hex = res.hex + ) + } + + fun createGrade( + cragId: Long, + request: SaveCragGrade.Request + ): SaveCragGrade.Response { + val color = colorAdminRepository.findByNameAndHex(request.colorName, request.colorHex) + ?: throw EntityNotFoundException("Color ${request.colorName} not found") + + val crag: Crag = cragAdminRepository.findById(cragId) + ?: throw NoSuchElementException("Crag not found with id: $cragId") + + val grade = Grade(null, color, crag, request.gradeOrder.toInt()) + val res = gradeAdminRepository.save(grade) + + return SaveCragGrade.Response( + colorName = res.color.name, + colorHex = res.color.hex, + gradeOrder = res.order + ) + } + + fun getGrades( + id: Long + ): List<GradeResult> { + val crag = cragAdminRepository.findById(id) + ?: throw EntityNotFoundException("Crag with ID $id not found") + + return gradeAdminRepository.findByCrag(crag).map { GradeResult.from(it) } + } +} diff --git a/clog-admin/src/main/kotlin/org/depromeet/clog/server/admin/api/presentation/AdminController.kt b/clog-admin/src/main/kotlin/org/depromeet/clog/server/admin/api/presentation/AdminController.kt new file mode 100644 index 00000000..15c10637 --- /dev/null +++ b/clog-admin/src/main/kotlin/org/depromeet/clog/server/admin/api/presentation/AdminController.kt @@ -0,0 +1,97 @@ +package org.depromeet.clog.server.admin.api.presentation + +import org.depromeet.clog.server.admin.api.application.AdminService +import org.depromeet.clog.server.admin.api.presentation.dto.SaveCrag +import org.depromeet.clog.server.admin.api.presentation.dto.SaveCragColor +import org.depromeet.clog.server.admin.api.presentation.dto.SaveCragGrade +import org.depromeet.clog.server.infrastructure.configuration.properties.KakaoMapProperties +import org.springframework.stereotype.Controller +import org.springframework.ui.Model +import org.springframework.web.bind.annotation.* + +@Controller +@RequestMapping("/admin") +class AdminController( + private val adminService: AdminService, + private val kakaoMapProperties: KakaoMapProperties +) { + + companion object { + private const val LOGIN_PAGE = "admin/login" + } + + @GetMapping("/login") + fun loginPage(): String = LOGIN_PAGE + + @GetMapping("/index") + fun index(model: Model): String { + val result = adminService.getAllCrag() + model.addAttribute("crags", result) + + return "admin/cragList" + } + + @GetMapping("/add/crags") + fun saveCragPage(model: Model): String { + model.addAttribute("crag", SaveCrag.Request()) + model.addAttribute("kakaoKey", kakaoMapProperties.restApiKey) + + return "admin/cragAdd" + } + + @PostMapping("/add/crags") + fun saveCrag(@ModelAttribute("crag") request: SaveCrag.Request): String { + val sanitized = request.sanitized() + adminService.createCrag(sanitized) + + return "redirect:/admin/add/crags" + } + + @GetMapping("/crags/{id}/details") + fun cragDetailsPage(@PathVariable id: Long, model: Model): String { + val crag = adminService.getCrag(id) + val grades = adminService.getGrades(id) + model.addAttribute("crag", crag) + model.addAttribute("grades", grades) + + return "admin/cragDetails" + } + + @GetMapping("/crags/colors") + fun getCragColors(model: Model): String { + val result = adminService.getAllColor() + model.addAttribute("colors", result) + + return "admin/colorList" + } + + @GetMapping("/crags/add/colors") + fun saveCragColorPage(model: Model): String { + model.addAttribute("color", SaveCragColor.Request()) + + return "admin/cragColorAdd" + } + + @PostMapping("/crags/add/colors") + fun saveCragColorPage(@ModelAttribute("color") request: SaveCragColor.Request): String { + adminService.createColor(request) + + return "redirect:/admin/crags/colors" + } + + @GetMapping("/crags/{id}/add/grades") + fun saveCragGradePage(@PathVariable id: Long, model: Model): String { + model.addAttribute("cragId", id) + model.addAttribute("grade", SaveCragGrade.Request()) + model.addAttribute("colors", adminService.getAllColor()) + + return "admin/cragGradeAdd" + } + + @PostMapping("/crags/{id}/add/grades") + fun saveCragGrade(@PathVariable id: Long, @ModelAttribute("grade") request: SaveCragGrade.Request): String { + adminService.createGrade(id, request) + + return "redirect:/admin/crags/$id/details" + } +} diff --git a/clog-admin/src/main/kotlin/org/depromeet/clog/server/admin/api/presentation/dto/ColorResult.kt b/clog-admin/src/main/kotlin/org/depromeet/clog/server/admin/api/presentation/dto/ColorResult.kt new file mode 100644 index 00000000..7c0bbd0d --- /dev/null +++ b/clog-admin/src/main/kotlin/org/depromeet/clog/server/admin/api/presentation/dto/ColorResult.kt @@ -0,0 +1,18 @@ +package org.depromeet.clog.server.admin.api.presentation.dto + +import org.depromeet.clog.server.domain.crag.domain.Color + +data class ColorResult( + val name: String, + val hex: String +) { + + companion object { + fun from(color: Color): ColorResult { + return ColorResult( + name = color.name, + hex = color.hex + ) + } + } +} diff --git a/clog-admin/src/main/kotlin/org/depromeet/clog/server/admin/api/presentation/dto/CragResult.kt b/clog-admin/src/main/kotlin/org/depromeet/clog/server/admin/api/presentation/dto/CragResult.kt new file mode 100644 index 00000000..c277f908 --- /dev/null +++ b/clog-admin/src/main/kotlin/org/depromeet/clog/server/admin/api/presentation/dto/CragResult.kt @@ -0,0 +1,26 @@ +package org.depromeet.clog.server.admin.api.presentation.dto + +import org.depromeet.clog.server.domain.crag.domain.Crag + +data class CragResult( + val id: Long, + val name: String, + val roadAddress: String, + val longitude: Double, + val latitude: Double, + val kakaoPlaceId: Long +) { + + companion object { + fun from(crag: Crag): CragResult { + return CragResult( + id = crag.id!!, + name = crag.name, + roadAddress = crag.roadAddress, + longitude = crag.coordinate.longitude, + latitude = crag.coordinate.latitude, + kakaoPlaceId = crag.kakaoPlaceId + ) + } + } +} diff --git a/clog-admin/src/main/kotlin/org/depromeet/clog/server/admin/api/presentation/dto/GradeResult.kt b/clog-admin/src/main/kotlin/org/depromeet/clog/server/admin/api/presentation/dto/GradeResult.kt new file mode 100644 index 00000000..2c305a01 --- /dev/null +++ b/clog-admin/src/main/kotlin/org/depromeet/clog/server/admin/api/presentation/dto/GradeResult.kt @@ -0,0 +1,20 @@ +package org.depromeet.clog.server.admin.api.presentation.dto + +import org.depromeet.clog.server.domain.crag.domain.Grade + +data class GradeResult( + val colorName: String, + val colorHex: String, + val gradeOrder: Int? +) { + + companion object { + fun from(grade: Grade): GradeResult { + return GradeResult( + colorName = grade.color.name, + colorHex = grade.color.hex, + gradeOrder = grade.order + ) + } + } +} diff --git a/clog-admin/src/main/kotlin/org/depromeet/clog/server/admin/api/presentation/dto/SaveCrag.kt b/clog-admin/src/main/kotlin/org/depromeet/clog/server/admin/api/presentation/dto/SaveCrag.kt new file mode 100644 index 00000000..2f315503 --- /dev/null +++ b/clog-admin/src/main/kotlin/org/depromeet/clog/server/admin/api/presentation/dto/SaveCrag.kt @@ -0,0 +1,23 @@ +package org.depromeet.clog.server.admin.api.presentation.dto + +object SaveCrag { + + data class Request( + val name: String = "", + val roadAddress: String = "", + val longitude: String = "", + val latitude: String = "", + val kakaoPlaceId: String = "" + ) { + + fun sanitized(): Request { + return Request( + name = name.replace(",", ""), + roadAddress = roadAddress.replace(",", ""), + longitude = longitude.replace(",", ""), + latitude = latitude.replace(",", ""), + kakaoPlaceId = kakaoPlaceId.replace(",", "") + ) + } + } +} diff --git a/clog-admin/src/main/kotlin/org/depromeet/clog/server/admin/api/presentation/dto/SaveCragColor.kt b/clog-admin/src/main/kotlin/org/depromeet/clog/server/admin/api/presentation/dto/SaveCragColor.kt new file mode 100644 index 00000000..6f9c24c2 --- /dev/null +++ b/clog-admin/src/main/kotlin/org/depromeet/clog/server/admin/api/presentation/dto/SaveCragColor.kt @@ -0,0 +1,14 @@ +package org.depromeet.clog.server.admin.api.presentation.dto + +object SaveCragColor { + + data class Request( + val name: String = "", + val hex: String = "" + ) + + data class Response( + val name: String, + val hex: String + ) +} diff --git a/clog-admin/src/main/kotlin/org/depromeet/clog/server/admin/api/presentation/dto/SaveCragGrade.kt b/clog-admin/src/main/kotlin/org/depromeet/clog/server/admin/api/presentation/dto/SaveCragGrade.kt new file mode 100644 index 00000000..ddf676b5 --- /dev/null +++ b/clog-admin/src/main/kotlin/org/depromeet/clog/server/admin/api/presentation/dto/SaveCragGrade.kt @@ -0,0 +1,16 @@ +package org.depromeet.clog.server.admin.api.presentation.dto + +object SaveCragGrade { + + data class Request( + val colorName: String = "", + val colorHex: String = "", + val gradeOrder: String = "" + ) + + data class Response( + val colorName: String, + val colorHex: String, + val gradeOrder: Int? + ) +} diff --git a/clog-admin/src/main/resources/application.yml b/clog-admin/src/main/resources/application.yml index 34882ba8..b9bda6ec 100644 --- a/clog-admin/src/main/resources/application.yml +++ b/clog-admin/src/main/resources/application.yml @@ -23,4 +23,12 @@ spring: jwt: secret: ${JWT_SECRET} access-token-expiration-millis: 3600000 - refresh-token-expiration-millis: 604800000 \ No newline at end of file + refresh-token-expiration-millis: 604800000 + +ncp: + storage: + access-key: ${STORAGE_ACCESS_KEY} + secret-key: ${STORAGE_SECRET_KEY} + end-point: ${STORAGE_END_POINT} + bucket-name: ${STORAGE_BUCKET_NAME} + region: ${STORAGE_REGION} \ No newline at end of file diff --git a/clog-api/src/main/kotlin/org/depromeet/clog/server/api/ClogApplication.kt b/clog-api/src/main/kotlin/org/depromeet/clog/server/api/ClogApplication.kt index fb6d4450..0c82c6a6 100644 --- a/clog-api/src/main/kotlin/org/depromeet/clog/server/api/ClogApplication.kt +++ b/clog-api/src/main/kotlin/org/depromeet/clog/server/api/ClogApplication.kt @@ -2,8 +2,16 @@ package org.depromeet.clog.server.api import org.springframework.boot.autoconfigure.SpringBootApplication import org.springframework.boot.runApplication +import org.springframework.context.annotation.ComponentScan +import org.springframework.context.annotation.FilterType -@SpringBootApplication(scanBasePackages = ["org.depromeet.clog.server"]) +@SpringBootApplication +@ComponentScan( + basePackages = ["org.depromeet.clog.server"], + excludeFilters = [ + ComponentScan.Filter(type = FilterType.REGEX, pattern = ["org\\.depromeet\\.clog\\.server\\.admin\\..*"]) + ] +) class ClogApplication fun main(args: Array<String>) { From 4d454e40050f3835b6176beaf16103e9443bd4e7 Mon Sep 17 00:00:00 2001 From: dae won <eodnjs01477@gmail.com> Date: Tue, 11 Mar 2025 23:32:58 +0900 Subject: [PATCH 4/9] =?UTF-8?q?chore:=20dockerfile=20=EC=B6=94=EA=B0=80=20?= =?UTF-8?q?=EB=B0=8F=20deploy.yml=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/dev-deploy.yml | 21 +++++++++++++-------- clog-admin/Dockerfile | 7 +++++++ 2 files changed, 20 insertions(+), 8 deletions(-) create mode 100644 clog-admin/Dockerfile diff --git a/.github/workflows/dev-deploy.yml b/.github/workflows/dev-deploy.yml index def21ecc..adea9a72 100644 --- a/.github/workflows/dev-deploy.yml +++ b/.github/workflows/dev-deploy.yml @@ -21,17 +21,21 @@ jobs: java-version: '21' - name: Build with Gradle (skip tests) - run: ./gradlew build -x test + run: ./gradlew :clog-api:build :clog-admin:build -x test - - name: Build Docker Image + - name: Build API Docker Image run: | - docker build -f clog-api/Dockerfile -t ${{ secrets.DOCKER_REGISTRY }}/${{ secrets.DOCKER_IMAGE }}:${{ github.ref_name }} . + docker build -f clog-api/Dockerfile -t ${{ secrets.DOCKER_REGISTRY }}/${{ secrets.DOCKER_API_IMAGE }}:${{ github.ref_name }} . - - name: Login to Docker Registry - run: echo "${{ secrets.DOCKER_PASSWORD }}" | docker login ${{ secrets.DOCKER_REGISTRY }} -u ${{ secrets.DOCKER_USERNAME }} --password-stdin + - name: Push API Docker Image + run: docker push ${{ secrets.DOCKER_REGISTRY }}/${{ secrets.DOCKER_API_IMAGE }}:${{ github.ref_name }} - - name: Push Docker Image - run: docker push ${{ secrets.DOCKER_REGISTRY }}/${{ secrets.DOCKER_IMAGE }}:${{ github.ref_name }} + - name: Build Admin Docker Image + run: | + docker build -f clog-admin/Dockerfile -t ${{ secrets.DOCKER_REGISTRY }}/${{ secrets.DOCKER_ADMIN_IMAGE }}:${{ github.ref_name }} . + + - name: Push Admin Docker Image + run: docker push ${{ secrets.DOCKER_REGISTRY }}/${{ secrets.DOCKER_ADMIN_IMAGE }}:${{ github.ref_name }} - name: Deploy on Remote Server via SSH uses: appleboy/ssh-action@v0.1.8 @@ -42,4 +46,5 @@ jobs: port: ${{ secrets.SSH_PORT }} script: | docker compose -f /root/docker-compose.yml pull api - docker compose -f /root/docker-compose.yml up -d api + docker compose -f /root/docker-compose.yml pull admin + docker compose -f /root/docker-compose.yml up -d api admin diff --git a/clog-admin/Dockerfile b/clog-admin/Dockerfile new file mode 100644 index 00000000..54a4cea9 --- /dev/null +++ b/clog-admin/Dockerfile @@ -0,0 +1,7 @@ +FROM openjdk:21-slim + +WORKDIR /data/www + +COPY clog-admin/build/libs/*.jar admin.jar + +ENTRYPOINT ["java", "-jar", "admin.jar"] From 28a0b6df8bc7c7c4a575e8ff9b9565c5464dd972 Mon Sep 17 00:00:00 2001 From: dae won <eodnjs01477@gmail.com> Date: Tue, 11 Mar 2025 23:46:02 +0900 Subject: [PATCH 5/9] =?UTF-8?q?chore:=20deploy.yml=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/dev-deploy.yml | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/.github/workflows/dev-deploy.yml b/.github/workflows/dev-deploy.yml index adea9a72..bf28e5e6 100644 --- a/.github/workflows/dev-deploy.yml +++ b/.github/workflows/dev-deploy.yml @@ -23,18 +23,21 @@ jobs: - name: Build with Gradle (skip tests) run: ./gradlew :clog-api:build :clog-admin:build -x test - - name: Build API Docker Image + - name: Build Docker Image run: | - docker build -f clog-api/Dockerfile -t ${{ secrets.DOCKER_REGISTRY }}/${{ secrets.DOCKER_API_IMAGE }}:${{ github.ref_name }} . + docker build -f clog-api/Dockerfile -t ${{ secrets.DOCKER_REGISTRY }}/${{ secrets.DOCKER_IMAGE }}:${{ github.ref_name }} . - - name: Push API Docker Image - run: docker push ${{ secrets.DOCKER_REGISTRY }}/${{ secrets.DOCKER_API_IMAGE }}:${{ github.ref_name }} + - name: Login to Docker Registry + run: echo "${{ secrets.DOCKER_PASSWORD }}" | docker login ${{ secrets.DOCKER_REGISTRY }} -u ${{ secrets.DOCKER_USERNAME }} --password-stdin - - name: Build Admin Docker Image + - name: Push Docker Image + run: docker push ${{ secrets.DOCKER_REGISTRY }}/${{ secrets.DOCKER_IMAGE }}:${{ github.ref_name }} + + - name: Build Docker Admin Image run: | docker build -f clog-admin/Dockerfile -t ${{ secrets.DOCKER_REGISTRY }}/${{ secrets.DOCKER_ADMIN_IMAGE }}:${{ github.ref_name }} . - - name: Push Admin Docker Image + - name: Push Docker Admin Image run: docker push ${{ secrets.DOCKER_REGISTRY }}/${{ secrets.DOCKER_ADMIN_IMAGE }}:${{ github.ref_name }} - name: Deploy on Remote Server via SSH From 4fb343dcad62ccc046754372bbcf7311e809dcaf Mon Sep 17 00:00:00 2001 From: dae won <eodnjs01477@gmail.com> Date: Wed, 12 Mar 2025 00:41:20 +0900 Subject: [PATCH 6/9] =?UTF-8?q?feat:=20=EC=95=94=EC=9E=A5=20=EB=82=9C?= =?UTF-8?q?=EC=9D=B4=EB=8F=84=20=EA=B0=9C=EC=88=98=20=ED=91=9C=EC=8B=9C=20?= =?UTF-8?q?view=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../admin/api/application/AdminService.kt | 10 ++++-- .../admin/api/presentation/dto/CragResult.kt | 5 +++ .../resources/templates/admin/cragList.html | 33 +++---------------- 3 files changed, 18 insertions(+), 30 deletions(-) diff --git a/clog-admin/src/main/kotlin/org/depromeet/clog/server/admin/api/application/AdminService.kt b/clog-admin/src/main/kotlin/org/depromeet/clog/server/admin/api/application/AdminService.kt index 9d6f4654..f1ca3075 100644 --- a/clog-admin/src/main/kotlin/org/depromeet/clog/server/admin/api/application/AdminService.kt +++ b/clog-admin/src/main/kotlin/org/depromeet/clog/server/admin/api/application/AdminService.kt @@ -18,8 +18,14 @@ class AdminService( private val gradeAdminRepository: GradeAdminRepository ) { - fun getAllCrag(): List<Crag> { - return cragAdminRepository.findAll() + fun getAllCrag(): List<CragResult.WithGradeCount> { + return cragAdminRepository.findAll().map { crag -> + val gradeCount = gradeAdminRepository.findByCrag(crag).size + CragResult.WithGradeCount( + cragResult = CragResult.from(crag), + gradeCount = gradeCount + ) + } } fun createCrag( diff --git a/clog-admin/src/main/kotlin/org/depromeet/clog/server/admin/api/presentation/dto/CragResult.kt b/clog-admin/src/main/kotlin/org/depromeet/clog/server/admin/api/presentation/dto/CragResult.kt index c277f908..87bc9ca4 100644 --- a/clog-admin/src/main/kotlin/org/depromeet/clog/server/admin/api/presentation/dto/CragResult.kt +++ b/clog-admin/src/main/kotlin/org/depromeet/clog/server/admin/api/presentation/dto/CragResult.kt @@ -23,4 +23,9 @@ data class CragResult( ) } } + + data class WithGradeCount( + val cragResult: CragResult, + val gradeCount: Int + ) } diff --git a/clog-admin/src/main/resources/templates/admin/cragList.html b/clog-admin/src/main/resources/templates/admin/cragList.html index aca697b9..d8233070 100644 --- a/clog-admin/src/main/resources/templates/admin/cragList.html +++ b/clog-admin/src/main/resources/templates/admin/cragList.html @@ -48,6 +48,7 @@ <h1 class="h3 mb-2 text-gray-800">암장 관리</h1> <th>암장 ID</th> <th>암장 이름</th> <th>도로명 주소</th> + <th>난이도 개수</th> <!-- <th>경도</th>--> <!-- <th>위도</th>--> <!-- <th>카카오 맵 ID</th>--> @@ -57,10 +58,11 @@ <h1 class="h3 mb-2 text-gray-800">암장 관리</h1> <tbody> <tr th:each="crag : ${crags}"> <td> - <a th:href="@{/admin/crags/{id}/details(id=${crag.id})}" th:text="${crag.id}"></a> + <a th:href="@{/admin/crags/{id}/details(id=${crag.cragResult.id})}" th:text="${crag.cragResult.id}"></a> </td> - <td th:text="${crag.name}"></td> - <td th:text="${crag.roadAddress}"></td> + <td th:text="${crag.cragResult.name}"></td> + <td th:text="${crag.cragResult.roadAddress}"></td> + <td th:text="${crag.gradeCount}"></td> <!-- <td th:text="${crag.coordinate.latitude}"></td>--> <!-- <td th:text="${crag.coordinate.longitude}"></td>--> <!-- <td th:text="${crag.kakaoPlaceId}"></td>--> @@ -93,30 +95,5 @@ <h1 class="h3 mb-2 text-gray-800">암장 관리</h1> </a> <th:block th:replace="~{fragments/admin/fragments.html :: admJS}"/> -<script th:src="@{/webjars/jquery/jquery.min.js}"></script> -<script th:src="@{/webjars/datatables/js/jquery.dataTables.min.js}"></script> - -<script> - $(document).ready(function() { - $('#dataTable').DataTable({ - "processing": true, - "serverSide": true, - "ajax": { - "url": "/admin/index", - "type": "GET", - "data": function (d) { - d.page = d.start / d.length; // DataTables가 요청하는 page 계산 - d.size = d.length; // DataTables가 요청하는 size - } - }, - "columns": [ - { "data": "id" }, - { "data": "name" }, - { "data": "roadAddress" } - ] - }); - }); -</script> - </body> </html> \ No newline at end of file From 3d68d703c116f243d062622a30bb152af8a30fbc Mon Sep 17 00:00:00 2001 From: dae won <eodnjs01477@gmail.com> Date: Wed, 12 Mar 2025 01:48:10 +0900 Subject: [PATCH 7/9] =?UTF-8?q?feat:=20hex=20code=20=EC=83=89=EC=83=81=20?= =?UTF-8?q?=ED=91=9C=EC=8B=9C=20view=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/main/resources/templates/admin/colorList.html | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/clog-admin/src/main/resources/templates/admin/colorList.html b/clog-admin/src/main/resources/templates/admin/colorList.html index c1165001..35d2db65 100644 --- a/clog-admin/src/main/resources/templates/admin/colorList.html +++ b/clog-admin/src/main/resources/templates/admin/colorList.html @@ -52,7 +52,12 @@ <h1 class="h3 mb-2 text-gray-800">색상 관리</h1> <tbody> <tr th:each="color : ${colors}"> <td th:text="${color.name}"></td> - <td th:text="${color.hex}"></td> + <td> + <div style="display: flex; align-items: center;"> + <div th:style="'width: 20px; height: 20px; background-color: ' + ${color.hex} + '; border: 1px solid #000; margin-right: 10px;'"></div> + <span th:text="${color.hex}"></span> + </div> + </td> </tr> </tbody> </table> From bcb43d17591bff4fc8b36eda8bcb600587563cca Mon Sep 17 00:00:00 2001 From: dae won <eodnjs01477@gmail.com> Date: Wed, 12 Mar 2025 15:43:46 +0900 Subject: [PATCH 8/9] =?UTF-8?q?feat:=20=ED=8A=B8=EB=9E=9C=EC=9E=AD?= =?UTF-8?q?=EC=85=98=20=EC=96=B4=EB=85=B8=ED=85=8C=EC=9D=B4=EC=85=98=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../clog/server/admin/api/application/AdminService.kt | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/clog-admin/src/main/kotlin/org/depromeet/clog/server/admin/api/application/AdminService.kt b/clog-admin/src/main/kotlin/org/depromeet/clog/server/admin/api/application/AdminService.kt index f1ca3075..975fbc0c 100644 --- a/clog-admin/src/main/kotlin/org/depromeet/clog/server/admin/api/application/AdminService.kt +++ b/clog-admin/src/main/kotlin/org/depromeet/clog/server/admin/api/application/AdminService.kt @@ -10,6 +10,7 @@ import org.depromeet.clog.server.domain.crag.domain.Coordinate import org.depromeet.clog.server.domain.crag.domain.Crag import org.depromeet.clog.server.domain.crag.domain.Grade import org.springframework.stereotype.Service +import org.springframework.transaction.annotation.Transactional @Service class AdminService( @@ -18,6 +19,7 @@ class AdminService( private val gradeAdminRepository: GradeAdminRepository ) { + @Transactional(readOnly = true) fun getAllCrag(): List<CragResult.WithGradeCount> { return cragAdminRepository.findAll().map { crag -> val gradeCount = gradeAdminRepository.findByCrag(crag).size @@ -28,6 +30,7 @@ class AdminService( } } + @Transactional fun createCrag( request: SaveCrag.Request ) { @@ -37,6 +40,7 @@ class AdminService( cragAdminRepository.save(crag) } + @Transactional(readOnly = true) fun getCrag( id: Long ): CragResult { @@ -46,10 +50,12 @@ class AdminService( return CragResult.from(crag) } + @Transactional(readOnly = true) fun getAllColor(): List<ColorResult> { return colorAdminRepository.findAll().map { ColorResult.from(it) } } + @Transactional fun createColor( request: SaveCragColor.Request ): SaveCragColor.Response { @@ -62,6 +68,7 @@ class AdminService( ) } + @Transactional fun createGrade( cragId: Long, request: SaveCragGrade.Request @@ -82,6 +89,7 @@ class AdminService( ) } + @Transactional(readOnly = true) fun getGrades( id: Long ): List<GradeResult> { From 8cbfd8ceee29bcde95f7ef2da389f579f429b112 Mon Sep 17 00:00:00 2001 From: bigcir <eodnjs01477@gmail.com> Date: Sat, 22 Mar 2025 17:18:33 +0900 Subject: [PATCH 9/9] =?UTF-8?q?refactor:=20=EB=B3=80=EA=B2=BD=EB=90=9C=20?= =?UTF-8?q?=EB=8F=84=EB=A9=94=EC=9D=B8=EC=97=90=20=EB=A7=9E=EC=B6=B0=20?= =?UTF-8?q?=EB=A6=AC=ED=8C=A9=ED=86=A0=EB=A7=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- clog-admin/build.gradle.kts | 1 - .../server/admin/api/application/AdminService.kt | 14 +++++++------- .../admin/api/presentation/dto/ColorResult.kt | 2 +- .../admin/api/presentation/dto/CragResult.kt | 4 ++-- .../admin/api/presentation/dto/GradeResult.kt | 2 +- .../admin/domain/crag/ColorAdminRepository.kt | 2 +- .../admin/domain/crag/GradeAdminRepository.kt | 2 +- .../resources/templates/admin/cragDetails.html | 16 ++++++++-------- .../infrastructure/admin/ColorAdminAdapter.kt | 13 ++++++++----- .../infrastructure/admin/CragAdminAdapter.kt | 11 +++++++---- .../infrastructure/admin/GradeAdminAdapter.kt | 13 ++++++++----- .../infrastructure/crag/GradeJpaRepository.kt | 2 ++ 12 files changed, 46 insertions(+), 36 deletions(-) diff --git a/clog-admin/build.gradle.kts b/clog-admin/build.gradle.kts index 15896013..537ac57d 100644 --- a/clog-admin/build.gradle.kts +++ b/clog-admin/build.gradle.kts @@ -3,7 +3,6 @@ dependencies { implementation(project(":clog-domain")) implementation(project(":clog-infrastructure")) - implementation("org.springframework.boot:spring-boot-devtools") implementation("org.springframework.boot:spring-boot-starter-data-jpa") implementation("org.springframework.boot:spring-boot-starter-thymeleaf") implementation("org.springframework.boot:spring-boot-starter-security") diff --git a/clog-admin/src/main/kotlin/org/depromeet/clog/server/admin/api/application/AdminService.kt b/clog-admin/src/main/kotlin/org/depromeet/clog/server/admin/api/application/AdminService.kt index 975fbc0c..dbbcd96b 100644 --- a/clog-admin/src/main/kotlin/org/depromeet/clog/server/admin/api/application/AdminService.kt +++ b/clog-admin/src/main/kotlin/org/depromeet/clog/server/admin/api/application/AdminService.kt @@ -5,10 +5,10 @@ import org.depromeet.clog.server.admin.api.presentation.dto.* import org.depromeet.clog.server.admin.domain.crag.ColorAdminRepository import org.depromeet.clog.server.admin.domain.crag.CragAdminRepository import org.depromeet.clog.server.admin.domain.crag.GradeAdminRepository -import org.depromeet.clog.server.domain.crag.domain.Color -import org.depromeet.clog.server.domain.crag.domain.Coordinate import org.depromeet.clog.server.domain.crag.domain.Crag -import org.depromeet.clog.server.domain.crag.domain.Grade +import org.depromeet.clog.server.domain.crag.domain.Location +import org.depromeet.clog.server.domain.crag.domain.color.Color +import org.depromeet.clog.server.domain.crag.domain.grade.Grade import org.springframework.stereotype.Service import org.springframework.transaction.annotation.Transactional @@ -34,8 +34,8 @@ class AdminService( fun createCrag( request: SaveCrag.Request ) { - val coordinate = Coordinate(request.longitude.toDouble(), request.latitude.toDouble()) - val crag = Crag(null, request.name, request.roadAddress, coordinate, request.kakaoPlaceId.toLong()) + val location = Location(request.longitude.toDouble(), request.latitude.toDouble()) + val crag = Crag(null, request.name, request.roadAddress, location, request.kakaoPlaceId.toLong()) cragAdminRepository.save(crag) } @@ -73,13 +73,13 @@ class AdminService( cragId: Long, request: SaveCragGrade.Request ): SaveCragGrade.Response { - val color = colorAdminRepository.findByNameAndHex(request.colorName, request.colorHex) + val color: Color = colorAdminRepository.findByNameAndHex(request.colorName, request.colorHex) ?: throw EntityNotFoundException("Color ${request.colorName} not found") val crag: Crag = cragAdminRepository.findById(cragId) ?: throw NoSuchElementException("Crag not found with id: $cragId") - val grade = Grade(null, color, crag, request.gradeOrder.toInt()) + val grade = Grade(null, crag.id!!, color, request.gradeOrder.toInt()) val res = gradeAdminRepository.save(grade) return SaveCragGrade.Response( diff --git a/clog-admin/src/main/kotlin/org/depromeet/clog/server/admin/api/presentation/dto/ColorResult.kt b/clog-admin/src/main/kotlin/org/depromeet/clog/server/admin/api/presentation/dto/ColorResult.kt index 7c0bbd0d..864f649d 100644 --- a/clog-admin/src/main/kotlin/org/depromeet/clog/server/admin/api/presentation/dto/ColorResult.kt +++ b/clog-admin/src/main/kotlin/org/depromeet/clog/server/admin/api/presentation/dto/ColorResult.kt @@ -1,6 +1,6 @@ package org.depromeet.clog.server.admin.api.presentation.dto -import org.depromeet.clog.server.domain.crag.domain.Color +import org.depromeet.clog.server.domain.crag.domain.color.Color data class ColorResult( val name: String, diff --git a/clog-admin/src/main/kotlin/org/depromeet/clog/server/admin/api/presentation/dto/CragResult.kt b/clog-admin/src/main/kotlin/org/depromeet/clog/server/admin/api/presentation/dto/CragResult.kt index 87bc9ca4..b2dce622 100644 --- a/clog-admin/src/main/kotlin/org/depromeet/clog/server/admin/api/presentation/dto/CragResult.kt +++ b/clog-admin/src/main/kotlin/org/depromeet/clog/server/admin/api/presentation/dto/CragResult.kt @@ -17,8 +17,8 @@ data class CragResult( id = crag.id!!, name = crag.name, roadAddress = crag.roadAddress, - longitude = crag.coordinate.longitude, - latitude = crag.coordinate.latitude, + longitude = crag.location.longitude, + latitude = crag.location.latitude, kakaoPlaceId = crag.kakaoPlaceId ) } diff --git a/clog-admin/src/main/kotlin/org/depromeet/clog/server/admin/api/presentation/dto/GradeResult.kt b/clog-admin/src/main/kotlin/org/depromeet/clog/server/admin/api/presentation/dto/GradeResult.kt index 2c305a01..f10580ae 100644 --- a/clog-admin/src/main/kotlin/org/depromeet/clog/server/admin/api/presentation/dto/GradeResult.kt +++ b/clog-admin/src/main/kotlin/org/depromeet/clog/server/admin/api/presentation/dto/GradeResult.kt @@ -1,6 +1,6 @@ package org.depromeet.clog.server.admin.api.presentation.dto -import org.depromeet.clog.server.domain.crag.domain.Grade +import org.depromeet.clog.server.domain.crag.domain.grade.Grade data class GradeResult( val colorName: String, diff --git a/clog-admin/src/main/kotlin/org/depromeet/clog/server/admin/domain/crag/ColorAdminRepository.kt b/clog-admin/src/main/kotlin/org/depromeet/clog/server/admin/domain/crag/ColorAdminRepository.kt index b7d23548..d414865f 100644 --- a/clog-admin/src/main/kotlin/org/depromeet/clog/server/admin/domain/crag/ColorAdminRepository.kt +++ b/clog-admin/src/main/kotlin/org/depromeet/clog/server/admin/domain/crag/ColorAdminRepository.kt @@ -1,6 +1,6 @@ package org.depromeet.clog.server.admin.domain.crag -import org.depromeet.clog.server.domain.crag.domain.Color +import org.depromeet.clog.server.domain.crag.domain.color.Color interface ColorAdminRepository { diff --git a/clog-admin/src/main/kotlin/org/depromeet/clog/server/admin/domain/crag/GradeAdminRepository.kt b/clog-admin/src/main/kotlin/org/depromeet/clog/server/admin/domain/crag/GradeAdminRepository.kt index ead15377..d61e931d 100644 --- a/clog-admin/src/main/kotlin/org/depromeet/clog/server/admin/domain/crag/GradeAdminRepository.kt +++ b/clog-admin/src/main/kotlin/org/depromeet/clog/server/admin/domain/crag/GradeAdminRepository.kt @@ -1,7 +1,7 @@ package org.depromeet.clog.server.admin.domain.crag import org.depromeet.clog.server.domain.crag.domain.Crag -import org.depromeet.clog.server.domain.crag.domain.Grade +import org.depromeet.clog.server.domain.crag.domain.grade.Grade interface GradeAdminRepository { diff --git a/clog-admin/src/main/resources/templates/admin/cragDetails.html b/clog-admin/src/main/resources/templates/admin/cragDetails.html index f56d8f3d..f1784d70 100644 --- a/clog-admin/src/main/resources/templates/admin/cragDetails.html +++ b/clog-admin/src/main/resources/templates/admin/cragDetails.html @@ -50,14 +50,14 @@ <h6 class="m-0 font-weight-bold text-primary" th:text="${crag.name}">암장 이 <th>도로명 주소</th> <td th:text="${crag.roadAddress}"></td> </tr> - <tr> - <th>경도</th> - <td th:text="${crag.coordinate.longitude}"></td> - </tr> - <tr> - <th>위도</th> - <td th:text="${crag.coordinate.latitude}"></td> - </tr> +<!-- <tr>--> +<!-- <th>경도</th>--> +<!-- <td th:text="${crag.coordinate.longitude}"></td>--> +<!-- </tr>--> +<!-- <tr>--> +<!-- <th>위도</th>--> +<!-- <td th:text="${crag.coordinate.latitude}"></td>--> +<!-- </tr>--> </tbody> </table> </div> diff --git a/clog-infrastructure/src/main/kotlin/org/depromeet/clog/server/infrastructure/admin/ColorAdminAdapter.kt b/clog-infrastructure/src/main/kotlin/org/depromeet/clog/server/infrastructure/admin/ColorAdminAdapter.kt index 8ce2f69a..9f9db621 100644 --- a/clog-infrastructure/src/main/kotlin/org/depromeet/clog/server/infrastructure/admin/ColorAdminAdapter.kt +++ b/clog-infrastructure/src/main/kotlin/org/depromeet/clog/server/infrastructure/admin/ColorAdminAdapter.kt @@ -1,25 +1,28 @@ package org.depromeet.clog.server.infrastructure.admin import org.depromeet.clog.server.admin.domain.crag.ColorAdminRepository -import org.depromeet.clog.server.domain.crag.domain.Color -import org.depromeet.clog.server.infrastructure.crag.ColorEntity +import org.depromeet.clog.server.domain.crag.domain.color.Color import org.depromeet.clog.server.infrastructure.crag.ColorJpaRepository +import org.depromeet.clog.server.infrastructure.mappers.ColorMapper import org.springframework.stereotype.Component @Component class ColorAdminAdapter( + private val colorMapper: ColorMapper, private val colorJpaRepository: ColorJpaRepository ) : ColorAdminRepository { override fun save(color: Color): Color { - return colorJpaRepository.save(ColorEntity.fromDomain(color)).toDomain() + val entity = colorJpaRepository.save(colorMapper.toEntity(color)) + return colorMapper.toDomain(entity) } override fun findAll(): List<Color> { - return colorJpaRepository.findAll().map { it.toDomain() } + return colorJpaRepository.findAll().map { colorMapper.toDomain(it) } } override fun findByNameAndHex(name: String, hex: String): Color? { - return colorJpaRepository.findByNameAndHex(name, hex).toDomain() + val entity = colorJpaRepository.findByNameAndHex(name, hex) + return colorMapper.toDomain(entity) } } diff --git a/clog-infrastructure/src/main/kotlin/org/depromeet/clog/server/infrastructure/admin/CragAdminAdapter.kt b/clog-infrastructure/src/main/kotlin/org/depromeet/clog/server/infrastructure/admin/CragAdminAdapter.kt index 21bf79bc..6bb793ee 100644 --- a/clog-infrastructure/src/main/kotlin/org/depromeet/clog/server/infrastructure/admin/CragAdminAdapter.kt +++ b/clog-infrastructure/src/main/kotlin/org/depromeet/clog/server/infrastructure/admin/CragAdminAdapter.kt @@ -2,25 +2,28 @@ package org.depromeet.clog.server.infrastructure.admin import org.depromeet.clog.server.admin.domain.crag.CragAdminRepository import org.depromeet.clog.server.domain.crag.domain.Crag -import org.depromeet.clog.server.infrastructure.crag.CragEntity import org.depromeet.clog.server.infrastructure.crag.CragJpaRepository +import org.depromeet.clog.server.infrastructure.mappers.CragMapper import org.springframework.data.repository.findByIdOrNull import org.springframework.stereotype.Component @Component class CragAdminAdapter( + private val cragMapper: CragMapper, private val cragJpaRepository: CragJpaRepository ) : CragAdminRepository { override fun save(crag: Crag): Crag { - return cragJpaRepository.save(CragEntity.fromDomain(crag)).toDomain() + val entity = cragJpaRepository.save(cragMapper.toEntity(crag)) + return cragMapper.toDomain(entity) } override fun findById(id: Long): Crag? { - return cragJpaRepository.findByIdOrNull(id)?.toDomain() + val entity = cragJpaRepository.findByIdOrNull(id) + return cragMapper.toDomain(entity!!) } override fun findAll(): List<Crag> { - return cragJpaRepository.findAll().map { it.toDomain() } + return cragJpaRepository.findAll().map { cragMapper.toDomain(it) } } } diff --git a/clog-infrastructure/src/main/kotlin/org/depromeet/clog/server/infrastructure/admin/GradeAdminAdapter.kt b/clog-infrastructure/src/main/kotlin/org/depromeet/clog/server/infrastructure/admin/GradeAdminAdapter.kt index 042cb7a4..08519f80 100644 --- a/clog-infrastructure/src/main/kotlin/org/depromeet/clog/server/infrastructure/admin/GradeAdminAdapter.kt +++ b/clog-infrastructure/src/main/kotlin/org/depromeet/clog/server/infrastructure/admin/GradeAdminAdapter.kt @@ -2,22 +2,25 @@ package org.depromeet.clog.server.infrastructure.admin import org.depromeet.clog.server.admin.domain.crag.GradeAdminRepository import org.depromeet.clog.server.domain.crag.domain.Crag -import org.depromeet.clog.server.domain.crag.domain.Grade -import org.depromeet.clog.server.infrastructure.crag.CragEntity -import org.depromeet.clog.server.infrastructure.crag.GradeEntity +import org.depromeet.clog.server.domain.crag.domain.grade.Grade import org.depromeet.clog.server.infrastructure.crag.GradeJpaRepository +import org.depromeet.clog.server.infrastructure.mappers.CragMapper +import org.depromeet.clog.server.infrastructure.mappers.GradeMapper import org.springframework.stereotype.Component @Component class GradeAdminAdapter( + private val cragMapper: CragMapper, + private val gradeMapper: GradeMapper, private val gradeJpaRepository: GradeJpaRepository ) : GradeAdminRepository { override fun save(grade: Grade): Grade { - return gradeJpaRepository.save(GradeEntity.fromDomain(grade)).toDomain() + val entity = gradeJpaRepository.save(gradeMapper.toEntity(grade)) + return gradeMapper.toDomain(entity) } override fun findByCrag(crag: Crag): List<Grade> { - return gradeJpaRepository.findByCrag(CragEntity.fromDomain(crag)).map { it.toDomain() } + return gradeJpaRepository.findByCrag(cragMapper.toEntity(crag)).map { gradeMapper.toDomain(it) } } } diff --git a/clog-infrastructure/src/main/kotlin/org/depromeet/clog/server/infrastructure/crag/GradeJpaRepository.kt b/clog-infrastructure/src/main/kotlin/org/depromeet/clog/server/infrastructure/crag/GradeJpaRepository.kt index 3fc464d5..e22c5aed 100644 --- a/clog-infrastructure/src/main/kotlin/org/depromeet/clog/server/infrastructure/crag/GradeJpaRepository.kt +++ b/clog-infrastructure/src/main/kotlin/org/depromeet/clog/server/infrastructure/crag/GradeJpaRepository.kt @@ -24,4 +24,6 @@ interface GradeJpaRepository : JpaRepository<GradeEntity, Long>, KotlinJdslJpqlE @Param("cursor") cursor: Long?, pageable: Pageable ): List<GradeEntity> + + fun findByCrag(crag: CragEntity): MutableList<GradeEntity> }