Skip to content
This repository has been archived by the owner on Nov 8, 2023. It is now read-only.

Commit

Permalink
�[refactor] 포트폴리오 실시간 주식 시세 개선 (#129)
Browse files Browse the repository at this point in the history
* #75 fix: cors 설정

* #75 fix: 로그인 응답 결과 변경

- member -> user

* [feat] 클라이언트 스톰프 연결 종료시 포트폴리오 구독 제거 구현 (#94)

* [feat] 웹소켓 주식 현재가 시세 연결 (#74)

* [feat] 포트폴리오 추가 서비스 구현 (#32)

* #2 feat: 프로젝트 초기화 (#12)

* #6 chore: jwt 관련 라이브러리 추가

* #6 docs: gitignore에 푸시하지 말아야할 파일들 추가

* #6 docs: 로컬 환경 docker-compose.yml 추가

* #2 docs: applicatoin.yml 파일 설정 및 로그백 파일 추가

* #6 feat: 회원 엔티티 구현

* #6 feat: 에러관련 코드, 예외, 핸들러 추가

* #6 feat: 소셜 로그인 서비스 구현

* #6 rename: oauth 파일 이동

* #6 feat: Oauth 로그인 서비스 구현

* #6 feat: 로그아웃 및 액세스 토큰 갱신 구현

* [feat] 소셜 로그인 및 로그아웃 서비스 구현 (#14)

* #6 chore: jwt 관련 라이브러리 추가

* #6 docs: gitignore에 푸시하지 말아야할 파일들 추가

* #6 docs: 로컬 환경 docker-compose.yml 추가

* #2 docs: applicatoin.yml 파일 설정 및 로그백 파일 추가

* #6 feat: 회원 엔티티 구현

* #6 feat: 에러관련 코드, 예외, 핸들러 추가

* #6 feat: 소셜 로그인 서비스 구현

* #6 rename: oauth 파일 이동

* #6 feat: Oauth 로그인 서비스 구현

* #6 feat: 로그아웃 및 액세스 토큰 갱신 구현

* #9 feat: 한국투자 증권 open api 연결

* #9 test: 한국투자 증권 open api 연결 테스트 작성

* #9 feat: 실시간 체결가 웹소켓 연결 구현

* #9 feat: stomp 추가

* #10 feat: 종목 엔티티 구현

* #15 feat: 포트폴리오 엔티티 구현

* #15 feat: 포트폴리오 엔티티 구현

* #15 feat: 포트폴리오 추가 서비스 구현

* #15 test: 포트롤리오 추가 서비스 테스트 추가

* #15 test: 포트폴리오 추가 컨트롤러 테스트 코드 작성

* #15 test: 포트폴리오 추가 입력형식 테스트 코드 추가

* #15 feat: 포트폴리오 추가시 동일한 이름 중복 검증 처리

* #15 test: 포트폴리오 추가시 동일한 이름 중복 검증 처리 테스트 코드 작성

* [feat] 포트폴리오 수정 및 삭제 서비스 구현 (#33)

* #2 feat: 프로젝트 초기화 (#12)

* #6 chore: jwt 관련 라이브러리 추가

* #6 docs: gitignore에 푸시하지 말아야할 파일들 추가

* #6 docs: 로컬 환경 docker-compose.yml 추가

* #2 docs: applicatoin.yml 파일 설정 및 로그백 파일 추가

* #6 feat: 회원 엔티티 구현

* #6 feat: 에러관련 코드, 예외, 핸들러 추가

* #6 feat: 소셜 로그인 서비스 구현

* #6 rename: oauth 파일 이동

* #6 feat: Oauth 로그인 서비스 구현

* #6 feat: 로그아웃 및 액세스 토큰 갱신 구현

* [feat] 소셜 로그인 및 로그아웃 서비스 구현 (#14)

* #6 chore: jwt 관련 라이브러리 추가

* #6 docs: gitignore에 푸시하지 말아야할 파일들 추가

* #6 docs: 로컬 환경 docker-compose.yml 추가

* #2 docs: applicatoin.yml 파일 설정 및 로그백 파일 추가

* #6 feat: 회원 엔티티 구현

* #6 feat: 에러관련 코드, 예외, 핸들러 추가

* #6 feat: 소셜 로그인 서비스 구현

* #6 rename: oauth 파일 이동

* #6 feat: Oauth 로그인 서비스 구현

* #6 feat: 로그아웃 및 액세스 토큰 갱신 구현

* #9 feat: 한국투자 증권 open api 연결

* #9 test: 한국투자 증권 open api 연결 테스트 작성

* #9 feat: 실시간 체결가 웹소켓 연결 구현

* #9 feat: stomp 추가

* #10 feat: 종목 엔티티 구현

* #15 feat: 포트폴리오 엔티티 구현

* #15 feat: 포트폴리오 엔티티 구현

* #15 feat: 포트폴리오 추가 서비스 구현

* #15 test: 포트롤리오 추가 서비스 테스트 추가

* #15 test: 포트폴리오 추가 컨트롤러 테스트 코드 작성

* #15 test: 포트폴리오 추가 입력형식 테스트 코드 추가

* #15 feat: 포트폴리오 추가시 동일한 이름 중복 검증 처리

* #15 test: 포트폴리오 추가시 동일한 이름 중복 검증 처리 테스트 코드 작성

* #17 feat: 포트폴리오 수정 및 삭제 서비스 구현

* #17 test: 포트폴리오 수정 및 삭제에 대한 테스트 코드 작성

* #17 style: 코드 정리

* [feat] 포트폴리오 종목 추가 및 삭제 서비스 구현 (#43)

* [feat] 포트폴리오 추가 서비스 구현 (#32)

* #2 feat: 프로젝트 초기화 (#12)

* #6 chore: jwt 관련 라이브러리 추가

* #6 docs: gitignore에 푸시하지 말아야할 파일들 추가

* #6 docs: 로컬 환경 docker-compose.yml 추가

* #2 docs: applicatoin.yml 파일 설정 및 로그백 파일 추가

* #6 feat: 회원 엔티티 구현

* #6 feat: 에러관련 코드, 예외, 핸들러 추가

* #6 feat: 소셜 로그인 서비스 구현

* #6 rename: oauth 파일 이동

* #6 feat: Oauth 로그인 서비스 구현

* #6 feat: 로그아웃 및 액세스 토큰 갱신 구현

* [feat] 소셜 로그인 및 로그아웃 서비스 구현 (#14)

* #6 chore: jwt 관련 라이브러리 추가

* #6 docs: gitignore에 푸시하지 말아야할 파일들 추가

* #6 docs: 로컬 환경 docker-compose.yml 추가

* #2 docs: applicatoin.yml 파일 설정 및 로그백 파일 추가

* #6 feat: 회원 엔티티 구현

* #6 feat: 에러관련 코드, 예외, 핸들러 추가

* #6 feat: 소셜 로그인 서비스 구현

* #6 rename: oauth 파일 이동

* #6 feat: Oauth 로그인 서비스 구현

* #6 feat: 로그아웃 및 액세스 토큰 갱신 구현

* #9 feat: 한국투자 증권 open api 연결

* #9 test: 한국투자 증권 open api 연결 테스트 작성

* #9 feat: 실시간 체결가 웹소켓 연결 구현

* #9 feat: stomp 추가

* #10 feat: 종목 엔티티 구현

* #15 feat: 포트폴리오 엔티티 구현

* #15 feat: 포트폴리오 엔티티 구현

* #15 feat: 포트폴리오 추가 서비스 구현

* #15 test: 포트롤리오 추가 서비스 테스트 추가

* #15 test: 포트폴리오 추가 컨트롤러 테스트 코드 작성

* #15 test: 포트폴리오 추가 입력형식 테스트 코드 추가

* #15 feat: 포트폴리오 추가시 동일한 이름 중복 검증 처리

* #15 test: 포트폴리오 추가시 동일한 이름 중복 검증 처리 테스트 코드 작성

* [feat] 포트폴리오 수정 및 삭제 서비스 구현 (#33)

* #2 feat: 프로젝트 초기화 (#12)

* #6 chore: jwt 관련 라이브러리 추가

* #6 docs: gitignore에 푸시하지 말아야할 파일들 추가

* #6 docs: 로컬 환경 docker-compose.yml 추가

* #2 docs: applicatoin.yml 파일 설정 및 로그백 파일 추가

* #6 feat: 회원 엔티티 구현

* #6 feat: 에러관련 코드, 예외, 핸들러 추가

* #6 feat: 소셜 로그인 서비스 구현

* #6 rename: oauth 파일 이동

* #6 feat: Oauth 로그인 서비스 구현

* #6 feat: 로그아웃 및 액세스 토큰 갱신 구현

* [feat] 소셜 로그인 및 로그아웃 서비스 구현 (#14)

* #6 chore: jwt 관련 라이브러리 추가

* #6 docs: gitignore에 푸시하지 말아야할 파일들 추가

* #6 docs: 로컬 환경 docker-compose.yml 추가

* #2 docs: applicatoin.yml 파일 설정 및 로그백 파일 추가

* #6 feat: 회원 엔티티 구현

* #6 feat: 에러관련 코드, 예외, 핸들러 추가

* #6 feat: 소셜 로그인 서비스 구현

* #6 rename: oauth 파일 이동

* #6 feat: Oauth 로그인 서비스 구현

* #6 feat: 로그아웃 및 액세스 토큰 갱신 구현

* #9 feat: 한국투자 증권 open api 연결

* #9 test: 한국투자 증권 open api 연결 테스트 작성

* #9 feat: 실시간 체결가 웹소켓 연결 구현

* #9 feat: stomp 추가

* #10 feat: 종목 엔티티 구현

* #15 feat: 포트폴리오 엔티티 구현

* #15 feat: 포트폴리오 엔티티 구현

* #15 feat: 포트폴리오 추가 서비스 구현

* #15 test: 포트롤리오 추가 서비스 테스트 추가

* #15 test: 포트폴리오 추가 컨트롤러 테스트 코드 작성

* #15 test: 포트폴리오 추가 입력형식 테스트 코드 추가

* #15 feat: 포트폴리오 추가시 동일한 이름 중복 검증 처리

* #15 test: 포트폴리오 추가시 동일한 이름 중복 검증 처리 테스트 코드 작성

* #17 feat: 포트폴리오 수정 및 삭제 서비스 구현

* #17 test: 포트폴리오 수정 및 삭제에 대한 테스트 코드 작성

* #17 style: 코드 정리

* [feat] CI/CD 설정 (#35)

* #7 docs: cicd 워크플로우 설정

- 빌드 설정 및 s3 업로드 설정

* #7 docs: cicd 설정

* #7 fix: appspec.yml 파일 오타 수정

* #7 fix: appspec.yml 파일 오타 수정

* #7 fix: 버킷 이름 수정

* #7 fix: deploy 이름 삭제

- 버킷 이름에 /를 지정할 수 없음

* #16 feat: 포트폴리오 목록 조회 구현

* #16 feat: 포트폴리오 목록 조회 페이징 구현

* #16 feat: 포트폴리오 목록 조회시 hasNext를 응답하도록 구현

- nextCursor가 null인 경우 hasNext는 false로 응답하도록 구현하였습니다.

* #18 feat: 포트폴리오 종목 추가 서비스 구현

* #18 feat: 포트폴리오 종목 삭제 서비스 구현

* #18 style: 코드 정리

* [feat] 종목 검색 구현 (#45)

* [feat] 포트폴리오 추가 서비스 구현 (#32)

* #2 feat: 프로젝트 초기화 (#12)

* #6 chore: jwt 관련 라이브러리 추가

* #6 docs: gitignore에 푸시하지 말아야할 파일들 추가

* #6 docs: 로컬 환경 docker-compose.yml 추가

* #2 docs: applicatoin.yml 파일 설정 및 로그백 파일 추가

* #6 feat: 회원 엔티티 구현

* #6 feat: 에러관련 코드, 예외, 핸들러 추가

* #6 feat: 소셜 로그인 서비스 구현

* #6 rename: oauth 파일 이동

* #6 feat: Oauth 로그인 서비스 구현

* #6 feat: 로그아웃 및 액세스 토큰 갱신 구현

* [feat] 소셜 로그인 및 로그아웃 서비스 구현 (#14)

* #6 chore: jwt 관련 라이브러리 추가

* #6 docs: gitignore에 푸시하지 말아야할 파일들 추가

* #6 docs: 로컬 환경 docker-compose.yml 추가

* #2 docs: applicatoin.yml 파일 설정 및 로그백 파일 추가

* #6 feat: 회원 엔티티 구현

* #6 feat: 에러관련 코드, 예외, 핸들러 추가

* #6 feat: 소셜 로그인 서비스 구현

* #6 rename: oauth 파일 이동

* #6 feat: Oauth 로그인 서비스 구현

* #6 feat: 로그아웃 및 액세스 토큰 갱신 구현

* #9 feat: 한국투자 증권 open api 연결

* #9 test: 한국투자 증권 open api 연결 테스트 작성

* #9 feat: 실시간 체결가 웹소켓 연결 구현

* #9 feat: stomp 추가

* #10 feat: 종목 엔티티 구현

* #15 feat: 포트폴리오 엔티티 구현

* #15 feat: 포트폴리오 엔티티 구현

* #15 feat: 포트폴리오 추가 서비스 구현

* #15 test: 포트롤리오 추가 서비스 테스트 추가

* #15 test: 포트폴리오 추가 컨트롤러 테스트 코드 작성

* #15 test: 포트폴리오 추가 입력형식 테스트 코드 추가

* #15 feat: 포트폴리오 추가시 동일한 이름 중복 검증 처리

* #15 test: 포트폴리오 추가시 동일한 이름 중복 검증 처리 테스트 코드 작성

* [feat] 포트폴리오 수정 및 삭제 서비스 구현 (#33)

* #2 feat: 프로젝트 초기화 (#12)

* #6 chore: jwt 관련 라이브러리 추가

* #6 docs: gitignore에 푸시하지 말아야할 파일들 추가

* #6 docs: 로컬 환경 docker-compose.yml 추가

* #2 docs: applicatoin.yml 파일 설정 및 로그백 파일 추가

* #6 feat: 회원 엔티티 구현

* #6 feat: 에러관련 코드, 예외, 핸들러 추가

* #6 feat: 소셜 로그인 서비스 구현

* #6 rename: oauth 파일 이동

* #6 feat: Oauth 로그인 서비스 구현

* #6 feat: 로그아웃 및 액세스 토큰 갱신 구현

* [feat] 소셜 로그인 및 로그아웃 서비스 구현 (#14)

* #6 chore: jwt 관련 라이브러리 추가

* #6 docs: gitignore에 푸시하지 말아야할 파일들 추가

* #6 docs: 로컬 환경 docker-compose.yml 추가

* #2 docs: applicatoin.yml 파일 설정 및 로그백 파일 추가

* #6 feat: 회원 엔티티 구현

* #6 feat: 에러관련 코드, 예외, 핸들러 추가

* #6 feat: 소셜 로그인 서비스 구현

* #6 rename: oauth 파일 이동

* #6 feat: Oauth 로그인 서비스 구현

* #6 feat: 로그아웃 및 액세스 토큰 갱신 구현

* #9 feat: 한국투자 증권 open api 연결

* #9 test: 한국투자 증권 open api 연결 테스트 작성

* #9 feat: 실시간 체결가 웹소켓 연결 구현

* #9 feat: stomp 추가

* #10 feat: 종목 엔티티 구현

* #15 feat: 포트폴리오 엔티티 구현

* #15 feat: 포트폴리오 엔티티 구현

* #15 feat: 포트폴리오 추가 서비스 구현

* #15 test: 포트롤리오 추가 서비스 테스트 추가

* #15 test: 포트폴리오 추가 컨트롤러 테스트 코드 작성

* #15 test: 포트폴리오 추가 입력형식 테스트 코드 추가

* #15 feat: 포트폴리오 추가시 동일한 이름 중복 검증 처리

* #15 test: 포트폴리오 추가시 동일한 이름 중복 검증 처리 테스트 코드 작성

* #17 feat: 포트폴리오 수정 및 삭제 서비스 구현

* #17 test: 포트폴리오 수정 및 삭제에 대한 테스트 코드 작성

* #17 style: 코드 정리

* [feat] CI/CD 설정 (#35)

* #7 docs: cicd 워크플로우 설정

- 빌드 설정 및 s3 업로드 설정

* #7 docs: cicd 설정

* #7 fix: appspec.yml 파일 오타 수정

* #7 fix: appspec.yml 파일 오타 수정

* #7 fix: 버킷 이름 수정

* #7 fix: deploy 이름 삭제

- 버킷 이름에 /를 지정할 수 없음

* #16 feat: 포트폴리오 목록 조회 구현

* #16 feat: 포트폴리오 목록 조회 페이징 구현

* #16 feat: 포트폴리오 목록 조회시 hasNext를 응답하도록 구현

- nextCursor가 null인 경우 hasNext는 false로 응답하도록 구현하였습니다.

* #18 feat: 포트폴리오 종목 추가 서비스 구현

* #18 feat: 포트폴리오 종목 삭제 서비스 구현

* #18 style: 코드 정리

* #21 feat: 엘라스틱 서치 환경 구현

* #21 feat: 종목 검색 구현

* [feat] 포스트맨 변경 사항 반영 (#48)

* #48 fix: 포스트맨에 맞추어 응답 형식 변경

* #48 style: 코드 정리

* [feat] 포트폴리오 종목 조회 구현 (#49)

* #10 feat: 포트폴리오 종목 목록 조회 구현

* #10 feat: @JsonUnWraaped 적용

* [feat] ci/cd 파이프라인 개선 (#55)

* #51 fix: cicd 개선

- docker 추가

* #51 fix: cicd 테스트 브랜치 추가

* #10 feat: getFile -> getInputStream으로 변경

* #10 feat: 엘라스틱 서치 코드 제거 및 REST API 검색 구현

* #10 feat: 엘라스틱 서치 컨테이너 제거

* #10 chore: 엘라스틱 서치 의존성 제거

* #51 fix: 경로 변경

* [fix] 포스트맨 변경 사항 반영 (#56)

* #54 fix: postman 변경사항 반영

* #54 fix: postman 변경사항 반영

* [feat] 매입 이력 추가 서비스 구현 (#58)

* #19 feat: 매입 입력 추가 서비스 구현

* #19 test: 매입 입력 추가 서비스 테스트 코드 추가

* [feat] 매입 이력 수정 및 삭제 서비스 구현 (#61)

* #20 feat: 매입 입력 수정 서비스 구현 및 테스트 구현

* #20 docs: 샘플 데이터 추가

* #20 feat: 매입 이력 삭제 서비스 구현 및 테스트 코드 작성

* #20 feat: 포트폴리오 손익 내역 기록 서비스 구현

* #62 fix: 포트폴리오 목록 조회 응답에 securitiesFirm 프로퍼티 추가 (#63)

* #41 feat: 포트폴리오 수익 내역 서비스 구현

* [feat] 포트폴리오 손익 내역 기록 서비스 구현 (#65)

* #20 feat: 포트폴리오 손익 내역 기록 서비스 구현

* #41 feat: 포트폴리오 수익 내역 서비스 구현

* #41 fix: 포트폴리오 상세 조회시 securitiesFirm 프로퍼티 추가

* [feat] 포트폴리오 수익 내역 추가 서비스 구현 (#66)

* #20 feat: 포트폴리오 손익 내역 기록 서비스 구현

* #41 feat: 포트폴리오 수익 내역 서비스 구현

* #41 fix: 포트폴리오 상세 조회시 securitiesFirm 프로퍼티 추가

* #68 feat: 포트폴리오 상세 조회시 매입 내역 목록 조회할 수 있도록 구현

* [feat] 매입 내역 목록 조회 구현 (#69)

* #20 feat: 포트폴리오 손익 내역 기록 서비스 구현

* #41 feat: 포트폴리오 수익 내역 서비스 구현

* #41 fix: 포트폴리오 상세 조회시 securitiesFirm 프로퍼티 추가

* #68 feat: 포트폴리오 상세 조회시 매입 내역 목록 조회할 수 있도록 구현

* #68 feat: 포트폴리오 상세 조회시 알림에 대한 설정을 응답하도록 추가

* #68 feat: 포트폴리오 상세 조회시 총손익 공식 개선

* #68 feat: 주식 현재가 시세 클라이언트와 연결 구현

* [refactor] kis 서버 액세스 토큰 발급 만료 문제 해결 (#79)

* #75 feat: 실시간 포트폴리오 계산 데이터 응답 구현

* #75 refactor: accessToken 만료 개선

* [fix] 주식 현재가가 0인 경우 비동기적으로 수행되는 문제 해결 (#81)

* #75 feat: 실시간 포트폴리오 계산 데이터 응답 구현

* #75 refactor: accessToken 만료 개선

* #75 style: 불필요 코드 삭제

* #75 fix: 주식 현재가의 비동기적 실행 문제 해결

* #75 fix: 포트폴리오 목록 조회 문제 해결

* #75 fix: 병렬 스트림으로 변경

* #75 fix: 포트폴리오 상세 조회 API 개선

* #75 fix: 도커 컴포즈 빌드 명령어 추가

* #83 feat: 포트폴리오 구독 세션 연결 종료시 포트폴리오 구독 해시맵에서 제거하도록 구현

* #83 fix: 중복된 리스너 제거

* #98 feat: 포트폴리오 추가시 응답으로 portfolioId 응답하도록 구현

* #98 feat: 포트폴리오 추가시 응답으로 portfolioId 응답하도록 구현 (#99)

* #101 feat: 배당금 데이터 초기화 구현

* [feat] 배당금 데이터 초기화 구현 (#103)

* #98 feat: 포트폴리오 추가시 응답으로 portfolioId 응답하도록 구현

* #101 feat: 배당금 데이터 초기화 구현

* #101 feat: 배당금 계산 데이터 개선

* #101 test: 포트폴리오 종목 상세 조회 테스트 코드 작성

* #101 feat: 포트폴리오 종목 상세 조회시 배당금 정보도 응답하도록 구현

* [feat] 포트폴리오 상세 조회시 배당금 데이터를 응답하도록 구현 (#104)

* #98 feat: 포트폴리오 추가시 응답으로 portfolioId 응답하도록 구현

* #101 feat: 배당금 데이터 초기화 구현

* #101 feat: 배당금 계산 데이터 개선

* #101 test: 포트폴리오 종목 상세 조회 테스트 코드 작성

* #101 feat: 포트폴리오 종목 상세 조회시 배당금 정보도 응답하도록 구현

* #22 feat: 포트폴리오 알림 활성화/비활성화 설정 서비스 구현

* #22 test: 포트폴리오 활성화/비활성화 테스트 코드 작성

* #22 fix: 포트폴리오 손익 내역 문제 해결

- 갱신화된 현재 주식 가격을 받아서 손익 내역 추가에 사용되도록 개선하였습니다.

* #22 feat: 포트폴리오의 최대손실금액 활성화/비활성화 서비스 구현

* #22 refacotor: 포트폴리오 현재 주식 시세 스케줄러 개선

* #22 fix: 포트폴리오 최대손실금액 메일 알림 문제 해결

* [feat] 목표수익금액/최대손실금액 알림 서비스 구현 (#110)

* #98 feat: 포트폴리오 추가시 응답으로 portfolioId 응답하도록 구현

* #101 feat: 배당금 데이터 초기화 구현

* #101 feat: 배당금 계산 데이터 개선

* #101 test: 포트폴리오 종목 상세 조회 테스트 코드 작성

* #101 feat: 포트폴리오 종목 상세 조회시 배당금 정보도 응답하도록 구현

* #22 feat: 포트폴리오 알림 활성화/비활성화 설정 서비스 구현

* #22 test: 포트폴리오 활성화/비활성화 테스트 코드 작성

* #22 fix: 포트폴리오 손익 내역 문제 해결

- 갱신화된 현재 주식 가격을 받아서 손익 내역 추가에 사용되도록 개선하였습니다.

* #22 feat: 포트폴리오의 최대손실금액 활성화/비활성화 서비스 구현

* #22 refacotor: 포트폴리오 현재 주식 시세 스케줄러 개선

* #22 fix: 포트폴리오 최대손실금액 메일 알림 문제 해결

* [feat] 클라이언트 스톰프 연결 종료시 포트폴리오 구독 제거 구현 (#95)

* #75 fix: cors 설정

* #75 fix: 로그인 응답 결과 변경

- member -> user

* [feat] 클라이언트 스톰프 연결 종료시 포트폴리오 구독 제거 구현 (#94)

* [feat] 웹소켓 주식 현재가 시세 연결 (#74)

* [feat] 포트폴리오 추가 서비스 구현 (#32)

* #2 feat: 프로젝트 초기화 (#12)

* #6 chore: jwt 관련 라이브러리 추가

* #6 docs: gitignore에 푸시하지 말아야할 파일들 추가

* #6 docs: 로컬 환경 docker-compose.yml 추가

* #2 docs: applicatoin.yml 파일 설정 및 로그백 파일 추가

* #6 feat: 회원 엔티티 구현

* #6 feat: 에러관련 코드, 예외, 핸들러 추가

* #6 feat: 소셜 로그인 서비스 구현

* #6 rename: oauth 파일 이동

* #6 feat: Oauth 로그인 서비스 구현

* #6 feat: 로그아웃 및 액세스 토큰 갱신 구현

* [feat] 소셜 로그인 및 로그아웃 서비스 구현 (#14)

* #6 chore: jwt 관련 라이브러리 추가

* #6 docs: gitignore에 푸시하지 말아야할 파일들 추가

* #6 docs: 로컬 환경 docker-compose.yml 추가

* #2 docs: applicatoin.yml 파일 설정 및 로그백 파일 추가

* #6 feat: 회원 엔티티 구현

* #6 feat: 에러관련 코드, 예외, 핸들러 추가

* #6 feat: 소셜 로그인 서비스 구현

* #6 rename: oauth 파일 이동

* #6 feat: Oauth 로그인 서비스 구현

* #6 feat: 로그아웃 및 액세스 토큰 갱신 구현

* #9 feat: 한국투자 증권 open api 연결

* #9 test: 한국투자 증권 open api 연결 테스트 작성

* #9 feat: 실시간 체결가 웹소켓 연결 구현

* #9 feat: stomp 추가

* #10 feat: 종목 엔티티 구현

* #15 feat: 포트폴리오 엔티티 구현

* #15 feat: 포트폴리오 엔티티 구현

* #15 feat: 포트폴리오 추가 서비스 구현

* #15 test: 포트롤리오 추가 서비스 테스트 추가

* #15 test: 포트폴리오 추가 컨트롤러 테스트 코드 작성

* #15 test: 포트폴리오 추가 입력형식 테스트 코드 추가

* #15 feat: 포트폴리오 추가시 동일한 이름 중복 검증 처리

* #15 test: 포트폴리오 추가시 동일한 이름 중복 검증 처리 테스트 코드 작성

* [feat] 포트폴리오 수정 및 삭제 서비스 구현 (#33)

* #2 feat: 프로젝트 초기화 (#12)

* #6 chore: jwt 관련 라이브러리 추가

* #6 docs: gitignore에 푸시하지 말아야할 파일들 추가

* #6 docs: 로컬 환경 docker-compose.yml 추가

* #2 docs: applicatoin.yml 파일 설정 및 로그백 파일 추가

* #6 feat: 회원 엔티티 구현

* #6 feat: 에러관련 코드, 예외, 핸들러 추가

* #6 feat: 소셜 로그인 서비스 구현

* #6 rename: oauth 파일 이동

* #6 feat: Oauth 로그인 서비스 구현

* #6 feat: 로그아웃 및 액세스 토큰 갱신 구현

* [feat] 소셜 로그인 및 로그아웃 서비스 구현 (#14)

* #6 chore: jwt 관련 라이브러리 추가

* #6 docs: gitignore에 푸시하지 말아야할 파일들 추가

* #6 docs: 로컬 환경 docker-compose.yml 추가

* #2 docs: applicatoin.yml 파일 설정 및 로그백 파일 추가

* #6 feat: 회원 엔티티 구현

* #6 feat: 에러관련 코드, 예외, 핸들러 추가

* #6 feat: 소셜 로그인 서비스 구현

* #6 rename: oauth 파일 이동

* #6 feat: Oauth 로그인 서비스 구현

* #6 feat: 로그아웃 및 액세스 토큰 갱신 구현

* #9 feat: 한국투자 증권 open api 연결

* #9 test: 한국투자 증권 open api 연결 테스트 작성

* #9 feat: 실시간 체결가 웹소켓 연결 구현

* #9 feat: stomp 추가

* #10 feat: 종목 엔티티 구현

* #15 feat: 포트폴리오 엔티티 구현

* #15 feat: 포트폴리오 엔티티 구현

* #15 feat: 포트폴리오 추가 서비스 구현

* #15 test: 포트롤리오 추가 서비스 테스트 추가

* #15 test: 포트폴리오 추가 컨트롤러 테스트 코드 작성

* #15 test: 포트폴리오 추가 입력형식 테스트 코드 추가

* #15 feat: 포트폴리오 추가시 동일한 이름 중복 검증 처리

* #15 test: 포트폴리오 추가시 동일한 이름 중복 검증 처리 테스트 코드 작성

* #17 feat: 포트폴리오 수정 및 삭제 서비스 구현

* #17 test: 포트폴리오 수정 및 삭제에 대한 테스트 코드 작성

* #17 style: 코드 정리

* [feat] 포트폴리오 종목 추가 및 삭제 서비스 구현 (#43)

* [feat] 포트폴리오 추가 서비스 구현 (#32)

* #2 feat: 프로젝트 초기화 (#12)

* #6 chore: jwt 관련 라이브러리 추가

* #6 docs: gitignore에 푸시하지 말아야할 파일들 추가

* #6 docs: 로컬 환경 docker-compose.yml 추가

* #2 docs: applicatoin.yml 파일 설정 및 로그백 파일 추가

* #6 feat: 회원 엔티티 구현

* #6 feat: 에러관련 코드, 예외, 핸들러 추가

* #6 feat: 소셜 로그인 서비스 구현

* #6 rename: oauth 파일 이동

* #6 feat: Oauth 로그인 서비스 구현

* #6 feat: 로그아웃 및 액세스 토큰 갱신 구현

* [feat] 소셜 로그인 및 로그아웃 서비스 구현 (#14)

* #6 chore: jwt 관련 라이브러리 추가

* #6 docs: gitignore에 푸시하지 말아야할 파일들 추가

* #6 docs: 로컬 환경 docker-compose.yml 추가

* #2 docs: applicatoin.yml 파일 설정 및 로그백 파일 추가

* #6 feat: 회원 엔티티 구현

* #6 feat: 에러관련 코드, 예외, 핸들러 추가

* #6 feat: 소셜 로그인 서비스 구현

* #6 rename: oauth 파일 이동

* #6 feat: Oauth 로그인 서비스 구현

* #6 feat: 로그아웃 및 액세스 토큰 갱신 구현

* #9 feat: 한국투자 증권 open api 연결

* #9 test: 한국투자 증권 open api 연결 테스트 작성

* #9 feat: 실시간 체결가 웹소켓 연결 구현

* #9 feat: stomp 추가

* #10 feat: 종목 엔티티 구현

* #15 feat: 포트폴리오 엔티티 구현

* #15 feat: 포트폴리오 엔티티 구현

* #15 feat: 포트폴리오 추가 서비스 구현

* #15 test: 포트롤리오 추가 서비스 테스트 추가

* #15 test: 포트폴리오 추가 컨트롤러 테스트 코드 작성

* #15 test: 포트폴리오 추가 입력형식 테스트 코드 추가

* #15 feat: 포트폴리오 추가시 동일한 이름 중복 검증 처리

* #15 test: 포트폴리오 추가시 동일한 이름 중복 검증 처리 테스트 코드 작성

* [feat] 포트폴리오 수정 및 삭제 서비스 구현 (#33)

* #2 feat: 프로젝트 초기화 (#12)

* #6 chore: jwt 관련 라이브러리 추가

* #6 docs: gitignore에 푸시하지 말아야할 파일들 추가

* #6 docs: 로컬 환경 docker-compose.yml 추가

* #2 docs: applicatoin.yml 파일 설정 및 로그백 파일 추가

* #6 feat: 회원 엔티티 구현

* #6 feat: 에러관련 코드, 예외, 핸들러 추가

* #6 feat: 소셜 로그인 서비스 구현

* #6 rename: oauth 파일 이동

* #6 feat: Oauth 로그인 서비스 구현

* #6 feat: 로그아웃 및 액세스 토큰 갱신 구현

* [feat] 소셜 로그인 및 로그아웃 서비스 구현 (#14)

* #6 chore: jwt 관련 라이브러리 추가

* #6 docs: gitignore에 푸시하지 말아야할 파일들 추가

* #6 docs: 로컬 환경 docker-compose.yml 추가

* #2 docs: applicatoin.yml 파일 설정 및 로그백 파일 추가

* #6 feat: 회원 엔티티 구현

* #6 feat: 에러관련 코드, 예외, 핸들러 추가

* #6 feat: 소셜 로그인 서비스 구현

* #6 rename: oauth 파일 이동

* #6 feat: Oauth 로그인 서비스 구현

* #6 feat: 로그아웃 및 액세스 토큰 갱신 구현

* #9 feat: 한국투자 증권 open api 연결

* #9 test: 한국투자 증권 open api 연결 테스트 작성

* #9 feat: 실시간 체결가 웹소켓 연결 구현

* #9 feat: stomp 추가

* #10 feat: 종목 엔티티 구현

* #15 feat: 포트폴리오 엔티티 구현

* #15 feat: 포트폴리오 엔티티 구현

* #15 feat: 포트폴리오 추가 서비스 구현

* #15 test: 포트롤리오 추가 서비스 테스트 추가

* #15 test: 포트폴리오 추가 컨트롤러 테스트 코드 작성

* #15 test: 포트폴리오 추가 입력형식 테스트 코드 추가

* #15 feat: 포트폴리오 추가시 동일한 이름 중복 검증 처리

* #15 test: 포트폴리오 추가시 동일한 이름 중복 검증 처리 테스트 코드 작성

* #17 feat: 포트폴리오 수정 및 삭제 서비스 구현

* #17 test: 포트폴리오 수정 및 삭제에 대한 테스트 코드 작성

* #17 style: 코드 정리

* [feat] CI/CD 설정 (#35)

* #7 docs: cicd 워크플로우 설정

- 빌드 설정 및 s3 업로드 설정

* #7 docs: cicd 설정

* #7 fix: appspec.yml 파일 오타 수정

* #7 fix: appspec.yml 파일 오타 수정

* #7 fix: 버킷 이름 수정

* #7 fix: deploy 이름 삭제

- 버킷 이름에 /를 지정할 수 없음

* #16 feat: 포트폴리오 목록 조회 구현

* #16 feat: 포트폴리오 목록 조회 페이징 구현

* #16 feat: 포트폴리오 목록 조회시 hasNext를 응답하도록 구현

- nextCursor가 null인 경우 hasNext는 false로 응답하도록 구현하였습니다.

* #18 feat: 포트폴리오 종목 추가 서비스 구현

* #18 feat: 포트폴리오 종목 삭제 서비스 구현

* #18 style: 코드 정리

* [feat] 종목 검색 구현 (#45)

* [feat] 포트폴리오 추가 서비스 구현 (#32)

* #2 feat: 프로젝트 초기화 (#12)

* #6 chore: jwt 관련 라이브러리 추가

* #6 docs: gitignore에 푸시하지 말아야할 파일들 추가

* #6 docs: 로컬 환경 docker-compose.yml 추가

* #2 docs: applicatoin.yml 파일 설정 및 로그백 파일 추가

* #6 feat: 회원 엔티티 구현

* #6 feat: 에러관련 코드, 예외, 핸들러 추가

* #6 feat: 소셜 로그인 서비스 구현

* #6 rename: oauth 파일 이동

* #6 feat: Oauth 로그인 서비스 구현

* #6 feat: 로그아웃 및 액세스 토큰 갱신 구현

* [feat] 소셜 로그인 및 로그아웃 서비스 구현 (#14)

* #6 chore: jwt 관련 라이브러리 추가

* #6 docs: gitignore에 푸시하지 말아야할 파일들 추가

* #6 docs: 로컬 환경 docker-compose.yml 추가

* #2 docs: applicatoin.yml 파일 설정 및 로그백 파일 추가

* #6 feat: 회원 엔티티 구현

* #6 feat: 에러관련 코드, 예외, 핸들러 추가

* #6 feat: 소셜 로그인 서비스 구현

* #6 rename: oauth 파일 이동

* #6 feat: Oauth 로그인 서비스 구현

* #6 feat: 로그아웃 및 액세스 토큰 갱신 구현

* #9 feat: 한국투자 증권 open api 연결

* #9 test: 한국투자 증권 open api 연결 테스트 작성

* #9 feat: 실시간 체결가 웹소켓 연결 구현

* #9 feat: stomp 추가

* #10 feat: 종목 엔티티 구현

* #15 feat: 포트폴리오 엔티티 구현

* #15 feat: 포트폴리오 엔티티 구현

* #15 feat: 포트폴리오 추가 서비스 구현

* #15 test: 포트롤리오 추가 서비스 테스트 추가

* #15 test: 포트폴리오 추가 컨트롤러 테스트 코드 작성

* #15 test: 포트폴리오 추가 입력형식 테스트 코드 추가

* #15 feat: 포트폴리오 추가시 동일한 이름 중복 검증 처리

* #15 test: 포트폴리오 추가시 동일한 이름 중복 검증 처리 테스트 코드 작성

* [feat] 포트폴리오 수정 및 삭제 서비스 구현 (#33)

* #2 feat: 프로젝트 초기화 (#12)

* #6 chore: jwt 관련 라이브러리 추가

* #6 docs: gitignore에 푸시하지 말아야할 파일들 추가

* #6 docs: 로컬 환경 docker-compose.yml 추가

* #2 docs: applicatoin.yml 파일 설정 및 로그백 파일 추가

* #6 feat: 회원 엔티티 구현

* #6 feat: 에러관련 코드, 예외, 핸들러 추가

* #6 feat: 소셜 로그인 서비스 구현

* #6 rename: oauth 파일 이동

* #6 feat: Oauth 로그인 서비스 구현

* #6 feat: 로그아웃 및 액세스 토큰 갱신 구현

* [feat] 소셜 로그인 및 로그아웃 서비스 구현 (#14)

* #6 chore: jwt 관련 라이브러리 추가

* #6 docs: gitignore에 푸시하지 말아야할 파일들 추가

* #6 docs: 로컬 환경 docker-compose.yml 추가

* #2 docs: applicatoin.yml 파일 설정 및 로그백 파일 추가

* #6 feat: 회원 엔티티 구현

* #6 feat: 에러관련 코드, 예외, 핸들러 추가

* #6 feat: 소셜 로그인 서비스 구현

* #6 rename: oauth 파일 이동

* #6 feat: Oauth 로그인 서비스 구현

* #6 feat: 로그아웃 및 액세스 토큰 갱신 구현

* #9 feat: 한국투자 증권 open api 연결

* #9 test: 한국투자 증권 open api 연결 테스트 작성

* #9 feat: 실시간 체결가 웹소켓 연결 구현

* #9 feat: stomp 추가

* #10 feat: 종목 엔티티 구현

* #15 feat: 포트폴리오 엔티티 구현

* #15 feat: 포트폴리오 엔티티 구현

* #15 feat: 포트폴리오 추가 서비스 구현

* #15 test: 포트롤리오 추가 서비스 테스트 추가

* #15 test: 포트폴리오 추가 컨트롤러 테스트 코드 작성

* #15 test: 포트폴리오 추가 입력형식 테스트 코드 추가

* #15 feat: 포트폴리오 추가시 동일한 이름 중복 검증 처리

* #15 test: 포트폴리오 추가시 동일한 이름 중복 검증 처리 테스트 코드 작성

* #17 feat: 포트폴리오 수정 및 삭제 서비스 구현

* #17 test: 포트폴리오 수정 및 삭제에 대한 테스트 코드 작성

* #17 style: 코드 정리

* [feat] CI/CD 설정 (#35)

* #7 docs: cicd 워크플로우 설정

- 빌드 설정 및 s3 업로드 설정

* #7 docs: cicd 설정

* #7 fix: appspec.yml 파일 오타 수정

* #7 fix: appspec.yml 파일 오타 수정

* #7 fix: 버킷 이름 수정

* #7 fix: deploy 이름 삭제

- 버킷 이름에 /를 지정할 수 없음

* #16 feat: 포트폴리오 목록 조회 구현

* #16 feat: 포트폴리오 목록 조회 페이징 구현

* #16 feat: 포트폴리오 목록 조회시 hasNext를 응답하도록 구현

- nextCursor가 null인 경우 hasNext는 false로 응답하도록 구현하였습니다.

* #18 feat: 포트폴리오 종목 추가 서비스 구현

* #18 feat: 포트폴리오 종목 삭제 서비스 구현

* #18 style: 코드 정리

* #21 feat: 엘라스틱 서치 환경 구현

* #21 feat: 종목 검색 구현

* [feat] 포스트맨 변경 사항 반영 (#48)

* #48 fix: 포스트맨에 맞추어 응답 형식 변경

* #48 style: 코드 정리

* [feat] 포트폴리오 종목 조회 구현 (#49)

* #10 feat: 포트폴리오 종목 목록 조회 구현

* #10 feat: @JsonUnWraaped 적용

* [feat] ci/cd 파이프라인 개선 (#55)

* #51 fix: cicd 개선

- docker 추가

* #51 fix: cicd 테스트 브랜치 추가

* #10 feat: getFile -> getInputStream으로 변경

* #10 feat: 엘라스틱 서치 코드 제거 및 REST API 검색 구현

* #10 feat: 엘라스틱 서치 컨테이너 제거

* #10 chore: 엘라스틱 서치 의존성 제거

* #51 fix: 경로 변경

* [fix] 포스트맨 변경 사항 반영 (#56)

* #54 fix: postman 변경사항 반영

* #54 fix: postman 변경사항 반영

* [feat] 매입 이력 추가 서비스 구현 (#58)

* #19 feat: 매입 입력 추가 서비스 구현

* #19 test: 매입 입력 추가 서비스 테스트 코드 추가

* [feat] 매입 이력 수정 및 삭제 서비스 구현 (#61)

* #20 feat: 매입 입력 수정 서비스 구현 및 테스트 구현

* #20 docs: 샘플 데이터 추가

* #20 feat: 매입 이력 삭제 서비스 구현 및 테스트 코드 작성

* #20 feat: 포트폴리오 손익 내역 기록 서비스 구현

* #62 fix: 포트폴리오 목록 조회 응답에 securitiesFirm 프로퍼티 추가 (#63)

* #41 feat: 포트폴리오 수익 내역 서비스 구현

* [feat] 포트폴리오 손익 내역 기록 서비스 구현 (#65)

* #20 feat: 포트폴리오 손익 내역 기록 서비스 구현

* #41 feat: 포트폴리오 수익 내역 서비스 구현

* #41 fix: 포트폴리오 상세 조회시 securitiesFirm 프로퍼티 추가

* [feat] 포트폴리오 수익 내역 추가 서비스 구현 (#66)

* #20 feat: 포트폴리오 손익 내역 기록 서비스 구현

* #41 feat: 포트폴리오 수익 내역 서비스 구현

* #41 fix: 포트폴리오 상세 조회시 securitiesFirm 프로퍼티 추가

* #68 feat: 포트폴리오 상세 조회시 매입 내역 목록 조회할 수 있도록 구현

* [feat] 매입 내역 목록 조회 구현 (#69)

* #20 feat: 포트폴리오 손익 내역 기록 서비스 구현

* #41 feat: 포트폴리오 수익 내역 서비스 구현

* #41 fix: 포트폴리오 상세 조회시 securitiesFirm 프로퍼티 추가

* #68 feat: 포트폴리오 상세 조회시 매입 내역 목록 조회할 수 있도록 구현

* #68 feat: 포트폴리오 상세 조회시 알림에 대한 설정을 응답하도록 추가

* #68 feat: 포트폴리오 상세 조회시 총손익 공식 개선

* #68 feat: 주식 현재가 시세 클라이언트와 연결 구현

* [refactor] kis 서버 액세스 토큰 발급 만료 문제 해결 (#79)

* #75 feat: 실시간 포트폴리오 계산 데이터 응답 구현

* #75 refactor: accessToken 만료 개선

* [fix] 주식 현재가가 0인 경우 비동기적으로 수행되는 문제 해결 (#81)

* #75 feat: 실시간 포트폴리오 계산 데이터 응답 구현

* #75 refactor: accessToken 만료 개선

* #75 style: 불필요 코드 삭제

* #75 fix: 주식 현재가의 비동기적 실행 문제 해결

* #75 fix: 포트폴리오 목록 조회 문제 해결

* #75 fix: 병렬 스트림으로 변경

* #75 fix: 포트폴리오 상세 조회 API 개선

* #75 fix: 도커 컴포즈 빌드 명령어 추가

* #83 feat: 포트폴리오 구독 세션 연결 종료시 포트폴리오 구독 해시맵에서 제거하도록 구현

* [feat] 포트폴리오 상세 조회 및 종목 조회시 배당금 데이터 응답 구현 (#105)

* #75 fix: cors 설정

* #75 fix: 로그인 응답 결과 변경

- member -> user

* [feat] 클라이언트 스톰프 연결 종료시 포트폴리오 구독 제거 구현 (#94)

* [feat] 웹소켓 주식 현재가 시세 연결 (#74)

* [feat] 포트폴리오 추가 서비스 구현 (#32)

* #2 feat: 프로젝트 초기화 (#12)

* #6 chore: jwt 관련 라이브러리 추가

* #6 docs: gitignore에 푸시하지 말아야할 파일들 추가

* #6 docs: 로컬 환경 docker-compose.yml 추가

* #2 docs: applicatoin.yml 파일 설정 및 로그백 파일 추가

* #6 feat: 회원 엔티티 구현

* #6 feat: 에러관련 코드, 예외, 핸들러 추가

* #6 feat: 소셜 로그인 서비스 구현

* #6 rename: oauth 파일 이동

* #6 feat: Oauth 로그인 서비스 구현

* #6 feat: 로그아웃 및 액세스 토큰 갱신 구현

* [feat] 소셜 로그인 및 로그아웃 서비스 구현 (#14)

* #6 chore: jwt 관련 라이브러리 추가

* #6 docs: gitignore에 푸시하지 말아야할 파일들 추가

* #6 docs: 로컬 환경 docker-compose.yml 추가

* #2 docs: applicatoin.yml 파일 설정 및 로그백 파일 추가

* #6 feat: 회원 엔티티 구현

* #6 feat: 에러관련 코드, 예외, 핸들러 추가

* #6 feat: 소셜 로그인 서비스 구현

* #6 rename: oauth 파일 이동

* #6 feat: Oauth 로그인 서비스 구현

* #6 feat: 로그아웃 및 액세스 토큰 갱신 구현

* #9 feat: 한국투자 증권 open api 연결

* #9 test: 한국투자 증권 open api 연결 테스트 작성

* #9 feat: 실시간 체결가 웹소켓 연결 구현

* #9 feat: stomp 추가

* #10 feat: 종목 엔티티 구현

* #15 feat: 포트폴리오 엔티티 구현

* #15 feat: 포트폴리오 엔티티 구현

* #15 feat: 포트폴리오 추가 서비스 구현

* #15 test: 포트롤리오 추가 서비스 테스트 추가

* #15 test: 포트폴리오 추가 컨트롤러 테스트 코드 작성

* #15 test: 포트폴리오 추가 입력형식 테스트 코드 추가

* #15 feat: 포트폴리오 추가시 동일한 이름 중복 검증 처리

* #15 test: 포트폴리오 추가시 동일한 이름 중복 검증 처리 테스트 코드 작성

* [feat] 포트폴리오 수정 및 삭제 서비스 구현 (#33)

* #2 feat: 프로젝트 초기화 (#12)

* #6 chore: jwt 관련 라이브러리 추가

* #6 docs: gitignore에 푸시하지 말아야할 파일들 추가

* #6 docs: 로컬 환경 docker-compose.yml 추가

* #2 docs: applicatoin.yml 파일 설정 및 로그백 파일 추가

* #6 feat: 회원 엔티티 구현

* #6 feat: 에러관련 코드, 예외, 핸들러 추가

* #6 feat: 소셜 로그인 서비스 구현

* #6 rename: oauth 파일 이동

* #6 feat: Oauth 로그인 서비스 구현

* #6 feat: 로그아웃 및 액세스 토큰 갱신 구현

* [feat] 소셜 로그인 및 로그아웃 서비스 구현 (#14)

* #6 chore: jwt 관련 라이브러리 추가

* #6 docs: gitignore에 푸시하지 말아야할 파일들 추가

* #6 docs: 로컬 환경 docker-compose.yml 추가

* #2 docs: applicatoin.yml 파일 설정 및 로그백 파일 추가

* #6 feat: 회원 엔티티 구현

* #6 feat: 에러관련 코드, 예외, 핸들러 추가

* #6 feat: 소셜 로그인 서비스 구현

* #6 rename: oauth 파일 이동

* #6 feat: Oauth 로그인 서비스 구현

* #6 feat: 로그아웃 및 액세스 토큰 갱신 구현

* #9 feat: 한국투자 증권 open api 연결

* #9 test: 한국투자 증권 open api 연결 테스트 작성

* #9 feat: 실시간 체결가 웹소켓 연결 구현

* #9 feat: stomp 추가

* #10 feat: 종목 엔티티 구현

* #15 feat: 포트폴리오 엔티티 구현

* #15 feat: 포트폴리오 엔티티 구현

* #15 feat: 포트폴리오 추가 서비스 구현

* #15 test: 포트롤리오 추가 서비스 테스트 추가

* #15 test: 포트폴리오 추가 컨트롤러 테스트 코드 작성

* #15 test: 포트폴리오 추가 입력형식 테스트 코드 추가

* #15 feat: 포트폴리오 추가시 동일한 이름 중복 검증 처리

* #15 test: 포트폴리오 추가시 동일한 이름 중복 검증 처리 테스트 코드 작성

* #17 feat: 포트폴리오 수정 및 삭제 서비스 구현

* #17 test: 포트폴리오 수정 및 삭제에 대한 테스트 코드 작성

* #17 style: 코드 정리

* [feat] 포트폴리오 종목 추가 및 삭제 서비스 구현 (#43)

* [feat] 포트폴리오 추가 서비스 구현 (#32)

* #2 feat: 프로젝트 초기화 (#12)

* #6 chore: jwt 관련 라이브러리 추가

* #6 docs: gitignore에 푸시하지 말아야할 파일들 추가

* #6 docs: 로컬 환경 docker-compose.yml 추가

* #2 docs: applicatoin.yml 파일 설정 및 로그백 파일 추가

* #6 feat: 회원 엔티티 구현

* #6 feat: 에러관련 코드, 예외, 핸들러 추가

* #6 feat: 소셜 로그인 서비스 구현

* #6 rename: oauth 파일 이동

* #6 feat: Oauth 로그인 서비스 구현

* #6 feat: 로그아웃 및 액세스 토큰 갱신 구현

* [feat] 소셜 로그인 및 로그아웃 서비스 구현 (#14)

* #6 chore: jwt 관련 라이브러리 추가

* #6 docs: gitignore에 푸시하지 말아야할 파일들 추가

* #6 docs: 로컬 환경 docker-compose.yml 추가

* #2 docs: applicatoin.yml 파일 설정 및 로그백 파일 추가

* #6 feat: 회원 엔티티 구현

* #6 feat: 에러관련 코드, 예외, 핸들러 추가

* #6 feat: 소셜 로그인 서비스 구현

* #6 rename: oauth 파일 이동

* #6 feat: Oauth 로그인 서비스 구현

* #6 feat: 로그아웃 및 액세스 토큰 갱신 구현

* #9 feat: 한국투자 증권 open api 연결

* #9 test: 한국투자 증권 open api 연결 테스트 작성

* #9 feat: 실시간 체결가 웹소켓 연결 구현

* #9 feat: stomp 추가

* #10 feat: 종목 엔티티 구현

* #15 feat: 포트폴리오 엔티티 구현

* #15 feat: 포트폴리오 엔티티 구현

* #15 feat: 포트폴리오 추가 서비스 구현

* #15 test: 포트롤리오 추가 서비스 테스트 추가

* #15 test: 포트폴리오 추가 컨트롤러 테스트 코드 작성

* #15 test: 포트폴리오 추가 입력형식 테스트 코드 추가

* #15 feat: 포트폴리오 추가시 동일한 이름 중복 검증 처리

* #15 test: 포트폴리오 추가시 동일한 이름 중복 검증 처리 테스트 코드 작성

* [feat] 포트폴리오 수정 및 삭제 서비스 구현 (#33)

* #2 feat: 프로젝트 초기화 (#12)

* #6 chore: jwt 관련 라이브러리 추가

* #6 docs: gitignore에 푸시하지 말아야할 파일들 추가

* #6 docs: 로컬 환경 docker-compose.yml 추가

* #2 docs: applicatoin.yml 파일 설정 및 로그백 파일 추가

* #6 feat: 회원 엔티티 구현

* #6 feat: 에러관련 코드, 예외, 핸들러 추가

* #6 feat: 소셜 로그인 서비스 구현

* #6 rename: oauth 파일 이동

* #6 feat: Oauth 로그인 서비스 구현

* #6 feat: 로그아웃 및 액세스 토큰 갱신 구현

* [feat] 소셜 로그인 및 로그아웃 서비스 구현 (#14)

* #6 chore: jwt 관련 라이브러리 추가

* #6 docs: gitignore에 푸시하지 말아야할 파일들 추가

* #6 docs: 로컬 환경 docker-compose.yml 추가

* #2 docs: applicatoin.yml 파일 설정 및 로그백 파일 추가

* #6 feat: 회원 엔티티 구현

* #6 feat: 에러관련 코드, 예외, 핸들러 추가

* #6 feat: 소셜 로그인 서비스 구현

* #6 rename: oauth 파일 이동

* #6 feat: Oauth 로그인 서비스 구현

* #6 feat: 로그아웃 및 액세스 토큰 갱신 구현

* #9 feat: 한국투자 증권 open api 연결

* #9 test: 한국투자 증권 open api 연결 테스트 작성

* #9 feat: 실시간 체결가 웹소켓 연결 구현

* #9 feat: stomp 추가

* #10 feat: 종목 엔티티 구현

* #15 feat: 포트폴리오 엔티티 구현

* #15 feat: 포트폴리오 엔티티 구현

* #15 feat: 포트폴리오 추가 서비스 구현

* #15 test: 포트롤리오 추가 서비스 테스트 추가

* #15 test: 포트폴리오 추가 컨트롤러 테스트 코드 작성

* #15 test: 포트폴리오 추가 입력형식 테스트 코드 추가

* #15 feat: 포트폴리오 추가시 동일한 이름 중복 검증 처리

* #15 test: 포트폴리오 추가시 동일한 이름 중복 검증 처리 테스트 코드 작성

* #17 feat: 포트폴리오 수정 및 삭제 서비스 구현

* #17 test: 포트폴리오 수정 및 삭제에 대한 테스트 코드 작성

* #17 style: 코드 정리

* [feat] CI/CD 설정 (#35)

* #7 docs: cicd 워크플로우 설정

- 빌드 설정 및 s3 업로드 설정

* #7 docs: cicd 설정

* #7 fix: appspec.yml 파일 오타 수정

* #7 fix: appspec.yml 파일 오타 수정

* #7 fix: 버킷 이름 수정

* #7 fix: deploy 이름 삭제

- 버킷 이름에 /를 지정할 수 없음

* #16 feat: 포트폴리오 목록 조회 구현

* #16 feat: 포트폴리오 목록 조회 페이징 구현

* #16 feat: 포트폴리오 목록 조회시 hasNext를 응답하도록 구현

- nextCursor가 null인 경우 hasNext는 false로 응답하도록 구현하였습니다.

* #18 feat: 포트폴리오 종목 추가 서비스 구현

* #18 feat: 포트폴리오 종목 삭제 서비스 구현

* #18 style: 코드 정리

* [feat] 종목 검색 구현 (#45)

* [feat] 포트폴리오 추가 서비스 구현 (#32)

* #2 feat: 프로젝트 초기화 (#12)

* #6 chore: jwt 관련 라이브러리 추가

* #6 docs: gitignore에 푸시하지 말아야할 파일들 추가

* #6 docs: 로컬 환경 docker-compose.yml 추가

* #2 docs: applicatoin.yml 파일 설정 및 로그백 파일 추가

* #6 feat: 회원 엔티티 구현

* #6 feat: 에러관련 코드, 예외, 핸들러 추가

* #6 feat: 소셜 로그인 서비스 구현

* #6 rename: oauth 파일 이동

* #6 feat: Oauth 로그인 서비스 구현

* #6 feat: 로그아웃 및 액세스 토큰 갱신 구현

* [feat] 소셜 로그인 및 로그아웃 서비스 구현 (#14)

* #6 chore: jwt 관련 라이브러리 추가

* #6 docs: gitignore에 푸시하지 말아야할 파일들 추가

* #6 docs: 로컬 환경 docker-compose.yml 추가

* #2 docs: applicatoin.yml 파일 설정 및 로그백 파일 추가

* #6 feat: 회원 엔티티 구현

* #6 feat: 에러관련 코드, 예외, 핸들러 추가

* #6 feat: 소셜 로그인 서비스 구현

* #6 rename: oauth 파일 이동

* #6 feat: Oauth 로그인 서비스 구현

* #6 feat: 로그아웃 및 액세스 토큰 갱신 구현

* #9 feat: 한국투자 증권 open api 연결

* #9 test: 한국투자 증권 open api 연결 테스트 작성

* #9 feat: 실시간 체결가 웹소켓 연결 구현

* #9 feat: stomp 추가

* #10 feat: 종목 엔티티 구현

* #15 feat: 포트폴리오 엔티티 구현

* #15 feat: 포트폴리오 엔티티 구현

* #15 feat: 포트폴리오 추가 서비스 구현

* #15 test: 포트롤리오 추가 서비스 테스트 추가

* #15 test: 포트폴리오 추가 컨트롤러 테스트 코드 작성

* #15 test: 포트폴리오 추가 입력형식 테스트 코드 추가

* #15 feat: 포트폴리오 추가시 동일한 이름 중복 검증 처리

* #15 test: 포트폴리오 추가시 동일한 이름 중복 검증 처리 테스트 코드 작성

* [feat] 포트폴리오 수정 및 삭제 서비스 구현 (#33)

* #2 feat: 프로젝트 초기화 (#12)

* #6 chore: jwt 관련 라이브러리 추가

* #6 docs: gitignore에 푸시하지 말아야할 파일들 추가

* #6 docs: 로컬 환경 docker-compose.yml 추가

* #2 docs: applicatoin.yml 파일 설정 및 로그백 파일 추가

* #6 feat: 회원 엔티티 구현

* #6 feat: 에러관련 코드, 예외, 핸들러 추가

* #6 feat: 소셜 로그인 서비스 구현

* #6 rename: oauth 파일 이동

* #6 feat: Oauth 로그인 서비스 구현

* #6 feat: 로그아웃 및 액세스 토큰 갱신 구현

* [feat] 소셜 로그인 및 로그아웃 서비스 구현 (#14)

* #6 chore: jwt 관련 라이브러리 추가

* #6 docs: gitignore에 푸시하지 말아야할 파일들 추가

* #6 docs: 로컬 환경 docker-compose.yml 추가

* #2 docs: applicatoin.yml 파일 설정 및 로그백 파일 추가

* #6 feat: 회원 엔티티 구현

* #6 feat: 에러관련 코드, 예외, 핸들러 추가

* #6 feat: 소셜 로그인 서비스 구현

* #6 rename: oauth 파일 이동

* #6 feat: Oauth 로그인 서비스 구현

* #6 feat: 로그아웃 및 액세스 토큰 갱신 구현

* #9 feat: 한국투자 증권 open api 연결

* #9 test: 한국투자 증권 open api 연결 테스트 작성

* #9 feat: 실시간 체결가 웹소켓 연결 구현

* #9 feat: stomp 추가

* #10 feat: 종목 엔티티 구현

* #15 feat: 포트폴리오 엔티티 구현

* #15 feat: 포트폴리오 엔티티 구현

* #15 feat: 포트폴리오 추가 서비스 구현

* #15 test: 포트롤리오 추가 서비스 테스트 추가

* #15 test: 포트폴리오 추가 컨트롤러 테스트 코드 작성

* #15 test: 포트폴리오 추가 입력형식 테스트 코드 추가

* #15 feat: 포트폴리오 추가시 동일한 이름 중복 검증 처리

* #15 test: 포트폴리오 추가시 동일한 이름 중복 검증 처리 테스트 코드 작성

* #17 feat: 포트폴리오 수정 및 삭제 서비스 구현

* #17 test: 포트폴리오 수정 및 삭제에 대한 테스트 코드 작성

* #17 style: 코드 정리

* [feat] CI/CD 설정 (#35)

* #7 docs: cicd 워크플로우 설정

- 빌드 설정 및 s3 업로드 설정

* #7 docs: cicd 설정

* #7 fix: appspec.yml 파일 오타 수정

* #7 fix: appspec.yml 파일 오타 수정

* #7 fix: 버킷 이름 수정

* #7 fix: deploy 이름 삭제

- 버킷 이름에 /를 지정할 수 없음

* #16 feat: 포트폴리오 목록 조회 구현

* #16 feat: 포트폴리오 목록 조회 페이징 구현

* #16 feat: 포트폴리오 목록 조회시 hasNext를 응답하도록 구현

- nextCursor가 null인 경우 hasNext는 false로 응답하도록 구현하였습니다.

* #18 feat: 포트폴리오 종목 추가 서비스 구현

* #18 feat: 포트폴리오 종목 삭제 서비스 구현

* #18 style: 코드 정리

* #21 feat: 엘라스틱 서치 환경 구현

* #21 feat: 종목 검색 구현

* [feat] 포스트맨 변경 사항 반영 (#48)

* #48 fix: 포스트맨에 맞추어 응답 형식 변경

* #48 style: 코드 정리

* [feat] 포트폴리오 종목 조회 구현 (#49)

* #10 feat: 포트폴리오 종목 목록 조회 구현

* #10 feat: @JsonUnWraaped 적용

* [feat] ci/cd 파이프라인 개선 (#55)

* #51 fix: cicd 개선

- docker 추가

* #51 fix: cicd 테스트 브랜치 추가

* #10 feat: getFile -> getInputStream으로 변경

* #10 feat: 엘라스틱 서치 코드 제거 및 REST API 검색 구현

* #10 feat: 엘라스틱 서치 컨테이너 제거

* #10 chore: 엘라스틱 서치 의존성 제거

* #51 fix: 경로 변경

* [fix] 포스트맨 변경 사항 반영 (#56)

* #54 fix: postman 변경사항 반영

* #54 fix: postman 변경사항 반영

* [feat] 매입 이력 추가 서비스 구현 (#58)

* #19 feat: 매입 입력 추가 서비스 구현

* #19 test: 매입 입력 추가 서비스 테스트 코드 추가

* [feat] 매입 이력 수정 및 삭제 서비스 구현 (#61)

* #20 feat: 매입 입력 수정 서비스 구현 및 테스트 구현

* #20 docs: 샘플 데이터 추가

* #20 feat: 매입 이력 삭제 서비스 구현 및 테스트 코드 작성

* #20 feat: 포트폴리오 손익 내역 기록 서비스 구현

* #62 fix: 포트폴리오 목록 조회 응답에 securitiesFirm 프로퍼티 추가 (#63)

* #41 feat: 포트폴리오 수익 내역 서비스 구현

* [feat] 포트폴리오 손익 내역 기록 서비스 구현 (#65)

* #20 feat: 포트폴리오 손익 내역 기록 서비스 구현

* #41 feat: 포트폴리오 수익 내역 서비스 구현

* #41 fix: 포트폴리오 상세 조회시 securitiesFirm 프로퍼티 추가

* [feat] 포트폴리오 수익 내역 추가 서비스 구현 (#66)

* #20 feat: 포트폴리오 손익 내역 기록 서비스 구현

* #41 feat: 포트폴리오 수익 내역 서비스 구현

* #41 fix: 포트폴리오 상세 조회시 securitiesFirm 프로퍼티 추가

* #68 feat: 포트폴리오 상세 조회시 매입 내역 목록 조회할 수 있도록 구현

* [feat] 매입 내역 목록 조회 구현 (#69)

* #20 feat: 포트폴리오 손익 내역 기록 서비스 구현

* #41 feat: 포트폴리오 수익 내역 서비스 구현

* #41 fix: 포트폴리오 상세 조회시 securitiesFirm 프로퍼티 추가

* #68 feat: 포트폴리오 상세 조회시 매입 내역 목록 조회할 수 있도록 구현

* #68 feat: 포트폴리오 상세 조회시 알림에 대한 설정을 응답하도록 추가

* #68 feat: 포트폴리오 상세 조회시 총손익 공식 개선

* #68 feat: 주식 현재가 시세 클라이언트와 연결 구현

* [refactor] kis 서버 액세스 토큰 발급 만료 문제 해결 (#79)

* #75 feat: 실시간 포트폴리오 계산 데이터 응답 구현

* #75 refactor: accessToken 만료 개선

* [fix] 주식 현재가가 0인 경우 비동기적으로 수행되는 문제 해결 (#81)

* #75 feat: 실시간 포트폴리오 계산 데이터 응답 구현

* #75 refactor: accessToken 만료 개선

* #75 style: 불필요 코드 삭제

* #75 fix: 주식 현재가의 비동기적 실행 문제 해결

* #75 fix: 포트폴리오 목록 조회 문제 해결

* #75 fix: 병렬 스트림으로 변경

* #75 fix: 포트폴리오 상세 조회 API 개선

* #75 fix: 도커 컴포즈 빌드 명령어 추가

* #83 feat: 포트폴리오 구독 세션 연결 종료시 포트폴리오 구독 해시맵에서 제거하도록 구현

* #83 fix: 중복된 리스너 제거

* #98 feat: 포트폴리오 추가시 응답으로 portfolioId 응답하도록 구현 (#99)

* [feat] 배당금 데이터 초기화 구현 (#103)

* #98 feat: 포트폴리오 추가시 응답으로 portfolioId 응답하도록 구현

* #101 feat: 배당금 데이터 초기화 구현

* [feat] 포트폴리오 상세 조회시 배당금 데이터를 응답하도록 구현 (#104)

* #98 feat: 포트폴리오 추가시 응답으로 portfolioId 응답하도록 구현

* #101 feat: 배당금 데이터 초기화 구현

* #101 feat: 배당금 계산 데이터 개선

* #101 test: 포트폴리오 종목 상세 조회 테스트 코드 작성

* #101 feat: 포트폴리오 종목 상세 조회시 배당금 정보도 응답하도록 구현

* #22 fix: cors 설정

* #22 fix: @EnableWebMvc 제거

* #22 fix: @EnableWebMvc 제거

* #22 fix: corsFilter 추가

* #22 refactor: 주식 현재가 구독-발행 변경

- 기존 각각의 currentPrice 구독이 아닌 포트폴리오 단위로 변경

* #22 feat: 웹소켓 엔드포인트 연결 url 변경

- stock -> portfolio

* #121 fix: 브로드캐스팅 오타 수정

* #121 refactor: PortfolioSubscriptionManager 추가

* #121 refactor: publishPortfolioDetail 일반 메소드 개선

- CompleteFuture를 이용하여 비동기로 개선

* #121 refactor: publishPortfolioDetail 스케줄링 메소드 개선

- CompleteFuture를 이용하여 비동기적으로 수행하게 함
  • Loading branch information
yonghwankim-dev authored Nov 2, 2023
1 parent a41d308 commit 85af276
Show file tree
Hide file tree
Showing 14 changed files with 214 additions and 62 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@
import java.util.Optional;

import org.springframework.data.jpa.repository.JpaRepository;

import codesquad.fineants.domain.portfolio.Portfolio;
import org.springframework.data.jpa.repository.Query;

public interface PortfolioGainHistoryRepository extends JpaRepository<PortfolioGainHistory, Long> {
@Query("select p from PortfolioGainHistory p where p.portfolio.id = :portfolioId and p.createAt <= :createAt order by p.createAt desc")
Optional<PortfolioGainHistory> findFirstByPortfolioAndCreateAtIsLessThanEqualOrderByCreateAtDesc(
Portfolio portfolio, LocalDateTime createAt);
Long portfolioId, LocalDateTime createAt);
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,12 @@
import org.springframework.messaging.handler.annotation.DestinationVariable;
import org.springframework.messaging.handler.annotation.MessageMapping;
import org.springframework.messaging.handler.annotation.Payload;
import org.springframework.messaging.handler.annotation.SendTo;
import org.springframework.messaging.simp.SimpMessageHeaderAccessor;
import org.springframework.web.bind.annotation.RestController;

import codesquad.fineants.spring.api.kis.request.MessageData;
import codesquad.fineants.spring.api.portfolio_stock.response.PortfolioHoldingsResponse;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;

Expand All @@ -18,14 +20,19 @@ public class KisMessageController {
private final KisService kisService;

@MessageMapping("/portfolio/{portfolioId}")
public void portfolioHolding(
@SendTo("/portfolio/{portfolioId}")
public PortfolioHoldingsResponse publishPortfolioSubscription(
@DestinationVariable Long portfolioId,
@Payload MessageData messageData,
SimpMessageHeaderAccessor headerAccessor) {
log.info("portfolioId : {}, messageData : {}, sessionid : {}", portfolioId, messageData,
headerAccessor.getSessionId());
kisService.addTickerSymbols(messageData.getTickerSymbols());
kisService.addPortfolioSubscription(headerAccessor.getSessionId(),
new PortfolioSubscription(portfolioId, messageData.getTickerSymbols()));
return kisService.publishPortfolioDetail(portfolioId)
.exceptionally(e -> {
log.error(e.getMessage(), e);
return null;
}).join();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,9 @@
import java.time.LocalDateTime;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
Expand All @@ -25,6 +24,7 @@
import codesquad.fineants.spring.api.kis.client.KisClient;
import codesquad.fineants.spring.api.kis.manager.CurrentPriceManager;
import codesquad.fineants.spring.api.kis.manager.KisAccessTokenManager;
import codesquad.fineants.spring.api.kis.manager.PortfolioSubscriptionManager;
import codesquad.fineants.spring.api.kis.response.CurrentPriceResponse;
import codesquad.fineants.spring.api.portfolio_stock.PortfolioStockService;
import codesquad.fineants.spring.api.portfolio_stock.response.PortfolioHoldingsResponse;
Expand All @@ -36,53 +36,65 @@
@Service
public class KisService {
private static final String SUBSCRIBE_PORTFOLIO_HOLDING_FORMAT = "/sub/portfolio/%d";
private static final Map<String, PortfolioSubscription> portfolioSubscriptions = new ConcurrentHashMap<>();
private static final ScheduledExecutorService executorService = Executors.newScheduledThreadPool(5);

private final KisClient kisClient;
private final PortfolioRepository portfolioRepository;
private final SimpMessagingTemplate messagingTemplate;
private final PortfolioStockService portfolioStockService;
private final KisAccessTokenManager manager;
private final CurrentPriceManager currentPriceManager;
private final PortfolioSubscriptionManager portfolioSubscriptionManager;
private final Executor portfolioDetailExecutor = Executors.newFixedThreadPool(100, r -> {
Thread thread = new Thread(r);
thread.setDaemon(true);
return thread;
});

// 제약조건 : kis 서버에 1초당 최대 5건, TR간격 0.1초 이하면 안됨
public CurrentPriceResponse readRealTimeCurrentPrice(String tickerSymbol) {
Map<String, String> output = (Map<String, String>)kisClient.readRealTimeCurrentPrice(tickerSymbol,
manager.createAuthorization()).get("output");
long currentPrice = Long.parseLong(output.get("stck_prpr"));

long currentPrice = kisClient.readRealTimeCurrentPrice(tickerSymbol, manager.createAuthorization());
log.info("tickerSymbol={}, currentPrice={}, time={}", tickerSymbol, currentPrice, LocalDateTime.now());
return new CurrentPriceResponse(tickerSymbol, currentPrice);
}

public void addPortfolioSubscription(String sessionId, PortfolioSubscription subscription) {
addTickerSymbols(subscription.getTickerSymbols());
portfolioSubscriptionManager.addPortfolioSubscription(sessionId, subscription);
}

public void addTickerSymbols(List<String> tickerSymbols) {
tickerSymbols.stream()
.filter(tickerSymbol -> !currentPriceManager.hasKey(tickerSymbol))
.forEach(currentPriceManager::addKey);
}

public void addPortfolioSubscription(String sessionId, PortfolioSubscription subscription) {
if (sessionId == null) {
return;
}
portfolioSubscriptions.put(sessionId, subscription);
}

public void removePortfolioSubscription(String sessionId) {
PortfolioSubscription delSubscription = portfolioSubscriptions.remove(sessionId);
log.info("포트폴리오 구독 삭제 : {}", delSubscription);
portfolioSubscriptionManager.removePortfolioSubscription(sessionId);
}

@Scheduled(fixedRate = 5, timeUnit = TimeUnit.SECONDS)
public void publishPortfolioDetail() {
portfolioSubscriptions.values().stream()
List<CompletableFuture<PortfolioHoldingsResponse>> futures = portfolioSubscriptionManager.values()
.parallelStream()
.filter(this::hasAllCurrentPrice)
.forEach(subscription -> {
PortfolioHoldingsResponse response = portfolioStockService.readMyPortfolioStocks(
subscription.getPortfolioId());
messagingTemplate.convertAndSend(
String.format(SUBSCRIBE_PORTFOLIO_HOLDING_FORMAT, subscription.getPortfolioId()), response);
});
.map(PortfolioSubscription::getPortfolioId)
.map(portfolioId -> CompletableFuture.supplyAsync(
() -> portfolioStockService.readMyPortfolioStocks(portfolioId), portfolioDetailExecutor))
.collect(Collectors.toList());

futures.parallelStream()
.map(CompletableFuture::join)
.forEach(response -> messagingTemplate.convertAndSend(
String.format(SUBSCRIBE_PORTFOLIO_HOLDING_FORMAT, response.getPortfolioId()), response));
}

public CompletableFuture<PortfolioHoldingsResponse> publishPortfolioDetail(Long portfolioId) {
return CompletableFuture.supplyAsync(() ->
portfolioSubscriptionManager.getPortfolioSubscription(portfolioId)
.map(PortfolioSubscription::getPortfolioId)
.map(portfolioStockService::readMyPortfolioStocks)
.orElse(null));
}

private boolean hasAllCurrentPrice(PortfolioSubscription subscription) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ public Map<String, Object> accessToken() {
);
}

public Map<String, Object> readRealTimeCurrentPrice(String tickerSymbol, String authorization) {
public long readRealTimeCurrentPrice(String tickerSymbol, String authorization) {
MultiValueMap<String, String> headerMap = new LinkedMultiValueMap<>();
log.info("authorization : {}", authorization);
headerMap.add("authorization", authorization);
Expand All @@ -86,9 +86,9 @@ public Map<String, Object> readRealTimeCurrentPrice(String tickerSymbol, String
queryParamMap.add("fid_cond_mrkt_div_code", "J");
queryParamMap.add("fid_input_iscd", tickerSymbol);

return getPerform(currentPrice,
headerMap,
queryParamMap);
Map<String, Object> responseMap = getPerform(currentPrice, headerMap, queryParamMap);
Map<String, String> output = (Map<String, String>)responseMap.get("output");
return Long.parseLong(output.get("stck_prpr"));
}

private Map<String, Object> getPerform(String uri, MultiValueMap<String, String> headerMap,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package codesquad.fineants.spring.api.kis.manager;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.ConcurrentHashMap;

import org.springframework.stereotype.Component;

import codesquad.fineants.spring.api.kis.PortfolioSubscription;
import lombok.extern.slf4j.Slf4j;

@Slf4j
@Component
public class PortfolioSubscriptionManager {
private static final Map<String, PortfolioSubscription> portfolioSubscriptions = new ConcurrentHashMap<>();

public void addPortfolioSubscription(String sessionId, PortfolioSubscription subscription) {
if (sessionId == null) {
return;
}
PortfolioSubscription sub = portfolioSubscriptions.put(sessionId, subscription);
log.info("포트폴리오 구독 추가 : portfolioSubscription={}, ", sub);
}

public void removePortfolioSubscription(String sessionId) {
PortfolioSubscription delSubscription = portfolioSubscriptions.remove(sessionId);
log.info("포트폴리오 구독 삭제 : {}", delSubscription);
}

public Optional<PortfolioSubscription> getPortfolioSubscription(Long portfolioId) {
return portfolioSubscriptions.values().stream()
.filter(subscription -> subscription.getPortfolioId().equals(portfolioId))
.findAny();
}

public List<PortfolioSubscription> values() {
return new ArrayList<>(portfolioSubscriptions.values());
}

public int size() {
return portfolioSubscriptions.size();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,7 @@ public PortfoliosResponse readMyAllPortfolio(AuthMember authMember, int size, Lo
.collect(Collectors.toMap(
portfolio -> portfolio,
portfolio -> portfolioGainHistoryRepository.findFirstByPortfolioAndCreateAtIsLessThanEqualOrderByCreateAtDesc(
portfolio, LocalDateTime.now()).orElseGet(PortfolioGainHistory::empty)
portfolio.getId(), LocalDateTime.now()).orElseGet(PortfolioGainHistory::empty)
));

ScrollPaginationCollection<Portfolio> portfoliosCursor = ScrollPaginationCollection.of(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,7 @@ public PortfolioGainHistoryCreateResponse addPortfolioGainHistory() {
for (Portfolio portfolio : portfolios) {
portfolio.changeCurrentPriceFromHoldings(currentPriceManager);
PortfolioGainHistory latestHistory = repository.findFirstByPortfolioAndCreateAtIsLessThanEqualOrderByCreateAtDesc(
portfolio, LocalDateTime.now()).orElseGet(PortfolioGainHistory::empty);
// TODO: 실시간 주식 시세 문제 해결
portfolio.getId(), LocalDateTime.now()).orElseGet(PortfolioGainHistory::empty);
PortfolioGainHistory history = portfolio.createPortfolioGainHistory(latestHistory);
portfolioGainHistories.add(repository.save(history));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ public PortfolioHoldingsResponse readMyPortfolioStocks(Long portfolioId) {
log.info("portfolioHoldings : {}", portfolioHoldings);

PortfolioGainHistory latestHistory = portfolioGainHistoryRepository.findFirstByPortfolioAndCreateAtIsLessThanEqualOrderByCreateAtDesc(
portfolio, LocalDateTime.now())
portfolio.getId(), LocalDateTime.now())
.orElseGet(PortfolioGainHistory::empty);
return PortfolioHoldingsResponse.of(portfolio, latestHistory, portfolioHoldings);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,12 @@
import codesquad.fineants.domain.portfolio_gain_history.PortfolioGainHistory;
import lombok.AccessLevel;
import lombok.Builder;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;

@Slf4j
public class PortfolioDetailResponse {
@Getter
private Long id;
private String securitiesFirm;
private String name;
Expand Down Expand Up @@ -77,9 +79,10 @@ public static PortfolioDetailResponse from(Portfolio portfolio, PortfolioGainHis
.totalAnnualDividendYield(portfolio.calculateTotalAnnualDividendYield())
.annualInvestmentDividendYield(portfolio.calculateAnnualInvestmentDividendYield())
.provisionalLossBalance(0L)
.targetGainNotification(false)
.maxLossNotification(false)
.targetGainNotification(portfolio.getTargetGainIsActive())
.maxLossNotification(portfolio.getMaximumIsActive())
.build();
}

}

Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,8 @@ public static PortfolioHoldingsResponse of(Portfolio portfolio, PortfolioGainHis
.collect(Collectors.toList());
return new PortfolioHoldingsResponse(portfolioDetailResponse, portfolioStockItems);
}

public Long getPortfolioId() {
return portfolioDetails.getId();
}
}

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ void findFirstByCreateAtIsLessThanEqualOrderByCreateAtDesc() {

// when
PortfolioGainHistory result = repository.findFirstByPortfolioAndCreateAtIsLessThanEqualOrderByCreateAtDesc(
portfolio, LocalDateTime.now()).orElseThrow();
portfolio.getId(), LocalDateTime.now()).orElseThrow();

// then
assertThat(result).extracting("currentValuation").isEqualTo(120000L);
Expand Down
Loading

0 comments on commit 85af276

Please sign in to comment.