-
Notifications
You must be signed in to change notification settings - Fork 48
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* feat: 실습1, 2 구현 - 문서화 실습 구현 - 인증 실습 구현 * refactor: MemberResponse 기본 생성자 추가 * feat: MethodArgumentResolver에서 password와 password-check가 일치하는 지 검증 * feat: interceptor 와 methodArgumentResolver 에서 발생하는 예외 관리 - 아직 미완성.. * feat: annotation 기반 method argument validate 추가 - 패스워드 일치 - 이메일 중복 * feat: create 예외에 대한 문서화 구현 * feat: get에 대한 서비스, 컨트롤러 테스트와 문서화 구현 * feat: update에 대한 서비스, 컨트롤러 테스트와 문서화 구현 * feat: delete에 대한 서비스, 컨트롤러 테스트와 문서화 구현 * feat: 회원 가입 프론트 연동 구현 * feat: 로그인, 회원 정보 보기 기능 구현 * feat: 업데이트 구현 * feat: 탈퇴 구현 * refactor, feat: 테스트 정상화 및, 문서화 구현 - 전체 테스트 정상화 - 문서화 추가 양식 구현 (필수값 여부, 입력값 foramt) - 예외 사항 추가 * feat: IsAuth 어노테이션 추가 및 테스트와 문서 수정 * feat: 컨트롤러 테스트 추가 - 토큰이 없는 경우 정보조회 테스트 추가 * feat: 즐겨찾기 서비스 테스트 추가 * feat: 즐겨찾기 관련 도메인 테스트 추가 * feat: 즐겨찾기 관련 도메인 테스트 추가 - 즐겨찾기 삭제 테스트 및 구현 * feat: 즐겨 찾기 프론트 연동 구현 * refactor: 테스트 정상화 * refactor: 패키지 수정 - 패키지 구조 수정 * refactor: 예외 관계 수정 - GlobalExceptionHandler 수정 - exception 상속 관계 수정 * refactor: 테스트 정상화 - 인터셉터 path 추가 - exception handler 수정 * docs: README.md 수정 * feat: Member 관련 인수테스트 추가 - 예외 사항에 대한 인수테스트 추가 * feat: Member 관련 api테스트 추가 - 예외사항에 대한 문서화 완료 * refactor: documentation 메서드 중복 제거 * refactor: favorites 예외 테스트 추가 -문서화 구현 완료 * refactor: 리뷰 반영 1 - Auth enum 제거 - Interceptor 전체 url 적용 - Favorite equals, hashcode 재정의 삭제 - logger 적용 - transaction 적용 - Favorite을 aggregate root로 수정
- Loading branch information
Showing
108 changed files
with
3,798 additions
and
961 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
# 지하철 3단계 - 회원 관리, 즐겨찾기 | ||
|
||
## 요구 사항 | ||
|
||
- 회원 정보를 관리하는 기능 구현 | ||
- 자신의 정보만 수정 가능하도록 해야하며 **로그인이 선행**되어야 함 | ||
- 토큰의 유효성 검사와 본인 여부를 판단하는 로직 추가 | ||
- side case에 대한 예외처리 | ||
- 인수 테스트와 단위 테스트 작성 | ||
- API 문서를 작성하고 문서화를 위한 테스트 작성 | ||
- 페이지 연동 | ||
- 즐겨찾기 기능을 추가(추가,삭제,조회) | ||
- 자신의 정보만 수정 가능하도록 해야하며 **로그인이 선행**되어야 함 | ||
- 토큰의 유효성 검사와 본인 여부를 판단하는 로직 추가(interceptor, argument resolver) | ||
- side case에 대한 예외처리 필수 | ||
- 인수 테스트와 단위 테스트 작성 | ||
- API 문서를 작성하고 문서화를 위한 테스트 작성 | ||
- 페이지 연동 | ||
|
||
### 기능 목록 | ||
|
||
회원 정보 관리 | ||
|
||
- [x] 회원 가입 | ||
- [x] 로그인 | ||
- [x] 로그인 후 회원 정보 조회/수정/삭제 | ||
- [x] 가입 요청에 대한 validation | ||
- [x] 로그인한 회원 정보를 토큰으로 보유 | ||
- [x] 회원 정보 토큰을 만료 시간이 존재하는 쿠키내에 저장 | ||
- [x] 회원 정보를 요구하는 요청에 대해 토큰을 통해 인증 | ||
- [x] 회원과 관련된 요청에 대한 테스트와 자동 문서화 기능 | ||
|
||
즐겨찾기 관리 | ||
|
||
- [x] 즐겨찾기 추가 | ||
- [x] 즐겨찾기 조회/ 제거 | ||
- [x] 즐겨찾기 추가/삭제 시 로그인 검증 | ||
- [x] 즐겨찾기 추가 시 중복 검증 | ||
- [x] 즐겨찾기 추가 시 역 이름 검증 | ||
|
||
### 예외 사항 | ||
|
||
- Member 예외사항 | ||
- 회원가입 | ||
- 비밀번호 확인 불일치 | ||
- Blank | ||
- 이메일 중복 | ||
- 로그인 | ||
- 비밀번호 불일치 | ||
- 존재하지 않는 이메일 | ||
- Blank | ||
- 정보조회 | ||
- 토큰 없음 | ||
- 정보수정 | ||
- 토큰 없음 | ||
- 비밀번호 불일치 | ||
- 비밀번호 확인 불일치 | ||
- Blank | ||
- 이메일 중복 | ||
- 정보삭제 | ||
- 토큰 없음 | ||
|
||
- Favorite 예외사항 | ||
- 즐겨찾기 추가 | ||
- 토큰 없음 | ||
- 즐겨찾기 중복 | ||
- 부적절한 역 이름 | ||
- 즐겨찾기 목록 조회 | ||
- 토큰 없음 | ||
- 즐겨찾기 제거 | ||
- 토큰 없음 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,31 +1,51 @@ | ||
plugins { | ||
id 'org.springframework.boot' version '2.2.5.RELEASE' | ||
id 'io.spring.dependency-management' version '1.0.9.RELEASE' | ||
id 'java' | ||
id 'org.springframework.boot' version '2.2.5.RELEASE' | ||
id 'io.spring.dependency-management' version '1.0.9.RELEASE' | ||
id "org.asciidoctor.convert" version "1.5.9.2" | ||
id 'java' | ||
} | ||
|
||
group = 'com.example' | ||
version = '0.0.1-SNAPSHOT' | ||
sourceCompatibility = '1.8' | ||
|
||
repositories { | ||
mavenCentral() | ||
mavenCentral() | ||
} | ||
|
||
dependencies { | ||
implementation 'org.springframework.boot:spring-boot-starter-web' | ||
implementation 'org.springframework.boot:spring-boot-starter-data-jdbc' | ||
implementation 'net.rakugakibox.spring.boot:logback-access-spring-boot-starter:2.7.1' | ||
implementation 'pl.allegro.tech.boot:handlebars-spring-boot-starter:0.3.0' | ||
implementation 'org.jgrapht:jgrapht-core:1.0.1' | ||
implementation 'io.jsonwebtoken:jjwt:0.9.1' | ||
testImplementation 'io.rest-assured:rest-assured:3.3.0' | ||
testImplementation('org.springframework.boot:spring-boot-starter-test') { | ||
exclude group: 'org.junit.vintage', module: 'junit-vintage-engine' | ||
} | ||
runtimeOnly 'com.h2database:h2' | ||
implementation 'org.springframework.boot:spring-boot-starter-web' | ||
implementation 'org.springframework.boot:spring-boot-starter-data-jdbc' | ||
implementation 'net.rakugakibox.spring.boot:logback-access-spring-boot-starter:2.7.1' | ||
implementation 'pl.allegro.tech.boot:handlebars-spring-boot-starter:0.3.0' | ||
implementation 'org.jgrapht:jgrapht-core:1.0.1' | ||
implementation 'io.jsonwebtoken:jjwt:0.9.1' | ||
testImplementation 'io.rest-assured:rest-assured:3.3.0' | ||
testImplementation 'org.springframework.restdocs:spring-restdocs-mockmvc:2.0.4.RELEASE' | ||
testImplementation('org.springframework.boot:spring-boot-starter-test') { | ||
exclude group: 'org.junit.vintage', module: 'junit-vintage-engine' | ||
} | ||
runtimeOnly 'com.h2database:h2' | ||
asciidoctor 'org.springframework.restdocs:spring-restdocs-asciidoctor:2.0.4.RELEASE' | ||
} | ||
|
||
ext { | ||
snippetsDir = file('build/generated-snippets') | ||
} | ||
|
||
test { | ||
useJUnitPlatform() | ||
useJUnitPlatform() | ||
outputs.dir snippetsDir | ||
} | ||
|
||
asciidoctor { | ||
inputs.dir snippetsDir | ||
dependsOn test | ||
} | ||
|
||
bootJar { | ||
dependsOn asciidoctor | ||
from("${asciidoctor.outputDir}/html5") { | ||
into 'static/docs' | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
51 changes: 51 additions & 0 deletions
51
src/main/java/wooteco/subway/domain/favorite/Favorite.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
package wooteco.subway.domain.favorite; | ||
|
||
import java.util.Objects; | ||
|
||
import org.springframework.data.annotation.Id; | ||
|
||
public class Favorite { | ||
@Id | ||
private Long id; | ||
private Long memberId; | ||
private Long sourceId; | ||
private Long targetId; | ||
|
||
protected Favorite() { | ||
} | ||
|
||
public Favorite(Long id, Long memberId, Long sourceId, Long targetId) { | ||
this.id = id; | ||
this.memberId = memberId; | ||
this.sourceId = sourceId; | ||
this.targetId = targetId; | ||
} | ||
|
||
public static Favorite of(Long id, Long memberId, Long sourceId, Long targetId) { | ||
return new Favorite(id, memberId, sourceId, targetId); | ||
} | ||
|
||
public static Favorite of(Long memberId, Long sourceId, Long targetId) { | ||
return new Favorite(null, memberId, sourceId, targetId); | ||
} | ||
|
||
public Long getId() { | ||
return id; | ||
} | ||
|
||
public Long getMemberId() { | ||
return memberId; | ||
} | ||
|
||
public Long getSourceId() { | ||
return sourceId; | ||
} | ||
|
||
public Long getTargetId() { | ||
return targetId; | ||
} | ||
|
||
public boolean isSameId(Long id) { | ||
return Objects.equals(this.id, id); | ||
} | ||
} |
Oops, something went wrong.