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 @@ -5,7 +5,6 @@

import com.campus.campus.domain.councilpost.domain.entity.PostCategory;
import com.campus.campus.domain.councilpost.domain.entity.ThumbnailIcon;
import com.campus.campus.domain.place.application.dto.response.SavedPlaceInfo;
import com.fasterxml.jackson.annotation.JsonFormat;

import io.swagger.v3.oas.annotations.media.Schema;
Expand All @@ -23,24 +22,7 @@ public record PostRequest(
@NotBlank
String content,

@Schema(example =
"""
"placeName": "숙명여자대학교",
"placeKey": "string",
"address": "서울특별시 용산구 청파로47길 99",
"category": "교육,학문>대학교",
"link": "https://map.naver.com/v5/search/%EC%88%99%EB%AA%85%EC%97%AC%EC%9E%90%EB%8C%80%ED%95%99%EA%B5%90+%EC%A0%9C1%EC%BA%A0%ED%8D%BC%EC%8A%A4?c=37.545947,126.964578,15,0,0,0,dh",
"telephone": "010-1234-1234",
"coordinate": {
"latitude": 0.1,
"longitude": 0.1
},
"imgUrls": [
"string"
]
""",
description = "/search API에서 반환된 결과 중 하나를 선택")
SavedPlaceInfo place,
String place,

@Schema(example = "2025-04-10T18:00")
@JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ public record GetPostResponse(
PostCategory category,
String title,
String content,
String placeName,
String place,
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Breaking Change: placeName에서 place로 필드명 변경

필드명이 placeName에서 place로 변경되었습니다. 이는 API 응답의 breaking change로, 기존 클라이언트가 placeName 필드를 참조하는 경우 오류가 발생할 수 있습니다.

리버트의 일관성을 위해 필요한 변경이지만, API 버전 관리 또는 클라이언트 업데이트 계획이 있는지 확인하시기 바랍니다.

🤖 Prompt for AI Agents
In
@src/main/java/com/campus/campus/domain/councilpost/application/dto/response/GetPostResponse.java
at line 25, The DTO field was renamed from placeName to place in
GetPostResponse, causing a breaking API change; to fix, restore backward
compatibility by mapping the new field to the old JSON name (e.g., annotate the
place field with the JSON property "placeName") or add a legacy accessor
getPlaceName() that returns place so existing clients keep working, and ensure
any API versioning or client update notes are handled accordingly.

LocalDate startDate,
LocalDate endDate,
LocalDateTime startDateTime,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ public record PostListItemResponse(
Long id,
PostCategory category,
String title,
Long placeId,
String place,
LocalDateTime endDateTime,
String thumbnailImageUrl,
ThumbnailIcon thumbnailIcon,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,19 +7,18 @@
import org.springframework.stereotype.Component;

import com.campus.campus.domain.council.domain.entity.StudentCouncil;
import com.campus.campus.domain.councilpost.application.dto.request.PostRequest;
import com.campus.campus.domain.councilpost.application.dto.response.GetActivePartnershipListForUserResponse;
import com.campus.campus.domain.councilpost.application.dto.response.GetLikedPostResponse;
import com.campus.campus.domain.councilpost.application.dto.response.GetPostForUserResponse;
import com.campus.campus.domain.councilpost.application.dto.response.GetPostListForCouncilResponse;
import com.campus.campus.domain.councilpost.application.dto.response.GetPostResponse;
import com.campus.campus.domain.councilpost.application.dto.response.GetUpcomingEventListForCouncilResponse;
import com.campus.campus.domain.councilpost.application.dto.response.LikePostResponse;
import com.campus.campus.domain.councilpost.application.dto.response.GetPostListForCouncilResponse;
import com.campus.campus.domain.councilpost.application.dto.response.GetUpcomingEventListForCouncilResponse;
import com.campus.campus.domain.councilpost.application.dto.response.GetActivePartnershipListForUserResponse;
import com.campus.campus.domain.councilpost.application.dto.response.PostListItemResponse;
import com.campus.campus.domain.councilpost.application.dto.request.PostRequest;
import com.campus.campus.domain.councilpost.application.dto.response.GetPostForUserResponse;
import com.campus.campus.domain.councilpost.domain.entity.LikePost;
import com.campus.campus.domain.councilpost.domain.entity.PostImage;
import com.campus.campus.domain.councilpost.domain.entity.StudentCouncilPost;
import com.campus.campus.domain.place.domain.entity.Place;
import com.campus.campus.domain.user.domain.entity.User;

import lombok.RequiredArgsConstructor;
Expand All @@ -32,10 +31,8 @@ public PostListItemResponse toPostListItemResponse(StudentCouncilPost post, bool
post.getId(),
post.getCategory(),
post.getTitle(),
post.getPlace().getPlaceId(),
post.isEvent()
? post.getStartDateTime()
: post.getEndDateTime(),
post.getPlace(),
post.isEvent() ? post.getStartDateTime() : post.getEndDateTime(),
post.getThumbnailImageUrl(),
post.getThumbnailIcon(),
isLiked
Expand All @@ -47,7 +44,7 @@ public GetPostListForCouncilResponse toGetPostListForCouncilResponse(StudentCoun
post.getId(),
post.getCategory(),
post.getTitle(),
post.getPlace().getPlaceName(),
post.getPlace(),
post.isEvent() ? post.getStartDateTime() : post.getEndDateTime(),
post.getThumbnailImageUrl(),
post.getThumbnailIcon()
Expand All @@ -59,7 +56,7 @@ public GetUpcomingEventListForCouncilResponse toGetUpcomingEventListForCouncilRe
post.getId(),
post.getCategory(),
post.getTitle(),
post.getPlace().getPlaceName(),
post.getPlace(),
post.getStartDateTime(),
post.getThumbnailIcon()
);
Expand All @@ -69,7 +66,7 @@ public GetActivePartnershipListForUserResponse toGetActivePartnershipListForUser
return new GetActivePartnershipListForUserResponse(
post.getId(),
post.getTitle(),
post.getPlace().getPlaceName(),
post.getPlace(),
post.getThumbnailImageUrl()
);
}
Expand All @@ -84,7 +81,7 @@ public GetPostResponse toGetPostResponse(StudentCouncilPost post, List<String> i
.category(post.getCategory())
.title(post.getTitle())
.content(post.getContent())
.placeName(post.getPlace().getPlaceName())
.place(post.getPlace())
.thumbnailImageUrl(post.getThumbnailImageUrl())
.thumbnailIcon(post.getThumbnailIcon())
.images(images != null ? images : Collections.emptyList());
Expand All @@ -99,9 +96,6 @@ public GetPostResponse toGetPostResponse(StudentCouncilPost post, List<String> i
return builder.build();
}

//
// public StudentCouncilPost createStudentCouncilPost(StudentCouncil writer, PostRequest dto,
// LocalDateTime startDateTime, LocalDateTime endDateTime, Place place) {
public GetPostForUserResponse toGetPostForUserResponse(StudentCouncilPost post, List<String> images,
Long currentUserId, boolean isLiked) {
var writer = post.getWriter();
Expand All @@ -112,7 +106,7 @@ public GetPostForUserResponse toGetPostForUserResponse(StudentCouncilPost post,
.category(post.getCategory())
.title(post.getTitle())
.content(post.getContent())
.place(post.getPlace().getPlaceName())
.place(post.getPlace())
.thumbnailImageUrl(post.getThumbnailImageUrl())
.thumbnailIcon(post.getThumbnailIcon())
.isLiked(isLiked)
Expand Down Expand Up @@ -140,20 +134,20 @@ public GetLikedPostResponse toGetLikedPostResponse(StudentCouncilPost post) {
return new GetLikedPostResponse(
post.getId(),
post.getTitle(),
post.getPlace().getPlaceName(),
post.getPlace(),
post.isEvent() ? post.getStartDateTime() : post.getEndDateTime(),
post.getThumbnailImageUrl()
);
}

public StudentCouncilPost createStudentCouncilPost(StudentCouncil writer, Place place, PostRequest dto,
public StudentCouncilPost createStudentCouncilPost(StudentCouncil writer, PostRequest dto,
LocalDateTime startDateTime, LocalDateTime endDateTime) {
return StudentCouncilPost.builder()
.writer(writer)
.category(dto.category())
.title(dto.title())
.content(dto.content())
.place(place)
.place(dto.place())
.startDateTime(startDateTime)
.endDateTime(endDateTime)
.thumbnailImageUrl(dto.thumbnailImageUrl())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,11 @@
import com.campus.campus.domain.council.application.exception.StudentCouncilNotFoundException;
import com.campus.campus.domain.council.domain.entity.StudentCouncil;
import com.campus.campus.domain.council.domain.repository.StudentCouncilRepository;
import com.campus.campus.domain.councilpost.application.dto.request.PostRequest;
import com.campus.campus.domain.councilpost.application.dto.response.GetPostListForCouncilResponse;
import com.campus.campus.domain.councilpost.application.dto.response.GetPostResponse;
import com.campus.campus.domain.councilpost.application.dto.response.GetUpcomingEventListForCouncilResponse;
import com.campus.campus.domain.councilpost.application.dto.response.NormalizedDateTime;
import com.campus.campus.domain.councilpost.application.dto.request.PostRequest;
import com.campus.campus.domain.councilpost.application.exception.NotPostWriterException;
import com.campus.campus.domain.councilpost.application.exception.PostImageLimitExceededException;
import com.campus.campus.domain.councilpost.application.exception.PostNotFoundException;
Expand All @@ -30,9 +30,6 @@
import com.campus.campus.domain.councilpost.domain.entity.StudentCouncilPost;
import com.campus.campus.domain.councilpost.domain.repository.PostImageRepository;
import com.campus.campus.domain.councilpost.domain.repository.StudentCouncilPostRepository;
import com.campus.campus.domain.partnership.application.service.PartnershipService;
import com.campus.campus.domain.place.application.service.PlaceService;
import com.campus.campus.domain.place.domain.entity.Place;
import com.campus.campus.global.oci.application.service.PresignedUrlService;

import lombok.RequiredArgsConstructor;
Expand All @@ -51,9 +48,6 @@ public class StudentCouncilPostService {

private static final int MAX_IMAGE_COUNT = 10;
private static final long UPCOMING_EVENT_WINDOW_HOURS = 72L;
private final PlaceService placeService;
private final StudentCouncilPostRepository studentCouncilPostRepository;
private final PartnershipService partnershipService;

@Transactional
public GetPostResponse create(Long councilId, PostRequest dto) {
Expand All @@ -71,18 +65,12 @@ public GetPostResponse create(Long councilId, PostRequest dto) {

NormalizedDateTime normalized = dto.category().validateAndNormalize(dto);

//Place 객체 생성
Place place = placeService.findOrCreatePlace(dto);

StudentCouncilPost post = studentCouncilPostMapper.createStudentCouncilPost(
writer, place, dto, normalized.startDateTime(), normalized.endDateTime()
writer, dto, normalized.startDateTime(), normalized.endDateTime()
);

postRepository.save(post);

//제휴 엔티티 생성
partnershipService.create(post, place);

if (dto.imageUrls() != null) {
for (String imageUrl : dto.imageUrls()) {
postImageRepository.save(studentCouncilPostMapper.createPostImage(post, imageUrl));
Expand Down Expand Up @@ -215,15 +203,10 @@ public GetPostResponse update(Long councilId, Long postId, PostRequest dto) {
String oldThumbnailUrl = post.getThumbnailImageUrl();
List<PostImage> oldImages = postImageRepository.findAllByPost(post);

Place place = post.getPlace();
if (!dto.place().placeName().equals(place.getPlaceName())) {
place = placeService.findOrCreatePlace(dto);
}

post.update(
dto.title(),
dto.content(),
place,
dto.place(),
normalized.startDateTime(),
normalized.endDateTime(),
dto.thumbnailImageUrl(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
import java.time.LocalDateTime;

import com.campus.campus.domain.council.domain.entity.StudentCouncil;
import com.campus.campus.domain.place.domain.entity.Place;
import com.campus.campus.global.entity.BaseEntity;

import jakarta.persistence.Column;
Expand Down Expand Up @@ -46,9 +45,7 @@ public class StudentCouncilPost extends BaseEntity {
@Column(columnDefinition = "TEXT")
private String content;

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "place_id")
private Place place;
private String place;

private LocalDateTime startDateTime;
private LocalDateTime endDateTime;
Expand All @@ -61,7 +58,7 @@ public class StudentCouncilPost extends BaseEntity {
public void update(
String title,
String content,
Place place,
String place,
LocalDateTime startDateTime,
LocalDateTime endDateTime,
String thumbnailImageUrl,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,9 @@
import java.util.List;

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;

import com.campus.campus.domain.councilpost.domain.entity.PostImage;
import com.campus.campus.domain.councilpost.domain.entity.StudentCouncilPost;
import com.campus.campus.domain.place.application.dto.response.partnership.PostImageSummary;

public interface PostImageRepository extends JpaRepository<PostImage, Long> {

Expand All @@ -17,26 +14,4 @@ public interface PostImageRepository extends JpaRepository<PostImage, Long> {
void deleteByPost(StudentCouncilPost post);

List<PostImage> findAllByPostOrderByIdAsc(StudentCouncilPost post);

@Query("""
SELECT NEW com.campus.campus.domain.place.application.dto.response.partnership.PostImageSummary
(post.place.placeId,
img.imageUrl)
FROM PostImage img
JOIN img.post post
WHERE post.category='PARTNERSHIP'
AND post.place.placeId in :placeIds
ORDER BY img.id asc
""")
List<PostImageSummary> findPartnershipImagesByPlaceIds(
@Param("placeIds") List<Long> placeIds
);

@Query("""
select pi.imageUrl
from PostImage pi
where pi.post = :post
order by pi.id asc
""")
List<String> findImageUrlsByPost(@Param("post") StudentCouncilPost post);
}
Original file line number Diff line number Diff line change
Expand Up @@ -205,87 +205,4 @@ Page<StudentCouncilPost> findUpcomingMajorEvents(
@Param("limit") LocalDateTime limit,
Pageable pageable
);

@Query("""
SELECT p
FROM StudentCouncilPost p
WHERE p.place.placeId=:placeId
and p.writer.id=:councilId
and p.category='PARTNERSHIP'
order by p.createdAt desc
""")
Optional<StudentCouncilPost> findByCouncilIdAndPlaceId(
@Param("placeId") Long placeId,
@Param("councilId") Long councilId
);

@EntityGraph(attributePaths = {"writer", "writer.school", "writer.college", "writer.major", "place"})
@Query("""
SELECT p
FROM StudentCouncilPost p
JOIN p.writer w
LEFT JOIN w.school s
LEFT JOIN w.college c
LEFT JOIN w.major m
WHERE w.deletedAt IS NULL
AND p.category = :category
AND p.startDateTime <= :now
AND p.endDateTime >= :now
AND (
(w.councilType = :majorType AND m.majorId = :majorId)
OR (w.councilType = :collegeType AND c.collegeId = :collegeId)
OR (w.councilType = :schoolType AND s.schoolId = :schoolId)
)
AND (:cursor IS NULL OR p.id < :cursor)
ORDER BY p.id DESC
""")
List<StudentCouncilPost> findByUserScopeWithCursor(
@Param("majorId") Long majorId,
@Param("collegeId") Long collegeId,
@Param("schoolId") Long schoolId,
@Param("category") PostCategory category,
@Param("majorType") CouncilType majorType,
@Param("collegeType") CouncilType collegeType,
@Param("schoolType") CouncilType schoolType,
@Param("cursor") Long cursor,
@Param("now") LocalDateTime now,
Pageable pageable
);

@Query("""
SELECT p
FROM StudentCouncilPost p
JOIN p.writer w
JOIN p.place pl
LEFT JOIN w.school s
LEFT JOIN w.college c
LEFT JOIN w.major m
WHERE w.deletedAt IS NULL
AND p.category = :category
AND p.startDateTime <= :now
AND p.endDateTime >= :now
AND pl.coordinate.latitude BETWEEN :minLat AND :maxLat
AND pl.coordinate.longitude BETWEEN :minLng AND :maxLng
AND (
(w.councilType = :majorType AND m.majorId = :majorId)
OR (w.councilType = :collegeType AND c.collegeId = :collegeId)
OR (w.councilType = :schoolType AND s.schoolId = :schoolId)
)
ORDER BY p.id DESC
""")
List<StudentCouncilPost> findPinsInBounds(
@Param("majorId") Long majorId,
@Param("collegeId") Long collegeId,
@Param("schoolId") Long schoolId,
@Param("category") PostCategory category,
@Param("majorType") CouncilType majorType,
@Param("collegeType") CouncilType collegeType,
@Param("schoolType") CouncilType schoolType,
@Param("minLat") Double minLat,
@Param("maxLat") Double maxLat,
@Param("minLng") Double minLng,
@Param("maxLng") Double maxLng,
@Param("now") LocalDateTime now
);

}
Loading