Skip to content

Commit

Permalink
Feat: 약관 동의 API 추가
Browse files Browse the repository at this point in the history
  • Loading branch information
wnsvy607 committed Sep 9, 2024
1 parent 49ac158 commit e210157
Show file tree
Hide file tree
Showing 13 changed files with 161 additions and 1 deletion.
17 changes: 16 additions & 1 deletion src/main/java/com/join/core/auth/controller/TermController.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,12 @@
import org.springframework.security.access.prepost.PreAuthorize;
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.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.join.core.auth.domain.TermCommand;
import com.join.core.auth.domain.TermInfo;
import com.join.core.auth.domain.UserPrincipal;
import com.join.core.auth.service.TermService;
Expand All @@ -31,8 +34,20 @@ public class TermController {
security = {@SecurityRequirement(name = "session-token")})
@PreAuthorize("isAuthenticated()")
@GetMapping("/terms")
public ApiResponse<List<TermInfo.Main>> get(@AuthenticationPrincipal UserPrincipal principal) {
public ApiResponse<List<TermInfo.Main>> getRequiredConsentTerms(@AuthenticationPrincipal UserPrincipal principal) {
return ApiResponse.ok(termService.getRequiredConsentTerms(principal.getUserId()));
}

@Tag(name = "${swagger.tag.sign-up}")
@Operation(summary = "약관 동의 API - 인증 필요",
description = "약관 동의 API - 받은 약관에 동의 || 비동의 이력을 남기는 API입니다.",
security = {@SecurityRequirement(name = "session-token")})
@PreAuthorize("isAuthenticated()")
@PostMapping("/terms/agree")
public ApiResponse<Void> agreeTerms(@AuthenticationPrincipal UserPrincipal principal,
@RequestBody TermCommand.Agree command) {
termService.agreeTerm(principal.getUserId(), command);
return ApiResponse.ok();
}

}
7 changes: 7 additions & 0 deletions src/main/java/com/join/core/auth/domain/Term.java
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import lombok.AccessLevel;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.RequiredArgsConstructor;
Expand All @@ -27,6 +28,7 @@ public class Term extends BaseTimeEntity {

@Getter
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@EqualsAndHashCode
@Embeddable
public static class Key implements Serializable {
@NotNull
Expand All @@ -35,6 +37,11 @@ public static class Key implements Serializable {
@NotNull
@NotBlank
private String version;

public Key(Long id, String version) {
this.id = id;
this.version = version;
}
}

// 약관 종류
Expand Down
7 changes: 7 additions & 0 deletions src/main/java/com/join/core/auth/domain/TermAgreeHistory.java
Original file line number Diff line number Diff line change
Expand Up @@ -53,4 +53,11 @@ public enum AcceptStatus {
@NotNull
private LocalDateTime agreeDate;

TermAgreeHistory(User user, Term term, AcceptStatus status) {
this.user = user;
this.term = term;
this.status = status;
this.agreeDate = LocalDateTime.now();
}

}
32 changes: 32 additions & 0 deletions src/main/java/com/join/core/auth/domain/TermCommand.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package com.join.core.auth.domain;

import java.util.List;

import lombok.Builder;
import lombok.Getter;

public class TermCommand {

private TermCommand() {
}

@Builder
@Getter
public static class Agree {
private final List<AgreeTerm> terms;
}

@Builder
@Getter
public static class AgreeTerm {
private final Long id;
private final String version;
private final TermAgreeHistory.AcceptStatus status;

public Term.Key toKey() {
return new Term.Key(id, version);
}

}

}
11 changes: 11 additions & 0 deletions src/main/java/com/join/core/auth/domain/User.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import java.util.Set;
import java.util.stream.Collectors;

import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.security.core.authority.SimpleGrantedAuthority;

Expand Down Expand Up @@ -75,6 +76,10 @@ public enum Status {
@OneToMany(mappedBy = "user", cascade = CascadeType.ALL, orphanRemoval = true)
private List<UserRole> userRoles = new ArrayList<>();

@OneToMany(mappedBy = "user", cascade = CascadeType.PERSIST, orphanRemoval = true)
private List<TermAgreeHistory> termAgreeHistoryList = new ArrayList<>();


public boolean isUserOf(UserType providerType) {
return providerType.equals(this.platform);
}
Expand All @@ -100,4 +105,10 @@ public Set<SimpleGrantedAuthority> getAuthorities() {
return this.userRoles.stream().map(UserRole::getAuthority).collect(Collectors.toUnmodifiableSet());
}

public void agree(Term term, TermAgreeHistory.AcceptStatus status) {
if(ObjectUtils.isEmpty(term))
throw new InvalidParamException(INVALID_PARAMETER, "agree.term");
this.termAgreeHistoryList.add(new TermAgreeHistory(this, term, status));
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package com.join.core.auth.repository;

import java.util.List;

import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import com.join.core.auth.domain.Term;
import com.join.core.auth.domain.TermCommand;
import com.join.core.auth.domain.User;
import com.join.core.auth.service.TermAgreeHistoryStore;
import com.join.core.auth.service.TermReader;
import com.join.core.common.exception.ErrorCode;
import com.join.core.common.exception.impl.TermAgreeException;

import lombok.RequiredArgsConstructor;

@RequiredArgsConstructor
@Component
public class TermAgreeHistoryStoreImpl implements TermAgreeHistoryStore {

private final TermReader termReader;

@Transactional
@Override
public void store(User user, TermCommand.Agree agree) {
List<Term.Key> keys = agree.getTerms().stream().map(TermCommand.AgreeTerm::toKey).toList();
List<Term> terms = termReader.getTerms(keys);
terms.forEach(t -> {
Term.Key key = t.getKey();
TermCommand.AgreeTerm agreeTerm = agree.getTerms().stream().filter(at -> at.toKey().equals(key)).findFirst()
.orElseThrow(() -> new TermAgreeException(ErrorCode.TERM_NOT_EXIST));
user.agree(t, agreeTerm.getStatus());
});

}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.join.core.auth.repository;

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

import org.springframework.stereotype.Component;
Expand All @@ -25,4 +26,10 @@ public List<TermInfo.Main> getRequiredConsentTerms(Long userId) {
List<Term> terms = termRepository.findRequiredConsentWith(userId);
return terms.stream().map(termInfoMapper::of).toList();
}

@Override
public List<Term> getTerms(Collection<Term.Key> keys) {
return termRepository.findAllById(keys);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package com.join.core.auth.service;

import com.join.core.auth.domain.TermCommand;
import com.join.core.auth.domain.User;

public interface TermAgreeHistoryStore {

void store(User user, TermCommand.Agree agree);

}
4 changes: 4 additions & 0 deletions src/main/java/com/join/core/auth/service/TermReader.java
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
package com.join.core.auth.service;

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

import com.join.core.auth.domain.Term;
import com.join.core.auth.domain.TermInfo;

public interface TermReader {

List<TermInfo.Main> getRequiredConsentTerms(Long userId);

List<Term> getTerms(Collection<Term.Key> keys);

}
10 changes: 10 additions & 0 deletions src/main/java/com/join/core/auth/service/TermService.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.join.core.auth.domain.TermCommand;
import com.join.core.auth.domain.TermInfo;
import com.join.core.auth.domain.User;

import lombok.RequiredArgsConstructor;

Expand All @@ -15,9 +17,17 @@
public class TermService {

private final TermReader termReader;
private final TermAgreeHistoryStore termAgreeHistoryStore;
private final UserReader userReader;

public List<TermInfo.Main> getRequiredConsentTerms(Long userId) {
return termReader.getRequiredConsentTerms(userId);
}

@Transactional
public void agreeTerm(Long userId, TermCommand.Agree command) {
User user = userReader.getUser(userId);
termAgreeHistoryStore.store(user, command);
}

}
3 changes: 3 additions & 0 deletions src/main/java/com/join/core/auth/service/UserReader.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.join.core.auth.service;

import com.join.core.auth.domain.Role;
import com.join.core.auth.domain.User;
import com.join.core.auth.domain.UserInfo;

public interface UserReader {
Expand All @@ -11,4 +12,6 @@ public interface UserReader {

Role getUserRole();

User getUser(Long userId);

}
5 changes: 5 additions & 0 deletions src/main/java/com/join/core/common/exception/ErrorCode.java
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,11 @@ public enum ErrorCode {
IMAGE_FILE_IS_NULL(HttpStatus.BAD_REQUEST, "F-005", "요청된 파일이 null입니다."),
IMAGE_EXTENSION_IS_NOT_ALLOWED(HttpStatus.BAD_REQUEST, "F-006", "요청된 파일의 확장자는 지원되지 않습니다."),

/**
* 약관 관련 오류
*/
TERM_NOT_EXIST(HttpStatus.BAD_REQUEST, "T-001", "요청된 약관은 존재하지 않습니다."),

/**
* 주소 선택 관련 오류
*/
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package com.join.core.common.exception.impl;

import com.join.core.common.exception.ErrorCode;
import com.join.core.common.exception.GeneralException;

public class TermAgreeException extends GeneralException {

public TermAgreeException(ErrorCode errorCode) {
super(errorCode);
}

}

0 comments on commit e210157

Please sign in to comment.