Skip to content

Commit

Permalink
Merge pull request #42 from Onion-City/feat/clubJoinApi
Browse files Browse the repository at this point in the history
유저 클럽 가입 신청 구현 및 예외처리
  • Loading branch information
kjyyjk authored Feb 29, 2024
2 parents ecb5aec + f51a0fd commit c23ff1f
Show file tree
Hide file tree
Showing 26 changed files with 242 additions and 57 deletions.
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package GDG.whatssue.domain.attendance.entity;

import GDG.whatssue.domain.club.entity.ClubMember;
import GDG.whatssue.domain.member.entity.ClubMember;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
import GDG.whatssue.domain.attendance.dto.ScheduleAttendanceRequestDto;
import GDG.whatssue.global.common.AttendanceType;
import GDG.whatssue.domain.attendance.entity.ScheduleAttendanceResult;
import GDG.whatssue.domain.club.repository.ClubMemberRepository;
import GDG.whatssue.domain.member.repository.ClubMemberRepository;
import GDG.whatssue.domain.attendance.repository.ScheduleAttendanceResultRepository;
import GDG.whatssue.domain.schedule.repository.ScheduleRepository;
import lombok.RequiredArgsConstructor;
Expand Down
2 changes: 2 additions & 0 deletions src/main/java/GDG/whatssue/domain/club/entity/Club.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package GDG.whatssue.domain.club.entity;


import GDG.whatssue.domain.member.entity.ClubJoinRequest;
import GDG.whatssue.domain.member.entity.ClubMember;
import GDG.whatssue.domain.schedule.entity.Schedule;
import GDG.whatssue.global.common.BaseEntity;
import jakarta.persistence.*;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
package GDG.whatssue.domain.club.repository;

import GDG.whatssue.domain.club.entity.Club;
import java.util.Optional;
import org.springframework.data.jpa.repository.JpaRepository;

public interface ClubRepository extends JpaRepository<Club, Long> {

Optional<Club> findByClubCode(String clubCode);
boolean existsByClubCode(String clubCode);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package GDG.whatssue.domain.member.controller;

import GDG.whatssue.domain.member.exception.ClubMemberErrorCode;
import GDG.whatssue.domain.member.service.ClubMemberService;
import GDG.whatssue.global.error.CommonException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import lombok.RequiredArgsConstructor;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.util.PatternMatchUtils;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;


@RestController
@RequiredArgsConstructor
@RequestMapping("/api")
public class ClubMemberController {

private final ClubMemberService clubMemberService;

@PostMapping("/join/{clubCode}")
public ResponseEntity joinClub(@PathVariable(name = "clubCode") String clubCode) {
//현재 로그인 id parameter로 받아오기 TODO
Long userId = 1L;

boolean checkClubCode = Pattern.matches("[0-9]{6}", clubCode);

if (checkClubCode) {
clubMemberService.addClubJoinRequest(userId, clubCode);
return new ResponseEntity("ok", HttpStatus.OK);
} else {
throw new CommonException(ClubMemberErrorCode.INVALID_CLUB_CODE_ERROR);
}
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package GDG.whatssue.domain.club.entity;
package GDG.whatssue.domain.member.entity;

import GDG.whatssue.domain.club.entity.Club;
import GDG.whatssue.domain.user.entity.User;
Expand All @@ -10,10 +10,16 @@
import jakarta.persistence.Id;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.ManyToOne;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;

@Getter
@Entity
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class ClubJoinRequest extends BaseEntity {

@Id
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
package GDG.whatssue.domain.club.entity;
package GDG.whatssue.domain.member.entity;

import GDG.whatssue.domain.attendance.entity.MemberAttendanceResult;
import GDG.whatssue.domain.officialAbsenceRequest.entity.OfficialAbsenceRequest;
import GDG.whatssue.domain.club.entity.Club;
import GDG.whatssue.domain.officialabsence.entity.OfficialAbsenceRequest;
import GDG.whatssue.domain.user.entity.User;
import GDG.whatssue.global.common.BaseEntity;
import GDG.whatssue.global.common.Role;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package GDG.whatssue.domain.member.exception;

import GDG.whatssue.global.error.ErrorCode;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import org.springframework.http.HttpStatus;

@Getter
@RequiredArgsConstructor
public enum ClubMemberErrorCode implements ErrorCode {

CLUB_NOT_FOUND_ERROR(HttpStatus.BAD_REQUEST, "No Club With That Club Code"),
INVALID_CLUB_CODE_ERROR(HttpStatus.BAD_REQUEST, "Invalid Club Code Pattern [******]"),
DUPLICATE_CLUB_JOIN_ERROR(HttpStatus.BAD_REQUEST, "Club That Has Already Joined");


private final HttpStatus httpStatus;
private final String message;

}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package GDG.whatssue.domain.club.repository;
package GDG.whatssue.domain.member.repository;

import GDG.whatssue.domain.club.entity.ClubJoinRequest;
import GDG.whatssue.domain.member.entity.ClubJoinRequest;
import org.springframework.data.jpa.repository.JpaRepository;

public interface ClubJoinRequestRepository extends JpaRepository<ClubJoinRequest, Long> {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package GDG.whatssue.domain.club.repository;
package GDG.whatssue.domain.member.repository;

import GDG.whatssue.domain.club.entity.ClubMember;
import GDG.whatssue.domain.member.entity.ClubMember;
import org.springframework.data.jpa.repository.JpaRepository;

public interface ClubMemberRepository extends JpaRepository<ClubMember, Long> {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package GDG.whatssue.domain.member.service;

import GDG.whatssue.domain.club.entity.Club;
import GDG.whatssue.domain.club.repository.ClubRepository;
import GDG.whatssue.domain.member.entity.ClubJoinRequest;
import GDG.whatssue.domain.member.exception.ClubMemberErrorCode;
import GDG.whatssue.domain.member.repository.ClubJoinRequestRepository;
import GDG.whatssue.domain.user.entity.User;
import GDG.whatssue.domain.user.repository.UserRepository;
import GDG.whatssue.global.error.CommonException;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

@Service
@RequiredArgsConstructor
public class ClubMemberService {

private final UserRepository userRepository;
private final ClubRepository clubRepository;
private final ClubJoinRequestRepository clubJoinRequestRepository;

public void addClubJoinRequest(Long userId, String clubCode) {
Club club = clubRepository.findByClubCode(clubCode)
.orElseThrow(() -> new CommonException(ClubMemberErrorCode.CLUB_NOT_FOUND_ERROR));

User loginUser = userRepository.findById(userId).get();

checkJoinDuplicate(loginUser, club);

ClubJoinRequest newClubJoinRequest = ClubJoinRequest.builder()
.club(club).user(loginUser).build();

clubJoinRequestRepository.save(newClubJoinRequest);
}

private void checkJoinDuplicate(User loginUser, Club club) {
boolean result = clubJoinRequestRepository.findAll()
.stream()
.anyMatch(r -> r.getClub().equals(club) && r.getUser().equals(loginUser));

if (result) {
throw new CommonException(ClubMemberErrorCode.DUPLICATE_CLUB_JOIN_ERROR);
}
}
}
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
package GDG.whatssue.domain.officialAbsenceRequest.controller;
package GDG.whatssue.domain.officialabsence.controller;

import GDG.whatssue.domain.officialAbsenceRequest.dto.OfficialAbsenceAddRequestDto;
import GDG.whatssue.domain.officialAbsenceRequest.dto.OfficialAbsenceGetRequestDto;
import GDG.whatssue.domain.officialAbsenceRequest.service.OfficialAbsenceService;
import GDG.whatssue.domain.officialabsence.dto.OfficialAbsenceAddRequestDto;
import GDG.whatssue.domain.officialabsence.dto.OfficialAbsenceGetRequestDto;
import GDG.whatssue.domain.officialabsence.service.OfficialAbsenceService;
import io.swagger.v3.oas.annotations.Operation;
import lombok.RequiredArgsConstructor;
import org.springframework.http.ResponseEntity;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package GDG.whatssue.domain.officialAbsenceRequest.dto;
package GDG.whatssue.domain.officialabsence.dto;

import lombok.AllArgsConstructor;
import lombok.Builder;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package GDG.whatssue.domain.officialAbsenceRequest.dto;
package GDG.whatssue.domain.officialabsence.dto;

import lombok.AllArgsConstructor;
import lombok.Builder;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package GDG.whatssue.domain.officialAbsenceRequest.entity;
package GDG.whatssue.domain.officialabsence.entity;

import GDG.whatssue.domain.club.entity.ClubMember;
import GDG.whatssue.domain.member.entity.ClubMember;
import GDG.whatssue.domain.schedule.entity.Schedule;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package GDG.whatssue.domain.officialAbsenceRequest.repository;
package GDG.whatssue.domain.officialabsence.repository;

import GDG.whatssue.domain.officialAbsenceRequest.entity.OfficialAbsenceRequest;
import GDG.whatssue.domain.officialabsence.entity.OfficialAbsenceRequest;
import org.springframework.data.jpa.repository.JpaRepository;

public interface OfficialAbsenceRequestRepository extends JpaRepository<OfficialAbsenceRequest, Long> {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
package GDG.whatssue.domain.officialAbsenceRequest.service;
package GDG.whatssue.domain.officialabsence.service;

import static GDG.whatssue.global.common.AttendanceType.ABSENCE;
import static GDG.whatssue.global.common.AttendanceType.OFFICIAL_ABSENCE;

import GDG.whatssue.domain.attendance.entity.ScheduleAttendanceResult;
import GDG.whatssue.domain.attendance.repository.ScheduleAttendanceResultRepository;
import GDG.whatssue.domain.club.entity.ClubMember;
import GDG.whatssue.domain.club.repository.ClubMemberRepository;
import GDG.whatssue.domain.officialAbsenceRequest.dto.OfficialAbsenceAddRequestDto;
import GDG.whatssue.domain.officialAbsenceRequest.dto.OfficialAbsenceGetRequestDto;
import GDG.whatssue.domain.officialAbsenceRequest.entity.OfficialAbsenceRequest;
import GDG.whatssue.domain.officialAbsenceRequest.repository.OfficialAbsenceRequestRepository;
import GDG.whatssue.domain.member.entity.ClubMember;
import GDG.whatssue.domain.member.repository.ClubMemberRepository;
import GDG.whatssue.domain.officialabsence.dto.OfficialAbsenceAddRequestDto;
import GDG.whatssue.domain.officialabsence.dto.OfficialAbsenceGetRequestDto;
import GDG.whatssue.domain.officialabsence.entity.OfficialAbsenceRequest;
import GDG.whatssue.domain.officialabsence.repository.OfficialAbsenceRequestRepository;
import GDG.whatssue.domain.schedule.entity.Schedule;
import GDG.whatssue.domain.schedule.repository.ScheduleRepository;
import jakarta.transaction.Transactional;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,24 +3,20 @@
import GDG.whatssue.domain.schedule.dto.AddScheduleRequest;
import GDG.whatssue.domain.schedule.dto.GetScheduleResponse;
import GDG.whatssue.domain.schedule.dto.ModifyScheduleRequest;
import GDG.whatssue.domain.schedule.exception.NoScheduleException;
import GDG.whatssue.domain.schedule.exception.ScheduleErrorCode;
import GDG.whatssue.domain.schedule.service.ScheduleService;
import GDG.whatssue.global.error.CommonException;
import GDG.whatssue.global.error.ErrorResult;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.enums.ParameterIn;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.validation.Valid;
import java.util.List;

import java.util.regex.Pattern;
import lombok.RequiredArgsConstructor;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PatchMapping;
import org.springframework.web.bind.annotation.PathVariable;
Expand All @@ -41,42 +37,37 @@ public class ScheduleController {
* Filter 또는 Interceptor를 통해 schedule이 club의 것인지 체크 필요 TODO
*/

@Operation(summary = "일정 추가", description = "날짜 패턴 yyyy-MM-dd HH:ss")
@PostMapping
// @PreAuthorize("hasRole('ROLE_'+#clubId+'MANAGER')")
public ResponseEntity addSchedule(@PathVariable(name = "clubId") Long clubId,
@Valid @RequestBody AddScheduleRequest requestDto, BindingResult bindingResult) {

if (bindingResult.hasErrors()) {
//bean validation 처리 TODO
}
public ResponseEntity addSchedule(@PathVariable(name = "clubId") Long clubId, @Valid @RequestBody AddScheduleRequest requestDto) {

scheduleService.saveSchedule(clubId, requestDto);

return ResponseEntity.status(200).body("ok");
}

@Operation(summary = "일정 수정", description = "날짜 패턴 yyyy-MM-dd HH:ss")
@PatchMapping("/{scheduleId}")
// @PreAuthorize("hasRole('ROLE_'+#clubId+'MANAGER')")
public ResponseEntity modifySchedule(@PathVariable(name = "clubId") Long clubId, @PathVariable(name = "scheduleId") Long scheduleId,
@Valid @RequestBody ModifyScheduleRequest requestDto, BindingResult bindingResult) {

if (bindingResult.hasErrors()) {
//bean validation 처리 TODO
}
@Valid @RequestBody ModifyScheduleRequest requestDto) {

scheduleService.updateSchedule(scheduleId, requestDto);

return ResponseEntity.status(HttpStatus.OK).body("ok");
}

@Operation(summary = "일정 삭제")
@DeleteMapping("/{scheduleId}")
// @PreAuthorize("hasRole('ROLE_'+#clubId+'MANAGER')")
public ResponseEntity deleteSchedule(@PathVariable(name = "clubId") Long clubId, @PathVariable(name = "scheduleId") Long scheduleId) {
scheduleService.deleteSchedule(scheduleId);

return ResponseEntity.status(HttpStatus.OK).body("ok");
}


@Operation(summary = "일정 상세조회")
@GetMapping("/{scheduleId}")
// @PreAuthorize("hasAnyRole('ROLE_'+#clubId+'MANAGER','ROLE_'+#clubId+'MEMBER')")
public ResponseEntity getSchedule (@PathVariable(name = "clubId") Long clubId, @PathVariable(name = "scheduleId") Long scheduleId) {
Expand All @@ -86,9 +77,9 @@ public ResponseEntity getSchedule (@PathVariable(name = "clubId") Long clubId, @
return ResponseEntity.status(HttpStatus.OK).body(scheduleDto);
}

//전체조회
@Operation(summary = "일정 조회(전체/일별/월별)")
@GetMapping
@Parameter(name = "date", description = "쿼리 파라미터 미입력 시 전체 일정 조회 (날짜 패턴 : yyyy-MM-dd or yyyy-MM)", required = false, in = ParameterIn.QUERY)
@Parameter(name = "date", description = "날짜 미입력 시 전체 일정 조회 (날짜 패턴 : yyyy-MM-dd or yyyy-MM)", required = false, in = ParameterIn.QUERY)
// @PreAuthorize("hasAnyRole('ROLE_'+#clubId+'MANAGER','ROLE_'+#clubId+'MEMBER')")
public ResponseEntity getScheduleAll( @PathVariable(name = "clubId") Long clubId, @RequestParam(name = "date", required = false) String date) {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import GDG.whatssue.domain.schedule.entity.Schedule;
import com.fasterxml.jackson.annotation.JsonFormat;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import java.time.LocalDateTime;
import lombok.AllArgsConstructor;
import lombok.Builder;
Expand All @@ -21,7 +22,7 @@ public class AddScheduleRequest {
@NotBlank
private String scheduleContent;

@NotBlank
@NotNull
@JsonFormat(pattern = "yyyy-MM-dd HH:mm")
private LocalDateTime scheduleDateTime;

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package GDG.whatssue.domain.schedule.dto;

import com.fasterxml.jackson.annotation.JsonFormat;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import java.time.LocalDateTime;
import lombok.AllArgsConstructor;
import lombok.Builder;
Expand All @@ -19,6 +21,7 @@ public class ModifyScheduleRequest {
@NotBlank
private String scheduleContent;

@NotBlank
@NotNull
@JsonFormat(pattern = "yyyy-MM-dd HH:mm")
private LocalDateTime scheduleDateTime;
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,9 @@
public enum ScheduleErrorCode implements ErrorCode {

SCHEDULE_NOT_FOUND_ERROR(HttpStatus.NOT_FOUND, "Invalid Schedule Id [%d]"),
SCHEDULE_DATE_PATTERN_ERROR(HttpStatus.BAD_REQUEST, "Invalid Schedule Date Pattern [yyyy-MM-dd or yyyy-MM]");
SCHEDULE_DATE_PATTERN_ERROR(HttpStatus.BAD_REQUEST, "Invalid Schedule Date Pattern [yyyy-MM-dd or yyyy-MM]"),
SCHEDULE_DATETIME_PATTERN_ERROR(HttpStatus.BAD_REQUEST, "Invalid Schedule DateTime Pattern [yyyy-MM-dd HH:ss]");


private final HttpStatus httpStatus;
private final String message;
Expand Down
Loading

0 comments on commit c23ff1f

Please sign in to comment.