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
@@ -0,0 +1,51 @@
package umc.th.juinjang.api.termsAgreement.controller;

import org.springframework.security.core.annotation.AuthenticationPrincipal;
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;
import org.springframework.web.bind.annotation.RestController;

import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import lombok.RequiredArgsConstructor;
import umc.th.juinjang.api.dto.ApiResponse;
import umc.th.juinjang.api.termsAgreement.controller.request.AgreeRequest;
import umc.th.juinjang.api.termsAgreement.controller.response.AgreeResponse;
import umc.th.juinjang.api.termsAgreement.controller.response.StatusResponse;
import umc.th.juinjang.api.termsAgreement.service.TermsAgreementService;
import umc.th.juinjang.domain.member.model.Member;
import umc.th.juinjang.domain.termsAgreement.repository.TermsType;

@RestController
@RequestMapping("/api/v2/terms-agreement")
@RequiredArgsConstructor
public class TermsAgreementController {

private final TermsAgreementService termsAgreementService;

@Operation(summary = "특정 약관 동의 여부 확인",
description = "로그인한 멤버가 특정 약관에 동의했는지 확인합니다.")
@GetMapping("/{termsType}")
public ApiResponse<StatusResponse> checkStatus(
@AuthenticationPrincipal Member member,
@Parameter(description = "확인할 약관 타입")
@PathVariable TermsType termsType) {
boolean isAgreed = termsAgreementService.checkStatus(member.getMemberId(), termsType);
return ApiResponse.onSuccess(StatusResponse.of(isAgreed));
}

@Operation(summary = "특정 약관에 동의 하기",
description = "해당 멤버가 특정 약관에 동의합니다.")
@PostMapping
public ApiResponse<AgreeResponse> agreeToSpecificTerms(
@AuthenticationPrincipal Member member,
@RequestBody AgreeRequest request
) {
termsAgreementService.agreeToSpecificTerms(member.getMemberId(), request.termsType());
return ApiResponse.onSuccess(AgreeResponse.from(request.termsType(), true));
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package umc.th.juinjang.api.termsAgreement.controller.request;

import umc.th.juinjang.domain.termsAgreement.repository.TermsType;

public record AgreeRequest(
TermsType termsType
) {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package umc.th.juinjang.api.termsAgreement.controller.response;

import umc.th.juinjang.domain.termsAgreement.repository.TermsType;

public record AgreeResponse(
TermsType termsType,
boolean isAgreed
) {
public static AgreeResponse from(TermsType termsType, boolean isAgreed) {
return new AgreeResponse(
termsType,
isAgreed
);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package umc.th.juinjang.api.termsAgreement.controller.response;

public record StatusResponse(
boolean status
) {
public static StatusResponse of(boolean isAgreed) {
return new StatusResponse(isAgreed);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package umc.th.juinjang.api.termsAgreement.service;

import static umc.th.juinjang.common.code.status.ErrorStatus.*;

import java.util.Optional;

import org.springframework.stereotype.Service;

import lombok.RequiredArgsConstructor;
import umc.th.juinjang.common.exception.handler.MemberHandler;
import umc.th.juinjang.domain.termsAgreement.repository.TermsAgreement;
import umc.th.juinjang.domain.termsAgreement.repository.TermsAgreementRepository;
import umc.th.juinjang.domain.termsAgreement.repository.TermsType;

@Service
@RequiredArgsConstructor
public class TermsAgreementService {

private final TermsAgreementRepository termsAgreementRepository;

public boolean checkStatus(Long memberId, TermsType termsType) {
return termsAgreementRepository.findByMemberIdAndTermsType(memberId, termsType)
.isPresent();
}

public void agreeToSpecificTerms(Long memberId, TermsType termsType) {
Optional<TermsAgreement> existingAgreement =
termsAgreementRepository.findByMemberIdAndTermsType(memberId, termsType);

if (existingAgreement.isPresent()) {
throw new MemberHandler(TERMS_AGREEMENT_DUPLICATED);
}

TermsAgreement agreement = TermsAgreement.create(memberId, termsType);
termsAgreementRepository.save(agreement);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -119,8 +119,11 @@ public enum ErrorStatus implements BaseErrorCode {

// LikedNote
LIKEDNOTE_CONFLICT(HttpStatus.CONFLICT, "LIKEDNOTE4000", "이미 좋아요한 노트입니다"),
LIKEDNOTE_NOT_FOUND(HttpStatus.NOT_FOUND, "LIKEDNOTE4001", "이미 취소했거나 좋아요한 적이 없습니다.");
LIKEDNOTE_NOT_FOUND(HttpStatus.NOT_FOUND, "LIKEDNOTE4001", "이미 취소했거나 좋아요한 적이 없습니다."),

// Terms_Agreement
TERMS_AGREEMENT_DUPLICATED(HttpStatus.BAD_REQUEST, "TERMS_AGREEMENT_4000", "이미 약관에 동의하였습니다.");

private final HttpStatus httpStatus;
private final String code;
private final String message;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package umc.th.juinjang.domain.termsAgreement.repository;

import java.time.LocalDateTime;

import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.EnumType;
import jakarta.persistence.Enumerated;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import lombok.AccessLevel;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;

@Entity
@Getter
@Builder
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@AllArgsConstructor
public class TermsAgreement {

@Id
@Column(name = "terms_agreement_id")
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;

private Long memberId;

@Enumerated(EnumType.STRING)
private TermsType termsType;

private LocalDateTime agreedAt;

public static TermsAgreement create(Long memberId, TermsType termsType) {
return TermsAgreement.builder()
.memberId(memberId)
.termsType(termsType)
.agreedAt(LocalDateTime.now())
.build();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package umc.th.juinjang.domain.termsAgreement.repository;

import java.util.Optional;

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

@Repository
public interface TermsAgreementRepository extends JpaRepository<TermsAgreement, Long> {
// 멤버가 특정 약관에 동의 했는 여부를 체크하는 메서드
Optional<TermsAgreement> findByMemberIdAndTermsType(Long memberId, TermsType termsType);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package umc.th.juinjang.domain.termsAgreement.repository;

import lombok.AllArgsConstructor;

@AllArgsConstructor
public enum TermsType {
PENCIL_SHOP_SERVICE("연필상점 이용약관");

private final String text;
}