Skip to content

Commit

Permalink
Merge pull request #48 from Na-o-man/feature/#17/agendas-createAgenda…
Browse files Browse the repository at this point in the history
…-api

[FEAT] 새 안건 추가 API 구현
  • Loading branch information
bflykky authored Aug 5, 2024
2 parents a97b122 + 1f89c5e commit 2e9378d
Show file tree
Hide file tree
Showing 19 changed files with 315 additions and 20 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package com.umc.naoman.domain.agenda.controller;

import com.umc.naoman.domain.agenda.converter.AgendaConverter;
import com.umc.naoman.domain.agenda.dto.AgendaRequest;
import com.umc.naoman.domain.agenda.dto.AgendaResponse;
import com.umc.naoman.domain.agenda.entity.Agenda;
import com.umc.naoman.domain.agenda.service.AgendaService;
import com.umc.naoman.domain.member.entity.Member;
import com.umc.naoman.global.error.ErrorResponse;
import com.umc.naoman.global.result.ResultResponse;
import com.umc.naoman.global.result.code.AgendaResultCode;
import com.umc.naoman.global.security.annotation.LoginMember;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.responses.ApiResponses;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequiredArgsConstructor
@Slf4j
public class AgendaController {

private final AgendaService agendaService;
private final AgendaConverter agendaConverter;

@PostMapping("/agendas")
@Operation(summary = "안건 생성 API", description = "[request]\n shareGroupId, title, 안건에 올릴 PhotoId 리스트" +
"\n[response]\n 생성된 안건의 agendaId, 생성시간 createdAt")
@ApiResponses({
@io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "SA001",description = "안건 생성 성공"),
@io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "EG005",description = "해당 shareGroupId를 가진 그룹이 없습니다.",
content = @Content(schema = @Schema(implementation = ErrorResponse.class))),
@io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "ES3005",description = "해당 photoId를 가진 사진이 없습니다.",
content = @Content(schema = @Schema(implementation = ErrorResponse.class))),
@io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "EG006",description = "그룹에 속한 회원의 프로필이 없습니다..",
content = @Content(schema = @Schema(implementation = ErrorResponse.class))),
})
public ResultResponse<AgendaResponse.AgendaInfo> createAgenda(@RequestBody @Valid AgendaRequest.CreateAgendaRequest request,
@LoginMember Member member) {
Agenda agenda = agendaService.createAgenda(member,request);
return ResultResponse.of(AgendaResultCode.CREATE_AGENDA, agendaConverter.toAgendaInfo(agenda));
}
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package com.umc.naoman.domain.agenda.converter;

import com.umc.naoman.domain.agenda.dto.AgendaResponse;
import com.umc.naoman.domain.agenda.entity.Agenda;
import com.umc.naoman.domain.shareGroup.entity.Profile;
import com.umc.naoman.domain.shareGroup.entity.ShareGroup;
import org.springframework.stereotype.Component;

@Component
public class AgendaConverter {

public AgendaResponse.AgendaInfo toAgendaInfo(Agenda agenda){
return AgendaResponse.AgendaInfo.builder()
.agendaId(agenda.getId())
.createdAt(agenda.getCreatedAt())
.build();
}

public Agenda toEntity(Profile profile, String title, ShareGroup shareGroup){
return Agenda.builder()
.profile(profile)
.title(title)
.shareGroup(shareGroup)
.build();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package com.umc.naoman.domain.agenda.converter;

import com.umc.naoman.domain.agenda.entity.Agenda;
import com.umc.naoman.domain.agenda.entity.AgendaPhoto;
import com.umc.naoman.domain.photo.entity.Photo;

public class AgendaPhotoConverter {

public static AgendaPhoto toEntity(Agenda agenda, Photo photo) {
return AgendaPhoto.builder()
.agenda(agenda)
.photo(photo)
.build();
}
}
26 changes: 26 additions & 0 deletions src/main/java/com/umc/naoman/domain/agenda/dto/AgendaRequest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package com.umc.naoman.domain.agenda.dto;

import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Size;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;

import java.util.List;

public abstract class AgendaRequest {

@Builder
@Getter
@NoArgsConstructor
@AllArgsConstructor
public static class CreateAgendaRequest {
@NotNull
private Long shareGroupId;
@NotNull
private String title;
@Size(min = 2, max = 6, message = "안건에 등록하는 사진은 최소 2개 최대 6개로 한정 시켜 주세요.")
private List<Long> agendasPhotoList;
}
}
20 changes: 20 additions & 0 deletions src/main/java/com/umc/naoman/domain/agenda/dto/AgendaResponse.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package com.umc.naoman.domain.agenda.dto;

import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;

import java.time.LocalDateTime;

public abstract class AgendaResponse {

@Builder
@Getter
@AllArgsConstructor
public static class AgendaInfo {
private Long agendaId;
@JsonFormat(pattern = "yyyy-MM-dd")
private LocalDateTime createdAt;
}
}
15 changes: 10 additions & 5 deletions src/main/java/com/umc/naoman/domain/agenda/entity/Agenda.java
Original file line number Diff line number Diff line change
@@ -1,16 +1,18 @@
package com.umc.naoman.domain.agenda.entity;

import com.umc.naoman.domain.shareGroup.entity.Profile;
import com.umc.naoman.domain.shareGroup.entity.ShareGroup;
import com.umc.naoman.global.entity.BaseTimeEntity;
import jakarta.persistence.Column;

import jakarta.persistence.Entity;
import jakarta.persistence.FetchType;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.ManyToOne;
import jakarta.persistence.Table;
import jakarta.persistence.Column;
import jakarta.persistence.ManyToOne;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.GenerationType;
import jakarta.persistence.FetchType;
import lombok.AccessLevel;
import lombok.AllArgsConstructor;
import lombok.Builder;
Expand All @@ -35,4 +37,7 @@ public class Agenda extends BaseTimeEntity {
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "share_group_id")
private ShareGroup shareGroup;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "profile_id")
private Profile profile;
}
17 changes: 2 additions & 15 deletions src/main/java/com/umc/naoman/domain/agenda/entity/AgendaPhoto.java
Original file line number Diff line number Diff line change
@@ -1,22 +1,9 @@
package com.umc.naoman.domain.agenda.entity;

import com.umc.naoman.domain.photo.entity.Photo;
import com.umc.naoman.domain.shareGroup.entity.ShareGroup;
import com.umc.naoman.global.entity.BaseTimeEntity;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.FetchType;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.ManyToOne;
import jakarta.persistence.Table;
import lombok.AccessLevel;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import jakarta.persistence.*;
import lombok.*;
import org.hibernate.annotations.SQLRestriction;

@Entity
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package com.umc.naoman.domain.agenda.repository;

import com.umc.naoman.domain.agenda.entity.AgendaPhoto;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

@Repository
public interface AgendaPhotoRepository extends JpaRepository<AgendaPhoto, Long> {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package com.umc.naoman.domain.agenda.repository;

import com.umc.naoman.domain.agenda.entity.Agenda;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

@Repository
public interface AgendaRepository extends JpaRepository<Agenda,Long> {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package com.umc.naoman.domain.agenda.service;

import com.umc.naoman.domain.agenda.entity.Agenda;

import java.util.List;

public interface AgendaPhotoService {
void saveAgendaPhotoList(Agenda agenda, List<Long> photos);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package com.umc.naoman.domain.agenda.service;

import com.umc.naoman.domain.agenda.converter.AgendaPhotoConverter;
import com.umc.naoman.domain.agenda.entity.Agenda;
import com.umc.naoman.domain.agenda.repository.AgendaPhotoRepository;
import com.umc.naoman.domain.photo.entity.Photo;
import com.umc.naoman.domain.photo.service.PhotoService;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

@Service
@RequiredArgsConstructor
public class AgendaPhotoServiceImpl implements AgendaPhotoService {

private final AgendaPhotoRepository agendaPhotoRepository;
private final PhotoService photoService;

@Override
@Transactional
public void saveAgendaPhotoList(Agenda agenda, List<Long> photos) {
for (Long photoId : photos) {
Photo photo = photoService.findPhoto(photoId);
agendaPhotoRepository.save(AgendaPhotoConverter.toEntity(agenda, photo));
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package com.umc.naoman.domain.agenda.service;

import com.umc.naoman.domain.agenda.dto.AgendaRequest;
import com.umc.naoman.domain.agenda.entity.Agenda;
import com.umc.naoman.domain.member.entity.Member;

public interface AgendaService {

Agenda findAgenda(Long agendaId);
Agenda createAgenda(Member member, AgendaRequest.CreateAgendaRequest request);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package com.umc.naoman.domain.agenda.service;

import com.umc.naoman.domain.agenda.converter.AgendaConverter;
import com.umc.naoman.domain.agenda.dto.AgendaRequest;
import com.umc.naoman.domain.agenda.entity.Agenda;
import com.umc.naoman.domain.agenda.repository.AgendaRepository;
import com.umc.naoman.domain.member.entity.Member;
import com.umc.naoman.domain.shareGroup.entity.Profile;
import com.umc.naoman.domain.shareGroup.entity.ShareGroup;
import com.umc.naoman.domain.shareGroup.service.ShareGroupService;
import com.umc.naoman.global.error.BusinessException;
import com.umc.naoman.global.error.code.AgendaErrorCode;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service
@RequiredArgsConstructor
public class AgendaServiceImpl implements AgendaService {

private final AgendaRepository agendaRepository;
private final ShareGroupService shareGroupService;
private final AgendaPhotoService agendaPhotoService;
private final AgendaConverter agendaConverter;

@Override
@Transactional(readOnly = true)
public Agenda findAgenda(Long agendaId) {
return agendaRepository.findById(agendaId)
.orElseThrow(() -> new BusinessException(AgendaErrorCode.AGENDA_NOT_FOUND_BY_AGENDA_ID));
}

@Override
@Transactional
public Agenda createAgenda(Member member, AgendaRequest.CreateAgendaRequest request) {
Long shareGroupId = request.getShareGroupId();
ShareGroup shareGroup = shareGroupService.findShareGroup(shareGroupId);
Profile profile = shareGroupService.findProfile(shareGroupId, member.getId());
Agenda newAgenda = agendaConverter.toEntity(profile,request.getTitle(),shareGroup);
agendaPhotoService.saveAgendaPhotoList(newAgenda,request.getAgendasPhotoList());

return agendaRepository.save(newAgenda);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,5 +20,7 @@ public interface PhotoService {

List<Photo> deletePhotoList(PhotoRequest.PhotoDeletedRequest request, Member member);

Photo findPhoto(Long photoId);

PhotoResponse.PhotoDownloadUrlListInfo getPhotoDownloadUrlList(List<Long> photoIdList, Long shareGroupId, Member member);
}
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,9 @@ private void deletePhoto(Photo photo) {

@Override
@Transactional(readOnly = true)
public Photo findPhoto(Long photoId) {
return photoRepository.findById(photoId).orElseThrow(() -> new BusinessException(PHOTO_NOT_FOUND));

public PhotoResponse.PhotoDownloadUrlListInfo getPhotoDownloadUrlList(List<Long> photoIdList, Long shareGroupId, Member member) {
validateShareGroupAndProfile(shareGroupId, member);
List<Photo> photoList = photoRepository.findByIdIn(photoIdList);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import com.umc.naoman.domain.shareGroup.repository.ProfileRepository;
import com.umc.naoman.domain.shareGroup.repository.ShareGroupRepository;
import com.umc.naoman.global.error.BusinessException;
import com.umc.naoman.global.error.code.MemberErrorCode;
import com.umc.naoman.global.error.code.ShareGroupErrorCode;
import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.Page;
Expand All @@ -33,6 +34,7 @@ public class ShareGroupServiceImpl implements ShareGroupService {
@Transactional
@Override
public ShareGroup createShareGroup(ShareGroupRequest.createShareGroupRequest request, Member member) {

// 초대링크를 위한 고유번호 생성 (UUID)
String inviteCode = UUID.randomUUID().toString().replace("-", "").toUpperCase();

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package com.umc.naoman.global.error.code;

import com.umc.naoman.global.error.ErrorCode;
import lombok.Getter;
import lombok.RequiredArgsConstructor;

@Getter
@RequiredArgsConstructor
public enum AgendaErrorCode implements ErrorCode {
AGENDA_NOT_FOUND_BY_AGENDA_ID(404, "EA001", "해당 agendaId를 가진 안건이 존재하지 않습니다."),
;

private final int status;
private final String code;
private final String message;
}
17 changes: 17 additions & 0 deletions src/main/java/com/umc/naoman/global/error/code/PhotoErrorCode.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package com.umc.naoman.global.error.code;


import com.umc.naoman.global.error.ErrorCode;
import lombok.Getter;
import lombok.RequiredArgsConstructor;

@Getter
@RequiredArgsConstructor
public enum PhotoErrorCode implements ErrorCode {
PHOTO_NOT_FOUND_BY_PHOTO_ID(404, "EP001", "해당 photoId를 가진 사진이 존재하지 않습니다."),
;

private final int status;
private final String code;
private final String message;
}
Loading

0 comments on commit 2e9378d

Please sign in to comment.