Skip to content
Merged
Show file tree
Hide file tree
Changes from 9 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
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,39 @@ public static class TeamSummary {
private String teamName;

public static TeamSummary from(AppjamUser appjamUser) {
return TeamSummary.builder().
teamNumber(appjamUser.getTeamNumber())
return TeamSummary.builder()
.teamNumber(appjamUser.getTeamNumber())
.teamName(appjamUser.getTeamName())
.build();
}

public static TeamSummary empty() {
return TeamSummary.builder()
.build();
}
}

@Getter
@Builder
@ToString
public static class AppjamUserStatus {

private TeamNumber teamNumber;
private String teamName;
private boolean isAppjamJoined;

public static AppjamUserStatus appjamJoined(AppjamUser appjamUser) {
return AppjamUserStatus.builder()
.teamNumber(appjamUser.getTeamNumber())
.teamName(appjamUser.getTeamName())
.isAppjamJoined(true)
.build();
}

public static AppjamUserStatus appjamNotJoined() {
return AppjamUserStatus.builder()
.isAppjamJoined(false)
.build();
}
}
}
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
package org.sopt.app.application.appjamuser;

import lombok.RequiredArgsConstructor;
import lombok.val;
import org.sopt.app.application.appjamuser.AppjamUserInfo.AppjamUserStatus;
import org.sopt.app.application.appjamuser.AppjamUserInfo.TeamSummary;
import org.sopt.app.common.exception.NotFoundException;
import org.sopt.app.common.response.ErrorCode;
import org.sopt.app.domain.entity.AppjamUser;
import org.sopt.app.domain.enums.TeamNumber;
import org.sopt.app.interfaces.postgres.AppjamUserRepository;
import org.springframework.stereotype.Service;
Expand All @@ -15,14 +16,20 @@ public class AppjamUserService {

private final AppjamUserRepository appjamUserRepository;

public AppjamUserStatus getAppjamUserStatus(Long userId) {
return appjamUserRepository.findByUserId(userId)
.map(AppjamUserStatus::appjamJoined)
.orElseGet(AppjamUserStatus::appjamNotJoined);
}

public TeamSummary getTeamSummaryByTeamNumber(TeamNumber teamNumber) {
AppjamUser appjamUser = appjamUserRepository.findTopByTeamNumberOrderById(teamNumber)
val appjamUser = appjamUserRepository.findTopByTeamNumberOrderById(teamNumber)
.orElseThrow(() -> new NotFoundException(ErrorCode.TEAM_NOT_FOUND));
return TeamSummary.from(appjamUser);
}

public TeamSummary getTeamSummaryByUserId(Long userId) {
AppjamUser appjamUser = appjamUserRepository.findByUserId(userId)
val appjamUser = appjamUserRepository.findByUserId(userId)
.orElseThrow(() -> new NotFoundException(ErrorCode.TEAM_NOT_FOUND));
return TeamSummary.from(appjamUser);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,14 @@ public class AppjamMissionService {
private final StampRepository stampRepository;
private final SoptampUserRepository soptampUserRepository;

public List<AppjamMissionInfo> getDisplayedMissions() {
val displayedMissions = missionRepository.findAllByDisplay(true);
return displayedMissions.stream()
.map(AppjamMissionInfo::createWhenUncompleted)
.toList();
}

public List<AppjamMissionInfo> getAllMissions(TeamNumber teamNumber) {
public List<AppjamMissionInfo> getMissionsByTeam(TeamNumber teamNumber) {
val userIds = getTeamUserIds(teamNumber);
val stampsByMissionId = getStampMapByUserIds(userIds);
val soptampUserByUserId = getSoptampUserMapByUserIds(userIds);
Expand All @@ -42,9 +48,9 @@ public List<AppjamMissionInfo> getAllMissions(TeamNumber teamNumber) {
.toList();
}

public List<AppjamMissionInfo> getMissionsByCondition(TeamNumber teamNumber,
public List<AppjamMissionInfo> getMissionsByTeamAndCondition(TeamNumber teamNumber,
boolean isCompleted) {
List<AppjamMissionInfo> allMissions = getAllMissions(teamNumber);
List<AppjamMissionInfo> allMissions = getMissionsByTeam(teamNumber);

return allMissions.stream()
.filter(mission -> Objects.equals(mission.isCompleted(), isCompleted))
Expand Down
16 changes: 16 additions & 0 deletions src/main/java/org/sopt/app/application/mission/MissionInfo.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.ToString;
import org.sopt.app.application.appjamuser.AppjamUserInfo.AppjamUserStatus;
import org.sopt.app.application.appjamuser.AppjamUserInfo.TeamSummary;
import org.sopt.app.domain.entity.soptamp.Mission;
import org.sopt.app.domain.enums.TeamNumber;
Expand Down Expand Up @@ -63,22 +64,37 @@ public static AppjamMissionInfo of(
.isCompleted(isCompleted)
.build();
}

public static AppjamMissionInfo createWhenUncompleted(Mission mission) {
return AppjamMissionInfo.builder()
.id(mission.getId())
.title(mission.getTitle())
.level(mission.getLevel())
.profileImage(mission.getProfileImage())
.isCompleted(false)
.build();
}
}

@Getter
@Builder
@ToString
public static class AppjamMissionInfos {

private TeamNumber myTeamNumber;
private boolean isAppjamJoined;
private TeamNumber teamNumber;
private String teamName;
private List<AppjamMissionInfo> missions;

public static AppjamMissionInfos of(
AppjamUserStatus appjamUserStatus,
TeamSummary teamSummary,
List<AppjamMissionInfo> missions
) {
return AppjamMissionInfos.builder()
.myTeamNumber(appjamUserStatus.getTeamNumber())
.isAppjamJoined(appjamUserStatus.isAppjamJoined())
.teamNumber(teamSummary.getTeamNumber())
.teamName(teamSummary.getTeamName())
.missions(missions)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package org.sopt.app.application.stamp;

import lombok.RequiredArgsConstructor;
import lombok.val;
import org.sopt.app.common.exception.BadRequestException;
import org.sopt.app.common.response.ErrorCode;
import org.sopt.app.domain.entity.AppjamUser;
import org.sopt.app.domain.enums.TeamNumber;
import org.sopt.app.interfaces.postgres.AppjamUserRepository;
import org.sopt.app.interfaces.postgres.StampRepository;
import org.sopt.app.presentation.appjamtamp.AppjamtampRequest;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service
@RequiredArgsConstructor
public class AppjamStampService {

private final AppjamUserRepository appjamUserRepository;
private final StampRepository stampRepository;

@Transactional(readOnly = true)
public void checkDuplicateStamp(TeamNumber teamNumber, Long missionId) {
val appjamUsers = appjamUserRepository.findAllByTeamNumber(teamNumber);
val isDuplicated = stampRepository.existsByUserIdInAndMissionId(
appjamUsers.stream().map(AppjamUser::getId).toList(), missionId);
if (isDuplicated) {
throw new BadRequestException(ErrorCode.DUPLICATE_STAMP);
}
}

@Transactional
public StampInfo.Stamp uploadStamp(
AppjamtampRequest.RegisterStampRequest stampRequest,
Long userId
) {
val stamp = stampRequest.toStamp(userId);
val newStamp = stampRepository.save(stamp);
return StampInfo.Stamp.from(newStamp);
}
}
15 changes: 15 additions & 0 deletions src/main/java/org/sopt/app/application/stamp/StampInfo.java
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,21 @@ public static class Stamp {
private LocalDateTime updatedAt;
private int clapCount;
private int viewCount;

public static StampInfo.Stamp from(org.sopt.app.domain.entity.soptamp.Stamp stamp) {
return Stamp.builder()
.id(stamp.getId())
.contents(stamp.getContents())
.images(stamp.getImages())
.userId(stamp.getUserId())
.missionId(stamp.getMissionId())
.activityDate(stamp.getActivityDate())
.createdAt(stamp.getCreatedAt())
.updatedAt(stamp.getUpdatedAt())
.clapCount(stamp.getClapCount())
.viewCount(stamp.getViewCount())
.build();
}
}

@Getter
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
package org.sopt.app.application.stamp;

import jakarta.validation.Valid;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import jakarta.validation.Valid;
import java.util.Objects;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
Expand All @@ -20,6 +20,7 @@
import org.sopt.app.presentation.stamp.StampRequest.RegisterStampRequest;
import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

Expand Down Expand Up @@ -242,7 +243,8 @@ public int getStampClapCount(Long stampId) {
.getClapCount();
}

@Transactional
// TODO: 비동기로 별도 스레드 혹은 이벤트로 처리하도록 변경
@Transactional(propagation = Propagation.REQUIRES_NEW)
public void increaseViewCountById(Long stampId) {
stampRepository.increaseViewCount(stampId);
}
Expand Down
3 changes: 2 additions & 1 deletion src/main/java/org/sopt/app/common/response/ErrorCode.java
Original file line number Diff line number Diff line change
Expand Up @@ -61,8 +61,9 @@ public enum ErrorCode {
// MISSION
MISSION_NOT_FOUND("존재하지 않는 미션입니다.", HttpStatus.NOT_FOUND),

//TEAM
// TEAM
TEAM_NOT_FOUND("존재하지 않는 팀입니다.", HttpStatus.NOT_FOUND),
TEAM_FORBIDDEN("해당 팀에 대한 권한이 없습니다.", HttpStatus.FORBIDDEN),

// STAMP
STAMP_NOT_FOUND("존재하지 않는 스탬프입니다.", HttpStatus.BAD_REQUEST),
Expand Down
29 changes: 29 additions & 0 deletions src/main/java/org/sopt/app/facade/AppjamtampFacade.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,21 @@
import java.util.Objects;
import lombok.RequiredArgsConstructor;
import lombok.val;
import org.sopt.app.application.appjamuser.AppjamUserInfo.AppjamUserStatus;
import org.sopt.app.application.appjamuser.AppjamUserService;
import org.sopt.app.application.mission.MissionInfo.Level;
import org.sopt.app.application.mission.MissionService;
import org.sopt.app.application.platform.PlatformService;
import org.sopt.app.application.soptamp.SoptampUserFinder;
import org.sopt.app.application.soptamp.SoptampUserService;
import org.sopt.app.application.stamp.AppjamStampService;
import org.sopt.app.application.stamp.ClapService;
import org.sopt.app.application.stamp.StampInfo;
import org.sopt.app.application.stamp.StampInfo.AppjamtampView;
import org.sopt.app.application.stamp.StampService;
import org.sopt.app.common.exception.BadRequestException;
import org.sopt.app.common.response.ErrorCode;
import org.sopt.app.presentation.appjamtamp.AppjamtampRequest.RegisterStampRequest;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

Expand All @@ -22,6 +30,9 @@ public class AppjamtampFacade {
private final StampService stampService;
private final ClapService clapService;
private final AppjamUserService appjamUserService;
private final AppjamStampService appjamStampService;
private final SoptampUserService soptampUserService;
private final MissionService missionService;

@Transactional(readOnly = true)
public AppjamtampView getAppjamtamps(Long requestUserId, Long missionId, String nickname) {
Expand All @@ -42,4 +53,22 @@ public AppjamtampView getAppjamtamps(Long requestUserId, Long missionId, String
teamSummary
);
}

@Transactional
public StampInfo.Stamp uploadStamp(Long userId, RegisterStampRequest registerStampRequest) {
val appjamUserStatus = appjamUserService.getAppjamUserStatus(userId);
if (!appjamUserStatus.isAppjamJoined()) {
throw new BadRequestException(ErrorCode.TEAM_FORBIDDEN);
}
appjamStampService.checkDuplicateStamp(appjamUserStatus.getTeamNumber(),
registerStampRequest.getMissionId());
val result = appjamStampService.uploadStamp(registerStampRequest, userId);
Level mission = missionService.getMissionLevelById(registerStampRequest.getMissionId());
soptampUserService.addPointByLevel(userId, mission.getLevel());
return result;
}

public AppjamUserStatus getAppjampStatus(Long userId){
return appjamUserService.getAppjamUserStatus(userId);
}
}
24 changes: 18 additions & 6 deletions src/main/java/org/sopt/app/facade/MissionFacade.java
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
package org.sopt.app.facade;

import java.util.Optional;
import lombok.RequiredArgsConstructor;
import lombok.val;
import org.sopt.app.application.appjamuser.AppjamUserInfo.AppjamUserStatus;
import org.sopt.app.application.appjamuser.AppjamUserInfo.TeamSummary;
import org.sopt.app.application.appjamuser.AppjamUserService;
import org.sopt.app.application.mission.AppjamMissionService;
import org.sopt.app.application.mission.MissionInfo.AppjamMissionInfos;
import org.sopt.app.domain.enums.TeamNumber;
import org.springframework.lang.Nullable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

Expand All @@ -19,16 +21,26 @@ public class MissionFacade {

@Transactional(readOnly = true)
public AppjamMissionInfos getTeamMissions(
TeamNumber teamNumber,
Optional<Boolean> complete
Long userId,
@Nullable TeamNumber teamNumber,
@Nullable Boolean complete
) {
if (teamNumber == null) {
val missions = appjamMissionService.getDisplayedMissions();
return AppjamMissionInfos.of(AppjamUserStatus.appjamNotJoined(), TeamSummary.empty(),
missions);
}

val teamSummary = appjamUserService.getTeamSummaryByTeamNumber(teamNumber);
if (complete.isPresent()) {
val appjamUserStatus = appjamUserService.getAppjamUserStatus(userId);
if (complete != null) {
return AppjamMissionInfos.of(
appjamUserStatus,
teamSummary,
appjamMissionService.getMissionsByCondition(teamNumber, complete.get()));
appjamMissionService.getMissionsByTeamAndCondition(teamNumber, complete));
}
return AppjamMissionInfos.of(teamSummary, appjamMissionService.getAllMissions(teamNumber));
return AppjamMissionInfos.of(appjamUserStatus, teamSummary,
appjamMissionService.getMissionsByTeam(teamNumber));
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ public interface StampRepository extends JpaRepository<Stamp, Long>, StampReposi

List<Stamp> findAllByUserIdIn(Collection<Long> userIds);

boolean existsByUserIdInAndMissionId(Collection<Long> userIds, Long missionId);

@Modifying(clearAutomatically = true, flushAutomatically = true)
@Query("""
update Stamp s set s.viewCount = s.viewCount + 1
Expand Down
Loading