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] 7.03 매수 API 구현 #49 #70

Merged
merged 5 commits into from
Nov 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
2 changes: 2 additions & 0 deletions BE/src/app.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ 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 { StockOrderModule } from './stock/order/stock-order.module';
import { typeOrmConfig } from './configs/typeorm.config';

@Module({
Expand All @@ -21,6 +22,7 @@ import { typeOrmConfig } from './configs/typeorm.config';
StockIndexModule,
StockTopfiveModule,
SocketModule,
StockOrderModule,
],
controllers: [AppController],
providers: [AppService],
Expand Down
5 changes: 5 additions & 0 deletions BE/src/auth/jwt-auth-guard.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { AuthGuard } from '@nestjs/passport';
import { Injectable } from '@nestjs/common';

@Injectable()
export class JwtAuthGuard extends AuthGuard('jwt') {}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟢 오우 JwtAuthGuard를 클래스로 만들어서 사용할 수 있었네요 ..? 저는 AuthGuard('strategy 이름') 이런 식으로 사용해봤는데 가독성이나 이후 검증 로직을 추가하거나 하는데 좋을것 같네요 canActivate 함수에 원하는 로직을 넣거나 해서요

19 changes: 19 additions & 0 deletions BE/src/stock/order/dto/stock-order-request.dto.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { ApiProperty } from '@nestjs/swagger';
import { IsInt, IsNumber, IsPositive } from 'class-validator';

export class StockOrderRequestDto {
@ApiProperty({ description: '주식 id' })
@IsInt()
@IsPositive()
stock_id: number;

@ApiProperty({ description: '매수/매도 희망 가격' })
@IsNumber()
@IsPositive()
price: number;

@ApiProperty({ description: '매수/매도 희망 수량' })
@IsInt()
@IsPositive()
amount: number;
}
4 changes: 4 additions & 0 deletions BE/src/stock/order/enum/status-type.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
export enum StatusType {
PENDING = 'PENDING',
COMPLETE = 'COMPLETE',
}
4 changes: 4 additions & 0 deletions BE/src/stock/order/enum/trade-type.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
export enum TradeType {
SELL = 'SELL',
BUY = 'BUY',
}
9 changes: 9 additions & 0 deletions BE/src/stock/order/interface/request.interface.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
export interface RequestInterface {
user: {
id: number;
email: string;
password: string;
tutorial: boolean;
kakaoId: number;
};
}
42 changes: 42 additions & 0 deletions BE/src/stock/order/stock-order.controller.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import {
Body,
Controller,
Post,
Req,
UseGuards,
ValidationPipe,
} from '@nestjs/common';
import {
ApiBearerAuth,
ApiOperation,
ApiResponse,
ApiTags,
} from '@nestjs/swagger';
import { StockOrderService } from './stock-order.service';
import { StockOrderRequestDto } from './dto/stock-order-request.dto';
import { JwtAuthGuard } from '../../auth/jwt-auth-guard';
import { RequestInterface } from './interface/request.interface';

@Controller('/api/stocks/trade')
@ApiTags('주식 매수/매도 API')
export class StockOrderController {
constructor(private readonly stockTradeService: StockOrderService) {}

@Post('/buy')
@ApiBearerAuth()
@UseGuards(JwtAuthGuard)
@ApiOperation({
summary: '주식 매수 API',
description: '주식 id, 매수 가격, 수량으로 주식을 매수한다.',
})
@ApiResponse({
status: 201,
description: '주식 매수 성공',
})
async buy(
@Req() request: RequestInterface,
@Body(ValidationPipe) stockOrderRequest: StockOrderRequestDto,
) {
await this.stockTradeService.buy(request.user.id, stockOrderRequest);
}
}
46 changes: 46 additions & 0 deletions BE/src/stock/order/stock-order.entity.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import {
Column,
CreateDateColumn,
Entity,
PrimaryGeneratedColumn,
} from 'typeorm';
import { TradeType } from './enum/trade-type';
import { StatusType } from './enum/status-type';

@Entity('orders')
export class Order {
@PrimaryGeneratedColumn()
id: number;

@Column({ nullable: false })
user_id: number;

@Column({ nullable: false })
stock_id: number;

@Column({
type: 'enum',
enum: TradeType,
nullable: false,
})
trade_type: TradeType;

@Column({ nullable: false })
amount: number;

@Column({ nullable: false })
price: number;

@Column({
type: 'enum',
enum: StatusType,
nullable: false,
})
status: StatusType;

@CreateDateColumn()
created_at: Date;

@Column({ nullable: true })
completed_at?: Date;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟢 타입스크립트에서는 nullable한 값은 옵셔널로 두는게 관례인가요? 신기하네요

}
13 changes: 13 additions & 0 deletions BE/src/stock/order/stock-order.module.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { StockOrderController } from './stock-order.controller';
import { StockOrderService } from './stock-order.service';
import { Order } from './stock-order.entity';
import { StockOrderRepository } from './stock-order.repository';

@Module({
imports: [TypeOrmModule.forFeature([Order])],
controllers: [StockOrderController],
providers: [StockOrderService, StockOrderRepository],
})
export class StockOrderModule {}
11 changes: 11 additions & 0 deletions BE/src/stock/order/stock-order.repository.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { DataSource, Repository } from 'typeorm';
import { InjectDataSource } from '@nestjs/typeorm';
import { Injectable } from '@nestjs/common';
import { Order } from './stock-order.entity';

@Injectable()
export class StockOrderRepository extends Repository<Order> {
constructor(@InjectDataSource() dataSource: DataSource) {
super(Order, dataSource.createEntityManager());
}
}
23 changes: 23 additions & 0 deletions BE/src/stock/order/stock-order.service.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { Injectable } from '@nestjs/common';
import { StockOrderRequestDto } from './dto/stock-order-request.dto';
import { StockOrderRepository } from './stock-order.repository';
import { TradeType } from './enum/trade-type';
import { StatusType } from './enum/status-type';

@Injectable()
export class StockOrderService {
constructor(private readonly stockOrderRepository: StockOrderRepository) {}

async buy(userId: number, stockOrderRequest: StockOrderRequestDto) {
const order = this.stockOrderRepository.create({
user_id: userId,
stock_id: stockOrderRequest.stock_id,
trade_type: TradeType.BUY,
amount: stockOrderRequest.amount,
price: stockOrderRequest.price,
status: StatusType.PENDING,
});

await this.stockOrderRepository.save(order);
}
}
1 change: 1 addition & 0 deletions BE/src/util/swagger.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ export function setupSwagger(app: INestApplication): void {
.setTitle('Juga API')
.setDescription('Juga API 문서입니다.')
.setVersion('1.0.0')
.addBearerAuth()
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟢 처음으로 토큰이 필요한 무언가가 나왔네요.. 고생하셨습니다!!

.build();

const document = SwaggerModule.createDocument(app, options);
Expand Down
Loading