testing all features

This commit is contained in:
Kevsl
2024-06-06 16:31:31 +02:00
commit 9f5c23c7c9
74 changed files with 18541 additions and 0 deletions

1
src/trade/dto/index.ts Normal file
View File

@@ -0,0 +1 @@
export * from './trade.dto';

View 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;
}

View 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);
}
}

View 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
View 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,
},
});
}
}