Skip to content

Commit 689ac44

Browse files
committed
feat: Member 도메인 구현
- BaseEntity 상속 받은 Member 엔티티 구현 - 회원가입 구현 - Role Enum으로 권한 정의
1 parent 7f3c212 commit 689ac44

File tree

7 files changed

+210
-0
lines changed

7 files changed

+210
-0
lines changed
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
package dmu.dasom.api.domain.member.controller;
2+
3+
import dmu.dasom.api.domain.common.exception.ErrorResponse;
4+
import dmu.dasom.api.domain.member.dto.SignupRequestDto;
5+
import dmu.dasom.api.domain.member.service.MemberService;
6+
import io.swagger.v3.oas.annotations.Operation;
7+
import io.swagger.v3.oas.annotations.media.Content;
8+
import io.swagger.v3.oas.annotations.media.ExampleObject;
9+
import io.swagger.v3.oas.annotations.media.Schema;
10+
import io.swagger.v3.oas.annotations.responses.ApiResponse;
11+
import io.swagger.v3.oas.annotations.responses.ApiResponses;
12+
import jakarta.validation.Valid;
13+
import lombok.RequiredArgsConstructor;
14+
import org.springframework.http.ResponseEntity;
15+
import org.springframework.web.bind.annotation.PostMapping;
16+
import org.springframework.web.bind.annotation.RequestBody;
17+
import org.springframework.web.bind.annotation.RequestMapping;
18+
import org.springframework.web.bind.annotation.RestController;
19+
20+
@RestController
21+
@RequestMapping("/api")
22+
@RequiredArgsConstructor
23+
public class MemberController {
24+
25+
private final MemberService memberService;
26+
27+
// 회원가입
28+
@Operation(summary = "회원가입")
29+
@ApiResponses(value = {
30+
@ApiResponse(responseCode = "200", description = "회원가입 성공"),
31+
@ApiResponse(responseCode = "400", description = "실패 케이스",
32+
content = @Content(
33+
mediaType = "application/json",
34+
schema = @Schema(implementation = ErrorResponse.class),
35+
examples = {
36+
@ExampleObject(
37+
name = "이메일 중복",
38+
value = "{ \"code\": \"C006\", \"message\": \"회원가입에 실패하였습니다.\" }"
39+
),
40+
@ExampleObject(
41+
name = "이메일 또는 비밀번호 형식 올바르지 않음",
42+
value = "{ \"code\": \"C007\", \"message\": \"요청한 값이 올바르지 않습니다.\" }"
43+
)
44+
}
45+
)
46+
)
47+
})
48+
@PostMapping("/auth/signup")
49+
public ResponseEntity<Void> signUp(@Valid @RequestBody final SignupRequestDto request) {
50+
memberService.signUp(request);
51+
return ResponseEntity.ok().build();
52+
}
53+
54+
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
package dmu.dasom.api.domain.member.dto;
2+
3+
import dmu.dasom.api.domain.member.entity.Member;
4+
import io.swagger.v3.oas.annotations.media.Schema;
5+
import jakarta.validation.constraints.Email;
6+
import jakarta.validation.constraints.NotNull;
7+
import lombok.Getter;
8+
import org.hibernate.validator.constraints.Length;
9+
10+
@Getter
11+
@Schema(name = "SignupRequestDto", description = "회원가입 요청 DTO")
12+
public class SignupRequestDto {
13+
14+
@Email
15+
@Length(max = 64)
16+
@NotNull
17+
@Schema(description = "이메일", example = "[email protected]", maxLength = 64)
18+
private String email;
19+
20+
@Length(min = 8, max = 128)
21+
@NotNull
22+
@Schema(description = "비밀번호", example = "password", minLength = 8, maxLength = 128)
23+
private String password;
24+
25+
public Member toEntity(final String password) {
26+
return Member.builder()
27+
.email(this.email)
28+
.password(password)
29+
.build();
30+
}
31+
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
package dmu.dasom.api.domain.member.entity;
2+
3+
import dmu.dasom.api.domain.common.BaseEntity;
4+
import dmu.dasom.api.domain.member.enums.Role;
5+
import jakarta.persistence.*;
6+
import jakarta.validation.constraints.Email;
7+
import lombok.AllArgsConstructor;
8+
import lombok.Builder;
9+
import lombok.Getter;
10+
import lombok.NoArgsConstructor;
11+
12+
@AllArgsConstructor
13+
@Builder
14+
@Entity
15+
@Getter
16+
@NoArgsConstructor
17+
public class Member extends BaseEntity {
18+
19+
@Column(name = "id")
20+
@GeneratedValue(strategy = GenerationType.IDENTITY)
21+
@Id
22+
private Long id;
23+
24+
@Column(name = "email", unique = true, length = 64, nullable = false)
25+
@Email
26+
private String email;
27+
28+
@Column(name = "password", length = 128, nullable = false)
29+
private String password;
30+
31+
@Builder.Default
32+
@Column(name = "role", length = 16, nullable = false)
33+
@Enumerated(EnumType.STRING)
34+
private Role role = Role.ROLE_MEMBER;
35+
36+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
package dmu.dasom.api.domain.member.enums;
2+
3+
import lombok.AllArgsConstructor;
4+
import lombok.Getter;
5+
6+
@AllArgsConstructor
7+
@Getter
8+
public enum Role {
9+
10+
ROLE_MEMBER("MEMBER"),
11+
ROLE_ADMIN("ADMIN"),
12+
;
13+
14+
private final String name;
15+
16+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
package dmu.dasom.api.domain.member.repository;
2+
3+
import dmu.dasom.api.domain.member.entity.Member;
4+
import org.springframework.data.jpa.repository.JpaRepository;
5+
6+
import java.util.Optional;
7+
8+
public interface MemberRepository extends JpaRepository<Member, Long> {
9+
10+
Optional<Member> findByEmail(final String email);
11+
12+
boolean existsByEmail(final String email);
13+
14+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
package dmu.dasom.api.domain.member.service;
2+
3+
import dmu.dasom.api.domain.member.dto.SignupRequestDto;
4+
import dmu.dasom.api.domain.member.entity.Member;
5+
6+
public interface MemberService {
7+
8+
Member getMemberByEmail(final String email);
9+
10+
boolean checkByEmail(final String email);
11+
12+
void signUp(final SignupRequestDto request);
13+
14+
}
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
package dmu.dasom.api.domain.member.service;
2+
3+
import dmu.dasom.api.domain.common.exception.CustomException;
4+
import dmu.dasom.api.domain.common.exception.ErrorCode;
5+
import dmu.dasom.api.domain.member.dto.SignupRequestDto;
6+
import dmu.dasom.api.domain.member.entity.Member;
7+
import dmu.dasom.api.domain.member.repository.MemberRepository;
8+
import lombok.RequiredArgsConstructor;
9+
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
10+
import org.springframework.stereotype.Service;
11+
import org.springframework.transaction.annotation.Transactional;
12+
13+
@RequiredArgsConstructor
14+
@Service
15+
@Transactional(readOnly = true)
16+
public class MemberServiceImpl implements MemberService {
17+
18+
private final BCryptPasswordEncoder encoder;
19+
private final MemberRepository memberRepository;
20+
21+
// 이메일로 사용자 조회
22+
@Override
23+
public Member getMemberByEmail(final String email) {
24+
return memberRepository.findByEmail(email)
25+
.orElseThrow(() -> new CustomException(ErrorCode.MEMBER_NOT_FOUND));
26+
}
27+
28+
// 이메일 확인
29+
@Override
30+
public boolean checkByEmail(final String email) {
31+
return memberRepository.existsByEmail(email);
32+
}
33+
34+
// 회원가입
35+
@Override
36+
public void signUp(final SignupRequestDto request) {
37+
// 이미 가입된 이메일인지 확인
38+
if (checkByEmail(request.getEmail()))
39+
throw new CustomException(ErrorCode.SIGNUP_FAILED);
40+
41+
// 비밀번호 암호화 후 저장
42+
memberRepository.save(request.toEntity(encoder.encode(request.getPassword())));
43+
}
44+
45+
}

0 commit comments

Comments
 (0)