From 133a387c18745a6ea5132494257cca434b0c56d6 Mon Sep 17 00:00:00 2001 From: JanooGwan Date: Thu, 19 Feb 2026 02:43:53 +0900 Subject: [PATCH 1/3] =?UTF-8?q?feat:=20=EB=8F=99=EC=95=84=EB=A6=AC=20?= =?UTF-8?q?=EC=84=A4=EC=A0=95=20=EA=B4=80=EB=A6=AC=20API=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../club/controller/ClubSettingsApi.java | 61 +++++++++ .../controller/ClubSettingsController.java | 41 ++++++ .../domain/club/dto/ClubSettingsResponse.java | 72 +++++++++++ .../club/dto/ClubSettingsUpdateRequest.java | 18 +++ .../agit/konect/domain/club/model/Club.java | 58 ++++++--- .../club/service/ClubSettingsService.java | 120 ++++++++++++++++++ .../V29__add_club_settings_toggle_columns.sql | 3 + 7 files changed, 356 insertions(+), 17 deletions(-) create mode 100644 src/main/java/gg/agit/konect/domain/club/controller/ClubSettingsApi.java create mode 100644 src/main/java/gg/agit/konect/domain/club/controller/ClubSettingsController.java create mode 100644 src/main/java/gg/agit/konect/domain/club/dto/ClubSettingsResponse.java create mode 100644 src/main/java/gg/agit/konect/domain/club/dto/ClubSettingsUpdateRequest.java create mode 100644 src/main/java/gg/agit/konect/domain/club/service/ClubSettingsService.java create mode 100644 src/main/resources/db/migration/V29__add_club_settings_toggle_columns.sql diff --git a/src/main/java/gg/agit/konect/domain/club/controller/ClubSettingsApi.java b/src/main/java/gg/agit/konect/domain/club/controller/ClubSettingsApi.java new file mode 100644 index 00000000..6ba983fc --- /dev/null +++ b/src/main/java/gg/agit/konect/domain/club/controller/ClubSettingsApi.java @@ -0,0 +1,61 @@ +package gg.agit.konect.domain.club.controller; + +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PatchMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; + +import gg.agit.konect.domain.club.dto.ClubSettingsResponse; +import gg.agit.konect.domain.club.dto.ClubSettingsUpdateRequest; +import gg.agit.konect.global.auth.annotation.UserId; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.validation.Valid; + +@Tag(name = "(Normal) Club - Settings: 동아리 설정 관리") +@RequestMapping("/clubs") +public interface ClubSettingsApi { + + @Operation(summary = "동아리 설정 정보를 조회한다.", description = """ + 동아리 설정 관리 화면에 필요한 정보를 조회합니다. + + 토글 상태(모집공고, 지원서, 회비)와 각 항목의 요약 정보를 반환합니다. + - 모집공고: 모집 기간 정보 + - 지원서: 문항 개수 + - 회비: 금액, 은행, 계좌번호, 예금주 + + 요약 정보가 설정되지 않은 경우 해당 필드는 null로 반환됩니다. + + ## 에러 + - NOT_FOUND_CLUB (404): 동아리를 찾을 수 없습니다. + - NOT_FOUND_USER (404): 유저를 찾을 수 없습니다. + - FORBIDDEN_CLUB_MANAGER_ACCESS (403): 동아리 매니저 권한이 없습니다. + """) + @GetMapping("/{clubId}/settings") + ResponseEntity getSettings( + @PathVariable(name = "clubId") Integer clubId, + @UserId Integer userId + ); + + @Operation(summary = "동아리 설정을 변경한다.", description = """ + 동아리의 토글 설정(모집공고, 지원서, 회비 활성화 여부)을 변경합니다. + + 요청에 포함된 필드만 업데이트됩니다. (PATCH 방식) + - isRecruitmentEnabled: 모집공고 활성화 여부 + - isApplicationEnabled: 지원서 활성화 여부 + - isFeeEnabled: 회비 활성화 여부 + + ## 에러 + - NOT_FOUND_CLUB (404): 동아리를 찾을 수 없습니다. + - NOT_FOUND_USER (404): 유저를 찾을 수 없습니다. + - FORBIDDEN_CLUB_MANAGER_ACCESS (403): 동아리 매니저 권한이 없습니다. + """) + @PatchMapping("/{clubId}/settings") + ResponseEntity updateSettings( + @PathVariable(name = "clubId") Integer clubId, + @Valid @RequestBody ClubSettingsUpdateRequest request, + @UserId Integer userId + ); +} diff --git a/src/main/java/gg/agit/konect/domain/club/controller/ClubSettingsController.java b/src/main/java/gg/agit/konect/domain/club/controller/ClubSettingsController.java new file mode 100644 index 00000000..7fd032b5 --- /dev/null +++ b/src/main/java/gg/agit/konect/domain/club/controller/ClubSettingsController.java @@ -0,0 +1,41 @@ +package gg.agit.konect.domain.club.controller; + +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import gg.agit.konect.domain.club.dto.ClubSettingsResponse; +import gg.agit.konect.domain.club.dto.ClubSettingsUpdateRequest; +import gg.agit.konect.domain.club.service.ClubSettingsService; +import gg.agit.konect.global.auth.annotation.UserId; +import jakarta.validation.Valid; +import lombok.RequiredArgsConstructor; + +@RestController +@RequiredArgsConstructor +@RequestMapping("/clubs") +public class ClubSettingsController implements ClubSettingsApi { + + private final ClubSettingsService clubSettingsService; + + @Override + public ResponseEntity getSettings( + @PathVariable(name = "clubId") Integer clubId, + @UserId Integer userId + ) { + ClubSettingsResponse response = clubSettingsService.getSettings(clubId, userId); + return ResponseEntity.ok(response); + } + + @Override + public ResponseEntity updateSettings( + @PathVariable(name = "clubId") Integer clubId, + @Valid @RequestBody ClubSettingsUpdateRequest request, + @UserId Integer userId + ) { + ClubSettingsResponse response = clubSettingsService.updateSettings(clubId, userId, request); + return ResponseEntity.ok(response); + } +} diff --git a/src/main/java/gg/agit/konect/domain/club/dto/ClubSettingsResponse.java b/src/main/java/gg/agit/konect/domain/club/dto/ClubSettingsResponse.java new file mode 100644 index 00000000..beb81e25 --- /dev/null +++ b/src/main/java/gg/agit/konect/domain/club/dto/ClubSettingsResponse.java @@ -0,0 +1,72 @@ +package gg.agit.konect.domain.club.dto; + +import static io.swagger.v3.oas.annotations.media.Schema.RequiredMode.NOT_REQUIRED; +import static io.swagger.v3.oas.annotations.media.Schema.RequiredMode.REQUIRED; + +import java.time.LocalDate; + +import com.fasterxml.jackson.annotation.JsonFormat; + +import io.swagger.v3.oas.annotations.media.Schema; + +@Schema(description = "동아리 설정 관리 응답") +public record ClubSettingsResponse( + @Schema(description = "모집공고 활성화 여부", example = "true", requiredMode = REQUIRED) + Boolean isRecruitmentEnabled, + + @Schema(description = "지원서 활성화 여부", example = "true", requiredMode = REQUIRED) + Boolean isApplicationEnabled, + + @Schema(description = "회비 활성화 여부", example = "false", requiredMode = REQUIRED) + Boolean isFeeEnabled, + + @Schema(description = "모집공고 요약 정보", requiredMode = NOT_REQUIRED) + RecruitmentSummary recruitment, + + @Schema(description = "지원서 요약 정보", requiredMode = NOT_REQUIRED) + ApplicationSummary application, + + @Schema(description = "회비 요약 정보", requiredMode = NOT_REQUIRED) + FeeSummary fee +) { + @Schema(description = "모집공고 요약") + public record RecruitmentSummary( + @Schema(description = "모집 시작일", example = "2026.02.02", requiredMode = NOT_REQUIRED) + @JsonFormat(pattern = "yyyy.MM.dd") + LocalDate startDate, + + @Schema(description = "모집 종료일", example = "2027.02.02", requiredMode = NOT_REQUIRED) + @JsonFormat(pattern = "yyyy.MM.dd") + LocalDate endDate, + + @Schema(description = "상시 모집 여부", example = "false", requiredMode = REQUIRED) + Boolean isAlwaysRecruiting + ) { + } + + @Schema(description = "지원서 요약") + public record ApplicationSummary( + @Schema(description = "문항 개수", example = "3", requiredMode = REQUIRED) + Integer questionCount + ) { + } + + @Schema(description = "회비 요약") + public record FeeSummary( + @Schema(description = "회비 금액", example = "3만원", requiredMode = NOT_REQUIRED) + String amount, + + @Schema(description = "은행 고유 ID", example = "1", requiredMode = NOT_REQUIRED) + Integer bankId, + + @Schema(description = "은행명", example = "국민은행", requiredMode = NOT_REQUIRED) + String bankName, + + @Schema(description = "계좌번호", example = "123-456-7890", requiredMode = NOT_REQUIRED) + String accountNumber, + + @Schema(description = "예금주", example = "BCSD", requiredMode = NOT_REQUIRED) + String accountHolder + ) { + } +} diff --git a/src/main/java/gg/agit/konect/domain/club/dto/ClubSettingsUpdateRequest.java b/src/main/java/gg/agit/konect/domain/club/dto/ClubSettingsUpdateRequest.java new file mode 100644 index 00000000..7918d2c9 --- /dev/null +++ b/src/main/java/gg/agit/konect/domain/club/dto/ClubSettingsUpdateRequest.java @@ -0,0 +1,18 @@ +package gg.agit.konect.domain.club.dto; + +import static io.swagger.v3.oas.annotations.media.Schema.RequiredMode.NOT_REQUIRED; + +import io.swagger.v3.oas.annotations.media.Schema; + +@Schema(description = "동아리 설정 변경 요청") +public record ClubSettingsUpdateRequest( + @Schema(description = "모집공고 활성화 여부", example = "true", requiredMode = NOT_REQUIRED) + Boolean isRecruitmentEnabled, + + @Schema(description = "지원서 활성화 여부", example = "true", requiredMode = NOT_REQUIRED) + Boolean isApplicationEnabled, + + @Schema(description = "회비 활성화 여부", example = "false", requiredMode = NOT_REQUIRED) + Boolean isFeeEnabled +) { +} diff --git a/src/main/java/gg/agit/konect/domain/club/model/Club.java b/src/main/java/gg/agit/konect/domain/club/model/Club.java index 0f0ffac3..dc44ee3b 100644 --- a/src/main/java/gg/agit/konect/domain/club/model/Club.java +++ b/src/main/java/gg/agit/konect/domain/club/model/Club.java @@ -7,8 +7,6 @@ import static jakarta.persistence.GenerationType.IDENTITY; import static lombok.AccessLevel.PROTECTED; -import java.time.LocalDate; - import org.springframework.util.StringUtils; import gg.agit.konect.domain.club.dto.ClubCreateRequest; @@ -77,8 +75,14 @@ public class Club extends BaseEntity { @Column(name = "fee_account_holder", length = 100) private String feeAccountHolder; - @Column(name = "fee_deadline") - private LocalDate feeDeadline; + @Column(name = "is_fee_required") + private Boolean isFeeRequired; + + @Column(name = "is_recruitment_enabled") + private Boolean isRecruitmentEnabled; + + @Column(name = "is_application_enabled") + private Boolean isApplicationEnabled; @OneToOne(mappedBy = "club", fetch = LAZY, cascade = ALL, orphanRemoval = true) private ClubRecruitment clubRecruitment; @@ -97,7 +101,9 @@ private Club( String feeBank, String feeAccountNumber, String feeAccountHolder, - LocalDate feeDeadline, + Boolean isFeeRequired, + Boolean isRecruitmentEnabled, + Boolean isApplicationEnabled, ClubRecruitment clubRecruitment ) { this.id = id; @@ -112,7 +118,9 @@ private Club( this.feeBank = feeBank; this.feeAccountNumber = feeAccountNumber; this.feeAccountHolder = feeAccountHolder; - this.feeDeadline = feeDeadline; + this.isFeeRequired = isFeeRequired; + this.isRecruitmentEnabled = isRecruitmentEnabled; + this.isApplicationEnabled = isApplicationEnabled; this.clubRecruitment = clubRecruitment; } @@ -133,18 +141,18 @@ public void replaceFeeInfo( String feeBank, String feeAccountNumber, String feeAccountHolder, - LocalDate feeDeadline + Boolean isFeeRequired ) { - if (isFeeInfoEmpty(feeAmount, feeBank, feeAccountNumber, feeAccountHolder, feeDeadline)) { + if (isFeeInfoEmpty(feeAmount, feeBank, feeAccountNumber, feeAccountHolder, isFeeRequired)) { clearFeeInfo(); return; } - if (!isFeeInfoComplete(feeAmount, feeBank, feeAccountNumber, feeAccountHolder, feeDeadline)) { + if (!isFeeInfoComplete(feeAmount, feeBank, feeAccountNumber, feeAccountHolder, isFeeRequired)) { throw CustomException.of(INVALID_REQUEST_BODY); } - updateFeeInfo(feeAmount, feeBank, feeAccountNumber, feeAccountHolder, feeDeadline); + updateFeeInfo(feeAmount, feeBank, feeAccountNumber, feeAccountHolder, isFeeRequired); } public void updateInfo(String description, String imageUrl, String location, String introduce) { @@ -159,18 +167,34 @@ public void updateBasicInfo(String name, ClubCategory clubCategory) { // 어드 this.clubCategory = clubCategory; } + public void updateSettings( + Boolean isRecruitmentEnabled, + Boolean isApplicationEnabled, + Boolean isFeeRequired + ) { + if (isRecruitmentEnabled != null) { + this.isRecruitmentEnabled = isRecruitmentEnabled; + } + if (isApplicationEnabled != null) { + this.isApplicationEnabled = isApplicationEnabled; + } + if (isFeeRequired != null) { + this.isFeeRequired = isFeeRequired; + } + } + private boolean isFeeInfoEmpty( String feeAmount, String feeBank, String feeAccountNumber, String feeAccountHolder, - LocalDate feeDeadline + Boolean isFeeRequired ) { return !StringUtils.hasText(feeAmount) && !StringUtils.hasText(feeBank) && !StringUtils.hasText(feeAccountNumber) && !StringUtils.hasText(feeAccountHolder) - && feeDeadline == null; + && isFeeRequired == null; } private boolean isFeeInfoComplete( @@ -178,13 +202,13 @@ private boolean isFeeInfoComplete( String feeBank, String feeAccountNumber, String feeAccountHolder, - LocalDate feeDeadline + Boolean isFeeRequired ) { return StringUtils.hasText(feeAmount) && StringUtils.hasText(feeBank) && StringUtils.hasText(feeAccountNumber) && StringUtils.hasText(feeAccountHolder) - && feeDeadline != null; + && isFeeRequired != null; } private void updateFeeInfo( @@ -192,13 +216,13 @@ private void updateFeeInfo( String feeBank, String feeAccountNumber, String feeAccountHolder, - LocalDate feeDeadline + Boolean isFeeRequired ) { this.feeAmount = feeAmount; this.feeBank = feeBank; this.feeAccountNumber = feeAccountNumber; this.feeAccountHolder = feeAccountHolder; - this.feeDeadline = feeDeadline; + this.isFeeRequired = isFeeRequired; } private void clearFeeInfo() { @@ -206,6 +230,6 @@ private void clearFeeInfo() { this.feeBank = null; this.feeAccountNumber = null; this.feeAccountHolder = null; - this.feeDeadline = null; + this.isFeeRequired = null; } } diff --git a/src/main/java/gg/agit/konect/domain/club/service/ClubSettingsService.java b/src/main/java/gg/agit/konect/domain/club/service/ClubSettingsService.java new file mode 100644 index 00000000..25b20e14 --- /dev/null +++ b/src/main/java/gg/agit/konect/domain/club/service/ClubSettingsService.java @@ -0,0 +1,120 @@ +package gg.agit.konect.domain.club.service; + +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.util.StringUtils; + +import gg.agit.konect.domain.bank.repository.BankRepository; +import gg.agit.konect.domain.club.dto.ClubSettingsResponse; +import gg.agit.konect.domain.club.dto.ClubSettingsResponse.ApplicationSummary; +import gg.agit.konect.domain.club.dto.ClubSettingsResponse.FeeSummary; +import gg.agit.konect.domain.club.dto.ClubSettingsResponse.RecruitmentSummary; +import gg.agit.konect.domain.club.dto.ClubSettingsUpdateRequest; +import gg.agit.konect.domain.club.model.Club; +import gg.agit.konect.domain.club.repository.ClubApplyQuestionRepository; +import gg.agit.konect.domain.club.repository.ClubRecruitmentRepository; +import gg.agit.konect.domain.club.repository.ClubRepository; +import gg.agit.konect.domain.user.repository.UserRepository; +import lombok.RequiredArgsConstructor; + +@Service +@RequiredArgsConstructor +@Transactional(readOnly = true) +public class ClubSettingsService { + + private final ClubRepository clubRepository; + private final ClubRecruitmentRepository clubRecruitmentRepository; + private final ClubApplyQuestionRepository clubApplyQuestionRepository; + private final BankRepository bankRepository; + private final UserRepository userRepository; + private final ClubPermissionValidator clubPermissionValidator; + + public ClubSettingsResponse getSettings(Integer clubId, Integer userId) { + userRepository.getById(userId); + Club club = clubRepository.getById(clubId); + + clubPermissionValidator.validateManagerAccess(clubId, userId); + + RecruitmentSummary recruitmentSummary = buildRecruitmentSummary(clubId); + ApplicationSummary applicationSummary = buildApplicationSummary(clubId); + FeeSummary feeSummary = buildFeeSummary(club); + + return new ClubSettingsResponse( + Boolean.TRUE.equals(club.getIsRecruitmentEnabled()), + Boolean.TRUE.equals(club.getIsApplicationEnabled()), + Boolean.TRUE.equals(club.getIsFeeRequired()), + recruitmentSummary, + applicationSummary, + feeSummary + ); + } + + @Transactional + public ClubSettingsResponse updateSettings( + Integer clubId, + Integer userId, + ClubSettingsUpdateRequest request + ) { + userRepository.getById(userId); + Club club = clubRepository.getById(clubId); + + clubPermissionValidator.validateManagerAccess(clubId, userId); + + club.updateSettings( + request.isRecruitmentEnabled(), + request.isApplicationEnabled(), + request.isFeeEnabled() + ); + + RecruitmentSummary recruitmentSummary = buildRecruitmentSummary(clubId); + ApplicationSummary applicationSummary = buildApplicationSummary(clubId); + FeeSummary feeSummary = buildFeeSummary(club); + + return new ClubSettingsResponse( + Boolean.TRUE.equals(club.getIsRecruitmentEnabled()), + Boolean.TRUE.equals(club.getIsApplicationEnabled()), + Boolean.TRUE.equals(club.getIsFeeRequired()), + recruitmentSummary, + applicationSummary, + feeSummary + ); + } + + private RecruitmentSummary buildRecruitmentSummary(Integer clubId) { + return clubRecruitmentRepository.findByClubId(clubId) + .map(recruitment -> new RecruitmentSummary( + recruitment.getStartDate(), + recruitment.getEndDate(), + Boolean.TRUE.equals(recruitment.getIsAlwaysRecruiting()) + )) + .orElse(null); + } + + private ApplicationSummary buildApplicationSummary(Integer clubId) { + int questionCount = clubApplyQuestionRepository.findAllByClubIdOrderByIdAsc(clubId).size(); + return new ApplicationSummary(questionCount); + } + + private FeeSummary buildFeeSummary(Club club) { + if (!StringUtils.hasText(club.getFeeBank())) { + return null; + } + + Integer bankId = resolveBankId(club.getFeeBank()); + + return new FeeSummary( + club.getFeeAmount(), + bankId, + club.getFeeBank(), + club.getFeeAccountNumber(), + club.getFeeAccountHolder() + ); + } + + private Integer resolveBankId(String bankName) { + if (!StringUtils.hasText(bankName)) { + return null; + } + return bankRepository.getByName(bankName).getId(); + } +} diff --git a/src/main/resources/db/migration/V29__add_club_settings_toggle_columns.sql b/src/main/resources/db/migration/V29__add_club_settings_toggle_columns.sql new file mode 100644 index 00000000..0996ce1d --- /dev/null +++ b/src/main/resources/db/migration/V29__add_club_settings_toggle_columns.sql @@ -0,0 +1,3 @@ +-- 동아리 설정 토글 컬럼 추가 (모집공고 활성화, 지원서 활성화) +ALTER TABLE club ADD COLUMN is_recruitment_enabled TINYINT(1) DEFAULT NULL; +ALTER TABLE club ADD COLUMN is_application_enabled TINYINT(1) DEFAULT NULL; From 6d418b4ddcd7b491379a3b5014896e875ed0278b Mon Sep 17 00:00:00 2001 From: JanooGwan Date: Thu, 19 Feb 2026 02:51:05 +0900 Subject: [PATCH 2/3] =?UTF-8?q?refactor:=20=EC=A4=91=EB=B3=B5=20=ED=95=84?= =?UTF-8?q?=EB=93=9C(=ED=9A=8C=EB=B9=84=20=EB=82=A9=EB=B6=80=20=ED=95=84?= =?UTF-8?q?=EC=9A=94=20=EC=97=AC=EB=B6=80)=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../club/dto/ClubFeeInfoReplaceRequest.java | 7 +---- .../domain/club/dto/ClubFeeInfoResponse.java | 8 ++---- .../agit/konect/domain/club/model/Club.java | 26 +++++++------------ .../club/service/ClubApplicationService.java | 3 +-- 4 files changed, 13 insertions(+), 31 deletions(-) diff --git a/src/main/java/gg/agit/konect/domain/club/dto/ClubFeeInfoReplaceRequest.java b/src/main/java/gg/agit/konect/domain/club/dto/ClubFeeInfoReplaceRequest.java index 9d15f20c..88644fd0 100644 --- a/src/main/java/gg/agit/konect/domain/club/dto/ClubFeeInfoReplaceRequest.java +++ b/src/main/java/gg/agit/konect/domain/club/dto/ClubFeeInfoReplaceRequest.java @@ -1,7 +1,6 @@ package gg.agit.konect.domain.club.dto; import static io.swagger.v3.oas.annotations.media.Schema.RequiredMode.NOT_REQUIRED; -import static io.swagger.v3.oas.annotations.media.Schema.RequiredMode.REQUIRED; import io.swagger.v3.oas.annotations.media.Schema; import jakarta.validation.constraints.NotNull; @@ -22,10 +21,6 @@ public record ClubFeeInfoReplaceRequest( @Size(max = 100, message = "예금주는 최대 100자 입니다.") @Schema(description = "예금주", example = "BCSD", requiredMode = NOT_REQUIRED) - String accountHolder, - - @NotNull(message = "회비 납부 필요 여부는 필수로 입력해야 합니다.") - @Schema(description = "회비 납부 필요 여부", example = "true", requiredMode = REQUIRED) - Boolean isFeeRequired + String accountHolder ) { } diff --git a/src/main/java/gg/agit/konect/domain/club/dto/ClubFeeInfoResponse.java b/src/main/java/gg/agit/konect/domain/club/dto/ClubFeeInfoResponse.java index c7e4c1b8..7de0831d 100644 --- a/src/main/java/gg/agit/konect/domain/club/dto/ClubFeeInfoResponse.java +++ b/src/main/java/gg/agit/konect/domain/club/dto/ClubFeeInfoResponse.java @@ -19,10 +19,7 @@ public record ClubFeeInfoResponse( String accountNumber, @Schema(description = "예금주", example = "BCSD", requiredMode = REQUIRED) - String accountHolder, - - @Schema(description = "회비 납부 필요 여부", example = "true", requiredMode = REQUIRED) - Boolean isFeeRequired + String accountHolder ) { public static ClubFeeInfoResponse of(Club club, Integer bankId, String bankName) { return new ClubFeeInfoResponse( @@ -30,8 +27,7 @@ public static ClubFeeInfoResponse of(Club club, Integer bankId, String bankName) bankId, bankName, club.getFeeAccountNumber(), - club.getFeeAccountHolder(), - club.getIsFeeRequired() + club.getFeeAccountHolder() ); } } diff --git a/src/main/java/gg/agit/konect/domain/club/model/Club.java b/src/main/java/gg/agit/konect/domain/club/model/Club.java index dc44ee3b..3e946392 100644 --- a/src/main/java/gg/agit/konect/domain/club/model/Club.java +++ b/src/main/java/gg/agit/konect/domain/club/model/Club.java @@ -140,19 +140,18 @@ public void replaceFeeInfo( String feeAmount, String feeBank, String feeAccountNumber, - String feeAccountHolder, - Boolean isFeeRequired + String feeAccountHolder ) { - if (isFeeInfoEmpty(feeAmount, feeBank, feeAccountNumber, feeAccountHolder, isFeeRequired)) { + if (isFeeInfoEmpty(feeAmount, feeBank, feeAccountNumber, feeAccountHolder)) { clearFeeInfo(); return; } - if (!isFeeInfoComplete(feeAmount, feeBank, feeAccountNumber, feeAccountHolder, isFeeRequired)) { + if (!isFeeInfoComplete(feeAmount, feeBank, feeAccountNumber, feeAccountHolder)) { throw CustomException.of(INVALID_REQUEST_BODY); } - updateFeeInfo(feeAmount, feeBank, feeAccountNumber, feeAccountHolder, isFeeRequired); + updateFeeInfo(feeAmount, feeBank, feeAccountNumber, feeAccountHolder); } public void updateInfo(String description, String imageUrl, String location, String introduce) { @@ -187,42 +186,36 @@ private boolean isFeeInfoEmpty( String feeAmount, String feeBank, String feeAccountNumber, - String feeAccountHolder, - Boolean isFeeRequired + String feeAccountHolder ) { return !StringUtils.hasText(feeAmount) && !StringUtils.hasText(feeBank) && !StringUtils.hasText(feeAccountNumber) - && !StringUtils.hasText(feeAccountHolder) - && isFeeRequired == null; + && !StringUtils.hasText(feeAccountHolder); } private boolean isFeeInfoComplete( String feeAmount, String feeBank, String feeAccountNumber, - String feeAccountHolder, - Boolean isFeeRequired + String feeAccountHolder ) { return StringUtils.hasText(feeAmount) && StringUtils.hasText(feeBank) && StringUtils.hasText(feeAccountNumber) - && StringUtils.hasText(feeAccountHolder) - && isFeeRequired != null; + && StringUtils.hasText(feeAccountHolder); } private void updateFeeInfo( String feeAmount, String feeBank, String feeAccountNumber, - String feeAccountHolder, - Boolean isFeeRequired + String feeAccountHolder ) { this.feeAmount = feeAmount; this.feeBank = feeBank; this.feeAccountNumber = feeAccountNumber; this.feeAccountHolder = feeAccountHolder; - this.isFeeRequired = isFeeRequired; } private void clearFeeInfo() { @@ -230,6 +223,5 @@ private void clearFeeInfo() { this.feeBank = null; this.feeAccountNumber = null; this.feeAccountHolder = null; - this.isFeeRequired = null; } } diff --git a/src/main/java/gg/agit/konect/domain/club/service/ClubApplicationService.java b/src/main/java/gg/agit/konect/domain/club/service/ClubApplicationService.java index b61775e4..5ade109a 100644 --- a/src/main/java/gg/agit/konect/domain/club/service/ClubApplicationService.java +++ b/src/main/java/gg/agit/konect/domain/club/service/ClubApplicationService.java @@ -345,8 +345,7 @@ public ClubFeeInfoResponse replaceFeeInfo(Integer clubId, Integer userId, ClubFe request.amount(), bankName, request.accountNumber(), - request.accountHolder(), - request.isFeeRequired() + request.accountHolder() ); return ClubFeeInfoResponse.of(club, request.bankId(), bankName); From 021f04f2156993f647492ccdfa4142ffe4b0c740 Mon Sep 17 00:00:00 2001 From: JanooGwan Date: Thu, 19 Feb 2026 03:04:59 +0900 Subject: [PATCH 3/3] =?UTF-8?q?refactor:=20DB=20=EB=A7=88=EC=9D=B4?= =?UTF-8?q?=EA=B7=B8=EB=A0=88=EC=9D=B4=EC=85=98=20=EA=B8=B0=EB=B3=B8?= =?UTF-8?q?=EA=B0=92=20=EC=84=A4=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../migration/V29__add_club_settings_toggle_columns.sql | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/main/resources/db/migration/V29__add_club_settings_toggle_columns.sql b/src/main/resources/db/migration/V29__add_club_settings_toggle_columns.sql index 0996ce1d..58894e3e 100644 --- a/src/main/resources/db/migration/V29__add_club_settings_toggle_columns.sql +++ b/src/main/resources/db/migration/V29__add_club_settings_toggle_columns.sql @@ -1,3 +1,5 @@ --- 동아리 설정 토글 컬럼 추가 (모집공고 활성화, 지원서 활성화) -ALTER TABLE club ADD COLUMN is_recruitment_enabled TINYINT(1) DEFAULT NULL; -ALTER TABLE club ADD COLUMN is_application_enabled TINYINT(1) DEFAULT NULL; +ALTER TABLE club ADD COLUMN is_recruitment_enabled TINYINT(1) NOT NULL DEFAULT 1; +ALTER TABLE club ADD COLUMN is_application_enabled TINYINT(1) NOT NULL DEFAULT 1; + +UPDATE club SET is_recruitment_enabled = 1 WHERE is_recruitment_enabled IS NULL; +UPDATE club SET is_application_enabled = 1 WHERE is_application_enabled IS NULL;