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
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,10 @@
import java.util.List;
import java.util.Optional;
import java.util.Set;

import feign.FeignException;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;

import org.sopt.app.application.platform.PlatformService;
import org.sopt.app.application.playground.PlaygroundAuthService;
Expand All @@ -17,6 +20,7 @@
import org.sopt.app.presentation.poke.PokeResponse.*;
import org.springframework.stereotype.Service;

@Slf4j
@Service
@RequiredArgsConstructor
public class FriendRecommender {
Expand Down Expand Up @@ -81,12 +85,24 @@ private List<UserProfile> getRecommendableUserProfiles(
// size 가드 : 이상값 들어오면 500 대신 빈 리스트
if (size <= 0) return List.of();

// ALL_USER 아닐 경우 playground에서 후보 id 수집
/*
후보 id 수집 : ALL_USER 아닐 경우 playground에서 후보 id 수집
TODO : playground 414 시 ALL_USER fallback -> 임시 해결책으로, 플그, 플폼팀과의 논의 후 수정 예정
*/
Set<Long> userIds;
if (type == FriendRecommendType.ALL_USER) {
userIds = Set.copyOf(userService.getAllUserIds());
} else {
userIds = playgroundUserIdsProvider.findPlaygroundIdsByType(ownProfile, type);
try {
userIds = playgroundUserIdsProvider.findPlaygroundIdsByType(ownProfile, type);
} catch (FeignException e) {
if (isUriTooLarge(e)) {
log.info("Playground profile/recommend 414 detected for type={}, fallback to ALL_USER", type);
userIds = Set.copyOf(userService.getAllUserIds());
} else {
throw e; // 다른 에러는 그대로 올림
}
}
}
if (userIds.isEmpty()) return List.of();

Expand Down Expand Up @@ -121,4 +137,10 @@ private List<FriendRecommendType> adjustTypeList(List<FriendRecommendType> typeL
}
return typeList;
}

private boolean isUriTooLarge(FeignException e) {
// playground가 414를 400으로 감싸서 내려주므로 메시지로 판단
String msg = e.getMessage();
return e.status() == 414 || (e.status() == 400 && msg != null && msg.contains("414 Request-URI Too Large"));
}
}
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
package org.sopt.app.application.playground;

import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.stream.Collectors;
import java.util.Map;

import org.sopt.app.application.playground.dto.PlaygroundPopularPost;
import org.sopt.app.application.playground.dto.PlaygroundProfileInfo;
Expand Down Expand Up @@ -35,20 +35,15 @@ public class PlaygroundAuthService {
@Value("${makers.playground.web-page}")
private String playgroundWebPageUrl;

// public PlaygroundProfile getPlaygroundMemberProfile(Long userId) {
// try {
// return playgroundClient.getPlaygroundMemberProfiles(userId).getFirst();
// } catch (BadRequest e) {
// throw new BadRequestException(ErrorCode.PLAYGROUND_PROFILE_NOT_EXISTS);
// }
// }

public List<PlaygroundProfile> getPlaygroundMemberProfiles(List<Long> userIds) {
String stringifyIds = userIds.stream()
.map(String::valueOf)
.collect(Collectors.joining(","));
if (userIds == null || userIds.isEmpty()) return List.of();

// 반복 파라미터 구성
Map<String, Collection<String>> query = new HashMap<>();
query.put("memberIds", userIds.stream().map(String::valueOf).toList());

try {
return playgroundClient.getPlaygroundMemberProfiles(URLEncoder.encode(stringifyIds, StandardCharsets.UTF_8));
return playgroundClient.getPlaygroundMemberProfiles(query);
} catch (BadRequest e) {
throw new BadRequestException(ErrorCode.PLAYGROUND_PROFILE_NOT_EXISTS);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package org.sopt.app.application.playground;

import java.util.Collection;
import java.util.List;
import java.util.Map;

import org.sopt.app.application.playground.dto.PlayGroundUserSoptLevelResponse;
import org.sopt.app.application.playground.dto.PlaygroundPopularPost;
Expand All @@ -14,6 +16,7 @@

import feign.Headers;
import feign.Param;
import feign.QueryMap;
import feign.RequestLine;

@EnableFeignClients
Expand All @@ -24,8 +27,8 @@ public interface PlaygroundClient {
// List<PlaygroundProfile> getPlaygroundMemberProfiles(@Param("memberId") Long playgroundId);

// headers 제외
@RequestLine("GET /internal/api/v1/members/profile?memberIds={encodedIds}")
List<PlaygroundProfile> getPlaygroundMemberProfiles(@Param(value = "encodedIds") String encodedIds);
@RequestLine("GET /internal/api/v1/members/profile")
List<PlaygroundProfile> getPlaygroundMemberProfiles(@QueryMap Map<String, Collection<String>> query);

// headers 제외, userId
@RequestLine("GET /internal/api/v1/members/profile/me?memberId={memberId}")
Expand Down
4 changes: 4 additions & 0 deletions src/main/java/org/sopt/app/application/user/UserInfo.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
package org.sopt.app.application.user;

public record UserInfo (Long userId){
}
10 changes: 10 additions & 0 deletions src/main/java/org/sopt/app/application/user/UserService.java
Original file line number Diff line number Diff line change
Expand Up @@ -96,4 +96,14 @@ public List<String> getIcons(IconType iconType) {
.map(Icons::getIconUrl)
.toList();
}

@Transactional
public UserInfo createUser(Long userId) {
User user = User.builder()
.id(userId)
.build();
User savedUser = userRepository.save(user);

return new UserInfo(savedUser.getId());
}
}
2 changes: 1 addition & 1 deletion src/main/java/org/sopt/app/common/response/ErrorCode.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ public enum ErrorCode {
INVALID_PLAYGROUND_CODE("유효하지 않은 플레이그라운드 OAuth 코드입니다.", HttpStatus.UNAUTHORIZED),
UNAUTHORIZED("권한이 없습니다", HttpStatus.UNAUTHORIZED),
TOKEN_EXPIRED("토큰이 만료되었습니다.", HttpStatus.UNAUTHORIZED),

INVALID_INTERNAL_API_KEY("유효하지 않은 내부 API key 입니다.", HttpStatus.UNAUTHORIZED),
// AUTH_CLIENT
RESPONSE_ERROR("외부 서버 응답 오류", HttpStatus.INTERNAL_SERVER_ERROR),
COMMUNICATION_ERROR("외부 서버 통신 실패", HttpStatus.INTERNAL_SERVER_ERROR),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ public class WebSecurityConfig {
"/api/v2/firebase/**",
"/api/v2/notification/**",
"/api/v2/user/main",
"/api/v2/user/register",
"/api/v2/home/app-service",
"/api/v2/home/floating-button",
"/api/v2/home/review-form"
Expand Down
8 changes: 8 additions & 0 deletions src/main/java/org/sopt/app/facade/UserFacade.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
import org.sopt.app.application.notification.NotificationService;
import org.sopt.app.application.app_service.AppServiceService;
import org.sopt.app.application.playground.dto.PlaygroundProfileInfo;
import org.sopt.app.application.user.UserInfo;
import org.sopt.app.application.user.UserService;
import org.sopt.app.domain.entity.User;
import org.sopt.app.presentation.user.UserResponse.*;
import org.sopt.app.presentation.user.UserResponseMapper;
Expand All @@ -25,6 +27,7 @@ public class UserFacade {
private final AppServiceService appServiceService;
private final UserResponseMapper userResponseMapper;
private final PlatformService platformService;
private final UserService userService;

@Transactional(readOnly = true)
public MainView getMainViewInfo(Long userId) {
Expand All @@ -50,4 +53,9 @@ public List<AppService> getAppServiceInfo() {
.map(AppService::of)
.toList();
}

@Transactional
public UserInfo createUser(Long requestUserId){
return userService.createUser(requestUserId);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,20 +5,23 @@
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.responses.ApiResponses;
import io.swagger.v3.oas.annotations.security.SecurityRequirement;
import java.util.List;
import lombok.RequiredArgsConstructor;
import lombok.val;

import org.sopt.app.application.platform.PlatformService;
import org.sopt.app.application.playground.PlaygroundAuthService;
import org.sopt.app.application.playground.dto.PlaygroundPostInfo.PlaygroundPost;
import org.sopt.app.application.playground.dto.PlaygroundProfileInfo;
import org.sopt.app.domain.entity.User;
import org.sopt.app.common.exception.UnauthorizedException;
import org.sopt.app.common.response.ErrorCode;
import org.sopt.app.facade.UserFacade;
import org.sopt.app.presentation.user.UserResponse.AppService;
import org.sopt.app.presentation.user.UserRequest.CreateUserRequest;
import org.sopt.app.presentation.user.UserResponse.Create;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.ResponseEntity;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

Expand Down Expand Up @@ -61,4 +64,25 @@ public ResponseEntity<UserResponse.Generation> getGenerationInfo(
userResponseMapper.ofGeneration(
platformService.getUserActiveInfo(userId)));
}

@Operation
@ApiResponses({
@ApiResponse(responseCode = "200", description = "success"),
@ApiResponse(responseCode = "401", description = "token error", content = @Content),
@ApiResponse(responseCode = "500", description = "server error", content = @Content)
})
@PostMapping("/register")
public ResponseEntity<Create> createDefaultUserProfile(
@RequestBody CreateUserRequest request,
@RequestHeader("apiKey") String apiKey,
@Value("${internal.auth.api-key}") String internalApiKey
){
if(!internalApiKey.equals(apiKey)){
throw new UnauthorizedException(ErrorCode.INVALID_INTERNAL_API_KEY);
}

return ResponseEntity.ok(
userResponseMapper.ofCreate(
userFacade.createUser(request.getUserId())));
}
}
9 changes: 9 additions & 0 deletions src/main/java/org/sopt/app/presentation/user/UserRequest.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,13 @@ public static class EditProfileMessageRequest {
@NotNull(message = "profileMessage may not be null")
private String profileMessage;
}

@Getter
@AllArgsConstructor(access = AccessLevel.PUBLIC)
@NoArgsConstructor(access = AccessLevel.PRIVATE)
public static class CreateUserRequest{
@Schema(description = "생성된 UserId", example = "101")
@NotNull(message = "userId may not be null")
private Long userId;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,12 @@
import java.util.stream.Collectors;

import lombok.AccessLevel;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.ToString;
import org.sopt.app.application.app_service.dto.AppServiceInfo;
import org.sopt.app.application.playground.dto.PlaygroundProfileInfo;
import org.sopt.app.application.playground.dto.PlaygroundProfileInfo.PlaygroundProfile;
import org.sopt.app.domain.enums.PlaygroundPart;

Expand Down Expand Up @@ -186,4 +186,11 @@ public static SoptLog of(int soptLevel, Long pokeCount, Long soptampRank, Long d
.build();
}
}

@Getter
@AllArgsConstructor
public static class Create {
@Schema(description = "생성된 유저 ID", example = "101")
private Long userId;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import org.mapstruct.*;
import org.sopt.app.application.playground.dto.PlaygroundProfileInfo;
import org.sopt.app.application.user.UserInfo;
import org.sopt.app.presentation.user.UserResponse.*;

@Mapper(
Expand All @@ -17,4 +18,6 @@ UserResponse.MainView ofMainView(PlaygroundProfileInfo.MainView user, UserRespon
UserResponse.ProfileMessage of(ProfileMessage profileMessage);

UserResponse.Generation ofGeneration(PlaygroundProfileInfo.UserActiveInfo userActiveInfo);

Create ofCreate(UserInfo userInfo);
}