From 973d69a9c507a8f4a757398363a85e16908fe52b Mon Sep 17 00:00:00 2001 From: leeheefull Date: Sat, 16 Nov 2024 00:09:21 +0900 Subject: [PATCH 1/2] =?UTF-8?q?feat:=20=EA=B7=B8=EB=A3=B9=20=ED=83=9C?= =?UTF-8?q?=EA=B7=B8=20=EA=B8=B0=EB=8A=A5=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sql/group.sql | 23 ++++++++ .../config/database/QueryDslConfig.kt | 16 ++++++ .../domain/group/application/GroupFacade.kt | 46 ++++++++++++--- .../domain/group/application/GroupService.kt | 21 +------ .../group/application/GroupTagService.kt | 56 +++++++++++++++++++ .../alignlab/domain/group/domain/GroupTag.kt | 15 +++++ .../domain/group/domain/GroupTagMap.kt | 18 ++++++ .../group/infrastructure/GroupQRepository.kt | 9 +++ .../infrastructure/GroupQRepositoryImpl.kt | 55 ++++++++++++++++++ .../group/infrastructure/GroupRepository.kt | 2 +- .../infrastructure/GroupTagMapRepository.kt | 11 ++++ .../infrastructure/GroupTagRepository.kt | 12 ++++ .../group/model/request/CreateGroupRequest.kt | 2 + .../model/request/CreateGroupTagRequest.kt | 8 +++ .../group/model/request/GroupTagRequest.kt | 8 +++ .../group/model/request/UpdateGroupRequest.kt | 2 + .../model/response/CreateGroupResponse.kt | 6 +- .../group/model/response/GetGroupResponse.kt | 10 +++- .../group/model/response/GroupTagResponse.kt | 8 +++ .../model/response/UpdateGroupResponse.kt | 6 +- .../domain/group/resource/GroupResource.kt | 7 ++- .../com/hero/alignlab/exception/ErrorCode.kt | 3 + 22 files changed, 308 insertions(+), 36 deletions(-) create mode 100644 src/main/kotlin/com/hero/alignlab/config/database/QueryDslConfig.kt create mode 100644 src/main/kotlin/com/hero/alignlab/domain/group/application/GroupTagService.kt create mode 100644 src/main/kotlin/com/hero/alignlab/domain/group/domain/GroupTag.kt create mode 100644 src/main/kotlin/com/hero/alignlab/domain/group/domain/GroupTagMap.kt create mode 100644 src/main/kotlin/com/hero/alignlab/domain/group/infrastructure/GroupQRepository.kt create mode 100644 src/main/kotlin/com/hero/alignlab/domain/group/infrastructure/GroupQRepositoryImpl.kt create mode 100644 src/main/kotlin/com/hero/alignlab/domain/group/infrastructure/GroupTagMapRepository.kt create mode 100644 src/main/kotlin/com/hero/alignlab/domain/group/infrastructure/GroupTagRepository.kt create mode 100644 src/main/kotlin/com/hero/alignlab/domain/group/model/request/CreateGroupTagRequest.kt create mode 100644 src/main/kotlin/com/hero/alignlab/domain/group/model/request/GroupTagRequest.kt create mode 100644 src/main/kotlin/com/hero/alignlab/domain/group/model/response/GroupTagResponse.kt diff --git a/sql/group.sql b/sql/group.sql index d2f25e6..f8000f7 100644 --- a/sql/group.sql +++ b/sql/group.sql @@ -46,3 +46,26 @@ CREATE TABLE `group_user_score` CREATE UNIQUE INDEX uidx__group_user_id ON group_user_score (group_user_id); CREATE INDEX idx__group_id__group_user_id ON group_user_score (group_id, group_user_id); CREATE INDEX idx__uid ON group_user_score (uid); + +-- 그룹 태그 +CREATE TABLE `group_tag` +( + `id` bigint NOT NULL AUTO_INCREMENT COMMENT 'group tag id', + `name` varchar(30) NOT NULL COMMENT '태그명', + `created_at` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '생성일', + `modified_at` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '수정일', + PRIMARY KEY (`id`) +) ENGINE = InnoDB AUTO_INCREMENT=200000 DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT='그룹 태그'; +CREATE UNIQUE INDEX uidx__group_tag_name ON group_tag (name); + +-- 그룹 태그 매핑 +CREATE TABLE `group_tag_map` +( + `id` bigint NOT NULL AUTO_INCREMENT COMMENT 'group tag map id', + `group_id` bigint NOT NULL COMMENT 'group id', + `tag_id` bigint NOT NULL COMMENT 'group tag id', + `created_at` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '생성일', + `modified_at` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '수정일', + PRIMARY KEY (`id`) +) ENGINE = InnoDB AUTO_INCREMENT=200000 DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT='그룹 태그 매핑'; +CREATE UNIQUE INDEX uidx__group_id__tag_id ON group_tag_map (group_id, tag_id); \ No newline at end of file diff --git a/src/main/kotlin/com/hero/alignlab/config/database/QueryDslConfig.kt b/src/main/kotlin/com/hero/alignlab/config/database/QueryDslConfig.kt new file mode 100644 index 0000000..8f2aa3f --- /dev/null +++ b/src/main/kotlin/com/hero/alignlab/config/database/QueryDslConfig.kt @@ -0,0 +1,16 @@ +package com.hero.alignlab.config.database + +import com.querydsl.jpa.impl.JPAQueryFactory +import jakarta.persistence.EntityManager +import jakarta.persistence.PersistenceContext +import org.springframework.context.annotation.Bean +import org.springframework.context.annotation.Configuration + +@Configuration +class QueryDslConfig { + @PersistenceContext(name = "heroEntityManager") + private lateinit var entityManager: EntityManager + + @Bean + fun jpaQueryFactory(): JPAQueryFactory = JPAQueryFactory(entityManager) +} \ No newline at end of file diff --git a/src/main/kotlin/com/hero/alignlab/domain/group/application/GroupFacade.kt b/src/main/kotlin/com/hero/alignlab/domain/group/application/GroupFacade.kt index 91db601..b373325 100644 --- a/src/main/kotlin/com/hero/alignlab/domain/group/application/GroupFacade.kt +++ b/src/main/kotlin/com/hero/alignlab/domain/group/application/GroupFacade.kt @@ -7,11 +7,15 @@ import com.hero.alignlab.common.model.HeroPageRequest import com.hero.alignlab.config.database.TransactionTemplates import com.hero.alignlab.domain.auth.model.AuthUser import com.hero.alignlab.domain.group.domain.Group +import com.hero.alignlab.domain.group.domain.GroupTag import com.hero.alignlab.domain.group.domain.GroupUser import com.hero.alignlab.domain.group.domain.GroupUserScore import com.hero.alignlab.domain.group.model.CreateGroupContext +import com.hero.alignlab.domain.group.model.UpdateGroupContext import com.hero.alignlab.domain.group.model.request.CheckGroupRegisterRequest import com.hero.alignlab.domain.group.model.request.CreateGroupRequest +import com.hero.alignlab.domain.group.model.request.CreateGroupTagRequest +import com.hero.alignlab.domain.group.model.request.UpdateGroupRequest import com.hero.alignlab.domain.group.model.response.* import com.hero.alignlab.domain.pose.application.PoseSnapshotService import com.hero.alignlab.domain.pose.domain.vo.PoseType.Companion.BAD_POSE @@ -33,6 +37,7 @@ class GroupFacade( private val groupService: GroupService, private val groupUserService: GroupUserService, private val groupUserScoreService: GroupUserScoreService, + private val groupTagService: GroupTagService, private val userInfoService: UserInfoService, private val txTemplates: TransactionTemplates, private val publisher: ApplicationEventPublisher, @@ -54,19 +59,42 @@ class GroupFacade( val group = CreateGroupContext(user, request).create() - val createdGroup = createGroup(user, group) + txTemplates.writer.executes { + val createdGroup = createGroup(user, group) + val createdGroupTags = createGroupTag(createdGroup.id, request.tagNames) - CreateGroupResponse.from(createdGroup) + CreateGroupResponse.from(createdGroup, createdGroupTags) + } } } fun createGroup(user: AuthUser, group: Group): Group { + val createdGroup = groupService.saveSync(group) + + publisher.publishEvent(CreateGroupEvent(createdGroup)) + + return createdGroup + } + + fun createGroupTag(groupId: Long, tagNames: List?): List { + return if (!tagNames.isNullOrEmpty()) { + groupTagService.validateGroupTag(tagNames) + groupTagService.saveSync(CreateGroupTagRequest(groupId, tagNames)) + } else emptyList() + } + + suspend fun updateGroup(user: AuthUser, groupId: Long, request: UpdateGroupRequest): UpdateGroupResponse { + val group = groupService.findByIdAndOwnerUidOrThrow(groupId, user.uid) return txTemplates.writer.executes { - val createdGroup = groupService.saveSync(group) + val updatedGroup = groupService.saveSync(UpdateGroupContext(group, request).update()) - publisher.publishEvent(CreateGroupEvent(createdGroup)) + val updatedGroupTag = if (!request.tagNames.isNullOrEmpty()) { + groupTagService.validateGroupTag(request.tagNames) + groupTagService.deleteSyncGroupId(groupId) + groupTagService.saveSync(CreateGroupTagRequest(groupId, request.tagNames)) + } else emptyList() - createdGroup + UpdateGroupResponse.from(updatedGroup, updatedGroupTag) } } @@ -90,6 +118,7 @@ class GroupFacade( txTemplates.writer.executes { groupUserScoreService.deleteAllByUid(uid) + groupTagService.deleteSyncGroupId(groupId) } } @@ -188,8 +217,9 @@ class GroupFacade( } ) { group, groupUserScore -> val ownerGroupUser = userInfoService.getUserByIdOrThrow(group.ownerUid) + val tags = groupTagService.findByGroupId(groupId) - GetGroupResponse.from(group, ownerGroupUser.nickname).run { + GetGroupResponse.from(group, ownerGroupUser.nickname, tags).run { when (group.ownerUid == user.uid) { true -> this false -> this.copy(joinCode = null) @@ -222,8 +252,8 @@ class GroupFacade( } } - suspend fun searchGroup(user: AuthUser, pageRequest: HeroPageRequest): Page { - val groups = groupService.findAll(pageRequest.toDefault()) + suspend fun searchGroup(user: AuthUser, tagName: String?, pageRequest: HeroPageRequest): Page { + val groups = groupService.findByTagNameAndPage(tagName, pageRequest.toDefault()) val groupUserByUid = groups.content.map { group -> group.id } .run { groupUserService.findByUidAndGroupIdIn(user.uid, this) } diff --git a/src/main/kotlin/com/hero/alignlab/domain/group/application/GroupService.kt b/src/main/kotlin/com/hero/alignlab/domain/group/application/GroupService.kt index f5f1524..da37edb 100644 --- a/src/main/kotlin/com/hero/alignlab/domain/group/application/GroupService.kt +++ b/src/main/kotlin/com/hero/alignlab/domain/group/application/GroupService.kt @@ -1,13 +1,7 @@ package com.hero.alignlab.domain.group.application -import com.hero.alignlab.common.extension.executes -import com.hero.alignlab.config.database.TransactionTemplates -import com.hero.alignlab.domain.auth.model.AuthUser import com.hero.alignlab.domain.group.domain.Group import com.hero.alignlab.domain.group.infrastructure.GroupRepository -import com.hero.alignlab.domain.group.model.UpdateGroupContext -import com.hero.alignlab.domain.group.model.request.UpdateGroupRequest -import com.hero.alignlab.domain.group.model.response.UpdateGroupResponse import com.hero.alignlab.exception.ErrorCode import com.hero.alignlab.exception.NotFoundException import kotlinx.coroutines.Dispatchers @@ -21,18 +15,7 @@ import org.springframework.transaction.annotation.Transactional @Service class GroupService( private val groupRepository: GroupRepository, - private val txTemplates: TransactionTemplates, ) { - suspend fun updateGroup(user: AuthUser, id: Long, request: UpdateGroupRequest): UpdateGroupResponse { - val group = findByIdAndOwnerUidOrThrow(id, user.uid) - - val updatedGroup = txTemplates.writer.executes { - groupRepository.save(UpdateGroupContext(group, request).update()) - } - - return UpdateGroupResponse.from(updatedGroup) - } - suspend fun existsByName(name: String): Boolean { return withContext(Dispatchers.IO) { groupRepository.existsByName(name) @@ -72,9 +55,9 @@ class GroupService( return groupRepository.save(group) } - suspend fun findAll(pageable: Pageable): Page { + suspend fun findByTagNameAndPage(tagName: String?, pageable: Pageable): Page { return withContext(Dispatchers.IO) { - groupRepository.findAll(pageable) + groupRepository.findByTagNameAndPage(tagName, pageable) } } diff --git a/src/main/kotlin/com/hero/alignlab/domain/group/application/GroupTagService.kt b/src/main/kotlin/com/hero/alignlab/domain/group/application/GroupTagService.kt new file mode 100644 index 0000000..06a1da1 --- /dev/null +++ b/src/main/kotlin/com/hero/alignlab/domain/group/application/GroupTagService.kt @@ -0,0 +1,56 @@ +package com.hero.alignlab.domain.group.application + +import com.hero.alignlab.domain.group.domain.GroupTag +import com.hero.alignlab.domain.group.domain.GroupTagMap +import com.hero.alignlab.domain.group.infrastructure.GroupTagMapRepository +import com.hero.alignlab.domain.group.infrastructure.GroupTagRepository +import com.hero.alignlab.domain.group.model.request.CreateGroupTagRequest +import com.hero.alignlab.exception.ErrorCode +import com.hero.alignlab.exception.InvalidRequestException +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.withContext +import org.springframework.stereotype.Service +import org.springframework.transaction.annotation.Transactional + +@Service +class GroupTagService( + private val groupTagRepository: GroupTagRepository, + private val groupTagMapRepository: GroupTagMapRepository, +) { + @Transactional + fun saveSync(request: CreateGroupTagRequest): List { + return request.tagNames.map { tagName -> + findOrCreateTag(tagName).also { tag -> + groupTagMapRepository.save(GroupTagMap(groupId = request.groupId, tagId = tag.id)) + } + } + } + + @Transactional + fun deleteSyncGroupId(groupId: Long) { + groupTagMapRepository.deleteByGroupId(groupId) + } + + suspend fun findByGroupId(groupId: Long): List { + return withContext(Dispatchers.IO) { + val tagIds = groupTagMapRepository.findByGroupId(groupId) + .map { it.tagId } + groupTagRepository.findByIdIn(tagIds) + } + } + + private fun findOrCreateTag(tagName: String): GroupTag { + return groupTagRepository.findByName(tagName) + .firstOrNull() ?: groupTagRepository.save(GroupTag(name = tagName)) + } + + fun validateGroupTag(tagNames: List) { + if (tagNames.size > 3) { + throw InvalidRequestException(ErrorCode.OVER_COUNT_GROUP_TAG_ERROR) + } + + if (tagNames.size != tagNames.distinct().size) { + throw InvalidRequestException(ErrorCode.DUPLICATE_GROUP_TAG_NAME_ERROR) + } + } +} \ No newline at end of file diff --git a/src/main/kotlin/com/hero/alignlab/domain/group/domain/GroupTag.kt b/src/main/kotlin/com/hero/alignlab/domain/group/domain/GroupTag.kt new file mode 100644 index 0000000..85fc777 --- /dev/null +++ b/src/main/kotlin/com/hero/alignlab/domain/group/domain/GroupTag.kt @@ -0,0 +1,15 @@ +package com.hero.alignlab.domain.group.domain + +import com.hero.alignlab.domain.common.domain.BaseEntity +import jakarta.persistence.* + +@Entity +@Table(name = "`group_tag`") +data class GroupTag( + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + val id: Long = -1, + + @Column(name = "name") + var name: String, +) : BaseEntity() \ No newline at end of file diff --git a/src/main/kotlin/com/hero/alignlab/domain/group/domain/GroupTagMap.kt b/src/main/kotlin/com/hero/alignlab/domain/group/domain/GroupTagMap.kt new file mode 100644 index 0000000..55bf409 --- /dev/null +++ b/src/main/kotlin/com/hero/alignlab/domain/group/domain/GroupTagMap.kt @@ -0,0 +1,18 @@ +package com.hero.alignlab.domain.group.domain + +import com.hero.alignlab.domain.common.domain.BaseEntity +import jakarta.persistence.* + +@Entity +@Table(name = "`group_tag_map`") +data class GroupTagMap ( + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + val id: Long = -1, + + @Column(name = "group_id") + val groupId: Long, + + @Column(name = "tag_id") + val tagId: Long +) : BaseEntity() \ No newline at end of file diff --git a/src/main/kotlin/com/hero/alignlab/domain/group/infrastructure/GroupQRepository.kt b/src/main/kotlin/com/hero/alignlab/domain/group/infrastructure/GroupQRepository.kt new file mode 100644 index 0000000..bff8386 --- /dev/null +++ b/src/main/kotlin/com/hero/alignlab/domain/group/infrastructure/GroupQRepository.kt @@ -0,0 +1,9 @@ +package com.hero.alignlab.domain.group.infrastructure + +import com.hero.alignlab.domain.group.domain.Group +import org.springframework.data.domain.Page +import org.springframework.data.domain.Pageable + +interface GroupQRepository { + fun findByTagNameAndPage(tagName: String?, pageable: Pageable): Page +} \ No newline at end of file diff --git a/src/main/kotlin/com/hero/alignlab/domain/group/infrastructure/GroupQRepositoryImpl.kt b/src/main/kotlin/com/hero/alignlab/domain/group/infrastructure/GroupQRepositoryImpl.kt new file mode 100644 index 0000000..883d4fc --- /dev/null +++ b/src/main/kotlin/com/hero/alignlab/domain/group/infrastructure/GroupQRepositoryImpl.kt @@ -0,0 +1,55 @@ +package com.hero.alignlab.domain.group.infrastructure + +import com.hero.alignlab.domain.group.domain.Group +import com.hero.alignlab.domain.group.domain.QGroup.group +import com.hero.alignlab.domain.group.domain.QGroupTag.groupTag +import com.hero.alignlab.domain.group.domain.QGroupTagMap.groupTagMap +import com.querydsl.core.types.OrderSpecifier +import com.querydsl.core.types.dsl.ComparableExpressionBase +import com.querydsl.jpa.impl.JPAQueryFactory +import org.springframework.data.domain.Page +import org.springframework.data.domain.PageImpl +import org.springframework.data.domain.Pageable + +class GroupQRepositoryImpl( + private val queryFactory: JPAQueryFactory, +) : GroupQRepository { + override fun findByTagNameAndPage(tagName: String?, pageable: Pageable): Page { + val groups = queryFactory + .selectDistinct(group) + .from(group) + .leftJoin(groupTagMap).on(group.id.eq(groupTagMap.groupId)) + .leftJoin(groupTag).on(groupTagMap.tagId.eq(groupTag.id)) + .where( + tagName?.takeIf { it.isNotEmpty() }?.let { groupTag.name.contains(it) } + ) + .offset(pageable.offset) + .limit(pageable.pageSize.toLong()) + .orderBy(getGroupOrderSpecifier(pageable)) + .fetch() + + val count = queryFactory + .select(group.countDistinct()) + .from(group) + .leftJoin(groupTagMap).on(group.id.eq(groupTagMap.groupId)) + .leftJoin(groupTag).on(groupTagMap.tagId.eq(groupTag.id)) + .where( + tagName?.takeIf { it.isNotEmpty() }?.let { groupTag.name.contains(it) } + ) + .orderBy(getGroupOrderSpecifier(pageable)) + .fetchOne() ?: 0L + + return PageImpl(groups, pageable, count) + } + + private fun getGroupOrderSpecifier(pageable: Pageable): OrderSpecifier?>? { + val order = pageable.sort.firstOrNull() ?: return null + val orderSpecifier: ComparableExpressionBase> = when (order.property) { + "createdAt" -> group.createdAt + "name" -> group.name + "ownerUid" -> group.ownerUid + else -> group.createdAt + } + return if (order.isDescending) orderSpecifier.desc() else orderSpecifier.asc() + } +} \ No newline at end of file diff --git a/src/main/kotlin/com/hero/alignlab/domain/group/infrastructure/GroupRepository.kt b/src/main/kotlin/com/hero/alignlab/domain/group/infrastructure/GroupRepository.kt index 6463acf..77cf701 100644 --- a/src/main/kotlin/com/hero/alignlab/domain/group/infrastructure/GroupRepository.kt +++ b/src/main/kotlin/com/hero/alignlab/domain/group/infrastructure/GroupRepository.kt @@ -8,7 +8,7 @@ import java.time.LocalDateTime @Repository @Transactional(readOnly = true) -interface GroupRepository : JpaRepository { +interface GroupRepository : JpaRepository, GroupQRepository { fun existsByName(name: String): Boolean fun findByIdAndOwnerUid(id: Long, ownerUid: Long): Group? diff --git a/src/main/kotlin/com/hero/alignlab/domain/group/infrastructure/GroupTagMapRepository.kt b/src/main/kotlin/com/hero/alignlab/domain/group/infrastructure/GroupTagMapRepository.kt new file mode 100644 index 0000000..12fdf91 --- /dev/null +++ b/src/main/kotlin/com/hero/alignlab/domain/group/infrastructure/GroupTagMapRepository.kt @@ -0,0 +1,11 @@ +package com.hero.alignlab.domain.group.infrastructure + +import com.hero.alignlab.domain.group.domain.GroupTagMap +import org.springframework.data.jpa.repository.JpaRepository +import org.springframework.stereotype.Repository + +@Repository +interface GroupTagMapRepository : JpaRepository { + fun findByGroupId(groupId: Long): MutableList + fun deleteByGroupId(groupId: Long) +} \ No newline at end of file diff --git a/src/main/kotlin/com/hero/alignlab/domain/group/infrastructure/GroupTagRepository.kt b/src/main/kotlin/com/hero/alignlab/domain/group/infrastructure/GroupTagRepository.kt new file mode 100644 index 0000000..216a344 --- /dev/null +++ b/src/main/kotlin/com/hero/alignlab/domain/group/infrastructure/GroupTagRepository.kt @@ -0,0 +1,12 @@ +package com.hero.alignlab.domain.group.infrastructure + +import com.hero.alignlab.domain.group.domain.GroupTag +import org.springframework.data.jpa.repository.JpaRepository +import org.springframework.stereotype.Repository + +@Repository +interface GroupTagRepository : JpaRepository { + fun findByName(name: String): List + + fun findByIdIn(ids: List): List +} \ No newline at end of file diff --git a/src/main/kotlin/com/hero/alignlab/domain/group/model/request/CreateGroupRequest.kt b/src/main/kotlin/com/hero/alignlab/domain/group/model/request/CreateGroupRequest.kt index 8b21684..9ba24d8 100644 --- a/src/main/kotlin/com/hero/alignlab/domain/group/model/request/CreateGroupRequest.kt +++ b/src/main/kotlin/com/hero/alignlab/domain/group/model/request/CreateGroupRequest.kt @@ -11,4 +11,6 @@ data class CreateGroupRequest( val joinCode: String?, /** 정원, 기본값 30 */ val userCapacity: Int?, + /** 태그 리스트, 최대 3개 */ + val tagNames: List?, ) diff --git a/src/main/kotlin/com/hero/alignlab/domain/group/model/request/CreateGroupTagRequest.kt b/src/main/kotlin/com/hero/alignlab/domain/group/model/request/CreateGroupTagRequest.kt new file mode 100644 index 0000000..04ef3f0 --- /dev/null +++ b/src/main/kotlin/com/hero/alignlab/domain/group/model/request/CreateGroupTagRequest.kt @@ -0,0 +1,8 @@ +package com.hero.alignlab.domain.group.model.request + +data class CreateGroupTagRequest( + /** 그룹명, 중복 불가능 */ + val groupId: Long, + /** 태그 리스트, 최대 3개 */ + val tagNames: List, +) \ No newline at end of file diff --git a/src/main/kotlin/com/hero/alignlab/domain/group/model/request/GroupTagRequest.kt b/src/main/kotlin/com/hero/alignlab/domain/group/model/request/GroupTagRequest.kt new file mode 100644 index 0000000..c9480dd --- /dev/null +++ b/src/main/kotlin/com/hero/alignlab/domain/group/model/request/GroupTagRequest.kt @@ -0,0 +1,8 @@ +package com.hero.alignlab.domain.group.model.request + +data class GroupTagRequest( + /** 태그 ID */ + val tagId: Long, + /** 태그명 */ + val tagName: String, +) diff --git a/src/main/kotlin/com/hero/alignlab/domain/group/model/request/UpdateGroupRequest.kt b/src/main/kotlin/com/hero/alignlab/domain/group/model/request/UpdateGroupRequest.kt index 29ab4b9..20e4ab9 100644 --- a/src/main/kotlin/com/hero/alignlab/domain/group/model/request/UpdateGroupRequest.kt +++ b/src/main/kotlin/com/hero/alignlab/domain/group/model/request/UpdateGroupRequest.kt @@ -11,4 +11,6 @@ data class UpdateGroupRequest( val joinCode: String?, /** 정원, 기본값 30 */ val userCapacity: Int?, + /** 수정할 태그 리스트 */ + val tagNames: List?, ) diff --git a/src/main/kotlin/com/hero/alignlab/domain/group/model/response/CreateGroupResponse.kt b/src/main/kotlin/com/hero/alignlab/domain/group/model/response/CreateGroupResponse.kt index 492b423..0392df3 100644 --- a/src/main/kotlin/com/hero/alignlab/domain/group/model/response/CreateGroupResponse.kt +++ b/src/main/kotlin/com/hero/alignlab/domain/group/model/response/CreateGroupResponse.kt @@ -1,6 +1,7 @@ package com.hero.alignlab.domain.group.model.response import com.hero.alignlab.domain.group.domain.Group +import com.hero.alignlab.domain.group.domain.GroupTag data class CreateGroupResponse( /** group id */ @@ -9,13 +10,16 @@ data class CreateGroupResponse( val name: String, /** 그룹 설명 */ val description: String?, + /** 그룹 태그 리스트 */ + val tags: List?, ) { companion object { - fun from(group: Group): CreateGroupResponse { + fun from(group: Group, tags: List): CreateGroupResponse { return CreateGroupResponse( id = group.id, name = group.name, description = group.description, + tags = tags.map { GroupTagResponse(it.id, it.name) }, ) } } diff --git a/src/main/kotlin/com/hero/alignlab/domain/group/model/response/GetGroupResponse.kt b/src/main/kotlin/com/hero/alignlab/domain/group/model/response/GetGroupResponse.kt index fb9540a..48931d4 100644 --- a/src/main/kotlin/com/hero/alignlab/domain/group/model/response/GetGroupResponse.kt +++ b/src/main/kotlin/com/hero/alignlab/domain/group/model/response/GetGroupResponse.kt @@ -1,6 +1,7 @@ package com.hero.alignlab.domain.group.model.response import com.hero.alignlab.domain.group.domain.Group +import com.hero.alignlab.domain.group.domain.GroupTag data class GetGroupResponse( val id: Long, @@ -16,10 +17,12 @@ data class GetGroupResponse( val userCount: Int, /** 그룹 정원 */ val userCapacity: Int, - val ranks: List? = null + val ranks: List? = null, + /** 그룹 태그 리스트 */ + val tags: List?, ) { companion object { - fun from(group: Group, ownerName: String): GetGroupResponse { + fun from(group: Group, ownerName: String, tags: List): GetGroupResponse { return GetGroupResponse( id = group.id, name = group.name, @@ -29,7 +32,8 @@ data class GetGroupResponse( isHidden = group.isHidden, joinCode = group.joinCode, userCount = group.userCount, - userCapacity = group.userCapacity + userCapacity = group.userCapacity, + tags = tags.map { GroupTagResponse(it.id, it.name) }, ) } } diff --git a/src/main/kotlin/com/hero/alignlab/domain/group/model/response/GroupTagResponse.kt b/src/main/kotlin/com/hero/alignlab/domain/group/model/response/GroupTagResponse.kt new file mode 100644 index 0000000..e1e2c2f --- /dev/null +++ b/src/main/kotlin/com/hero/alignlab/domain/group/model/response/GroupTagResponse.kt @@ -0,0 +1,8 @@ +package com.hero.alignlab.domain.group.model.response + +data class GroupTagResponse( + /** 태그 ID */ + val tagId: Long, + /** 태그명 */ + val tagName: String, +) diff --git a/src/main/kotlin/com/hero/alignlab/domain/group/model/response/UpdateGroupResponse.kt b/src/main/kotlin/com/hero/alignlab/domain/group/model/response/UpdateGroupResponse.kt index 6e03dfe..e0c4cfa 100644 --- a/src/main/kotlin/com/hero/alignlab/domain/group/model/response/UpdateGroupResponse.kt +++ b/src/main/kotlin/com/hero/alignlab/domain/group/model/response/UpdateGroupResponse.kt @@ -1,6 +1,7 @@ package com.hero.alignlab.domain.group.model.response import com.hero.alignlab.domain.group.domain.Group +import com.hero.alignlab.domain.group.domain.GroupTag data class UpdateGroupResponse( /** group id */ @@ -9,13 +10,16 @@ data class UpdateGroupResponse( val name: String, /** 그룹 설명 */ val description: String?, + /** 그룹 태그 리스트 */ + val tags: List?, ) { companion object { - fun from(group: Group): UpdateGroupResponse { + fun from(group: Group, tags: List): UpdateGroupResponse { return UpdateGroupResponse( id = group.id, name = group.name, description = group.description, + tags = tags.map { GroupTagResponse(it.id, it.name) }, ) } } diff --git a/src/main/kotlin/com/hero/alignlab/domain/group/resource/GroupResource.kt b/src/main/kotlin/com/hero/alignlab/domain/group/resource/GroupResource.kt index d78eec1..1c9c1ee 100644 --- a/src/main/kotlin/com/hero/alignlab/domain/group/resource/GroupResource.kt +++ b/src/main/kotlin/com/hero/alignlab/domain/group/resource/GroupResource.kt @@ -51,9 +51,10 @@ class GroupResource( @GetMapping("/api/v1/groups") suspend fun searchGroups( user: AuthUser, + @RequestParam(required = false) tagName: String?, @ParameterObject pageRequest: HeroPageRequest, ): PageResponse { - return groupFacade.searchGroup(user, pageRequest).wrapPage() + return groupFacade.searchGroup(user, tagName, pageRequest).wrapPage() } @Operation(summary = "그룹 생성") @@ -72,9 +73,9 @@ class GroupResource( @PathVariable id: Long, @RequestBody request: UpdateGroupRequest ): ResponseEntity> { - return groupService.updateGroup( + return groupFacade.updateGroup( user = user, - id = id, + groupId = id, request = request ).wrapOk() } diff --git a/src/main/kotlin/com/hero/alignlab/exception/ErrorCode.kt b/src/main/kotlin/com/hero/alignlab/exception/ErrorCode.kt index 212bf4a..1ebe7ac 100644 --- a/src/main/kotlin/com/hero/alignlab/exception/ErrorCode.kt +++ b/src/main/kotlin/com/hero/alignlab/exception/ErrorCode.kt @@ -44,7 +44,10 @@ enum class ErrorCode(val status: HttpStatus, val description: String) { INVALID_JOIN_CODE_ERROR(HttpStatus.BAD_REQUEST, "비밀번호의 조건이 부합하지 않습니다."), NOT_CONTAINS_GROUP_USER_ERROR(HttpStatus.BAD_REQUEST, "그룹원이 아닙니다."), NOT_FOUND_GROUP_ID_ERROR(HttpStatus.NOT_FOUND, "group Id를 찾을 수 없습니다."), + NOT_FOUND_GROUP_TAG_ERROR(HttpStatus.NOT_FOUND, "그룹 태그 정보를 찾을 수 없습니다."), OVER_RANGE_GROUP_NAME_ERROR(HttpStatus.BAD_REQUEST, "그룹명은 16글자까지만 입력할 수 있습니다."), + OVER_COUNT_GROUP_TAG_ERROR(HttpStatus.BAD_REQUEST, "그룹 태그는 최대 3개까지 입력 가능합니다."), + DUPLICATE_GROUP_TAG_NAME_ERROR(HttpStatus.BAD_REQUEST, "중복된 태그명이 있습니다."), /** Group User Error Code */ DUPLICATE_GROUP_JOIN_ERROR(HttpStatus.BAD_REQUEST, "한개의 그룹만 참여 가능합니다."), From 9c287eef17ec3e3ddf66d884eff16580ea5847f5 Mon Sep 17 00:00:00 2001 From: leeheefull Date: Sun, 17 Nov 2024 23:21:17 +0900 Subject: [PATCH 2/2] =?UTF-8?q?refactor:=20=EA=B7=B8=EB=A3=B9=20=ED=83=9C?= =?UTF-8?q?=EA=B7=B8=20=EA=B8=B0=EB=8A=A5=20=EC=B6=94=EA=B0=80=20=EC=BD=94?= =?UTF-8?q?=EB=93=9C=20=EB=A6=AC=EB=B7=B0=20=EB=B0=98=EC=98=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../common/extension/QuerydslExtension.kt | 2 +- .../domain/discussion/domain/Discussion.kt | 2 +- .../discussion/domain/DiscussionComment.kt | 2 +- .../domain/group/application/GroupFacade.kt | 12 +++---- .../group/application/GroupTagService.kt | 36 +++++++++++-------- .../alignlab/domain/group/domain/Group.kt | 2 +- .../alignlab/domain/group/domain/GroupTag.kt | 2 +- .../domain/group/domain/GroupTagMap.kt | 2 +- .../alignlab/domain/group/domain/GroupUser.kt | 2 +- .../domain/group/domain/GroupUserScore.kt | 2 +- .../infrastructure/GroupQRepositoryImpl.kt | 9 ++--- .../infrastructure/GroupTagMapRepository.kt | 7 ++-- .../infrastructure/GroupTagQRepository.kt | 9 +++++ .../infrastructure/GroupTagQRepositoryImpl.kt | 23 ++++++++++++ .../infrastructure/GroupTagRepository.kt | 8 ++--- .../group/model/response/GetGroupResponse.kt | 4 +-- .../domain/group/resource/GroupResource.kt | 2 -- .../domain/image/domain/ImageMetadata.kt | 4 +-- .../domain/log/domain/SystemActionLog.kt | 2 +- .../notification/domain/PoseNotification.kt | 4 +-- .../alignlab/domain/pose/domain/PoseCount.kt | 2 +- .../pose/domain/PoseKeyPointSnapshot.kt | 2 +- .../alignlab/domain/pose/domain/PoseLayout.kt | 2 +- .../domain/pose/domain/PoseLayoutPoint.kt | 2 +- .../domain/pose/domain/PoseSnapshot.kt | 2 +- .../domain/user/domain/CredentialUserInfo.kt | 2 +- .../domain/user/domain/OAuthUserInfo.kt | 2 +- .../alignlab/domain/user/domain/UserInfo.kt | 2 +- 28 files changed, 92 insertions(+), 60 deletions(-) create mode 100644 src/main/kotlin/com/hero/alignlab/domain/group/infrastructure/GroupTagQRepository.kt create mode 100644 src/main/kotlin/com/hero/alignlab/domain/group/infrastructure/GroupTagQRepositoryImpl.kt diff --git a/src/main/kotlin/com/hero/alignlab/common/extension/QuerydslExtension.kt b/src/main/kotlin/com/hero/alignlab/common/extension/QuerydslExtension.kt index a16a55f..c77df6a 100644 --- a/src/main/kotlin/com/hero/alignlab/common/extension/QuerydslExtension.kt +++ b/src/main/kotlin/com/hero/alignlab/common/extension/QuerydslExtension.kt @@ -44,7 +44,7 @@ fun NumberPath.isEquals(parameter: Long?): BooleanExpression? { } fun StringPath.isContains(parameter: String?): BooleanExpression? { - return parameter?.let { param -> this.contains(param) } + return parameter?.takeIf { param -> param.isNotEmpty() }?.let { param -> this.contains(param) } } fun NumberPath.isIn(parameters: Set?): BooleanExpression? { diff --git a/src/main/kotlin/com/hero/alignlab/domain/discussion/domain/Discussion.kt b/src/main/kotlin/com/hero/alignlab/domain/discussion/domain/Discussion.kt index a9fe16a..3b359f8 100644 --- a/src/main/kotlin/com/hero/alignlab/domain/discussion/domain/Discussion.kt +++ b/src/main/kotlin/com/hero/alignlab/domain/discussion/domain/Discussion.kt @@ -9,7 +9,7 @@ import jakarta.persistence.* class Discussion( @Id @GeneratedValue(strategy = GenerationType.IDENTITY) - val id: Long = -1L, + val id: Long = 0L, @Column(name = "uid") val uid: Long, diff --git a/src/main/kotlin/com/hero/alignlab/domain/discussion/domain/DiscussionComment.kt b/src/main/kotlin/com/hero/alignlab/domain/discussion/domain/DiscussionComment.kt index b2d7c92..a613b8d 100644 --- a/src/main/kotlin/com/hero/alignlab/domain/discussion/domain/DiscussionComment.kt +++ b/src/main/kotlin/com/hero/alignlab/domain/discussion/domain/DiscussionComment.kt @@ -8,7 +8,7 @@ import jakarta.persistence.* class DiscussionComment( @Id @GeneratedValue(strategy = GenerationType.IDENTITY) - val id: Long = -1L, + val id: Long = 0L, @Column(name = "uid") val uid: Long, diff --git a/src/main/kotlin/com/hero/alignlab/domain/group/application/GroupFacade.kt b/src/main/kotlin/com/hero/alignlab/domain/group/application/GroupFacade.kt index b373325..166a8f7 100644 --- a/src/main/kotlin/com/hero/alignlab/domain/group/application/GroupFacade.kt +++ b/src/main/kotlin/com/hero/alignlab/domain/group/application/GroupFacade.kt @@ -90,7 +90,7 @@ class GroupFacade( val updatedGroupTag = if (!request.tagNames.isNullOrEmpty()) { groupTagService.validateGroupTag(request.tagNames) - groupTagService.deleteSyncGroupId(groupId) + groupTagService.deleteGroupTagMapSyncByGroupId(groupId) groupTagService.saveSync(CreateGroupTagRequest(groupId, request.tagNames)) } else emptyList() @@ -118,7 +118,7 @@ class GroupFacade( txTemplates.writer.executes { groupUserScoreService.deleteAllByUid(uid) - groupTagService.deleteSyncGroupId(groupId) + groupTagService.deleteGroupTagMapSyncByGroupId(groupId) } } @@ -214,12 +214,12 @@ class GroupFacade( .filterNot { groupUserScore -> groupUserScore.score == null } .sortedBy { groupUserScore -> groupUserScore.score } .take(5) - } - ) { group, groupUserScore -> + }, + { groupTagService.findByGroupId(groupId) }, + ) { group, groupUserScore, tags -> val ownerGroupUser = userInfoService.getUserByIdOrThrow(group.ownerUid) - val tags = groupTagService.findByGroupId(groupId) - GetGroupResponse.from(group, ownerGroupUser.nickname, tags).run { + GetGroupResponse.of(group, tags, ownerGroupUser.nickname).run { when (group.ownerUid == user.uid) { true -> this false -> this.copy(joinCode = null) diff --git a/src/main/kotlin/com/hero/alignlab/domain/group/application/GroupTagService.kt b/src/main/kotlin/com/hero/alignlab/domain/group/application/GroupTagService.kt index 06a1da1..622269e 100644 --- a/src/main/kotlin/com/hero/alignlab/domain/group/application/GroupTagService.kt +++ b/src/main/kotlin/com/hero/alignlab/domain/group/application/GroupTagService.kt @@ -19,31 +19,37 @@ class GroupTagService( ) { @Transactional fun saveSync(request: CreateGroupTagRequest): List { - return request.tagNames.map { tagName -> - findOrCreateTag(tagName).also { tag -> - groupTagMapRepository.save(GroupTagMap(groupId = request.groupId, tagId = tag.id)) - } - } + val existsTags = groupTagRepository.findAllByNameIn(request.tagNames) + val existsTagNames = existsTags.map { tag -> tag.name } + + val needToCreateTags = request.tagNames + .filterNot { tagName -> existsTagNames.contains(tagName) } + .map { tagName -> GroupTag(name = tagName) } + + val createdTags = groupTagRepository.saveAll(needToCreateTags) + + (createdTags + existsTags) + .map { tag -> GroupTagMap(groupId = request.groupId, tagId = tag.id) } + .run { groupTagMapRepository.saveAll(this) } + + return (createdTags + existsTags) } @Transactional - fun deleteSyncGroupId(groupId: Long) { - groupTagMapRepository.deleteByGroupId(groupId) + fun deleteGroupTagMapSyncByGroupId(groupId: Long) { + /** + * 왜, QueryDSL로 삭제를 했는지 + * https://docs.jboss.org/hibernate/orm/4.2/javadocs/org/hibernate/event/internal/AbstractFlushingEventListener.html + */ + groupTagRepository.deleteGroupTagMapByGroupId(groupId) } suspend fun findByGroupId(groupId: Long): List { return withContext(Dispatchers.IO) { - val tagIds = groupTagMapRepository.findByGroupId(groupId) - .map { it.tagId } - groupTagRepository.findByIdIn(tagIds) + groupTagRepository.findByGroupId(groupId) } } - private fun findOrCreateTag(tagName: String): GroupTag { - return groupTagRepository.findByName(tagName) - .firstOrNull() ?: groupTagRepository.save(GroupTag(name = tagName)) - } - fun validateGroupTag(tagNames: List) { if (tagNames.size > 3) { throw InvalidRequestException(ErrorCode.OVER_COUNT_GROUP_TAG_ERROR) diff --git a/src/main/kotlin/com/hero/alignlab/domain/group/domain/Group.kt b/src/main/kotlin/com/hero/alignlab/domain/group/domain/Group.kt index c91e428..fa34c6d 100644 --- a/src/main/kotlin/com/hero/alignlab/domain/group/domain/Group.kt +++ b/src/main/kotlin/com/hero/alignlab/domain/group/domain/Group.kt @@ -8,7 +8,7 @@ import jakarta.persistence.* data class Group( @Id @GeneratedValue(strategy = GenerationType.IDENTITY) - val id: Long = -1, + val id: Long = 0L, @Column(name = "name") var name: String, diff --git a/src/main/kotlin/com/hero/alignlab/domain/group/domain/GroupTag.kt b/src/main/kotlin/com/hero/alignlab/domain/group/domain/GroupTag.kt index 85fc777..90e9d23 100644 --- a/src/main/kotlin/com/hero/alignlab/domain/group/domain/GroupTag.kt +++ b/src/main/kotlin/com/hero/alignlab/domain/group/domain/GroupTag.kt @@ -8,7 +8,7 @@ import jakarta.persistence.* data class GroupTag( @Id @GeneratedValue(strategy = GenerationType.IDENTITY) - val id: Long = -1, + val id: Long = 0L, @Column(name = "name") var name: String, diff --git a/src/main/kotlin/com/hero/alignlab/domain/group/domain/GroupTagMap.kt b/src/main/kotlin/com/hero/alignlab/domain/group/domain/GroupTagMap.kt index 55bf409..33ef049 100644 --- a/src/main/kotlin/com/hero/alignlab/domain/group/domain/GroupTagMap.kt +++ b/src/main/kotlin/com/hero/alignlab/domain/group/domain/GroupTagMap.kt @@ -8,7 +8,7 @@ import jakarta.persistence.* data class GroupTagMap ( @Id @GeneratedValue(strategy = GenerationType.IDENTITY) - val id: Long = -1, + val id: Long = 0L, @Column(name = "group_id") val groupId: Long, diff --git a/src/main/kotlin/com/hero/alignlab/domain/group/domain/GroupUser.kt b/src/main/kotlin/com/hero/alignlab/domain/group/domain/GroupUser.kt index 0203f95..ac64adb 100644 --- a/src/main/kotlin/com/hero/alignlab/domain/group/domain/GroupUser.kt +++ b/src/main/kotlin/com/hero/alignlab/domain/group/domain/GroupUser.kt @@ -8,7 +8,7 @@ import jakarta.persistence.* data class GroupUser( @Id @GeneratedValue(strategy = GenerationType.IDENTITY) - val id: Long = -1, + val id: Long = 0L, @Column(name = "group_id") val groupId: Long, diff --git a/src/main/kotlin/com/hero/alignlab/domain/group/domain/GroupUserScore.kt b/src/main/kotlin/com/hero/alignlab/domain/group/domain/GroupUserScore.kt index 074d82d..04dc288 100644 --- a/src/main/kotlin/com/hero/alignlab/domain/group/domain/GroupUserScore.kt +++ b/src/main/kotlin/com/hero/alignlab/domain/group/domain/GroupUserScore.kt @@ -8,7 +8,7 @@ import jakarta.persistence.* class GroupUserScore( @Id @GeneratedValue(strategy = GenerationType.IDENTITY) - val id: Long = -1, + val id: Long = 0L, @Column(name = "group_id") val groupId: Long, diff --git a/src/main/kotlin/com/hero/alignlab/domain/group/infrastructure/GroupQRepositoryImpl.kt b/src/main/kotlin/com/hero/alignlab/domain/group/infrastructure/GroupQRepositoryImpl.kt index 883d4fc..16f0449 100644 --- a/src/main/kotlin/com/hero/alignlab/domain/group/infrastructure/GroupQRepositoryImpl.kt +++ b/src/main/kotlin/com/hero/alignlab/domain/group/infrastructure/GroupQRepositoryImpl.kt @@ -1,5 +1,6 @@ package com.hero.alignlab.domain.group.infrastructure +import com.hero.alignlab.common.extension.isContains import com.hero.alignlab.domain.group.domain.Group import com.hero.alignlab.domain.group.domain.QGroup.group import com.hero.alignlab.domain.group.domain.QGroupTag.groupTag @@ -20,9 +21,7 @@ class GroupQRepositoryImpl( .from(group) .leftJoin(groupTagMap).on(group.id.eq(groupTagMap.groupId)) .leftJoin(groupTag).on(groupTagMap.tagId.eq(groupTag.id)) - .where( - tagName?.takeIf { it.isNotEmpty() }?.let { groupTag.name.contains(it) } - ) + .where(groupTag.name.isContains(tagName)) .offset(pageable.offset) .limit(pageable.pageSize.toLong()) .orderBy(getGroupOrderSpecifier(pageable)) @@ -33,9 +32,7 @@ class GroupQRepositoryImpl( .from(group) .leftJoin(groupTagMap).on(group.id.eq(groupTagMap.groupId)) .leftJoin(groupTag).on(groupTagMap.tagId.eq(groupTag.id)) - .where( - tagName?.takeIf { it.isNotEmpty() }?.let { groupTag.name.contains(it) } - ) + .where(groupTag.name.isContains(tagName)) .orderBy(getGroupOrderSpecifier(pageable)) .fetchOne() ?: 0L diff --git a/src/main/kotlin/com/hero/alignlab/domain/group/infrastructure/GroupTagMapRepository.kt b/src/main/kotlin/com/hero/alignlab/domain/group/infrastructure/GroupTagMapRepository.kt index 12fdf91..8de0426 100644 --- a/src/main/kotlin/com/hero/alignlab/domain/group/infrastructure/GroupTagMapRepository.kt +++ b/src/main/kotlin/com/hero/alignlab/domain/group/infrastructure/GroupTagMapRepository.kt @@ -3,9 +3,8 @@ package com.hero.alignlab.domain.group.infrastructure import com.hero.alignlab.domain.group.domain.GroupTagMap import org.springframework.data.jpa.repository.JpaRepository import org.springframework.stereotype.Repository +import org.springframework.transaction.annotation.Transactional +@Transactional(readOnly = true) @Repository -interface GroupTagMapRepository : JpaRepository { - fun findByGroupId(groupId: Long): MutableList - fun deleteByGroupId(groupId: Long) -} \ No newline at end of file +interface GroupTagMapRepository : JpaRepository \ No newline at end of file diff --git a/src/main/kotlin/com/hero/alignlab/domain/group/infrastructure/GroupTagQRepository.kt b/src/main/kotlin/com/hero/alignlab/domain/group/infrastructure/GroupTagQRepository.kt new file mode 100644 index 0000000..6cf05f8 --- /dev/null +++ b/src/main/kotlin/com/hero/alignlab/domain/group/infrastructure/GroupTagQRepository.kt @@ -0,0 +1,9 @@ +package com.hero.alignlab.domain.group.infrastructure + +import com.hero.alignlab.domain.group.domain.GroupTag + +interface GroupTagQRepository { + fun findByGroupId(groupId: Long): List + + fun deleteGroupTagMapByGroupId(groupId: Long) +} \ No newline at end of file diff --git a/src/main/kotlin/com/hero/alignlab/domain/group/infrastructure/GroupTagQRepositoryImpl.kt b/src/main/kotlin/com/hero/alignlab/domain/group/infrastructure/GroupTagQRepositoryImpl.kt new file mode 100644 index 0000000..529eba4 --- /dev/null +++ b/src/main/kotlin/com/hero/alignlab/domain/group/infrastructure/GroupTagQRepositoryImpl.kt @@ -0,0 +1,23 @@ +package com.hero.alignlab.domain.group.infrastructure + +import com.hero.alignlab.domain.group.domain.GroupTag +import com.hero.alignlab.domain.group.domain.QGroupTag.groupTag +import com.hero.alignlab.domain.group.domain.QGroupTagMap.groupTagMap +import com.querydsl.jpa.impl.JPAQueryFactory + +class GroupTagQRepositoryImpl( + private val queryFactory: JPAQueryFactory, +) : GroupTagQRepository { + override fun findByGroupId(groupId: Long): List { + return queryFactory.selectFrom(groupTag) + .join(groupTagMap).on(groupTag.id.eq(groupTagMap.tagId)) + .where(groupTagMap.groupId.eq(groupId)) + .fetch() + } + + override fun deleteGroupTagMapByGroupId(groupId: Long) { + queryFactory.delete(groupTagMap) + .where(groupTagMap.groupId.eq(groupId)) + .execute() + } +} \ No newline at end of file diff --git a/src/main/kotlin/com/hero/alignlab/domain/group/infrastructure/GroupTagRepository.kt b/src/main/kotlin/com/hero/alignlab/domain/group/infrastructure/GroupTagRepository.kt index 216a344..bd72a84 100644 --- a/src/main/kotlin/com/hero/alignlab/domain/group/infrastructure/GroupTagRepository.kt +++ b/src/main/kotlin/com/hero/alignlab/domain/group/infrastructure/GroupTagRepository.kt @@ -3,10 +3,10 @@ package com.hero.alignlab.domain.group.infrastructure import com.hero.alignlab.domain.group.domain.GroupTag import org.springframework.data.jpa.repository.JpaRepository import org.springframework.stereotype.Repository +import org.springframework.transaction.annotation.Transactional +@Transactional(readOnly = true) @Repository -interface GroupTagRepository : JpaRepository { - fun findByName(name: String): List - - fun findByIdIn(ids: List): List +interface GroupTagRepository : JpaRepository, GroupTagQRepository { + fun findAllByNameIn(names: List): Set } \ No newline at end of file diff --git a/src/main/kotlin/com/hero/alignlab/domain/group/model/response/GetGroupResponse.kt b/src/main/kotlin/com/hero/alignlab/domain/group/model/response/GetGroupResponse.kt index 48931d4..b3d44bc 100644 --- a/src/main/kotlin/com/hero/alignlab/domain/group/model/response/GetGroupResponse.kt +++ b/src/main/kotlin/com/hero/alignlab/domain/group/model/response/GetGroupResponse.kt @@ -22,7 +22,7 @@ data class GetGroupResponse( val tags: List?, ) { companion object { - fun from(group: Group, ownerName: String, tags: List): GetGroupResponse { + fun of(group: Group, tags: List?, ownerName: String): GetGroupResponse { return GetGroupResponse( id = group.id, name = group.name, @@ -33,7 +33,7 @@ data class GetGroupResponse( joinCode = group.joinCode, userCount = group.userCount, userCapacity = group.userCapacity, - tags = tags.map { GroupTagResponse(it.id, it.name) }, + tags = tags?.map { GroupTagResponse(it.id, it.name) }, ) } } diff --git a/src/main/kotlin/com/hero/alignlab/domain/group/resource/GroupResource.kt b/src/main/kotlin/com/hero/alignlab/domain/group/resource/GroupResource.kt index 1c9c1ee..3411d28 100644 --- a/src/main/kotlin/com/hero/alignlab/domain/group/resource/GroupResource.kt +++ b/src/main/kotlin/com/hero/alignlab/domain/group/resource/GroupResource.kt @@ -9,7 +9,6 @@ import com.hero.alignlab.common.model.PageResponse import com.hero.alignlab.common.model.Response import com.hero.alignlab.domain.auth.model.AuthUser import com.hero.alignlab.domain.group.application.GroupFacade -import com.hero.alignlab.domain.group.application.GroupService import com.hero.alignlab.domain.group.model.request.CheckGroupRegisterRequest import com.hero.alignlab.domain.group.model.request.CreateGroupRequest import com.hero.alignlab.domain.group.model.request.UpdateGroupRequest @@ -25,7 +24,6 @@ import org.springframework.web.bind.annotation.* @RestController @RequestMapping(produces = [MediaType.APPLICATION_JSON_VALUE]) class GroupResource( - private val groupService: GroupService, private val groupFacade: GroupFacade, ) { /** diff --git a/src/main/kotlin/com/hero/alignlab/domain/image/domain/ImageMetadata.kt b/src/main/kotlin/com/hero/alignlab/domain/image/domain/ImageMetadata.kt index 339f03a..b8515ed 100644 --- a/src/main/kotlin/com/hero/alignlab/domain/image/domain/ImageMetadata.kt +++ b/src/main/kotlin/com/hero/alignlab/domain/image/domain/ImageMetadata.kt @@ -9,10 +9,10 @@ import jakarta.persistence.* class ImageMetadata( @Id @GeneratedValue(strategy = GenerationType.IDENTITY) - val id: Long = -1, + val id: Long = 0L, @Column(name = "uid") - val uid: Long = -1, + val uid: Long = 0L, @Column(name = "filename") val filename: String, diff --git a/src/main/kotlin/com/hero/alignlab/domain/log/domain/SystemActionLog.kt b/src/main/kotlin/com/hero/alignlab/domain/log/domain/SystemActionLog.kt index 5443676..e185e3e 100644 --- a/src/main/kotlin/com/hero/alignlab/domain/log/domain/SystemActionLog.kt +++ b/src/main/kotlin/com/hero/alignlab/domain/log/domain/SystemActionLog.kt @@ -8,7 +8,7 @@ import jakarta.persistence.* class SystemActionLog( @Id @GeneratedValue(strategy = GenerationType.IDENTITY) - val id: Long = -1L, + val id: Long = 0L, @Column(name = "uid") val uid: Long? = null, diff --git a/src/main/kotlin/com/hero/alignlab/domain/notification/domain/PoseNotification.kt b/src/main/kotlin/com/hero/alignlab/domain/notification/domain/PoseNotification.kt index 7b2727f..fd6bd46 100644 --- a/src/main/kotlin/com/hero/alignlab/domain/notification/domain/PoseNotification.kt +++ b/src/main/kotlin/com/hero/alignlab/domain/notification/domain/PoseNotification.kt @@ -10,10 +10,10 @@ import jakarta.persistence.* class PoseNotification( @Id @GeneratedValue(strategy = GenerationType.IDENTITY) - val id: Long = -1, + val id: Long = 0L, @Column(name = "uid") - val uid: Long = -1, + val uid: Long = 0L, @Column(name = "is_active") var isActive: Boolean = true, diff --git a/src/main/kotlin/com/hero/alignlab/domain/pose/domain/PoseCount.kt b/src/main/kotlin/com/hero/alignlab/domain/pose/domain/PoseCount.kt index dd6e448..83683f5 100644 --- a/src/main/kotlin/com/hero/alignlab/domain/pose/domain/PoseCount.kt +++ b/src/main/kotlin/com/hero/alignlab/domain/pose/domain/PoseCount.kt @@ -11,7 +11,7 @@ class PoseCount( @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = "id") - val id: Long = -1, + val id: Long = 0L, @Column(name = "uid") val uid: Long, diff --git a/src/main/kotlin/com/hero/alignlab/domain/pose/domain/PoseKeyPointSnapshot.kt b/src/main/kotlin/com/hero/alignlab/domain/pose/domain/PoseKeyPointSnapshot.kt index 9c5a393..720645b 100644 --- a/src/main/kotlin/com/hero/alignlab/domain/pose/domain/PoseKeyPointSnapshot.kt +++ b/src/main/kotlin/com/hero/alignlab/domain/pose/domain/PoseKeyPointSnapshot.kt @@ -10,7 +10,7 @@ class PoseKeyPointSnapshot( @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = "id") - val id: Long = -1L, + val id: Long = 0L, @Column(name = "pose_snapshot_id") val poseSnapshotId: Long, diff --git a/src/main/kotlin/com/hero/alignlab/domain/pose/domain/PoseLayout.kt b/src/main/kotlin/com/hero/alignlab/domain/pose/domain/PoseLayout.kt index 12142f7..7e6d777 100644 --- a/src/main/kotlin/com/hero/alignlab/domain/pose/domain/PoseLayout.kt +++ b/src/main/kotlin/com/hero/alignlab/domain/pose/domain/PoseLayout.kt @@ -9,7 +9,7 @@ class PoseLayout( @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = "id") - val id: Long = -1, + val id: Long = 0L, @Column(name = "uid") val uid: Long, diff --git a/src/main/kotlin/com/hero/alignlab/domain/pose/domain/PoseLayoutPoint.kt b/src/main/kotlin/com/hero/alignlab/domain/pose/domain/PoseLayoutPoint.kt index 0b68bea..f917d71 100644 --- a/src/main/kotlin/com/hero/alignlab/domain/pose/domain/PoseLayoutPoint.kt +++ b/src/main/kotlin/com/hero/alignlab/domain/pose/domain/PoseLayoutPoint.kt @@ -10,7 +10,7 @@ class PoseLayoutPoint( @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = "id") - val id: Long = -1, + val id: Long = 0L, @Column(name = "pose_layout_id") val poseLayoutId: Long, diff --git a/src/main/kotlin/com/hero/alignlab/domain/pose/domain/PoseSnapshot.kt b/src/main/kotlin/com/hero/alignlab/domain/pose/domain/PoseSnapshot.kt index b5b3f01..1b3dcb4 100644 --- a/src/main/kotlin/com/hero/alignlab/domain/pose/domain/PoseSnapshot.kt +++ b/src/main/kotlin/com/hero/alignlab/domain/pose/domain/PoseSnapshot.kt @@ -11,7 +11,7 @@ data class PoseSnapshot( @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = "id") - val id: Long = -1, + val id: Long = 0L, @Column(name = "uid") val uid: Long, diff --git a/src/main/kotlin/com/hero/alignlab/domain/user/domain/CredentialUserInfo.kt b/src/main/kotlin/com/hero/alignlab/domain/user/domain/CredentialUserInfo.kt index 7d54218..0ee7984 100644 --- a/src/main/kotlin/com/hero/alignlab/domain/user/domain/CredentialUserInfo.kt +++ b/src/main/kotlin/com/hero/alignlab/domain/user/domain/CredentialUserInfo.kt @@ -10,7 +10,7 @@ import jakarta.persistence.* class CredentialUserInfo( @Id @GeneratedValue(strategy = GenerationType.IDENTITY) - val id: Long = -1, + val id: Long = 0L, @Column(name = "uid") val uid: Long, diff --git a/src/main/kotlin/com/hero/alignlab/domain/user/domain/OAuthUserInfo.kt b/src/main/kotlin/com/hero/alignlab/domain/user/domain/OAuthUserInfo.kt index 9417a88..bb246cc 100644 --- a/src/main/kotlin/com/hero/alignlab/domain/user/domain/OAuthUserInfo.kt +++ b/src/main/kotlin/com/hero/alignlab/domain/user/domain/OAuthUserInfo.kt @@ -9,7 +9,7 @@ import jakarta.persistence.* class OAuthUserInfo( @Id @GeneratedValue(strategy = GenerationType.IDENTITY) - val id: Long = -1, + val id: Long = 0L, @Column(name = "uid") val uid: Long, diff --git a/src/main/kotlin/com/hero/alignlab/domain/user/domain/UserInfo.kt b/src/main/kotlin/com/hero/alignlab/domain/user/domain/UserInfo.kt index b31e92c..b18b0e4 100644 --- a/src/main/kotlin/com/hero/alignlab/domain/user/domain/UserInfo.kt +++ b/src/main/kotlin/com/hero/alignlab/domain/user/domain/UserInfo.kt @@ -8,7 +8,7 @@ import jakarta.persistence.* class UserInfo( @Id @GeneratedValue(strategy = GenerationType.IDENTITY) - val id: Long = -1, + val id: Long = 0L, @Column(name = "nickname") var nickname: String,