Skip to content

Commit d5b7b0f

Browse files
authored
Merge pull request #36 from kusitms-com/feat/학회-모집-이메일-저장-구현
pr feat : 모집 이메일 전송 이메일 저장 API 구현
2 parents 2ff7476 + ae8c111 commit d5b7b0f

7 files changed

Lines changed: 158 additions & 4 deletions

File tree

src/main/java/com/kusitms/website/domain/blog/service/BlogService.java

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,14 @@
11
package com.kusitms.website.domain.blog.service;
22

33
import com.kusitms.website.domain.blog.dto.response.BlogResponse;
4-
import com.kusitms.website.domain.blog.entity.BlogPost;
54
import com.kusitms.website.domain.blog.entity.Category;
65
import com.kusitms.website.domain.blog.entity.Position;
7-
import com.kusitms.website.domain.blog.repository.BlogPostQueryRepository;
86
import com.kusitms.website.domain.blog.repository.BlogPostRepository;
97
import lombok.RequiredArgsConstructor;
108
import org.springframework.data.domain.Page;
119
import org.springframework.data.domain.Pageable;
1210
import org.springframework.stereotype.Service;
1311

14-
import java.util.List;
15-
import java.util.stream.Collectors;
1612

1713
@Service
1814
@RequiredArgsConstructor
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
package com.kusitms.website.domain.email;
2+
3+
import lombok.AllArgsConstructor;
4+
import lombok.Builder;
5+
import lombok.Getter;
6+
import lombok.NoArgsConstructor;
7+
8+
import javax.persistence.*;
9+
10+
@Entity
11+
@Getter
12+
@Builder
13+
@NoArgsConstructor
14+
@AllArgsConstructor
15+
public class Email {
16+
@Id @GeneratedValue(strategy = GenerationType.IDENTITY)
17+
@Column(name = "email_id", nullable = false)
18+
private Long id;
19+
20+
@Column(nullable = false, unique = true)
21+
private String email;
22+
}
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
package com.kusitms.website.domain.email.controller;
2+
3+
import com.kusitms.website.domain.email.dto.response.EmailResponse;
4+
import com.kusitms.website.domain.email.service.EmailService;
5+
import com.kusitms.website.domain.introduction.IntroService;
6+
import com.kusitms.website.domain.introduction.dto.response.IntroResponse;
7+
import com.kusitms.website.global.common.BaseResponse;
8+
import io.swagger.v3.oas.annotations.Operation;
9+
import io.swagger.v3.oas.annotations.media.Content;
10+
import io.swagger.v3.oas.annotations.media.Schema;
11+
import io.swagger.v3.oas.annotations.responses.ApiResponse;
12+
import io.swagger.v3.oas.annotations.responses.ApiResponses;
13+
import io.swagger.v3.oas.annotations.tags.Tag;
14+
import lombok.RequiredArgsConstructor;
15+
import org.springframework.http.ResponseEntity;
16+
import org.springframework.web.bind.annotation.*;
17+
18+
@RestController
19+
@RequestMapping("/api")
20+
@RequiredArgsConstructor
21+
@Tag(name = "Email", description = "이메일 API Document")
22+
public class EmailController {
23+
24+
private final EmailService emailService;
25+
26+
@PostMapping("/emails")
27+
@Operation(summary = "이메일 저장 API", description = "학회 모집 소식 전송 이메일을 저장합니다.")
28+
@ApiResponses(value = {
29+
@ApiResponse(
30+
responseCode = "200",
31+
description = "저장 성공",
32+
content = @Content(schema = @Schema(implementation = EmailResponse.class))
33+
),
34+
@ApiResponse(
35+
responseCode = "400",
36+
description = "잘못된 요청 (이메일 형식 오류, 중복 이메일 등)",
37+
content = @Content(schema = @Schema(implementation = BaseResponse.class))
38+
)
39+
})
40+
public ResponseEntity<BaseResponse<EmailResponse>> saveEmail(
41+
@RequestParam String email
42+
) {
43+
return ResponseEntity.ok(
44+
new BaseResponse<>(emailService.saveEmail(email))
45+
);
46+
}
47+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
package com.kusitms.website.domain.email.dto.response;
2+
3+
import io.swagger.v3.oas.annotations.media.Schema;
4+
import lombok.Builder;
5+
import lombok.Getter;
6+
7+
@Getter
8+
@Builder
9+
@Schema
10+
public class EmailResponse {
11+
@Schema(description = "Id")
12+
private String id;
13+
14+
@Schema(description = "이메일")
15+
private String email;
16+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
package com.kusitms.website.domain.email.repository;
2+
3+
import com.kusitms.website.domain.email.Email;
4+
import org.springframework.data.jpa.repository.JpaRepository;
5+
import org.springframework.stereotype.Repository;
6+
7+
@Repository
8+
public interface EmailRepository extends JpaRepository<Email, Long> {
9+
boolean existsByEmail(String email);
10+
11+
}
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
package com.kusitms.website.domain.email.service;
2+
3+
import com.kusitms.website.domain.email.Email;
4+
import com.kusitms.website.domain.email.dto.response.EmailResponse;
5+
import com.kusitms.website.domain.email.repository.EmailRepository;
6+
import lombok.RequiredArgsConstructor;
7+
import org.springframework.stereotype.Service;
8+
import org.springframework.transaction.annotation.Transactional;
9+
10+
import java.util.regex.Pattern;
11+
12+
@Service
13+
@RequiredArgsConstructor
14+
public class EmailService {
15+
16+
private final EmailRepository emailRepository;
17+
18+
private static final Pattern EMAIL_PATTERN = Pattern.compile(
19+
"^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,}$"
20+
);
21+
22+
@Transactional
23+
public EmailResponse saveEmail(String email) {
24+
25+
if (email == null || email.trim().isEmpty()) {
26+
throw new IllegalArgumentException("이메일은 필수 입력값입니다.");
27+
}
28+
29+
if (!EMAIL_PATTERN.matcher(email).matches()) {
30+
throw new IllegalArgumentException("유효하지 않은 이메일 형식입니다.");
31+
}
32+
33+
if (emailRepository.existsByEmail(email)) {
34+
throw new IllegalArgumentException("이미 등록된 이메일입니다.");
35+
}
36+
37+
Email savedEmail = emailRepository.save(
38+
Email.builder()
39+
.email(email)
40+
.build()
41+
);
42+
43+
return EmailResponse.builder()
44+
.id(String.valueOf(savedEmail.getId()))
45+
.email(savedEmail.getEmail())
46+
.build();
47+
}
48+
}

src/main/java/com/kusitms/website/global/exception/GlobalExceptionHandler.java

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,27 @@
11
package com.kusitms.website.global.exception;
22

3+
import com.kusitms.website.global.common.BaseException;
34
import com.kusitms.website.global.common.BaseExceptionStatus;
45
import com.kusitms.website.global.common.BaseResponse;
6+
import org.springframework.http.ResponseEntity;
57
import org.springframework.web.bind.annotation.ExceptionHandler;
68
import org.springframework.web.bind.annotation.RestControllerAdvice;
79

810
@RestControllerAdvice
911
public class GlobalExceptionHandler {
1012

13+
@ExceptionHandler(IllegalArgumentException.class)
14+
public ResponseEntity<BaseResponse<BaseException>> handleIllegalArgument(
15+
IllegalArgumentException ex
16+
) {
17+
return ResponseEntity
18+
.badRequest()
19+
.body(BaseResponse.error(
20+
BaseExceptionStatus.BAD_REQUEST,
21+
ex.getMessage()
22+
));
23+
}
24+
1125
@ExceptionHandler(RuntimeException.class)
1226
public BaseResponse handleException(RuntimeException ex) {
1327
return BaseResponse.error(BaseExceptionStatus.INTER_SERVER_ERROR);

0 commit comments

Comments
 (0)