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
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

## ⚡️변경사항 확인 바람⚡️

- [Entity를 변경하고 다시 시작해도, db에 반영이 안되는 이유](https://github.com/UMC-CodePlay/CodePlay-BE/discussions/125)
- [배포 과정 설명](https://github.com/UMC-CodePlay/CodePlay-BE/discussions/52)
- [Docker를 이용한 DB 세팅 방법 확인하기](https://github.com/UMC-CodePlay/CodePlay-BE/discussions/28)
- [자동 스타일 포맷터 사용법 바로가기](https://github.com/UMC-CodePlay/CodePlay-BE/discussions/3#discussioncomment-11796830)
20 changes: 20 additions & 0 deletions docker/local/deleteEvent.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
create event clean_input_data on schedule
EVERY 1 DAY STARTS CURRENT_DATE + INTERVAL 1 DAY
enable
do
BEGIN
-- 2달 이상 지난 데이터 삭제
DELETE FROM music WHERE DATE(created_at) < DATE_SUB(NOW(), INTERVAL 60 DAY);
DELETE FROM remix WHERE DATE(updated_at) < DATE_SUB(NOW(), INTERVAL 60 DAY);
END;

create event clean_result_data on schedule
EVERY 1 DAY STARTS CURRENT_DATE + INTERVAL 1 DAY
enable
do
BEGIN
-- 2주 이상 지난 데이터 삭제
DELETE FROM harmony WHERE DATE(updated_at) < DATE_SUB(NOW(), INTERVAL 14 DAY);
DELETE FROM track WHERE DATE(updated_at) < DATE_SUB(NOW(), INTERVAL 14 DAY);
UPDATE remix set deleted_at = now() WHERE DATE(updated_at) < DATE_SUB(NOW(), INTERVAL 14 DAY);
END;
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,12 @@ public enum ErrorStatus implements BaseErrorCode {
LIKE_ALREADY_EXIST(HttpStatus.BAD_REQUEST, "LIKE401", "이미 좋아요 목록에 추가된 음원입니다."),

EMAIL_SEND_ERROR(HttpStatus.BAD_REQUEST, "EMAIL400", "메일 발송에 실패하였습니다."),
EMAIL_CODE_ERROR(HttpStatus.BAD_REQUEST, "EMAIL401", "유효한 코드가 아닙니다.");
EMAIL_CODE_ERROR(HttpStatus.BAD_REQUEST, "EMAIL401", "유효한 코드가 아닙니다."),

TASK_NOT_FOUND(HttpStatus.BAD_REQUEST, "TASK400", "해당 task를 찾을 수 없습니다."),
HARMONY_NOT_FOUND(HttpStatus.BAD_REQUEST, "HARMONY400", "해당 화성 분석 결과를 찾을 수 없습니다."),
TRACK_NOT_FOUND(HttpStatus.BAD_REQUEST, "TRACK400", "해당 트랙 분리 결과를 찾을 수 없습니다."),
REMIX_NOT_FOUND(HttpStatus.BAD_REQUEST, "REMIX400", "해당 리믹스 결과를 찾을 수 없습니다.");

private final HttpStatus httpStatus;
private final String code;
Expand Down
1 change: 1 addition & 0 deletions src/main/java/umc/codeplay/config/SecurityConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Excepti
"/health",
"/health/s3",
"/auth/**",
"/member/**",
"/v2/api-docs",
"/v3/api-docs",
"/v3/api-docs/**",
Expand Down
5 changes: 2 additions & 3 deletions src/main/java/umc/codeplay/controller/AuthController.java
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ public ApiResponse<MemberResponseDTO.LoginResultDTO> login(
throw new GeneralHandler(ErrorStatus.AUTHORIZATION_METHOD_ERROR);
}

// 아이디/비밀번호를 사용해 AuthenticationToken 생성
// 이메일/비밀번호를 사용해 AuthenticationToken 생성
UsernamePasswordAuthenticationToken authToken =
new UsernamePasswordAuthenticationToken(request.getEmail(), request.getPassword());

Expand All @@ -56,7 +56,6 @@ public ApiResponse<MemberResponseDTO.LoginResultDTO> login(

// Role 정보 가져오기
Collection<? extends GrantedAuthority> authorities = authentication.getAuthorities();

// 인증에 성공했다면, JWT 토큰 생성 후 반환
String token = jwtUtil.generateToken(authentication.getName(), authorities);
String refreshToken =
Expand Down Expand Up @@ -86,7 +85,7 @@ public ApiResponse<MemberResponseDTO.LoginResultDTO> refresh(
if (jwtUtil.validateToken(refreshToken)
&& (jwtUtil.getTypeFromToken(refreshToken).equals("refresh"))) {
// 리프레시 토큰에서 사용자명 추출
String usernameFromToken = jwtUtil.getUsernameFromToken(refreshToken);
String usernameFromToken = jwtUtil.getEmailFromToken(refreshToken);

if (!email.equals(usernameFromToken)) {
throw new GeneralHandler(ErrorStatus.INVALID_REFRESH_TOKEN);
Expand Down
2 changes: 2 additions & 0 deletions src/main/java/umc/codeplay/controller/FileController.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import lombok.RequiredArgsConstructor;

import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import umc.codeplay.apiPayLoad.ApiResponse;
import umc.codeplay.domain.enums.FileType;
import umc.codeplay.dto.FileResponseDTO;
Expand All @@ -19,6 +20,7 @@
@RestController
@RequestMapping("/files")
@RequiredArgsConstructor
@Tag(name = "file-controller", description = "모든 파일(사진, 음성)을 s3에 올릴 때 사용하는 api")
public class FileController {

private final FileService fileService;
Expand Down
114 changes: 114 additions & 0 deletions src/main/java/umc/codeplay/controller/MemberController.java
Original file line number Diff line number Diff line change
@@ -1,16 +1,23 @@
package umc.codeplay.controller;

import java.util.List;
import java.util.Optional;

import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.web.bind.annotation.*;

import lombok.RequiredArgsConstructor;

import io.swagger.v3.oas.annotations.Operation;
import umc.codeplay.apiPayLoad.ApiResponse;
import umc.codeplay.config.security.CustomUserDetails;
import umc.codeplay.converter.MemberConverter;
import umc.codeplay.domain.Member;
import umc.codeplay.domain.Music;
import umc.codeplay.dto.MemberRequestDTO;
import umc.codeplay.dto.MemberResponseDTO;
import umc.codeplay.repository.MemberRepository;
import umc.codeplay.repository.MusicRepository;
import umc.codeplay.service.MemberService;

@RestController
Expand All @@ -20,18 +27,125 @@ public class MemberController {

private final MemberService memberService;
private final MemberConverter memberConverter;
private final MemberRepository memberRepository;
private final MusicRepository musicRepository;

@Operation(summary = "유저 정보 업데이트(비밀번호 변경)", description = "기존 비밀번호, 새로운 비밀번호 입력")
@PutMapping("/update")
public ApiResponse<MemberResponseDTO.UpdateResultDTO> updateMember(
@AuthenticationPrincipal
CustomUserDetails
userDetails, // 현재 로그인된 사용자 정보, email로 조회하기 위해 customUserDetails 사용
@RequestBody MemberRequestDTO.UpdateMemberDTO requestDto) {

// userDetails.getUsername() -> 로그인된 사용자의 email
Member updatedMember = memberService.updateMember(userDetails.getUsername(), requestDto);
MemberResponseDTO.UpdateResultDTO responseDto =
memberConverter.toUpdateResultDTO(updatedMember);

return ApiResponse.onSuccess(responseDto);
}

@Operation(summary = "마이페이지 화성분석 탭 결과", description = "로그인한 상태에서 마이페이지")
@GetMapping("/mypage/harmony")
public ApiResponse<List<MemberResponseDTO.GetMyHarmonyDTO>> getMyHarmony(
@AuthenticationPrincipal CustomUserDetails userDetails) {

String email = userDetails.getUsername();

Optional<Member> optionalMember = memberRepository.findByEmail(email);
if (optionalMember.isEmpty()) {
throw new RuntimeException("사용자를 찾을 수 없습니다.");
}
Member member = optionalMember.get();

List<MemberResponseDTO.GetMyHarmonyDTO> results = memberService.getMyHarmony(member);

return ApiResponse.onSuccess(results);
}

@Operation(summary = "마이페이지 세션분리 탭 결과", description = "로그인한 상태에서 마이페이지")
@GetMapping("/mypage/track")
public ApiResponse<List<MemberResponseDTO.GetMyTrackDTO>> getMyTracks(
@AuthenticationPrincipal CustomUserDetails userDetails) {

String email = userDetails.getUsername();

Optional<Member> optionalMember = memberRepository.findByEmail(email);
if (optionalMember.isEmpty()) {
throw new RuntimeException("사용자를 찾을 수 없습니다.");
}
Member member = optionalMember.get();

List<MemberResponseDTO.GetMyTrackDTO> results = memberService.getMyTrack(member);

return ApiResponse.onSuccess(results);
}

@Operation(summary = "마이페이지 전체 검색", description = "파라미터 musicTitle에 음원 제목으로 검색")
@GetMapping("/mypage/search")
public ApiResponse<MemberResponseDTO.GetAllByMusicTitleDTO> getByMusicTitle(
@AuthenticationPrincipal CustomUserDetails userDetails,
@RequestParam String musicTitle) {

// 현재 로그인한 사용자 검색
String email = userDetails.getUsername();

Optional<Member> optionalMember = memberRepository.findByEmail(email);
if (optionalMember.isEmpty()) {
throw new RuntimeException("사용자를 찾을 수 없습니다.");
}
Member member = optionalMember.get();

Music music = musicRepository.findByTitle(musicTitle);

MemberResponseDTO.GetAllByMusicTitleDTO results =
memberService.getAllByMusicTitle(member, music);

return ApiResponse.onSuccess(results);
}

@Operation(summary = "마이페이지 화성분석 검색", description = "파라미터 musicTitle에 음원 제목으로 검색")
@GetMapping("/mypage/harmony/search")
public ApiResponse<List<MemberResponseDTO.GetMyHarmonyDTO>> getHarmonyByMusicTitle(
@AuthenticationPrincipal CustomUserDetails userDetails,
@RequestParam String musicTitle) {
// 현재 로그인한 사용자 검색
String email = userDetails.getUsername();

Optional<Member> optionalMember = memberRepository.findByEmail(email);
if (optionalMember.isEmpty()) {
throw new RuntimeException("사용자를 찾을 수 없습니다.");
}
Member member = optionalMember.get();

Music music = musicRepository.findByTitle(musicTitle);

List<MemberResponseDTO.GetMyHarmonyDTO> results =
memberService.getHarmonyByMusicTitle(member, music);

return ApiResponse.onSuccess(results);
}

@Operation(summary = "마이페이지 세션분리 검색", description = "파라미터 musicTitle에 음원 제목으로 검색")
@GetMapping("/mypage/track/search")
public ApiResponse<List<MemberResponseDTO.GetMyTrackDTO>> getTrackByMusicTitle(
@AuthenticationPrincipal CustomUserDetails userDetails,
@RequestParam String musicTitle) {
// 현재 로그인한 사용자 검색
String email = userDetails.getUsername();

Optional<Member> optionalMember = memberRepository.findByEmail(email);
if (optionalMember.isEmpty()) {
throw new RuntimeException("사용자를 찾을 수 없습니다.");
}
Member member = optionalMember.get();

Music music = musicRepository.findByTitle(musicTitle);

List<MemberResponseDTO.GetMyTrackDTO> results =
memberService.getTrackByMusicTitle(member, music);

return ApiResponse.onSuccess(results);
}
}
61 changes: 61 additions & 0 deletions src/main/java/umc/codeplay/controller/ModelResultController.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
package umc.codeplay.controller;

import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import lombok.RequiredArgsConstructor;

import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import umc.codeplay.apiPayLoad.ApiResponse;
import umc.codeplay.dto.ModelRequestDTO;
import umc.codeplay.dto.ModelResponseDTO;
import umc.codeplay.service.ModelService;

@RestController
@RequiredArgsConstructor
@RequestMapping("/python-model")
@Tag(name = "py-model-controller", description = "Python 로컬 서버의 분석 결과를 저장하는 API (프론트엔드 사용 X)")
public class ModelResultController {

private final ModelService modelService;

@Operation(
summary = "화성 분석 결과 저장",
description = "Python 서버의 화성 분석 결과를 저장합니다. 프론트엔드에서 사용하지 않습니다.")
@PostMapping("/harmony")
public ApiResponse<ModelResponseDTO.HarmonyResponseDTO> updateHarmony(
@RequestBody ModelRequestDTO.HarmonyRequestDTO harmonyRequestDTO) {

return ApiResponse.onSuccess(
ModelResponseDTO.HarmonyResponseDTO.builder()
.harmonyId(modelService.setHarmony(harmonyRequestDTO))
.build());
}

@Operation(
summary = "세션 분리 결과 저장",
description = "Python 서버의 세션 분리 결과를 저장합니다. 프론트엔드에서 사용하지 않습니다.")
@PostMapping("/tracks")
public ApiResponse<ModelResponseDTO.TrackResponseDTO> updateTrack(
@RequestBody ModelRequestDTO.TrackRequestDTO trackRequestDTO) {

return ApiResponse.onSuccess(
ModelResponseDTO.TrackResponseDTO.builder()
.trackId(modelService.setTrack(trackRequestDTO))
.build());
}

@Operation(summary = "리믹스 결과 저장", description = "Python 서버의 리믹스 결과를 저장합니다. 프론트엔드에서 사용하지 않습니다.")
@PostMapping("/remix")
public ApiResponse<ModelResponseDTO.RemixResponseDTO> updateTrack(
@RequestBody ModelRequestDTO.RemixRequestDTO remixRequestDTO) {

return ApiResponse.onSuccess(
ModelResponseDTO.RemixResponseDTO.builder()
.remixId(modelService.setRemix(remixRequestDTO))
.build());
}
}
8 changes: 4 additions & 4 deletions src/main/java/umc/codeplay/controller/OAuthController.java
Original file line number Diff line number Diff line change
Expand Up @@ -74,12 +74,12 @@ public ApiResponse<MemberResponseDTO.LoginResultDTO> OAuthCallback(
String accessToken = (String) tokenResponse.get("access_token");
Map<String, Object> userInfo = requestOAuthUserInfo(accessToken, properties);
String email = null;
String name = null;
// String name = null;
switch (provider) {
case "google" -> {
// (3-a) 구글 UserInfo Endpoint 로 이메일, 프로필 등 조회
email = (String) userInfo.get("email");
name = (String) userInfo.get("name");
// name = (String) userInfo.get("name");
}
case "kakao" -> {
// (3-b) 카카오 UserInfo Endpoint 로 이메일, 프로필 등 조회
Expand All @@ -88,14 +88,14 @@ public ApiResponse<MemberResponseDTO.LoginResultDTO> OAuthCallback(
Map<String, Object> kakaoProperties =
(Map<String, Object>) userInfo.get("properties");
email = (String) kakaoAccount.get("email");
name = (String) kakaoProperties.get("nickname");
// name = (String) kakaoProperties.get("nickname");
}
}

// (4) 우리 DB에서 회원 조회 or 생성
Member member =
memberService.findOrCreateOAuthMember(
email, name, SocialStatus.valueOf(provider.toUpperCase()));
email, SocialStatus.valueOf(provider.toUpperCase()));

// (5) JWTUtil 이용해서 Access/Refresh 토큰 발급
var authorities = List.of(new SimpleGrantedAuthority("ROLE_" + member.getRole().name()));
Expand Down
Loading
Loading