Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,14 @@ public ResponseEntity<?> getClubDetail(@PathVariable String clubId) {
return Response.ok(clubDetailedPageResponse);
}

@GetMapping("/@{clubName}")
@Operation(summary = "클럽 상세 정보 조회", description = "클럽 이름을 이용해 상세 정보를 조회합니다.")
public ResponseEntity<?> getClubDetailByClubName(@PathVariable String clubName) {
ClubDetailedResponse clubDetailedResponse = clubProfileService.getClubDetailByClubName(clubName);
return Response.ok(clubDetailedResponse);
}


@PutMapping("/info")
@Operation(summary = "클럽 약력 수정", description = "클럽 약력을 수정합니다.<br>"
+ "tags는 최대 2개, 5글자 이내로 입력해야 합니다.<br>"
Expand Down
3 changes: 3 additions & 0 deletions backend/src/main/java/moadong/club/entity/Club.java
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
import org.springframework.data.annotation.Id;
import org.springframework.data.annotation.Version;
import org.springframework.data.domain.Persistable;
import org.springframework.data.mongodb.core.index.Indexed;
import org.springframework.data.mongodb.core.mapping.Document;
import org.springframework.data.mongodb.core.mapping.Field;

Expand All @@ -27,6 +28,8 @@ public class Club implements Persistable<String> {
@Id
private String id;

@Indexed(name = "uk_club_name_not_blank", unique = true,
partialFilter = "{ \"name\": { \"$type\": \"string\", \"$gt\": \"\" } }")
Comment on lines +31 to +32
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이름이 비어있지 않은것만 만들겠다는 뜻이군요 굳굳

private String name;

private String category;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,9 @@ public interface ClubRepository extends MongoRepository<Club, String> {
Long countByIdIn(List<String> id);

List<Club> findAllByClubRecruitmentInformation_ClubRecruitmentStatus(ClubRecruitmentStatus status);

Optional<Club> findClubByName(String name);

boolean existsByNameAndIdNot(String name, String id);

}
36 changes: 34 additions & 2 deletions backend/src/main/java/moadong/club/service/ClubProfileService.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import moadong.user.payload.CustomUserDetails;
import org.bson.types.ObjectId;
import org.javers.core.Javers;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

Expand All @@ -42,8 +43,9 @@ public class ClubProfileService {
public void updateClubInfo(ClubInfoRequest request, CustomUserDetails user) {
Club club = clubRepository.findClubByUserId(user.getId())
.orElseThrow(() -> new RestApiException(ErrorCode.CLUB_NOT_FOUND));
validateClubNameUnique(club.getId(), request.name());
club.update(request);
Club saved = clubRepository.save(club);
Club saved = saveClub(club);
javers.commit(user.getUsername(), saved);
}

Expand Down Expand Up @@ -94,13 +96,24 @@ public ClubDetailedResponse getClubDetail(String clubId) {
return new ClubDetailedResponse(clubDetailedResult);
}

public ClubDetailedResponse getClubDetailByClubName(String clubName) {
Club club = clubRepository.findClubByName(clubName)
.orElseThrow(() -> new RestApiException(ErrorCode.CLUB_NOT_FOUND));

ClubDetailedResult clubDetailedResult = ClubDetailedResult.of(
club
);
return new ClubDetailedResponse(clubDetailedResult);
}

@Transactional
public void updateClubInfoByClubId(String clubId, ClubInfoRequest request, CustomUserDetails user) {
ObjectId objectId = ObjectIdConverter.convertString(clubId);
Club club = clubRepository.findClubById(objectId)
.orElseThrow(() -> new RestApiException(ErrorCode.CLUB_NOT_FOUND));
validateClubNameUnique(club.getId(), request.name());
club.update(request);
Club saved = clubRepository.save(club);
Club saved = saveClub(club);
javers.commit(user.getUsername(), saved);
}

Expand Down Expand Up @@ -128,4 +141,23 @@ public void updateClubRecruitmentInfoByClubId(String clubId, ClubRecruitmentInfo
);
}
}

private void validateClubNameUnique(String clubId, String name) {
if (name == null || name.isBlank()) {
return;
}

if (clubRepository.existsByNameAndIdNot(name, clubId)) {
throw new RestApiException(ErrorCode.CLUB_NAME_ALREADY_EXISTS);
}
}

// 레이스 컨디션을 위한 시큐어 코딩
private Club saveClub(Club club) {
try {
return clubRepository.save(club);
} catch (DuplicateKeyException e) {
throw new RestApiException(ErrorCode.CLUB_NAME_ALREADY_EXISTS);
}
Comment on lines +156 to +161
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

DB 에서 막음으로써 레이스컨디션을 방지한것 좋습니다

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ public enum ErrorCode {
TOO_MANY_TAGS(HttpStatus.BAD_REQUEST, "600-8", "태그는 최대 3개까지 입력할 수 있습니다."),
TOO_LONG_TAG(HttpStatus.BAD_REQUEST, "600-9", "태그는 최대 5글자까지 입력할 수 있습니다."),
TOO_LONG_INTRODUCTION(HttpStatus.BAD_REQUEST, "600-10", "소개는 최대 24글자까지 입력할 수 있습니다."),
CLUB_NAME_ALREADY_EXISTS(HttpStatus.CONFLICT, "600-11", "이미 사용 중인 동아리 이름입니다."),

// 601xx: 파일/미디어 관련 오류
IMAGE_UPLOAD_FAILED(HttpStatus.INTERNAL_SERVER_ERROR, "601-1", "이미지 업로드에 실패하였습니다."),
Expand Down
Loading