Skip to content

Commit b534544

Browse files
authored
Merge pull request #967 from Moadong/develop/be
[release] BE
2 parents 8a88572 + bfa1fc3 commit b534544

File tree

51 files changed

+1164
-631
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

51 files changed

+1164
-631
lines changed

backend/build.gradle

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ dependencies {
5454
// S3
5555
implementation 'software.amazon.awssdk:s3:2.26.0'
5656
implementation 'software.amazon.awssdk:auth:2.26.0'
57+
implementation 'software.amazon.awssdk:url-connection-client:2.26.0'
5758

5859
// resize tool
5960
implementation 'net.coobird:thumbnailator:0.4.14'

backend/src/main/java/moadong/club/controller/ClubApplyAdminController.java

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import io.swagger.v3.oas.annotations.Operation;
44
import io.swagger.v3.oas.annotations.security.SecurityRequirement;
55
import io.swagger.v3.oas.annotations.tags.Tag;
6+
import jakarta.servlet.http.HttpServletResponse;
67
import jakarta.validation.Valid;
78
import jakarta.validation.constraints.NotEmpty;
89
import lombok.AllArgsConstructor;
@@ -69,6 +70,16 @@ public ResponseEntity<?> getClubApplications(@CurrentUser CustomUserDetails user
6970
return Response.ok(clubApplyAdminService.getClubApplicationForms(user));
7071
}
7172

73+
@DeleteMapping("/application/{applicationFormId}")
74+
@Operation(summary = "클럽 지원서 양식 삭제", description = "클럽의 지원서 양식을 삭제합니다")
75+
@PreAuthorize("isAuthenticated()")
76+
@SecurityRequirement(name = "BearerAuth")
77+
public ResponseEntity<?> deleteClubApplicationForm(@PathVariable String applicationFormId,
78+
@CurrentUser CustomUserDetails user) {
79+
clubApplyAdminService.deleteClubApplicationForm(applicationFormId, user);
80+
return Response.ok("success delete application");
81+
}
82+
7283
@GetMapping("/apply/info/{applicationFormId}")
7384
@Operation(summary = "클럽 지원자 현황", description = "클럽 지원자 현황을 불러옵니다")
7485
@PreAuthorize("isAuthenticated()")
@@ -105,13 +116,16 @@ public ResponseEntity<?> removeApplicant(@PathVariable String applicationFormId,
105116
return Response.ok("success delete applicant");
106117
}
107118

108-
@GetMapping(value = "/applicant/{applicationFormId}/events",produces = "text/event-stream")
109-
@Operation(summary = "지원자 상태 변경 실시간 이벤트",
110-
description = "지원자의 상태 변경을 실시간으로 받아볼 수 있는 SSE 엔드포인트입니다.")
119+
@GetMapping(value = "/applicant/{applicationFormId}/events", produces = "text/event-stream")
120+
@Operation(summary = "지원자 상태 변경 실시간 이벤트",
121+
description = "지원자의 상태 변경을 실시간으로 받아볼 수 있는 SSE 엔드포인트입니다.")
111122
@PreAuthorize("isAuthenticated()")
112123
@SecurityRequirement(name = "BearerAuth")
113-
public SseEmitter getApplicantStatusEvents(@PathVariable String applicationFormId,
124+
public SseEmitter getApplicantStatusEvents(HttpServletResponse response,
125+
@PathVariable String applicationFormId,
114126
@CurrentUser CustomUserDetails user) {
127+
response.addHeader("X-Accel-Buffering", "no");
128+
response.addHeader("Cache-Control", "no-cache");
115129
return clubApplyAdminService.createSseConnection(applicationFormId, user);
116130
}
117131

backend/src/main/java/moadong/club/controller/ClubApplyPublicController.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,12 +34,11 @@ public ResponseEntity<?> applyToClub(@PathVariable String clubId,
3434
return Response.ok("success apply");
3535
}
3636

37-
@GetMapping("/apply")
37+
@GetMapping("/apply")
3838
@Operation(summary = "클럽의 활성화된 지원서 목록 불러오기", description = "클럽의 활성화된 모든 지원서 목록을 불러옵니다")
3939
public ResponseEntity<?> getActiveApplicationForms(@PathVariable String clubId) {
4040
return Response.ok(clubApplyPublicService.getActiveApplicationForms(clubId));
4141
}
4242

4343

44-
4544
}

backend/src/main/java/moadong/club/controller/ClubSearchController.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ public class ClubSearchController {
2929
+ "keyword에 빈칸 입력 시 전체 검색<br>"
3030
+ "recruitmentStatus, category, division에 all 입력 시 전체 검색<br>"
3131
+ "<br>"
32-
+ "keyword는 대소문자 구분 없이 자유롭게 검색"
32+
+ "keyword는 대소문자 구분 없이 자유롭게 검색<br>"
3333
+ "recruitmentStatus은 모집상태로 ALWAYS(상시모집), OPEN(모집중), CLOSED(모집마감), UPCOMING(모집예정)<br>"
3434
+ "division은 분과로 중동<br>"
3535
+ "category는 종류로 봉사, 종교, 취미교양, 학술, 운동, 공연, 기타<br>")

backend/src/main/java/moadong/club/entity/Club.java

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,8 @@
11
package moadong.club.entity;
22

3-
import java.time.format.DateTimeFormatter;
4-
import java.util.List;
5-
import java.util.Locale;
6-
import java.util.Map;
7-
83
import com.google.firebase.messaging.FirebaseMessaging;
94
import com.google.firebase.messaging.FirebaseMessagingException;
105
import com.google.firebase.messaging.Message;
11-
import com.google.firebase.messaging.Notification;
126
import lombok.AllArgsConstructor;
137
import lombok.Builder;
148
import lombok.Getter;
@@ -25,6 +19,9 @@
2519
import org.springframework.data.mongodb.core.mapping.Document;
2620
import org.springframework.data.mongodb.core.mapping.Field;
2721

22+
import java.util.List;
23+
import java.util.Map;
24+
2825
@Slf4j
2926
@Document("clubs")
3027
@AllArgsConstructor
@@ -49,15 +46,18 @@ public class Club implements Persistable<String> {
4946
@Field("recruitmentInformation")
5047
private ClubRecruitmentInformation clubRecruitmentInformation;
5148

49+
@Field("description")
50+
private ClubDescription clubDescription;
51+
5252
@Version
5353
private Long version;
54-
5554
public Club() {
5655
this.name = "";
5756
this.category = "";
5857
this.division = "";
5958
this.state = ClubState.UNAVAILABLE;
6059
this.clubRecruitmentInformation = ClubRecruitmentInformation.builder().build();
60+
this.clubDescription = ClubDescription.builder().build();
6161
}
6262

6363
public Club(String userId) {
@@ -67,6 +67,7 @@ public Club(String userId) {
6767
this.state = ClubState.UNAVAILABLE;
6868
this.clubRecruitmentInformation = ClubRecruitmentInformation.builder().build();
6969
this.userId = userId;
70+
this.clubDescription = ClubDescription.builder().build();
7071
}
7172

7273
public Club(String id, String userId) {
@@ -77,15 +78,19 @@ public Club(String id, String userId) {
7778
this.state = ClubState.UNAVAILABLE;
7879
this.clubRecruitmentInformation = ClubRecruitmentInformation.builder().build();
7980
this.userId = userId;
81+
this.clubDescription = ClubDescription.builder().build();
8082
}
8183

8284
@Builder
8385
public Club(String name, String category, String division,
86+
String userId,
8487
ClubRecruitmentInformation clubRecruitmentInformation) {
8588
this.name = name;
8689
this.category = category;
8790
this.division = division;
91+
this.userId = userId;
8892
this.clubRecruitmentInformation = clubRecruitmentInformation;
93+
this.clubDescription = ClubDescription.builder().build();
8994
}
9095

9196
public void update(ClubInfoRequest request) {
@@ -98,6 +103,7 @@ public void update(ClubInfoRequest request) {
98103
this.state = ClubState.AVAILABLE;
99104
this.socialLinks = request.socialLinks();
100105
this.clubRecruitmentInformation.update(request);
106+
this.clubDescription = request.description().toEntity();
101107
}
102108

103109
private void validateTags(List<String> tags) {

backend/src/main/java/moadong/club/entity/ClubApplicationForm.java

Lines changed: 38 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,26 +2,32 @@
22

33
import jakarta.persistence.Id;
44
import jakarta.validation.constraints.NotNull;
5-
import java.time.LocalDateTime;
6-
import java.time.ZoneId;
7-
import java.time.ZonedDateTime;
8-
import java.util.ArrayList;
9-
import java.util.List;
105
import lombok.AllArgsConstructor;
116
import lombok.Builder;
127
import lombok.Getter;
13-
import moadong.club.enums.ApplicantStatus;
8+
import moadong.club.enums.ApplicationFormMode;
149
import moadong.club.enums.ApplicationFormStatus;
1510
import moadong.club.enums.SemesterTerm;
11+
import moadong.global.exception.ErrorCode;
12+
import moadong.global.exception.RestApiException;
1613
import org.springframework.data.annotation.Version;
1714
import org.springframework.data.domain.Persistable;
1815
import org.springframework.data.mongodb.core.mapping.Document;
1916

17+
import java.time.LocalDateTime;
18+
import java.time.ZoneId;
19+
import java.time.ZonedDateTime;
20+
import java.util.ArrayList;
21+
import java.util.Arrays;
22+
import java.util.List;
23+
import java.util.Optional;
24+
2025
@Document("club_application_forms")
2126
@AllArgsConstructor
2227
@Getter
2328
@Builder(toBuilder = true)
2429
public class ClubApplicationForm implements Persistable<String> {
30+
private static final String[] externalApplicationUrlAllowed = {"https://forms.gle", "https://docs.google.com/forms", "https://form.naver.com", "https://naver.me"};
2531

2632
@Id
2733
private String id;
@@ -57,9 +63,20 @@ public class ClubApplicationForm implements Persistable<String> {
5763
@Builder.Default
5864
private ApplicationFormStatus status = ApplicationFormStatus.UNPUBLISHED;
5965

66+
@NotNull
67+
@Builder.Default
68+
private ApplicationFormMode formMode = ApplicationFormMode.INTERNAL;
69+
70+
@Builder.Default
71+
private String externalApplicationUrl = "";
72+
6073
@Version
6174
private Long version;
6275

76+
public ApplicationFormMode getFormMode() {
77+
return Optional.ofNullable(this.formMode).orElse(ApplicationFormMode.INTERNAL);
78+
}
79+
6380
public void updateFormTitle(String title) {
6481
this.title = title;
6582
}
@@ -89,6 +106,21 @@ public void updateFormStatus(boolean activeFlag) {
89106
this.status = ApplicationFormStatus.fromFlag(this.status, activeFlag);
90107
}
91108

109+
public void updateFormMode(ApplicationFormMode formMode) {
110+
this.formMode = formMode;
111+
}
112+
113+
public void updateExternalApplicationUrl(String externalApplicationUrl) {
114+
boolean allowed = Arrays.stream(externalApplicationUrlAllowed)
115+
.anyMatch(externalApplicationUrl::startsWith);
116+
117+
if (!allowed) {
118+
throw new RestApiException(ErrorCode.NOT_ALLOWED_EXTERNAL_URL);
119+
}
120+
121+
this.externalApplicationUrl = externalApplicationUrl.trim();
122+
}
123+
92124
@Override
93125
public boolean isNew() {
94126
return this.version == null;
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
package moadong.club.entity;
2+
3+
import lombok.AllArgsConstructor;
4+
import lombok.Builder;
5+
import lombok.Getter;
6+
import lombok.NoArgsConstructor;
7+
8+
import java.util.List;
9+
10+
@Getter
11+
@Builder
12+
@AllArgsConstructor
13+
@NoArgsConstructor
14+
public class ClubAward {
15+
16+
private String semester;
17+
18+
private List<String> achievements;
19+
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
package moadong.club.entity;
2+
3+
import lombok.AllArgsConstructor;
4+
import lombok.Builder;
5+
import lombok.Getter;
6+
import lombok.NoArgsConstructor;
7+
8+
import java.util.List;
9+
10+
@Getter
11+
@Builder
12+
@AllArgsConstructor
13+
@NoArgsConstructor
14+
public class ClubDescription {
15+
16+
private String introDescription;
17+
18+
private String activityDescription;
19+
20+
private List<ClubAward> awards;
21+
22+
private ClubIdealCandidate idealCandidate;
23+
24+
private String benefits;
25+
26+
private List<Faq> faqs;
27+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
package moadong.club.entity;
2+
3+
import lombok.AllArgsConstructor;
4+
import lombok.Builder;
5+
import lombok.Getter;
6+
import lombok.NoArgsConstructor;
7+
8+
import java.util.List;
9+
10+
@Getter
11+
@Builder
12+
@AllArgsConstructor
13+
@NoArgsConstructor
14+
public class ClubIdealCandidate {
15+
16+
private List<String> tags;
17+
18+
private String content;
19+
}

backend/src/main/java/moadong/club/entity/ClubRecruitmentInformation.java

Lines changed: 18 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,6 @@
66
import jakarta.persistence.Id;
77
import jakarta.validation.constraints.NotNull;
88
import jakarta.validation.constraints.Pattern;
9-
import java.time.LocalDateTime;
10-
import java.time.ZoneId;
11-
import java.time.ZonedDateTime;
12-
import java.util.List;
139
import lombok.AllArgsConstructor;
1410
import lombok.Builder;
1511
import lombok.Getter;
@@ -19,6 +15,12 @@
1915
import moadong.global.RegexConstants;
2016
import org.checkerframework.common.aliasing.qual.Unique;
2117

18+
import java.time.Instant;
19+
import java.time.LocalDateTime;
20+
import java.time.ZoneId;
21+
import java.time.ZonedDateTime;
22+
import java.util.List;
23+
2224
@AllArgsConstructor
2325
@Getter
2426
@Builder(toBuilder = true)
@@ -38,19 +40,16 @@ public class ClubRecruitmentInformation {
3840
@Column(length = 30)
3941
private String introduction;
4042

41-
@Column(length = 20000)
42-
private String description;
43-
4443
@Column(length = 5)
4544
private String presidentName;
4645

4746
@Pattern(regexp = RegexConstants.PHONE_NUMBER, message = "전화번호 형식이 올바르지 않습니다.")
4847
@Column(length = 13)
4948
private String presidentTelephoneNumber;
5049

51-
private LocalDateTime recruitmentStart;
50+
private Instant recruitmentStart;
5251

53-
private LocalDateTime recruitmentEnd;
52+
private Instant recruitmentEnd;
5453

5554
private String recruitmentTarget;
5655

@@ -60,12 +59,12 @@ public class ClubRecruitmentInformation {
6059

6160
private List<String> tags;
6261

63-
private List<Faq> faqs;
64-
6562
@Enumerated(EnumType.STRING)
6663
@NotNull
6764
private ClubRecruitmentStatus clubRecruitmentStatus;
6865

66+
private LocalDateTime lastModifiedDate;
67+
6968
public void updateLogo(String logo) {
7069
this.logo = logo;
7170
}
@@ -75,12 +74,10 @@ public void updateRecruitmentStatus(ClubRecruitmentStatus status) {
7574
}
7675

7776
public void updateDescription(ClubRecruitmentInfoUpdateRequest request) {
78-
this.description = request.description();
7977
this.recruitmentStart = request.recruitmentStart();
8078
this.recruitmentEnd = request.recruitmentEnd();
8179
this.recruitmentTarget = request.recruitmentTarget();
8280
this.externalApplicationUrl = request.externalApplicationUrl();
83-
this.faqs = request.faqs();
8481
}
8582

8683
public boolean hasRecruitmentPeriod() {
@@ -121,4 +118,12 @@ public void update(ClubInfoRequest request) {
121118
public void updateCover(String cover) {
122119
this.cover = cover;
123120
}
121+
122+
private void setLastModifiedDate(LocalDateTime lastModifiedDate) {
123+
this.lastModifiedDate = lastModifiedDate;
124+
}
125+
126+
public void updateLastModifiedDate() {
127+
setLastModifiedDate(LocalDateTime.now());
128+
}
124129
}

0 commit comments

Comments
 (0)