-
Notifications
You must be signed in to change notification settings - Fork 2
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Feat/9 monthly agenda #15
Changes from 12 commits
3cd2d67
31ef3ae
de39a21
7238e0a
22cd59a
14b5ab8
0dcfdef
3e6cd66
fcfb074
25e1208
80d7502
f3de1ae
ce67783
e610014
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
package com.example.rework.MonthlyAgenda.application; | ||
|
||
import com.example.rework.MonthlyAgenda.application.dto.MonthlyAgendaRequestDto; | ||
import com.example.rework.MonthlyAgenda.application.dto.MonthlyAgendaResponseDto; | ||
import com.example.rework.config.security.SecurityUtils; | ||
|
||
public interface MonthlyAgendaService { | ||
MonthlyAgendaResponseDto.ReadMonthlyAgendaResponseDto readMonthlyAgenda(MonthlyAgendaRequestDto.ReadMonthlyAgendaRequestDto readMonthlyAgendaRequestDto , SecurityUtils securityUtils); | ||
|
||
MonthlyAgendaResponseDto.CreateMonthlyAgendaResponseDto createMonthlyAgenda(MonthlyAgendaRequestDto.CreateMonthlyAgendaRequestDto createMonthlyAgendaRequestDto, SecurityUtils securityUtils); | ||
|
||
MonthlyAgendaResponseDto.UpdateMonthlyAgendaResponseDto updateMonthlyAgenda(MonthlyAgendaRequestDto.UpdateMonthlyAgendaRequestDto updateMonthlyAgendaRequestDto, SecurityUtils securityUtils); | ||
|
||
boolean deleteMonthlyAgenda(Long monthlyAgendaId, SecurityUtils securityUtils); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
package com.example.rework.MonthlyAgenda.application.dto; | ||
|
||
import lombok.*; | ||
|
||
public class MonthlyAgendaRequestDto { | ||
@Getter | ||
@NoArgsConstructor | ||
@AllArgsConstructor | ||
@Builder | ||
public static class ReadMonthlyAgendaRequestDto{ | ||
private int year; | ||
private int month; | ||
} | ||
|
||
@Getter | ||
@NoArgsConstructor(access = AccessLevel.PROTECTED) | ||
@AllArgsConstructor | ||
@Builder | ||
public static class CreateMonthlyAgendaRequestDto{ | ||
private String todo; | ||
} | ||
|
||
@Getter | ||
@NoArgsConstructor(access = AccessLevel.PROTECTED) | ||
@AllArgsConstructor | ||
@Builder | ||
public static class UpdateMonthlyAgendaRequestDto{ | ||
private Long agendaId; | ||
private String todo; | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
package com.example.rework.MonthlyAgenda.application.dto; | ||
|
||
import com.fasterxml.jackson.annotation.JsonFormat; | ||
import lombok.*; | ||
|
||
import java.time.LocalDateTime; | ||
|
||
public class MonthlyAgendaResponseDto { | ||
@Getter | ||
@NoArgsConstructor(access = AccessLevel.PROTECTED) | ||
@AllArgsConstructor | ||
@Builder | ||
public static class CreateMonthlyAgendaResponseDto { | ||
private Long agendaId; | ||
private String todo; | ||
private boolean state; | ||
} | ||
|
||
@Getter | ||
@NoArgsConstructor(access = AccessLevel.PROTECTED) | ||
@AllArgsConstructor | ||
@Builder | ||
public static class UpdateMonthlyAgendaResponseDto { | ||
private Long agendaId; | ||
private String todo; | ||
private boolean state; | ||
} | ||
|
||
@Getter | ||
@NoArgsConstructor(access = AccessLevel.PROTECTED) | ||
@AllArgsConstructor | ||
@Builder | ||
public static class ReadMonthlyAgendaResponseDto { | ||
private Long agendaId; | ||
private String todo; | ||
private boolean state; | ||
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM") | ||
private LocalDateTime createTime; | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,126 @@ | ||
package com.example.rework.MonthlyAgenda.application.impl; | ||
|
||
import com.example.rework.MonthlyAgenda.application.MonthlyAgendaService; | ||
import com.example.rework.MonthlyAgenda.application.dto.MonthlyAgendaRequestDto.CreateMonthlyAgendaRequestDto; | ||
import com.example.rework.MonthlyAgenda.application.dto.MonthlyAgendaRequestDto.ReadMonthlyAgendaRequestDto; | ||
import com.example.rework.MonthlyAgenda.application.dto.MonthlyAgendaRequestDto.UpdateMonthlyAgendaRequestDto; | ||
import com.example.rework.MonthlyAgenda.application.dto.MonthlyAgendaResponseDto; | ||
import com.example.rework.MonthlyAgenda.domain.MonthlyAgenda; | ||
import com.example.rework.MonthlyAgenda.domain.repository.MonthlyAgendaRepository; | ||
import com.example.rework.config.security.SecurityUtils; | ||
import com.example.rework.global.error.NotFoundAccountException; | ||
import com.example.rework.global.error.NotFoundAgendaException; | ||
import com.example.rework.global.error.UnAuthorizedException; | ||
import com.example.rework.member.domain.Member; | ||
import com.example.rework.member.domain.repository.MemberRepository; | ||
import lombok.RequiredArgsConstructor; | ||
import lombok.extern.slf4j.Slf4j; | ||
import org.springframework.stereotype.Service; | ||
import org.springframework.transaction.annotation.Transactional; | ||
|
||
import java.time.LocalDateTime; | ||
import java.time.YearMonth; | ||
import java.util.List; | ||
import java.util.Optional; | ||
|
||
@Service | ||
@RequiredArgsConstructor | ||
@Slf4j | ||
@Transactional(readOnly = true) | ||
public class MonthlyAgendaServiceImpl implements MonthlyAgendaService { | ||
private final MonthlyAgendaRepository monthlyAgendaRepository; | ||
private final MemberRepository memberRepository; | ||
|
||
@Override | ||
public MonthlyAgendaResponseDto.ReadMonthlyAgendaResponseDto readMonthlyAgenda(ReadMonthlyAgendaRequestDto readMonthlyAgendaRequestDto, SecurityUtils securityUtils) { | ||
Optional<Member> curMember = memberRepository.findByUserId(securityUtils.getCurrentUserId()); | ||
Long currentUserId = curMember.get().getId(); | ||
|
||
LocalDateTime start = YearMonth.of(readMonthlyAgendaRequestDto.getYear(), readMonthlyAgendaRequestDto.getMonth()).atDay(1).atStartOfDay(); | ||
LocalDateTime end = YearMonth.of(readMonthlyAgendaRequestDto.getYear(), readMonthlyAgendaRequestDto.getMonth()).atEndOfMonth().atTime(23, 59, 59); | ||
|
||
Optional<MonthlyAgenda> monthlyAgendaOptional = monthlyAgendaRepository.findByMemberIdAndCreatedAtBetween(currentUserId, start, end); | ||
|
||
if (monthlyAgendaOptional.isPresent()) { | ||
MonthlyAgenda monthlyAgenda = monthlyAgendaOptional.get(); | ||
return MonthlyAgendaResponseDto.ReadMonthlyAgendaResponseDto.builder() | ||
.agendaId(monthlyAgenda.getId()) | ||
.todo(monthlyAgenda.getTodo()) | ||
.state(monthlyAgenda.isState()) | ||
.createTime(monthlyAgenda.getCreatedAt()) | ||
.build(); | ||
} else { | ||
return MonthlyAgendaResponseDto.ReadMonthlyAgendaResponseDto.builder().build(); | ||
} | ||
|
||
|
||
} | ||
|
||
@Override | ||
@Transactional | ||
public MonthlyAgendaResponseDto.CreateMonthlyAgendaResponseDto createMonthlyAgenda(CreateMonthlyAgendaRequestDto createMonthlyAgendaRequestDto, SecurityUtils securityUtils) { | ||
Optional<Member> curMember = memberRepository.findByUserId(securityUtils.getCurrentUserId()); | ||
Long currentUserId = curMember.get().getId(); | ||
|
||
Member member = memberRepository.findById(currentUserId) | ||
.orElseThrow(() -> new NotFoundAccountException("Member not found with id: " + currentUserId)); | ||
|
||
MonthlyAgenda monthlyAgenda = MonthlyAgenda.builder() | ||
.member(member) | ||
.todo(createMonthlyAgendaRequestDto.getTodo()) | ||
.state(false) | ||
.build(); | ||
|
||
MonthlyAgenda returnMonthlyAgenda = monthlyAgendaRepository.save(monthlyAgenda); | ||
|
||
return MonthlyAgendaResponseDto.CreateMonthlyAgendaResponseDto.builder() | ||
.agendaId(returnMonthlyAgenda.getId()) | ||
.todo(returnMonthlyAgenda.getTodo()) | ||
.state(returnMonthlyAgenda.isState()) | ||
.build(); | ||
} | ||
|
||
@Override | ||
@Transactional | ||
public MonthlyAgendaResponseDto.UpdateMonthlyAgendaResponseDto updateMonthlyAgenda(UpdateMonthlyAgendaRequestDto updateMonthlyAgendaRequestDto, SecurityUtils securityUtils) { | ||
Optional<Member> curMember = memberRepository.findByUserId(securityUtils.getCurrentUserId()); | ||
Long currentUserId = curMember.get().getId(); | ||
|
||
Member member = memberRepository.findById(currentUserId) | ||
.orElseThrow(() -> new NotFoundAccountException("Member not found with id: " + currentUserId)); | ||
MonthlyAgenda monthlyAgenda = monthlyAgendaRepository.findById(updateMonthlyAgendaRequestDto.getAgendaId()) | ||
.orElseThrow(() -> new NotFoundAgendaException("Goal not found with id: " + updateMonthlyAgendaRequestDto.getAgendaId())); | ||
|
||
if (!monthlyAgenda.getMember().getId().equals(currentUserId)) { | ||
throw new UnAuthorizedException("유저가 소유한 아젠다가 아닙니다."); | ||
} | ||
monthlyAgenda.setTodo(updateMonthlyAgendaRequestDto.getTodo()); | ||
|
||
return MonthlyAgendaResponseDto.UpdateMonthlyAgendaResponseDto | ||
.builder() | ||
.agendaId(monthlyAgenda.getId()) | ||
.todo(monthlyAgenda.getTodo()) | ||
.state(monthlyAgenda.isState()) | ||
.build(); | ||
} | ||
|
||
@Override | ||
@Transactional | ||
public boolean deleteMonthlyAgenda(Long monthlyAgendaId, SecurityUtils securityUtils) { | ||
Optional<Member> curMember = memberRepository.findByUserId(securityUtils.getCurrentUserId()); | ||
Long currentUserId = curMember.get().getId(); | ||
|
||
Member member = memberRepository.findById(currentUserId) | ||
.orElseThrow(() -> new NotFoundAccountException("Member not found with id: " + currentUserId)); | ||
MonthlyAgenda monthlyAgenda = monthlyAgendaRepository.findById(monthlyAgendaId) | ||
.orElseThrow(() -> new NotFoundAgendaException("Goal not found with id: " + monthlyAgendaId)); | ||
|
||
if (!monthlyAgenda.getMember().getId().equals(currentUserId)) { | ||
throw new UnAuthorizedException("유저가 소유한 아젠다가 아닙니다."); | ||
} | ||
monthlyAgendaRepository.deleteById(monthlyAgenda.getId()); | ||
|
||
return true; | ||
} | ||
|
||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
package com.example.rework.MonthlyAgenda.domain; | ||
|
||
import com.example.rework.global.base.BaseTimeEntity; | ||
import com.example.rework.member.domain.Member; | ||
import jakarta.persistence.*; | ||
import lombok.*; | ||
|
||
|
||
@Entity(name = "MONTHLY_AGENDA") | ||
@Getter | ||
@NoArgsConstructor(access = AccessLevel.PROTECTED) | ||
@AllArgsConstructor | ||
@Builder | ||
public class MonthlyAgenda extends BaseTimeEntity { | ||
@Id | ||
@GeneratedValue(strategy = GenerationType.IDENTITY) | ||
@Column(name = "MONTHLY_AGENDA_ID") | ||
private Long id; | ||
@Column(length = 400) | ||
private String todo; | ||
@Column(length = 30, nullable = false) | ||
private boolean state; | ||
@JoinColumn(name = "MEMBER_ID") | ||
@ManyToOne(fetch = FetchType.LAZY) | ||
private Member member; | ||
|
||
public void setTodo(String todo) { | ||
this.todo = todo; | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
package com.example.rework.MonthlyAgenda.domain.repository; | ||
|
||
import com.example.rework.MonthlyAgenda.domain.MonthlyAgenda; | ||
import org.springframework.data.jpa.repository.JpaRepository; | ||
|
||
import java.time.LocalDateTime; | ||
import java.util.List; | ||
import java.util.Optional; | ||
|
||
public interface MonthlyAgendaRepository extends JpaRepository<MonthlyAgenda, Long> { | ||
Optional<MonthlyAgenda> findByMemberIdAndCreatedAtBetween(Long memberId, LocalDateTime start, LocalDateTime end); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
package com.example.rework.MonthlyAgenda.presentation; | ||
|
||
import com.example.rework.MonthlyAgenda.application.MonthlyAgendaService; | ||
import com.example.rework.MonthlyAgenda.application.dto.MonthlyAgendaRequestDto.*; | ||
import com.example.rework.MonthlyAgenda.application.dto.MonthlyAgendaResponseDto; | ||
import com.example.rework.MonthlyAgenda.restapi.MonthlyAgendaApi; | ||
import com.example.rework.config.security.SecurityUtils; | ||
import com.example.rework.global.common.CommonResDto; | ||
import lombok.RequiredArgsConstructor; | ||
import lombok.extern.slf4j.Slf4j; | ||
import org.springframework.http.HttpStatus; | ||
import org.springframework.http.ResponseEntity; | ||
import org.springframework.web.bind.annotation.RequestMapping; | ||
import org.springframework.web.bind.annotation.RestController; | ||
|
||
|
||
@RestController | ||
@RequestMapping("/api/v1/monthlyAgenda") | ||
@RequiredArgsConstructor | ||
@Slf4j | ||
public class MonthlyAgendaController implements MonthlyAgendaApi { | ||
private final MonthlyAgendaService monthlyAgendaService; | ||
|
||
@Override | ||
public ResponseEntity<CommonResDto<?>> readMonthlyAgenda(ReadMonthlyAgendaRequestDto readMonthlyAgendaRequestDto, SecurityUtils securityUtils) { | ||
MonthlyAgendaResponseDto.ReadMonthlyAgendaResponseDto result = monthlyAgendaService.readMonthlyAgenda(readMonthlyAgendaRequestDto, securityUtils); | ||
return ResponseEntity.status(HttpStatus.OK).body(new CommonResDto<>(1, "이번달 아젠다 조회에 성고했습니다.", result)); | ||
} | ||
|
||
@Override | ||
public ResponseEntity<CommonResDto<?>> createMonthlyAgenda(CreateMonthlyAgendaRequestDto createMonthlyAgendaRequestDto, SecurityUtils securityUtils) { | ||
MonthlyAgendaResponseDto.CreateMonthlyAgendaResponseDto result = monthlyAgendaService.createMonthlyAgenda(createMonthlyAgendaRequestDto, securityUtils); | ||
return ResponseEntity.status(HttpStatus.CREATED).body(new CommonResDto<>(1, "이번달 아젠다 생성에 성공했습니다.", result)); | ||
} | ||
|
||
@Override | ||
public ResponseEntity<CommonResDto<?>> updateMonthlyAgenda(UpdateMonthlyAgendaRequestDto updateMonthlyAgendaRequestDto, SecurityUtils securityUtils) { | ||
MonthlyAgendaResponseDto.UpdateMonthlyAgendaResponseDto result = monthlyAgendaService.updateMonthlyAgenda(updateMonthlyAgendaRequestDto, securityUtils); | ||
return ResponseEntity.status(HttpStatus.OK).body(new CommonResDto<>(1, "이번달 아젠달 수정에 성공했습니다.", result)); | ||
} | ||
|
||
@Override | ||
public ResponseEntity<CommonResDto<?>> deleteMonthlyAgenda(Long monthlyAgendaId, SecurityUtils securityUtils) { | ||
boolean result = monthlyAgendaService.deleteMonthlyAgenda(monthlyAgendaId, securityUtils); | ||
return ResponseEntity.status(HttpStatus.OK).body(new CommonResDto<>(1, "이번달 아젠다 삭제에 성공했습니다.", result)); | ||
} | ||
|
||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
package com.example.rework.MonthlyAgenda.restapi; | ||
|
||
import com.example.rework.config.security.SecurityUtils; | ||
import com.example.rework.global.common.CommonResDto; | ||
import io.swagger.v3.oas.annotations.Operation; | ||
import io.swagger.v3.oas.annotations.tags.Tag; | ||
import jakarta.validation.Valid; | ||
import org.springframework.http.ResponseEntity; | ||
import org.springframework.validation.annotation.Validated; | ||
import org.springframework.web.bind.annotation.*; | ||
|
||
import java.security.Principal; | ||
|
||
import com.example.rework.MonthlyAgenda.application.dto.MonthlyAgendaRequestDto.*; | ||
|
||
@Tag(name = "이번달 아젠다 API", description = "이번달 아젠다 관련 API") | ||
@RestController | ||
@RequestMapping("/api/v1/monthlyAgenda") | ||
@Validated | ||
public interface MonthlyAgendaApi { | ||
|
||
@Operation( | ||
summary = "이번달 아젠다 조회", | ||
description = "사용자 정보와 연,월을 받아 해당하는 달의 '이번달 아젠다를' 조회하는 API" | ||
) | ||
@GetMapping("/read") | ||
ResponseEntity<CommonResDto<?>> readMonthlyAgenda( | ||
@RequestBody ReadMonthlyAgendaRequestDto readMonthlyAgendaRequestDto, | ||
SecurityUtils securityUtils | ||
); | ||
|
||
@Operation( | ||
summary = "이번달 아젠다 등록", | ||
description = "사용자가 입력한 이번달 아젠다를 저장하는 API" | ||
) | ||
@PostMapping("/create") | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. restful 규칙: 행위를 포함하지 않는다. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 요기까지 다 확인했습니다 ㅎㅎ |
||
ResponseEntity<CommonResDto<?>> createMonthlyAgenda( | ||
@Valid | ||
@RequestBody | ||
CreateMonthlyAgendaRequestDto createMonthlyAgendaRequestDto, | ||
SecurityUtils securityUtils | ||
); | ||
|
||
@Operation( | ||
summary = "이번달 아젠다 수정", | ||
description = "사용자가 설정한 이번달 아젠다를 수정하는 API" | ||
) | ||
@PutMapping("/update") | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. restful 규칙: 행위를 포함하지 않는다. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 넵! |
||
ResponseEntity<CommonResDto<?>> updateMonthlyAgenda( | ||
@RequestBody | ||
UpdateMonthlyAgendaRequestDto updateMonthlyAgendaRequestDto, | ||
SecurityUtils securityUtils | ||
); | ||
|
||
|
||
@Operation( | ||
summary = "이번달 아젠다 삭제", | ||
description = "이번달 아젠다를 삭제하는 API, 현재는 필요하지 않음." | ||
) | ||
@DeleteMapping("/delete") | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. restful 규칙: 행위를 포함하지 않는다. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 좋습니다! 수정하도록 할게요! |
||
ResponseEntity<CommonResDto<?>> deleteMonthlyAgenda( | ||
@RequestParam("monthlyAgendaId") Long monthlyAgendaId, | ||
SecurityUtils securityUtils | ||
); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -63,6 +63,7 @@ public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { | |
.authorizeHttpRequests((authorizeRequests) -> | ||
authorizeRequests | ||
.requestMatchers("/api/v1/members/signup", "/api/v1/members/login/**","/api/v1/members/renew-access-token","/api/v1/members/logout").permitAll() | ||
.requestMatchers("/api/v1/monthlyAgenda/**").permitAll() | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 저 경로 밑에 있는 경로 전부 오픈시키면 로그인 하지않은 유저들도 해당 API에 데이터에 접근할 수 있을 것 같아요! Member 등급 이상인 권한을 가진 유저들만 API해당 접근할 수있도록 수정해주시면 좋을 것같습니다! There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 아 테스트용 설정했는데, 깜빡했습니다.! |
||
.requestMatchers("/api/v1/mails/send/**").hasAuthority("ADMIN") | ||
.requestMatchers("/swagger-ui/**").permitAll() | ||
.requestMatchers("/v3/api-docs/**").permitAll() | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
해당 부분을 orElseThrow로 처리해서 if else 문 안쓰고처리하는방법은 어떨까요!?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
아아 빈배열 반환을 위해 저렇게 하신거군요 ! 이해했습니다