Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

전체 사용자 및 사용자 검색 API 구현 #8

Merged
merged 35 commits into from
Feb 14, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
cea9ec2
add: ``Member`` 컨트롤러 클래스 선언
snowykte0426 Feb 8, 2025
ab7dd85
add: ``/member`` 엔드포인트 선언
snowykte0426 Feb 8, 2025
8750a0c
add: ``PATCH /members/password`` 엔드포인트 용 Request DTO 정의
snowykte0426 Feb 8, 2025
7ea18f3
add: 사용자 권한 정의 Enum 클래스 선언
snowykte0426 Feb 8, 2025
baad175
add: 사용자 정보 조회 API Response DTO 정의
snowykte0426 Feb 8, 2025
763f579
add: ``Member`` 도메인 객체 생성
snowykte0426 Feb 8, 2025
843458c
update: 확장 가능한 ``BaseEntity``에 접근제어자 및 Get 메서드 추가
snowykte0426 Feb 8, 2025
8506d4e
add: ``member`` JPA Entity 클래스 정의
snowykte0426 Feb 8, 2025
93ba1b9
add: Mapper 인터페이스 정의 및 ``Member`` 도메인 모델-JPA Entity 간 Mapper 구현
snowykte0426 Feb 8, 2025
148776b
docs:: ERD 임베드 추가
snowykte0426 Feb 10, 2025
26c2f1a
docs:: 테이블과 기타 요소 분리
snowykte0426 Feb 10, 2025
bcebee6
delete: ``BaseUuidEntity`` 삭제
snowykte0426 Feb 11, 2025
804e61b
update: ``BaseIdEntity`` id 필드 접근 제어자 변경
snowykte0426 Feb 11, 2025
4ce1874
update: Auto Increment 기반 PK로 변경
snowykte0426 Feb 11, 2025
9c99206
update: Entity 클래스 필드 변동에 따른 변경
snowykte0426 Feb 11, 2025
6a389c4
docs: README 확장자 변경
snowykte0426 Feb 11, 2025
a213273
add: ``@Adapter`` 어노테이션 정의
snowykte0426 Feb 11, 2025
e2dbcbe
update: Record로 변경
snowykte0426 Feb 11, 2025
a37b47a
add: Application 계층 Port/Adapter 구현
snowykte0426 Feb 11, 2025
537ac7f
add: ``toResponse`` 메서드 추가
snowykte0426 Feb 11, 2025
c480219
add: Member Persistence Port 정의
snowykte0426 Feb 11, 2025
248f9d9
add: Member Persistence Adapter 구현
snowykte0426 Feb 11, 2025
9c12989
add: Member Repository 구현
snowykte0426 Feb 11, 2025
f5da626
add: ``@UseCase`` 어노테이션 정의
snowykte0426 Feb 11, 2025
7f11125
add: 모든 Member 조회 UseCase 구현
snowykte0426 Feb 11, 2025
871f89f
add: Member 검색 UseCase 구현
snowykte0426 Feb 11, 2025
5210278
add: 예외 반환 설정 및 관련 클래스 선언
snowykte0426 Feb 11, 2025
d8a48f8
add: Member 데이터가 없을 시 발행될 예외 정의
snowykte0426 Feb 11, 2025
d47ea1d
add: 전체 사용자 조회,사용자 검색 엔드포인트 구현
snowykte0426 Feb 11, 2025
463a7a7
chore: TODO 주석 추가
snowykte0426 Feb 12, 2025
1dbd017
delete: ``Read``,``Write`` Port 구분 제거
snowykte0426 Feb 12, 2025
182b0b0
test: ``QueryAllMemberUseCase``,``SearchMemberUseCase`` Test 추가
snowykte0426 Feb 12, 2025
98d174f
test: ``contextLoads`` 테스트에서 ``test`` 프로파일 설정
snowykte0426 Feb 12, 2025
63876a5
update: 메서드 및 클래스 이름 변경
snowykte0426 Feb 13, 2025
ea542fa
update: Presentation 계층 메서드명 변경
snowykte0426 Feb 13, 2025
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
40 changes: 0 additions & 40 deletions README.adoc

This file was deleted.

44 changes: 44 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
# Groom

GSM Room Booking System

---

## Commit Message Rule

| Type | Meaning |
|--------|--------------------|
| add | 새로운 코드나 파일을 추가했을 때 |
| update | 기존의 코드를 수정했을 때 |
| fix | 버그를 수정했을 때 |
| delete | 삭제한 사항이 있을 때 |
| chore | 그 외 자잘한 작업을 했을 때 |
| docs | 문서를 수정했을 때 |
| test | 테스트 관련 사항을 수정했을 때 |
| merge | 브랜치를 병합했을 때 |
| init | 프로젝트를 초기화했을 때 |

### Example

```bash
docs: README 작성

README.md 파일을 작성했습니다
```
---

## Branch Rule

기본적으로 ``Git Flow``를 따르며, ``main``,`develop`,`feature`,`hotfix` 브랜치를 사용합니다.

| Branch | Meaning | Merge Branch |
|---------|--------------------------|--------------|
| main | 배포 가능한 상태로 유지하는 브랜치 | [가장 최신 버전] |
| develop | 다음 버전을 개발하는 브랜치 | main |
| feature | 기능을 개발하는 브랜치 | develop |
| hotfix | 배포 버전에서 발생한 버그를 수정하는 브랜치 | main |


## Database Schema

<iframe width="600" height="336" src="https://www.erdcloud.com/p/gBu6AkAeoALCdRew2" frameborder="0" allowfullscreen></iframe>
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package com.ampersand.groom.domain.member.application;

import com.ampersand.groom.domain.member.application.port.MemberApplicationPort;
import com.ampersand.groom.domain.member.application.usecase.FindAllMembersUseCase;
import com.ampersand.groom.domain.member.application.usecase.FindMembersByCriteriaUseCase;
import com.ampersand.groom.domain.member.domain.constant.MemberRole;
import com.ampersand.groom.domain.member.presentation.data.response.GetCurrentMemberResponse;
import com.ampersand.groom.domain.member.presentation.data.response.GetMemberResponse;
import com.ampersand.groom.global.annotation.adapter.Adapter;
import com.ampersand.groom.global.annotation.adapter.constant.AdapterType;
import lombok.RequiredArgsConstructor;

import java.util.List;

@Adapter(AdapterType.INBOUND)
@RequiredArgsConstructor
public class MemberApplicationAdapter implements MemberApplicationPort {

private final FindAllMembersUseCase findAllMembersUseCase;
private final FindMembersByCriteriaUseCase findMembersByCriteriaUseCase;

@Override
public List<GetMemberResponse> findAllMembers() {
return findAllMembersUseCase.execute();
}

@Override
public List<GetMemberResponse> findMembersByCriteria(Long id, String name, Integer generation, String email, Boolean isAvailable, MemberRole role) {
return findMembersByCriteriaUseCase.execute(id, name, generation, email, isAvailable, role);
}

@Override
public GetCurrentMemberResponse findCurrentMember() {
return null; // TODO: 인증/인가 및 booking 관련 로직 구현 시 구현
}

@Override
public void updatePassword(Long id, String currentPassword, String newPassword) {
// TODO: 인증/인가 및 Email 전송 로직 구현 시 구현
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package com.ampersand.groom.domain.member.application.port;

import com.ampersand.groom.domain.member.domain.constant.MemberRole;
import com.ampersand.groom.domain.member.presentation.data.response.GetCurrentMemberResponse;
import com.ampersand.groom.domain.member.presentation.data.response.GetMemberResponse;

import java.util.List;

public interface MemberApplicationPort {
List<GetMemberResponse> findAllMembers();

List<GetMemberResponse> findMembersByCriteria(Long id, String name, Integer generation, String email, Boolean isAvailable, MemberRole role);

GetCurrentMemberResponse findCurrentMember();

void updatePassword(Long id, String currentPassword, String newPassword);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package com.ampersand.groom.domain.member.application.port;

import com.ampersand.groom.domain.member.domain.Member;
import com.ampersand.groom.domain.member.domain.constant.MemberRole;

import java.util.List;

public interface MemberPersistencePort {
List<Member> findAllMembers();

List<Member> findMembersByCriteria(Long id, String name, Integer generation, String email, Boolean isAvailable, MemberRole role);

Member findMemberById(Long id);

void updateMemberPassword(Long id, String newPassword);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package com.ampersand.groom.domain.member.application.usecase;

import com.ampersand.groom.domain.member.application.port.MemberPersistencePort;
import com.ampersand.groom.domain.member.persistence.mapper.MemberMapper;
import com.ampersand.groom.domain.member.presentation.data.response.GetMemberResponse;
import com.ampersand.groom.global.annotation.usecase.UseCaseWithReadOnlyTransaction;
import lombok.RequiredArgsConstructor;

import java.util.List;

@UseCaseWithReadOnlyTransaction
@RequiredArgsConstructor
public class FindAllMembersUseCase {

private final MemberPersistencePort memberPersistencePort;
private final MemberMapper memberMapper;

public List<GetMemberResponse> execute() {
return memberPersistencePort.findAllMembers().stream().map(
memberMapper::toResponse
).toList();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package com.ampersand.groom.domain.member.application.usecase;

import com.ampersand.groom.domain.member.application.port.MemberPersistencePort;
import com.ampersand.groom.domain.member.domain.constant.MemberRole;
import com.ampersand.groom.domain.member.persistence.mapper.MemberMapper;
import com.ampersand.groom.domain.member.presentation.data.response.GetMemberResponse;
import com.ampersand.groom.global.annotation.usecase.UseCaseWithReadOnlyTransaction;
import lombok.RequiredArgsConstructor;

import java.util.List;

@UseCaseWithReadOnlyTransaction
@RequiredArgsConstructor
public class FindMembersByCriteriaUseCase {

private final MemberPersistencePort memberPersistencePort;
private final MemberMapper memberMapper;

public List<GetMemberResponse> execute(Long id, String name, Integer generation, String email, Boolean isAvailable, MemberRole role) {
return memberPersistencePort.findMembersByCriteria(id, name, generation, email, isAvailable, role).stream().map(
memberMapper::toResponse
).toList();
}
}
17 changes: 17 additions & 0 deletions src/main/java/com/ampersand/groom/domain/member/domain/Member.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package com.ampersand.groom.domain.member.domain;

import com.ampersand.groom.domain.member.domain.constant.MemberRole;
import lombok.Builder;
import lombok.Getter;

@Getter
@Builder
public class Member {
private final Long id;
private final String name;
private final String email;
private final String password;
private final Integer generation;
private final Boolean isAvailable;
private final MemberRole role;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package com.ampersand.groom.domain.member.domain.constant;

import org.springframework.security.core.GrantedAuthority;

public enum MemberRole implements GrantedAuthority {
ROLE_ADMIN, ROLE_STUDENT, ROLE_TEACHER;

@Override
public String getAuthority() {
return name();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package com.ampersand.groom.domain.member.exception;

import com.ampersand.groom.global.error.ErrorCode;
import com.ampersand.groom.global.error.exception.GroomException;

public class MemberNotFoundException extends GroomException {
public MemberNotFoundException() {
super(ErrorCode.MEMBER_NOT_FOUND);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package com.ampersand.groom.domain.member.persistence;

import com.ampersand.groom.domain.member.application.port.MemberPersistencePort;
import com.ampersand.groom.domain.member.domain.Member;
import com.ampersand.groom.domain.member.domain.constant.MemberRole;
import com.ampersand.groom.domain.member.exception.MemberNotFoundException;
import com.ampersand.groom.domain.member.persistence.mapper.MemberMapper;
import com.ampersand.groom.domain.member.persistence.repository.MemberJpaRepository;
import com.ampersand.groom.global.annotation.adapter.Adapter;
import com.ampersand.groom.global.annotation.adapter.constant.AdapterType;
import lombok.RequiredArgsConstructor;

import java.util.List;

@Adapter(AdapterType.OUTBOUND)
@RequiredArgsConstructor
public class MemberPersistenceAdapter implements MemberPersistencePort {

private final MemberJpaRepository memberJpaRepository;
private final MemberMapper memberMapper;

@Override
public List<Member> findAllMembers() {
return memberJpaRepository.findAll().stream()
.map(memberMapper::toDomain)
.toList();
}

@Override
public List<Member> findMembersByCriteria(Long id, String name, Integer generation, String email, Boolean isAvailable, MemberRole role) {
return memberJpaRepository.findMembersByCriteria(id, name, generation, email, isAvailable, role).stream()
.map(memberMapper::toDomain)
.toList();
}

@Override
public Member findMemberById(Long id) {
return memberJpaRepository.findById(id)
.map(memberMapper::toDomain)
.orElseThrow(MemberNotFoundException::new);
}

@Override
public void updateMemberPassword(Long id, String newPassword) {
memberJpaRepository.updatePassword(id, newPassword);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package com.ampersand.groom.domain.member.persistence.entity;

import com.ampersand.groom.domain.member.domain.constant.MemberRole;
import com.ampersand.groom.global.entity.BaseIdEntity;
import jakarta.persistence.*;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.ToString;

@Getter
@NoArgsConstructor
@Entity
@Table(name = "member")
@ToString
public class MemberJpaEntity extends BaseIdEntity {
@Column(nullable = false)
private String name;
@Column(nullable = false, unique = true)
private String email;
@Column(nullable = false)
@ToString.Exclude
private String password;
@Column(nullable = false)
private Integer generation;
@Column(nullable = false, name = "available")
private Boolean isAvailable;
@Column(nullable = false)
@Enumerated(EnumType.STRING)
private MemberRole role;

@Builder
public MemberJpaEntity(Long id, String name, String email, String password, Integer generation, Boolean isAvailable, MemberRole role) {
this.id = id;
this.name = name;
this.email = email;
this.password = password;
this.generation = generation;
this.isAvailable = isAvailable;
this.role = role;
}
}
Loading