From cca8f309e84a1240909d84c8b4a9caeaa99da3be Mon Sep 17 00:00:00 2001 From: dldmsql Date: Sun, 1 Sep 2024 16:00:49 +0900 Subject: [PATCH] =?UTF-8?q?feat(POLABO-128):=203=EC=B0=A8=20mvp=20?= =?UTF-8?q?=EA=B0=9C=EB=B0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../board/controller/BoardController.kt | 36 +++++++++----- .../board/my/controller/MyBoardController.kt | 48 +++++++++++++------ .../my/controller/MyBoardV2Controller.kt | 38 +++++++++++++++ .../domain/board/my/dto/MyBoardDto.kt | 7 ++- .../domain/board/my/service/MyBoardService.kt | 43 ++++++++++++++++- .../board/repository/BoardJooqRepository.kt | 10 +++- .../repository/BoardJooqRepositoryImpl.kt | 46 +++++++++++++++++- .../domain/board/service/BoardService.kt | 11 +++-- .../controller/BoardPolaroidController.kt | 14 ++++-- .../controller/BoardPolaroidV2Controller.kt | 45 +++++++++++++++++ .../polaroid/controller/PolaroidController.kt | 8 +++- .../controller/dto/PolaroidCreateRequest.kt | 6 ++- .../controller/dto/PolaroidGetResponse.kt | 2 + .../repository/PolaroidJooqRepository.kt | 1 + .../repository/PolaroidJooqRepositoryImpl.kt | 19 ++++++++ .../polaroid/service/PolaroidService.kt | 33 +++++++++++-- .../global/config/SecurityConfig.kt | 3 +- src/main/resources/application-dev.yml | 20 -------- src/main/resources/application-local.yml | 20 -------- 19 files changed, 319 insertions(+), 91 deletions(-) create mode 100644 src/main/kotlin/com/ddd/sonnypolabobe/domain/board/my/controller/MyBoardV2Controller.kt create mode 100644 src/main/kotlin/com/ddd/sonnypolabobe/domain/polaroid/controller/BoardPolaroidV2Controller.kt diff --git a/src/main/kotlin/com/ddd/sonnypolabobe/domain/board/controller/BoardController.kt b/src/main/kotlin/com/ddd/sonnypolabobe/domain/board/controller/BoardController.kt index e3084b5..3276e1b 100644 --- a/src/main/kotlin/com/ddd/sonnypolabobe/domain/board/controller/BoardController.kt +++ b/src/main/kotlin/com/ddd/sonnypolabobe/domain/board/controller/BoardController.kt @@ -23,36 +23,46 @@ import java.util.UUID class BoardController( private val boardService: BoardService ) { - @Operation(summary = "보드 생성", description = """ + @Operation( + summary = "보드 생성", description = """ 보드를 생성합니다. userId는 추후 회원가입 기능이 추가될 것을 대비한 것입니다. 지금은 null로 주세요. userId 데이터는 백에서 채울 것입니다.! - """) + """ + ) @PostMapping - fun create(@RequestBody request : BoardCreateRequest) - : ApplicationResponse { - val user = SecurityContextHolder.getContext().authentication.principal as UserDto.Companion.Res + fun create(@RequestBody request: BoardCreateRequest) + : ApplicationResponse { + val user = + SecurityContextHolder.getContext().authentication.principal as UserDto.Companion.Res request.userId = user.id return ApplicationResponse.ok(this.boardService.create(request)) } - @Operation(summary = "보드 조회", description = """ + @Tag(name = "1.1.0") + @Operation( + summary = "보드 조회", description = """ 보드를 조회합니다. - """) + DTO 필드 수정했습니다. 폴라로이드에 닉네임 필드 추가 + """ + ) @GetMapping("/{id}") - fun get(@PathVariable id : String) - = ApplicationResponse.ok(this.boardService.getById(id)) + fun get(@PathVariable id: String) = ApplicationResponse.ok(this.boardService.getById(id)) - @Operation(summary = "보드 누적 생성 수 조회", description = """ + @Operation( + summary = "보드 누적 생성 수 조회", description = """ 보드 누적 생성 수를 조회합니다. - """) + """ + ) @GetMapping("/total-count") fun getTotalCount() = ApplicationResponse.ok(this.boardService.getTotalCount()) - @Operation(summary = "오늘 생성 가능한 보드 수 조회", description = """ + @Operation( + summary = "오늘 생성 가능한 보드 수 조회", description = """ 오늘 생성 가능한 보드 수를 조회합니다. - """) + """ + ) @GetMapping("/create-available") fun createAvailable() = ApplicationResponse.ok(this.boardService.createAvailable()) } \ No newline at end of file diff --git a/src/main/kotlin/com/ddd/sonnypolabobe/domain/board/my/controller/MyBoardController.kt b/src/main/kotlin/com/ddd/sonnypolabobe/domain/board/my/controller/MyBoardController.kt index 10522e3..b7fd8ce 100644 --- a/src/main/kotlin/com/ddd/sonnypolabobe/domain/board/my/controller/MyBoardController.kt +++ b/src/main/kotlin/com/ddd/sonnypolabobe/domain/board/my/controller/MyBoardController.kt @@ -6,22 +6,26 @@ import com.ddd.sonnypolabobe.domain.user.dto.UserDto import com.ddd.sonnypolabobe.global.entity.PageDto import com.ddd.sonnypolabobe.global.response.ApplicationResponse import io.swagger.v3.oas.annotations.Operation +import io.swagger.v3.oas.annotations.tags.Tag import org.springframework.security.core.context.SecurityContextHolder import org.springframework.web.bind.annotation.* @RestController @RequestMapping("/api/v1/my/boards") -class MyBoardController(private val myBoardService : MyBoardService) { +class MyBoardController(private val myBoardService: MyBoardService) { - @Operation(summary = "내 보드 목록 조회", description = """ + @Operation( + summary = "내 보드 목록 조회", description = """ 내 보드 목록을 조회합니다. - """) + """ + ) @GetMapping fun getMyBoards( - @RequestParam(name = "page", defaultValue = "1") page : Int, - @RequestParam size : Int - ) : ApplicationResponse> { - val user = SecurityContextHolder.getContext().authentication.principal as UserDto.Companion.Res + @RequestParam(name = "page", defaultValue = "1") page: Int, + @RequestParam size: Int + ): ApplicationResponse> { + val user = + SecurityContextHolder.getContext().authentication.principal as UserDto.Companion.Res return ApplicationResponse.ok(this.myBoardService.getMyBoards(user.id, page, size)) } @@ -34,10 +38,11 @@ class MyBoardController(private val myBoardService : MyBoardService) { ) @PutMapping("/{id}") fun updateMyBoard( - @PathVariable id : String, - @RequestBody request : MyBoardDto.Companion.MBUpdateReq - ) : ApplicationResponse { - val userId = SecurityContextHolder.getContext().authentication.principal as UserDto.Companion.Res + @PathVariable id: String, + @RequestBody request: MyBoardDto.Companion.MBUpdateReq + ): ApplicationResponse { + val userId = + SecurityContextHolder.getContext().authentication.principal as UserDto.Companion.Res this.myBoardService.updateMyBoard(id, request, userId.id) return ApplicationResponse.ok() } @@ -50,10 +55,25 @@ class MyBoardController(private val myBoardService : MyBoardService) { ) @DeleteMapping("/{id}") fun deleteMyBoard( - @PathVariable id : String - ) : ApplicationResponse { - val userId = SecurityContextHolder.getContext().authentication.principal as UserDto.Companion.Res + @PathVariable id: String + ): ApplicationResponse { + val userId = + SecurityContextHolder.getContext().authentication.principal as UserDto.Companion.Res this.myBoardService.deleteMyBoard(id, userId.id) return ApplicationResponse.ok() } + + @Tag(name = "1.1.0") + @Operation( + summary = "내가 만든 보드 총 개수", + description = """ + 내가 만든 보드의 총 개수를 조회합니다. + """ + ) + @GetMapping("/total-count") + fun getTotalCount(): ApplicationResponse { + val userId = + SecurityContextHolder.getContext().authentication.principal as UserDto.Companion.Res + return ApplicationResponse.ok(this.myBoardService.getTotalCount(userId.id)) + } } \ No newline at end of file diff --git a/src/main/kotlin/com/ddd/sonnypolabobe/domain/board/my/controller/MyBoardV2Controller.kt b/src/main/kotlin/com/ddd/sonnypolabobe/domain/board/my/controller/MyBoardV2Controller.kt new file mode 100644 index 0000000..0eeb7d2 --- /dev/null +++ b/src/main/kotlin/com/ddd/sonnypolabobe/domain/board/my/controller/MyBoardV2Controller.kt @@ -0,0 +1,38 @@ +package com.ddd.sonnypolabobe.domain.board.my.controller + +import com.ddd.sonnypolabobe.domain.board.my.dto.MyBoardDto +import com.ddd.sonnypolabobe.domain.board.my.service.MyBoardService +import com.ddd.sonnypolabobe.domain.user.dto.UserDto +import com.ddd.sonnypolabobe.global.entity.PageDto +import com.ddd.sonnypolabobe.global.response.ApplicationResponse +import io.swagger.v3.oas.annotations.Operation +import io.swagger.v3.oas.annotations.tags.Tag +import org.springframework.security.core.context.SecurityContextHolder +import org.springframework.web.bind.annotation.* + +@Tag(name = "1.1.0") +@RestController +@RequestMapping("/api/v2/my/boards") +class MyBoardV2Controller(private val myBoardService : MyBoardService) { + + @Operation(summary = "내 보드 목록 조회 - v2", description = """ + 내 보드 목록을 조회합니다. + 필터가 추가되었습니다. + """) + @GetMapping + fun getMyBoards( + @RequestParam(name = "page", defaultValue = "1") page : Int, + @RequestParam size : Int, + @RequestParam filter : Filter + ) : ApplicationResponse> { + val user = SecurityContextHolder.getContext().authentication.principal as UserDto.Companion.Res + return ApplicationResponse.ok(this.myBoardService.getMyBoards(user.id, page, size, filter)) + } + + companion object { + enum class Filter { + OWNER, PARTICIPANT + } + } + +} \ No newline at end of file diff --git a/src/main/kotlin/com/ddd/sonnypolabobe/domain/board/my/dto/MyBoardDto.kt b/src/main/kotlin/com/ddd/sonnypolabobe/domain/board/my/dto/MyBoardDto.kt index 91ce2eb..9aa647f 100644 --- a/src/main/kotlin/com/ddd/sonnypolabobe/domain/board/my/dto/MyBoardDto.kt +++ b/src/main/kotlin/com/ddd/sonnypolabobe/domain/board/my/dto/MyBoardDto.kt @@ -24,7 +24,12 @@ class MyBoardDto { val title: String, @DateTimeFormat(pattern = "yyyy-MM-dd", iso = DateTimeFormat.ISO.DATE) val createdAt: LocalDateTime, - val userId : Long? + val userId: Long? + ) + + data class TotalCountRes( + val totalCreateCount: Long, + val totalParticipantCount: Long ) } diff --git a/src/main/kotlin/com/ddd/sonnypolabobe/domain/board/my/service/MyBoardService.kt b/src/main/kotlin/com/ddd/sonnypolabobe/domain/board/my/service/MyBoardService.kt index 6382951..c08fc93 100644 --- a/src/main/kotlin/com/ddd/sonnypolabobe/domain/board/my/service/MyBoardService.kt +++ b/src/main/kotlin/com/ddd/sonnypolabobe/domain/board/my/service/MyBoardService.kt @@ -1,13 +1,20 @@ package com.ddd.sonnypolabobe.domain.board.my.service +import com.ddd.sonnypolabobe.domain.board.my.controller.MyBoardV2Controller import com.ddd.sonnypolabobe.domain.board.my.dto.MyBoardDto import com.ddd.sonnypolabobe.domain.board.repository.BoardJooqRepository +import com.ddd.sonnypolabobe.domain.polaroid.repository.PolaroidJooqRepository +import com.ddd.sonnypolabobe.domain.polaroid.service.PolaroidService import com.ddd.sonnypolabobe.global.entity.PageDto import com.ddd.sonnypolabobe.global.util.UuidConverter import org.springframework.stereotype.Service +import org.springframework.transaction.annotation.Transactional @Service -class MyBoardService(private val boardJooqRepository: BoardJooqRepository) { +class MyBoardService( + private val boardJooqRepository: BoardJooqRepository, +) { + @Transactional fun updateMyBoard(id: String, request: MyBoardDto.Companion.MBUpdateReq, userId: Long) { val board = this.boardJooqRepository.findById(UuidConverter.stringToUUID(id)) ?: throw IllegalArgumentException("해당 보드가 존재하지 않습니다.") @@ -17,6 +24,7 @@ class MyBoardService(private val boardJooqRepository: BoardJooqRepository) { this.boardJooqRepository.updateTitle(UuidConverter.stringToUUID(id), request.title) } + @Transactional fun deleteMyBoard(id: String, userId: Long) { val board = this.boardJooqRepository.findById(UuidConverter.stringToUUID(id)) ?: throw IllegalArgumentException("해당 보드가 존재하지 않습니다.") @@ -26,10 +34,41 @@ class MyBoardService(private val boardJooqRepository: BoardJooqRepository) { this.boardJooqRepository.delete(UuidConverter.stringToUUID(id)) } + @Transactional(readOnly = true) fun getMyBoards(userId: Long, page: Int, size: Int): PageDto { - val data = this.boardJooqRepository.findAllByUserId(userId, page-1, size) + val data = this.boardJooqRepository.findAllByUserId(userId, page - 1, size) val totalCount = this.boardJooqRepository.selectTotalCountByUserId(userId) return PageDto(data, totalCount, page, size) } + + @Transactional(readOnly = true) + fun getMyBoards( + userId: Long, + page: Int, + size: Int, + filter: MyBoardV2Controller.Companion.Filter + ): PageDto { + when (filter) { + MyBoardV2Controller.Companion.Filter.OWNER -> { + val data = this.boardJooqRepository.findAllByUserId(userId, page - 1, size) + val totalCount = this.boardJooqRepository.selectTotalCountByUserId(userId) + return PageDto(data, totalCount, page, size) + } + + MyBoardV2Controller.Companion.Filter.PARTICIPANT -> { + val data = this.boardJooqRepository.findAllByParticipant(userId, page - 1, size) + val totalCount = this.boardJooqRepository.selectTotalCountByParticipant(userId) + return PageDto(data, totalCount, page, size) + } + } + } + + @Transactional(readOnly = true) + fun getTotalCount(userId: Long): MyBoardDto.Companion.TotalCountRes { + return MyBoardDto.Companion.TotalCountRes( + totalCreateCount = this.boardJooqRepository.selectTotalCountByUserId(userId), + totalParticipantCount = this.boardJooqRepository.selectTotalCountByParticipant(userId) + ) + } } \ No newline at end of file diff --git a/src/main/kotlin/com/ddd/sonnypolabobe/domain/board/repository/BoardJooqRepository.kt b/src/main/kotlin/com/ddd/sonnypolabobe/domain/board/repository/BoardJooqRepository.kt index 1520e6f..fd5da4e 100644 --- a/src/main/kotlin/com/ddd/sonnypolabobe/domain/board/repository/BoardJooqRepository.kt +++ b/src/main/kotlin/com/ddd/sonnypolabobe/domain/board/repository/BoardJooqRepository.kt @@ -4,12 +4,13 @@ import com.ddd.sonnypolabobe.domain.board.controller.dto.BoardCreateRequest import com.ddd.sonnypolabobe.domain.board.my.dto.MyBoardDto import com.ddd.sonnypolabobe.jooq.polabo.tables.Board import org.jooq.Record6 +import org.jooq.Record7 import java.time.LocalDateTime import java.util.* interface BoardJooqRepository { fun insertOne(request: BoardCreateRequest): ByteArray? - fun selectOneById(id: UUID) : Array> + fun selectOneById(id: UUID) : Array> fun selectTotalCount(): Long fun selectTodayTotalCount(): Long fun findById(id: UUID): MyBoardDto.Companion.GetOneRes? @@ -17,4 +18,11 @@ interface BoardJooqRepository { fun delete(id: UUID) fun findAllByUserId(userId: Long, page: Int, size: Int): List fun selectTotalCountByUserId(userId: Long): Long + fun findAllByParticipant( + userId: Long, + page: Int, + size: Int + ): List + + fun selectTotalCountByParticipant(userId: Long): Long } \ No newline at end of file diff --git a/src/main/kotlin/com/ddd/sonnypolabobe/domain/board/repository/BoardJooqRepositoryImpl.kt b/src/main/kotlin/com/ddd/sonnypolabobe/domain/board/repository/BoardJooqRepositoryImpl.kt index 0dfaa2b..1b31102 100644 --- a/src/main/kotlin/com/ddd/sonnypolabobe/domain/board/repository/BoardJooqRepositoryImpl.kt +++ b/src/main/kotlin/com/ddd/sonnypolabobe/domain/board/repository/BoardJooqRepositoryImpl.kt @@ -10,6 +10,7 @@ import com.ddd.sonnypolabobe.jooq.polabo.tables.Board import com.ddd.sonnypolabobe.jooq.polabo.tables.Polaroid import org.jooq.DSLContext import org.jooq.Record6 +import org.jooq.Record7 import org.springframework.stereotype.Repository import java.time.LocalDateTime import java.util.* @@ -36,7 +37,7 @@ class BoardJooqRepositoryImpl( return if (result == 1) id else null } - override fun selectOneById(id: UUID): Array> { + override fun selectOneById(id: UUID): Array> { val jBoard = Board.BOARD val jPolaroid = Polaroid.POLAROID return this.dslContext @@ -46,7 +47,8 @@ class BoardJooqRepositoryImpl( jPolaroid.IMAGE_KEY, jPolaroid.ONE_LINE_MESSAGE, jPolaroid.CREATED_AT, - jPolaroid.USER_ID + jPolaroid.USER_ID, + jPolaroid.NICKNAME ) .from(jBoard) .leftJoin(jPolaroid).on( @@ -149,4 +151,44 @@ class BoardJooqRepositoryImpl( .where(jBoard.USER_ID.eq(userId).and(jBoard.YN.eq(1)).and(jBoard.ACTIVEYN.eq(1))) .fetchOne(0, Long::class.java) ?: 0L } + + override fun findAllByParticipant( + userId: Long, + page: Int, + size: Int + ): List { + val jBoard = Board.BOARD + val jPolaroid = Polaroid.POLAROID + val data = this.dslContext.select( + jBoard.ID, + jBoard.TITLE, + jBoard.CREATED_AT + ) + .from(jBoard) + .innerJoin(jPolaroid).on( + jBoard.ID.eq(jPolaroid.BOARD_ID).and(jPolaroid.USER_ID.eq(userId)) + .and(jPolaroid.YN.eq(1)).and(jPolaroid.ACTIVEYN.eq(1)) + ) + + return data.map { + MyBoardDto.Companion.PageListRes( + id = UuidConverter.byteArrayToUUID(it.get("id", ByteArray::class.java)!!), + title = it.get("title", String::class.java)!!, + createdAt = it.get("created_at", LocalDateTime::class.java)!!, + ) + } + } + + override fun selectTotalCountByParticipant(userId: Long): Long { + val jBoard = Board.BOARD + val jPolaroid = Polaroid.POLAROID + return this.dslContext + .selectCount() + .from(jBoard) + .innerJoin(jPolaroid).on( + jBoard.ID.eq(jPolaroid.BOARD_ID).and(jPolaroid.USER_ID.eq(userId)) + .and(jPolaroid.YN.eq(1)).and(jPolaroid.ACTIVEYN.eq(1)) + ) + .fetchOne(0, Long::class.java) ?: 0L + } } \ No newline at end of file diff --git a/src/main/kotlin/com/ddd/sonnypolabobe/domain/board/service/BoardService.kt b/src/main/kotlin/com/ddd/sonnypolabobe/domain/board/service/BoardService.kt index 15b3d16..9cfcac8 100644 --- a/src/main/kotlin/com/ddd/sonnypolabobe/domain/board/service/BoardService.kt +++ b/src/main/kotlin/com/ddd/sonnypolabobe/domain/board/service/BoardService.kt @@ -19,12 +19,14 @@ class BoardService( @Value("\${limit.count}") private val limit: Int ) { - fun create(request: BoardCreateRequest): UUID = this.boardJooqRepository.insertOne(request)?.let { UuidConverter.byteArrayToUUID(it) } - ?: throw ApplicationException(CustomErrorCode.BOARD_CREATED_FAILED) + fun create(request: BoardCreateRequest): UUID = + this.boardJooqRepository.insertOne(request)?.let { UuidConverter.byteArrayToUUID(it) } + ?: throw ApplicationException(CustomErrorCode.BOARD_CREATED_FAILED) fun getById(id: String): List { return id.run { - val queryResult = boardJooqRepository.selectOneById(UuidConverter.stringToUUID(this@run)) + val queryResult = + boardJooqRepository.selectOneById(UuidConverter.stringToUUID(this@run)) val groupByTitle = queryResult.groupBy { it.value1() } groupByTitle.map { entry -> val title = entry.key @@ -33,7 +35,8 @@ class BoardService( id = it.value2() ?: 0L, imageUrl = it.value3()?.let { it1 -> s3Util.getImgUrl(it1) } ?: "", oneLineMessage = it.value4() ?: "폴라보와의 추억 한 줄", - userId = it.value6() ?: 0L + userId = it.value6() ?: 0L, + nickname = it.value7() ?: "" ) }.filter { it.id != 0L } BoardGetResponse(title = title ?: "", items = polaroids) diff --git a/src/main/kotlin/com/ddd/sonnypolabobe/domain/polaroid/controller/BoardPolaroidController.kt b/src/main/kotlin/com/ddd/sonnypolabobe/domain/polaroid/controller/BoardPolaroidController.kt index 399a249..c4a94e0 100644 --- a/src/main/kotlin/com/ddd/sonnypolabobe/domain/polaroid/controller/BoardPolaroidController.kt +++ b/src/main/kotlin/com/ddd/sonnypolabobe/domain/polaroid/controller/BoardPolaroidController.kt @@ -4,6 +4,7 @@ import com.ddd.sonnypolabobe.domain.polaroid.controller.dto.PolaroidCreateReques import com.ddd.sonnypolabobe.domain.polaroid.service.PolaroidService import com.ddd.sonnypolabobe.global.response.ApplicationResponse import io.swagger.v3.oas.annotations.Operation +import io.swagger.v3.oas.annotations.tags.Tag import jakarta.validation.Valid import org.springframework.web.bind.annotation.* @@ -11,11 +12,16 @@ import org.springframework.web.bind.annotation.* @RequestMapping("/api/v1/boards/{boardId}/polaroids") class BoardPolaroidController(private val polaroidService: PolaroidService) { - @Operation(summary = "폴라로이드 생성", description = """ + @Tag(name = "1.1.0") + @Operation( + summary = "폴라로이드 생성", description = """ 폴라로이드를 생성합니다. - """) + + v2를 사용해주세요. 혹시 v1을 사용하는 곳이 남아있다면, 보드 내 폴라로이드 최대 30개 생성으로 제한 됩니다. + """ + ) @PostMapping - fun create(@PathVariable boardId : String, @RequestBody @Valid request : PolaroidCreateRequest) - = ApplicationResponse.ok(this.polaroidService.create(boardId, request)) + fun create(@PathVariable boardId: String, @RequestBody @Valid request: PolaroidCreateRequest) = + ApplicationResponse.ok(this.polaroidService.create(boardId, request)) } \ No newline at end of file diff --git a/src/main/kotlin/com/ddd/sonnypolabobe/domain/polaroid/controller/BoardPolaroidV2Controller.kt b/src/main/kotlin/com/ddd/sonnypolabobe/domain/polaroid/controller/BoardPolaroidV2Controller.kt new file mode 100644 index 0000000..1ec8d84 --- /dev/null +++ b/src/main/kotlin/com/ddd/sonnypolabobe/domain/polaroid/controller/BoardPolaroidV2Controller.kt @@ -0,0 +1,45 @@ +package com.ddd.sonnypolabobe.domain.polaroid.controller + +import com.ddd.sonnypolabobe.domain.polaroid.controller.dto.PolaroidCreateRequest +import com.ddd.sonnypolabobe.domain.polaroid.service.PolaroidService +import com.ddd.sonnypolabobe.global.response.ApplicationResponse +import com.ddd.sonnypolabobe.global.security.JwtUtil +import io.swagger.v3.oas.annotations.Operation +import io.swagger.v3.oas.annotations.tags.Tag +import jakarta.validation.Valid +import org.springframework.web.bind.annotation.* + +@Tag(name = "1.1.0") +@RestController +@RequestMapping("/api/v2/boards/{boardId}/polaroids") +class BoardPolaroidV2Controller( + private val polaroidService: PolaroidService, + private val jwtUtil: JwtUtil +) { + + @Operation( + summary = "폴라로이드 생성", description = """ + 폴라로이드를 생성합니다. + + 작성자 닉네임이 추가되었습니다. + """ + ) + @PostMapping + fun create( + @PathVariable boardId: String, + @RequestBody @Valid request: PolaroidCreateRequest, + @RequestHeader("Authorization") token: String? + ): ApplicationResponse { + val userInfo = token?.let { this.jwtUtil.getAuthenticatedMemberFromToken(it) } + userInfo?.let { + if(request.nickname == null) { + request.nickname = userInfo.nickname + } + } + val userId = userInfo?.id?.toLong() + ?: return ApplicationResponse.ok(this.polaroidService.create(boardId, request)) + return ApplicationResponse.ok(this.polaroidService.create(boardId, request, userId)) + } + + +} \ No newline at end of file diff --git a/src/main/kotlin/com/ddd/sonnypolabobe/domain/polaroid/controller/PolaroidController.kt b/src/main/kotlin/com/ddd/sonnypolabobe/domain/polaroid/controller/PolaroidController.kt index 35ae562..c1edb01 100644 --- a/src/main/kotlin/com/ddd/sonnypolabobe/domain/polaroid/controller/PolaroidController.kt +++ b/src/main/kotlin/com/ddd/sonnypolabobe/domain/polaroid/controller/PolaroidController.kt @@ -3,6 +3,7 @@ package com.ddd.sonnypolabobe.domain.polaroid.controller import com.ddd.sonnypolabobe.domain.polaroid.service.PolaroidService import com.ddd.sonnypolabobe.global.response.ApplicationResponse import io.swagger.v3.oas.annotations.Operation +import io.swagger.v3.oas.annotations.tags.Tag import org.springframework.web.bind.annotation.GetMapping import org.springframework.web.bind.annotation.PathVariable import org.springframework.web.bind.annotation.RequestMapping @@ -12,9 +13,12 @@ import org.springframework.web.bind.annotation.RestController @RequestMapping("/api/v1/polaroids") class PolaroidController(private val polaroidService: PolaroidService) { - @Operation(summary = "폴라로이드 조회", description = """ + @Tag(name = "1.1.0") + @Operation( + summary = "폴라로이드 조회", description = """ 폴라로이드를 조회합니다. - """) + """ + ) @GetMapping("/{id}") fun getById(@PathVariable id: Long) = ApplicationResponse.ok(this.polaroidService.getById(id)) } \ No newline at end of file diff --git a/src/main/kotlin/com/ddd/sonnypolabobe/domain/polaroid/controller/dto/PolaroidCreateRequest.kt b/src/main/kotlin/com/ddd/sonnypolabobe/domain/polaroid/controller/dto/PolaroidCreateRequest.kt index 05bed06..d9dbe69 100644 --- a/src/main/kotlin/com/ddd/sonnypolabobe/domain/polaroid/controller/dto/PolaroidCreateRequest.kt +++ b/src/main/kotlin/com/ddd/sonnypolabobe/domain/polaroid/controller/dto/PolaroidCreateRequest.kt @@ -3,11 +3,13 @@ package com.ddd.sonnypolabobe.domain.polaroid.controller.dto import io.swagger.v3.oas.annotations.media.Schema import jakarta.validation.constraints.Size -@Schema(description = "폴라로이드 생성 요청") +@Schema(description = "폴라로이드 생성 요청 v2") data class PolaroidCreateRequest( @Schema(description = "이미지 키", example = "imageKey") val imageKey : String, @Schema(description = "한 줄 문구", example = "한 줄 메시지입니다. 최대 20자까지 가능합니다.") @field:Size(max = 20) - val oneLineMessage : String + val oneLineMessage : String, + @Schema(description = "작성자 닉네임이 null 이면서 회원가입된 유저라면, 유저의 닉네임을 자동할당합니다.", example = "작성자 닉네임") + var nickname : String? ) \ No newline at end of file diff --git a/src/main/kotlin/com/ddd/sonnypolabobe/domain/polaroid/controller/dto/PolaroidGetResponse.kt b/src/main/kotlin/com/ddd/sonnypolabobe/domain/polaroid/controller/dto/PolaroidGetResponse.kt index 092882c..4322274 100644 --- a/src/main/kotlin/com/ddd/sonnypolabobe/domain/polaroid/controller/dto/PolaroidGetResponse.kt +++ b/src/main/kotlin/com/ddd/sonnypolabobe/domain/polaroid/controller/dto/PolaroidGetResponse.kt @@ -12,4 +12,6 @@ data class PolaroidGetResponse( val oneLineMessage: String, @Schema(description = "작성자 ID", example = "userId") val userId: Long?, + @Schema(description = "작성자 닉네임", example = "nickname") + val nickname: String ) diff --git a/src/main/kotlin/com/ddd/sonnypolabobe/domain/polaroid/repository/PolaroidJooqRepository.kt b/src/main/kotlin/com/ddd/sonnypolabobe/domain/polaroid/repository/PolaroidJooqRepository.kt index 61345b9..dd70759 100644 --- a/src/main/kotlin/com/ddd/sonnypolabobe/domain/polaroid/repository/PolaroidJooqRepository.kt +++ b/src/main/kotlin/com/ddd/sonnypolabobe/domain/polaroid/repository/PolaroidJooqRepository.kt @@ -7,4 +7,5 @@ interface PolaroidJooqRepository { fun insertOne(boardId: ByteArray, request: PolaroidCreateRequest): Long fun selectOneById(id: Long): PolaroidRecord fun countByBoardId(uuidToByteArray: ByteArray): Int + fun insertOne(boardId: ByteArray, request: PolaroidCreateRequest, userId: Long): Long } \ No newline at end of file diff --git a/src/main/kotlin/com/ddd/sonnypolabobe/domain/polaroid/repository/PolaroidJooqRepositoryImpl.kt b/src/main/kotlin/com/ddd/sonnypolabobe/domain/polaroid/repository/PolaroidJooqRepositoryImpl.kt index a775a83..b4a5963 100644 --- a/src/main/kotlin/com/ddd/sonnypolabobe/domain/polaroid/repository/PolaroidJooqRepositoryImpl.kt +++ b/src/main/kotlin/com/ddd/sonnypolabobe/domain/polaroid/repository/PolaroidJooqRepositoryImpl.kt @@ -21,6 +21,25 @@ class PolaroidJooqRepositoryImpl(private val dslContext: DSLContext) : PolaroidJ this.createdAt = DateConverter.convertToKst(LocalDateTime.now()) this.yn = 1 this.activeyn = 1 + this.nickname = request.nickname + } + return this.dslContext.insertInto(jPolaroid) + .set(insertValue) + .returningResult(jPolaroid.ID) + .fetchOne()?.value1() ?: 0 + } + + override fun insertOne(boardId: ByteArray, request: PolaroidCreateRequest, userId: Long): Long { + val jPolaroid = Polaroid.POLAROID + val insertValue = jPolaroid.newRecord().apply { + this.boardId = boardId + this.imageKey = request.imageKey + this.oneLineMessage = request.oneLineMessage + this.createdAt = DateConverter.convertToKst(LocalDateTime.now()) + this.userId = userId + this.yn = 1 + this.activeyn = 1 + this.nickname = request.nickname } return this.dslContext.insertInto(jPolaroid) .set(insertValue) diff --git a/src/main/kotlin/com/ddd/sonnypolabobe/domain/polaroid/service/PolaroidService.kt b/src/main/kotlin/com/ddd/sonnypolabobe/domain/polaroid/service/PolaroidService.kt index 01e540b..b7721e2 100644 --- a/src/main/kotlin/com/ddd/sonnypolabobe/domain/polaroid/service/PolaroidService.kt +++ b/src/main/kotlin/com/ddd/sonnypolabobe/domain/polaroid/service/PolaroidService.kt @@ -8,25 +8,48 @@ import com.ddd.sonnypolabobe.global.exception.CustomErrorCode import com.ddd.sonnypolabobe.global.util.S3Util import com.ddd.sonnypolabobe.global.util.UuidConverter import org.springframework.stereotype.Service +import org.springframework.transaction.annotation.Transactional @Service -class PolaroidService(private val polaroidJooqRepository: PolaroidJooqRepository, private val s3Util: S3Util){ +class PolaroidService( + private val polaroidJooqRepository: PolaroidJooqRepository, + private val s3Util: S3Util +) { + @Transactional fun create(boardId: String, request: PolaroidCreateRequest): Long { val boardIdUuid = UuidConverter.stringToUUID(boardId) - val countByBoardId = this.polaroidJooqRepository.countByBoardId(UuidConverter.uuidToByteArray(boardIdUuid)) - if(countByBoardId > 50) throw ApplicationException(CustomErrorCode.POLAROID_COUNT_EXCEEDED) - return this.polaroidJooqRepository.insertOne(UuidConverter.uuidToByteArray(boardIdUuid), request) + val countByBoardId = + this.polaroidJooqRepository.countByBoardId(UuidConverter.uuidToByteArray(boardIdUuid)) + if (countByBoardId > 30) throw ApplicationException(CustomErrorCode.POLAROID_COUNT_EXCEEDED) + return this.polaroidJooqRepository.insertOne( + UuidConverter.uuidToByteArray(boardIdUuid), + request + ) } + @Transactional(readOnly = true) fun getById(id: Long): PolaroidGetResponse { return this.polaroidJooqRepository.selectOneById(id).let { PolaroidGetResponse( id = it.id!!, imageUrl = s3Util.getImgUrl(it.imageKey!!), oneLineMessage = it.oneLineMessage ?: "", - userId = it.userId + userId = it.userId, + nickname = it.nickname ?: "" ) } + } + @Transactional + fun create(boardId: String, request: PolaroidCreateRequest, userId: Long): Long { + val boardIdUuid = UuidConverter.stringToUUID(boardId) + val countByBoardId = + this.polaroidJooqRepository.countByBoardId(UuidConverter.uuidToByteArray(boardIdUuid)) + if (countByBoardId > 30) throw ApplicationException(CustomErrorCode.POLAROID_COUNT_EXCEEDED) + return this.polaroidJooqRepository.insertOne( + UuidConverter.uuidToByteArray(boardIdUuid), + request, + userId + ) } } \ No newline at end of file diff --git a/src/main/kotlin/com/ddd/sonnypolabobe/global/config/SecurityConfig.kt b/src/main/kotlin/com/ddd/sonnypolabobe/global/config/SecurityConfig.kt index 589d7c5..050687b 100644 --- a/src/main/kotlin/com/ddd/sonnypolabobe/global/config/SecurityConfig.kt +++ b/src/main/kotlin/com/ddd/sonnypolabobe/global/config/SecurityConfig.kt @@ -36,7 +36,8 @@ class SecurityConfig( "/swagger-ui/**", "/v3/api-docs/**", "/api/v1/polaroids/{id}", - "/api/v1/boards/{boardId}/polaroids" + "/api/v1/boards/{boardId}/polaroids", + "/api/v2/boards/{boardId}/polaroids", ) } @Bean diff --git a/src/main/resources/application-dev.yml b/src/main/resources/application-dev.yml index 255a97d..b94926b 100644 --- a/src/main/resources/application-dev.yml +++ b/src/main/resources/application-dev.yml @@ -20,27 +20,7 @@ spring: jooq: sql-dialect: mysql - security: - oauth2: - client: - registration: - kakao: - client-id: ENC(BD9NHDqbUHDpLXYtua4QLLznXweUau5/N3dA1IQqKhQW2sWvniKSDTS3+Z9t/oct) - client-secret: ENC(dMTqjTdS4VJz/1Gduapvl1rDDXUUKkp0bilgqRWMI9X4DaAMVDXY13Fb7QMBDUkI) - scope: - - account_email - - profile_nickname - authorization-grant-type: authorization_code - redirect-uri: https://api.polabo.site/api/v1/oauth/sign-in - client-name: Kakao - client-authentication-method: client_secret_post - provider: - kakao: - authorization-uri: https://kauth.kakao.com/oauth/authorize - token-uri: https://kauth.kakao.com/oauth/token - user-info-uri: https://kapi.kakao.com/v2/user/me - user-name-attribute: id cloud: aws: diff --git a/src/main/resources/application-local.yml b/src/main/resources/application-local.yml index dfdfd02..e56f699 100644 --- a/src/main/resources/application-local.yml +++ b/src/main/resources/application-local.yml @@ -20,27 +20,7 @@ spring: jooq: sql-dialect: mysql - security: - oauth2: - client: - registration: - kakao: - client-id: ENC(BD9NHDqbUHDpLXYtua4QLLznXweUau5/N3dA1IQqKhQW2sWvniKSDTS3+Z9t/oct) - client-secret: ENC(dMTqjTdS4VJz/1Gduapvl1rDDXUUKkp0bilgqRWMI9X4DaAMVDXY13Fb7QMBDUkI) - scope: - - account_email - - profile_nickname - authorization-grant-type: authorization_code - redirect-uri: https://api-dev.polabo.site/api/v1/oauth/sign-in - client-name: Kakao - client-authentication-method: client_secret_post - provider: - kakao: - authorization-uri: https://kauth.kakao.com/oauth/authorize - token-uri: https://kauth.kakao.com/oauth/token - user-info-uri: https://kapi.kakao.com/v2/user/me - user-name-attribute: id cloud: aws: