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

[BE] 실제 서버 내에서 테스트를 위한 머지 #152

Closed
wants to merge 51 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
51 commits
Select commit Hold shift + click to select a range
edb326f
✨ feat: 실시간 체결가 웹소켓 연결 코드 작성#56
uuuo3o Nov 14, 2024
b266468
🔧 fix: status pending 조건 추가 #53
sieunie Nov 15, 2024
57d1174
🔧 fix: 매도/매수 체결 시 쿼리문 수정 #53
sieunie Nov 15, 2024
139bc4a
➕ add: 사용자 보유 주식 테이블 유니크 조건 추가 #53
sieunie Nov 15, 2024
b2fb455
🔧 fix: user id 로직 수정 #53
sieunie Nov 15, 2024
e81574e
➕ add: 에러 로그 추가 #53
sieunie Nov 15, 2024
e0c8c27
➕ add: 매수시 가용 자산 체크 로직 추가 #53
sieunie Nov 15, 2024
2371d93
Merge branch 'back/main' of https://github.com/boostcampwm-2024/web16…
sieunie Nov 15, 2024
3b7999d
🔧 fix: 매수시 가용 자산 체크 로직 수정 #53
sieunie Nov 15, 2024
8ae299c
🔧 fix: 매수시 보유 주식 평균가 업데이트 쿼리 수정 #53
sieunie Nov 15, 2024
e454dc2
🔧 fix: 보유 주식 평균가 타입 수정 #53
sieunie Nov 15, 2024
1e6a838
Merge branch 'dev' of https://github.com/boostcampwm-2024/web16-JuGa …
uuuo3o Nov 15, 2024
d68955b
✨ feat: 실시간 체결가 웹소켓 연결 코드 작성 및 test.html 생성#56
uuuo3o Nov 15, 2024
d1b6eef
Merge pull request #122 from boostcampwm-2024/feature/api/execute-#53
sieunie Nov 15, 2024
b34356d
Merge branch 'back/main' of https://github.com/boostcampwm-2024/web16…
uuuo3o Nov 18, 2024
43f5c1e
🔧 fix : alpha 서버 CD/CD 워크플로우 수정
jinddings Nov 18, 2024
f8b6560
🚚 rename :alpha 서버 워크플로우 rename
jinddings Nov 18, 2024
22fe6b8
Merge branch 'back/main' of https://github.com/boostcampwm-2024/web16…
jinddings Nov 18, 2024
0ed0871
✨ feat: 실시간 체결가 웹소켓 연결 코드 작성 및 test.html 생성#127
uuuo3o Nov 18, 2024
5feaf13
Merge branch 'back/main' of https://github.com/boostcampwm-2024/web16…
uuuo3o Nov 18, 2024
e15169b
🔥 remove: 불필요한 html 파일 삭제#127
uuuo3o Nov 18, 2024
279bd4b
📝 docs: swagger에 응답 타입 수정 및 불필요한 코드 삭제
uuuo3o Nov 18, 2024
03ac949
✨ feat: 모의 도메인용 함수 추가#127
uuuo3o Nov 18, 2024
5212038
✨ feat: SSE로 실시간 데이터 전송 로직 작성#127
uuuo3o Nov 18, 2024
e6cf90a
🔧 fix: cors 연결 설정에 불필요한 주소가 포함되어있던 부분 수정#127
uuuo3o Nov 18, 2024
9a4eaf2
🔧 fix: 소켓 연결 종료 시 1분 간격으로 재연결 로직 추가 #126
sieunie Nov 18, 2024
cfe7b06
Merge branch 'dev' of https://github.com/boostcampwm-2024/web16-JuGa …
jinddings Nov 18, 2024
0f3e141
🔧 fix : alpha, production ENV 분리
jinddings Nov 18, 2024
bd58ed3
Merge branch 'back/main' of https://github.com/boostcampwm-2024/web16…
uuuo3o Nov 18, 2024
4df492a
♻️ refactor: requestApi 메소드 모든 서비스에서 사용하도록 변경
sieunie Nov 18, 2024
b6ec95c
♻️ refactor: 다른 서비스에서 사용되는 서비스를 domain-service로 변경
sieunie Nov 18, 2024
52152b9
♻️ refactor: stock index controller 로직 줄이고 service로 위임
sieunie Nov 18, 2024
3e85e3d
✨ feat: 주식 종목코드도 함께 반환할 수 있도록 구현
uuuo3o Nov 18, 2024
c825569
Merge pull request #129 from boostcampwm-2024/feature/socket/stockTra…
uuuo3o Nov 19, 2024
693df66
Merge pull request #131 from boostcampwm-2024/fix/socket
uuuo3o Nov 19, 2024
df57558
Merge pull request #139 from boostcampwm-2024/refactor/api/topfive
uuuo3o Nov 19, 2024
14242bc
Merge branch 'back/main' into refactor-J188
sieunie Nov 19, 2024
dab1f7b
🔧 fix: websocket 경로 수정
sieunie Nov 19, 2024
f7b9673
🔧 fix: 불필요한 try-catch문 및 logger 삭제
sieunie Nov 19, 2024
c07c5bc
♻️ refactor: 불필요한 logger 삭제
sieunie Nov 19, 2024
405e2d3
Merge pull request #134 from boostcampwm-2024/refactor-J188
sieunie Nov 19, 2024
8d60390
🔧 fix: 매도/매수 시 종목 코드 isNotEmpty 확인 추가
sieunie Nov 19, 2024
c0d2270
Merge pull request #143 from boostcampwm-2024/fix/order
sieunie Nov 19, 2024
49edc8f
✨ feat: 주식 주문에 사용할 상한가, 하한가 추가#144
uuuo3o Nov 19, 2024
a02a4fa
Merge pull request #147 from boostcampwm-2024/feature/api/stockDetail…
uuuo3o Nov 19, 2024
22dd87d
🔧 fix : cookie를 이용한 accessToken validate(#4)
jinddings Nov 19, 2024
d4d977b
♻️ refactor : lint 오류 수정
jinddings Nov 19, 2024
328b163
🔧 fix : docker timezone 변경
jinddings Nov 19, 2024
650fdf2
🔧 fix : 명령어에서 sudo 제거
jinddings Nov 19, 2024
c7aa9ab
🔧 fix : credential 설정 추가
jinddings Nov 19, 2024
5b0200c
🔧 fix :
jinddings Nov 19, 2024
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
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,7 @@ jobs:
max-parallel: 1
matrix:
app:
[
{ name: 'be', dir: 'BE', port: 3000, container: 'juga-docker-be' },
{ name: 'fe', dir: 'FE', port: 5173, container: 'juga-docker-fe' },
]
[{ name: 'be', dir: 'BE', port: 3000, container: 'juga-docker-be' }]

steps:
- uses: actions/checkout@v4
Expand All @@ -35,11 +32,7 @@ jobs:
- name: Create .env file
run: |
touch ./${{ matrix.app.dir }}/.env
if [ "${{ matrix.app.name }}" = "be" ]; then
echo "${{ secrets.ENV }}" > ./${{matrix.app.dir}}/.env
else
echo "${{ secrets.ENV_FE }}" > ./${{matrix.app.dir}}/.env
fi
echo "${{ secrets.ENV_ALPHA }}" > ./${{matrix.app.dir}}/.env

- name: Install dependencies
working-directory: ./${{matrix.app.dir}}
Expand Down Expand Up @@ -108,12 +101,7 @@ jobs:
port: 22
script: |
docker system prune -af
if [ "${{ matrix.app.name }}" = "be" ]; then
echo "${{ secrets.ENV }}" > .env
else
echo "${{ secrets.ENV_FE }}" > .env
fi

echo "${{ secrets.ENV_ALPHA }}" > .env

docker network create juga-network || true

Expand Down
1 change: 1 addition & 0 deletions BE/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ WORKDIR /var/app
COPY package*.json ./
RUN npm install --only=production
COPY --from=builder /app/dist ./dist
RUN ln -snf /usr/share/zoneinfo/Asia/Seoul /etc/localtime

EXPOSE 3000
CMD ["node", "dist/main.js"]
4 changes: 2 additions & 2 deletions BE/src/app.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ import { AppService } from './app.service';
import { AuthModule } from './auth/auth.module';
import { StockIndexModule } from './stock/index/stock-index.module';
import { StockTopfiveModule } from './stock/topfive/stock-topfive.module';
import { KoreaInvestmentModule } from './koreaInvestment/korea-investment.module';
import { SocketModule } from './websocket/socket.module';
import { KoreaInvestmentModule } from './common/koreaInvestment/korea-investment.module';
import { SocketModule } from './common/websocket/socket.module';
import { StockOrderModule } from './stock/order/stock-order.module';
import { StockDetailModule } from './stock/detail/stock-detail.module';
import { typeOrmConfig } from './configs/typeorm.config';
Expand Down
8 changes: 1 addition & 7 deletions BE/src/auth/auth.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,18 +38,12 @@ export class AuthController {
const { accessToken, refreshToken } =
await this.authService.loginUser(authCredentialsDto);

res.cookie('accessToken', accessToken, { httpOnly: true });
res.cookie('refreshToken', refreshToken, { httpOnly: true });
res.cookie('isRefreshToken', true, { httpOnly: true });
return res.status(200).json({ accessToken });
}

@ApiOperation({ summary: 'Token 인증 테스트 API' })
@Get('/test')
@UseGuards(AuthGuard('jwt'))
test(@Req() req: Request) {
return req;
}

@ApiOperation({ summary: 'Kakao 로그인 API' })
@Get('/kakao')
@UseGuards(AuthGuard('kakao'))
Expand Down
26 changes: 23 additions & 3 deletions BE/src/auth/strategy/jwt.strategy.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,26 @@
import { PassportStrategy } from '@nestjs/passport';
import { InjectRepository } from '@nestjs/typeorm';
import { ExtractJwt, Strategy } from 'passport-jwt';
import { Strategy } from 'passport-jwt';
import { Injectable, UnauthorizedException } from '@nestjs/common';
import { ConfigService } from '@nestjs/config';
import { Request } from 'express';
import { UserRepository } from '../user.repository';
import { User } from '../user.entity';

interface RequestWithCookies extends Request {
cookies: {
accessToken?: string;
[key: string]: string | undefined;
};
}

function extractJWTFromCookie(req: RequestWithCookies): string | null {
if (req.cookies && 'accessToken' in req.cookies) {
return req.cookies.accessToken;
}
return null;
}

@Injectable()
export class JwtStrategy extends PassportStrategy(Strategy) {
constructor(
Expand All @@ -14,11 +29,16 @@ export class JwtStrategy extends PassportStrategy(Strategy) {
) {
super({
secretOrKey: configService.get<string>('JWT_SECRET'),
jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
jwtFromRequest: extractJWTFromCookie,
});
}

async validate(payload) {
async validate(payload: { email: string }): Promise<{
userId: number;
email: string;
tutorial: boolean;
kakaoId: string | null;
}> {
const { email } = payload;
const user: User = await this.userRepository.findOne({ where: { email } });
if (!user) throw new UnauthorizedException();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import axios from 'axios';
import { UnauthorizedException } from '@nestjs/common';
import { getFullURL } from '../util/get-full-URL';
import { getFullURL } from '../../util/get-full-URL';
import { AccessTokenInterface } from './interface/korea-investment.interface';
import { getHeader } from '../../util/get-header';

export class KoreaInvestmentService {
export class KoreaInvestmentDomainService {
private accessToken: string;
private tokenExpireTime: Date;

Expand All @@ -29,4 +30,30 @@ export class KoreaInvestmentService {

return this.accessToken;
}

/**
* @private 한국투자 Open API - API 호출용 공통 함수
* @param {string} trId - API 호출에 사용할 tr_id
* @param {string} apiURL - API 호출에 사용할 URL
* @param {Record<string, string>} params - API 요청 시 필요한 쿼리 파라미터 DTO
* @returns - API 호출에 대한 응답 데이터
*
* @author uuuo3o
*/
async requestApi<T>(
trId: string,
apiURL: string,
params: Record<string, string>,
): Promise<T> {
const accessToken = await this.getAccessToken();
const headers = getHeader(accessToken, trId);
const url = getFullURL(apiURL);

const response = await axios.get<T>(url, {
headers,
params,
});

return response.data;
}
}
10 changes: 10 additions & 0 deletions BE/src/common/koreaInvestment/korea-investment.module.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { Module } from '@nestjs/common';
import { KoreaInvestmentDomainService } from './korea-investment.domain-service';

@Module({
imports: [],
controllers: [],
providers: [KoreaInvestmentDomainService],
exports: [KoreaInvestmentDomainService],
})
export class KoreaInvestmentModule {}
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@ import {
Logger,
OnModuleInit,
} from '@nestjs/common';
import { SocketTokenService } from './socket-token.service';
import { SocketTokenDomainService } from './socket-token.domain-service';

@Injectable()
export class BaseSocketService implements OnModuleInit {
export class BaseSocketDomainService implements OnModuleInit {
private socket: WebSocket;
private socketConnectionKey: string;
private socketOpenHandlers: (() => void | Promise<void>)[] = [];
Expand All @@ -18,11 +18,13 @@ export class BaseSocketService implements OnModuleInit {

private readonly logger = new Logger();

constructor(private readonly socketTokenService: SocketTokenService) {}
constructor(
private readonly socketTokenDomainService: SocketTokenDomainService,
) {}

async onModuleInit() {
this.socketConnectionKey =
await this.socketTokenService.getSocketConnectionKey();
await this.socketTokenDomainService.getSocketConnectionKey();
this.socket = new WebSocket(process.env.KOREA_INVESTMENT_SOCKET_URL);

this.socket.onopen = () => {
Expand Down Expand Up @@ -63,6 +65,11 @@ export class BaseSocketService implements OnModuleInit {

this.socket.onclose = () => {
this.logger.warn(`한국투자증권 소켓 연결 종료`);
setTimeout(() => {
this.onModuleInit().catch((err) => {
throw new InternalServerErrorException(err);
});
}, 60000);
};
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import axios from 'axios';
import { SocketConnectTokenInterface } from './interface/socket.interface';
import { getFullURL } from '../util/get-full-URL';
import { getFullURL } from '../../util/get-full-URL';

export class SocketTokenService {
export class SocketTokenDomainService {
private approvalKey: string;

async getSocketConnectionKey() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,8 @@ export class SocketGateway {

this.server.emit(event, stockIndexValue);
}

sendStockTradeHistoryValueToClient(event, chartData) {
this.server.emit(event, chartData);
}
}
10 changes: 10 additions & 0 deletions BE/src/common/websocket/socket.module.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { Module } from '@nestjs/common';
import { SocketGateway } from './socket.gateway';
import { SocketTokenDomainService } from './socket-token.domain-service';
import { BaseSocketDomainService } from './base-socket.domain-service';

@Module({
providers: [SocketTokenDomainService, SocketGateway, BaseSocketDomainService],
exports: [SocketGateway, BaseSocketDomainService],
})
export class SocketModule {}
10 changes: 0 additions & 10 deletions BE/src/koreaInvestment/korea-investment.module.ts

This file was deleted.

1 change: 1 addition & 0 deletions BE/src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ async function bootstrap() {
methods: 'GET, HEAD, PUT, PATH, POST, DELETE',
preflightContinue: false,
optionsSuccessStatus: 204,
credentials: true,
});

app.use(cookieParser());
Expand Down
6 changes: 6 additions & 0 deletions BE/src/stock/detail/dto/stock-detail-response.dto.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,4 +24,10 @@ export class InquirePriceResponseDto {

@ApiProperty({ description: 'PER' })
per: string;

@ApiProperty({ description: '주식 상한가' })
stck_mxpr: string;

@ApiProperty({ description: '주식 하한가' })
stck_llam: string;
}
2 changes: 1 addition & 1 deletion BE/src/stock/detail/stock-detail.module.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { KoreaInvestmentModule } from '../../koreaInvestment/korea-investment.module';
import { KoreaInvestmentModule } from '../../common/koreaInvestment/korea-investment.module';
import { StockDetailController } from './stock-detail.controller';
import { StockDetailService } from './stock-detail.service';
import { StockDetailRepository } from './stock-detail.repository';
Expand Down
Loading
Loading