Skip to content

Commit

Permalink
[feat #204] 포킷 나가기 API (#205)
Browse files Browse the repository at this point in the history
* feat : 카테고리 owner_id 필드 추가

* feat : 포킷 나가기 api

* feat : 포킷 나가기 로직 구현
- 포킷 생성 시 공유카테고리 생성 로직 추가
- 내보내기 시 방장인 지 검증 로직 추가

* feat : 방장 후보 조회 쿼리 구현

* feat : 카테고리 생성자 오류 수정

* feat : 공유카테고리 조회 시 deleted 조건 추가
  • Loading branch information
dlswns2480 authored Dec 18, 2024
1 parent c00a36c commit 60ef5e0
Show file tree
Hide file tree
Showing 10 changed files with 84 additions and 9 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ package com.pokit.category.v1

import com.pokit.auth.aop.KakaoAuth
import com.pokit.auth.model.PrincipalUser
import com.pokit.category.port.`in`.CategoryUseCase
import com.pokit.category.v1.dto.request.DuplicateCategoryRequest
import com.pokit.category.v1.dto.response.SharedContentsResponse
import com.pokit.category.port.`in`.CategoryUseCase
import com.pokit.common.wrapper.ResponseWrapper.wrapOk
import com.pokit.common.wrapper.ResponseWrapper.wrapUnit
import com.pokit.content.port.`in`.ContentUseCase
Expand Down Expand Up @@ -86,4 +86,14 @@ class CategoryShareController(
.wrapUnit()
}

@Operation(summary = "포킷 나가기 API")
@PostMapping("/out/{categoryId}")
fun outCategory(
@AuthenticationPrincipal user: PrincipalUser,
@PathVariable categoryId: Long,
): ResponseEntity<Unit> {
return categoryUseCase.outCategory(user.id, categoryId)
.wrapUnit()
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -29,4 +29,11 @@ class SharedCategoryAdapter(
sharedCategoryRepository.findByIdOrNull(sharedCategory.id)
?.delete()
}

override fun loadFirstByCategoryId(categoryId: Long): SharedCategory? {
return sharedCategoryRepository.findFirstByCategoryIdAndIsDeletedOrderByCreatedAt(
categoryId,
false
)?.toDomain()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,9 @@ class CategoryEntity(
@Column(name = "keyword")
@Enumerated(EnumType.STRING)
var keyword: InterestType = InterestType.DEFAULT,

@Column(name = "owner_id")
var ownerId: Long,
) : BaseEntity() {

@Column(name = "is_deleted")
Expand All @@ -57,7 +60,8 @@ class CategoryEntity(
openType = category.openType,
userCount = category.userCount,
isShared = category.isShared,
keyword = category.keyword
keyword = category.keyword,
ownerId = category.ownerId,
)
}
}
Expand All @@ -71,5 +75,6 @@ fun CategoryEntity.toDomain() = Category(
openType = this.openType,
userCount = this.userCount,
isShared = this.isShared,
keyword = this.keyword
keyword = this.keyword,
ownerId = this.ownerId,
)
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,9 @@ interface SharedCategoryRepository : JpaRepository<SharedCategoryEntity, Long> {
categoryId: Long,
isDeleted: Boolean
): SharedCategoryEntity?

fun findFirstByCategoryIdAndIsDeletedOrderByCreatedAt(
categoryId: Long,
deleted: Boolean
): SharedCategoryEntity?
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,5 @@ interface CategoryUseCase {
fun duplicateCategory(originCategoryId: Long, categoryName: String, userId: Long, categoryImageId: Int)
fun acceptCategory(userId: Long, categoryId: Long)
fun resignUser(userId: Long, categoryId: Long, resignUserId: Long)
fun outCategory(userId: Long, categoryId: Long)
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,6 @@ interface SharedCategoryPort {
fun loadByUserIdAndCategoryId(userId: Long, categoryId: Long): SharedCategory?

fun delete(sharedCategory: SharedCategory)

fun loadFirstByCategoryId(categoryId: Long): SharedCategory?
}
Original file line number Diff line number Diff line change
Expand Up @@ -50,15 +50,25 @@ class CategoryService(
val categoryImage = categoryImagePort.loadById(command.categoryImageId)
?: throw NotFoundCustomException(CategoryErrorCode.NOT_FOUND_CATEGORY_IMAGE)

return categoryPort.persist(
val category = categoryPort.persist(
Category(
categoryName = command.categoryName,
categoryImage = categoryImage,
userId = userId,
openType = command.openType,
keyword = command.keywordType
keyword = command.keywordType,
ownerId = userId
)
)

val sharedCategory = SharedCategory(
userId = userId,
categoryId = category.categoryId
)

sharedCategoryPort.persist(sharedCategory)

return category
}

@Transactional
Expand Down Expand Up @@ -167,17 +177,44 @@ class CategoryService(

categoryPort.persist(category)

val sharedCategory = SharedCategory(userId = userId, categoryId = category.categoryId)
val sharedCategory = SharedCategory(
userId = userId,
categoryId = category.categoryId,
)
sharedCategoryPort.persist(sharedCategory)
}

@Transactional
override fun resignUser(userId: Long, categoryId: Long, resignUserId: Long) {
val category = categoryPort.loadByIdAndUserId(categoryId, userId)
?: throw NotFoundCustomException(CategoryErrorCode.NOT_FOUND_CATEGORY)
val category = categoryPort.loadCategoryOrThrow(categoryId, userId)
if (category.userId != userId) {
throw ClientValidationException(CategoryErrorCode.NOT_OWNER)
}
val sharedCategory = (sharedCategoryPort.loadByUserIdAndCategoryId(resignUserId, category.categoryId)
?: throw NotFoundCustomException(CategoryErrorCode.NEVER_ACCPTED))

sharedCategoryPort.delete(sharedCategory)

category.minusUserCount() // 포킷 인원수 감소
categoryPort.persist(category)
}

@Transactional
override fun outCategory(userId: Long, categoryId: Long) {
val category = categoryPort.loadByIdOrThrow(categoryId)

val sharedCategory = sharedCategoryPort.loadByUserIdAndCategoryId(userId, categoryId)
?: throw NotFoundCustomException(CategoryErrorCode.NEVER_ACCPTED)
sharedCategoryPort.delete(sharedCategory)

if (category.ownerId == userId) { // 나간사람이 방장이었다면
val firstSharedCategory = sharedCategoryPort.loadFirstByCategoryId(categoryId)
?: throw ClientValidationException(CategoryErrorCode.EMPTY_USER_IN_CATEGORY)
category.ownerId = firstSharedCategory.userId // 권한 위임
}

category.minusUserCount() // 포킷 인원수 감소
categoryPort.persist(category)
}

override fun getAllCategoryImages(): List<CategoryImage> =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,8 @@ class UserService(
categoryName = UNCATEGORIZED.displayName,
categoryImage = image,
openType = OpenType.PRIVATE,
keyword = InterestType.DEFAULT
keyword = InterestType.DEFAULT,
ownerId = user.id,
)
categoryPort.persist(category)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,5 +17,7 @@ enum class CategoryErrorCode(
ALREADY_ACCEPTED("이미 초대를 수락한 포킷입니다.", "CA_009"),
NEVER_ACCPTED("해당 유저가 포킷에 초대된 이력이 없습니다.", "CA_0010"),
INVALID_OPENTYPE("OpenType은 PUBLIC, PRIVATE중 하나여야 합니다.", "CA_0011"),
EMPTY_USER_IN_CATEGORY("포킷에 방장 제외 아무도 없습니다.", "CA_0012"),
NOT_OWNER("해당 유저는 방장이 아닙니다.", "CA_0013"),

}
5 changes: 5 additions & 0 deletions domain/src/main/kotlin/com/pokit/category/model/Category.kt
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ data class Category(
var userCount: Int = 0,
var isShared: Boolean = false,
var keyword: InterestType,
var ownerId: Long,
) {
fun update(command: CategoryCommand, categoryImage: CategoryImage) {
this.categoryName = command.categoryName
Expand All @@ -32,6 +33,10 @@ data class Category(
this.userCount++
}

fun minusUserCount() {
this.userCount--
}

fun shared() {
this.isShared = true
}
Expand Down

0 comments on commit 60ef5e0

Please sign in to comment.