FitPass의 핵심 기능 중 하나인 피트니스 목표 관리 시스템을 개발했습니다. 사용자가 체중 관련 목표를 설정하고 일일 기록을 통해 진행상황을 추적할 수 있도록 하였습니다.
src/main/java/org/example/fitpass/domain/fitnessGoal/
├── controller/
│ ├── FitnessGoalController.java
│ ├── WeightRecordController.java
│ └── DailyRecordController.java
├── service/
│ ├── FitnessGoalService.java
│ ├── WeightRecordService.java
│ └── DailyRecordService.java
├── entity/
│ ├── FitnessGoal.java
│ ├── WeightRecord.java
│ └── DailyRecord.java
├── dto/
│ ├── request/
│ └── response/
├── repository/
├── enums/
└── scheduler/
POST /fitness-goals
GET /fitness-goals
GET /fitness-goals/{goalId}
PUT /fitness-goals/{goalId}
PATCH /fitness-goals/{goalId}/cancel
DELETE /fitness-goals/{goalId}
POST /fitness-goals/{goalId}/weight-records
GET /fitness-goals/{goalId}/weight-records
PUT /weight-records/{recordId}
DELETE /weight-records/{recordId}
POST /fitness-goals/{goalId}/daily-records
GET /fitness-goals/{goalId}/daily-records
DELETE /daily-records/{recordId}
RESTful API 설계
도메인 주도 설계
확장 가능한 아키텍처
자동화된 비즈니스 로직 (스케줄링 기반 자동화)
목표 달성률을 계산하는 과정에서 다양한 제약사항들을 로직으로 체크해야하는 과정이 어려웠음.
null 체크시 누락, 0으로 나누기, 목표 유형 미고려, 음수 진행률, 100% 초과 등 여러 제약들이 있었기에 하나씩 추가하는 과정을 거쳤다.
// 목표 달성률 계산
public double calculateProgressRate() {
if (startWeight == null || targetWeight == null || currentWeight == null) {
return 0.0;
}
// 목표 체중과 시작 체중이 같으면 100% (이미 달성)
if (startWeight.equals(targetWeight)) {
return 100.0;
}
double totalWeightDiff = Math.abs(targetWeight - startWeight);
double currentWeightDiff = Math.abs(startWeight - currentWeight);
// 감량 목표인지 증량 목표인지 확인
if (goalType == GoalType.WEIGHT_LOSS) {
// 감량: 현재가 목표보다 적게 나가야 함
if (currentWeight <= targetWeight) {
return 100.0; // 목표 달성
}
return Math.min(currentWeightDiff / totalWeightDiff * 100, 100.0);
} else if (goalType == GoalType.WEIGHT_GAIN) {
// 증량: 현재가 목표보다 많이 나가야 함
if (currentWeight >= targetWeight) {
return 100.0; // 목표 달성
}
return Math.min(currentWeightDiff / totalWeightDiff * 100, 100.0);
} else {
// 유지: 목표 체중 ±1kg 범위 내면 100%
double diff = Math.abs(currentWeight - targetWeight);
if (diff <= 1.0) {
return 100.0;
}
return Math.max(0, 100 - (diff * 10)); // 1kg당 10%씩 감점
}
}