diff --git a/sql/DDL.sql b/sql/DDL.sql index 7d1ab4d..fdbbecc 100644 --- a/sql/DDL.sql +++ b/sql/DDL.sql @@ -32,17 +32,20 @@ CREATE UNIQUE INDEX uidx__username ON credential_user_info (username); -- 그룹 CREATE TABLE `group` ( - `id` bigint NOT NULL AUTO_INCREMENT COMMENT 'group id', - `name` varchar(32) NOT NULL COMMENT '그룹명', - `description` varchar(512) DEFAULT NULL COMMENT '그룹 설명', - `owner_uid` bigint NOT NULL COMMENT 'owner uid', - `created_at` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '생성일', - `modified_at` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '수정일', + `id` bigint NOT NULL AUTO_INCREMENT COMMENT 'group id', + `name` varchar(32) NOT NULL COMMENT '그룹명', + `description` varchar(512) DEFAULT NULL COMMENT '그룹 설명', + `owner_uid` bigint NOT NULL COMMENT 'owner uid', + `is_hidden` tinyint NOT NULL DEFAULT 0 COMMENT '숨김 여부', + `join_code` varchar(128) 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__name ON `group` (name); CREATE INDEX idx__owner_uid ON `group` (owner_uid); +CREATE INDEX idx__join_code ON `group` (join_code); -- 그룹 유저 CREATE TABLE `group_user` 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 5bc8bf7..c835d0d 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 @@ -33,11 +33,19 @@ class GroupFacade( } } - suspend fun joinGroup(user: AuthUser, groupId: Long): JoinGroupResponse { + suspend fun joinGroup( + user: AuthUser, + groupId: Long, + joinCode: String? + ): JoinGroupResponse { return parZip( { groupService.findByIdOrThrow(groupId) }, { groupUserService.findAllByUid(user.uid).associateBy { it.groupId } } ) { group, groupUsers -> + if (group.isHidden && group.joinCode != joinCode) { + throw InvalidRequestException(ErrorCode.IMPOSSIBLE_TO_JOIN_GROUP_ERROR) + } + val groupUser = groupUsers[groupId] if (groupUser == null && groupUsers.isNotEmpty()) { 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 8bc600a..de0a5ed 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 @@ -16,6 +16,7 @@ import kotlinx.coroutines.withContext import org.springframework.context.ApplicationEventPublisher import org.springframework.data.repository.findByIdOrNull import org.springframework.stereotype.Service +import java.util.* @Service class GroupService( @@ -33,7 +34,9 @@ class GroupService( Group( name = request.name, description = request.description, - ownerUid = user.uid + ownerUid = user.uid, + isHidden = request.isHidden, + joinCode = request.joinCode ?: UUID.randomUUID().toString().replace("-", "") ) ) 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 dc0182f..b63f85b 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 @@ -18,4 +18,10 @@ data class Group( @Column(name = "owner_uid") var ownerUid: Long, + + @Column(name = "is_hidden") + val isHidden: Boolean, + + @Column(name = "join_code") + val joinCode: String ) : BaseEntity() 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 87e3c8f..702a212 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 @@ -5,4 +5,8 @@ data class CreateGroupRequest( val name: String, /** 그룹 설명 */ val description: String?, + /** 숨김 여부 */ + val isHidden: Boolean, + /** 참여 코드, 미입력시 자동 생성 */ + val joinCode: String?, ) 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 fcceed1..f932b67 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 @@ -36,6 +36,11 @@ class GroupResource( @PostMapping("/api/v1/groups/{groupId}/join") suspend fun joinGroup( user: AuthUser, - @PathVariable groupId: Long - ) = groupFacade.joinGroup(user, groupId).wrapOk() + @PathVariable groupId: Long, + @RequestParam(required = false) joinCode: String?, + ) = groupFacade.joinGroup( + user = user, + groupId = groupId, + joinCode = joinCode + ).wrapOk() } diff --git a/src/main/kotlin/com/hero/alignlab/exception/ErrorCode.kt b/src/main/kotlin/com/hero/alignlab/exception/ErrorCode.kt index 17073fc..ab60505 100644 --- a/src/main/kotlin/com/hero/alignlab/exception/ErrorCode.kt +++ b/src/main/kotlin/com/hero/alignlab/exception/ErrorCode.kt @@ -34,6 +34,7 @@ enum class ErrorCode(val status: HttpStatus, val description: String) { /** Group Error Code */ DUPLICATE_GROUP_NAME_ERROR(HttpStatus.BAD_REQUEST, "중복된 그룹명입니다."), NOT_FOUND_GROUP_ERROR(HttpStatus.NOT_FOUND, "그룹 정보를 찾을 수 없습니다."), + IMPOSSIBLE_TO_JOIN_GROUP_ERROR(HttpStatus.BAD_REQUEST, "그룹에 들어갈 수 없습니다."), /** Group User Error Code */ DUPLICATE_GROUP_JOIN_ERROR(HttpStatus.BAD_REQUEST, "한개의 그룹만 참여 가능합니다."),