From de77605a108153fe1712be31dd522dd46880593b Mon Sep 17 00:00:00 2001 From: EunHaSong Date: Wed, 13 May 2026 18:07:52 +0900 Subject: [PATCH 01/26] =?UTF-8?q?add/#12:=20=ED=8C=80=20entity=20=EB=B0=8F?= =?UTF-8?q?=20eum=20=ED=8C=8C=EC=9D=BC=20=EC=83=9D=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/beat_it/team/entity/TeamLinks.kt | 34 +++++++++++++++ .../beat_it/team/entity/TeamMemberships.kt | 28 ++++++++++++ .../com/beat_it/team/entity/TeamParts.kt | 32 ++++++++++++++ .../com/beat_it/team/entity/TeamSettings.kt | 23 ++++++++++ .../kotlin/com/beat_it/team/entity/Teams.kt | 43 +++++++++++++++++++ .../beat_it/team/entity/enum/PlatformCode.kt | 8 ++++ .../com/beat_it/team/entity/enum/TeamRole.kt | 8 ++++ .../com/beat_it/team/entity/enum/TeamType.kt | 8 ++++ 8 files changed, 184 insertions(+) create mode 100644 src/main/kotlin/com/beat_it/team/entity/TeamLinks.kt create mode 100644 src/main/kotlin/com/beat_it/team/entity/TeamMemberships.kt create mode 100644 src/main/kotlin/com/beat_it/team/entity/TeamParts.kt create mode 100644 src/main/kotlin/com/beat_it/team/entity/TeamSettings.kt create mode 100644 src/main/kotlin/com/beat_it/team/entity/Teams.kt create mode 100644 src/main/kotlin/com/beat_it/team/entity/enum/PlatformCode.kt create mode 100644 src/main/kotlin/com/beat_it/team/entity/enum/TeamRole.kt create mode 100644 src/main/kotlin/com/beat_it/team/entity/enum/TeamType.kt diff --git a/src/main/kotlin/com/beat_it/team/entity/TeamLinks.kt b/src/main/kotlin/com/beat_it/team/entity/TeamLinks.kt new file mode 100644 index 0000000..3d35b10 --- /dev/null +++ b/src/main/kotlin/com/beat_it/team/entity/TeamLinks.kt @@ -0,0 +1,34 @@ +package com.beat_it.team.entity + +import com.beat_it.team.entity.enum.PlatformCode +import com.beat_it.team.entity.enum.TeamRole +import jakarta.persistence.* +import java.time.OffsetDateTime + +@Entity +@Table(name = "team_links") +class TeamLinks( + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(nullable = false) + val teamLinkId: Long? = null, + + //TODO: 팀 ID 연결하기 + + @Column(nullable = false) + var partName: String = "", + + @Enumerated(EnumType.STRING) + @Column(nullable = false) + var platformCode: PlatformCode = PlatformCode.CUSTOM, + + @Column(nullable = false) + var linkUrl: String = "", + + @Column(nullable = false) + var updateAt: OffsetDateTime = OffsetDateTime.now(), + + @Column(nullable = false) + val createdAt: OffsetDateTime = OffsetDateTime.now(), + + ) \ No newline at end of file diff --git a/src/main/kotlin/com/beat_it/team/entity/TeamMemberships.kt b/src/main/kotlin/com/beat_it/team/entity/TeamMemberships.kt new file mode 100644 index 0000000..827bd90 --- /dev/null +++ b/src/main/kotlin/com/beat_it/team/entity/TeamMemberships.kt @@ -0,0 +1,28 @@ +package com.beat_it.team.entity + +import com.beat_it.team.entity.enum.TeamRole +import jakarta.persistence.* +import java.time.OffsetDateTime + +@Entity +@Table(name = "team_membership") +class TeamMemberships( + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + val teamMembershipId: Long? = null, + + //TODO: 팀 ID 연결하기 + //TODO: 사용자 ID 연결하기 >> 모듈 분리 + + @Column(nullable = false) + var teamRole: TeamRole = TeamRole.MEMBER, + + @Column(nullable = false) + var updateAt: OffsetDateTime = OffsetDateTime.now(), + + @Column(nullable = false) + val createdAt: OffsetDateTime = OffsetDateTime.now(), + + @Column(nullable = true) + var leftAt: OffsetDateTime? = null, +) \ No newline at end of file diff --git a/src/main/kotlin/com/beat_it/team/entity/TeamParts.kt b/src/main/kotlin/com/beat_it/team/entity/TeamParts.kt new file mode 100644 index 0000000..e8912b3 --- /dev/null +++ b/src/main/kotlin/com/beat_it/team/entity/TeamParts.kt @@ -0,0 +1,32 @@ +package com.beat_it.team.entity + +import com.beat_it.team.entity.enum.TeamRole +import jakarta.persistence.* +import java.time.OffsetDateTime + +@Entity +@Table(name = "team_parts") +class TeamParts( + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(nullable = false) + val teamPartId: Long? = null, + + //TODO: 팀 ID 연결하기 + + @Column(nullable = false) + var partName: String = "", + + @Column(nullable = false) + var displayOrder: Int = 0, + + @Column(nullable = false) + var isActive: Boolean = true, + + @Column(nullable = false) + var updateAt: OffsetDateTime = OffsetDateTime.now(), + + @Column(nullable = false) + val createdAt: OffsetDateTime = OffsetDateTime.now(), + + ) \ No newline at end of file diff --git a/src/main/kotlin/com/beat_it/team/entity/TeamSettings.kt b/src/main/kotlin/com/beat_it/team/entity/TeamSettings.kt new file mode 100644 index 0000000..925817e --- /dev/null +++ b/src/main/kotlin/com/beat_it/team/entity/TeamSettings.kt @@ -0,0 +1,23 @@ +package com.beat_it.team.entity + +import jakarta.persistence.* +import java.time.OffsetDateTime + +@Entity +@Table(name = "team_settings") +class TeamSettings( + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + val teamSettingId: Long? = null, + + //TODO: 팀 ID 연결하기 + + @Column(nullable = false) + var maxStorage: Int = 10, + + @Column(nullable = false) + var usedStorage: Int = 0, + + @Column(nullable = false) + var updateAt: OffsetDateTime = OffsetDateTime.now(), +) \ No newline at end of file diff --git a/src/main/kotlin/com/beat_it/team/entity/Teams.kt b/src/main/kotlin/com/beat_it/team/entity/Teams.kt new file mode 100644 index 0000000..65e1e13 --- /dev/null +++ b/src/main/kotlin/com/beat_it/team/entity/Teams.kt @@ -0,0 +1,43 @@ +package com.beat_it.team.entity + +import com.beat_it.team.entity.enum.TeamType +import jakarta.persistence.* +import java.time.OffsetDateTime +import java.util.UUID + +@Entity +@Table(name = "teams") +class Teams( + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + val teamId: Long? = null, + + @Column(nullable = false, unique = true) + val publicId: UUID = UUID.randomUUID(), // 외부 노출용 ID + + @Column(nullable = false) + var name: String = "", + + @Column(nullable = true) + var description: String = "", + + @Enumerated(EnumType.STRING) + @Column(nullable = false) + val teamType: TeamType = TeamType.TEAM, + + @Column(nullable = false) + var establishedOn: OffsetDateTime? = null, + + @Column(nullable = false, unique = true) + val inviteCode: String = "", + + @Column(nullable = false) + var updateAt: OffsetDateTime = OffsetDateTime.now(), + + @Column(nullable = false) + val createdAt: OffsetDateTime = OffsetDateTime.now(), + + @Column(nullable = true) + var deleteddAt: OffsetDateTime? = null, + +) diff --git a/src/main/kotlin/com/beat_it/team/entity/enum/PlatformCode.kt b/src/main/kotlin/com/beat_it/team/entity/enum/PlatformCode.kt new file mode 100644 index 0000000..3b34a5c --- /dev/null +++ b/src/main/kotlin/com/beat_it/team/entity/enum/PlatformCode.kt @@ -0,0 +1,8 @@ +package com.beat_it.team.entity.enum + +enum class PlatformCode(val description : String) { + YOUTUBE("유튜브"), + INSTAGRAM("인스타"), + CUSTOM("기타"); +} + diff --git a/src/main/kotlin/com/beat_it/team/entity/enum/TeamRole.kt b/src/main/kotlin/com/beat_it/team/entity/enum/TeamRole.kt new file mode 100644 index 0000000..ce6147b --- /dev/null +++ b/src/main/kotlin/com/beat_it/team/entity/enum/TeamRole.kt @@ -0,0 +1,8 @@ +package com.beat_it.team.entity.enum + +enum class TeamRole(val description : String) { + LEADER("대표"), + MENAGER("운영진"), + MEMBER("팀원"); +} + diff --git a/src/main/kotlin/com/beat_it/team/entity/enum/TeamType.kt b/src/main/kotlin/com/beat_it/team/entity/enum/TeamType.kt new file mode 100644 index 0000000..9b21cb6 --- /dev/null +++ b/src/main/kotlin/com/beat_it/team/entity/enum/TeamType.kt @@ -0,0 +1,8 @@ +package com.beat_it.team.entity.enum + +enum class TeamType(val description : String) { + BAND("밴드"), + DANCE("댄스팀"), + VOCAL("보컬팀"), + TEAM("기본 팀"); +} \ No newline at end of file From 783222f4306a0d486bf3d6fd3fdb8068e1747325 Mon Sep 17 00:00:00 2001 From: EunHaSong Date: Tue, 19 May 2026 21:53:20 +0900 Subject: [PATCH 02/26] =?UTF-8?q?chore/#12:=20entity=20=ED=8C=8C=EC=9D=BC?= =?UTF-8?q?=20=ED=8F=AC=EB=A7=B7=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/beat_it/team/entity/TeamLinks.kt | 18 +++++++++------ .../beat_it/team/entity/TeamMemberships.kt | 9 ++++---- .../com/beat_it/team/entity/TeamParts.kt | 12 +++++----- .../com/beat_it/team/entity/TeamSettings.kt | 7 +++--- .../kotlin/com/beat_it/team/entity/Teams.kt | 23 ++++++++++--------- 5 files changed, 38 insertions(+), 31 deletions(-) diff --git a/src/main/kotlin/com/beat_it/team/entity/TeamLinks.kt b/src/main/kotlin/com/beat_it/team/entity/TeamLinks.kt index 3d35b10..dc02755 100644 --- a/src/main/kotlin/com/beat_it/team/entity/TeamLinks.kt +++ b/src/main/kotlin/com/beat_it/team/entity/TeamLinks.kt @@ -10,25 +10,29 @@ import java.time.OffsetDateTime class TeamLinks( @Id @GeneratedValue(strategy = GenerationType.IDENTITY) - @Column(nullable = false) + @Column(name="team_link_id", nullable = false) val teamLinkId: Long? = null, //TODO: 팀 ID 연결하기 + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name="team_id", nullable = false) + val teams: Teams = Teams(), - @Column(nullable = false) + @Column(name="part_name",nullable = false) var partName: String = "", @Enumerated(EnumType.STRING) - @Column(nullable = false) + @Column(name="platform_code",nullable = false) var platformCode: PlatformCode = PlatformCode.CUSTOM, - @Column(nullable = false) + @Column(name="link_url",nullable = false) var linkUrl: String = "", - @Column(nullable = false) + @Column(name="update_at",nullable = false) var updateAt: OffsetDateTime = OffsetDateTime.now(), - @Column(nullable = false) + @Column(name="create_at",nullable = false) val createdAt: OffsetDateTime = OffsetDateTime.now(), - ) \ No newline at end of file + ) +// ) : BaseTime \ No newline at end of file diff --git a/src/main/kotlin/com/beat_it/team/entity/TeamMemberships.kt b/src/main/kotlin/com/beat_it/team/entity/TeamMemberships.kt index 827bd90..e56a69a 100644 --- a/src/main/kotlin/com/beat_it/team/entity/TeamMemberships.kt +++ b/src/main/kotlin/com/beat_it/team/entity/TeamMemberships.kt @@ -9,20 +9,21 @@ import java.time.OffsetDateTime class TeamMemberships( @Id @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "team_membership_id") val teamMembershipId: Long? = null, //TODO: 팀 ID 연결하기 //TODO: 사용자 ID 연결하기 >> 모듈 분리 - @Column(nullable = false) + @Column(name="team_role", nullable = false) var teamRole: TeamRole = TeamRole.MEMBER, - @Column(nullable = false) + @Column(name="update_at", nullable = false) var updateAt: OffsetDateTime = OffsetDateTime.now(), - @Column(nullable = false) + @Column(name="create_at", nullable = false) val createdAt: OffsetDateTime = OffsetDateTime.now(), - @Column(nullable = true) + @Column(name="left_at", nullable = true) var leftAt: OffsetDateTime? = null, ) \ No newline at end of file diff --git a/src/main/kotlin/com/beat_it/team/entity/TeamParts.kt b/src/main/kotlin/com/beat_it/team/entity/TeamParts.kt index e8912b3..f83483f 100644 --- a/src/main/kotlin/com/beat_it/team/entity/TeamParts.kt +++ b/src/main/kotlin/com/beat_it/team/entity/TeamParts.kt @@ -9,24 +9,24 @@ import java.time.OffsetDateTime class TeamParts( @Id @GeneratedValue(strategy = GenerationType.IDENTITY) - @Column(nullable = false) + @Column(name="team_role", nullable = false) val teamPartId: Long? = null, //TODO: 팀 ID 연결하기 - @Column(nullable = false) + @Column(name="part_name", nullable = false) var partName: String = "", - @Column(nullable = false) + @Column(name="display_order", nullable = false) var displayOrder: Int = 0, - @Column(nullable = false) + @Column(name="is_active", nullable = false) var isActive: Boolean = true, - @Column(nullable = false) + @Column(name="update_at", nullable = false) var updateAt: OffsetDateTime = OffsetDateTime.now(), - @Column(nullable = false) + @Column(name="create_at", nullable = false) val createdAt: OffsetDateTime = OffsetDateTime.now(), ) \ No newline at end of file diff --git a/src/main/kotlin/com/beat_it/team/entity/TeamSettings.kt b/src/main/kotlin/com/beat_it/team/entity/TeamSettings.kt index 925817e..25114b6 100644 --- a/src/main/kotlin/com/beat_it/team/entity/TeamSettings.kt +++ b/src/main/kotlin/com/beat_it/team/entity/TeamSettings.kt @@ -8,16 +8,17 @@ import java.time.OffsetDateTime class TeamSettings( @Id @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name="team_settings_id") val teamSettingId: Long? = null, //TODO: 팀 ID 연결하기 - @Column(nullable = false) + @Column(name="max_storage", nullable = false) var maxStorage: Int = 10, - @Column(nullable = false) + @Column(name="used_storage", nullable = false) var usedStorage: Int = 0, - @Column(nullable = false) + @Column(name="update_at", nullable = false) var updateAt: OffsetDateTime = OffsetDateTime.now(), ) \ No newline at end of file diff --git a/src/main/kotlin/com/beat_it/team/entity/Teams.kt b/src/main/kotlin/com/beat_it/team/entity/Teams.kt index 65e1e13..fdc9b41 100644 --- a/src/main/kotlin/com/beat_it/team/entity/Teams.kt +++ b/src/main/kotlin/com/beat_it/team/entity/Teams.kt @@ -10,34 +10,35 @@ import java.util.UUID class Teams( @Id @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name="team_id", nullable = false) val teamId: Long? = null, - @Column(nullable = false, unique = true) + @Column(name="public_at", nullable = false, unique = true) val publicId: UUID = UUID.randomUUID(), // 외부 노출용 ID - @Column(nullable = false) - var name: String = "", + @Column(name="name", nullable = false) + var teamName: String = "", - @Column(nullable = true) + @Column(name="description", nullable = true) var description: String = "", @Enumerated(EnumType.STRING) - @Column(nullable = false) + @Column(name="team_type", nullable = false) val teamType: TeamType = TeamType.TEAM, - @Column(nullable = false) + @Column(name="established_on", nullable = false) var establishedOn: OffsetDateTime? = null, - @Column(nullable = false, unique = true) + @Column(name="invite_code", nullable = false, unique = true) val inviteCode: String = "", - @Column(nullable = false) + @Column(name="update_at", nullable = false) var updateAt: OffsetDateTime = OffsetDateTime.now(), - @Column(nullable = false) + @Column(name="create_at", nullable = false) val createdAt: OffsetDateTime = OffsetDateTime.now(), - @Column(nullable = true) - var deleteddAt: OffsetDateTime? = null, + @Column(name="deleted_at", nullable = true) + var deletedAt: OffsetDateTime? = null, ) From 52c94e6225ab4219390bd3a94774015d30a56ac4 Mon Sep 17 00:00:00 2001 From: EunHaSong Date: Tue, 19 May 2026 21:54:08 +0900 Subject: [PATCH 03/26] =?UTF-8?q?add/#12:=20=ED=8C=80=20service,=20control?= =?UTF-8?q?ler=20=ED=8C=8C=EC=9D=BC=20=EC=83=9D=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../team/controller/TeamController.java | 58 +++++++++++++++++++ .../com/beat_it/team/service/TeamService.java | 4 ++ 2 files changed, 62 insertions(+) create mode 100644 src/main/kotlin/com/beat_it/team/controller/TeamController.java create mode 100644 src/main/kotlin/com/beat_it/team/service/TeamService.java diff --git a/src/main/kotlin/com/beat_it/team/controller/TeamController.java b/src/main/kotlin/com/beat_it/team/controller/TeamController.java new file mode 100644 index 0000000..5487548 --- /dev/null +++ b/src/main/kotlin/com/beat_it/team/controller/TeamController.java @@ -0,0 +1,58 @@ +//package com.beat_it.team.controller +// +//import com.beat_it.global.response.BasicResponse +//import com.beat_it.team.dto.TeamCreateRequest +//import com.beat_it.team.dto.TeamCreateResponse +//import com.beat_it.team.dto.TeamListResponse +//import com.beat_it.team.dto.TeamUpdateRequest +//import com.beat_it.team.dto.TeamUpdateResponse +//import com.beat_it.team.service.TeamService +//import org.springframework.http.HttpStatus +//import org.springframework.http.ResponseEntity +//import org.springframework.web.bind.annotation.* +// +//@RestController +//@RequestMapping("/teams") +//class TeamController( +// private val teamService: TeamService +//) { +// +// @PostMapping +// fun createTeam( +// @RequestHeader("X-USER-ID") userId: Long, +// @RequestBody request: TeamCreateRequest +// ): ResponseEntity> { +// +// val responseData = teamService.createTeam(userId, request) +// +// return ResponseEntity +// .status(HttpStatus.CREATED) +// .body(BasicResponse.success(responseData, "팀 생성에 성공했습니다.")) +// } +// +// @GetMapping +// fun getMyTeams( +// @RequestHeader("X-USER-ID") userId: Long +// ): ResponseEntity> { +// +// val responseData = teamService.getMyTeams(userId) +// +// return ResponseEntity.ok( +// BasicResponse.success(responseData, "내 팀 목록 조회에 성공했습니다.") +// ) +// } +// +// @PatchMapping +// fun updateTeamPage( +// @RequestHeader("X-USER-ID") userId: Long, +// @RequestHeader(value = "X-TEAM-ID", required = false) teamId: Long?, +// @RequestBody request: TeamUpdateRequest +// ): ResponseEntity> { +// +// val responseData = teamService.updateTeamPage(userId, teamId, request) +// +// return ResponseEntity.ok( +// BasicResponse.success(responseData, "팀 페이지 수정에 성공했습니다.") +// ) +// } +//} \ No newline at end of file diff --git a/src/main/kotlin/com/beat_it/team/service/TeamService.java b/src/main/kotlin/com/beat_it/team/service/TeamService.java new file mode 100644 index 0000000..ab679c4 --- /dev/null +++ b/src/main/kotlin/com/beat_it/team/service/TeamService.java @@ -0,0 +1,4 @@ +package com.beat_it.team.service; + +public class TeamService { +} From 21232261666f8c678019bdf866445f2396ef51ae Mon Sep 17 00:00:00 2001 From: EunHaSong Date: Fri, 22 May 2026 12:05:09 +0900 Subject: [PATCH 04/26] =?UTF-8?q?add/#12:=20entity=20=EB=82=B4=20=EC=B0=B8?= =?UTF-8?q?=EC=A1=B0=20id=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/kotlin/com/beat_it/team/entity/TeamLinks.kt | 4 ++-- .../kotlin/com/beat_it/team/entity/TeamMemberships.kt | 3 +++ src/main/kotlin/com/beat_it/team/entity/TeamParts.kt | 5 ++++- .../kotlin/com/beat_it/team/entity/TeamSettings.kt | 3 +++ src/main/kotlin/com/beat_it/team/entity/Teams.kt | 10 +++++----- 5 files changed, 17 insertions(+), 8 deletions(-) diff --git a/src/main/kotlin/com/beat_it/team/entity/TeamLinks.kt b/src/main/kotlin/com/beat_it/team/entity/TeamLinks.kt index dc02755..e29d72b 100644 --- a/src/main/kotlin/com/beat_it/team/entity/TeamLinks.kt +++ b/src/main/kotlin/com/beat_it/team/entity/TeamLinks.kt @@ -15,8 +15,8 @@ class TeamLinks( //TODO: 팀 ID 연결하기 @ManyToOne(fetch = FetchType.LAZY) - @JoinColumn(name="team_id", nullable = false) - val teams: Teams = Teams(), + @JoinColumn(name = "team_id", nullable = false) + val team: Teams, @Column(name="part_name",nullable = false) var partName: String = "", diff --git a/src/main/kotlin/com/beat_it/team/entity/TeamMemberships.kt b/src/main/kotlin/com/beat_it/team/entity/TeamMemberships.kt index e56a69a..66c7e9d 100644 --- a/src/main/kotlin/com/beat_it/team/entity/TeamMemberships.kt +++ b/src/main/kotlin/com/beat_it/team/entity/TeamMemberships.kt @@ -14,6 +14,9 @@ class TeamMemberships( //TODO: 팀 ID 연결하기 //TODO: 사용자 ID 연결하기 >> 모듈 분리 + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "team_id", nullable = false) + val team: Teams, @Column(name="team_role", nullable = false) var teamRole: TeamRole = TeamRole.MEMBER, diff --git a/src/main/kotlin/com/beat_it/team/entity/TeamParts.kt b/src/main/kotlin/com/beat_it/team/entity/TeamParts.kt index f83483f..50dc850 100644 --- a/src/main/kotlin/com/beat_it/team/entity/TeamParts.kt +++ b/src/main/kotlin/com/beat_it/team/entity/TeamParts.kt @@ -9,10 +9,13 @@ import java.time.OffsetDateTime class TeamParts( @Id @GeneratedValue(strategy = GenerationType.IDENTITY) - @Column(name="team_role", nullable = false) + @Column(name="team_part_id", nullable = false) val teamPartId: Long? = null, //TODO: 팀 ID 연결하기 + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "team_id", nullable = false) + val team: Teams, @Column(name="part_name", nullable = false) var partName: String = "", diff --git a/src/main/kotlin/com/beat_it/team/entity/TeamSettings.kt b/src/main/kotlin/com/beat_it/team/entity/TeamSettings.kt index 25114b6..a82c891 100644 --- a/src/main/kotlin/com/beat_it/team/entity/TeamSettings.kt +++ b/src/main/kotlin/com/beat_it/team/entity/TeamSettings.kt @@ -12,6 +12,9 @@ class TeamSettings( val teamSettingId: Long? = null, //TODO: 팀 ID 연결하기 + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "team_id", nullable = false) + val team: Teams, @Column(name="max_storage", nullable = false) var maxStorage: Int = 10, diff --git a/src/main/kotlin/com/beat_it/team/entity/Teams.kt b/src/main/kotlin/com/beat_it/team/entity/Teams.kt index fdc9b41..f62c85e 100644 --- a/src/main/kotlin/com/beat_it/team/entity/Teams.kt +++ b/src/main/kotlin/com/beat_it/team/entity/Teams.kt @@ -32,11 +32,11 @@ class Teams( @Column(name="invite_code", nullable = false, unique = true) val inviteCode: String = "", - @Column(name="update_at", nullable = false) - var updateAt: OffsetDateTime = OffsetDateTime.now(), - - @Column(name="create_at", nullable = false) - val createdAt: OffsetDateTime = OffsetDateTime.now(), +// @Column(name="update_at", nullable = false) +// var updateAt: OffsetDateTime = OffsetDateTime.now(), +// +// @Column(name="create_at", nullable = false) +// val createdAt: OffsetDateTime = OffsetDateTime.now(), @Column(name="deleted_at", nullable = true) var deletedAt: OffsetDateTime? = null, From 7ed3b4c4b1e76aeecfe3a649079512ed3a9a8539 Mon Sep 17 00:00:00 2001 From: EunHaSong Date: Sat, 23 May 2026 05:50:53 +0900 Subject: [PATCH 05/26] =?UTF-8?q?feat/#12:=20=ED=8C=80=20=EC=83=9D?= =?UTF-8?q?=EC=84=B1,=20=ED=8C=80=20=EC=A1=B0=ED=9A=8C,=20=ED=8C=80=20?= =?UTF-8?q?=EC=82=AD=EC=A0=9C=20=EA=B8=B0=EB=8A=A5=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 단, 현재 상태에서는 테스트를 진행하지 않았음. --- .../com/beat_it/global/error/ErrorCode.kt | 10 + .../team/controller/TeamController.java | 58 ------ .../beat_it/team/controller/TeamController.kt | 63 ++++++ .../com/beat_it/team/dto/TeamCreateRequest.kt | 19 ++ .../beat_it/team/dto/TeamCreateResponse.kt | 27 +++ .../beat_it/team/dto/TeamDetailResponse.kt | 34 ++++ .../team/dto/TeamDetailUpdateRequest.kt | 24 +++ .../team/dto/TeamDetailUpdateResponse.kt | 20 ++ .../com/beat_it/team/entity/TeamLinks.kt | 2 +- .../beat_it/team/entity/TeamMemberships.kt | 2 +- .../com/beat_it/team/entity/TeamParts.kt | 2 +- .../com/beat_it/team/entity/TeamSettings.kt | 2 +- .../kotlin/com/beat_it/team/entity/Teams.kt | 59 ++++-- .../beat_it/team/repository/TeamRepository.kt | 13 ++ .../com/beat_it/team/service/TeamService.java | 4 - .../com/beat_it/team/service/TeamService.kt | 183 ++++++++++++++++++ 16 files changed, 435 insertions(+), 87 deletions(-) delete mode 100644 src/main/kotlin/com/beat_it/team/controller/TeamController.java create mode 100644 src/main/kotlin/com/beat_it/team/controller/TeamController.kt create mode 100644 src/main/kotlin/com/beat_it/team/dto/TeamCreateRequest.kt create mode 100644 src/main/kotlin/com/beat_it/team/dto/TeamCreateResponse.kt create mode 100644 src/main/kotlin/com/beat_it/team/dto/TeamDetailResponse.kt create mode 100644 src/main/kotlin/com/beat_it/team/dto/TeamDetailUpdateRequest.kt create mode 100644 src/main/kotlin/com/beat_it/team/dto/TeamDetailUpdateResponse.kt create mode 100644 src/main/kotlin/com/beat_it/team/repository/TeamRepository.kt delete mode 100644 src/main/kotlin/com/beat_it/team/service/TeamService.java create mode 100644 src/main/kotlin/com/beat_it/team/service/TeamService.kt diff --git a/src/main/kotlin/com/beat_it/global/error/ErrorCode.kt b/src/main/kotlin/com/beat_it/global/error/ErrorCode.kt index f2590c6..104d170 100644 --- a/src/main/kotlin/com/beat_it/global/error/ErrorCode.kt +++ b/src/main/kotlin/com/beat_it/global/error/ErrorCode.kt @@ -23,6 +23,16 @@ enum class ErrorCode( CALENDAR_START_TIME_REQUIRED(HttpStatus.BAD_REQUEST, "CALENDAR-008", "일정 시작 시각은 필수입니다."), CALENDAR_END_TIME_REQUIRED(HttpStatus.BAD_REQUEST, "CALENDAR-009", "일정 종료 시각은 필수입니다."), + // --- 팀 관련 에러 (TEAM) --- + TEAM_NO_CONTENT_TO_UPDATE(HttpStatus.BAD_REQUEST, "TEAM-001", "팀에 대해 변경할 내용이 업습니다."), + TEAM_NO_PERMISSION(HttpStatus.FORBIDDEN, "TEAM-002", "팀 조회 권한이 없습니다."), + TEAM_NOT_FOUND(HttpStatus.NOT_FOUND, "TEAM-003", "팀을 찾을 수 없습니다."), + TEAM_NAME_REQUIRED(HttpStatus.BAD_REQUEST, "TEAM-004", "팀 이름은 필수입니다."), + TEAM_NAME_TOO_LONG(HttpStatus.BAD_REQUEST, "TEAM-005", "팀 이름은 100자 이하여야 합니다."), + TEAM_DESCRIPTION_TOO_LONG(HttpStatus.BAD_REQUEST, "TEAM-006", "팀 설명은 500자 이하여야 합니다."), + TEAM_NO_UPDATE_PERMISSION(HttpStatus.FORBIDDEN, "TEAM-007","팀 수정 권한이 없습니다."), + + // --- 장소 관련 에러 --- LOCATION_NOT_FOUND(HttpStatus.NOT_FOUND, "LOCATION-001", "장소를 찾을 수 없습니다."), diff --git a/src/main/kotlin/com/beat_it/team/controller/TeamController.java b/src/main/kotlin/com/beat_it/team/controller/TeamController.java deleted file mode 100644 index 5487548..0000000 --- a/src/main/kotlin/com/beat_it/team/controller/TeamController.java +++ /dev/null @@ -1,58 +0,0 @@ -//package com.beat_it.team.controller -// -//import com.beat_it.global.response.BasicResponse -//import com.beat_it.team.dto.TeamCreateRequest -//import com.beat_it.team.dto.TeamCreateResponse -//import com.beat_it.team.dto.TeamListResponse -//import com.beat_it.team.dto.TeamUpdateRequest -//import com.beat_it.team.dto.TeamUpdateResponse -//import com.beat_it.team.service.TeamService -//import org.springframework.http.HttpStatus -//import org.springframework.http.ResponseEntity -//import org.springframework.web.bind.annotation.* -// -//@RestController -//@RequestMapping("/teams") -//class TeamController( -// private val teamService: TeamService -//) { -// -// @PostMapping -// fun createTeam( -// @RequestHeader("X-USER-ID") userId: Long, -// @RequestBody request: TeamCreateRequest -// ): ResponseEntity> { -// -// val responseData = teamService.createTeam(userId, request) -// -// return ResponseEntity -// .status(HttpStatus.CREATED) -// .body(BasicResponse.success(responseData, "팀 생성에 성공했습니다.")) -// } -// -// @GetMapping -// fun getMyTeams( -// @RequestHeader("X-USER-ID") userId: Long -// ): ResponseEntity> { -// -// val responseData = teamService.getMyTeams(userId) -// -// return ResponseEntity.ok( -// BasicResponse.success(responseData, "내 팀 목록 조회에 성공했습니다.") -// ) -// } -// -// @PatchMapping -// fun updateTeamPage( -// @RequestHeader("X-USER-ID") userId: Long, -// @RequestHeader(value = "X-TEAM-ID", required = false) teamId: Long?, -// @RequestBody request: TeamUpdateRequest -// ): ResponseEntity> { -// -// val responseData = teamService.updateTeamPage(userId, teamId, request) -// -// return ResponseEntity.ok( -// BasicResponse.success(responseData, "팀 페이지 수정에 성공했습니다.") -// ) -// } -//} \ No newline at end of file diff --git a/src/main/kotlin/com/beat_it/team/controller/TeamController.kt b/src/main/kotlin/com/beat_it/team/controller/TeamController.kt new file mode 100644 index 0000000..1784d70 --- /dev/null +++ b/src/main/kotlin/com/beat_it/team/controller/TeamController.kt @@ -0,0 +1,63 @@ +package com.beat_it.team.controller + +import com.beat_it.team.dto.TeamCreateRequest +import com.beat_it.team.dto.TeamCreateResponse +import com.beat_it.team.dto.TeamDetailResponse +import com.beat_it.team.dto.TeamDetailUpdateRequest +import com.beat_it.team.dto.TeamDetailUpdateResponse +import com.beat_it.team.service.TeamService +import com.beat_it.global.response.BasicResponse +import org.springframework.http.HttpStatus +import org.springframework.http.ResponseEntity +import org.springframework.web.bind.annotation.* + +@RestController +@RequestMapping("/teams") +class TeamController( + private val teamService: TeamService +) { + + @PostMapping + fun createTeam( + @RequestBody request: TeamCreateRequest + ): ResponseEntity> { + + val responseData = teamService.createTeam(request) + + return ResponseEntity + .status(HttpStatus.CREATED) + .body(BasicResponse.success(responseData, "팀 생성에 성공했습니다.")) + } + + @PatchMapping + fun updateTeamDetail( + @RequestHeader("X-USER-ID") teamId: Long, + @RequestHeader("X-USER-ID") userId: Long, + @RequestBody request: TeamDetailUpdateRequest, + ): ResponseEntity> { + val responseData = teamService.updateTeamDetail(teamId, userId, request) + return ResponseEntity.ok(BasicResponse.success(responseData, "팀 상세 내용이 수정되었습니다.")) + } + + @DeleteMapping + fun deleteTeam( + @RequestHeader("X-USER-ID") teamId: Long, + @RequestHeader("X-USER-ID") userId: Long, + ): ResponseEntity> { + teamService.deleteTeam(teamId, userId) + return ResponseEntity.ok( + BasicResponse.success("팀이 성공적으로 삭제되었습니다.") + ) + } + + @GetMapping + fun getTeamDetail( + @RequestHeader("X-USER-ID") teamId: Long, + ): ResponseEntity> { + val responseData = teamService.getTeamDetail(teamId) + return ResponseEntity.ok( + BasicResponse.success(responseData, "팀 상세 내용 조회에 성공했습니다.") + ) + } +} + diff --git a/src/main/kotlin/com/beat_it/team/dto/TeamCreateRequest.kt b/src/main/kotlin/com/beat_it/team/dto/TeamCreateRequest.kt new file mode 100644 index 0000000..64549ae --- /dev/null +++ b/src/main/kotlin/com/beat_it/team/dto/TeamCreateRequest.kt @@ -0,0 +1,19 @@ +package com.beat_it.team.dto + +import com.beat_it.team.entity.enum.TeamType +import com.fasterxml.jackson.annotation.JsonProperty +import java.time.LocalDate +import java.time.OffsetDateTime + +data class TeamCreateRequest( + val teamName: String, + + val description: String?, + + @JsonProperty("team_type") val teamType: TeamType, + + @JsonProperty("established_on") val establishedOn: LocalDate?, + + @JsonProperty("profile_image_url") val profileImageUrl: String?, + + ) \ No newline at end of file diff --git a/src/main/kotlin/com/beat_it/team/dto/TeamCreateResponse.kt b/src/main/kotlin/com/beat_it/team/dto/TeamCreateResponse.kt new file mode 100644 index 0000000..af29f0e --- /dev/null +++ b/src/main/kotlin/com/beat_it/team/dto/TeamCreateResponse.kt @@ -0,0 +1,27 @@ +package com.beat_it.team.dto + +import com.beat_it.team.entity.enum.TeamType +import com.fasterxml.jackson.annotation.JsonProperty +import java.time.OffsetDateTime + +data class TeamCreateResponse( + @JsonProperty("team_id") + val teamId: Long, + + @JsonProperty("team_name") + val teamName: String, + + val description: String?, + + @JsonProperty("invite_code") + val inviteCode: String, + + @JsonProperty("team_type") + val teamType: TeamType, + + @JsonProperty("team_role") + val teamRole: String, + + @JsonProperty("created_at") + val createdAt: OffsetDateTime, +) \ No newline at end of file diff --git a/src/main/kotlin/com/beat_it/team/dto/TeamDetailResponse.kt b/src/main/kotlin/com/beat_it/team/dto/TeamDetailResponse.kt new file mode 100644 index 0000000..a15469d --- /dev/null +++ b/src/main/kotlin/com/beat_it/team/dto/TeamDetailResponse.kt @@ -0,0 +1,34 @@ +package com.beat_it.team.dto + +import com.fasterxml.jackson.annotation.JsonProperty +import java.time.LocalDate +import java.time.OffsetDateTime + +data class TeamDetailResponse( + @JsonProperty("team_id") val teamId: Long? = null, + @JsonProperty("profile_image_url") val profileImageUrl: String?, + @JsonProperty("team_name") val teamName: String, + val description: String?, + @JsonProperty("established_on") val establishedOn: LocalDate?, + @JsonProperty("invite_code") val inviteCode: String, + @JsonProperty("member_count") val memberCount: Int, + @JsonProperty("created_at") val createdAt: OffsetDateTime, + @JsonProperty("updated_at") val updatedAt: OffsetDateTime, + val links: List, + val parts: List, + @JsonProperty("archive_count") val archiveCount: Int, + @JsonProperty("cloud_item_count") val cloudItemCount: Int, + +) + +data class LinksResponse( + @JsonProperty("team_link_id") val teamLinkId: Long, + @JsonProperty("plat_form_code") val platFormCode: String, + @JsonProperty("link_url") val linkUrl: String, +) + +data class PartsResponse( + @JsonProperty("team_part_id") val teamPartId: Long, + @JsonProperty("part_name") val partName: String, + @JsonProperty("display_order") val displayOrder: Int, +) \ No newline at end of file diff --git a/src/main/kotlin/com/beat_it/team/dto/TeamDetailUpdateRequest.kt b/src/main/kotlin/com/beat_it/team/dto/TeamDetailUpdateRequest.kt new file mode 100644 index 0000000..f68bda4 --- /dev/null +++ b/src/main/kotlin/com/beat_it/team/dto/TeamDetailUpdateRequest.kt @@ -0,0 +1,24 @@ +package com.beat_it.team.dto + +import com.fasterxml.jackson.annotation.JsonProperty +import java.time.LocalDate +import java.time.OffsetDateTime + +data class TeamDetailUpdateRequest( + @JsonProperty("team_name") + val teamName: String, + + val description: String?, + + @JsonProperty("established_on") val establishedOn: LocalDate?, + + @JsonProperty("profile_image_url") val profileImageUrl: String?, + + val links: List = emptyList(), + +) + +data class LinksRequest( + @JsonProperty("link_url") val linkUrl: String, + @JsonProperty("plat_form_code") val platFormCode: String, +) \ No newline at end of file diff --git a/src/main/kotlin/com/beat_it/team/dto/TeamDetailUpdateResponse.kt b/src/main/kotlin/com/beat_it/team/dto/TeamDetailUpdateResponse.kt new file mode 100644 index 0000000..09bc697 --- /dev/null +++ b/src/main/kotlin/com/beat_it/team/dto/TeamDetailUpdateResponse.kt @@ -0,0 +1,20 @@ +package com.beat_it.team.dto + +import com.fasterxml.jackson.annotation.JsonProperty +import java.time.LocalDate +import java.time.OffsetDateTime + +data class TeamDetailUpdateResponse( + @JsonProperty("team_id") + val teamId: Long, + + @JsonProperty("team_name") + val teamName: String, + + val description: String?, + + @JsonProperty("established_on") val establishedOn: LocalDate?, + + @JsonProperty("updated_at") val updatedAt: OffsetDateTime, + + ) \ No newline at end of file diff --git a/src/main/kotlin/com/beat_it/team/entity/TeamLinks.kt b/src/main/kotlin/com/beat_it/team/entity/TeamLinks.kt index e29d72b..bd4386f 100644 --- a/src/main/kotlin/com/beat_it/team/entity/TeamLinks.kt +++ b/src/main/kotlin/com/beat_it/team/entity/TeamLinks.kt @@ -11,7 +11,7 @@ class TeamLinks( @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name="team_link_id", nullable = false) - val teamLinkId: Long? = null, + val teamLinkId: Long, //TODO: 팀 ID 연결하기 @ManyToOne(fetch = FetchType.LAZY) diff --git a/src/main/kotlin/com/beat_it/team/entity/TeamMemberships.kt b/src/main/kotlin/com/beat_it/team/entity/TeamMemberships.kt index 66c7e9d..9750663 100644 --- a/src/main/kotlin/com/beat_it/team/entity/TeamMemberships.kt +++ b/src/main/kotlin/com/beat_it/team/entity/TeamMemberships.kt @@ -10,7 +10,7 @@ class TeamMemberships( @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = "team_membership_id") - val teamMembershipId: Long? = null, + val teamMembershipId: Long, //TODO: 팀 ID 연결하기 //TODO: 사용자 ID 연결하기 >> 모듈 분리 diff --git a/src/main/kotlin/com/beat_it/team/entity/TeamParts.kt b/src/main/kotlin/com/beat_it/team/entity/TeamParts.kt index 50dc850..9f00b11 100644 --- a/src/main/kotlin/com/beat_it/team/entity/TeamParts.kt +++ b/src/main/kotlin/com/beat_it/team/entity/TeamParts.kt @@ -10,7 +10,7 @@ class TeamParts( @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name="team_part_id", nullable = false) - val teamPartId: Long? = null, + val teamPartId: Long, //TODO: 팀 ID 연결하기 @ManyToOne(fetch = FetchType.LAZY) diff --git a/src/main/kotlin/com/beat_it/team/entity/TeamSettings.kt b/src/main/kotlin/com/beat_it/team/entity/TeamSettings.kt index a82c891..2db0f67 100644 --- a/src/main/kotlin/com/beat_it/team/entity/TeamSettings.kt +++ b/src/main/kotlin/com/beat_it/team/entity/TeamSettings.kt @@ -9,7 +9,7 @@ class TeamSettings( @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name="team_settings_id") - val teamSettingId: Long? = null, + val teamSettingId: Long, //TODO: 팀 ID 연결하기 @ManyToOne(fetch = FetchType.LAZY) diff --git a/src/main/kotlin/com/beat_it/team/entity/Teams.kt b/src/main/kotlin/com/beat_it/team/entity/Teams.kt index f62c85e..0e8c270 100644 --- a/src/main/kotlin/com/beat_it/team/entity/Teams.kt +++ b/src/main/kotlin/com/beat_it/team/entity/Teams.kt @@ -1,7 +1,9 @@ package com.beat_it.team.entity +import com.beat_it.global.entity.BaseTimeEntity import com.beat_it.team.entity.enum.TeamType import jakarta.persistence.* +import java.time.LocalDate import java.time.OffsetDateTime import java.util.UUID @@ -10,35 +12,50 @@ import java.util.UUID class Teams( @Id @GeneratedValue(strategy = GenerationType.IDENTITY) - @Column(name="team_id", nullable = false) + @Column(name = "team_id", nullable = false) val teamId: Long? = null, - @Column(name="public_at", nullable = false, unique = true) - val publicId: UUID = UUID.randomUUID(), // 외부 노출용 ID + @Column(name = "public_id", nullable = false, unique = true) + val publicId: UUID = UUID.randomUUID(), - @Column(name="name", nullable = false) - var teamName: String = "", + @Column(name = "profile_image_url", nullable = false) + var profileImageUrl: String? = null, - @Column(name="description", nullable = true) - var description: String = "", + @Column(name = "team_name", nullable = false) + var teamName: String, - @Enumerated(EnumType.STRING) - @Column(name="team_type", nullable = false) - val teamType: TeamType = TeamType.TEAM, + @Column(name = "description", nullable = true) + var description: String? = null, - @Column(name="established_on", nullable = false) - var establishedOn: OffsetDateTime? = null, + @Enumerated(EnumType.STRING) + @Column(name = "team_type", nullable = false) + var teamType: TeamType = TeamType.TEAM, - @Column(name="invite_code", nullable = false, unique = true) - val inviteCode: String = "", + @Column(name = "established_on", nullable = true) + var establishedOn: LocalDate? = null, -// @Column(name="update_at", nullable = false) -// var updateAt: OffsetDateTime = OffsetDateTime.now(), -// -// @Column(name="create_at", nullable = false) -// val createdAt: OffsetDateTime = OffsetDateTime.now(), + @Column(name = "invite_code", nullable = false, unique = true) + val inviteCode: String, - @Column(name="deleted_at", nullable = true) + @Column(name = "deleted_at", nullable = true) var deletedAt: OffsetDateTime? = null, -) +) : BaseTimeEntity() { + + fun updateTeamDetail ( + teamName: String, + description: String?, + establishedOn: LocalDate?, + teamType: TeamType, + ) { + this.teamName = teamName + this.description = description + this.establishedOn = establishedOn + this.teamType = teamType + } + + + fun deleteTeam() { + this.deletedAt = OffsetDateTime.now() + } +} \ No newline at end of file diff --git a/src/main/kotlin/com/beat_it/team/repository/TeamRepository.kt b/src/main/kotlin/com/beat_it/team/repository/TeamRepository.kt new file mode 100644 index 0000000..6f04723 --- /dev/null +++ b/src/main/kotlin/com/beat_it/team/repository/TeamRepository.kt @@ -0,0 +1,13 @@ +package com.beat_it.team.repository + +import com.beat_it.team.entity.Teams +import org.springframework.data.jpa.repository.JpaRepository +import org.springframework.stereotype.Repository + +@Repository +interface TeamRepository : JpaRepository { + + fun findByTeamIdAndDeletedAtIsNull(teamId: Long): Teams? + + fun existsByInviteCode(inviteCode: String): Boolean +} \ No newline at end of file diff --git a/src/main/kotlin/com/beat_it/team/service/TeamService.java b/src/main/kotlin/com/beat_it/team/service/TeamService.java deleted file mode 100644 index ab679c4..0000000 --- a/src/main/kotlin/com/beat_it/team/service/TeamService.java +++ /dev/null @@ -1,4 +0,0 @@ -package com.beat_it.team.service; - -public class TeamService { -} diff --git a/src/main/kotlin/com/beat_it/team/service/TeamService.kt b/src/main/kotlin/com/beat_it/team/service/TeamService.kt new file mode 100644 index 0000000..b61ca39 --- /dev/null +++ b/src/main/kotlin/com/beat_it/team/service/TeamService.kt @@ -0,0 +1,183 @@ +package com.beat_it.team.service + +import com.beat_it.cal.dto.ScheduleUpdateRequest +import com.beat_it.cal.entity.Schedule +import com.beat_it.global.error.BusinessException +import com.beat_it.global.error.ErrorCode +import com.beat_it.team.dto.TeamCreateRequest +import com.beat_it.team.dto.TeamCreateResponse +import com.beat_it.team.dto.TeamDetailResponse +import com.beat_it.team.dto.TeamDetailUpdateRequest +import com.beat_it.team.dto.TeamDetailUpdateResponse +import com.beat_it.team.entity.Teams +import com.beat_it.team.repository.TeamRepository +import org.springframework.stereotype.Service +import org.springframework.transaction.annotation.Transactional +import java.util.UUID + +@Service +class TeamService( + private val teamRepository: TeamRepository +) { + + @Transactional + fun createTeam(request: TeamCreateRequest): TeamCreateResponse { + validateCreateRequest(request) + + val inviteCode = generateInviteCode() + + val team = Teams( + teamName = request.teamName, + description = request.description, + teamType = request.teamType, + establishedOn = request.establishedOn, + inviteCode = inviteCode + ) + + val savedTeam = teamRepository.save(team) + + // TODO: 팀 생성자를 TeamMember에 LEADER로 저장해야 함 + // 현재 createTeam 함수에 userId가 없기 때문에, 나중에 Controller에서 userId를 넘겨받는 구조가 필요함 + + return TeamCreateResponse( + teamId = savedTeam.teamId!!, + teamName = savedTeam.teamName, + description = savedTeam.description, + inviteCode = savedTeam.inviteCode, + teamType = savedTeam.teamType, + teamRole = "LEADER", + createdAt = savedTeam.createdAt + ) + } + + @Transactional + fun updateTeamDetail( + teamId: Long, + userId: Long, + request: TeamDetailUpdateRequest + ): TeamDetailUpdateResponse { + val team = findTeamOrThrow(teamId) + + validateTeamUpdatePermission(teamId, userId) + + if (isNotChanged(team, request)) { + throw BusinessException(ErrorCode.TEAM_NO_CONTENT_TO_UPDATE) + } + + validateUpdateRequest(request) + + team.updateTeamDetail( + teamName = request.teamName, + description = request.description, + establishedOn = request.establishedOn, + teamType = team.teamType, + + ) + + // TODO: profileImageFileId가 있다면 파일 존재 여부 검증 후 연결 + // TODO: links가 있다면 TeamLinks 엔티티 저장/수정 + + return TeamDetailUpdateResponse( + teamId = team.teamId!!, + teamName = team.teamName, + description = team.description, + establishedOn = team.establishedOn, + updatedAt = team.updatedAt + ) + } + + @Transactional + fun deleteTeam( + teamId: Long, + userId: Long + ) { + val team = findTeamOrThrow(teamId) + + validateTeamDeletePermission(teamId, userId) + + team.deleteTeam() + } + + @Transactional(readOnly = true) + fun getTeamDetail(teamId: Long): TeamDetailResponse { + val team = findTeamOrThrow(teamId) + + return TeamDetailResponse( + teamId = team.teamId, + profileImageUrl = team.profileImageUrl, + teamName = team.teamName, + description = team.description, + establishedOn = team.establishedOn, + inviteCode = team.inviteCode, + memberCount = 0, + createdAt = team.createdAt, + updatedAt = team.updatedAt, + links = emptyList(), + parts = emptyList(), + archiveCount = 0, + cloudItemCount = 0 + ) + } + + private fun validateCreateRequest(request: TeamCreateRequest) { + if (request.teamName.isNullOrBlank()) { + throw BusinessException(ErrorCode.TEAM_NAME_REQUIRED) + } + + if (request.teamName.length > 100) { + throw BusinessException(ErrorCode.TEAM_NAME_TOO_LONG) + } + + if ((request.description?.length ?: 0) > 500) { + throw BusinessException(ErrorCode.TEAM_DESCRIPTION_TOO_LONG) + } + } + + private fun validateUpdateRequest(request: TeamDetailUpdateRequest) { + if ((request.teamName?.length ?: 0) > 100) { + throw BusinessException(ErrorCode.TEAM_NAME_TOO_LONG) + } + + if ((request.description?.length ?: 0) > 500) { + throw BusinessException(ErrorCode.TEAM_DESCRIPTION_TOO_LONG) + } + } + + + private fun isNotChanged(team: Teams, request: TeamDetailUpdateRequest): Boolean { + val isAnyFieldChanged = + (request.teamName != null && request.teamName != team.teamName) || + (request.description != null && request.description != team.description) || + (request.establishedOn != null && request.establishedOn != team.establishedOn) + (request.establishedOn != null && request.establishedOn != team.establishedOn) + + return !(isAnyFieldChanged) + } + + private fun findTeamOrThrow(teamId: Long): Teams { + return teamRepository.findByTeamIdAndDeletedAtIsNull(teamId) + ?: throw BusinessException(ErrorCode.TEAM_NOT_FOUND) + } + + private fun validateTeamUpdatePermission(teamId: Long, userId: Long) { + // TODO: TeamMemberRepository가 생기면 여기서 LEADER 또는 MANAGER인지 확인 + // val member = teamMemberRepository.findByTeamIdAndUserId(teamId, userId) + // if (member.role != TeamRole.LEADER && member.role != TeamRole.MANAGER) { + // throw BusinessException(ErrorCode.TEAM_NO_PERMISSION) + // } + } + + private fun validateTeamDeletePermission(teamId: Long, userId: Long) { + // TODO: 팀 삭제 권한 검증 + // 보통 LEADER만 삭제 가능하게 처리 >> API 명세 수정할 것. + } + + private fun generateInviteCode(): String { + // TODO: 팀 초대코드 생성법 고안 필요 + return "BEATIT-" + UUID.randomUUID() + .toString() + .replace("-", "") + .take(6) + .uppercase() + } +} \ No newline at end of file From cf36c27a08f3b274b9af91933284cf4f74567661 Mon Sep 17 00:00:00 2001 From: EunHaSong Date: Sat, 23 May 2026 14:21:43 +0900 Subject: [PATCH 06/26] =?UTF-8?q?fix/#12:=20Controller=EC=97=90=20HttpStat?= =?UTF-8?q?us=20=EA=B0=92=20body=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/beat_it/team/controller/TeamController.kt | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/main/kotlin/com/beat_it/team/controller/TeamController.kt b/src/main/kotlin/com/beat_it/team/controller/TeamController.kt index 1784d70..c7babf4 100644 --- a/src/main/kotlin/com/beat_it/team/controller/TeamController.kt +++ b/src/main/kotlin/com/beat_it/team/controller/TeamController.kt @@ -26,37 +26,37 @@ class TeamController( return ResponseEntity .status(HttpStatus.CREATED) - .body(BasicResponse.success(responseData, "팀 생성에 성공했습니다.")) + .body(BasicResponse.success(responseData, HttpStatus.CREATED, "팀 생성에 성공했습니다.")) } @PatchMapping fun updateTeamDetail( - @RequestHeader("X-USER-ID") teamId: Long, + @RequestHeader("X-TEAM-ID") teamId: Long, @RequestHeader("X-USER-ID") userId: Long, @RequestBody request: TeamDetailUpdateRequest, ): ResponseEntity> { val responseData = teamService.updateTeamDetail(teamId, userId, request) - return ResponseEntity.ok(BasicResponse.success(responseData, "팀 상세 내용이 수정되었습니다.")) + return ResponseEntity.ok(BasicResponse.success(responseData, HttpStatus.OK, "팀 상세 내용이 수정되었습니다.")) } @DeleteMapping fun deleteTeam( - @RequestHeader("X-USER-ID") teamId: Long, + @RequestHeader("X-TEAM-ID") teamId: Long, @RequestHeader("X-USER-ID") userId: Long, ): ResponseEntity> { teamService.deleteTeam(teamId, userId) return ResponseEntity.ok( - BasicResponse.success("팀이 성공적으로 삭제되었습니다.") + BasicResponse.success(HttpStatus.OK,"팀이 성공적으로 삭제되었습니다.") ) } @GetMapping fun getTeamDetail( - @RequestHeader("X-USER-ID") teamId: Long, + @RequestHeader("X-TEAM-ID") teamId: Long, ): ResponseEntity> { val responseData = teamService.getTeamDetail(teamId) return ResponseEntity.ok( - BasicResponse.success(responseData, "팀 상세 내용 조회에 성공했습니다.") + BasicResponse.success(responseData, HttpStatus.OK,"팀 상세 내용 조회에 성공했습니다.") ) } } From ecb0434b236ff992955547cf7628318c2f670e58 Mon Sep 17 00:00:00 2001 From: EunHaSong Date: Sat, 23 May 2026 14:24:39 +0900 Subject: [PATCH 07/26] =?UTF-8?q?fix/#12:=20db=20=EC=A0=80=EC=9E=A5=20?= =?UTF-8?q?=EC=9D=B4=EB=A6=84=20name=20=EC=9E=AC=EC=A7=80=EC=A0=95=20?= =?UTF-8?q?=EB=B0=8F=20profile=20=EC=82=AC=EC=A7=84=20null=EA=B0=92=20?= =?UTF-8?q?=ED=97=88=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/kotlin/com/beat_it/team/entity/Teams.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/kotlin/com/beat_it/team/entity/Teams.kt b/src/main/kotlin/com/beat_it/team/entity/Teams.kt index 0e8c270..609e806 100644 --- a/src/main/kotlin/com/beat_it/team/entity/Teams.kt +++ b/src/main/kotlin/com/beat_it/team/entity/Teams.kt @@ -18,10 +18,10 @@ class Teams( @Column(name = "public_id", nullable = false, unique = true) val publicId: UUID = UUID.randomUUID(), - @Column(name = "profile_image_url", nullable = false) + @Column(name = "profile_image_url", nullable = true) var profileImageUrl: String? = null, - @Column(name = "team_name", nullable = false) + @Column(name = "name", nullable = false) var teamName: String, @Column(name = "description", nullable = true) From a41abec6e1c744c77f5b93d1bd1f5d23c4abeb02 Mon Sep 17 00:00:00 2001 From: EunHaSong Date: Sat, 23 May 2026 14:25:41 +0900 Subject: [PATCH 08/26] =?UTF-8?q?fix/#12:=20BaseUpdatedTimeEntity=EB=A1=9C?= =?UTF-8?q?=20createdAt,=20updatedAt=20=EB=8F=99=EC=8B=9C=20=EC=A7=80?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/kotlin/com/beat_it/team/entity/Teams.kt | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/main/kotlin/com/beat_it/team/entity/Teams.kt b/src/main/kotlin/com/beat_it/team/entity/Teams.kt index 609e806..bfcd9d3 100644 --- a/src/main/kotlin/com/beat_it/team/entity/Teams.kt +++ b/src/main/kotlin/com/beat_it/team/entity/Teams.kt @@ -1,6 +1,5 @@ package com.beat_it.team.entity - -import com.beat_it.global.entity.BaseTimeEntity +import com.beat_it.global.entity.BaseUpdatedTimeEntity import com.beat_it.team.entity.enum.TeamType import jakarta.persistence.* import java.time.LocalDate @@ -40,7 +39,7 @@ class Teams( @Column(name = "deleted_at", nullable = true) var deletedAt: OffsetDateTime? = null, -) : BaseTimeEntity() { +) : BaseUpdatedTimeEntity() { fun updateTeamDetail ( teamName: String, From 44db48487aaed1205766447020201129e85adc69 Mon Sep 17 00:00:00 2001 From: EunHaSong Date: Sat, 23 May 2026 14:30:31 +0900 Subject: [PATCH 09/26] =?UTF-8?q?test/#12:=20team=20=EA=B4=80=EB=A0=A8=20A?= =?UTF-8?q?PI=20=ED=85=8C=EC=8A=A4=ED=8A=B8=EB=A5=BC=20=EC=9C=84=ED=95=9C?= =?UTF-8?q?=20=EC=9E=84=EC=8B=9C=EC=A0=81=20=EC=84=9C=EB=B2=84=20=EC=A0=91?= =?UTF-8?q?=EA=B7=BC=20=ED=97=88=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/kotlin/com/beat_it/global/config/SecurityConfig.kt | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/kotlin/com/beat_it/global/config/SecurityConfig.kt b/src/main/kotlin/com/beat_it/global/config/SecurityConfig.kt index e2d5945..0161a30 100644 --- a/src/main/kotlin/com/beat_it/global/config/SecurityConfig.kt +++ b/src/main/kotlin/com/beat_it/global/config/SecurityConfig.kt @@ -30,6 +30,7 @@ class SecurityConfig( .authorizeHttpRequests { auth -> auth .requestMatchers("/auth/**").permitAll() + .requestMatchers("/teams/**").permitAll() .requestMatchers("/swagger-ui/**", "/v3/api-docs/**").permitAll() .anyRequest().authenticated() } From 9a5fa603614f1ab11a05939e182cebea0ff32436 Mon Sep 17 00:00:00 2001 From: EunHaSong Date: Mon, 25 May 2026 02:35:13 +0900 Subject: [PATCH 10/26] =?UTF-8?q?style/#12:=20team=5Fname=20>=20name?= =?UTF-8?q?=EC=9C=BC=EB=A1=9C=20=EC=A7=80=EB=AA=85=20=ED=95=A8=EC=88=98=20?= =?UTF-8?q?=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/beat_it/team/controller/TeamController.kt | 1 + .../com/beat_it/team/dto/TeamCreateRequest.kt | 1 + .../com/beat_it/team/dto/TeamCreateResponse.kt | 2 +- .../com/beat_it/team/dto/TeamDetailResponse.kt | 2 +- .../beat_it/team/dto/TeamDetailUpdateRequest.kt | 2 +- .../beat_it/team/dto/TeamDetailUpdateResponse.kt | 2 +- .../com/beat_it/team/entity/TeamMemberships.kt | 14 ++++++-------- 7 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/main/kotlin/com/beat_it/team/controller/TeamController.kt b/src/main/kotlin/com/beat_it/team/controller/TeamController.kt index c7babf4..2439394 100644 --- a/src/main/kotlin/com/beat_it/team/controller/TeamController.kt +++ b/src/main/kotlin/com/beat_it/team/controller/TeamController.kt @@ -19,6 +19,7 @@ class TeamController( @PostMapping fun createTeam( + @RequestHeader("X-USER-ID") userId: Long, @RequestBody request: TeamCreateRequest ): ResponseEntity> { diff --git a/src/main/kotlin/com/beat_it/team/dto/TeamCreateRequest.kt b/src/main/kotlin/com/beat_it/team/dto/TeamCreateRequest.kt index 64549ae..770cad4 100644 --- a/src/main/kotlin/com/beat_it/team/dto/TeamCreateRequest.kt +++ b/src/main/kotlin/com/beat_it/team/dto/TeamCreateRequest.kt @@ -6,6 +6,7 @@ import java.time.LocalDate import java.time.OffsetDateTime data class TeamCreateRequest( + @JsonProperty("name") val teamName: String, val description: String?, diff --git a/src/main/kotlin/com/beat_it/team/dto/TeamCreateResponse.kt b/src/main/kotlin/com/beat_it/team/dto/TeamCreateResponse.kt index af29f0e..823070c 100644 --- a/src/main/kotlin/com/beat_it/team/dto/TeamCreateResponse.kt +++ b/src/main/kotlin/com/beat_it/team/dto/TeamCreateResponse.kt @@ -8,7 +8,7 @@ data class TeamCreateResponse( @JsonProperty("team_id") val teamId: Long, - @JsonProperty("team_name") + @JsonProperty("name") val teamName: String, val description: String?, diff --git a/src/main/kotlin/com/beat_it/team/dto/TeamDetailResponse.kt b/src/main/kotlin/com/beat_it/team/dto/TeamDetailResponse.kt index a15469d..24f219b 100644 --- a/src/main/kotlin/com/beat_it/team/dto/TeamDetailResponse.kt +++ b/src/main/kotlin/com/beat_it/team/dto/TeamDetailResponse.kt @@ -7,7 +7,7 @@ import java.time.OffsetDateTime data class TeamDetailResponse( @JsonProperty("team_id") val teamId: Long? = null, @JsonProperty("profile_image_url") val profileImageUrl: String?, - @JsonProperty("team_name") val teamName: String, + @JsonProperty("name") val teamName: String, val description: String?, @JsonProperty("established_on") val establishedOn: LocalDate?, @JsonProperty("invite_code") val inviteCode: String, diff --git a/src/main/kotlin/com/beat_it/team/dto/TeamDetailUpdateRequest.kt b/src/main/kotlin/com/beat_it/team/dto/TeamDetailUpdateRequest.kt index f68bda4..8646d8c 100644 --- a/src/main/kotlin/com/beat_it/team/dto/TeamDetailUpdateRequest.kt +++ b/src/main/kotlin/com/beat_it/team/dto/TeamDetailUpdateRequest.kt @@ -5,7 +5,7 @@ import java.time.LocalDate import java.time.OffsetDateTime data class TeamDetailUpdateRequest( - @JsonProperty("team_name") + @JsonProperty("name") val teamName: String, val description: String?, diff --git a/src/main/kotlin/com/beat_it/team/dto/TeamDetailUpdateResponse.kt b/src/main/kotlin/com/beat_it/team/dto/TeamDetailUpdateResponse.kt index 09bc697..4352854 100644 --- a/src/main/kotlin/com/beat_it/team/dto/TeamDetailUpdateResponse.kt +++ b/src/main/kotlin/com/beat_it/team/dto/TeamDetailUpdateResponse.kt @@ -8,7 +8,7 @@ data class TeamDetailUpdateResponse( @JsonProperty("team_id") val teamId: Long, - @JsonProperty("team_name") + @JsonProperty("name") val teamName: String, val description: String?, diff --git a/src/main/kotlin/com/beat_it/team/entity/TeamMemberships.kt b/src/main/kotlin/com/beat_it/team/entity/TeamMemberships.kt index 9750663..eb72f8a 100644 --- a/src/main/kotlin/com/beat_it/team/entity/TeamMemberships.kt +++ b/src/main/kotlin/com/beat_it/team/entity/TeamMemberships.kt @@ -1,5 +1,6 @@ package com.beat_it.team.entity +import com.beat_it.global.entity.BaseUpdatedTimeEntity import com.beat_it.team.entity.enum.TeamRole import jakarta.persistence.* import java.time.OffsetDateTime @@ -13,20 +14,17 @@ class TeamMemberships( val teamMembershipId: Long, //TODO: 팀 ID 연결하기 - //TODO: 사용자 ID 연결하기 >> 모듈 분리 @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "team_id", nullable = false) val team: Teams, + //TODO: 사용자 ID 연결하기 >> 모듈 분리 + @Column(name="team_role", nullable = false) var teamRole: TeamRole = TeamRole.MEMBER, - @Column(name="update_at", nullable = false) - var updateAt: OffsetDateTime = OffsetDateTime.now(), - - @Column(name="create_at", nullable = false) - val createdAt: OffsetDateTime = OffsetDateTime.now(), - @Column(name="left_at", nullable = true) var leftAt: OffsetDateTime? = null, -) \ No newline at end of file +) : BaseUpdatedTimeEntity() { + // TODO: 팀 권한 설정 함수 만들기 +} \ No newline at end of file From d94bc049b94e1e7484ba273e436b3ba3e6de3b5d Mon Sep 17 00:00:00 2001 From: EunHaSong Date: Mon, 25 May 2026 02:36:48 +0900 Subject: [PATCH 11/26] =?UTF-8?q?style/#12:=20BaseUpdatedTimeEntity()=20?= =?UTF-8?q?=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../kotlin/com/beat_it/team/entity/TeamLinks.kt | 14 +++++++------- .../kotlin/com/beat_it/team/entity/TeamParts.kt | 15 +++++++++------ .../com/beat_it/team/service/TeamService.kt | 8 +++++--- 3 files changed, 21 insertions(+), 16 deletions(-) diff --git a/src/main/kotlin/com/beat_it/team/entity/TeamLinks.kt b/src/main/kotlin/com/beat_it/team/entity/TeamLinks.kt index bd4386f..94246d2 100644 --- a/src/main/kotlin/com/beat_it/team/entity/TeamLinks.kt +++ b/src/main/kotlin/com/beat_it/team/entity/TeamLinks.kt @@ -1,5 +1,6 @@ package com.beat_it.team.entity +import com.beat_it.global.entity.BaseUpdatedTimeEntity import com.beat_it.team.entity.enum.PlatformCode import com.beat_it.team.entity.enum.TeamRole import jakarta.persistence.* @@ -28,11 +29,10 @@ class TeamLinks( @Column(name="link_url",nullable = false) var linkUrl: String = "", - @Column(name="update_at",nullable = false) - var updateAt: OffsetDateTime = OffsetDateTime.now(), +// @Column(name="update_at",nullable = false) +// var updateAt: OffsetDateTime = OffsetDateTime.now(), +// +// @Column(name="create_at",nullable = false) +// val createdAt: OffsetDateTime = OffsetDateTime.now(), - @Column(name="create_at",nullable = false) - val createdAt: OffsetDateTime = OffsetDateTime.now(), - - ) -// ) : BaseTime \ No newline at end of file +) : BaseUpdatedTimeEntity() \ No newline at end of file diff --git a/src/main/kotlin/com/beat_it/team/entity/TeamParts.kt b/src/main/kotlin/com/beat_it/team/entity/TeamParts.kt index 9f00b11..8baf1d6 100644 --- a/src/main/kotlin/com/beat_it/team/entity/TeamParts.kt +++ b/src/main/kotlin/com/beat_it/team/entity/TeamParts.kt @@ -1,5 +1,6 @@ package com.beat_it.team.entity +import com.beat_it.global.entity.BaseUpdatedTimeEntity import com.beat_it.team.entity.enum.TeamRole import jakarta.persistence.* import java.time.OffsetDateTime @@ -26,10 +27,12 @@ class TeamParts( @Column(name="is_active", nullable = false) var isActive: Boolean = true, - @Column(name="update_at", nullable = false) - var updateAt: OffsetDateTime = OffsetDateTime.now(), +// @Column(name="update_at", nullable = false) +// var updateAt: OffsetDateTime = OffsetDateTime.now(), +// +// @Column(name="create_at", nullable = false) +// val createdAt: OffsetDateTime = OffsetDateTime.now(), - @Column(name="create_at", nullable = false) - val createdAt: OffsetDateTime = OffsetDateTime.now(), - - ) \ No newline at end of file + ) : BaseUpdatedTimeEntity() { + // TODO: 파트를 추가하는 함수를 넣어야 함. +} \ No newline at end of file diff --git a/src/main/kotlin/com/beat_it/team/service/TeamService.kt b/src/main/kotlin/com/beat_it/team/service/TeamService.kt index b61ca39..5867cc2 100644 --- a/src/main/kotlin/com/beat_it/team/service/TeamService.kt +++ b/src/main/kotlin/com/beat_it/team/service/TeamService.kt @@ -120,7 +120,7 @@ class TeamService( } private fun validateCreateRequest(request: TeamCreateRequest) { - if (request.teamName.isNullOrBlank()) { + if (request.teamName.isBlank()) { throw BusinessException(ErrorCode.TEAM_NAME_REQUIRED) } @@ -146,10 +146,11 @@ class TeamService( private fun isNotChanged(team: Teams, request: TeamDetailUpdateRequest): Boolean { val isAnyFieldChanged = - (request.teamName != null && request.teamName != team.teamName) || + (request.teamName != team.teamName) || (request.description != null && request.description != team.description) || (request.establishedOn != null && request.establishedOn != team.establishedOn) - (request.establishedOn != null && request.establishedOn != team.establishedOn) + (request.profileImageUrl != null && request.profileImageUrl != team.profileImageUrl) + // (request.links != null && request.links != team.links) return !(isAnyFieldChanged) } @@ -174,6 +175,7 @@ class TeamService( private fun generateInviteCode(): String { // TODO: 팀 초대코드 생성법 고안 필요 + // TODO: Redis로 초대코드를 구성하는 블로그 참고하기 return "BEATIT-" + UUID.randomUUID() .toString() .replace("-", "") From c2c7c25a2d39654ff67330cf15e6ca2516bd5173 Mon Sep 17 00:00:00 2001 From: EunHaSong Date: Mon, 25 May 2026 02:59:43 +0900 Subject: [PATCH 12/26] =?UTF-8?q?style/#12:=20entity=20id=20=EC=88=98?= =?UTF-8?q?=EC=A0=95=20=EB=B0=8F=20update/delete=20=ED=95=A8=EC=88=98=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../kotlin/com/beat_it/team/entity/TeamLinks.kt | 10 ++++++++-- .../com/beat_it/team/entity/TeamMemberships.kt | 10 +++++++++- .../kotlin/com/beat_it/team/entity/TeamParts.kt | 14 +++++++++++++- .../kotlin/com/beat_it/team/entity/TeamSettings.kt | 2 +- 4 files changed, 31 insertions(+), 5 deletions(-) diff --git a/src/main/kotlin/com/beat_it/team/entity/TeamLinks.kt b/src/main/kotlin/com/beat_it/team/entity/TeamLinks.kt index 94246d2..e909529 100644 --- a/src/main/kotlin/com/beat_it/team/entity/TeamLinks.kt +++ b/src/main/kotlin/com/beat_it/team/entity/TeamLinks.kt @@ -3,6 +3,7 @@ package com.beat_it.team.entity import com.beat_it.global.entity.BaseUpdatedTimeEntity import com.beat_it.team.entity.enum.PlatformCode import com.beat_it.team.entity.enum.TeamRole +import io.swagger.v3.oas.annotations.links.Link import jakarta.persistence.* import java.time.OffsetDateTime @@ -12,7 +13,7 @@ class TeamLinks( @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name="team_link_id", nullable = false) - val teamLinkId: Long, + val teamLinkId: Long? = null, //TODO: 팀 ID 연결하기 @ManyToOne(fetch = FetchType.LAZY) @@ -35,4 +36,9 @@ class TeamLinks( // @Column(name="create_at",nullable = false) // val createdAt: OffsetDateTime = OffsetDateTime.now(), -) : BaseUpdatedTimeEntity() \ No newline at end of file +) : BaseUpdatedTimeEntity() { + fun updateLink(platformCode: PlatformCode, linkUrl: String) { + this.platformCode = platformCode + this.linkUrl = linkUrl + } +} \ No newline at end of file diff --git a/src/main/kotlin/com/beat_it/team/entity/TeamMemberships.kt b/src/main/kotlin/com/beat_it/team/entity/TeamMemberships.kt index eb72f8a..8258325 100644 --- a/src/main/kotlin/com/beat_it/team/entity/TeamMemberships.kt +++ b/src/main/kotlin/com/beat_it/team/entity/TeamMemberships.kt @@ -11,7 +11,7 @@ class TeamMemberships( @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = "team_membership_id") - val teamMembershipId: Long, + val teamMembershipId: Long? = null, //TODO: 팀 ID 연결하기 @ManyToOne(fetch = FetchType.LAZY) @@ -25,6 +25,14 @@ class TeamMemberships( @Column(name="left_at", nullable = true) var leftAt: OffsetDateTime? = null, + ) : BaseUpdatedTimeEntity() { // TODO: 팀 권한 설정 함수 만들기 + fun updateTeamRole(teamRole: TeamRole) { + this.teamRole = teamRole + } + + fun leaveTeam() { + this.leftAt = OffsetDateTime.now() + } } \ No newline at end of file diff --git a/src/main/kotlin/com/beat_it/team/entity/TeamParts.kt b/src/main/kotlin/com/beat_it/team/entity/TeamParts.kt index 8baf1d6..4aa5e94 100644 --- a/src/main/kotlin/com/beat_it/team/entity/TeamParts.kt +++ b/src/main/kotlin/com/beat_it/team/entity/TeamParts.kt @@ -11,7 +11,7 @@ class TeamParts( @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name="team_part_id", nullable = false) - val teamPartId: Long, + val teamPartId: Long? = null, //TODO: 팀 ID 연결하기 @ManyToOne(fetch = FetchType.LAZY) @@ -35,4 +35,16 @@ class TeamParts( ) : BaseUpdatedTimeEntity() { // TODO: 파트를 추가하는 함수를 넣어야 함. + fun updateTeamPart( + partName: String, + displayOrder: Int, + ) { + this.partName = partName + this.displayOrder = displayOrder + } + + fun deactivateTeamPart() { + this.isActive = false + } + } \ No newline at end of file diff --git a/src/main/kotlin/com/beat_it/team/entity/TeamSettings.kt b/src/main/kotlin/com/beat_it/team/entity/TeamSettings.kt index 2db0f67..a82c891 100644 --- a/src/main/kotlin/com/beat_it/team/entity/TeamSettings.kt +++ b/src/main/kotlin/com/beat_it/team/entity/TeamSettings.kt @@ -9,7 +9,7 @@ class TeamSettings( @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name="team_settings_id") - val teamSettingId: Long, + val teamSettingId: Long? = null, //TODO: 팀 ID 연결하기 @ManyToOne(fetch = FetchType.LAZY) From bea7734c8bb403ac487d9134dcb643c193aa5da2 Mon Sep 17 00:00:00 2001 From: EunHaSong Date: Mon, 25 May 2026 03:00:40 +0900 Subject: [PATCH 13/26] =?UTF-8?q?feat/#12:=20=ED=8C=80=EB=A7=88=EB=8B=A4?= =?UTF-8?q?=20=EA=B6=8C=ED=95=9C/=ED=8C=8C=ED=8A=B8/=EB=A7=81=ED=81=AC=20?= =?UTF-8?q?=EC=A0=91=EA=B7=BC=20Repository=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../team/repository/TeamLinksRepository.kt | 14 ++++++++++++++ .../team/repository/TeamMembershipRepository.kt | 15 +++++++++++++++ .../team/repository/TeamPartsRepository.kt | 14 ++++++++++++++ 3 files changed, 43 insertions(+) create mode 100644 src/main/kotlin/com/beat_it/team/repository/TeamLinksRepository.kt create mode 100644 src/main/kotlin/com/beat_it/team/repository/TeamMembershipRepository.kt create mode 100644 src/main/kotlin/com/beat_it/team/repository/TeamPartsRepository.kt diff --git a/src/main/kotlin/com/beat_it/team/repository/TeamLinksRepository.kt b/src/main/kotlin/com/beat_it/team/repository/TeamLinksRepository.kt new file mode 100644 index 0000000..533c6bf --- /dev/null +++ b/src/main/kotlin/com/beat_it/team/repository/TeamLinksRepository.kt @@ -0,0 +1,14 @@ +package com.beat_it.team.repository + +import com.beat_it.team.entity.TeamLinks +import org.springframework.data.jpa.repository.JpaRepository + +interface TeamLinksRepository : JpaRepository { + + fun findAllByTeamId( + teamId: Long, + ): List + + fun deleteAllByTeamId(teamId: Long) + +} \ No newline at end of file diff --git a/src/main/kotlin/com/beat_it/team/repository/TeamMembershipRepository.kt b/src/main/kotlin/com/beat_it/team/repository/TeamMembershipRepository.kt new file mode 100644 index 0000000..010e082 --- /dev/null +++ b/src/main/kotlin/com/beat_it/team/repository/TeamMembershipRepository.kt @@ -0,0 +1,15 @@ +package com.beat_it.team.repository + +import com.beat_it.team.entity.TeamMemberships +import org.springframework.data.jpa.repository.JpaRepository + +interface TeamMembershipRepository : JpaRepository { + + fun findByTeamIdAndUserIdAndLeaftAtIsNull( + teamId: Long, + userId: Long, + ): TeamMemberships? + + fun countByTeamIdAndLeftAtIsNull(teamId: Long): Int + +} \ No newline at end of file diff --git a/src/main/kotlin/com/beat_it/team/repository/TeamPartsRepository.kt b/src/main/kotlin/com/beat_it/team/repository/TeamPartsRepository.kt new file mode 100644 index 0000000..b7cd2b5 --- /dev/null +++ b/src/main/kotlin/com/beat_it/team/repository/TeamPartsRepository.kt @@ -0,0 +1,14 @@ +package com.beat_it.team.repository + +import com.beat_it.team.entity.TeamParts +import org.springframework.data.jpa.repository.JpaRepository + +interface TeamPartsRepository : JpaRepository { + + fun findAllByTeamId( + teamId: Long, + ): List + + fun deleteAllByTeamId(teamId: Long) + +} \ No newline at end of file From 3475cffdc9b6bfb8b0047987cc26d9bda9548800 Mon Sep 17 00:00:00 2001 From: EunHaSong Date: Mon, 25 May 2026 04:07:44 +0900 Subject: [PATCH 14/26] =?UTF-8?q?style/#12:=20ENUM=20MANAGER=20=EC=98=A4?= =?UTF-8?q?=ED=83=80=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/kotlin/com/beat_it/team/entity/enum/TeamRole.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/kotlin/com/beat_it/team/entity/enum/TeamRole.kt b/src/main/kotlin/com/beat_it/team/entity/enum/TeamRole.kt index ce6147b..b2861ef 100644 --- a/src/main/kotlin/com/beat_it/team/entity/enum/TeamRole.kt +++ b/src/main/kotlin/com/beat_it/team/entity/enum/TeamRole.kt @@ -2,7 +2,7 @@ package com.beat_it.team.entity.enum enum class TeamRole(val description : String) { LEADER("대표"), - MENAGER("운영진"), + MANAGER("운영진"), MEMBER("팀원"); } From 05ff93b92623c460bbef5808244c221b172694a6 Mon Sep 17 00:00:00 2001 From: EunHaSong Date: Mon, 25 May 2026 04:08:57 +0900 Subject: [PATCH 15/26] =?UTF-8?q?feat/#12:=20=ED=8C=80=20=EC=9C=A0?= =?UTF-8?q?=EC=A0=80=20ID=20=EC=9E=84=EC=8B=9C=20=EC=97=B0=EA=B2=B0=20(?= =?UTF-8?q?=EC=9D=B4=ED=9B=84,=20=EB=AA=A8=EB=93=88=20=EC=88=98=EC=A0=95?= =?UTF-8?q?=20=ED=95=84=EC=9A=94)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/beat_it/team/controller/TeamController.kt | 2 +- .../kotlin/com/beat_it/team/entity/TeamMemberships.kt | 11 +++++++---- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/src/main/kotlin/com/beat_it/team/controller/TeamController.kt b/src/main/kotlin/com/beat_it/team/controller/TeamController.kt index 2439394..4711c2d 100644 --- a/src/main/kotlin/com/beat_it/team/controller/TeamController.kt +++ b/src/main/kotlin/com/beat_it/team/controller/TeamController.kt @@ -23,7 +23,7 @@ class TeamController( @RequestBody request: TeamCreateRequest ): ResponseEntity> { - val responseData = teamService.createTeam(request) + val responseData = teamService.createTeam(userId, request) return ResponseEntity .status(HttpStatus.CREATED) diff --git a/src/main/kotlin/com/beat_it/team/entity/TeamMemberships.kt b/src/main/kotlin/com/beat_it/team/entity/TeamMemberships.kt index 8258325..78afc53 100644 --- a/src/main/kotlin/com/beat_it/team/entity/TeamMemberships.kt +++ b/src/main/kotlin/com/beat_it/team/entity/TeamMemberships.kt @@ -18,15 +18,18 @@ class TeamMemberships( @JoinColumn(name = "team_id", nullable = false) val team: Teams, - //TODO: 사용자 ID 연결하기 >> 모듈 분리 + //TODO: 사용자 ID 임시 연결 - User 모듈과 연결 시 지우거나 수정 필요 + @Column(name = "user_id", nullable = false) + val userId: Long? = null, - @Column(name="team_role", nullable = false) + @Column(name = "team_role", nullable = false) var teamRole: TeamRole = TeamRole.MEMBER, - @Column(name="left_at", nullable = true) + @Column(name = "left_at", nullable = true) var leftAt: OffsetDateTime? = null, + userid: Long, -) : BaseUpdatedTimeEntity() { + ) : BaseUpdatedTimeEntity() { // TODO: 팀 권한 설정 함수 만들기 fun updateTeamRole(teamRole: TeamRole) { this.teamRole = teamRole From 67a4b98634c725eb70f196e6b0931c66ff1acca9 Mon Sep 17 00:00:00 2001 From: EunHaSong Date: Mon, 25 May 2026 04:11:51 +0900 Subject: [PATCH 16/26] =?UTF-8?q?feat/#12:=20=ED=8C=80=20=EA=B6=8C?= =?UTF-8?q?=ED=95=9C=EC=97=90=20=EB=94=B0=EB=9D=BC=20=EC=82=AD=EC=A0=9C=20?= =?UTF-8?q?=EB=B0=8F=20=EC=88=98=EC=A0=95=20=ED=83=80=EB=8B=B9=EC=84=B1=20?= =?UTF-8?q?=EA=B2=80=EC=A6=9D=20=EB=A1=9C=EC=A7=81=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/beat_it/team/service/TeamService.kt | 34 ++++++++++++++----- 1 file changed, 25 insertions(+), 9 deletions(-) diff --git a/src/main/kotlin/com/beat_it/team/service/TeamService.kt b/src/main/kotlin/com/beat_it/team/service/TeamService.kt index 5867cc2..e65fb05 100644 --- a/src/main/kotlin/com/beat_it/team/service/TeamService.kt +++ b/src/main/kotlin/com/beat_it/team/service/TeamService.kt @@ -1,7 +1,5 @@ package com.beat_it.team.service -import com.beat_it.cal.dto.ScheduleUpdateRequest -import com.beat_it.cal.entity.Schedule import com.beat_it.global.error.BusinessException import com.beat_it.global.error.ErrorCode import com.beat_it.team.dto.TeamCreateRequest @@ -9,7 +7,12 @@ import com.beat_it.team.dto.TeamCreateResponse import com.beat_it.team.dto.TeamDetailResponse import com.beat_it.team.dto.TeamDetailUpdateRequest import com.beat_it.team.dto.TeamDetailUpdateResponse +import com.beat_it.team.entity.TeamMemberships import com.beat_it.team.entity.Teams +import com.beat_it.team.entity.enum.TeamRole +import com.beat_it.team.repository.TeamLinksRepository +import com.beat_it.team.repository.TeamMembershipRepository +import com.beat_it.team.repository.TeamPartsRepository import com.beat_it.team.repository.TeamRepository import org.springframework.stereotype.Service import org.springframework.transaction.annotation.Transactional @@ -17,11 +20,14 @@ import java.util.UUID @Service class TeamService( - private val teamRepository: TeamRepository + private val teamRepository: TeamRepository, + private val teamLinksRepository: TeamLinksRepository, + private val teamPartsRepository: TeamPartsRepository, + private val teamMembershipRepository: TeamMembershipRepository, ) { @Transactional - fun createTeam(request: TeamCreateRequest): TeamCreateResponse { + fun createTeam(userid: Long, request: TeamCreateRequest): TeamCreateResponse { validateCreateRequest(request) val inviteCode = generateInviteCode() @@ -38,6 +44,13 @@ class TeamService( // TODO: 팀 생성자를 TeamMember에 LEADER로 저장해야 함 // 현재 createTeam 함수에 userId가 없기 때문에, 나중에 Controller에서 userId를 넘겨받는 구조가 필요함 + val leaderTeamMemberships = TeamMemberships( + team = savedTeam, + userid = userid, + teamRole = TeamRole.LEADER, + ) + + teamMembershipRepository.save(leaderTeamMemberships) return TeamCreateResponse( teamId = savedTeam.teamId!!, @@ -162,15 +175,18 @@ class TeamService( private fun validateTeamUpdatePermission(teamId: Long, userId: Long) { // TODO: TeamMemberRepository가 생기면 여기서 LEADER 또는 MANAGER인지 확인 - // val member = teamMemberRepository.findByTeamIdAndUserId(teamId, userId) - // if (member.role != TeamRole.LEADER && member.role != TeamRole.MANAGER) { - // throw BusinessException(ErrorCode.TEAM_NO_PERMISSION) - // } + val membership = teamMembershipRepository.findByTeamIdAndUserIdAndLeaftAtIsNull(teamId, userId) ?: throw BusinessException(ErrorCode.TEAM_NO_PERMISSION) + if (membership.teamRole != TeamRole.LEADER && membership.teamRole != TeamRole.MANAGER) { + throw BusinessException(ErrorCode.TEAM_NO_PERMISSION) + } } private fun validateTeamDeletePermission(teamId: Long, userId: Long) { // TODO: 팀 삭제 권한 검증 - // 보통 LEADER만 삭제 가능하게 처리 >> API 명세 수정할 것. + val membership = teamMembershipRepository.findByTeamIdAndUserIdAndLeaftAtIsNull(teamId, userId) ?: throw BusinessException(ErrorCode.TEAM_NO_PERMISSION) + if (membership.teamRole != TeamRole.LEADER) { + throw BusinessException(ErrorCode.TEAM_NO_PERMISSION) + } } private fun generateInviteCode(): String { From 56ef939bb2a2de175aa6b07d5feb63cda12339bc Mon Sep 17 00:00:00 2001 From: EunHaSong Date: Mon, 25 May 2026 04:21:04 +0900 Subject: [PATCH 17/26] =?UTF-8?q?Feat/#12:=20=ED=8C=80=20=EC=83=81?= =?UTF-8?q?=EC=84=B8=EC=A1=B0=ED=9A=8C=20links,=20parts,=20memberCount=20?= =?UTF-8?q?=ED=99=95=EC=9D=B8=20=EB=A1=9C=EC=A7=81=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../beat_it/team/dto/TeamDetailResponse.kt | 3 +- .../com/beat_it/team/service/TeamService.kt | 30 +++++++++++++++++-- 2 files changed, 29 insertions(+), 4 deletions(-) diff --git a/src/main/kotlin/com/beat_it/team/dto/TeamDetailResponse.kt b/src/main/kotlin/com/beat_it/team/dto/TeamDetailResponse.kt index 24f219b..d865852 100644 --- a/src/main/kotlin/com/beat_it/team/dto/TeamDetailResponse.kt +++ b/src/main/kotlin/com/beat_it/team/dto/TeamDetailResponse.kt @@ -1,5 +1,6 @@ package com.beat_it.team.dto +import com.beat_it.team.entity.enum.PlatformCode import com.fasterxml.jackson.annotation.JsonProperty import java.time.LocalDate import java.time.OffsetDateTime @@ -23,7 +24,7 @@ data class TeamDetailResponse( data class LinksResponse( @JsonProperty("team_link_id") val teamLinkId: Long, - @JsonProperty("plat_form_code") val platFormCode: String, + @JsonProperty("plat_form_code") val platFormCode: PlatformCode, @JsonProperty("link_url") val linkUrl: String, ) diff --git a/src/main/kotlin/com/beat_it/team/service/TeamService.kt b/src/main/kotlin/com/beat_it/team/service/TeamService.kt index e65fb05..710fb73 100644 --- a/src/main/kotlin/com/beat_it/team/service/TeamService.kt +++ b/src/main/kotlin/com/beat_it/team/service/TeamService.kt @@ -2,6 +2,8 @@ package com.beat_it.team.service import com.beat_it.global.error.BusinessException import com.beat_it.global.error.ErrorCode +import com.beat_it.team.dto.LinksResponse +import com.beat_it.team.dto.PartsResponse import com.beat_it.team.dto.TeamCreateRequest import com.beat_it.team.dto.TeamCreateResponse import com.beat_it.team.dto.TeamDetailResponse @@ -115,6 +117,28 @@ class TeamService( fun getTeamDetail(teamId: Long): TeamDetailResponse { val team = findTeamOrThrow(teamId) + val memberCount = teamMembershipRepository.countByTeamIdAndLeftAtIsNull(teamId) + + val links = teamLinksRepository + .findAllByTeamId(teamId) + .map { + LinksResponse( + teamLinkId = it.teamLinkId!!, + platFormCode = it.platformCode, + linkUrl = it.linkUrl, + ) + } + + val parts = teamPartsRepository + .findAllByTeamId(teamId) + .map { + PartsResponse( + teamPartId = it.teamPartId!!, + partName = it.partName, + displayOrder = it.displayOrder, + ) + } + return TeamDetailResponse( teamId = team.teamId, profileImageUrl = team.profileImageUrl, @@ -122,11 +146,11 @@ class TeamService( description = team.description, establishedOn = team.establishedOn, inviteCode = team.inviteCode, - memberCount = 0, + memberCount = memberCount, createdAt = team.createdAt, updatedAt = team.updatedAt, - links = emptyList(), - parts = emptyList(), + links = links, + parts = parts, archiveCount = 0, cloudItemCount = 0 ) From fb28b2b6d12b1671845e5712388ffb219e80b851 Mon Sep 17 00:00:00 2001 From: EunHaSong Date: Mon, 25 May 2026 05:21:14 +0900 Subject: [PATCH 18/26] =?UTF-8?q?feat/#12:=20=ED=8C=80=20=EC=88=98?= =?UTF-8?q?=EC=A0=95=20=EC=8B=9C=20=EB=B3=80=EA=B2=BD=EB=90=9C=20=EC=82=AC?= =?UTF-8?q?=ED=95=AD=20=EB=B0=98=EC=98=81=ED=95=98=EB=8A=94=20=EC=A1=B0?= =?UTF-8?q?=EA=B1=B4=20=EB=A1=9C=EC=A7=81=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../beat_it/team/dto/TeamDetailResponse.kt | 2 +- .../team/dto/TeamDetailUpdateRequest.kt | 19 ++++---- .../com/beat_it/team/entity/TeamLinks.kt | 3 -- .../kotlin/com/beat_it/team/entity/Teams.kt | 14 +++--- .../com/beat_it/team/service/TeamService.kt | 46 ++++++++++++++----- 5 files changed, 53 insertions(+), 31 deletions(-) diff --git a/src/main/kotlin/com/beat_it/team/dto/TeamDetailResponse.kt b/src/main/kotlin/com/beat_it/team/dto/TeamDetailResponse.kt index d865852..c9034b9 100644 --- a/src/main/kotlin/com/beat_it/team/dto/TeamDetailResponse.kt +++ b/src/main/kotlin/com/beat_it/team/dto/TeamDetailResponse.kt @@ -24,7 +24,7 @@ data class TeamDetailResponse( data class LinksResponse( @JsonProperty("team_link_id") val teamLinkId: Long, - @JsonProperty("plat_form_code") val platFormCode: PlatformCode, + @JsonProperty("platform_code") val platFormCode: PlatformCode, @JsonProperty("link_url") val linkUrl: String, ) diff --git a/src/main/kotlin/com/beat_it/team/dto/TeamDetailUpdateRequest.kt b/src/main/kotlin/com/beat_it/team/dto/TeamDetailUpdateRequest.kt index 8646d8c..f829166 100644 --- a/src/main/kotlin/com/beat_it/team/dto/TeamDetailUpdateRequest.kt +++ b/src/main/kotlin/com/beat_it/team/dto/TeamDetailUpdateRequest.kt @@ -1,24 +1,27 @@ package com.beat_it.team.dto +import com.beat_it.team.entity.enum.TeamType import com.fasterxml.jackson.annotation.JsonProperty import java.time.LocalDate import java.time.OffsetDateTime data class TeamDetailUpdateRequest( @JsonProperty("name") - val teamName: String, + val teamName: String? = null, - val description: String?, + val description: String? = null, - @JsonProperty("established_on") val establishedOn: LocalDate?, + val teamType: TeamType? = null, - @JsonProperty("profile_image_url") val profileImageUrl: String?, + @JsonProperty("established_on") val establishedOn: LocalDate? = null, - val links: List = emptyList(), + @JsonProperty("profile_image_url") val profileImageUrl: String? = null, -) + val links: List? = null, -data class LinksRequest( + ) + +data class TeamLinksRequest( + @JsonProperty("platform_code") val platformCode: String, @JsonProperty("link_url") val linkUrl: String, - @JsonProperty("plat_form_code") val platFormCode: String, ) \ No newline at end of file diff --git a/src/main/kotlin/com/beat_it/team/entity/TeamLinks.kt b/src/main/kotlin/com/beat_it/team/entity/TeamLinks.kt index e909529..a65c2e7 100644 --- a/src/main/kotlin/com/beat_it/team/entity/TeamLinks.kt +++ b/src/main/kotlin/com/beat_it/team/entity/TeamLinks.kt @@ -20,9 +20,6 @@ class TeamLinks( @JoinColumn(name = "team_id", nullable = false) val team: Teams, - @Column(name="part_name",nullable = false) - var partName: String = "", - @Enumerated(EnumType.STRING) @Column(name="platform_code",nullable = false) var platformCode: PlatformCode = PlatformCode.CUSTOM, diff --git a/src/main/kotlin/com/beat_it/team/entity/Teams.kt b/src/main/kotlin/com/beat_it/team/entity/Teams.kt index bfcd9d3..6658649 100644 --- a/src/main/kotlin/com/beat_it/team/entity/Teams.kt +++ b/src/main/kotlin/com/beat_it/team/entity/Teams.kt @@ -41,16 +41,16 @@ class Teams( ) : BaseUpdatedTimeEntity() { - fun updateTeamDetail ( - teamName: String, + fun updateTeamDetail( + teamName: String?, description: String?, establishedOn: LocalDate?, - teamType: TeamType, + teamType: TeamType?, ) { - this.teamName = teamName - this.description = description - this.establishedOn = establishedOn - this.teamType = teamType + teamName?.let { this.teamName = it } + description?.let { this.description = it } + establishedOn?.let { this.establishedOn = it } + teamType?.let { this.teamType = it } } diff --git a/src/main/kotlin/com/beat_it/team/service/TeamService.kt b/src/main/kotlin/com/beat_it/team/service/TeamService.kt index 710fb73..7ed0939 100644 --- a/src/main/kotlin/com/beat_it/team/service/TeamService.kt +++ b/src/main/kotlin/com/beat_it/team/service/TeamService.kt @@ -9,6 +9,8 @@ import com.beat_it.team.dto.TeamCreateResponse import com.beat_it.team.dto.TeamDetailResponse import com.beat_it.team.dto.TeamDetailUpdateRequest import com.beat_it.team.dto.TeamDetailUpdateResponse +import com.beat_it.team.dto.TeamLinksRequest +import com.beat_it.team.entity.TeamLinks import com.beat_it.team.entity.TeamMemberships import com.beat_it.team.entity.Teams import com.beat_it.team.entity.enum.TeamRole @@ -72,21 +74,20 @@ class TeamService( request: TeamDetailUpdateRequest ): TeamDetailUpdateResponse { val team = findTeamOrThrow(teamId) + val currentLinks = teamLinksRepository.findAllByTeamId(teamId) validateTeamUpdatePermission(teamId, userId) + validateUpdateRequest(request) - if (isNotChanged(team, request)) { + if (isNotChanged(team, request, currentLinks)) { throw BusinessException(ErrorCode.TEAM_NO_CONTENT_TO_UPDATE) } - validateUpdateRequest(request) - team.updateTeamDetail( teamName = request.teamName, description = request.description, establishedOn = request.establishedOn, teamType = team.teamType, - ) // TODO: profileImageFileId가 있다면 파일 존재 여부 검증 후 연결 @@ -180,16 +181,37 @@ class TeamService( } } - - private fun isNotChanged(team: Teams, request: TeamDetailUpdateRequest): Boolean { + private fun isNotChanged( + team: Teams, + request: TeamDetailUpdateRequest, + currentLinks: List + ): Boolean { val isAnyFieldChanged = - (request.teamName != team.teamName) || - (request.description != null && request.description != team.description) || - (request.establishedOn != null && request.establishedOn != team.establishedOn) - (request.profileImageUrl != null && request.profileImageUrl != team.profileImageUrl) - // (request.links != null && request.links != team.links) + (request.teamName != team.teamName) || + (request.description != null && request.description != team.description) || + (request.establishedOn != null && request.establishedOn != team.establishedOn) || + (request.teamType != null && request.teamType != team.teamType) || + (request.profileImageUrl != null && request.profileImageUrl != team.profileImageUrl) + + val isLinksChanged = + request.links != null && !isLinksSame(currentLinks, request.links) + + return !(isAnyFieldChanged || isLinksChanged) + } + + private fun isLinksSame( + currentLinks: List, + requestLinks: List + ) : Boolean { + val current = currentLinks + .map { it.platformCode to it.linkUrl } + .sortedWith(compareBy({it.first.toString()}, { it.second })) + + val requested = requestLinks + .map { it.platformCode to it.linkUrl } + .sortedWith(compareBy({it.first.toString()}, { it.second })) - return !(isAnyFieldChanged) + return current == requested } private fun findTeamOrThrow(teamId: Long): Teams { From 1381f4f4d1863f07beff60097f765e7c3bfd486b Mon Sep 17 00:00:00 2001 From: EunHaSong Date: Mon, 25 May 2026 20:46:30 +0900 Subject: [PATCH 19/26] =?UTF-8?q?fix/#12:=20JPA=20Repository=20=EC=BD=94?= =?UTF-8?q?=EB=93=9C=20=EB=AC=B8=EC=A0=9C=20=ED=95=B4=EA=B2=B0=EC=9D=84=20?= =?UTF-8?q?=EC=9C=84=ED=95=9C=20Repository/dto=20=EA=B0=84=20=ED=83=80?= =?UTF-8?q?=EC=9E=85=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/beat_it/team/dto/TeamCreateRequest.kt | 3 +- .../beat_it/team/dto/TeamCreateResponse.kt | 18 ++++------ .../team/dto/TeamDetailUpdateRequest.kt | 8 ++--- .../team/dto/TeamDetailUpdateResponse.kt | 7 ++-- .../beat_it/team/entity/TeamMemberships.kt | 9 ++--- .../team/repository/TeamLinksRepository.kt | 7 ++-- .../repository/TeamMembershipRepository.kt | 7 ++-- .../team/repository/TeamPartsRepository.kt | 7 ++-- .../com/beat_it/team/service/TeamService.kt | 35 +++++++++++++------ 9 files changed, 54 insertions(+), 47 deletions(-) diff --git a/src/main/kotlin/com/beat_it/team/dto/TeamCreateRequest.kt b/src/main/kotlin/com/beat_it/team/dto/TeamCreateRequest.kt index 770cad4..944633d 100644 --- a/src/main/kotlin/com/beat_it/team/dto/TeamCreateRequest.kt +++ b/src/main/kotlin/com/beat_it/team/dto/TeamCreateRequest.kt @@ -6,8 +6,7 @@ import java.time.LocalDate import java.time.OffsetDateTime data class TeamCreateRequest( - @JsonProperty("name") - val teamName: String, + @JsonProperty("name") val teamName: String, val description: String?, diff --git a/src/main/kotlin/com/beat_it/team/dto/TeamCreateResponse.kt b/src/main/kotlin/com/beat_it/team/dto/TeamCreateResponse.kt index 823070c..801fdd7 100644 --- a/src/main/kotlin/com/beat_it/team/dto/TeamCreateResponse.kt +++ b/src/main/kotlin/com/beat_it/team/dto/TeamCreateResponse.kt @@ -5,23 +5,17 @@ import com.fasterxml.jackson.annotation.JsonProperty import java.time.OffsetDateTime data class TeamCreateResponse( - @JsonProperty("team_id") - val teamId: Long, + @JsonProperty("team_id") val teamId: Long, - @JsonProperty("name") - val teamName: String, + @JsonProperty("name") val teamName: String, val description: String?, - @JsonProperty("invite_code") - val inviteCode: String, + @JsonProperty("invite_code") val inviteCode: String, - @JsonProperty("team_type") - val teamType: TeamType, + @JsonProperty("team_type") val teamType: TeamType, - @JsonProperty("team_role") - val teamRole: String, + @JsonProperty("team_role") val teamRole: String, - @JsonProperty("created_at") - val createdAt: OffsetDateTime, + @JsonProperty("created_at") val createdAt: OffsetDateTime, ) \ No newline at end of file diff --git a/src/main/kotlin/com/beat_it/team/dto/TeamDetailUpdateRequest.kt b/src/main/kotlin/com/beat_it/team/dto/TeamDetailUpdateRequest.kt index f829166..8132585 100644 --- a/src/main/kotlin/com/beat_it/team/dto/TeamDetailUpdateRequest.kt +++ b/src/main/kotlin/com/beat_it/team/dto/TeamDetailUpdateRequest.kt @@ -1,17 +1,17 @@ package com.beat_it.team.dto +import com.beat_it.team.entity.enum.PlatformCode import com.beat_it.team.entity.enum.TeamType import com.fasterxml.jackson.annotation.JsonProperty import java.time.LocalDate import java.time.OffsetDateTime data class TeamDetailUpdateRequest( - @JsonProperty("name") - val teamName: String? = null, + @JsonProperty("name") val teamName: String? = null, val description: String? = null, - val teamType: TeamType? = null, + @JsonProperty("team_type") val teamType: TeamType? = null, @JsonProperty("established_on") val establishedOn: LocalDate? = null, @@ -22,6 +22,6 @@ data class TeamDetailUpdateRequest( ) data class TeamLinksRequest( - @JsonProperty("platform_code") val platformCode: String, + @JsonProperty("platform_code") val platformCode: PlatformCode, @JsonProperty("link_url") val linkUrl: String, ) \ No newline at end of file diff --git a/src/main/kotlin/com/beat_it/team/dto/TeamDetailUpdateResponse.kt b/src/main/kotlin/com/beat_it/team/dto/TeamDetailUpdateResponse.kt index 4352854..ae2cd41 100644 --- a/src/main/kotlin/com/beat_it/team/dto/TeamDetailUpdateResponse.kt +++ b/src/main/kotlin/com/beat_it/team/dto/TeamDetailUpdateResponse.kt @@ -5,11 +5,9 @@ import java.time.LocalDate import java.time.OffsetDateTime data class TeamDetailUpdateResponse( - @JsonProperty("team_id") - val teamId: Long, + @JsonProperty("team_id") val teamId: Long, - @JsonProperty("name") - val teamName: String, + @JsonProperty("name") val teamName: String, val description: String?, @@ -17,4 +15,5 @@ data class TeamDetailUpdateResponse( @JsonProperty("updated_at") val updatedAt: OffsetDateTime, + val links: List? = null, ) \ No newline at end of file diff --git a/src/main/kotlin/com/beat_it/team/entity/TeamMemberships.kt b/src/main/kotlin/com/beat_it/team/entity/TeamMemberships.kt index 78afc53..2146b92 100644 --- a/src/main/kotlin/com/beat_it/team/entity/TeamMemberships.kt +++ b/src/main/kotlin/com/beat_it/team/entity/TeamMemberships.kt @@ -13,24 +13,21 @@ class TeamMemberships( @Column(name = "team_membership_id") val teamMembershipId: Long? = null, - //TODO: 팀 ID 연결하기 @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "team_id", nullable = false) val team: Teams, - //TODO: 사용자 ID 임시 연결 - User 모듈과 연결 시 지우거나 수정 필요 @Column(name = "user_id", nullable = false) - val userId: Long? = null, + val userId: Long, + @Enumerated(EnumType.STRING) @Column(name = "team_role", nullable = false) var teamRole: TeamRole = TeamRole.MEMBER, @Column(name = "left_at", nullable = true) var leftAt: OffsetDateTime? = null, - userid: Long, +) : BaseUpdatedTimeEntity() { - ) : BaseUpdatedTimeEntity() { - // TODO: 팀 권한 설정 함수 만들기 fun updateTeamRole(teamRole: TeamRole) { this.teamRole = teamRole } diff --git a/src/main/kotlin/com/beat_it/team/repository/TeamLinksRepository.kt b/src/main/kotlin/com/beat_it/team/repository/TeamLinksRepository.kt index 533c6bf..1d5c4e1 100644 --- a/src/main/kotlin/com/beat_it/team/repository/TeamLinksRepository.kt +++ b/src/main/kotlin/com/beat_it/team/repository/TeamLinksRepository.kt @@ -5,10 +5,11 @@ import org.springframework.data.jpa.repository.JpaRepository interface TeamLinksRepository : JpaRepository { - fun findAllByTeamId( + fun findAllByTeamTeamId( teamId: Long, ): List - fun deleteAllByTeamId(teamId: Long) - + fun deleteAllByTeamTeamId( + teamId: Long, + ) } \ No newline at end of file diff --git a/src/main/kotlin/com/beat_it/team/repository/TeamMembershipRepository.kt b/src/main/kotlin/com/beat_it/team/repository/TeamMembershipRepository.kt index 010e082..6f898e6 100644 --- a/src/main/kotlin/com/beat_it/team/repository/TeamMembershipRepository.kt +++ b/src/main/kotlin/com/beat_it/team/repository/TeamMembershipRepository.kt @@ -5,11 +5,12 @@ import org.springframework.data.jpa.repository.JpaRepository interface TeamMembershipRepository : JpaRepository { - fun findByTeamIdAndUserIdAndLeaftAtIsNull( + fun findByTeamTeamIdAndUserIdAndLeftAtIsNull( teamId: Long, userId: Long, ): TeamMemberships? - fun countByTeamIdAndLeftAtIsNull(teamId: Long): Int - + fun countByTeamTeamIdAndLeftAtIsNull( + teamId: Long, + ): Int } \ No newline at end of file diff --git a/src/main/kotlin/com/beat_it/team/repository/TeamPartsRepository.kt b/src/main/kotlin/com/beat_it/team/repository/TeamPartsRepository.kt index b7cd2b5..6ab9dea 100644 --- a/src/main/kotlin/com/beat_it/team/repository/TeamPartsRepository.kt +++ b/src/main/kotlin/com/beat_it/team/repository/TeamPartsRepository.kt @@ -5,10 +5,11 @@ import org.springframework.data.jpa.repository.JpaRepository interface TeamPartsRepository : JpaRepository { - fun findAllByTeamId( + fun findAllByTeamTeamId( teamId: Long, ): List - fun deleteAllByTeamId(teamId: Long) - + fun deleteAllByTeamTeamId( + teamId: Long, + ) } \ No newline at end of file diff --git a/src/main/kotlin/com/beat_it/team/service/TeamService.kt b/src/main/kotlin/com/beat_it/team/service/TeamService.kt index 7ed0939..0f14e54 100644 --- a/src/main/kotlin/com/beat_it/team/service/TeamService.kt +++ b/src/main/kotlin/com/beat_it/team/service/TeamService.kt @@ -31,7 +31,7 @@ class TeamService( ) { @Transactional - fun createTeam(userid: Long, request: TeamCreateRequest): TeamCreateResponse { + fun createTeam(userId: Long, request: TeamCreateRequest): TeamCreateResponse { validateCreateRequest(request) val inviteCode = generateInviteCode() @@ -50,7 +50,7 @@ class TeamService( // 현재 createTeam 함수에 userId가 없기 때문에, 나중에 Controller에서 userId를 넘겨받는 구조가 필요함 val leaderTeamMemberships = TeamMemberships( team = savedTeam, - userid = userid, + userId = userId, teamRole = TeamRole.LEADER, ) @@ -74,7 +74,7 @@ class TeamService( request: TeamDetailUpdateRequest ): TeamDetailUpdateResponse { val team = findTeamOrThrow(teamId) - val currentLinks = teamLinksRepository.findAllByTeamId(teamId) + val currentLinks = teamLinksRepository.findAllByTeamTeamId(teamId) validateTeamUpdatePermission(teamId, userId) validateUpdateRequest(request) @@ -90,8 +90,23 @@ class TeamService( teamType = team.teamType, ) - // TODO: profileImageFileId가 있다면 파일 존재 여부 검증 후 연결 - // TODO: links가 있다면 TeamLinks 엔티티 저장/수정 + request.profileImageUrl?.let { + team.profileImageUrl = it + } + + request.links?.let { linkRequests -> + teamLinksRepository.deleteAllByTeamTeamId(teamId) + + val newLinks = linkRequests.map { linkRequest -> + TeamLinks( + team = team, + platformCode = linkRequest.platformCode, + linkUrl = linkRequest.linkUrl + ) + } + + teamLinksRepository.saveAll(newLinks) + } return TeamDetailUpdateResponse( teamId = team.teamId!!, @@ -118,10 +133,10 @@ class TeamService( fun getTeamDetail(teamId: Long): TeamDetailResponse { val team = findTeamOrThrow(teamId) - val memberCount = teamMembershipRepository.countByTeamIdAndLeftAtIsNull(teamId) + val memberCount = teamMembershipRepository.countByTeamTeamIdAndLeftAtIsNull(teamId) val links = teamLinksRepository - .findAllByTeamId(teamId) + .findAllByTeamTeamId(teamId) .map { LinksResponse( teamLinkId = it.teamLinkId!!, @@ -131,7 +146,7 @@ class TeamService( } val parts = teamPartsRepository - .findAllByTeamId(teamId) + .findAllByTeamTeamId(teamId) .map { PartsResponse( teamPartId = it.teamPartId!!, @@ -221,7 +236,7 @@ class TeamService( private fun validateTeamUpdatePermission(teamId: Long, userId: Long) { // TODO: TeamMemberRepository가 생기면 여기서 LEADER 또는 MANAGER인지 확인 - val membership = teamMembershipRepository.findByTeamIdAndUserIdAndLeaftAtIsNull(teamId, userId) ?: throw BusinessException(ErrorCode.TEAM_NO_PERMISSION) + val membership = teamMembershipRepository.findByTeamTeamIdAndUserIdAndLeftAtIsNull(teamId, userId) ?: throw BusinessException(ErrorCode.TEAM_NO_PERMISSION) if (membership.teamRole != TeamRole.LEADER && membership.teamRole != TeamRole.MANAGER) { throw BusinessException(ErrorCode.TEAM_NO_PERMISSION) } @@ -229,7 +244,7 @@ class TeamService( private fun validateTeamDeletePermission(teamId: Long, userId: Long) { // TODO: 팀 삭제 권한 검증 - val membership = teamMembershipRepository.findByTeamIdAndUserIdAndLeaftAtIsNull(teamId, userId) ?: throw BusinessException(ErrorCode.TEAM_NO_PERMISSION) + val membership = teamMembershipRepository.findByTeamTeamIdAndUserIdAndLeftAtIsNull(teamId, userId) ?: throw BusinessException(ErrorCode.TEAM_NO_PERMISSION) if (membership.teamRole != TeamRole.LEADER) { throw BusinessException(ErrorCode.TEAM_NO_PERMISSION) } From f78ea49e9987d470257c59ad877dff1d63ed80f7 Mon Sep 17 00:00:00 2001 From: EunHaSong Date: Mon, 25 May 2026 21:17:06 +0900 Subject: [PATCH 20/26] =?UTF-8?q?feat/#12:=20team,user=20public=20key?= =?UTF-8?q?=EB=A1=9C=20=EA=B2=80=EC=83=89=20=EB=B0=8F=20=ED=99=9C=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../beat_it/team/controller/TeamController.kt | 21 +++---- .../beat_it/team/repository/TeamRepository.kt | 3 +- .../com/beat_it/team/service/TeamService.kt | 55 ++++++++++++------- 3 files changed, 48 insertions(+), 31 deletions(-) diff --git a/src/main/kotlin/com/beat_it/team/controller/TeamController.kt b/src/main/kotlin/com/beat_it/team/controller/TeamController.kt index 4711c2d..6af08b7 100644 --- a/src/main/kotlin/com/beat_it/team/controller/TeamController.kt +++ b/src/main/kotlin/com/beat_it/team/controller/TeamController.kt @@ -10,6 +10,7 @@ import com.beat_it.global.response.BasicResponse import org.springframework.http.HttpStatus import org.springframework.http.ResponseEntity import org.springframework.web.bind.annotation.* +import java.util.UUID @RestController @RequestMapping("/teams") @@ -19,11 +20,11 @@ class TeamController( @PostMapping fun createTeam( - @RequestHeader("X-USER-ID") userId: Long, + @RequestHeader("X-User-Public-Id") userPublicId: UUID, @RequestBody request: TeamCreateRequest ): ResponseEntity> { - val responseData = teamService.createTeam(userId, request) + val responseData = teamService.createTeam(userPublicId, request) return ResponseEntity .status(HttpStatus.CREATED) @@ -32,20 +33,20 @@ class TeamController( @PatchMapping fun updateTeamDetail( - @RequestHeader("X-TEAM-ID") teamId: Long, - @RequestHeader("X-USER-ID") userId: Long, + @RequestHeader("X-Team-Public-Id") teamPublicId: UUID, + @RequestHeader("X-User-Public-Id") userPublicId: UUID, @RequestBody request: TeamDetailUpdateRequest, ): ResponseEntity> { - val responseData = teamService.updateTeamDetail(teamId, userId, request) + val responseData = teamService.updateTeamDetail(teamPublicId, userPublicId, request) return ResponseEntity.ok(BasicResponse.success(responseData, HttpStatus.OK, "팀 상세 내용이 수정되었습니다.")) } @DeleteMapping fun deleteTeam( - @RequestHeader("X-TEAM-ID") teamId: Long, - @RequestHeader("X-USER-ID") userId: Long, + @RequestHeader("X-Team-Public-Id") teamPublicId: UUID, + @RequestHeader("X-User-Public-Id") userPublicId: UUID, ): ResponseEntity> { - teamService.deleteTeam(teamId, userId) + teamService.deleteTeam(teamPublicId, userPublicId) return ResponseEntity.ok( BasicResponse.success(HttpStatus.OK,"팀이 성공적으로 삭제되었습니다.") ) @@ -53,9 +54,9 @@ class TeamController( @GetMapping fun getTeamDetail( - @RequestHeader("X-TEAM-ID") teamId: Long, + @RequestHeader("X-Team-Public-Id") teamPublicId: UUID, ): ResponseEntity> { - val responseData = teamService.getTeamDetail(teamId) + val responseData = teamService.getTeamDetail(teamPublicId) return ResponseEntity.ok( BasicResponse.success(responseData, HttpStatus.OK,"팀 상세 내용 조회에 성공했습니다.") ) diff --git a/src/main/kotlin/com/beat_it/team/repository/TeamRepository.kt b/src/main/kotlin/com/beat_it/team/repository/TeamRepository.kt index 6f04723..f2d5add 100644 --- a/src/main/kotlin/com/beat_it/team/repository/TeamRepository.kt +++ b/src/main/kotlin/com/beat_it/team/repository/TeamRepository.kt @@ -3,11 +3,12 @@ package com.beat_it.team.repository import com.beat_it.team.entity.Teams import org.springframework.data.jpa.repository.JpaRepository import org.springframework.stereotype.Repository +import java.util.UUID @Repository interface TeamRepository : JpaRepository { - fun findByTeamIdAndDeletedAtIsNull(teamId: Long): Teams? + fun findByPublicId(publicId: UUID): Teams? fun existsByInviteCode(inviteCode: String): Boolean } \ No newline at end of file diff --git a/src/main/kotlin/com/beat_it/team/service/TeamService.kt b/src/main/kotlin/com/beat_it/team/service/TeamService.kt index 0f14e54..e4b29b2 100644 --- a/src/main/kotlin/com/beat_it/team/service/TeamService.kt +++ b/src/main/kotlin/com/beat_it/team/service/TeamService.kt @@ -1,5 +1,7 @@ package com.beat_it.team.service +import com.beat_it.auth.entity.Users +import com.beat_it.auth.repository.UserRepository import com.beat_it.global.error.BusinessException import com.beat_it.global.error.ErrorCode import com.beat_it.team.dto.LinksResponse @@ -18,12 +20,14 @@ import com.beat_it.team.repository.TeamLinksRepository import com.beat_it.team.repository.TeamMembershipRepository import com.beat_it.team.repository.TeamPartsRepository import com.beat_it.team.repository.TeamRepository +import com.sun.org.apache.xalan.internal.lib.NodeInfo.publicId import org.springframework.stereotype.Service import org.springframework.transaction.annotation.Transactional import java.util.UUID @Service class TeamService( + private val userRepository: UserRepository, private val teamRepository: TeamRepository, private val teamLinksRepository: TeamLinksRepository, private val teamPartsRepository: TeamPartsRepository, @@ -31,9 +35,11 @@ class TeamService( ) { @Transactional - fun createTeam(userId: Long, request: TeamCreateRequest): TeamCreateResponse { + fun createTeam(userPublicId: UUID, request: TeamCreateRequest): TeamCreateResponse { validateCreateRequest(request) + val userId = findUserOrThrow(userPublicId).userId!! + val inviteCode = generateInviteCode() val team = Teams( @@ -69,14 +75,15 @@ class TeamService( @Transactional fun updateTeamDetail( - teamId: Long, - userId: Long, + teamPublicId: UUID, + userPublicId: UUID, request: TeamDetailUpdateRequest ): TeamDetailUpdateResponse { - val team = findTeamOrThrow(teamId) - val currentLinks = teamLinksRepository.findAllByTeamTeamId(teamId) + val team = findTeamOrThrow(teamPublicId) + val user = findUserOrThrow(userPublicId) + val currentLinks = teamLinksRepository.findAllByTeamTeamId(team.teamId!!) - validateTeamUpdatePermission(teamId, userId) + validateTeamUpdatePermission(team.teamId!!, user.userId!!) validateUpdateRequest(request) if (isNotChanged(team, request, currentLinks)) { @@ -95,7 +102,7 @@ class TeamService( } request.links?.let { linkRequests -> - teamLinksRepository.deleteAllByTeamTeamId(teamId) + teamLinksRepository.deleteAllByTeamTeamId(team.teamId!!) val newLinks = linkRequests.map { linkRequest -> TeamLinks( @@ -119,24 +126,25 @@ class TeamService( @Transactional fun deleteTeam( - teamId: Long, - userId: Long + teamPublicId: UUID, + userPublicId: UUID, ) { - val team = findTeamOrThrow(teamId) + val team = findTeamOrThrow(teamPublicId) + val user = findUserOrThrow(userPublicId) - validateTeamDeletePermission(teamId, userId) + validateTeamDeletePermission(team.teamId!!, user.userId!!) team.deleteTeam() } @Transactional(readOnly = true) - fun getTeamDetail(teamId: Long): TeamDetailResponse { - val team = findTeamOrThrow(teamId) + fun getTeamDetail(teamPublicId: UUID): TeamDetailResponse { + val team = findTeamOrThrow(teamPublicId) - val memberCount = teamMembershipRepository.countByTeamTeamIdAndLeftAtIsNull(teamId) + val memberCount = teamMembershipRepository.countByTeamTeamIdAndLeftAtIsNull(team.teamId!!) val links = teamLinksRepository - .findAllByTeamTeamId(teamId) + .findAllByTeamTeamId(team.teamId!!) .map { LinksResponse( teamLinkId = it.teamLinkId!!, @@ -146,7 +154,7 @@ class TeamService( } val parts = teamPartsRepository - .findAllByTeamTeamId(teamId) + .findAllByTeamTeamId(team.teamId!!) .map { PartsResponse( teamPartId = it.teamPartId!!, @@ -172,6 +180,16 @@ class TeamService( ) } + private fun findUserOrThrow(userPublicId: UUID) : Users { + return userRepository.findByPublicId(userPublicId) + ?: throw BusinessException(ErrorCode.USER_NOT_FOUND) + } + + private fun findTeamOrThrow(teamPublicId: UUID): Teams { + return teamRepository.findByPublicId(teamPublicId) + ?: throw BusinessException(ErrorCode.TEAM_NOT_FOUND) + } + private fun validateCreateRequest(request: TeamCreateRequest) { if (request.teamName.isBlank()) { throw BusinessException(ErrorCode.TEAM_NAME_REQUIRED) @@ -229,10 +247,7 @@ class TeamService( return current == requested } - private fun findTeamOrThrow(teamId: Long): Teams { - return teamRepository.findByTeamIdAndDeletedAtIsNull(teamId) - ?: throw BusinessException(ErrorCode.TEAM_NOT_FOUND) - } + private fun validateTeamUpdatePermission(teamId: Long, userId: Long) { // TODO: TeamMemberRepository가 생기면 여기서 LEADER 또는 MANAGER인지 확인 From 84336afa45964c8acf807bd9ca18aef80fa23f00 Mon Sep 17 00:00:00 2001 From: EunHaSong Date: Mon, 25 May 2026 21:57:03 +0900 Subject: [PATCH 21/26] =?UTF-8?q?Style/#12:=20Link=20Response=20=EB=B0=A9?= =?UTF-8?q?=EC=8B=9D=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../beat_it/team/dto/TeamDetailUpdateResponse.kt | 2 +- .../kotlin/com/beat_it/team/service/TeamService.kt | 13 +++++++++++-- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/src/main/kotlin/com/beat_it/team/dto/TeamDetailUpdateResponse.kt b/src/main/kotlin/com/beat_it/team/dto/TeamDetailUpdateResponse.kt index ae2cd41..3bdb045 100644 --- a/src/main/kotlin/com/beat_it/team/dto/TeamDetailUpdateResponse.kt +++ b/src/main/kotlin/com/beat_it/team/dto/TeamDetailUpdateResponse.kt @@ -15,5 +15,5 @@ data class TeamDetailUpdateResponse( @JsonProperty("updated_at") val updatedAt: OffsetDateTime, - val links: List? = null, + val links: List? = null, ) \ No newline at end of file diff --git a/src/main/kotlin/com/beat_it/team/service/TeamService.kt b/src/main/kotlin/com/beat_it/team/service/TeamService.kt index e4b29b2..e1a86b6 100644 --- a/src/main/kotlin/com/beat_it/team/service/TeamService.kt +++ b/src/main/kotlin/com/beat_it/team/service/TeamService.kt @@ -20,7 +20,6 @@ import com.beat_it.team.repository.TeamLinksRepository import com.beat_it.team.repository.TeamMembershipRepository import com.beat_it.team.repository.TeamPartsRepository import com.beat_it.team.repository.TeamRepository -import com.sun.org.apache.xalan.internal.lib.NodeInfo.publicId import org.springframework.stereotype.Service import org.springframework.transaction.annotation.Transactional import java.util.UUID @@ -115,12 +114,22 @@ class TeamService( teamLinksRepository.saveAll(newLinks) } + val links = teamLinksRepository.findAllByTeamTeamId(team.teamId!!) + .map { + LinksResponse( + teamLinkId = it.teamLinkId!!, + platFormCode = it.platformCode, + linkUrl = it.linkUrl, + ) + } + return TeamDetailUpdateResponse( teamId = team.teamId!!, teamName = team.teamName, description = team.description, establishedOn = team.establishedOn, - updatedAt = team.updatedAt + updatedAt = team.updatedAt, + links = links ) } From 607c7c6b59152f3ec2e5402f9bb047d527741a19 Mon Sep 17 00:00:00 2001 From: EunHaSong Date: Mon, 25 May 2026 22:05:01 +0900 Subject: [PATCH 22/26] =?UTF-8?q?feat/#12:=20=EC=82=AD=EC=A0=9C=EB=90=9C?= =?UTF-8?q?=20=ED=8C=80=EC=9D=84=20=EC=B0=BE=EC=9D=84=20=EC=88=98=20?= =?UTF-8?q?=EC=97=86=EB=8F=84=EB=A1=9D=20=EC=B2=98=EB=A6=AC=ED=95=A8.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/kotlin/com/beat_it/team/repository/TeamRepository.kt | 2 ++ src/main/kotlin/com/beat_it/team/service/TeamService.kt | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/main/kotlin/com/beat_it/team/repository/TeamRepository.kt b/src/main/kotlin/com/beat_it/team/repository/TeamRepository.kt index f2d5add..8965561 100644 --- a/src/main/kotlin/com/beat_it/team/repository/TeamRepository.kt +++ b/src/main/kotlin/com/beat_it/team/repository/TeamRepository.kt @@ -10,5 +10,7 @@ interface TeamRepository : JpaRepository { fun findByPublicId(publicId: UUID): Teams? + fun findByPublicIdAndDeletedAtIsNull(publicId: UUID): Teams? + fun existsByInviteCode(inviteCode: String): Boolean } \ No newline at end of file diff --git a/src/main/kotlin/com/beat_it/team/service/TeamService.kt b/src/main/kotlin/com/beat_it/team/service/TeamService.kt index e1a86b6..db66b62 100644 --- a/src/main/kotlin/com/beat_it/team/service/TeamService.kt +++ b/src/main/kotlin/com/beat_it/team/service/TeamService.kt @@ -195,7 +195,7 @@ class TeamService( } private fun findTeamOrThrow(teamPublicId: UUID): Teams { - return teamRepository.findByPublicId(teamPublicId) + return teamRepository.findByPublicIdAndDeletedAtIsNull(teamPublicId) ?: throw BusinessException(ErrorCode.TEAM_NOT_FOUND) } From 29f225fb28c52e978dc4097db46208a43e1188b5 Mon Sep 17 00:00:00 2001 From: EunHaSong Date: Mon, 25 May 2026 22:19:45 +0900 Subject: [PATCH 23/26] =?UTF-8?q?feat/#12:=20=EC=9D=B8=EC=A6=9D=EB=90=9C?= =?UTF-8?q?=20=ED=97=A4=EB=8D=94=20=ED=8C=8C=EB=9D=BC=EB=AF=B8=ED=84=B0=20?= =?UTF-8?q?=EC=88=A8=EA=B8=B0=EA=B8=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../beat_it/team/controller/TeamController.kt | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/src/main/kotlin/com/beat_it/team/controller/TeamController.kt b/src/main/kotlin/com/beat_it/team/controller/TeamController.kt index 6af08b7..98211b5 100644 --- a/src/main/kotlin/com/beat_it/team/controller/TeamController.kt +++ b/src/main/kotlin/com/beat_it/team/controller/TeamController.kt @@ -11,6 +11,7 @@ import org.springframework.http.HttpStatus import org.springframework.http.ResponseEntity import org.springframework.web.bind.annotation.* import java.util.UUID +import io.swagger.v3.oas.annotations.Parameter @RestController @RequestMapping("/teams") @@ -20,7 +21,9 @@ class TeamController( @PostMapping fun createTeam( + @Parameter(hidden = true) @RequestHeader("X-User-Public-Id") userPublicId: UUID, + @RequestBody request: TeamCreateRequest ): ResponseEntity> { @@ -33,8 +36,12 @@ class TeamController( @PatchMapping fun updateTeamDetail( - @RequestHeader("X-Team-Public-Id") teamPublicId: UUID, + @Parameter(hidden = true) @RequestHeader("X-User-Public-Id") userPublicId: UUID, + + @Parameter(hidden = true) + @RequestHeader("X-Team-Public-Id") teamPublicId: UUID, + @RequestBody request: TeamDetailUpdateRequest, ): ResponseEntity> { val responseData = teamService.updateTeamDetail(teamPublicId, userPublicId, request) @@ -43,8 +50,12 @@ class TeamController( @DeleteMapping fun deleteTeam( - @RequestHeader("X-Team-Public-Id") teamPublicId: UUID, + @Parameter(hidden = true) @RequestHeader("X-User-Public-Id") userPublicId: UUID, + + @Parameter(hidden = true) + @RequestHeader("X-Team-Public-Id") teamPublicId: UUID, + ): ResponseEntity> { teamService.deleteTeam(teamPublicId, userPublicId) return ResponseEntity.ok( @@ -54,7 +65,9 @@ class TeamController( @GetMapping fun getTeamDetail( + @Parameter(hidden = true) @RequestHeader("X-Team-Public-Id") teamPublicId: UUID, + ): ResponseEntity> { val responseData = teamService.getTeamDetail(teamPublicId) return ResponseEntity.ok( From 3f2e4732e61d336bc53f281e531c8aeff8b6880c Mon Sep 17 00:00:00 2001 From: EunHaSong Date: Wed, 27 May 2026 19:18:30 +0900 Subject: [PATCH 24/26] =?UTF-8?q?style/#12:=20@Repository=20=EC=96=B4?= =?UTF-8?q?=EB=85=B8=ED=85=8C=EC=9D=B4=EC=85=98=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../kotlin/com/beat_it/team/controller/TeamController.kt | 8 ++++---- .../com/beat_it/team/repository/TeamLinksRepository.kt | 2 ++ .../beat_it/team/repository/TeamMembershipRepository.kt | 2 ++ .../com/beat_it/team/repository/TeamPartsRepository.kt | 2 ++ 4 files changed, 10 insertions(+), 4 deletions(-) diff --git a/src/main/kotlin/com/beat_it/team/controller/TeamController.kt b/src/main/kotlin/com/beat_it/team/controller/TeamController.kt index 98211b5..b95fd8d 100644 --- a/src/main/kotlin/com/beat_it/team/controller/TeamController.kt +++ b/src/main/kotlin/com/beat_it/team/controller/TeamController.kt @@ -12,6 +12,8 @@ import org.springframework.http.ResponseEntity import org.springframework.web.bind.annotation.* import java.util.UUID import io.swagger.v3.oas.annotations.Parameter +import org.springframework.security.core.annotation.AuthenticationPrincipal +import org.springframework.security.core.userdetails.UserDetails @RestController @RequestMapping("/teams") @@ -21,13 +23,11 @@ class TeamController( @PostMapping fun createTeam( - @Parameter(hidden = true) - @RequestHeader("X-User-Public-Id") userPublicId: UUID, - + @AuthenticationPrincipal userDetails: UserDetails?, @RequestBody request: TeamCreateRequest ): ResponseEntity> { - val responseData = teamService.createTeam(userPublicId, request) + val responseData = teamService.createTeam(userDetails.username, request) return ResponseEntity .status(HttpStatus.CREATED) diff --git a/src/main/kotlin/com/beat_it/team/repository/TeamLinksRepository.kt b/src/main/kotlin/com/beat_it/team/repository/TeamLinksRepository.kt index 1d5c4e1..aa9b0bc 100644 --- a/src/main/kotlin/com/beat_it/team/repository/TeamLinksRepository.kt +++ b/src/main/kotlin/com/beat_it/team/repository/TeamLinksRepository.kt @@ -2,7 +2,9 @@ package com.beat_it.team.repository import com.beat_it.team.entity.TeamLinks import org.springframework.data.jpa.repository.JpaRepository +import org.springframework.stereotype.Repository +@Repository interface TeamLinksRepository : JpaRepository { fun findAllByTeamTeamId( diff --git a/src/main/kotlin/com/beat_it/team/repository/TeamMembershipRepository.kt b/src/main/kotlin/com/beat_it/team/repository/TeamMembershipRepository.kt index 6f898e6..4a973f0 100644 --- a/src/main/kotlin/com/beat_it/team/repository/TeamMembershipRepository.kt +++ b/src/main/kotlin/com/beat_it/team/repository/TeamMembershipRepository.kt @@ -2,7 +2,9 @@ package com.beat_it.team.repository import com.beat_it.team.entity.TeamMemberships import org.springframework.data.jpa.repository.JpaRepository +import org.springframework.stereotype.Repository +@Repository interface TeamMembershipRepository : JpaRepository { fun findByTeamTeamIdAndUserIdAndLeftAtIsNull( diff --git a/src/main/kotlin/com/beat_it/team/repository/TeamPartsRepository.kt b/src/main/kotlin/com/beat_it/team/repository/TeamPartsRepository.kt index 6ab9dea..57622c8 100644 --- a/src/main/kotlin/com/beat_it/team/repository/TeamPartsRepository.kt +++ b/src/main/kotlin/com/beat_it/team/repository/TeamPartsRepository.kt @@ -2,7 +2,9 @@ package com.beat_it.team.repository import com.beat_it.team.entity.TeamParts import org.springframework.data.jpa.repository.JpaRepository +import org.springframework.stereotype.Repository +@Repository interface TeamPartsRepository : JpaRepository { fun findAllByTeamTeamId( From 50b744d213999a23018856d2479bae7ba9922977 Mon Sep 17 00:00:00 2001 From: EunHaSong Date: Wed, 27 May 2026 19:36:10 +0900 Subject: [PATCH 25/26] =?UTF-8?q?style/#12:=20Request/Response=20=EC=B9=B4?= =?UTF-8?q?=EB=A9=9C=EC=BC=80=EC=9D=B4=EC=8A=A4=EB=A1=9C=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../beat_it/team/controller/TeamController.kt | 8 ++--- .../com/beat_it/team/dto/TeamCreateRequest.kt | 16 ++++----- .../beat_it/team/dto/TeamCreateResponse.kt | 18 ++++------ .../beat_it/team/dto/TeamDetailResponse.kt | 34 +++++++++---------- .../team/dto/TeamDetailUpdateRequest.kt | 22 ++++-------- .../team/dto/TeamDetailUpdateResponse.kt | 16 +++------ 6 files changed, 44 insertions(+), 70 deletions(-) diff --git a/src/main/kotlin/com/beat_it/team/controller/TeamController.kt b/src/main/kotlin/com/beat_it/team/controller/TeamController.kt index b95fd8d..98211b5 100644 --- a/src/main/kotlin/com/beat_it/team/controller/TeamController.kt +++ b/src/main/kotlin/com/beat_it/team/controller/TeamController.kt @@ -12,8 +12,6 @@ import org.springframework.http.ResponseEntity import org.springframework.web.bind.annotation.* import java.util.UUID import io.swagger.v3.oas.annotations.Parameter -import org.springframework.security.core.annotation.AuthenticationPrincipal -import org.springframework.security.core.userdetails.UserDetails @RestController @RequestMapping("/teams") @@ -23,11 +21,13 @@ class TeamController( @PostMapping fun createTeam( - @AuthenticationPrincipal userDetails: UserDetails?, + @Parameter(hidden = true) + @RequestHeader("X-User-Public-Id") userPublicId: UUID, + @RequestBody request: TeamCreateRequest ): ResponseEntity> { - val responseData = teamService.createTeam(userDetails.username, request) + val responseData = teamService.createTeam(userPublicId, request) return ResponseEntity .status(HttpStatus.CREATED) diff --git a/src/main/kotlin/com/beat_it/team/dto/TeamCreateRequest.kt b/src/main/kotlin/com/beat_it/team/dto/TeamCreateRequest.kt index 944633d..259083e 100644 --- a/src/main/kotlin/com/beat_it/team/dto/TeamCreateRequest.kt +++ b/src/main/kotlin/com/beat_it/team/dto/TeamCreateRequest.kt @@ -2,18 +2,14 @@ package com.beat_it.team.dto import com.beat_it.team.entity.enum.TeamType import com.fasterxml.jackson.annotation.JsonProperty +import io.swagger.v3.oas.annotations.media.Schema import java.time.LocalDate import java.time.OffsetDateTime data class TeamCreateRequest( - @JsonProperty("name") val teamName: String, - + val teamName: String, val description: String?, - - @JsonProperty("team_type") val teamType: TeamType, - - @JsonProperty("established_on") val establishedOn: LocalDate?, - - @JsonProperty("profile_image_url") val profileImageUrl: String?, - - ) \ No newline at end of file + val teamType: TeamType, + val establishedOn: LocalDate?, + val profileImageUrl: String?, +) \ No newline at end of file diff --git a/src/main/kotlin/com/beat_it/team/dto/TeamCreateResponse.kt b/src/main/kotlin/com/beat_it/team/dto/TeamCreateResponse.kt index 801fdd7..b818812 100644 --- a/src/main/kotlin/com/beat_it/team/dto/TeamCreateResponse.kt +++ b/src/main/kotlin/com/beat_it/team/dto/TeamCreateResponse.kt @@ -5,17 +5,11 @@ import com.fasterxml.jackson.annotation.JsonProperty import java.time.OffsetDateTime data class TeamCreateResponse( - @JsonProperty("team_id") val teamId: Long, - - @JsonProperty("name") val teamName: String, - + val teamId: Long, + val teamName: String, val description: String?, - - @JsonProperty("invite_code") val inviteCode: String, - - @JsonProperty("team_type") val teamType: TeamType, - - @JsonProperty("team_role") val teamRole: String, - - @JsonProperty("created_at") val createdAt: OffsetDateTime, + val inviteCode: String, + val teamType: TeamType, + val teamRole: String, + val createdAt: OffsetDateTime, ) \ No newline at end of file diff --git a/src/main/kotlin/com/beat_it/team/dto/TeamDetailResponse.kt b/src/main/kotlin/com/beat_it/team/dto/TeamDetailResponse.kt index c9034b9..9955f61 100644 --- a/src/main/kotlin/com/beat_it/team/dto/TeamDetailResponse.kt +++ b/src/main/kotlin/com/beat_it/team/dto/TeamDetailResponse.kt @@ -1,35 +1,33 @@ package com.beat_it.team.dto import com.beat_it.team.entity.enum.PlatformCode -import com.fasterxml.jackson.annotation.JsonProperty import java.time.LocalDate import java.time.OffsetDateTime data class TeamDetailResponse( - @JsonProperty("team_id") val teamId: Long? = null, - @JsonProperty("profile_image_url") val profileImageUrl: String?, - @JsonProperty("name") val teamName: String, + val teamId: Long? = null, + val profileImageUrl: String?, + val teamName: String, val description: String?, - @JsonProperty("established_on") val establishedOn: LocalDate?, - @JsonProperty("invite_code") val inviteCode: String, - @JsonProperty("member_count") val memberCount: Int, - @JsonProperty("created_at") val createdAt: OffsetDateTime, - @JsonProperty("updated_at") val updatedAt: OffsetDateTime, + val establishedOn: LocalDate?, + val inviteCode: String, + val memberCount: Int, + val createdAt: OffsetDateTime, + val updatedAt: OffsetDateTime, val links: List, val parts: List, - @JsonProperty("archive_count") val archiveCount: Int, - @JsonProperty("cloud_item_count") val cloudItemCount: Int, - + val archiveCount: Int, + val cloudItemCount: Int, ) data class LinksResponse( - @JsonProperty("team_link_id") val teamLinkId: Long, - @JsonProperty("platform_code") val platFormCode: PlatformCode, - @JsonProperty("link_url") val linkUrl: String, + val teamLinkId: Long, + val platformCode: PlatformCode, + val linkUrl: String, ) data class PartsResponse( - @JsonProperty("team_part_id") val teamPartId: Long, - @JsonProperty("part_name") val partName: String, - @JsonProperty("display_order") val displayOrder: Int, + val teamPartId: Long, + val partName: String, + val displayOrder: Int, ) \ No newline at end of file diff --git a/src/main/kotlin/com/beat_it/team/dto/TeamDetailUpdateRequest.kt b/src/main/kotlin/com/beat_it/team/dto/TeamDetailUpdateRequest.kt index 8132585..e80ad87 100644 --- a/src/main/kotlin/com/beat_it/team/dto/TeamDetailUpdateRequest.kt +++ b/src/main/kotlin/com/beat_it/team/dto/TeamDetailUpdateRequest.kt @@ -2,26 +2,18 @@ package com.beat_it.team.dto import com.beat_it.team.entity.enum.PlatformCode import com.beat_it.team.entity.enum.TeamType -import com.fasterxml.jackson.annotation.JsonProperty import java.time.LocalDate -import java.time.OffsetDateTime data class TeamDetailUpdateRequest( - @JsonProperty("name") val teamName: String? = null, - + val teamName: String? = null, val description: String? = null, - - @JsonProperty("team_type") val teamType: TeamType? = null, - - @JsonProperty("established_on") val establishedOn: LocalDate? = null, - - @JsonProperty("profile_image_url") val profileImageUrl: String? = null, - + val teamType: TeamType? = null, + val establishedOn: LocalDate? = null, + val profileImageUrl: String? = null, val links: List? = null, - - ) +) data class TeamLinksRequest( - @JsonProperty("platform_code") val platformCode: PlatformCode, - @JsonProperty("link_url") val linkUrl: String, + val platformCode: PlatformCode, + val linkUrl: String, ) \ No newline at end of file diff --git a/src/main/kotlin/com/beat_it/team/dto/TeamDetailUpdateResponse.kt b/src/main/kotlin/com/beat_it/team/dto/TeamDetailUpdateResponse.kt index 3bdb045..a98c3aa 100644 --- a/src/main/kotlin/com/beat_it/team/dto/TeamDetailUpdateResponse.kt +++ b/src/main/kotlin/com/beat_it/team/dto/TeamDetailUpdateResponse.kt @@ -1,19 +1,13 @@ package com.beat_it.team.dto -import com.fasterxml.jackson.annotation.JsonProperty import java.time.LocalDate import java.time.OffsetDateTime data class TeamDetailUpdateResponse( - @JsonProperty("team_id") val teamId: Long, - - @JsonProperty("name") val teamName: String, - + val teamId: Long, + val teamName: String, val description: String?, - - @JsonProperty("established_on") val establishedOn: LocalDate?, - - @JsonProperty("updated_at") val updatedAt: OffsetDateTime, - + val establishedOn: LocalDate?, + val updatedAt: OffsetDateTime, val links: List? = null, - ) \ No newline at end of file +) \ No newline at end of file From c07b8618b2142e912dd345dfed5f0f0a83d96493 Mon Sep 17 00:00:00 2001 From: EunHaSong Date: Wed, 27 May 2026 20:03:17 +0900 Subject: [PATCH 26/26] =?UTF-8?q?style/#12:=20isNotChange=20=ED=95=A8?= =?UTF-8?q?=EC=88=98=20=ED=98=95=EC=8B=9D=20validate=EC=9C=BC=EB=A1=9C=20?= =?UTF-8?q?=ED=86=B5=EC=9D=BC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/beat_it/team/service/TeamService.kt | 41 ++++++++++--------- 1 file changed, 21 insertions(+), 20 deletions(-) diff --git a/src/main/kotlin/com/beat_it/team/service/TeamService.kt b/src/main/kotlin/com/beat_it/team/service/TeamService.kt index db66b62..5f3e51f 100644 --- a/src/main/kotlin/com/beat_it/team/service/TeamService.kt +++ b/src/main/kotlin/com/beat_it/team/service/TeamService.kt @@ -80,20 +80,19 @@ class TeamService( ): TeamDetailUpdateResponse { val team = findTeamOrThrow(teamPublicId) val user = findUserOrThrow(userPublicId) - val currentLinks = teamLinksRepository.findAllByTeamTeamId(team.teamId!!) + val teamId = team.teamId!! - validateTeamUpdatePermission(team.teamId!!, user.userId!!) - validateUpdateRequest(request) + val currentLinks = teamLinksRepository.findAllByTeamTeamId(teamId) - if (isNotChanged(team, request, currentLinks)) { - throw BusinessException(ErrorCode.TEAM_NO_CONTENT_TO_UPDATE) - } + validateTeamUpdatePermission(teamId, user.userId!!) + validateUpdateRequest(request) + validateTeamDetailChanged(team, request, currentLinks) team.updateTeamDetail( teamName = request.teamName, description = request.description, establishedOn = request.establishedOn, - teamType = team.teamType, + teamType = request.teamType, ) request.profileImageUrl?.let { @@ -101,7 +100,7 @@ class TeamService( } request.links?.let { linkRequests -> - teamLinksRepository.deleteAllByTeamTeamId(team.teamId!!) + teamLinksRepository.deleteAllByTeamTeamId(teamId) val newLinks = linkRequests.map { linkRequest -> TeamLinks( @@ -114,17 +113,17 @@ class TeamService( teamLinksRepository.saveAll(newLinks) } - val links = teamLinksRepository.findAllByTeamTeamId(team.teamId!!) + val links = teamLinksRepository.findAllByTeamTeamId(teamId) .map { LinksResponse( teamLinkId = it.teamLinkId!!, - platFormCode = it.platformCode, + platformCode = it.platformCode, linkUrl = it.linkUrl, ) } return TeamDetailUpdateResponse( - teamId = team.teamId!!, + teamId = teamId, teamName = team.teamName, description = team.description, establishedOn = team.establishedOn, @@ -157,7 +156,7 @@ class TeamService( .map { LinksResponse( teamLinkId = it.teamLinkId!!, - platFormCode = it.platformCode, + platformCode = it.platformCode, linkUrl = it.linkUrl, ) } @@ -223,22 +222,24 @@ class TeamService( } } - private fun isNotChanged( + private fun validateTeamDetailChanged( team: Teams, request: TeamDetailUpdateRequest, currentLinks: List - ): Boolean { + ) { val isAnyFieldChanged = - (request.teamName != team.teamName) || - (request.description != null && request.description != team.description) || - (request.establishedOn != null && request.establishedOn != team.establishedOn) || - (request.teamType != null && request.teamType != team.teamType) || - (request.profileImageUrl != null && request.profileImageUrl != team.profileImageUrl) + (request.teamName != null && request.teamName != team.teamName) || + (request.description != null && request.description != team.description) || + (request.establishedOn != null && request.establishedOn != team.establishedOn) || + (request.teamType != null && request.teamType != team.teamType) || + (request.profileImageUrl != null && request.profileImageUrl != team.profileImageUrl) val isLinksChanged = request.links != null && !isLinksSame(currentLinks, request.links) - return !(isAnyFieldChanged || isLinksChanged) + if (!isAnyFieldChanged && !isLinksChanged) { + throw BusinessException(ErrorCode.TEAM_NO_CONTENT_TO_UPDATE) + } } private fun isLinksSame(