mirror of
https://github.com/Kevsl/crypto-exchange-api.git
synced 2026-02-09 19:26:13 +01:00
testing all features
This commit is contained in:
1
src/trade/dto/index.ts
Normal file
1
src/trade/dto/index.ts
Normal file
@@ -0,0 +1 @@
|
||||
export * from './trade.dto';
|
||||
48
src/trade/dto/trade.dto.ts
Normal file
48
src/trade/dto/trade.dto.ts
Normal file
@@ -0,0 +1,48 @@
|
||||
import { ApiProperty } from '@nestjs/swagger';
|
||||
import { IsDecimal, IsNotEmpty, IsString } from 'class-validator';
|
||||
export class TradeDto {
|
||||
@ApiProperty({
|
||||
type: String,
|
||||
description: 'UUID of the user that hold tokens before trade',
|
||||
example: '121212-DSDZ1-21212DJDZ-31313',
|
||||
})
|
||||
@IsNotEmpty()
|
||||
@IsString()
|
||||
id_giver: string;
|
||||
|
||||
@ApiProperty({
|
||||
type: String,
|
||||
description: 'UUID of the user that will receive tokens after trade',
|
||||
example: '121212-DSDZ1-21212DJDZ-31313',
|
||||
})
|
||||
@IsNotEmpty()
|
||||
@IsString()
|
||||
id_receiver: string;
|
||||
|
||||
@ApiProperty({
|
||||
type: String,
|
||||
description: 'UUID of the crypto traded',
|
||||
example: '121212-DSDZ1-21212DJDZ-31313',
|
||||
})
|
||||
@IsNotEmpty()
|
||||
@IsString()
|
||||
id_crypto: string;
|
||||
|
||||
@ApiProperty({
|
||||
type: Number,
|
||||
description: 'Amount of tokens traded ',
|
||||
example: 2,
|
||||
})
|
||||
@IsNotEmpty()
|
||||
@IsDecimal()
|
||||
amount_traded: number;
|
||||
|
||||
@ApiProperty({
|
||||
type: String,
|
||||
description: 'Offer UUID ',
|
||||
example: '121212-DSDZ1-21212DJDZ-31313',
|
||||
})
|
||||
@IsNotEmpty()
|
||||
@IsDecimal()
|
||||
id_offer: string;
|
||||
}
|
||||
58
src/trade/trade.controller.ts
Normal file
58
src/trade/trade.controller.ts
Normal file
@@ -0,0 +1,58 @@
|
||||
/* eslint-disable prettier/prettier */
|
||||
import {
|
||||
Body,
|
||||
Controller,
|
||||
Delete,
|
||||
Get,
|
||||
HttpCode,
|
||||
HttpStatus,
|
||||
Param,
|
||||
Patch,
|
||||
Post,
|
||||
UseGuards,
|
||||
} from '@nestjs/common';
|
||||
import { GetUser } from '../auth/decorator';
|
||||
import { ApiTags } from '@nestjs/swagger';
|
||||
import { User } from '@prisma/client';
|
||||
import { TradeService } from './trade.service';
|
||||
import { TradeDto } from './dto';
|
||||
import { JwtGuard } from 'src/auth/guard';
|
||||
|
||||
@UseGuards(JwtGuard)
|
||||
@ApiTags('trade')
|
||||
@Controller('trade')
|
||||
export class TradeController {
|
||||
constructor(private tradeService: TradeService) {}
|
||||
|
||||
@Get('/all')
|
||||
getAllPromoCodes(@GetUser() user: User) {
|
||||
return this.tradeService.getTrades(user.id);
|
||||
}
|
||||
|
||||
@HttpCode(HttpStatus.CREATED)
|
||||
@Post('/create')
|
||||
createPromoCode(
|
||||
// @GetUser() user: User,
|
||||
@Body()
|
||||
dto: TradeDto,
|
||||
@GetUser() user: User
|
||||
) {
|
||||
return this.tradeService.createTrade(user.id, dto);
|
||||
}
|
||||
|
||||
@HttpCode(HttpStatus.OK)
|
||||
@Patch('/update/:id')
|
||||
editPromoCodeById(
|
||||
@Param('id') promoCodeId: string,
|
||||
@Body() dto: TradeDto,
|
||||
@GetUser() user: User
|
||||
) {
|
||||
return this.tradeService.editTradeById(user.id, promoCodeId, dto);
|
||||
}
|
||||
|
||||
@HttpCode(HttpStatus.NO_CONTENT)
|
||||
@Delete('/delete/:id')
|
||||
deletePromoCodeById(@Param('id') promoCodeId: string, @GetUser() user: User) {
|
||||
return this.tradeService.deleteTradeById(user.id, promoCodeId);
|
||||
}
|
||||
}
|
||||
9
src/trade/trade.module.ts
Normal file
9
src/trade/trade.module.ts
Normal file
@@ -0,0 +1,9 @@
|
||||
import { Module } from '@nestjs/common';
|
||||
import { TradeService } from './trade.service';
|
||||
import { TradeController } from './trade.controller';
|
||||
|
||||
@Module({
|
||||
providers: [TradeService],
|
||||
controllers: [TradeController],
|
||||
})
|
||||
export class TradeModule {}
|
||||
177
src/trade/trade.service.ts
Normal file
177
src/trade/trade.service.ts
Normal file
@@ -0,0 +1,177 @@
|
||||
import { ForbiddenException, Injectable } from '@nestjs/common';
|
||||
import { PrismaService } from '../prisma/prisma.service';
|
||||
import { checkUserHasAccount, checkuserIsAdmin } from 'src/utils/checkUser';
|
||||
import { TradeDto } from './dto';
|
||||
@Injectable()
|
||||
export class TradeService {
|
||||
constructor(private prisma: PrismaService) {}
|
||||
|
||||
async getTrades(userId: string) {
|
||||
await checkuserIsAdmin(userId);
|
||||
|
||||
return this.prisma.trade.findMany({
|
||||
orderBy: {
|
||||
created_at: 'desc',
|
||||
},
|
||||
include: {
|
||||
Giver: true,
|
||||
Receiver: true,
|
||||
Crypto: true,
|
||||
},
|
||||
});
|
||||
}
|
||||
async getLastTrades() {
|
||||
return this.prisma.trade.findMany({
|
||||
orderBy: {
|
||||
created_at: 'desc',
|
||||
},
|
||||
select: {
|
||||
amount_traded: true,
|
||||
Crypto: true,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
async createTrade(userId: string, dto: TradeDto) {
|
||||
await checkUserHasAccount(userId);
|
||||
|
||||
const crypto = await this.prisma.crypto.findFirst({
|
||||
where: {
|
||||
id: dto.id_crypto,
|
||||
},
|
||||
});
|
||||
const buyer = await this.prisma.user.findFirst({
|
||||
where: {
|
||||
id: dto.id_receiver,
|
||||
},
|
||||
});
|
||||
const price = crypto.value * dto.amount_traded;
|
||||
if (buyer.dollarAvailables < price) {
|
||||
throw new ForbiddenException(
|
||||
// eslint-disable-next-line prettier/prettier
|
||||
`Acqueror ${buyer.pseudo} doesnt have enough money to make this trade`
|
||||
);
|
||||
}
|
||||
|
||||
const asset = await this.prisma.userHasCrypto.findFirst({
|
||||
where: {
|
||||
id_crypto: dto.id_crypto,
|
||||
id_user: dto.id_giver,
|
||||
},
|
||||
});
|
||||
|
||||
if (!asset || asset.amount < dto.amount_traded) {
|
||||
throw new ForbiddenException(`Seller doesnt have enough ${crypto.name} `);
|
||||
}
|
||||
|
||||
const trade = await this.prisma.trade.create({
|
||||
data: {
|
||||
id_giver: dto.id_giver,
|
||||
id_receiver: dto.id_receiver,
|
||||
id_crypto: dto.id_crypto,
|
||||
amount_traded: dto.amount_traded,
|
||||
id_offer: dto.id_offer,
|
||||
},
|
||||
});
|
||||
|
||||
const newBalanceGiver = (asset.amount -= dto.amount_traded);
|
||||
await this.prisma.userHasCrypto.update({
|
||||
where: {
|
||||
id: asset.id,
|
||||
},
|
||||
data: {
|
||||
amount: newBalanceGiver,
|
||||
},
|
||||
});
|
||||
|
||||
const receiverAssets = await this.prisma.userHasCrypto.findFirst({
|
||||
where: {
|
||||
id_user: dto.id_receiver,
|
||||
id_crypto: dto.id_crypto,
|
||||
},
|
||||
});
|
||||
if (!receiverAssets) {
|
||||
await this.prisma.userHasCrypto.create({
|
||||
data: {
|
||||
id_user: dto.id_receiver,
|
||||
id_crypto: dto.id_crypto,
|
||||
amount: dto.amount_traded,
|
||||
createdAt: new Date(),
|
||||
},
|
||||
});
|
||||
} else {
|
||||
const newBalanceReceiver = receiverAssets.amount + dto.amount_traded;
|
||||
await this.prisma.userHasCrypto.update({
|
||||
where: {
|
||||
id: receiverAssets.id,
|
||||
},
|
||||
data: {
|
||||
amount: newBalanceReceiver,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
const newValue = crypto.value * 1.1;
|
||||
|
||||
await this.prisma.crypto.update({
|
||||
where: {
|
||||
id: crypto.id,
|
||||
},
|
||||
data: {
|
||||
value: newValue,
|
||||
},
|
||||
});
|
||||
|
||||
const prevAmount = buyer.dollarAvailables;
|
||||
|
||||
await this.prisma.user.update({
|
||||
where: {
|
||||
id: dto.id_receiver,
|
||||
},
|
||||
data: {
|
||||
dollarAvailables: prevAmount - price,
|
||||
},
|
||||
});
|
||||
return trade;
|
||||
}
|
||||
|
||||
async editTradeById(userId: string, tradeId: string, dto: TradeDto) {
|
||||
await checkuserIsAdmin(userId);
|
||||
|
||||
const trade = await this.prisma.trade.findUnique({
|
||||
where: {
|
||||
id: tradeId,
|
||||
},
|
||||
});
|
||||
|
||||
if (!trade || trade.id !== tradeId)
|
||||
throw new ForbiddenException('Access to resources denied');
|
||||
|
||||
return this.prisma.trade.update({
|
||||
where: {
|
||||
id: trade.id,
|
||||
},
|
||||
data: {
|
||||
...dto,
|
||||
},
|
||||
});
|
||||
}
|
||||
async deleteTradeById(userId: string, id: string) {
|
||||
await checkuserIsAdmin(userId);
|
||||
|
||||
const trade = await this.prisma.trade.findUnique({
|
||||
where: {
|
||||
id: id,
|
||||
},
|
||||
});
|
||||
|
||||
if (!trade || trade.id !== id)
|
||||
throw new ForbiddenException('Access to resources denied');
|
||||
|
||||
await this.prisma.trade.delete({
|
||||
where: {
|
||||
id: trade.id,
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user