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
6 changes: 5 additions & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,11 @@ jobs:
run: chmod +x gradlew

- name: Build
run: ./gradlew build --info --stacktrace

- name: SonarCloud Analysis
continue-on-error: true
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
run: ./gradlew build sonar --info --stacktrace
run: ./gradlew sonar --info --stacktrace
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ application-local.yml
application-dev.yml
application-prod.yml
/src/main/generated/
.claude

### NetBeans ###
/nbproject/private/
Expand All @@ -47,3 +48,6 @@ application-prod.yml
./src/main/resources/config

/logs

# AI Tool Configuration
CLAUDE.md
9 changes: 7 additions & 2 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ sonar {
property "sonar.host.url", "https://sonarcloud.io"
property "sonar.coverage.jacoco.xmlReportPaths", "build/reports/jacoco/test/jacocoTestReport.xml"
property "sonar.exclusions", "**/*Application*.java, **/*Config*.java, **/*GlobalExceptionHandler.java, **/Q*.java, **/DynamicQuery.java, " +
"**/*Exception.java, **/*Adapter.java, **/CustomOAuth2UserService.java, **/*Filter.java"
"**/*Exception.java, **/*Adapter.java, **/CustomOAuth2UserService.java, **/*Filter.java, **/*Converter.java"
property "sonar.java.coveragePlugin", "jacoco"
}
}
Expand Down Expand Up @@ -126,7 +126,8 @@ jacocoTestCoverageVerification {
'*.*.CustomUserDetails',
'scouter.*',
'reactor.*',
'*.*RepositoryImpl'
'*.*RepositoryImpl',
'*.*Converter'
]
}
}
Expand Down Expand Up @@ -214,4 +215,8 @@ dependencies {
// 이미지 메타데이터 관련 라이브러리
implementation 'com.drewnoakes:metadata-extractor:2.19.0'
implementation 'org.apache.commons:commons-imaging:1.0.0-alpha5'

// Flyway
implementation 'org.flywaydb:flyway-core'
implementation 'org.flywaydb:flyway-mysql'
}
3 changes: 2 additions & 1 deletion src/main/java/com/tnt/common/error/model/ErrorMessage.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
public enum ErrorMessage {

SERVER_ERROR("서버 에러가 발생했습니다."),
FAILED_TO_CONVERT_JSON("JSON 직렬화에 실패했습니다."),
FCM_FAILED("FCM 전송에 실패했습니다."),
S3_UPLOAD_ERROR("S3로 이미지 업로드 중 오류가 발생했습니다."),
S3_DELETE_ERROR("S3 이미지 삭제 중 오류가 발생했습니다."),
Expand Down Expand Up @@ -48,7 +49,7 @@ public enum ErrorMessage {
TRAINEE_INVALID_CAUTION_NOTE("주의사항이 올바르지 않습니다."),
TRAINEE_NOT_FOUND("존재하지 않는 트레이니입니다."),

PT_GOAL_INVALID_CONTENT("목적 내용이 올바르지 않습니다."),
UNSUPPORTED_PT_GOAL("지원하지 않는 PT 목적입니다."),

PT_TRAINER_TRAINEE_ALREADY_EXIST("이미 연결된 트레이너-트레이니입니다."),
PT_TRAINEE_ALREADY_EXIST("이미 다른 트레이너와 연결되어 있습니다."),
Expand Down
43 changes: 2 additions & 41 deletions src/main/java/com/tnt/member/application/MemberService.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,8 @@
import static com.tnt.member.domain.MemberType.TRAINER;
import static com.tnt.member.dto.MemberProjection.MemberTypeDto;
import static java.util.Objects.isNull;
import static java.util.stream.Collectors.toSet;

import java.util.HashSet;
import java.util.List;
import java.util.Set;

import org.springframework.lang.Nullable;
import org.springframework.stereotype.Service;
Expand All @@ -28,9 +25,7 @@
import com.tnt.member.dto.response.MemberInfoResponse;
import com.tnt.pt.application.PtService;
import com.tnt.pt.domain.PtTrainerTrainee;
import com.tnt.trainee.application.PtGoalService;
import com.tnt.trainee.application.TraineeService;
import com.tnt.trainee.application.repository.PtGoalRepository;
import com.tnt.trainee.application.repository.TraineeRepository;
import com.tnt.trainee.domain.PtGoal;
import com.tnt.trainee.domain.Trainee;
Expand All @@ -45,12 +40,10 @@ public class MemberService {

private final TrainerService trainerService;
private final TraineeService traineeService;
private final PtGoalService ptGoalService;
private final PtService ptService;

private final MemberRepository memberRepository;
private final TraineeRepository traineeRepository;
private final PtGoalRepository ptGoalRepository;

@Transactional(readOnly = true)
public MemberInfoResponse getMemberInfo(Long memberId) {
Expand Down Expand Up @@ -78,10 +71,7 @@ public MemberInfoResponse getMemberInfo(Long memberId) {

if (member.getMemberType() == TRAINEE) {
Trainee trainee = traineeService.getByMemberId(memberId);
List<String> ptGoals = ptGoalService.getAllByTraineeId(trainee.getId())
.stream()
.map(PtGoal::getContent)
.toList();
List<PtGoal> ptGoals = trainee.getPtGoals();
boolean isConnected = ptService.isPtTrainerTraineeExistWithTraineeId(trainee.getId());

MemberInfoResponse.TraineeInfo traineeInfo = new MemberInfoResponse.TraineeInfo(isConnected,
Expand Down Expand Up @@ -154,8 +144,7 @@ public void updateMemberInfo(Long memberId, UpdateMemberInfoRequest request, Str
Trainee trainee = traineeService.getByMemberId(memberId);

member.updateBirthday(request.birthday());
trainee.updateTraineeInfo(request.height(), request.weight(), request.cautionNote());
updatePtGoals(trainee, new HashSet<>(request.goalContents()));
trainee.updateTraineeInfo(request.height(), request.weight(), request.cautionNote(), request.ptGoals());

traineeRepository.save(trainee);
}
Expand All @@ -175,32 +164,4 @@ public void validateMemberNotExists(String socialId, SocialType socialType) {
public Member getByMemberId(Long memberId) {
return memberRepository.findById(memberId);
}

private void updatePtGoals(Trainee trainee, HashSet<String> newGoalContents) {
// 기존 PT 목표들 조회
List<PtGoal> currentPtGoals = ptGoalService.getAllByTraineeId(trainee.getId());

// 기존 목표 중 더 이상 필요없는 목표 삭제
List<PtGoal> goalsToDelete = currentPtGoals.stream()
.filter(goal -> !newGoalContents.contains(goal.getContent()))
.toList();

if (!goalsToDelete.isEmpty()) {
ptGoalRepository.deleteAll(goalsToDelete);
}

// 새로운 목표 추가 (기존에 없는 것만)
Set<String> existingContents = currentPtGoals.stream()
.map(PtGoal::getContent)
.collect(toSet());

List<PtGoal> newPtGoals = newGoalContents.stream()
.filter(content -> !existingContents.contains(content))
.map(content -> PtGoal.builder().traineeId(trainee.getId()).content(content).build())
.toList();

if (!newPtGoals.isEmpty()) {
ptGoalRepository.saveAll(newPtGoals);
}
}
}
22 changes: 5 additions & 17 deletions src/main/java/com/tnt/member/application/SignUpService.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@
import com.tnt.member.domain.MemberType;
import com.tnt.member.dto.request.SignUpRequest;
import com.tnt.member.dto.response.SignUpResponse;
import com.tnt.trainee.application.repository.PtGoalRepository;
import com.tnt.trainee.application.repository.TraineeRepository;
import com.tnt.trainee.domain.PtGoal;
import com.tnt.trainee.domain.Trainee;
Expand All @@ -32,11 +31,9 @@ public class SignUpService {

private final SessionService sessionService;
private final MemberService memberService;

private final MemberRepository memberRepository;
private final TrainerRepository trainerRepository;
private final TraineeRepository traineeRepository;
private final PtGoalRepository ptGoalRepository;

@Transactional
public Long signUp(SignUpRequest request) {
Expand Down Expand Up @@ -76,16 +73,18 @@ private Long createTrainer(SignUpRequest request) {

private Long createTrainee(SignUpRequest request) {
Member member = createMember(request, TRAINEE_DEFAULT_IMAGE, TRAINEE);

List<PtGoal> ptGoals = request.ptGoals().stream().map(PtGoal::of).toList();

Trainee trainee = Trainee.builder()
.member(member)
.height(request.height())
.weight(request.weight())
.cautionNote(request.cautionNote())
.ptGoals(ptGoals)
.build();

trainee = traineeRepository.save(trainee);

createPtGoals(trainee, request.goalContents());
traineeRepository.save(trainee);

return member.getId();
}
Expand All @@ -107,15 +106,4 @@ private Member createMember(SignUpRequest request, String defaultImageUrl, Membe

return memberRepository.save(member);
}

private void createPtGoals(Trainee trainee, List<String> goalContents) {
List<PtGoal> ptGoals = goalContents.stream()
.map(content -> PtGoal.builder()
.traineeId(trainee.getId())
.content(content)
.build())
.toList();

ptGoalRepository.saveAll(ptGoals);
}
}
9 changes: 0 additions & 9 deletions src/main/java/com/tnt/member/application/WithdrawService.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,10 @@
import com.tnt.pt.domain.PtLesson;
import com.tnt.pt.domain.PtTrainerTrainee;
import com.tnt.trainee.application.DietService;
import com.tnt.trainee.application.PtGoalService;
import com.tnt.trainee.application.TraineeService;
import com.tnt.trainee.application.repository.DietRepository;
import com.tnt.trainee.application.repository.PtGoalRepository;
import com.tnt.trainee.application.repository.TraineeRepository;
import com.tnt.trainee.domain.Diet;
import com.tnt.trainee.domain.PtGoal;
import com.tnt.trainee.domain.Trainee;
import com.tnt.trainer.application.TrainerService;
import com.tnt.trainer.application.repository.TrainerRepository;
Expand All @@ -41,11 +38,8 @@ public class WithdrawService {
private final MemberService memberService;
private final TrainerService trainerService;
private final TraineeService traineeService;
private final PtGoalService ptGoalService;
private final DietService dietService;
private final PtService ptService;

private final PtGoalRepository ptGoalRepository;
private final MemberRepository memberRepository;
private final TrainerRepository trainerRepository;
private final TraineeRepository traineeRepository;
Expand Down Expand Up @@ -90,7 +84,6 @@ private void deleteMemberData(Member member) {

if (member.getMemberType() == TRAINEE) {
Trainee trainee = traineeService.getByMemberId(member.getId());
List<PtGoal> ptGoals = ptGoalService.getAllByTraineeId(trainee.getId());
List<Diet> diets = dietService.getAllByTraineeId(trainee.getId());

if (ptService.isPtTrainerTraineeExistWithTraineeId(trainee.getId())) {
Expand All @@ -108,8 +101,6 @@ private void deleteMemberData(Member member) {
}
}

ptGoalRepository.deleteAll(ptGoals);

diets.forEach(Diet::softDelete);
dietRepository.saveAll(diets);

Expand Down
4 changes: 2 additions & 2 deletions src/main/java/com/tnt/member/dto/request/SignUpRequest.java
Original file line number Diff line number Diff line change
Expand Up @@ -66,8 +66,8 @@ public record SignUpRequest(
@Schema(description = "주의사항", example = "가냘퍼요", nullable = true)
String cautionNote,

@Schema(description = "PT 목적들", example = "[\"체중 감량\", \"근력 향상\"]", nullable = false)
List<String> goalContents
@Schema(description = "PT 목적", example = "[\"체중 감량\", \"근력 향상\"]", nullable = false)
List<String> ptGoals
) {

}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import java.util.List;

import com.tnt.member.domain.MemberType;
import com.tnt.trainee.domain.PtGoal;

import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.Digits;
Expand Down Expand Up @@ -39,8 +40,8 @@ public record UpdateMemberInfoRequest(
@Schema(description = "주의사항", example = "가냘퍼요", nullable = true)
String cautionNote,

@Schema(description = "PT 목적들", example = "[\"체중 감량\", \"근력 향상\"]", nullable = false)
List<String> goalContents
@Schema(description = "PT 목적", example = "[\"WEIGHT_LOSS\", \"STRENGTH_ENHANCE\"]", nullable = false)
List<PtGoal> ptGoals
) {

}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

import com.tnt.member.domain.MemberType;
import com.tnt.member.domain.SocialType;
import com.tnt.trainee.domain.PtGoal;

import io.swagger.v3.oas.annotations.media.Schema;

Expand Down Expand Up @@ -61,8 +62,8 @@ public record TraineeInfo(
@Schema(description = "주의사항", example = "가냘퍼요", nullable = true)
String cautionNote,

@Schema(description = "PT 목적들", example = "[\"체중 감량\", \"근력 향상\"]", nullable = false)
List<String> ptGoals
@Schema(description = "PT 목적", example = "[\"WEIGHT_LOSS\", \"STRENGTH_ENHANCE\"]", nullable = false)
List<PtGoal> ptGoals
) {

}
Expand Down
12 changes: 3 additions & 9 deletions src/main/java/com/tnt/pt/application/PtService.java
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@
import com.tnt.pt.domain.PtTrainerTrainee;
import com.tnt.pt.dto.PtTrainerTraineeProjection;
import com.tnt.trainee.application.DietService;
import com.tnt.trainee.application.PtGoalService;
import com.tnt.trainee.application.TraineeService;
import com.tnt.trainee.domain.Diet;
import com.tnt.trainee.domain.PtGoal;
Expand Down Expand Up @@ -60,7 +59,6 @@ public class PtService {

private final TrainerService trainerService;
private final TraineeService traineeService;
private final PtGoalService ptGoalService;
private final DietService dietService;

private final PtTrainerTraineeRepository ptTrainerTraineeRepository;
Expand Down Expand Up @@ -100,13 +98,12 @@ public ConnectWithTraineeResponse getFirstTrainerTraineeConnect(Long memberId, L
Member trainerMember = trainer.getMember(); // fetch join 으로 가져온 member
Member traineeMember = trainee.getMember(); // fetch join 으로 가져온 member

List<PtGoal> ptGoals = ptGoalService.getAllByTraineeId(traineeId);
String ptGoal = ptGoals.stream().map(PtGoal::getContent).collect(Collectors.joining(", "));
List<PtGoal> ptGoals = trainee.getPtGoals();

return new ConnectWithTraineeResponse(
new ConnectTrainerInfo(trainerMember.getName(), trainerMember.getProfileImageUrl()),
new ConnectTraineeInfo(traineeMember.getName(), traineeMember.getProfileImageUrl(),
traineeMember.getAge(), trainee.getHeight(), trainee.getWeight(), ptGoal, trainee.getCautionNote())
traineeMember.getAge(), trainee.getHeight(), trainee.getWeight(), ptGoals, trainee.getCautionNote())
);
}

Expand Down Expand Up @@ -158,10 +155,7 @@ public GetActiveTraineesResponse getActiveTrainees(Long memberId) {
List<ActiveTraineeInfo> activeTraineeInfo = trainees.stream().map(trainee -> {
PtTrainerTrainee ptTrainerTrainee = ptTrainerTraineeRepository.findByTraineeId(trainee.getId());

List<String> ptGoals = ptGoalService.getAllByTraineeId(trainee.getId())
.stream()
.map(PtGoal::getContent)
.toList();
List<PtGoal> ptGoals = ptTrainerTrainee.getTrainee().getPtGoals();

// Memo 추가 구현 필요
return new ActiveTraineeInfo(trainee.getId(), trainee.getMember().getName(),
Expand Down
1 change: 0 additions & 1 deletion src/main/java/com/tnt/trainee/application/DietService.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@
public class DietService {

private final TraineeService traineeService;

private final DietRepository dietRepository;

@Transactional
Expand Down
21 changes: 0 additions & 21 deletions src/main/java/com/tnt/trainee/application/PtGoalService.java

This file was deleted.

Loading
Loading