Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
1d7f48d
feat: ๋™์•„๋ฆฌ ์ฃผ์ œ ํ•„๋“œ๋ฅผ ์‘๋‹ต์— ํฌํ•จ (#634)
dh2906 May 22, 2026
e31b019
chore: ์›น์šฉ ํ…Œ์ด๋ธ” ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜ ์ถ”๊ฐ€
dh2906 May 23, 2026
30aea71
feat: ์›น์šฉ ๋Œ€ํ•™/๋™์•„๋ฆฌ ์—”ํ‹ฐํ‹ฐ ์ถ”๊ฐ€
dh2906 May 23, 2026
358776a
refactor: ์›น์‚ฌ์ดํŠธ API๋ฅผ web ํ…Œ์ด๋ธ” ๊ธฐ๋ฐ˜์œผ๋กœ ๋ณ€๊ฒฝ
dh2906 May 23, 2026
f227c02
test: ์›น API ํ…Œ์ŠคํŠธ๋ฅผ web ์—”ํ‹ฐํ‹ฐ ๊ธฐ๋ฐ˜์œผ๋กœ ๋ณ€๊ฒฝ
dh2906 May 23, 2026
af1a825
feat: ์‹ ๊ทœ ๋™์•„๋ฆฌ ๋“ฑ๋ก ์š”์ฒญ API ์ถ”๊ฐ€ (#636)
dh2906 May 25, 2026
b3a3a4d
fix: ๋ถˆํ•„์š”ํ•œ ๋™์•„๋ฆฌ ์Šคํ‚ค๋งˆ ํ•„๋“œ ์ œ๊ฑฐ (#637)
dh2906 May 25, 2026
3163bb1
fix: ๋™์•„๋ฆฌ ๋“ฑ๋ก ์š”์ฒญ Slack ๋ฉ”์‹œ์ง€์— ์š”์ฒญ๊ฐ’ ์ „์ฒด ํ‘œ์‹œ (#638)
dh2906 May 25, 2026
0c2c476
fix: ๋™์•„๋ฆฌ ๋“ฑ๋ก ์š”์ฒญ Slack ๋ฉ”์‹œ์ง€ ํ˜•์‹ ์ •๋ฆฌ (#639)
dh2906 May 25, 2026
b22a1d5
fix: ๋Œ€ํ•™๋ณ„ ๋™์•„๋ฆฌ ์ˆ˜๋ฅผ ๋Œ€ํ•™ ์‘๋‹ต์— ๋ถ„๋ฆฌ (#640)
dh2906 May 26, 2026
b7b2a23
fix: ์›น์‚ฌ์ดํŠธ ํ•„ํ„ฐ ๋ชฉ๋ก์„ ํ‘œ์‹œ๋ช… ์ˆœ์„œ๋กœ ์ •๋ ฌ (#641)
dh2906 May 26, 2026
c04a980
feat: ๊ธฐ์กด ๋™์•„๋ฆฌ ์ •๋ณด ์ˆ˜์ • ์š”์ฒญ API ์ถ”๊ฐ€ (#642)
dh2906 May 26, 2026
9d8520e
feat: ๋™์•„๋ฆฌ ๋ถ„๊ณผ ์นดํ…Œ๊ณ ๋ฆฌ 8์ข…์œผ๋กœ ๊ฐœํŽธ
JanooGwan May 27, 2026
6847a80
chore: ์ „๊ตญ ๋™์•„๋ฆฌ 8๋ถ„๊ณผ import ๋ฐ์ดํ„ฐ ์ƒ์„ฑ
JanooGwan May 27, 2026
084b24a
fix: ๋ถ„๊ณผ ๋ณ€๊ฒฝ ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜ ๋Œ€์ƒ ๋ณด๊ฐ•
JanooGwan May 27, 2026
82ef470
fix: ๋™์•„๋ฆฌ ๋ถ„๊ณผ import ๊ฒ€์ฆ ํ๋ฆ„ ๋ณด๊ฐ•
JanooGwan May 27, 2026
e109134
fix: ๋™์•„๋ฆฌ ๋ถ„๊ณผ ๋ฆฌ๋ทฐ ์ง€์  ๋ฐ˜์˜
JanooGwan May 28, 2026
2116764
chore: ๊ฐœ์ธ์šฉ import ์Šคํฌ๋ฆฝํŠธ ์ถ”์  ์ œ๊ฑฐ
JanooGwan May 28, 2026
58f80fb
feat: ๋™์•„๋ฆฌ ๋ถ„๊ณผ ์นดํ…Œ๊ณ ๋ฆฌ 8์ข… ๊ฐœํŽธ
JanooGwan May 28, 2026
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
@@ -0,0 +1,20 @@
package gg.agit.konect.domain.club.controller;

import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PathVariable;

import gg.agit.konect.domain.club.dto.ClubInformationUpdateRequestDto;
import gg.agit.konect.domain.club.dto.ClubRegistrationRequestDto;
import io.swagger.v3.oas.annotations.parameters.RequestBody;

public interface ClubRegistrationRequestApi {

ResponseEntity<Void> registerClub(
@RequestBody ClubRegistrationRequestDto request
);

ResponseEntity<Void> requestClubInformationUpdate(
@PathVariable(name = "clubId") Integer clubId,
@RequestBody ClubInformationUpdateRequestDto request
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
package gg.agit.konect.domain.club.controller;

import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
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.ClubInformationUpdateRequestDto;
import gg.agit.konect.domain.club.dto.ClubRegistrationRequestDto;
import gg.agit.konect.domain.club.service.ClubRegistrationRequestService;
import gg.agit.konect.global.auth.annotation.PublicApi;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;

@Tag(name = "Club Registration", description = "๋™์•„๋ฆฌ ๋“ฑ๋ก ์š”์ฒญ API")
@RestController
@RequestMapping("/clubs")
@RequiredArgsConstructor
public class ClubRegistrationRequestController implements ClubRegistrationRequestApi {

private final ClubRegistrationRequestService clubRegistrationRequestService;

@Override
@Operation(
summary = "๋™์•„๋ฆฌ ๋“ฑ๋ก ์š”์ฒญ",
description = "๋น„๋กœ๊ทธ์ธ ์‚ฌ์šฉ์ž๊ฐ€ ์ƒˆ ๋™์•„๋ฆฌ ๋“ฑ๋ก์„ ์š”์ฒญํ•ฉ๋‹ˆ๋‹ค."
)
@PostMapping("/registration-requests")
@PublicApi
public ResponseEntity<Void> registerClub(
@Valid @RequestBody ClubRegistrationRequestDto request
) {
clubRegistrationRequestService.register(request);
return ResponseEntity.status(HttpStatus.CREATED).build();
}

@Override
@Operation(
summary = "๋™์•„๋ฆฌ ์ •๋ณด ์ˆ˜์ • ์š”์ฒญ",
description = "๋น„๋กœ๊ทธ์ธ ์‚ฌ์šฉ์ž๊ฐ€ ๊ธฐ์กด ๋™์•„๋ฆฌ ์ •๋ณด ์ˆ˜์ •์„ ์š”์ฒญํ•ฉ๋‹ˆ๋‹ค."
)
@PostMapping("/{clubId}/information-update-requests")
@PublicApi
public ResponseEntity<Void> requestClubInformationUpdate(
@PathVariable(name = "clubId") Integer clubId,
@Valid @RequestBody ClubInformationUpdateRequestDto request
) {
clubRegistrationRequestService.requestInformationUpdate(clubId, request);
return ResponseEntity.status(HttpStatus.CREATED).build();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
package gg.agit.konect.domain.club.dto;

import static io.swagger.v3.oas.annotations.media.Schema.RequiredMode.REQUIRED;

import java.util.List;

import gg.agit.konect.domain.club.enums.ClubCategory;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Size;

@Schema(name = "ClubInformationUpdateRequest", description = "๋™์•„๋ฆฌ ์ •๋ณด ์ˆ˜์ • ์š”์ฒญ")
public record ClubInformationUpdateRequestDto(

@Schema(description = "๋Œ€ํ•™๊ต ๋ช…", example = "ํ•œ๊ตญ๊ธฐ์ˆ ๊ต์œก๋Œ€ํ•™๊ต", requiredMode = REQUIRED)
@NotBlank(message = "๋Œ€ํ•™๊ต ๋ช…์€ ํ•„์ˆ˜์ž…๋‹ˆ๋‹ค.")
String universityName,

@Schema(description = "๋™์•„๋ฆฌ ๋ช…", example = "BCSD Lab", requiredMode = REQUIRED)
@NotBlank(message = "๋™์•„๋ฆฌ ๋ช…์€ ํ•„์ˆ˜์ž…๋‹ˆ๋‹ค.")
@Size(max = 50, message = "๋™์•„๋ฆฌ ๋ช…์€ ์ตœ๋Œ€ 50์ž์ž…๋‹ˆ๋‹ค.")
String clubName,

@Schema(description = "๋™์•„๋ฆฌ ๋ถ„๊ณผ", example = "ACADEMIC", requiredMode = REQUIRED)
@NotNull(message = "๋™์•„๋ฆฌ ๋ถ„๊ณผ๋Š” ํ•„์ˆ˜์ž…๋‹ˆ๋‹ค.")
ClubCategory clubCategory,

@Schema(description = "๋™์•„๋ฆฌ ์ฃผ์ œ", example = "์ฝ”๋”ฉ", requiredMode = REQUIRED)
@NotBlank(message = "๋™์•„๋ฆฌ ์ฃผ์ œ๋Š” ํ•„์ˆ˜์ž…๋‹ˆ๋‹ค.")
@Size(max = 20, message = "๋™์•„๋ฆฌ ์ฃผ์ œ๋Š” ์ตœ๋Œ€ 20์ž์ž…๋‹ˆ๋‹ค.")
String clubTopic,

@Schema(description = "๋™์•„๋ฆฌ ์ด๋ชจ์ง€", example = "๐Ÿ’ป", requiredMode = REQUIRED)
@NotBlank(message = "๋™์•„๋ฆฌ ์ด๋ชจ์ง€๋Š” ํ•„์ˆ˜์ž…๋‹ˆ๋‹ค.")
@Size(max = 10, message = "๋™์•„๋ฆฌ ์ด๋ชจ์ง€๋Š” ์ตœ๋Œ€ 10์ž์ž…๋‹ˆ๋‹ค.")
String clubEmoji,

@Schema(
description = "ํ•œ ์ค„ ์†Œ๊ฐœ (์ตœ๋Œ€ 30์ž)",
example = "์ฝ”๋”ฉ ๋™์•„๋ฆฌ์ž…๋‹ˆ๋‹ค.",
requiredMode = REQUIRED
)
@NotBlank(message = "ํ•œ ์ค„ ์†Œ๊ฐœ๋Š” ํ•„์ˆ˜์ž…๋‹ˆ๋‹ค.")
@Size(max = 30, message = "ํ•œ ์ค„ ์†Œ๊ฐœ๋Š” ์ตœ๋Œ€ 30์ž์ž…๋‹ˆ๋‹ค.")
String shortDescription,

@Schema(
description = "๋™์•„๋ฆฌ ์†Œ๊ฐœ (์ตœ๋Œ€ 2000์ž)",
example = "์ƒ์„ธํ•œ ๋™์•„๋ฆฌ ์†Œ๊ฐœ ๋‚ด์šฉ...",
requiredMode = REQUIRED
)
@NotBlank(message = "๋™์•„๋ฆฌ ์†Œ๊ฐœ๋Š” ํ•„์ˆ˜์ž…๋‹ˆ๋‹ค.")
@Size(max = 2000, message = "๋™์•„๋ฆฌ ์†Œ๊ฐœ๋Š” ์ตœ๋Œ€ 2000์ž์ž…๋‹ˆ๋‹ค.")
String fullIntroduction,

@Schema(
description = "์‚ฌ์ง„ ๋ฐ ์˜์ƒ URL ๋ชฉ๋ก (์ตœ๋Œ€ 5๊ฐœ)",
example = "[\"https://example.com/image1.jpg\"]"
)
@Size(max = 5, message = "์‚ฌ์ง„ ๋ฐ ์˜์ƒ์€ ์ตœ๋Œ€ 5๊ฐœ๊นŒ์ง€ ์—…๋กœ๋“œ ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.")
List<
@NotBlank(message = "์ด๋ฏธ์ง€ URL์€ ํ•„์ˆ˜์ž…๋‹ˆ๋‹ค.")
@Size(max = 500, message = "์ด๋ฏธ์ง€ URL์€ ์ตœ๋Œ€ 500์ž์ž…๋‹ˆ๋‹ค.")
String> imageUrls
) {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
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.util.List;

import gg.agit.konect.domain.club.enums.ClubCategory;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Size;

@Schema(name = "ClubRegistrationRequest", description = "๋™์•„๋ฆฌ ๋“ฑ๋ก ์š”์ฒญ")
public record ClubRegistrationRequestDto(

@Schema(description = "๋Œ€ํ•™๊ต ๋ช…", example = "ํ•œ๊ตญ๊ธฐ์ˆ ๊ต์œก๋Œ€ํ•™๊ต", requiredMode = REQUIRED)
@NotBlank(message = "๋Œ€ํ•™๊ต ๋ช…์€ ํ•„์ˆ˜์ž…๋‹ˆ๋‹ค.")
String universityName,

@Schema(description = "๋™์•„๋ฆฌ ๋ช…", example = "BCSD Lab", requiredMode = REQUIRED)
@NotBlank(message = "๋™์•„๋ฆฌ ๋ช…์€ ํ•„์ˆ˜์ž…๋‹ˆ๋‹ค.")
@Size(max = 50, message = "๋™์•„๋ฆฌ ๋ช…์€ ์ตœ๋Œ€ 50์ž์ž…๋‹ˆ๋‹ค.")
String clubName,

@Schema(description = "๋™์•„๋ฆฌ ๋ถ„๊ณผ", example = "ACADEMIC", requiredMode = REQUIRED)
@NotNull(message = "๋™์•„๋ฆฌ ๋ถ„๊ณผ๋Š” ํ•„์ˆ˜์ž…๋‹ˆ๋‹ค.")
ClubCategory clubCategory,

@Schema(description = "๋™์•„๋ฆฌ ์ฃผ์ œ", example = "์ฝ”๋”ฉ", requiredMode = REQUIRED)
@NotBlank(message = "๋™์•„๋ฆฌ ์ฃผ์ œ๋Š” ํ•„์ˆ˜์ž…๋‹ˆ๋‹ค.")
@Size(max = 20, message = "๋™์•„๋ฆฌ ์ฃผ์ œ๋Š” ์ตœ๋Œ€ 20์ž์ž…๋‹ˆ๋‹ค.")
String clubTopic,

@Schema(description = "๋™์•„๋ฆฌ ์ด๋ชจ์ง€", example = "๐Ÿ’ป", requiredMode = REQUIRED)
@NotBlank(message = "๋™์•„๋ฆฌ ์ด๋ชจ์ง€๋Š” ํ•„์ˆ˜์ž…๋‹ˆ๋‹ค.")
@Size(max = 10, message = "๋™์•„๋ฆฌ ์ด๋ชจ์ง€๋Š” ์ตœ๋Œ€ 10์ž์ž…๋‹ˆ๋‹ค.")
String clubEmoji,

@Schema(description = "ํ•œ ์ค„ ์†Œ๊ฐœ (์ตœ๋Œ€ 30์ž)", example = "์ฝ”๋”ฉ ๋™์•„๋ฆฌ์ž…๋‹ˆ๋‹ค.", requiredMode = REQUIRED)
@NotBlank(message = "ํ•œ ์ค„ ์†Œ๊ฐœ๋Š” ํ•„์ˆ˜์ž…๋‹ˆ๋‹ค.")
@Size(max = 30, message = "ํ•œ ์ค„ ์†Œ๊ฐœ๋Š” ์ตœ๋Œ€ 30์ž์ž…๋‹ˆ๋‹ค.")
String shortDescription,

@Schema(description = "๋™์•„๋ฆฌ ์†Œ๊ฐœ (์ตœ๋Œ€ 2000์ž)", example = "์ƒ์„ธํ•œ ๋™์•„๋ฆฌ ์†Œ๊ฐœ ๋‚ด์šฉ...", requiredMode = REQUIRED)
@NotBlank(message = "๋™์•„๋ฆฌ ์†Œ๊ฐœ๋Š” ํ•„์ˆ˜์ž…๋‹ˆ๋‹ค.")
@Size(max = 2000, message = "๋™์•„๋ฆฌ ์†Œ๊ฐœ๋Š” ์ตœ๋Œ€ 2000์ž์ž…๋‹ˆ๋‹ค.")
String fullIntroduction,

@Schema(
description = "์‚ฌ์ง„ ๋ฐ ์˜์ƒ URL ๋ชฉ๋ก (์ตœ๋Œ€ 5๊ฐœ)",
example = "[\"https://example.com/image1.jpg\"]",
requiredMode = NOT_REQUIRED
)
@Size(max = 5, message = "์‚ฌ์ง„ ๋ฐ ์˜์ƒ์€ ์ตœ๋Œ€ 5๊ฐœ๊นŒ์ง€ ์—…๋กœ๋“œ ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.")
List<String> imageUrls
) {
}
28 changes: 20 additions & 8 deletions src/main/java/gg/agit/konect/domain/club/enums/ClubCategory.java
Original file line number Diff line number Diff line change
@@ -1,18 +1,30 @@
package gg.agit.konect.domain.club.enums;

import java.util.Arrays;
import java.util.Comparator;
import java.util.List;

import lombok.Getter;
import lombok.RequiredArgsConstructor;

@Getter
@RequiredArgsConstructor
public enum ClubCategory {
ACADEMIC("ํ•™์ˆ "),
SPORTS("์šด๋™"),
HOBBY("์ทจ๋ฏธ"),
RELIGION("์ข…๊ต"),
PERFORMANCE("๊ณต์—ฐ"),
JUNIOR("์ค€๋™์•„๋ฆฌ")
;
PERFORMANCE("๊ณต์—ฐ", 1),
SOCIAL_SERVICE("์‚ฌํšŒ/๋ด‰์‚ฌ", 2),
EXHIBITION_CREATION("์ „์‹œ/์ฐฝ์ž‘", 3),
RELIGION("์ข…๊ต", 4),
SPORTS("์ฒด์œก(์šด๋™)", 5),
HOBBY("์ทจ๋ฏธ", 6),
ACADEMIC("ํ•™์ˆ ", 7),
ETC("๊ธฐํƒ€", 8);

@Getter
private final String description;
private final int displayOrder;

public static List<ClubCategory> sortedForDisplay() {
return Arrays.stream(values())
.sorted(Comparator.comparingInt(category -> category.displayOrder))
.toList();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package gg.agit.konect.domain.club.event;

import java.util.List;

import gg.agit.konect.domain.club.model.ClubInformationUpdateRequest;

public record ClubInformationUpdateRequestedEvent(
Integer requestId,
Integer clubId,
String currentUniversityName,
String requestedUniversityName,
String currentClubName,
String requestedClubName,
String currentCategory,
String requestedCategory,
String currentTopic,
String requestedTopic,
String requestedEmoji,
String currentDescription,
String requestedDescription,
String currentFullIntroduction,
String requestedFullIntroduction,
String currentImageUrl,
List<String> requestedImageUrls
) {

public static ClubInformationUpdateRequestedEvent from(ClubInformationUpdateRequest request) {
return new ClubInformationUpdateRequestedEvent(
request.getId(),
request.getClub().getId(),
request.getClub().getUniversity().getKoreanName(),
request.getUniversityName(),
request.getClub().getName(),
request.getClubName(),
request.getClub().getClubCategory().getDescription(),
request.getClubCategory().getDescription(),
request.getClub().getTopic(),
request.getClubTopic(),
request.getClubEmoji(),
request.getClub().getDescription(),
request.getShortDescription(),
request.getClub().getIntroduce(),
request.getFullIntroduction(),
request.getClub().getImageUrl(),
request.getImages().stream()
.map(image -> image.getImageUrl())
.toList()
);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package gg.agit.konect.domain.club.event;

import java.util.List;

import gg.agit.konect.domain.club.model.ClubRegistrationRequest;

public record ClubRegistrationRequestedEvent(
Integer requestId,
String universityName,
String clubName,
String category,
String topic,
String emoji,
String description,
String fullIntroduction,
List<String> imageUrls
) {

public static ClubRegistrationRequestedEvent from(ClubRegistrationRequest request) {
return new ClubRegistrationRequestedEvent(
request.getId(),
request.getUniversityName(),
request.getClubName(),
request.getClubCategory().getDescription(),
request.getClubTopic(),
request.getClubEmoji(),
request.getShortDescription(),
request.getFullIntroduction(),
request.getImages().stream()
.map(image -> image.getImageUrl())
.toList()
);
}

public int imageCount() {
return imageUrls.size();
}
}
Loading
Loading