Skip to content

Commit

Permalink
docs: 리드미 1차 작성
Browse files Browse the repository at this point in the history
  • Loading branch information
Sehee-Lee-01 committed Jan 19, 2024
1 parent 21c9fa9 commit 04f3618
Showing 1 changed file with 192 additions and 0 deletions.
192 changes: 192 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,194 @@
# outfit-of-the-weather
[#OOTW] 그날의 날씨를 보고 오늘의 코디를 공유하는 커뮤니티 By 빽엔두리

### 클론 타겟

- [꾸온꾸](https://korean.visitkorea.or.kr/detail/rem_detail.do?cotid=14a13909-134a-4a0e-a581-fc1ace95d925)
- 현재 날씨를 확인하고 날씨에 맞춰 아바타를 코디한 후 전국의 여행지를 배경으로 사진을 찍어 업로드하는 게시판
- 레퍼런스 이미지

![스크린샷 2024-01-16 오후 3.17.30.png](https://prod-files-secure.s3.us-west-2.amazonaws.com/a557051f-c7ef-49b4-83dc-fbd1373d5693/6cef6311-6a06-48cd-9643-c1a131869bec/%E1%84%89%E1%85%B3%E1%84%8F%E1%85%B3%E1%84%85%E1%85%B5%E1%86%AB%E1%84%89%E1%85%A3%E1%86%BA_2024-01-16_%E1%84%8B%E1%85%A9%E1%84%92%E1%85%AE_3.17.30.png)

### 개발 목표

- 현재의 날씨를 보고 그에 맞는 아바타 코디를 선택해 이미지를 저장할 수 있고 저장한 이미지를 공유할 수 있는 게시판을 만드는 것을 1차 프로젝트 mvp로 삼고 진행
- 이후 프로젝트 고도화에 따라 여러 기능을 추가적으로 구현 예정
- 최종적으로 해당 콘텐츠를 메인으로 아바타 아이템 상거래가 가능한 커머스 시스템 도입을 목표로 진행 예정

<details>
<summary>moscow</summary>

- Must Have: 날씨 API 기반 게시글, 사용자 인증, 이미지 서비스
- Should Have: 댓글, 무한 스크롤, 사용자 인증/인가, 소셜 로그인, 좋아요, 해시태그, 히스토리
- Could Have: 검색, 서비스 구독, 사용자 권한, 사용자 인증/인가
- Won't Have: 게시글 북마크, 알림, 이메일, 아바타 아이템 커머스, 통합회원, 휴대폰 인증

</details>

### 기술 스택

- java 17
- springboot 3.2.0
- spring security
- jsonwebtoken jjwt 0.12.3
- openfeign 4.1.0
- spring data jpa
- spring data redis
- spring mail
- green mail
- minio 8.5.7

### 팀 역할(SM, PO, Dev)

<table>
<tr align="center">
<td><B>SM</B></td>
<td><B>PO</B></td>
<td><B>Dev</B></td>
</tr>
<tr align="center">
<td><a href="https://github.com/Sehee-Lee-01">이세희</a></td>
<td><a href="https://github.com/shoeone96">이중원</a></td>
<td><a href="https://github.com/ASak1104">김현우</a></td>
</tr>
<tr align="center">
<td>
<img src="https://github.com/Sehee-Lee-01.png?size=100">
</td>
<td>
<img src="https://github.com/shoeone96.png?size=100">
</td>
<td>
<img src="https://github.com/ASak1104.png?size=100">
</td>
</tr>
</table>

1. 그라운드 룰
- **트러블 슈팅** 경험은 **2주 내**에 기록하고 공유
- [Git Wiki](https://github.com/spring-comes-to-us/outfit-of-the-weather/wiki)에 작성
- **가독성**을 중요하게 생각하여 코드 작성.
- 서로의 지식을 **공유**하고 코드와 의견을 **존중**하자
2. 스크럼 규칙

| 진행 시간 | 내용 |
| --- | --- |
| 매일 오전 9시, 15~30분 <br>(QR 찍고 진행) | - 어제 한 일(전날 커밋 기록) 공유 <br>- 오늘 할 일(체크 리스트) 공유 |
| 금요일 오전 9시 <br>(QR 찍자마자 진행) | - 스프린트(1주) 회고, 피드백 |
3. 트러블 슈팅
4. 프로젝트 관리

## 주요 기능

### 유저 기능

- 회원가입
- Email 검증
- [RFC 5322](https://www.rfc-editor.org/rfc/rfc5322#section-3.4.1)기준의 정규 표현식 검증
- 최대 길이 255
- Password 검증
- 최소 한 개 이상의 영문자, 숫자, 특수문자가 각각 필요
- 최소 길이 8, 최대 길이 30
- DTO에서`@Password`커스텀 어노테이션 기반으로 진행
- Entity 생성자를 통한 2차 검증
- 인증 코드 발송
- 회원가입 시 회원가입한 Email로 인증 코드 날리는 시스템 도입 (재전송 가능)
- Spring `MailSender`로 회원 가입자 이메일로 회원 가입 인증 코드 전송
- mail을 보내는 메서드는 `@Async`를 이용하여 비동기 처리
- 회원 정보를 저장하되 회원 인증 여부(`certified`)를 `false`로 저장하고 `true`가 될 때까지 로그인 서비스를 이용할 수 없게 설정
- `GreenMail` 라이브러리를 통한 인증 코드 전송 테스트 진행
- 회원가입 코드 인증
- 가입한 이메일과 코드를 body에 담아 회원 가입 인증 진행
- 회원 테이블의 `certified` column을 `true`로 변경하고 로그인 하여 사용할 수 있게 만듬
- 인증 코드를 `Redis`에서 관리
- Redis TTL 설정으로 10분이 지난 인증 코드는 만료 처리
- 로그인
- jwtToken 기반의 인증 시스템 도입
- 로그인 정보를 받은 후 유저 검증 후 `TokenProvider`를 통해 토큰 발급 및 검증
- 토큰 프로세스는 `jsonwebtoken jjwt` 라이브러리를 활용
- Token 인증 필터
- SecurityFilter 내부에 `JwtAuthenticationFilter`를 추가
- `JwtAuthenticationFilter`에서 로그인 시 사용한 토큰을 파싱 후 `userId`를 기반으로 `UsernameAuthenticationToken`을 생성
`SecurityContext`에 저장
- 로그인이 필요한 API에서 `Authentication` 객체를 받거나 직접 `principal`을 호출하는 메서드로 user 정보 호출

### 현재 날씨 조회 기능

- 기상청 OpenAPI 호출
- `OpenFeign`을 이용하여 기상청 API를 호출
- 기상청 API 응답 중 현재 날씨 정보(현재 기온, 강수 형태, 하늘 상태) 정보 조회
- 복잡한 OpenAPI 응답을 처리하기 위해 `@JsonDeserialize` 를 이용하여 API 응답 비직렬화 구현
- 요청이 제한된 기상청 API를 반복적으로 호출하는 문제 상황
- 추후 날씨 요청 위치를 Enum(시.도.동 등)으로 관리하고 Redis 기능을 이용하여 캐싱 기능 추가하여 외부 API 중복 호출을 줄일 예정
- `Coordinate` 클래스 유효성 검사
- `@Grid` 커스텀 어노테이션 기반으로 Controller에서 유효성 검사 진행

### 게시판 기능

- 게시판 CRUD 기능 작성
- 로그인 여부에 따라 보여주는 정보 분기문 작성
- jmeter 부하 테스트 중 게시글 목록 조회 성능이 가장 안 좋은 것을 확인
- 추후 조회 성능을 더 분석해보고 개선 예정
- 목록 조회는 필터 조회 기능을 추가할 예정
- 게시글 생성 시 `OpenFeign`을 이용하여 기상청 OpenAPI 호출
- 게시글 작성 시 일교차(최저/최고 기온) 정보 반영하여 저장
- 레이어별 요청 값 유효성 검사
- 요청 dto에서 annotation으로 1차 유효성 검사
- Entity 생성시 2차 유효성 검사
- 게시판 좋아요 기능
- 좋아요 여부(`isLike`) 바꿔주는 Patch API로 좋아요 기능 처리
- 게시글에 좋아요가 눌러진 숫자를 게시판 테이블에 추가
- 좋아요 동시성 문제 해결
- 한 사람이 한 게시물에 대해 여러 번 좋아요를 눌러서 생기는 문제
- 여러 사람이 한 게시물에 대하여 동시에 좋아요를 누르는 문제
- 비관적 락(`Pessimistic Lock`)을 사용하여 동시성 문제 해결
- jmeter 부하 테스트 중 두 번째로 성능이 안 좋은 것을 확인
(평균 시간이 전체 조회를 제외하고 가장 오래 걸림)
- 추후 성능 테스트 결과 확인 후 낙관적 락(`Optimistic Lock`) or `Redis`를 이용한 성능 개선 예정

### 아바타 이미지 기능

- 아바타 이미지 등록 및 조회 기능
- Enum Validation annotation 생성 및 적용
- 모든 Enum 타입을 String으로 받고 그 Enum에 해당하는 값이 존재하지 않을 시 예외를 반환하는 annotation 생성
- AvatarItem 전용 validation 클래스로 Entity validation 진행
- 파일 저장 오픈 소스 `MinIO` 도입
- 추후 배포 시 S3와의 호환성을 위해 로컬 작업에서 MinIO를 도입

→ S3 설정과 MinIO 설정 및 메서드가 동일하여 interface로 작성, 배포 버전에서는 S3 도입 예정

- Docker를 이용해 컨테이너로 이미지 저장소 생성
- `MinIO` 설정 후 이미지 저장 및 이미지 URL 반환 서비스 생성
- 게시판, 아바타 이미지에 로직 진행 중 이미지 저장 후 실패하면 이미지 삭제하는 로직 추가
- 대용량 이미지, 이미지 이외의 타입을 필터링 해주는 annotation 기반 validation 적용
- Post, AvatarItem 등 이미지를 사용하는 테이블이 많아 이미지를 관리할 수 있는 별도의 테이블 생성
- 추후 아바타 이미지/게시글의 수정 삭제 로직 후 발생 가능한 이미지 정합성 문제 확인 및 scheduling을 도입, 일정 시간 마다 `@Async` 를 이용하여 비동기적으로 처리 작업중
- filename의 unique 조건을 위해 UUID를 이용한 filename 생성 도입

### CI 도입(Github Action)

- pull request 시 테스트 코드를 모두 돌려보는 CI 환경 생성
- 로컬환경과 동일하게 Docker-compose 기반의 컨테이너 구동 후 test, build를 진행하는 방식 적용
- github secret 기반으로 환경 변수 지정
- Jacoco 테스트 리포트 자동화

### Jacoco 도입

- test coverage를 설정하여 기능 개발 시 test code를 작성하지 못한 케이스 확인
- 메서드 개행 제한 및 분기문에 따른 test 기준 추가
- Class Line Coverage → 70% 이상
- Branch Coverage → 70% 이상
- Method Line Count → 20줄
- 전체 프로젝트 테스트 커버리지 **✨98.48%✨** (2024.01.18 15:00 기준)

### Check style 도입

- google checkstyle 파일을 기반으로 팀 프로젝트에 적합한 코드 스타일 컨벤션 정의
- import 문, 여백 등 코드 스타일 컨벤션을 build 시 확인할 수 있도록 gradle 설정
- 정의한 checkstyle 파일을 통해 Intelij 코드 스타일 자동 정렬 설정

### JMeter 부하 테스트 실행

- 수치로 나타난 객관적인 성능을 파악하기 위해 일부 API 부하 테스트 진행
- 동시 접속이 많아지면 일부 요청이 예외를 반환하는 것을 확인
- 최대 DB Connection Pool을 조절함으로써 해결

0 comments on commit 04f3618

Please sign in to comment.