Skip to content

Commit

Permalink
Merge pull request #15 from OneK-2/Feat/9-monthlyAgenda
Browse files Browse the repository at this point in the history
Feat/9 monthly agenda
  • Loading branch information
minwoo1999 authored May 23, 2024
2 parents c202873 + e610014 commit 7c8bf68
Show file tree
Hide file tree
Showing 20 changed files with 844 additions and 14 deletions.
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("/")
ResponseEntity<CommonResDto<?>> readMonthlyAgenda(
@RequestBody ReadMonthlyAgendaRequestDto readMonthlyAgendaRequestDto,
SecurityUtils securityUtils
);

@Operation(
summary = "이번달 아젠다 등록",
description = "사용자가 입력한 이번달 아젠다를 저장하는 API"
)
@PostMapping("/")
ResponseEntity<CommonResDto<?>> createMonthlyAgenda(
@Valid
@RequestBody
CreateMonthlyAgendaRequestDto createMonthlyAgendaRequestDto,
SecurityUtils securityUtils
);

@Operation(
summary = "이번달 아젠다 수정",
description = "사용자가 설정한 이번달 아젠다를 수정하는 API"
)
@PutMapping("/")
ResponseEntity<CommonResDto<?>> updateMonthlyAgenda(
@RequestBody
UpdateMonthlyAgendaRequestDto updateMonthlyAgendaRequestDto,
SecurityUtils securityUtils
);


@Operation(
summary = "이번달 아젠다 삭제",
description = "이번달 아젠다를 삭제하는 API, 현재는 필요하지 않음."
)
@DeleteMapping("/")
ResponseEntity<CommonResDto<?>> deleteMonthlyAgenda(
@RequestParam("monthlyAgendaId") Long monthlyAgendaId,
SecurityUtils securityUtils
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -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/**").hasAnyAuthority("ADMIN", "MEMBER")
.requestMatchers("/api/v1/mails/send/**").hasAuthority("ADMIN")
.requestMatchers("/swagger-ui/**").permitAll()
.requestMatchers("/v3/api-docs/**").permitAll()
Expand Down
Loading

0 comments on commit 7c8bf68

Please sign in to comment.