Skip to content

Commit e86b0c0

Browse files
dbwp031yj-lee00
andauthored
✨ feat: 내 조직 조회 / 수정 / 삭제 기능 개발 (#55)
* ✨ feat: Organization 관련 Response 생성 * ✨ feat: Organization 조회 기능 구현 * ✨ feat: 내 조직 수정 기능 구현 * ✅ test: 내 조직 조회 & 업데이트 테스트 request 추가 * ♻️ refactor: 조직 수정 매서드 입력 파라미터 organization에서 organizationId로 수정 Organization을 외부에서 찾은 후 전달해야 하는 불필요한 로직 제거를 위함 * ✨ feat: 내 조직 삭제(soft delete, 비활성화) 기능 구현 * ✅ test: 내 조직 삭제(soft delete) 기능 테스트 request 구현 --------- Co-authored-by: Yuje Lee <[email protected]>
1 parent 3c2c84e commit e86b0c0

8 files changed

+245
-2
lines changed

http/test.http

+38
Original file line numberDiff line numberDiff line change
@@ -77,3 +77,41 @@ Content-Type: application/json
7777

7878
### 보고서 조회
7979
GET http://localhost:8080/api/v1/reports/0
80+
81+
### 내 조직 조회
82+
GET http://localhost:8080/api/v1/organizations/me
83+
Authorization: Bearer {{matsterToken}}
84+
85+
### 내 조직 수정
86+
PATCH http://localhost:8080/api/v1/organizations/me
87+
Authorization: Bearer {{matsterToken}}
88+
Content-Type: application/json
89+
90+
{
91+
"name": "팀 스포너스 업데이트!!!!",
92+
"email": "[email protected] 업데이트!!!!",
93+
"password": "password1234 업데이트!!!!",
94+
"location": "none 업데이트!!!!",
95+
"organizationType": "COMPANY",
96+
"suborganizationType": "CLUB",
97+
"managerName": "이가은",
98+
"managerPosition": "Project Manager",
99+
"managerEmail": "[email protected]",
100+
"managerPhone": "01012345678",
101+
"managerAvailableDay": "월-금",
102+
"managerAvailableHour": "15:00-18:00",
103+
"managerContactPreference": "EMAIL 업데이트!!!!"
104+
}
105+
106+
### 내 조직 수정 2
107+
PATCH http://localhost:8080/api/v1/organizations/me
108+
Authorization: Bearer {{matsterToken}}
109+
Content-Type: application/json
110+
111+
{
112+
"name": "팀 스포너스 업데이트!!!!2"
113+
}
114+
115+
### 내 조직 삭제 [soft delete] (OrganizationStatus = INACTIVE)
116+
DELETE http://localhost:8080/api/v1/organizations/me
117+
Authorization: Bearer {{matsterToken}}

src/main/java/com/sponus/sponusbe/domain/organization/controller/OrganizationController.java

+24
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,18 @@
11
package com.sponus.sponusbe.domain.organization.controller;
22

3+
import org.springframework.web.bind.annotation.DeleteMapping;
34
import org.springframework.web.bind.annotation.GetMapping;
5+
import org.springframework.web.bind.annotation.PatchMapping;
46
import org.springframework.web.bind.annotation.PostMapping;
57
import org.springframework.web.bind.annotation.RequestBody;
68
import org.springframework.web.bind.annotation.RequestMapping;
79
import org.springframework.web.bind.annotation.RestController;
810

911
import com.sponus.sponusbe.auth.annotation.AuthOrganization;
12+
import com.sponus.sponusbe.domain.organization.dto.OrganizationDetailGetResponse;
1013
import com.sponus.sponusbe.domain.organization.dto.OrganizationJoinRequest;
1114
import com.sponus.sponusbe.domain.organization.dto.OrganizationJoinResponse;
15+
import com.sponus.sponusbe.domain.organization.dto.OrganizationUpdateRequest;
1216
import com.sponus.sponusbe.domain.organization.entity.Organization;
1317
import com.sponus.sponusbe.domain.organization.service.OrganizationService;
1418
import com.sponus.sponusbe.global.common.ApiResponse;
@@ -34,4 +38,24 @@ public ApiResponse<Long> test(@AuthOrganization Organization organization) {
3438
Long id = organization.getId();
3539
return ApiResponse.onSuccess(id);
3640
}
41+
42+
@GetMapping("/me")
43+
public ApiResponse<OrganizationDetailGetResponse> getMyOrganization(@AuthOrganization Organization organization) {
44+
return ApiResponse.onSuccess(OrganizationDetailGetResponse.from(organization));
45+
}
46+
47+
@PatchMapping("/me")
48+
public ApiResponse<Void> updateMyOrganization(
49+
@AuthOrganization Organization organization,
50+
@RequestBody @Valid OrganizationUpdateRequest request
51+
) {
52+
organizationService.updateOrganization(organization.getId(), request);
53+
return ApiResponse.onSuccess(null);
54+
}
55+
56+
@DeleteMapping("/me")
57+
public ApiResponse<Void> deleteMyOrganization(@AuthOrganization Organization organization) {
58+
organizationService.deactivateOrganization(organization.getId());
59+
return ApiResponse.onSuccess(null);
60+
}
3761
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
package com.sponus.sponusbe.domain.organization.dto;
2+
3+
import com.sponus.sponusbe.domain.organization.entity.Organization;
4+
import com.sponus.sponusbe.domain.organization.entity.enums.OrganizationStatus;
5+
import com.sponus.sponusbe.domain.organization.entity.enums.OrganizationType;
6+
import com.sponus.sponusbe.domain.organization.entity.enums.SuborganizationType;
7+
8+
import java.util.List;
9+
10+
public record OrganizationDetailGetResponse(
11+
Long organizationId,
12+
String name,
13+
String email,
14+
String password,
15+
String location,
16+
String description,
17+
String imageUrl,
18+
OrganizationType organizationType,
19+
SuborganizationType suborganizationType,
20+
String managerName,
21+
String managerPosition,
22+
String managerEmail,
23+
String managerPhone,
24+
String managerAvailableDay,
25+
String managerAvailableHour,
26+
String managerContactPreference,
27+
OrganizationStatus organizationStatus,
28+
List<TagGetResponse> tags,
29+
List<OrganizationLinkGetResponse> links
30+
) {
31+
public static OrganizationDetailGetResponse from(Organization organization) {
32+
List<TagGetResponse> tagGetResponses = TagGetResponse.getTagResponses(organization);
33+
List<OrganizationLinkGetResponse> linkGetResponses = OrganizationLinkGetResponse.getOrganizationLinkResponses(organization);
34+
return new OrganizationDetailGetResponse(
35+
organization.getId(),
36+
organization.getName(),
37+
organization.getEmail(),
38+
organization.getPassword(),
39+
organization.getLocation(),
40+
organization.getDescription(),
41+
organization.getImageUrl(),
42+
organization.getOrganizationType(),
43+
organization.getSuborganizationType(),
44+
organization.getManagerName(),
45+
organization.getManagerPosition(),
46+
organization.getManagerEmail(),
47+
organization.getManagerPhone(),
48+
organization.getManagerAvailableDay(),
49+
organization.getManagerAvailableHour(),
50+
organization.getManagerContactPreference(),
51+
organization.getOrganizationStatus(),
52+
tagGetResponses,
53+
linkGetResponses
54+
);
55+
}
56+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
package com.sponus.sponusbe.domain.organization.dto;
2+
3+
import com.sponus.sponusbe.domain.organization.entity.Organization;
4+
import com.sponus.sponusbe.domain.organization.entity.OrganizationLink;
5+
6+
import java.util.List;
7+
8+
public record OrganizationLinkGetResponse(
9+
Long organizationLinkId,
10+
Long organizationId,
11+
String name,
12+
String url
13+
) {
14+
public static OrganizationLinkGetResponse from(OrganizationLink organizationLink) {
15+
return new OrganizationLinkGetResponse(
16+
organizationLink.getId(),
17+
organizationLink.getOrganization().getId(),
18+
organizationLink.getName(),
19+
organizationLink.getUrl()
20+
);
21+
}
22+
23+
public static List<OrganizationLinkGetResponse> getOrganizationLinkResponses(Organization organization) {
24+
return organization.getOrganizationLinks().stream()
25+
.map(OrganizationLinkGetResponse::from)
26+
.toList();
27+
}
28+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
package com.sponus.sponusbe.domain.organization.dto;
2+
3+
import com.sponus.sponusbe.domain.organization.entity.enums.OrganizationType;
4+
import com.sponus.sponusbe.domain.organization.entity.enums.SuborganizationType;
5+
6+
public record OrganizationUpdateRequest(
7+
String name,
8+
String email,
9+
String password,
10+
String location,
11+
String description,
12+
String imageUrl,
13+
OrganizationType organizationType,
14+
SuborganizationType suborganizationType,
15+
String managerName,
16+
String managerPosition,
17+
String managerEmail,
18+
String managerPhone,
19+
String managerAvailableDay,
20+
String managerAvailableHour,
21+
String managerContactPreference
22+
) {
23+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
package com.sponus.sponusbe.domain.organization.dto;
2+
3+
import com.sponus.sponusbe.domain.organization.entity.Organization;
4+
import com.sponus.sponusbe.domain.organization.entity.Tag;
5+
6+
import java.util.List;
7+
import java.util.stream.Collectors;
8+
9+
public record TagGetResponse(
10+
Long id,
11+
String name
12+
) {
13+
public static TagGetResponse from(Tag tag) {
14+
return new TagGetResponse(tag.getId(), tag.getName());
15+
}
16+
17+
public static List<TagGetResponse> getTagResponses(Organization organization) {
18+
return organization.getOrganizationTags()
19+
.stream()
20+
.map(organizationTag -> TagGetResponse.from(organizationTag.getTag()))
21+
.toList();
22+
}
23+
24+
}

src/main/java/com/sponus/sponusbe/domain/organization/entity/Organization.java

+34-2
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import java.util.ArrayList;
44
import java.util.List;
55

6+
import com.sponus.sponusbe.domain.organization.dto.OrganizationUpdateRequest;
67
import com.sponus.sponusbe.domain.organization.entity.enums.OrganizationStatus;
78
import com.sponus.sponusbe.domain.organization.entity.enums.OrganizationType;
89
import com.sponus.sponusbe.domain.organization.entity.enums.SuborganizationType;
@@ -12,6 +13,7 @@
1213
import jakarta.persistence.Entity;
1314
import jakarta.persistence.EnumType;
1415
import jakarta.persistence.Enumerated;
16+
import jakarta.persistence.FetchType;
1517
import jakarta.persistence.GeneratedValue;
1618
import jakarta.persistence.GenerationType;
1719
import jakarta.persistence.Id;
@@ -88,14 +90,44 @@ public class Organization extends BaseEntity {
8890
private OrganizationStatus organizationStatus;
8991

9092
@Builder.Default
91-
@OneToMany(mappedBy = "organization")
93+
@OneToMany(mappedBy = "organization", fetch = FetchType.EAGER)
9294
private List<OrganizationTag> organizationTags = new ArrayList<>();
9395

9496
@Builder.Default
95-
@OneToMany(mappedBy = "organization")
97+
@OneToMany(mappedBy = "organization", fetch = FetchType.EAGER)
9698
private List<OrganizationLink> organizationLinks = new ArrayList<>();
9799

98100
public boolean isStudentOrganization() {
99101
return this.organizationType == OrganizationType.STUDENT;
100102
}
103+
104+
public void update(OrganizationUpdateRequest request) {
105+
this.name = request.name() == null ? this.name : request.name();
106+
this.email = request.email() == null ? this.email : request.email();
107+
this.password = request.password() == null ? this.password : request.password();
108+
this.location = request.location() == null ? this.location : request.location();
109+
this.description = request.description() == null ? this.description : request.description();
110+
this.imageUrl = request.imageUrl() == null ? this.imageUrl : request.imageUrl();
111+
this.organizationType = request.organizationType() == null ? this.organizationType : request.organizationType();
112+
this.suborganizationType =
113+
request.suborganizationType() == null ? this.suborganizationType : request.suborganizationType();
114+
this.managerName = request.managerName() == null ? this.managerName : request.managerName();
115+
this.managerPosition = request.managerPosition() == null ? this.managerPosition : request.managerPosition();
116+
this.managerEmail = request.managerEmail() == null ? this.managerEmail : request.managerEmail();
117+
this.managerPhone = request.managerPhone() == null ? this.managerPhone : request.managerPhone();
118+
this.managerAvailableDay =
119+
request.managerAvailableDay() == null ? this.managerAvailableDay : request.managerAvailableDay();
120+
this.managerAvailableHour =
121+
request.managerAvailableHour() == null ? this.managerAvailableHour : request.managerAvailableHour();
122+
this.managerContactPreference = request.managerContactPreference() == null ? this.managerContactPreference :
123+
request.managerContactPreference();
124+
}
125+
126+
public void deactivate() {
127+
this.organizationStatus = OrganizationStatus.INACTIVE;
128+
}
129+
130+
public void activate() {
131+
this.organizationStatus = OrganizationStatus.ACTIVE;
132+
}
101133
}

src/main/java/com/sponus/sponusbe/domain/organization/service/OrganizationService.java

+18
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,16 @@
11
package com.sponus.sponusbe.domain.organization.service;
22

3+
import static com.sponus.sponusbe.domain.organization.exception.OrganizationErrorCode.*;
4+
35
import org.springframework.security.crypto.password.PasswordEncoder;
46
import org.springframework.stereotype.Service;
57
import org.springframework.transaction.annotation.Transactional;
68

79
import com.sponus.sponusbe.domain.organization.dto.OrganizationJoinRequest;
810
import com.sponus.sponusbe.domain.organization.dto.OrganizationJoinResponse;
11+
import com.sponus.sponusbe.domain.organization.dto.OrganizationUpdateRequest;
912
import com.sponus.sponusbe.domain.organization.entity.Organization;
13+
import com.sponus.sponusbe.domain.organization.exception.OrganizationException;
1014
import com.sponus.sponusbe.domain.organization.repository.OrganizationRepository;
1115

1216
import lombok.RequiredArgsConstructor;
@@ -25,4 +29,18 @@ public OrganizationJoinResponse join(OrganizationJoinRequest request) {
2529
request.toEntity(passwordEncoder.encode(request.password())));
2630
return OrganizationJoinResponse.from(organization);
2731
}
32+
33+
@Transactional
34+
public void updateOrganization(Long organizationId, OrganizationUpdateRequest request) {
35+
Organization organization = organizationRepository.findById(organizationId)
36+
.orElseThrow(() -> new OrganizationException(ORGANIZATION_NOT_FOUND));
37+
organization.update(request);
38+
}
39+
40+
@Transactional
41+
public void deactivateOrganization(Long organizationId) {
42+
Organization organization = organizationRepository.findById(organizationId)
43+
.orElseThrow(() -> new OrganizationException(ORGANIZATION_NOT_FOUND));
44+
organization.deactivate();
45+
}
2846
}

0 commit comments

Comments
 (0)