Skip to content

Commit c4cf1ff

Browse files
authored
Merge pull request #32 from 508PERFACT/feature/31-guest-login
Feat : 게스트 로그인 기능 추가 및 GUEST 플랜 추가
2 parents accc19c + 4a942e0 commit c4cf1ff

File tree

11 files changed

+97
-19
lines changed

11 files changed

+97
-19
lines changed

src/main/java/com/perfact/be/domain/auth/controller/AuthController.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,18 @@ public ApiResponse<AuthResponseDto.LoginResponse> socialLogin(
4848
return ApiResponse.of(AuthSuccessStatus.SOCIAL_LOGIN_SUCCESS, response);
4949
}
5050

51+
@Operation(
52+
summary = "게스트 로그인",
53+
description = "UUID 기반 게스트 계정을 생성하고 엑세스/리프레시 토큰을 발급합니다."
54+
)
55+
@PostMapping(value = "/guest-login", produces = "application/json")
56+
public ApiResponse<AuthResponseDto.LoginResponse> guestLogin(
57+
) {
58+
AuthResponseDto.LoginResponse response = authService.guestLogin();
59+
return ApiResponse.of(AuthSuccessStatus.GUEST_LOGIN_SUCCESS, response);
60+
}
61+
62+
5163
@Operation(
5264
summary = "엑세스 토큰 재발급",
5365
description = "리프레시 토큰을 이용해 엑세스 토큰을 재발급합니다."

src/main/java/com/perfact/be/domain/auth/exception/status/AuthSuccessStatus.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,10 @@ public enum AuthSuccessStatus implements BaseCode {
1313
SOCIAL_LOGIN_SUCCESS(HttpStatus.OK, "AUTH2001", "소셜 로그인이 완료되었습니다."),
1414
DEV_TOKEN_ISSUED(HttpStatus.OK, "AUTH2002", "개발용 액세스 토큰 발급이 완료되었습니다."),
1515
LOGOUT_SUCCESS(HttpStatus.OK, "AUTH2003", "로그아웃이 완료되었습니다."),
16-
AT_REFRESH_SUCCESS(HttpStatus.OK, "AUTH2004", "엑세스 토큰 재생성이 완료되었습니다.");
16+
AT_REFRESH_SUCCESS(HttpStatus.OK, "AUTH2004", "엑세스 토큰 재생성이 완료되었습니다."),
17+
GUEST_LOGIN_SUCCESS(HttpStatus.OK, "AUTH2005", "게스트 로그인이 완료되었습니다."),
18+
19+
;
1720

1821
private final HttpStatus httpStatus;
1922
private final String code;

src/main/java/com/perfact/be/domain/auth/service/AuthService.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package com.perfact.be.domain.auth.service;
22

33
import com.perfact.be.domain.auth.dto.AuthResponseDto;
4+
import com.perfact.be.domain.auth.dto.AuthResponseDto.LoginResponse;
45
import com.perfact.be.domain.auth.dto.AuthResponseDto.TokenResponse;
56
import com.perfact.be.domain.user.entity.User;
67
import jakarta.validation.constraints.NotNull;
@@ -12,4 +13,6 @@ public interface AuthService {
1213
TokenResponse refreshAccessToken(User loginUser, String refreshToken);
1314

1415
void logout(User loginUser, String refreshToken);
16+
17+
AuthResponseDto.LoginResponse guestLogin();
1518
}

src/main/java/com/perfact/be/domain/auth/service/AuthServiceImpl.java

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package com.perfact.be.domain.auth.service;
22

33
import com.perfact.be.domain.auth.dto.AuthResponseDto;
4+
import com.perfact.be.domain.auth.dto.AuthResponseDto.LoginResponse;
45
import com.perfact.be.domain.auth.dto.AuthResponseDto.TokenResponse;
56
import com.perfact.be.domain.auth.dto.NaverTokenResponse;
67
import com.perfact.be.domain.auth.dto.NaverUserInfoResponse;
@@ -85,6 +86,21 @@ public void logout(User loginUser, String refreshToken) {
8586
redisTemplate.delete(redisKey);
8687
}
8788

89+
@Override
90+
public LoginResponse guestLogin() {
91+
String deviceUuid = UUID.randomUUID().toString();
92+
User guestUser = userService.createGuestUser(deviceUuid);
93+
94+
String accessToken = jwtProvider.generateAccessToken(guestUser.getId(), deviceUuid);
95+
96+
String rtUuid = UUID.randomUUID().toString();
97+
String refreshToken = jwtProvider.generateRefreshToken(guestUser.getId(), deviceUuid, rtUuid);
98+
99+
String redisKey = "RT:" + deviceUuid + ":" + rtUuid;
100+
redisTemplate.opsForValue().set(redisKey, refreshToken, 3, TimeUnit.HOURS);
101+
return new AuthResponseDto.LoginResponse(guestUser.getId(), guestUser.getEmail(), accessToken, refreshToken);
102+
}
103+
88104

89105
private String getAccessToken(String code, String state) {
90106
NaverTokenResponse tokenResponse = webClient
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
package com.perfact.be.domain.credit.entity.enums;
22

33
public enum PlanType {
4-
FREE, STANDARD, PREMIUM
4+
FREE, STANDARD, PREMIUM, GUEST
55
}

src/main/java/com/perfact/be/domain/user/entity/User.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,15 +27,14 @@ public class User extends BaseEntity {
2727
private String socialId;
2828
@Enumerated(EnumType.STRING)
2929
private SocialType socialType;
30-
@Column(name = "nickname", length = 10)
30+
@Column(name = "nickname", length = 20)
3131
private String nickname;
3232
@Column(name = "email", length = 255)
3333
private String email;
3434
@Enumerated(EnumType.STRING)
3535
@Column(length = 20)
3636
private Role role;
3737
@Enumerated(EnumType.STRING)
38-
3938
@Builder.Default
4039
@Column(length = 20, nullable = false)
4140
private UserStatus status = UserStatus.ACTIVE;
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
package com.perfact.be.domain.user.entity.enums;
22

33
public enum Role {
4-
ROLE_USER, ROLE_ADMIN
4+
ROLE_USER, ROLE_ADMIN, ROLE_GUEST;
55
}
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
package com.perfact.be.domain.user.entity.enums;
22

33
public enum SocialType {
4-
NAVER, KAKAO
4+
NAVER, KAKAO, GUEST
55
}

src/main/java/com/perfact/be/domain/user/service/UserService.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,4 +16,6 @@ public interface UserService {
1616
void decreaseCredit(User user, int cost);
1717

1818
NicknameResponse getNickname(User loginUser);
19+
20+
User createGuestUser(String deviceUuid);
1921
}

src/main/java/com/perfact/be/domain/user/service/UserServiceImpl.java

Lines changed: 55 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -57,10 +57,23 @@ public SubscribeStatusResponse getSubscribeStatus(User loginUser) {
5757

5858
String planName = plan != null ? plan.getName().toString() : "UNKNOWN";
5959
boolean isFreePlan = "FREE".equals(planName);
60-
String subscribeStatus = isFreePlan ? "무료 플랜 사용 중" : "유료 플랜 사용 중";
61-
String nextBillingDate = isFreePlan ? "무료 플랜 사용 중" : "미정";
60+
boolean isGuestPlan = "GUEST".equals(planName);
61+
62+
String subscribeStatus;
63+
String nextBillingDate;
6264
Long dailyCredit = plan != null ? plan.getDailyCredit() : 0L;
6365

66+
if (isGuestPlan) {
67+
subscribeStatus = "게스트 모드 사용 중";
68+
nextBillingDate = "게스트 모드는 결제/갱신 없음";
69+
} else if (isFreePlan) {
70+
subscribeStatus = "무료 플랜 사용 중";
71+
nextBillingDate = "무료 플랜 사용 중";
72+
} else {
73+
subscribeStatus = "유료 플랜 사용 중";
74+
nextBillingDate = "미정"; // TODO : 유료 결제 로직 붙으면 수정
75+
}
76+
6477
LocalDateTime startOfToday = LocalDate.now().atStartOfDay();
6578
LocalDateTime startOfTomorrow = startOfToday.plusDays(1);
6679

@@ -70,35 +83,64 @@ public SubscribeStatusResponse getSubscribeStatus(User loginUser) {
7083

7184
// 오늘 사용량
7285
Long todayUsage = Optional.ofNullable(
73-
creditLogRepository.sumUsedCreditByUserAndTypeAndCreatedAtBetween(
74-
loginUser,
75-
CreditLogType.REPORT_CREATE,
76-
startOfToday,
77-
startOfTomorrow))
86+
creditLogRepository.sumUsedCreditByUserAndTypeAndCreatedAtBetween(
87+
loginUser,
88+
CreditLogType.REPORT_CREATE,
89+
startOfToday,
90+
startOfTomorrow))
7891
.map(Math::abs).orElse(0L);
7992

8093
// 이번 달 사용량
8194
Long thisMonthUsage = Optional.ofNullable(
82-
creditLogRepository.sumUsedCreditByUserAndTypeAndCreatedAtBetween(
83-
loginUser,
84-
CreditLogType.REPORT_CREATE,
85-
startOfMonth,
86-
startOfNextMonth))
95+
creditLogRepository.sumUsedCreditByUserAndTypeAndCreatedAtBetween(
96+
loginUser,
97+
CreditLogType.REPORT_CREATE,
98+
startOfMonth,
99+
startOfNextMonth))
87100
.map(Math::abs).orElse(0L);
88101
return new SubscribeStatusResponse(
89102
planName,
90103
subscribeStatus,
91104
nextBillingDate,
92105
dailyCredit,
93106
todayUsage,
94-
thisMonthUsage);
107+
thisMonthUsage
108+
);
95109
}
96110

97111
@Override
98112
public NicknameResponse getNickname(User loginUser) {
99113
return new NicknameResponse(loginUser.getNickname());
100114
}
101115

116+
@Override
117+
@Transactional
118+
public User createGuestUser(String deviceUuid) {
119+
return userRepository.findBySocialIdAndSocialType(deviceUuid, SocialType.GUEST)
120+
.orElseGet(() -> {
121+
// 테스트로 지정하기
122+
SubscriptionPlans testPlan = subscriptionPlansRepository.findByName(PlanType.GUEST)
123+
.orElseThrow(() -> new UserHandler(UserErrorStatus.PLAN_NOT_FOUND));
124+
125+
String nick = "게스트-" + deviceUuid.substring(0, 8);
126+
127+
User newGuest = User.builder()
128+
.email(null) // 게스트는 이메일 없음.. 기획 보고 나중에 수정해야 될 수도 있음.
129+
.nickname(nick)
130+
.socialId(deviceUuid)
131+
.socialType(SocialType.GUEST)
132+
.role(Role.ROLE_GUEST)
133+
.status(UserStatus.ACTIVE)
134+
.plan(testPlan)
135+
.isSubscribe(false)
136+
.isNotificationAgreed(false)
137+
.build();
138+
139+
return userRepository.save(newGuest);
140+
});
141+
}
142+
143+
102144
@Override
103145
@Transactional
104146
public void decreaseCredit(User user, int amount) {

0 commit comments

Comments
 (0)