Skip to content
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ public enum ErrorStatus implements BaseErrorCode {
// Enum 관련 에러
INVALID_POT_STATUS(HttpStatus.BAD_REQUEST, "POT_STATUS4000", "Pot Status 형식이 올바르지 않습니다 (RECRUITING / ONGOING / COMPLETED)"),
INVALID_POT_MODE_OF_OPERATION(HttpStatus.BAD_REQUEST, "MODE_OF_OPERATION4000", "Pot ModeOfOperation 형식이 올바르지 않습니다 (ONLINE / OFFLINE / HYBRID)"),
INVALID_ROLE(HttpStatus.BAD_REQUEST, "ROLE4000", "Role 형식이 올바르지 않습니다 (FRONTEND / DESIGN / BACKEND / PLANNING)"),
INVALID_ROLE(HttpStatus.BAD_REQUEST, "ROLE4000", "Role 형식이 올바르지 않습니다 (FRONTEND / DESIGN / BACKEND / PLAN)"),

// Taskboard 관련 에러
TASKBOARD_NOT_FOUND(HttpStatus.NOT_FOUND, "TASKBOARD4004", "해당 Task를 찾을 수 없습니다."),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,15 @@ public final class RoleNameMapper {
"BACKEND", "양파",
"FRONTEND", "버섯",
"DESIGN", "브로콜리",
"PLANNING", "당근"
"PLAN", "당근"
);

public static String getKoreanRoleName(String role) {
Map<String, String> roleToKoreanMap = Map.of(
"BACKEND", "백엔드",
"FRONTEND", "프론트엔드",
"DESIGN", "디자인",
"PLANNING", "기획"
"PLAN", "기획"
);
return roleToKoreanMap.getOrDefault(role, "알 수 없음");
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ public class FeedController {
@PostMapping("")
@Operation(summary = "Feed 생성 API",
description = "Feed를 생성하는 API입니다.\n" +
"- categories: 다중 선택 가능하며 enum입니다. [ALL, BACKEND, FRONTEND, DESIGN, PLANNING] \n" +
"- categories: 다중 선택 가능하며 enum입니다. [ALL, BACKEND, FRONTEND, DESIGN, PLAN] \n" +
Copy link

Choose a reason for hiding this comment

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

💡 Verification agent

🧩 Analysis chain

Swagger 문서의 카테고리 enum 값 PLAN 반영 OK — Category 정의와 싱크 확인

문서 갱신은 적절합니다. Category enum에 실제로 PLAN이 존재하는지, 이전 PLANNING이 남아있지 않은지 확인해 주세요.


🏁 Script executed:

#!/bin/bash
# Category enum에 PLAN이 정의되어 있는지와 PLANNING 잔존 여부 점검
rg -nP -C2 'enum\s+Category\b' --type=java
rg -nP '\bPLAN(NING)?\b' src/main/java/stackpot/stackpot/feed --type=java

Length of output: 1171


Category enum과 Swagger 문서 카테고리 불일치: ‘PLAN’ vs ‘PLANNING’
FeedController 내 문서에서 ‘[ALL, BACKEND, FRONTEND, DESIGN, PLAN]’으로 표기하고 있으나, 실제 Category enum에는 ‘PLANNING’이 정의되어 있습니다. 문서와 enum 이름을 일치시키거나, enum에 ‘PLAN’을 추가/이름 변경하세요.

🤖 Prompt for AI Agents
In src/main/java/stackpot/stackpot/feed/controller/FeedController.java around
line 36, the Swagger/documentation lists category values as "[ALL, BACKEND,
FRONTEND, DESIGN, PLAN]" but the actual Category enum defines "PLANNING"; update
the documentation to match the enum (change "PLAN" to "PLANNING") or
alternatively rename/add the enum value to "PLAN" so names are consistent; make
the change in the Swagger string/annotation, ensure any examples/tests
referencing the old name are updated, and run a build to verify no references
remain to the mismatched value.

"- interests: 다중 선택 가능하며 enum입니다. [SIDE_PROJECT(사이드 프로젝트), SOLO_DEVELOPMENT(1인 개발), COMPETITION(공모전), STARTUP(창업), NETWORKING(네트워킹 행사)]\n" +
"- seriesId: 저장할 시리즈의 Id를 입력해 주시면 됩니다. 선택하지 않을 경우 null을 보내주세요. \n")
@ApiErrorCodeExamples({
Expand All @@ -50,7 +50,7 @@ public ResponseEntity<ApiResponse<FeedResponseDto.CreatedFeedDto>> createFeeds(
@GetMapping("")
@Operation(summary = "Feed 전체 조회 API", description = "category와 sort에 따라 정렬하여 Feed를 보여줍니다. 커서 기반 페이지페니션으로 응답합니다.",
parameters = {
@Parameter(name = "category", description = "ALL : 전체 보기, PLANNING/DESIGN/FRONTEND/BACKEND : 역할별로 보기 ", example = "BACKEND"),
@Parameter(name = "category", description = "ALL : 전체 보기, PLAN/DESIGN/FRONTEND/BACKEND : 역할별로 보기 ", example = "BACKEND"),
@Parameter(name = "sort", description = "new : 최신순, old : 오래된순, popular : 인기순(좋아요)", example = "old"),
@Parameter(name = "cursor", description = "현재 페이지의 마지막 값"),
@Parameter(name = "limit", description = "요청에 불러올 Feed 수", example = "10")
Expand Down Expand Up @@ -88,7 +88,7 @@ public ResponseEntity<ApiResponse<FeedResponseDto.AuthorizedFeedDto>> getDetailF
@Operation(
summary = "Feed 수정 API",
description = "요청된 feedId의 feed 내용을 수정합니다. 수정 사항이 없다면 null 값을 넣어주세요\n" +
"- categories: 다중 선택 가능하며 enum입니다. [ALL, BACKEND, FRONTEND, DESIGN, PLANNING] \n" +
"- categories: 다중 선택 가능하며 enum입니다. [ALL, BACKEND, FRONTEND, DESIGN, PLAN] \n" +
"- interests: 다중 선택 가능하며 enum입니다. [SIDE_PROJECT(사이드 프로젝트), SOLO_DEVELOPMENT(1인 개발), COMPETITION(공모전), STARTUP(창업), NETWORKING(네트워킹 행사)]\n" +
"- seriesId: 저장할 시리즈의 Id를 입력해 주시면 됩니다. 선택하지 않을 경우 null을 보내주세요.\n",
parameters = {
Expand Down
28 changes: 5 additions & 23 deletions src/main/java/stackpot/stackpot/feed/converter/FeedConverter.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,19 +9,15 @@
import stackpot.stackpot.feed.entity.Feed;
import stackpot.stackpot.feed.dto.FeedRequestDto;
import stackpot.stackpot.feed.dto.FeedResponseDto;
import stackpot.stackpot.feed.dto.FeedSearchResponseDto;
import stackpot.stackpot.feed.entity.Series;
import stackpot.stackpot.feed.entity.enums.Interest;
import stackpot.stackpot.feed.repository.FeedCommentRepository;
import stackpot.stackpot.feed.repository.FeedLikeRepository;
import stackpot.stackpot.user.entity.User;

import java.util.ArrayList;
import java.util.Map;
import java.util.stream.Collectors;

import static stackpot.stackpot.common.util.RoleNameMapper.mapRoleName;

@RequiredArgsConstructor
@Component
public class FeedConverter{
Expand All @@ -37,7 +33,7 @@ public FeedResponseDto.FeedDto feedDto(Feed feed, Boolean isOwner, Boolean isLik
.feedId(feed.getFeedId())
.writerId(feed.getUser().getId())
.writer(writerNickname)
.writerRole(feed.getUser().getRole())
.writerRoles(feed.getUser().getRoleNames())
.title(feed.getTitle())
.content(feed.getContent())
.likeCount(feed.getLikeCount())
Expand Down Expand Up @@ -67,7 +63,7 @@ public FeedResponseDto.CreatedFeedDto createFeedDto(Feed feed) {
.content(feed.getContent())
.writerId(feed.getUser().getId())
.writer(feed.getUser().getNickname()+ " 새싹")
.writerRole(feed.getUser().getRole())
.writerRoles(feed.getUser().getRoleNames())
.categories(feed.getCategories().stream()
.map(Enum::name)
.collect(Collectors.toList()))
Expand All @@ -89,20 +85,6 @@ public Feed toFeed(FeedRequestDto.createDto dto, Series series) {
.build();
}

public FeedSearchResponseDto toSearchDto(Feed feed) {

return FeedSearchResponseDto.builder()
.userId(feed.getUser().getId())
.feedId(feed.getFeedId())
.title(feed.getTitle())
.content(feed.getContent())
.creatorNickname(feed.getUser().getNickname()+" 새싹")
.creatorRole(mapRoleName(String.valueOf(feed.getUser().getRole())))
.createdAt(DateFormatter.koreanFormatter(feed.getCreatedAt()))
.likeCount(feed.getLikeCount()) // 좋아요 개수 포함
.build();
}

public FeedResponseDto.AuthorizedFeedDto toAuthorizedFeedDto(Feed feed, boolean isOwner, boolean isLiked, boolean isSaved, Long commentCount) {
Map<String, Object> seriesMap = null;
if (feed.getSeries() != null) {
Expand All @@ -116,7 +98,7 @@ public FeedResponseDto.AuthorizedFeedDto toAuthorizedFeedDto(Feed feed, boolean
.feedId(feed.getFeedId())
.writerId(feed.getUser().getId())
.writer(writerNickname)
.writerRole(feed.getUser().getRole())
.writerRoles(feed.getUser().getRoleNames())
.title(feed.getTitle())
.content(feed.getContent())
.createdAt(DateFormatter.koreanFormatter(feed.getCreatedAt()))
Expand Down Expand Up @@ -145,7 +127,7 @@ public FeedResponseDto.FeedDto toFeedDtoFromCache(FeedCacheDto feed, boolean isL
.feedId(feed.getFeedId())
.writerId(feed.getUserId())
.writer(feed.getWriter())
.writerRole(feed.getWriterRole())
.writerRoles(feed.getWriterRoles())
.title(feed.getTitle())
.content(feed.getContent())
.likeCount(likeCount)
Expand All @@ -162,7 +144,7 @@ public FeedCacheDto toFeedCacheDto(Feed feed) {
.feedId(feed.getFeedId())
.userId(feed.getUser().getId())
.writer(feed.getUser().getNickname())
.writerRole(feed.getUser().getRole())
.writerRoles(feed.getUser().getRoleNames())
.title(feed.getTitle())
.content(feed.getContent())
.createdAt(feed.getCreatedAt().toString())
Expand Down
3 changes: 2 additions & 1 deletion src/main/java/stackpot/stackpot/feed/dto/FeedCacheDto.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import stackpot.stackpot.user.entity.enums.Role;

import java.time.LocalDateTime;
import java.util.List;

@Getter
@Setter
Expand All @@ -16,7 +17,7 @@ public class FeedCacheDto {
private String content;
private Long userId;
private String writer;
private Role writerRole;
private List<String> writerRoles;
private String createdAt;
}

Expand Down
4 changes: 2 additions & 2 deletions src/main/java/stackpot/stackpot/feed/dto/FeedResponseDto.java
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ public static class FeedDto {
private Long feedId;
private Long writerId;
private String writer;
private Role writerRole;
private List<String> writerRoles;
private String title;
private String content;
private Long likeCount;
Expand All @@ -59,7 +59,7 @@ public static class CreatedFeedDto {
private Long feedId;
private Long writerId;
private String writer;
private Role writerRole;
private List<String> writerRoles;
private String title;
private String content;
private String createdAt;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

import lombok.*;

import java.util.List;

@Getter
@Setter
@Builder
Expand All @@ -11,7 +13,7 @@ public class FeedSearchResponseDto {
private Long feedId;
private Long userId;

private String creatorRole;
private List<String> creatorRole;
private Boolean isLiked;
private String title;
private String content;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ public class PotController {
- potStatus: RECRUITING / ONGOING / COMPLETED
- potStartDate, potEndDate: yyyy.MM 형식 (예: 2025.08)
- potModeOfOperation: ONLINE / OFFLINE / HYBRID
- Role: FRONTEND / BACKEND / DESIGN / PLANNING
- Role: FRONTEND / BACKEND / DESIGN / PLAN
""")
@PostMapping
public ResponseEntity<ApiResponse<PotResponseDto>> createPot(@RequestBody @Valid PotRequestDto requestDto) {
Expand Down
36 changes: 2 additions & 34 deletions src/main/java/stackpot/stackpot/pot/converter/PotConverter.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,9 @@
import org.springframework.stereotype.Component;


import java.time.LocalDate;
import java.time.temporal.ChronoUnit;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import java.time.format.DateTimeFormatter;

@Component
public class PotConverter{

Expand Down Expand Up @@ -71,7 +66,7 @@ public PotPreviewResponseDto toPrviewDto(User user, Pot pot, List<String> recrui

return PotPreviewResponseDto.builder()
.userId(user.getId())
.userRole(user.getRole().name())
.userRoles(user.getRoleNames())
.userNickname(user.getNickname() + " 새싹")
.potId(pot.getPotId())
.potName(pot.getPotName())
Expand All @@ -87,7 +82,7 @@ public PotPreviewResponseDto toPrviewDto(User user, Pot pot, List<String> recrui
public CompletedPotResponseDto toCompletedPotResponseDto(Pot pot, String formattedMembers, Role userPotRole) {
Map<String, Integer> roleCountMap = pot.getPotMembers().stream()
.collect(Collectors.groupingBy(
member -> member.getRoleName().name(),
member -> member.getRoleName().getKoreanName(),
Collectors.reducing(0, e -> 1, Integer::sum)
));

Expand All @@ -104,33 +99,6 @@ public CompletedPotResponseDto toCompletedPotResponseDto(Pot pot, String formatt
.build();
}

public PotSearchResponseDto toSearchDto(Pot pot) {
String roleName = (pot.getUser() != null && pot.getUser().getRole() != null)
? pot.getUser().getRole().name()
: "멤버";

String nicknameWithRole = (pot.getUser() != null && pot.getUser().getNickname() != null)
? pot.getUser().getNickname() + " " + RoleNameMapper.mapRoleName(roleName)
: "Unknown 멤버";

return PotSearchResponseDto.builder()
.potId(pot.getPotId())
.potName(pot.getPotName())
.potContent(pot.getPotContent())
.creatorNickname(nicknameWithRole)
.creatorRole(roleName)
.recruitmentPart(
pot.getRecruitmentDetails() != null
? pot.getRecruitmentDetails().stream()
.filter(rd -> rd.getRecruitmentRole() != null)
.map(rd -> rd.getRecruitmentRole().name())
.collect(Collectors.joining(", "))
: "없음"
)
.recruitmentDeadline(pot.getPotRecruitmentDeadline())
.build();
}

public PotSummaryDto toDto(Pot pot, Boolean isMember) {
return PotSummaryDto.builder()
.summary(pot.getPotSummary())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
import stackpot.stackpot.common.util.DateFormatter;
import stackpot.stackpot.common.util.DdayCounter;
import stackpot.stackpot.common.util.OperationModeMapper;
import stackpot.stackpot.common.util.RoleNameMapper;
import stackpot.stackpot.pot.entity.Pot;
import stackpot.stackpot.pot.entity.PotRecruitmentDetails;
import stackpot.stackpot.user.entity.User;
Expand All @@ -28,7 +27,7 @@ public AppealContentDto toCompletedPotDetailDto(String appealContent, String use
.build();
}

public PotDetailResponseDto toPotDetailResponseDto(User user, Pot pot, String recruitmentDetails, Boolean isOwner, Boolean isApplied, Boolean isSaved, Long commentCount) {
public PotDetailResponseDto toPotDetailResponseDto(User user, Pot pot, String recruitmentDetails, Boolean isOwner, Boolean isApplied, Boolean isSaved, Long commentCount, String creatorRoleName) {
String dDay = DdayCounter.dDayCount(pot.getPotRecruitmentDeadline());

Map<String, Integer> recruitingMembers = pot.getRecruitmentDetails().stream()
Expand All @@ -39,7 +38,7 @@ public PotDetailResponseDto toPotDetailResponseDto(User user, Pot pot, String re

return PotDetailResponseDto.builder()
.userId(user.getId())
.userRole(user.getRole().name())
.userRole(creatorRoleName)
.userNickname(user.getNickname() + " 새싹")
.isOwner(isOwner)
.potId(pot.getPotId())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,11 @@ public PotMember toEntity(User user, Pot pot, PotApplication application, Boolea
.user(user)
.pot(pot)
.potApplication(application)
.roleName(application != null ? application.getPotRole() : user.getRole()) // PotRole Enum 그대로 사용
.roleName(
application != null
? application.getPotRole()
: (user.getRoles().isEmpty() ? Role.UNKNOWN : user.getRoles().get(0))
)
.owner(isOwner)
.appealContent(null)
.build();
Expand Down Expand Up @@ -81,4 +85,12 @@ public PotMemberInfoResponseDto toKaKaoMemberDto(PotMember entity) {
.potRole(roleName)
.build();
}
public PotMember toCreatorEntity(User user, Pot pot, String potRole) {
return PotMember.builder()
.user(user)
.pot(pot)
.roleName(Role.fromString(potRole))
.owner(true)
.build();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
@Builder
public class PotPreviewResponseDto {
private Long userId;
protected String userRole;
protected List<String> userRoles;
private String userNickname;
private Long potId;
private String potName;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package stackpot.stackpot.pot.dto;

import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Builder;
import lombok.Getter;
import lombok.Setter;
Expand All @@ -10,6 +11,8 @@
@Builder
public class PotRecruitmentRequestDto {
@ValidRole
@Schema(description = "모집 역할", example = "BACKEND")
private String recruitmentRole;
@Schema(description = "역할 별 모집 인원 수", example = "1")
private Integer recruitmentCount;
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
import stackpot.stackpot.user.entity.User;
import stackpot.stackpot.user.entity.enums.Role;

import java.util.Collection;
import java.util.List;
import java.util.Optional;
import java.util.Set;
Expand Down Expand Up @@ -96,4 +97,13 @@ public interface PotMemberRepository extends JpaRepository<PotMember, Long> {
long countByPot_PotId(Long potId);
Optional<PotMember> findByPot_PotIdAndUser_Id(Long potId, Long userId);

@Query("""
select pm.user.id as userId, pm.roleName as role
from PotMember pm
where pm.pot.potId = :potId
and pm.user.id in :userIds
""")
List<Object[]> findCreatorRolesByPotAndUserIds(@Param("potId") Long potId,
@Param("userIds") Collection<Long> userIds);

}
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,8 @@ public PotResponseDto createPotWithRecruitments(PotRequestDto requestDto) {
pot.setPotStatus("RECRUITING");
Pot savedPot = potRepository.save(pot);

PotMember creator = potMemberConverter.toCreatorEntity(user, savedPot, String.valueOf(requestDto.getPotRole()));
potMemberRepository.save(creator);

List<PotRecruitmentDetails> recruitmentDetails = requestDto.getRecruitmentDetails().stream()
.map(dto -> PotRecruitmentDetails.builder()
Expand Down
Loading