Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

YEL-220 [deploy] 광고 보고 보상얻기 가능 여부 조회 #455

Merged
merged 8 commits into from
Feb 17, 2024
40 changes: 8 additions & 32 deletions src/docs/asciidoc/check-is-possible-admob.adoc
Original file line number Diff line number Diff line change
@@ -1,52 +1,28 @@
:reproducible:
== 상점에서 보상형 광고 가능한지 여부 (명세)
== 상점에서 보상형 광고 가능한지 여부

=== 요청

[http,json]
----
GET /api/v1/admob/{tag} HTTP/1.1
Authorization: Bearer your-access-token
Content-Type: application/json
----
include::{snippets}/api/v1/admob/possible/http-request.adoc[]

=== 요청 파라미터

include::{snippets}/api/v1/admob/possible/path-parameters.adoc[]

----
tag -> shop
tag -> ADMOB_POINT
----
* 보상형 광고 다른곳에서 사용할 수도 있으므로 tag로 어떤 곳에서 사용하고 있는곳인지 tag로 명시
* 현재는 상점 -> shop에서만 보상형 광고 진행
* 현재는 상점에 있는 보상형 광고 (ADMOB_POINT를 tag에 요청)

=== 응답

[http,json]
----
HTTP/1.1 200 OK
Vary: Origin
Vary: Access-Control-Request-Method
Vary: Access-Control-Request-Headers
Content-Type: application/json
{
"status" : 200,
"message" : "광고 보고 포인트 얻기 가능 여부 조회에 성공했습니다.",
"data": {
"createdAt": "2024-01-01 12:00:00",
"isPossible" : true,
}
}
----

include::{snippets}/api/v1/admob/possible/http-response.adoc[]

=== NOTE

- Header에 무작위한 UUID4 값을 넣어주세요
* 예시) IdempotencyKey: 0397b5f3-ecdc-47d6-b5d7-2b1afcf00e87
- 주의사항
* 같은 멱등성키를 2번 요청하면, 400번 에러.
- ADMOB
* ADMOB 서버에 SSV(ServerSideVerification) Options의 customData에 입력한 것과 동일한 멱등성 키를 넘겨주세요.

=== CHANGELOG

- 2024.02.17 API 릴리즈
- 2024.02.16 명세서 작성
2 changes: 1 addition & 1 deletion src/docs/asciidoc/index.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -118,4 +118,4 @@

* 🆕 link:reward-admob.html[광고보고 보상 얻기, 2024-02-11]

* 🆕 link:check-is-possible-admob.adoc[광고보고 보상 얻기 가능 여부 조회, 2024-02-16 (명세)]
* 🆕 link:check-is-possible-admob.adoc[광고보고 보상 얻기 가능 여부 조회, 2024-02-17]
Original file line number Diff line number Diff line change
@@ -1,20 +1,22 @@
package com.yello.server.domain.event.controller;

import static com.yello.server.global.common.ErrorCode.ADMOB_URI_BAD_REQUEST_EXCEPTION;
import static com.yello.server.global.common.ErrorCode.EMPTY_QUERY_STRING_EXCEPTION;
import static com.yello.server.global.common.SuccessCode.EVENT_JOIN_SUCCESS;
import static com.yello.server.global.common.SuccessCode.EVENT_NOTICE_SUCCESS;
import static com.yello.server.global.common.SuccessCode.EVENT_REWARD_SUCCESS;
import static com.yello.server.global.common.SuccessCode.GET_IS_POSSIBLE_ADMOB_SUCCESS;
import static com.yello.server.global.common.SuccessCode.REWARD_ADMOB_SUCCESS;
import static com.yello.server.global.common.SuccessCode.VERIFY_ADMOB_SSV_SUCCESS;
import static com.yello.server.global.common.util.ConstantUtil.IdempotencyKeyHeader;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ser.Serializers.Base;
import com.yello.server.domain.event.dto.request.AdmobRewardRequest;
import com.yello.server.domain.event.dto.request.EventJoinRequest;
import com.yello.server.domain.event.dto.response.EventResponse;
import com.yello.server.domain.event.dto.response.EventRewardResponse;
import com.yello.server.domain.event.dto.response.GetIsPossibleAdmob;
import com.yello.server.domain.event.exception.EventBadRequestException;
import com.yello.server.domain.event.exception.EventNotFoundException;
import com.yello.server.domain.event.service.EventService;
import com.yello.server.domain.user.entity.User;
import com.yello.server.global.common.annotation.AccessTokenUser;
Expand All @@ -30,6 +32,7 @@
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
Expand Down Expand Up @@ -71,6 +74,10 @@ public BaseResponse<EventRewardResponse> rewardEvent(@AccessTokenUser User user,
public ResponseEntity<?> verifyAdmob(HttpServletRequest request) {
URI uri;
System.out.println(request.getQueryString() + " alalalalalal");
if (request.getQueryString()==null) {
throw new EventNotFoundException(EMPTY_QUERY_STRING_EXCEPTION);
}

try {
uri =
new URI(request.getScheme(), null, request.getServerName(), request.getServerPort(),
Expand All @@ -85,8 +92,16 @@ public ResponseEntity<?> verifyAdmob(HttpServletRequest request) {
}

@PostMapping("/v1/admob/reward")
public BaseResponse<EventRewardResponse> rewardAdmob(@AccessTokenUser User user, @RequestBody AdmobRewardRequest request) {
public BaseResponse<EventRewardResponse> rewardAdmob(@AccessTokenUser User user,
@RequestBody AdmobRewardRequest request) {
val data = eventService.rewardAdmob(user.getId(), request);
return BaseResponse.success(REWARD_ADMOB_SUCCESS, data);
}

@GetMapping("/v1/admob/possible/{tag}")
public BaseResponse<GetIsPossibleAdmob> getIsPossibleAdmob(@AccessTokenUser User user,
@PathVariable("tag") String tag) {
val data = eventService.getIsPossibleAdmob(user.getId(), tag);
return BaseResponse.success(GET_IS_POSSIBLE_ADMOB_SUCCESS, data);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package com.yello.server.domain.event.dto.response;

import com.yello.server.domain.user.entity.UserData;
import com.yello.server.global.common.factory.TimeFactory;
import lombok.Builder;

@Builder
public record GetIsPossibleAdmob(
String createdAt,
Boolean isPossible
) {
public static GetIsPossibleAdmob of(UserData userAdmob) {
return GetIsPossibleAdmob.builder()
.createdAt(userAdmob.getValue())
.isPossible(userAdmob.isPossible())
.build();
}

}
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
package com.yello.server.domain.event.service;

import static com.yello.server.domain.user.entity.UserDataType.fromCode;
import static com.yello.server.global.common.ErrorCode.DUPLICATE_ADMOB_REWARD_EXCEPTION;
import static com.yello.server.global.common.ErrorCode.EVENT_COUNT_BAD_REQUEST_EXCEPTION;
import static com.yello.server.global.common.ErrorCode.EVENT_DATE_BAD_REQUEST_EXCEPTION;
import static com.yello.server.global.common.ErrorCode.EVENT_TIME_BAD_REQUEST_EXCEPTION;
import static com.yello.server.global.common.ErrorCode.IDEMPOTENCY_KEY_CONFLICT_EXCEPTION;
import static com.yello.server.global.common.ErrorCode.IDEMPOTENCY_KEY_NOT_FOUND_EXCEPTION;
import static com.yello.server.global.common.factory.TimeFactory.minusTime;
import static com.yello.server.global.common.factory.TimeFactory.toDateFormattedString;
import static com.yello.server.global.common.util.ConstantUtil.ADMOB_SHOP_TIME;
import static com.yello.server.global.common.util.ConstantUtil.GlobalZoneId;

import com.fasterxml.jackson.core.JsonProcessingException;
Expand All @@ -17,6 +21,7 @@
import com.yello.server.domain.event.dto.request.EventJoinRequest;
import com.yello.server.domain.event.dto.response.EventResponse;
import com.yello.server.domain.event.dto.response.EventRewardResponse;
import com.yello.server.domain.event.dto.response.GetIsPossibleAdmob;
import com.yello.server.domain.event.entity.Event;
import com.yello.server.domain.event.entity.EventHistory;
import com.yello.server.domain.event.entity.EventInstance;
Expand All @@ -33,13 +38,16 @@
import com.yello.server.domain.event.exception.EventNotFoundException;
import com.yello.server.domain.event.repository.EventRepository;
import com.yello.server.domain.user.entity.User;
import com.yello.server.domain.user.entity.UserData;
import com.yello.server.domain.user.repository.UserDataRepository;
import com.yello.server.domain.user.repository.UserRepository;
import com.yello.server.global.common.factory.UuidFactory;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.validation.constraints.NotEmpty;
import jakarta.validation.constraints.NotNull;
import java.net.URI;
import java.time.Duration;
import java.time.LocalDateTime;
import java.time.OffsetTime;
import java.time.ZonedDateTime;
import java.util.ArrayList;
Expand All @@ -61,6 +69,7 @@ public class EventService {
private final EventRepository eventRepository;
private final ObjectMapper objectMapper;
private final UserRepository userRepository;
private final UserDataRepository userDataRepository;

public List<EventResponse> getEvents(Long userId) throws JsonProcessingException {
// exception
Expand Down Expand Up @@ -290,9 +299,25 @@ public EventRewardResponse rewardAdmob(Long userId, AdmobRewardRequest request)
EventInstanceReward rewardInstance =
eventRepository.save(EventInstanceReward.of(eventInstance, eventReward));

// user-data cooldown 추가
UserData userAdmob =
userDataRepository.findByUserIdAndTag(userId, fromCode(request.rewardType()))
.orElseGet(() -> userDataRepository.save(UserData.of(fromCode(request.rewardType()),
toDateFormattedString(LocalDateTime.now()), user)));

userAdmob.setValue(toDateFormattedString(LocalDateTime.now()));

return EventRewardResponse.of(rewardInstance);
}

public GetIsPossibleAdmob getIsPossibleAdmob(Long userId, String tag) {
final User user = userRepository.getById(userId);
UserData userAdmob = userDataRepository.findByUserIdAndTag(userId, fromCode(tag))
.orElse(UserData.of(fromCode(tag),
toDateFormattedString(minusTime(LocalDateTime.now(), ADMOB_SHOP_TIME)), user));
return GetIsPossibleAdmob.of(userAdmob);
}

private EventReward handleRewardByType(AdmobRewardRequest request, User user) {
switch (RewardType.fromCode(request.rewardType())) {
case ADMOB_POINT -> {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,16 +1,7 @@
package com.yello.server.domain.friend.service;

import static com.yello.server.global.common.ErrorCode.EXIST_FRIEND_EXCEPTION;
import static com.yello.server.global.common.util.ConstantUtil.YELLO_FEMALE;
import static com.yello.server.global.common.util.ConstantUtil.YELLO_MALE;

import com.yello.server.domain.friend.dto.request.KakaoRecommendRequest;
import com.yello.server.domain.friend.dto.response.FriendResponse;
import com.yello.server.domain.friend.dto.response.FriendShuffleResponse;
import com.yello.server.domain.friend.dto.response.FriendsResponse;
import com.yello.server.domain.friend.dto.response.RecommendFriendResponse;
import com.yello.server.domain.friend.dto.response.SearchFriendResponse;
import com.yello.server.domain.friend.dto.response.SearchFriendVO;
import com.yello.server.domain.friend.dto.response.*;
import com.yello.server.domain.friend.entity.Friend;
import com.yello.server.domain.friend.exception.FriendException;
import com.yello.server.domain.friend.repository.FriendRepository;
Expand All @@ -20,19 +11,20 @@
import com.yello.server.domain.vote.repository.VoteRepository;
import com.yello.server.domain.vote.service.VoteManager;
import com.yello.server.global.common.factory.PaginationFactory;
import java.lang.Character.UnicodeBlock;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Optional;
import lombok.Builder;
import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.lang.Character.UnicodeBlock;
import java.util.*;

import static com.yello.server.global.common.ErrorCode.EXIST_FRIEND_EXCEPTION;
import static com.yello.server.global.common.util.ConstantUtil.YELLO_FEMALE;
import static com.yello.server.global.common.util.ConstantUtil.YELLO_MALE;

@Service
@Builder
@RequiredArgsConstructor
Expand All @@ -47,13 +39,13 @@ public class FriendService {
public FriendsResponse findAllFriends(Pageable pageable, Long userId) {
final Page<Friend> friendsData = friendRepository.findAllFriendsByUserId(pageable, userId);
List<UserResponse> friends = friendsData.stream()
.map(friend -> {
User targetUser = friend.getTarget();
Integer friendCount = friendRepository.countAllByUserId(targetUser.getId());
Integer yelloCount = voteRepository.countAllByReceiverUserId(targetUser.getId());
return UserResponse.of(targetUser, yelloCount, friendCount);
})
.toList();
.map(friend -> {
User targetUser = friend.getTarget();
Integer friendCount = friendRepository.countAllByUserId(targetUser.getId());
Integer yelloCount = voteRepository.countAllByReceiverUserId(targetUser.getId());
return UserResponse.of(targetUser, yelloCount, friendCount);
})
.toList();

return FriendsResponse.of(friendsData.getTotalElements(), friends);
}
Expand Down Expand Up @@ -85,10 +77,10 @@ public RecommendFriendResponse findAllRecommendSchoolFriends(Pageable pageable,

Integer size = userRepository.countAllByGroupNameFilteredByNotFriend(userId, user.getGroup().getGroupName());
List<FriendResponse> recommendFriends =
userRepository.findAllByGroupNameFilteredByNotFriend(userId, user.getGroup().getGroupName(), pageable)
.stream()
.map(FriendResponse::of)
.toList();
userRepository.findAllByGroupNameFilteredByNotFriend(userId, user.getGroup().getGroupName(), pageable)
.stream()
.map(FriendResponse::of)
.toList();

return RecommendFriendResponse.of(size, recommendFriends);
}
Expand All @@ -106,25 +98,25 @@ public void deleteFriend(Long userId, Long targetId) {
}

public RecommendFriendResponse findAllRecommendKakaoFriends(Pageable pageable, Long userId,
KakaoRecommendRequest request) {
KakaoRecommendRequest request) {
final User user = userRepository.getById(userId);

List<User> kakaoFriends = Arrays.stream(request.friendKakaoId())
.filter(userRepository::existsByUuid)
.map(userRepository::getByUuid)
.filter(friend -> !friendRepository.existsByUserAndTarget(user.getId(), friend.getId()))
.toList();
.filter(userRepository::existsByUuid)
.map(userRepository::getByUuid)
.filter(friend -> !friendRepository.existsByUserAndTarget(user.getId(), friend.getId()))
.toList();

List<FriendResponse> pageList = PaginationFactory.getPage(kakaoFriends, pageable)
.stream()
.map(FriendResponse::of)
.toList();
.stream()
.map(FriendResponse::of)
.toList();

return RecommendFriendResponse.of(kakaoFriends.size(), pageList);
}

public SearchFriendResponse searchFriend(Long userId, Pageable pageable,
String keyword) {
String keyword) {
final User user = userRepository.getById(userId);
final String groupName = user.getGroup().getGroupName();
List<String> uuidList = Arrays.asList(YELLO_FEMALE, YELLO_MALE);
Expand All @@ -137,23 +129,23 @@ public SearchFriendResponse searchFriend(Long userId, Pageable pageable,

if (!isEnglish(keyword)) {
friendList.addAll(
userRepository.findAllByGroupContainingName(groupName, keyword, uuidList));
userRepository.findAllByGroupContainingName(groupName, keyword, uuidList));
friendList.addAll(
userRepository.findAllByOtherGroupContainingName(groupName, keyword, uuidList));

userRepository.findAllByOtherGroupContainingName(groupName, keyword, uuidList));
friendList.addAll(userRepository.findAllByGroupNameContainingAndFriendListNotContaining(keyword, uuidList, friendList));
} else {
friendList.addAll(
userRepository.findAllByGroupContainingYelloId(groupName, keyword, uuidList));
userRepository.findAllByGroupContainingYelloId(groupName, keyword, uuidList));
friendList.addAll(
userRepository.findAllByOtherGroupContainingYelloId(groupName, keyword, uuidList));
userRepository.findAllByOtherGroupContainingYelloId(groupName, keyword, uuidList));
}

List<SearchFriendVO> pageList = PaginationFactory.getPage(friendList, pageable)
.stream()
.filter(friend -> !userId.equals(friend.getId()))
.map(friend -> SearchFriendVO.of(friend,
friendRepository.existsByUserAndTarget(userId, friend.getId())))
.toList();
.stream()
.filter(friend -> !userId.equals(friend.getId()))
.map(friend -> SearchFriendVO.of(friend,
friendRepository.existsByUserAndTarget(userId, friend.getId())))
.toList();

return SearchFriendResponse.of(friendList.size(), pageList);
}
Expand Down
Loading
Loading