User => Player
This commit is contained in:
parent
c6da328023
commit
65576fc5b1
@ -1,14 +0,0 @@
|
||||
/*
|
||||
Warnings:
|
||||
|
||||
- Added the required column `accuracy` to the `Geolocation` table without a default value. This is not possible if the table is not empty.
|
||||
- Added the required column `altitude` to the `Geolocation` table without a default value. This is not possible if the table is not empty.
|
||||
- Added the required column `altitudeAccuracy` to the `Geolocation` table without a default value. This is not possible if the table is not empty.
|
||||
- Added the required column `speed` to the `Geolocation` table without a default value. This is not possible if the table is not empty.
|
||||
|
||||
*/
|
||||
-- AlterTable
|
||||
ALTER TABLE "Geolocation" ADD COLUMN "accuracy" DOUBLE PRECISION NOT NULL,
|
||||
ADD COLUMN "altitude" DOUBLE PRECISION NOT NULL,
|
||||
ADD COLUMN "altitudeAccuracy" DOUBLE PRECISION NOT NULL,
|
||||
ADD COLUMN "speed" DOUBLE PRECISION NOT NULL;
|
@ -1,5 +0,0 @@
|
||||
-- AlterTable
|
||||
ALTER TABLE "ChallengeAction" ADD COLUMN "end" TIMESTAMP(3),
|
||||
ADD COLUMN "penaltyEnd" TIMESTAMP(3),
|
||||
ADD COLUMN "penaltyStart" TIMESTAMP(3),
|
||||
ADD COLUMN "start" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP;
|
@ -1,12 +0,0 @@
|
||||
-- AlterTable
|
||||
ALTER TABLE "ChallengeAction" ALTER COLUMN "end" SET DATA TYPE TIMESTAMPTZ(3),
|
||||
ALTER COLUMN "penaltyEnd" SET DATA TYPE TIMESTAMPTZ(3),
|
||||
ALTER COLUMN "penaltyStart" SET DATA TYPE TIMESTAMPTZ(3),
|
||||
ALTER COLUMN "start" SET DATA TYPE TIMESTAMPTZ(3);
|
||||
|
||||
-- AlterTable
|
||||
ALTER TABLE "Geolocation" ALTER COLUMN "timestamp" SET DATA TYPE TIMESTAMPTZ(3);
|
||||
|
||||
-- AlterTable
|
||||
ALTER TABLE "TrainTrip" ALTER COLUMN "departureTime" SET DATA TYPE TIMESTAMPTZ(3),
|
||||
ALTER COLUMN "arrivalTime" SET DATA TYPE TIMESTAMPTZ(3);
|
@ -1,8 +0,0 @@
|
||||
/*
|
||||
Warnings:
|
||||
|
||||
- You are about to drop the column `geometry` on the `TrainTrip` table. All the data in the column will be lost.
|
||||
|
||||
*/
|
||||
-- AlterTable
|
||||
ALTER TABLE "TrainTrip" DROP COLUMN "geometry";
|
@ -1,13 +0,0 @@
|
||||
/*
|
||||
Warnings:
|
||||
|
||||
- You are about to drop the column `after` on the `MoneyUpdate` table. All the data in the column will be lost.
|
||||
- You are about to drop the column `before` on the `MoneyUpdate` table. All the data in the column will be lost.
|
||||
- Added the required column `amount` to the `MoneyUpdate` table without a default value. This is not possible if the table is not empty.
|
||||
|
||||
*/
|
||||
-- AlterTable
|
||||
ALTER TABLE "MoneyUpdate" DROP COLUMN "after",
|
||||
DROP COLUMN "before",
|
||||
ADD COLUMN "amount" INTEGER NOT NULL,
|
||||
ADD COLUMN "timestamp" TIMESTAMPTZ(3) NOT NULL DEFAULT CURRENT_TIMESTAMP;
|
@ -2,23 +2,27 @@
|
||||
CREATE TYPE "MoneyUpdateType" AS ENUM ('START', 'WIN_CHALLENGE', 'BUY_TRAIN');
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "User" (
|
||||
CREATE TABLE "Player" (
|
||||
"id" SERIAL NOT NULL,
|
||||
"name" TEXT NOT NULL,
|
||||
"password" TEXT NOT NULL,
|
||||
"money" INTEGER NOT NULL DEFAULT 0,
|
||||
"currentRunner" BOOLEAN NOT NULL DEFAULT false,
|
||||
|
||||
CONSTRAINT "User_pkey" PRIMARY KEY ("id")
|
||||
CONSTRAINT "Player_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "Geolocation" (
|
||||
"id" SERIAL NOT NULL,
|
||||
"userId" INTEGER NOT NULL,
|
||||
"playerId" INTEGER NOT NULL,
|
||||
"longitude" DOUBLE PRECISION NOT NULL,
|
||||
"latitude" DOUBLE PRECISION NOT NULL,
|
||||
"timestamp" TIMESTAMP(3) NOT NULL,
|
||||
"speed" DOUBLE PRECISION NOT NULL,
|
||||
"accuracy" DOUBLE PRECISION NOT NULL,
|
||||
"altitude" DOUBLE PRECISION NOT NULL,
|
||||
"altitudeAccuracy" DOUBLE PRECISION NOT NULL,
|
||||
"timestamp" TIMESTAMPTZ(3) NOT NULL,
|
||||
|
||||
CONSTRAINT "Geolocation_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
@ -36,10 +40,14 @@ CREATE TABLE "Challenge" (
|
||||
-- CreateTable
|
||||
CREATE TABLE "ChallengeAction" (
|
||||
"id" SERIAL NOT NULL,
|
||||
"userId" INTEGER NOT NULL,
|
||||
"playerId" INTEGER NOT NULL,
|
||||
"challengeId" INTEGER NOT NULL,
|
||||
"active" BOOLEAN NOT NULL DEFAULT false,
|
||||
"success" BOOLEAN NOT NULL DEFAULT false,
|
||||
"start" TIMESTAMPTZ(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"end" TIMESTAMPTZ(3),
|
||||
"penaltyStart" TIMESTAMPTZ(3),
|
||||
"penaltyEnd" TIMESTAMPTZ(3),
|
||||
|
||||
CONSTRAINT "ChallengeAction_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
@ -47,14 +55,13 @@ CREATE TABLE "ChallengeAction" (
|
||||
-- CreateTable
|
||||
CREATE TABLE "TrainTrip" (
|
||||
"id" TEXT NOT NULL,
|
||||
"userId" INTEGER NOT NULL,
|
||||
"playerId" INTEGER NOT NULL,
|
||||
"distance" DOUBLE PRECISION NOT NULL,
|
||||
"from" TEXT NOT NULL,
|
||||
"to" TEXT NOT NULL,
|
||||
"departureTime" TIMESTAMP(3) NOT NULL,
|
||||
"arrivalTime" TIMESTAMP(3) NOT NULL,
|
||||
"departureTime" TIMESTAMPTZ(3) NOT NULL,
|
||||
"arrivalTime" TIMESTAMPTZ(3) NOT NULL,
|
||||
"infoJson" JSONB NOT NULL,
|
||||
"geometry" TEXT NOT NULL,
|
||||
|
||||
CONSTRAINT "TrainTrip_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
@ -62,18 +69,18 @@ CREATE TABLE "TrainTrip" (
|
||||
-- CreateTable
|
||||
CREATE TABLE "MoneyUpdate" (
|
||||
"id" SERIAL NOT NULL,
|
||||
"userId" INTEGER NOT NULL,
|
||||
"before" INTEGER NOT NULL,
|
||||
"after" INTEGER NOT NULL,
|
||||
"playerId" INTEGER NOT NULL,
|
||||
"amount" INTEGER NOT NULL,
|
||||
"reason" "MoneyUpdateType" NOT NULL,
|
||||
"actionId" INTEGER,
|
||||
"tripId" TEXT,
|
||||
"timestamp" TIMESTAMPTZ(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
|
||||
CONSTRAINT "MoneyUpdate_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "User_name_key" ON "User"("name");
|
||||
CREATE UNIQUE INDEX "Player_name_key" ON "Player"("name");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "Challenge_title_key" ON "Challenge"("title");
|
||||
@ -88,22 +95,22 @@ CREATE UNIQUE INDEX "MoneyUpdate_actionId_key" ON "MoneyUpdate"("actionId");
|
||||
CREATE UNIQUE INDEX "MoneyUpdate_tripId_key" ON "MoneyUpdate"("tripId");
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "Geolocation" ADD CONSTRAINT "Geolocation_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
||||
ALTER TABLE "Geolocation" ADD CONSTRAINT "Geolocation_playerId_fkey" FOREIGN KEY ("playerId") REFERENCES "Player"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "ChallengeAction" ADD CONSTRAINT "ChallengeAction_playerId_fkey" FOREIGN KEY ("playerId") REFERENCES "Player"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "ChallengeAction" ADD CONSTRAINT "ChallengeAction_challengeId_fkey" FOREIGN KEY ("challengeId") REFERENCES "Challenge"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "ChallengeAction" ADD CONSTRAINT "ChallengeAction_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
||||
ALTER TABLE "TrainTrip" ADD CONSTRAINT "TrainTrip_playerId_fkey" FOREIGN KEY ("playerId") REFERENCES "Player"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "TrainTrip" ADD CONSTRAINT "TrainTrip_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
||||
ALTER TABLE "MoneyUpdate" ADD CONSTRAINT "MoneyUpdate_playerId_fkey" FOREIGN KEY ("playerId") REFERENCES "Player"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "MoneyUpdate" ADD CONSTRAINT "MoneyUpdate_actionId_fkey" FOREIGN KEY ("actionId") REFERENCES "ChallengeAction"("id") ON DELETE SET NULL ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "MoneyUpdate" ADD CONSTRAINT "MoneyUpdate_tripId_fkey" FOREIGN KEY ("tripId") REFERENCES "TrainTrip"("id") ON DELETE SET NULL ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "MoneyUpdate" ADD CONSTRAINT "MoneyUpdate_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
@ -7,7 +7,7 @@ datasource db {
|
||||
url = env("DATABASE_URL")
|
||||
}
|
||||
|
||||
model User {
|
||||
model Player {
|
||||
id Int @id @default(autoincrement())
|
||||
name String @unique
|
||||
password String
|
||||
@ -21,8 +21,8 @@ model User {
|
||||
|
||||
model Geolocation {
|
||||
id Int @id @default(autoincrement())
|
||||
user User @relation(fields: [userId], references: [id])
|
||||
userId Int
|
||||
player Player @relation(fields: [playerId], references: [id])
|
||||
playerId Int
|
||||
longitude Float
|
||||
latitude Float
|
||||
speed Float
|
||||
@ -42,8 +42,8 @@ model Challenge {
|
||||
|
||||
model ChallengeAction {
|
||||
id Int @id @default(autoincrement())
|
||||
user User @relation(fields: [userId], references: [id])
|
||||
userId Int
|
||||
player Player @relation(fields: [playerId], references: [id])
|
||||
playerId Int
|
||||
challenge Challenge @relation(fields: [challengeId], references: [id])
|
||||
challengeId Int @unique
|
||||
active Boolean @default(false)
|
||||
@ -57,8 +57,8 @@ model ChallengeAction {
|
||||
|
||||
model TrainTrip {
|
||||
id String @id
|
||||
user User @relation(fields: [userId], references: [id])
|
||||
userId Int
|
||||
player Player @relation(fields: [playerId], references: [id])
|
||||
playerId Int
|
||||
distance Float
|
||||
from String
|
||||
to String
|
||||
@ -70,8 +70,8 @@ model TrainTrip {
|
||||
|
||||
model MoneyUpdate {
|
||||
id Int @id @default(autoincrement())
|
||||
user User @relation(fields: [userId], references: [id])
|
||||
userId Int
|
||||
player Player @relation(fields: [playerId], references: [id])
|
||||
playerId Int
|
||||
amount Int
|
||||
reason MoneyUpdateType
|
||||
action ChallengeAction? @relation(fields: [actionId], references: [id])
|
||||
|
@ -5,14 +5,14 @@ const prisma = new PrismaClient()
|
||||
|
||||
async function main() {
|
||||
const emmyPassword = await bcrypt.hash("Emmy", 10)
|
||||
const emmy = await prisma.user.upsert({
|
||||
const emmy = await prisma.player.upsert({
|
||||
where: { id: 1 },
|
||||
update: { name: 'Emmy' },
|
||||
create: { name: 'Emmy', password: emmyPassword },
|
||||
})
|
||||
|
||||
const taminaPassword = await bcrypt.hash("Tamina", 10)
|
||||
const tamina = await prisma.user.upsert({
|
||||
const tamina = await prisma.player.upsert({
|
||||
where: { id: 2 },
|
||||
update: { name: 'Tamina' },
|
||||
create: { name: 'Tamina', password: taminaPassword },
|
||||
|
@ -1,7 +1,7 @@
|
||||
import { Module } from '@nestjs/common'
|
||||
import { PrismaService } from './prisma/prisma.service'
|
||||
import { PrismaModule } from './prisma/prisma.module'
|
||||
import { UsersModule } from './users/users.module'
|
||||
import { PlayersModule } from './players/players.module'
|
||||
import { AuthModule } from './auth/auth.module'
|
||||
import { GeolocationsModule } from './geolocations/geolocations.module'
|
||||
import { ChallengesModule } from './challenges/challenges.module'
|
||||
@ -10,7 +10,7 @@ import { TrainsModule } from './trains/trains.module'
|
||||
import { MoneyUpdatesModule } from './money-updates/money-updates.module'
|
||||
|
||||
@Module({
|
||||
imports: [PrismaModule, UsersModule, AuthModule, GeolocationsModule, ChallengesModule, ChallengeActionsModule, TrainsModule, MoneyUpdatesModule],
|
||||
imports: [PrismaModule, PlayersModule, AuthModule, GeolocationsModule, ChallengesModule, ChallengeActionsModule, TrainsModule, MoneyUpdatesModule],
|
||||
providers: [PrismaService],
|
||||
})
|
||||
export class AppModule {}
|
||||
|
@ -5,7 +5,7 @@ import { PrismaModule } from 'src/prisma/prisma.module'
|
||||
import { PassportModule } from '@nestjs/passport'
|
||||
import { JwtModule } from '@nestjs/jwt'
|
||||
import { env } from 'process'
|
||||
import { UsersModule } from 'src/users/users.module'
|
||||
import { PlayersModule } from 'src/players/players.module'
|
||||
import { JwtStrategy } from './jwt.strategy'
|
||||
|
||||
export const JWT_SECRET = env.JWT_SECRET
|
||||
@ -18,7 +18,7 @@ export const JWT_SECRET = env.JWT_SECRET
|
||||
secret: JWT_SECRET,
|
||||
signOptions: { expiresIn: '12h' },
|
||||
}),
|
||||
UsersModule,
|
||||
PlayersModule,
|
||||
],
|
||||
controllers: [AuthController],
|
||||
providers: [AuthService, JwtStrategy],
|
||||
|
@ -9,17 +9,17 @@ export class AuthService {
|
||||
constructor(private prisma: PrismaService, private jwtService: JwtService) {}
|
||||
|
||||
async login(name: string, password: string): Promise<AuthEntity> {
|
||||
const user = await this.prisma.user.findUnique({ where: { name: name } })
|
||||
if (!user) {
|
||||
throw new NotFoundException(`Aucun⋅e utilisateur⋅rice avec pour nom ${name}`)
|
||||
const player = await this.prisma.player.findUnique({ where: { name: name } })
|
||||
if (!player) {
|
||||
throw new NotFoundException(`Aucun⋅e joueur⋅se avec pour nom ${name}`)
|
||||
}
|
||||
const isPasswordValid = await bcrypt.compare(password, user.password)
|
||||
const isPasswordValid = await bcrypt.compare(password, player.password)
|
||||
if (!isPasswordValid) {
|
||||
throw new UnauthorizedException('Mot de passe incorrect')
|
||||
}
|
||||
|
||||
return {
|
||||
accessToken: this.jwtService.sign({ userId: user.id }),
|
||||
accessToken: this.jwtService.sign({ playerId: player.id }),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,9 +1,9 @@
|
||||
import { Injectable } from '@nestjs/common'
|
||||
import { AuthGuard } from '@nestjs/passport'
|
||||
import { User } from '@prisma/client'
|
||||
import { Player } from '@prisma/client'
|
||||
import { Request } from 'express'
|
||||
|
||||
@Injectable()
|
||||
export class JwtAuthGuard extends AuthGuard('jwt') {}
|
||||
|
||||
export type AuthenticatedRequest = Request & { user: User }
|
||||
export type AuthenticatedRequest = Request & { user: Player }
|
||||
|
@ -2,23 +2,24 @@ import { Injectable, UnauthorizedException } from '@nestjs/common'
|
||||
import { PassportStrategy } from '@nestjs/passport'
|
||||
import { ExtractJwt, Strategy } from 'passport-jwt'
|
||||
import { JWT_SECRET } from './auth.module'
|
||||
import { UsersService } from 'src/users/users.service'
|
||||
import { User } from '@prisma/client'
|
||||
import { PlayersService } from 'src/players/players.service'
|
||||
import { Player } from '@prisma/client'
|
||||
|
||||
@Injectable()
|
||||
export class JwtStrategy extends PassportStrategy(Strategy, 'jwt') {
|
||||
constructor(private usersService: UsersService) {
|
||||
constructor(private playersService: PlayersService) {
|
||||
super({
|
||||
jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
|
||||
secretOrKey: JWT_SECRET,
|
||||
})
|
||||
}
|
||||
|
||||
async validate(payload: { userId: number }): Promise<User> {
|
||||
const user = await this.usersService.findOne(payload.userId)
|
||||
if (!user) {
|
||||
async validate(payload: { playerId: number }): Promise<Player> {
|
||||
console.log(payload)
|
||||
const player = await this.playersService.findOne(payload.playerId)
|
||||
if (!player) {
|
||||
throw new UnauthorizedException()
|
||||
}
|
||||
return user
|
||||
return player
|
||||
}
|
||||
}
|
||||
|
@ -23,8 +23,7 @@ export class ChallengeActionsController {
|
||||
@ApiUnauthorizedResponse({ description: "Non authentifié⋅e" })
|
||||
@ApiForbiddenResponse({ description: "Permission refusée" })
|
||||
async create(@Req() request: AuthenticatedRequest, @Body() createChallengeActionDto: CreateChallengeActionDto): Promise<ChallengeActionEntity> {
|
||||
const user = request.user
|
||||
const challenge = await this.challengeActionsService.create(user, createChallengeActionDto)
|
||||
const challenge = await this.challengeActionsService.create(request.user, createChallengeActionDto)
|
||||
return new ChallengeActionEntity(challenge)
|
||||
}
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
import { Injectable, NotAcceptableException } from '@nestjs/common'
|
||||
import { CreateChallengeActionDto } from './dto/create-challenge-action.dto'
|
||||
import { UpdateChallengeActionDto } from './dto/update-challenge-action.dto'
|
||||
import { ChallengeAction, User } from '@prisma/client'
|
||||
import { ChallengeAction, Player } from '@prisma/client'
|
||||
import { PrismaService } from 'src/prisma/prisma.service'
|
||||
import { QueryPaginationDto } from 'src/common/dto/pagination-query.dto'
|
||||
import { paginate } from 'src/common/utils/pagination.utils'
|
||||
@ -11,8 +11,8 @@ import { FilterChallengeActionsDto } from './dto/filter-challenge-action.dto'
|
||||
export class ChallengeActionsService {
|
||||
constructor(private prisma: PrismaService) { }
|
||||
|
||||
async create(authenticatedUser: User, createChallengeActionDto: CreateChallengeActionDto): Promise<ChallengeAction> {
|
||||
const data = { ...createChallengeActionDto, userId: authenticatedUser.id }
|
||||
async create(authenticatedPlayer: Player, createChallengeActionDto: CreateChallengeActionDto): Promise<ChallengeAction> {
|
||||
const data = { ...createChallengeActionDto, playerId: authenticatedPlayer.id }
|
||||
return await this.prisma.challengeAction.create({
|
||||
data: data,
|
||||
})
|
||||
@ -49,10 +49,10 @@ export class ChallengeActionsService {
|
||||
})
|
||||
}
|
||||
|
||||
async endCurrentChallenge(user: User, success: boolean): Promise<ChallengeAction> {
|
||||
async endCurrentChallenge(player: Player, success: boolean): Promise<ChallengeAction> {
|
||||
const challengeAction = await this.prisma.challengeAction.findFirst({
|
||||
where: {
|
||||
userId: user.id,
|
||||
playerId: player.id,
|
||||
active: true,
|
||||
}
|
||||
})
|
||||
|
@ -7,8 +7,8 @@ export class FilterChallengeActionsDto {
|
||||
@IsOptional()
|
||||
@IsInt()
|
||||
@Type(() => Number)
|
||||
@ApiProperty({ description: "Identifiant de l'utilisateur⋅rice qui effectue le défi", required: false })
|
||||
userId?: number
|
||||
@ApiProperty({ description: "Identifiant de læ joueur⋅se qui effectue le défi", required: false })
|
||||
playerId?: number
|
||||
|
||||
@IsOptional()
|
||||
@IsInt()
|
||||
|
@ -10,8 +10,8 @@ export class ChallengeActionEntity implements ChallengeAction {
|
||||
@ApiProperty({ description: "Identifiant unique" })
|
||||
id: number
|
||||
|
||||
@ApiProperty({ description: "Identifiant de l'utilisateur⋅rice effectuant le défi" })
|
||||
userId: number
|
||||
@ApiProperty({ description: "Identifiant de læ joueur⋅se effectuant le défi" })
|
||||
playerId: number
|
||||
|
||||
@ApiProperty({ description: "Identifiant du défi rattaché à l'action" })
|
||||
challengeId: number
|
||||
|
@ -1,7 +1,7 @@
|
||||
import { Injectable, NotAcceptableException, NotFoundException } from '@nestjs/common'
|
||||
import { CreateChallengeDto } from './dto/create-challenge.dto'
|
||||
import { UpdateChallengeDto } from './dto/update-challenge.dto'
|
||||
import { Challenge, User } from '@prisma/client'
|
||||
import { Challenge, Player } from '@prisma/client'
|
||||
import { PrismaService } from 'src/prisma/prisma.service'
|
||||
import { QueryPaginationDto } from 'src/common/dto/pagination-query.dto'
|
||||
import { paginate } from 'src/common/utils/pagination.utils'
|
||||
@ -56,10 +56,10 @@ export class ChallengesService {
|
||||
})
|
||||
}
|
||||
|
||||
async drawRandom(user: User): Promise<ChallengeEntity> {
|
||||
async drawRandom(player: Player): Promise<ChallengeEntity> {
|
||||
const currentChallengeAction = await this.prisma.challengeAction.findFirst({
|
||||
where: {
|
||||
userId: user.id,
|
||||
playerId: player.id,
|
||||
active: true,
|
||||
}
|
||||
})
|
||||
@ -82,7 +82,7 @@ export class ChallengesService {
|
||||
const challengeEntity: ChallengeEntity = new ChallengeEntity(challenge)
|
||||
const action = await this.prisma.challengeAction.create({
|
||||
data: {
|
||||
userId: user.id,
|
||||
playerId: player.id,
|
||||
challengeId: challenge.id,
|
||||
active: true,
|
||||
success: false,
|
||||
|
@ -1,9 +1,9 @@
|
||||
import { Type } from "class-transformer"
|
||||
import { IsNumber, IsOptional } from "class-validator"
|
||||
|
||||
export class UserFilterDto {
|
||||
export class PlayerFilterDto {
|
||||
@IsOptional()
|
||||
@IsNumber()
|
||||
@Type(() => Number)
|
||||
userId?: number
|
||||
playerId?: number
|
||||
}
|
@ -9,8 +9,8 @@ export class GeolocationEntity implements Geolocation {
|
||||
@ApiProperty({description: "Identifiant unique"})
|
||||
id: number
|
||||
|
||||
@ApiProperty({description: "Utilisateur⋅rice ayant émis la géolocalisation"})
|
||||
userId: number
|
||||
@ApiProperty({description: "Joueur⋅se ayant émis la géolocalisation"})
|
||||
playerId: number
|
||||
|
||||
@ApiProperty({description: "Longitude en degrés"})
|
||||
longitude: number
|
||||
|
@ -7,7 +7,7 @@ import { GeolocationEntity } from './entities/geolocation.entity'
|
||||
import { ApiOkResponsePaginated, paginateOutput } from 'src/common/utils/pagination.utils'
|
||||
import { QueryPaginationDto } from 'src/common/dto/pagination-query.dto'
|
||||
import { PaginateOutputDto } from 'src/common/dto/pagination-output.dto'
|
||||
import { UserFilterDto } from 'src/common/dto/user_filter.dto'
|
||||
import { PlayerFilterDto } from 'src/common/dto/player_filter.dto'
|
||||
|
||||
@Controller('geolocations')
|
||||
export class GeolocationsController {
|
||||
@ -21,8 +21,7 @@ export class GeolocationsController {
|
||||
@ApiUnauthorizedResponse({ description: "Non authentifié⋅e" })
|
||||
@ApiForbiddenResponse({ description: "Permission refusée" })
|
||||
async create(@Req() request: AuthenticatedRequest, @Body() createGeolocationDto: CreateGeolocationDto): Promise<GeolocationEntity> {
|
||||
const user = request.user
|
||||
const geolocation = await this.geolocationsService.create(user, createGeolocationDto)
|
||||
const geolocation = await this.geolocationsService.create(request.user, createGeolocationDto)
|
||||
return new GeolocationEntity(geolocation)
|
||||
}
|
||||
|
||||
@ -32,8 +31,8 @@ export class GeolocationsController {
|
||||
@ApiOkResponsePaginated(GeolocationEntity)
|
||||
@ApiUnauthorizedResponse({ description: "Non authentifié⋅e" })
|
||||
@ApiForbiddenResponse({ description: "Permission refusée" })
|
||||
async findAll(@Query() queryPagination?: QueryPaginationDto, @Query() userFilter?: UserFilterDto): Promise<PaginateOutputDto<GeolocationEntity>> {
|
||||
const [geolocations, total] = await this.geolocationsService.findAll(queryPagination, userFilter)
|
||||
async findAll(@Query() queryPagination?: QueryPaginationDto, @Query() playerFilter?: PlayerFilterDto): Promise<PaginateOutputDto<GeolocationEntity>> {
|
||||
const [geolocations, total] = await this.geolocationsService.findAll(queryPagination, playerFilter)
|
||||
return paginateOutput<GeolocationEntity>(geolocations.map(geolocation => new GeolocationEntity(geolocation)), total, queryPagination)
|
||||
}
|
||||
|
||||
@ -51,17 +50,17 @@ export class GeolocationsController {
|
||||
return new GeolocationEntity(geolocation)
|
||||
}
|
||||
|
||||
@Get('/last-location/:userId')
|
||||
@Get('/last-location/:playerId')
|
||||
@UseGuards(JwtAuthGuard)
|
||||
@ApiBearerAuth()
|
||||
@ApiOkResponse({ type: GeolocationEntity })
|
||||
@ApiUnauthorizedResponse({ description: "Non authentifié⋅e" })
|
||||
@ApiForbiddenResponse({ description: "Permission refusée" })
|
||||
@ApiNotFoundResponse({ description: "Aucune localisation trouvée" })
|
||||
async findLastLocation(@Param('userId', ParseIntPipe) userId: number): Promise<GeolocationEntity> {
|
||||
const geolocation = await this.geolocationsService.findLastLocation(userId)
|
||||
async findLastLocation(@Param('playerId', ParseIntPipe) playerId: number): Promise<GeolocationEntity> {
|
||||
const geolocation = await this.geolocationsService.findLastLocation(playerId)
|
||||
if (!geolocation)
|
||||
throw new NotFoundException(`Géolocalisation inexistante pour l'utilisateur⋅rice ${userId}`)
|
||||
throw new NotFoundException(`Géolocalisation inexistante pour læ joueur⋅se ${playerId}`)
|
||||
return new GeolocationEntity(geolocation)
|
||||
}
|
||||
|
||||
|
@ -1,23 +1,23 @@
|
||||
import { Injectable } from '@nestjs/common'
|
||||
import { CreateGeolocationDto } from './dto/create-geolocation.dto'
|
||||
import { PrismaService } from 'src/prisma/prisma.service'
|
||||
import { Geolocation, Prisma, User } from '@prisma/client'
|
||||
import { Geolocation, Player, Prisma } from '@prisma/client'
|
||||
import { QueryPaginationDto } from 'src/common/dto/pagination-query.dto'
|
||||
import { paginate } from 'src/common/utils/pagination.utils'
|
||||
import { UserFilterDto } from 'src/common/dto/user_filter.dto'
|
||||
import { PlayerFilterDto } from 'src/common/dto/player_filter.dto'
|
||||
|
||||
@Injectable()
|
||||
export class GeolocationsService {
|
||||
constructor(private prisma: PrismaService) { }
|
||||
|
||||
async create(authenticatedUser: User, createGeolocationDto: CreateGeolocationDto): Promise<Geolocation> {
|
||||
const data = { ...createGeolocationDto, userId: authenticatedUser.id }
|
||||
async create(authenticatedPlayer: Player, createGeolocationDto: CreateGeolocationDto): Promise<Geolocation> {
|
||||
const data = { ...createGeolocationDto, playerId: authenticatedPlayer.id }
|
||||
return await this.prisma.geolocation.create({ data: data })
|
||||
}
|
||||
|
||||
async findAll(queryPagination?: QueryPaginationDto, userFilter?: UserFilterDto): Promise<[Geolocation[], number]> {
|
||||
async findAll(queryPagination?: QueryPaginationDto, playerFilter?: PlayerFilterDto): Promise<[Geolocation[], number]> {
|
||||
const filter = {
|
||||
where: (userFilter?.userId ? { userId: userFilter.userId } : {}),
|
||||
where: (playerFilter?.playerId ? { playerId: playerFilter.playerId } : {}),
|
||||
orderBy: { timestamp: Prisma.SortOrder.desc },
|
||||
}
|
||||
return [
|
||||
@ -33,9 +33,9 @@ export class GeolocationsService {
|
||||
return await this.prisma.geolocation.findUnique({ where: { id } })
|
||||
}
|
||||
|
||||
async findLastLocation(userId: number): Promise<Geolocation> {
|
||||
async findLastLocation(playerId: number): Promise<Geolocation> {
|
||||
return await this.prisma.geolocation.findFirst({
|
||||
where: { userId: userId },
|
||||
where: { playerId: playerId },
|
||||
orderBy: { timestamp: Prisma.SortOrder.desc },
|
||||
take: 1
|
||||
})
|
||||
|
@ -9,8 +9,8 @@ export class MoneyUpdateEntity implements MoneyUpdate {
|
||||
@ApiProperty({ description: "Identifiant unique de la mise à jour de solde" })
|
||||
id: number
|
||||
|
||||
@ApiProperty({ description: "Utilisateur⋅rice concerné⋅e par la mise à jour de solde" })
|
||||
userId: number
|
||||
@ApiProperty({ description: "Joueur⋅se concerné⋅e par la mise à jour de solde" })
|
||||
playerId: number
|
||||
|
||||
@ApiProperty({ description: "Montant de la modification du solde" })
|
||||
amount: number
|
||||
|
@ -7,7 +7,7 @@ import { ApiBearerAuth, ApiCreatedResponse, ApiForbiddenResponse, ApiNotFoundRes
|
||||
import { MoneyUpdateEntity } from './entities/money-update.entity'
|
||||
import { ApiOkResponsePaginated, paginateOutput } from 'src/common/utils/pagination.utils'
|
||||
import { QueryPaginationDto } from 'src/common/dto/pagination-query.dto'
|
||||
import { UserFilterDto } from 'src/common/dto/user_filter.dto'
|
||||
import { PlayerFilterDto } from 'src/common/dto/player_filter.dto'
|
||||
import { PaginateOutputDto } from 'src/common/dto/pagination-output.dto'
|
||||
|
||||
@Controller('money-updates')
|
||||
@ -32,8 +32,8 @@ export class MoneyUpdatesController {
|
||||
@ApiOkResponsePaginated(MoneyUpdateEntity)
|
||||
@ApiUnauthorizedResponse({ description: "Non authentifié⋅e" })
|
||||
@ApiForbiddenResponse({ description: "Permission refusée" })
|
||||
async findAll(@Query() queryPagination: QueryPaginationDto, @Query() userFilter: UserFilterDto): Promise<PaginateOutputDto<MoneyUpdateEntity>> {
|
||||
const [trains, total] = await this.moneyUpdatesService.findAll(queryPagination, userFilter)
|
||||
async findAll(@Query() queryPagination: QueryPaginationDto, @Query() playerFilter: PlayerFilterDto): Promise<PaginateOutputDto<MoneyUpdateEntity>> {
|
||||
const [trains, total] = await this.moneyUpdatesService.findAll(queryPagination, playerFilter)
|
||||
return paginateOutput<MoneyUpdateEntity>(trains.map(train => new MoneyUpdateEntity(train)), total, queryPagination)
|
||||
}
|
||||
|
||||
|
@ -2,32 +2,32 @@ import { Injectable } from '@nestjs/common'
|
||||
import { CreateMoneyUpdateDto } from './dto/create-money-update.dto'
|
||||
import { UpdateMoneyUpdateDto } from './dto/update-money-update.dto'
|
||||
import { PrismaService } from 'src/prisma/prisma.service'
|
||||
import { MoneyUpdate, User } from '@prisma/client'
|
||||
import { MoneyUpdate, Player } from '@prisma/client'
|
||||
import { QueryPaginationDto } from 'src/common/dto/pagination-query.dto'
|
||||
import { UserFilterDto } from 'src/common/dto/user_filter.dto'
|
||||
import { PlayerFilterDto } from 'src/common/dto/player_filter.dto'
|
||||
import { paginate } from 'src/common/utils/pagination.utils'
|
||||
|
||||
@Injectable()
|
||||
export class MoneyUpdatesService {
|
||||
constructor(private prisma: PrismaService) { }
|
||||
|
||||
async create(user: User, createMoneyUpdateDto: CreateMoneyUpdateDto): Promise<MoneyUpdate> {
|
||||
async create(player: Player, createMoneyUpdateDto: CreateMoneyUpdateDto): Promise<MoneyUpdate> {
|
||||
return await this.prisma.moneyUpdate.create({
|
||||
data: {
|
||||
...createMoneyUpdateDto,
|
||||
userId: user.id,
|
||||
playerId: player.id,
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
async findAll(queryPagination: QueryPaginationDto, userFilter: UserFilterDto): Promise<[MoneyUpdate[], number]> {
|
||||
async findAll(queryPagination: QueryPaginationDto, playerFilter: PlayerFilterDto): Promise<[MoneyUpdate[], number]> {
|
||||
return [
|
||||
await this.prisma.moneyUpdate.findMany({
|
||||
where: userFilter,
|
||||
where: playerFilter,
|
||||
...paginate(queryPagination),
|
||||
}),
|
||||
await this.prisma.moneyUpdate.count({
|
||||
where: userFilter,
|
||||
where: playerFilter,
|
||||
}),
|
||||
]
|
||||
}
|
||||
|
@ -1,9 +1,9 @@
|
||||
import { ApiProperty } from "@nestjs/swagger"
|
||||
import { User } from "@prisma/client"
|
||||
import { Player } from "@prisma/client"
|
||||
import { Exclude } from 'class-transformer'
|
||||
|
||||
export class UserEntity implements User {
|
||||
constructor(partial: Partial<UserEntity>) {
|
||||
export class PlayerEntity implements Player {
|
||||
constructor(partial: Partial<PlayerEntity>) {
|
||||
Object.assign(this, partial)
|
||||
}
|
||||
|
20
server/src/players/players.controller.spec.ts
Normal file
20
server/src/players/players.controller.spec.ts
Normal file
@ -0,0 +1,20 @@
|
||||
import { Test, TestingModule } from '@nestjs/testing'
|
||||
import { PlayersController } from './players.controller'
|
||||
import { PlayersService } from './players.service'
|
||||
|
||||
describe('PlayersController', () => {
|
||||
let controller: PlayersController
|
||||
|
||||
beforeEach(async () => {
|
||||
const module: TestingModule = await Test.createTestingModule({
|
||||
controllers: [PlayersController],
|
||||
providers: [PlayersService],
|
||||
}).compile()
|
||||
|
||||
controller = module.get<PlayersController>(PlayersController)
|
||||
})
|
||||
|
||||
it('should be defined', () => {
|
||||
expect(controller).toBeDefined()
|
||||
})
|
||||
})
|
@ -1,40 +1,40 @@
|
||||
import { Body, Controller, Get, HttpCode, NotFoundException, Param, ParseIntPipe, Patch, Query, Req, UseGuards } from '@nestjs/common'
|
||||
import { UsersService } from './users.service'
|
||||
import { PlayersService } from './players.service'
|
||||
import { ApiBadRequestResponse, ApiBearerAuth, ApiForbiddenResponse, ApiNoContentResponse, ApiNotFoundResponse, ApiOkResponse, ApiUnauthorizedResponse } from '@nestjs/swagger'
|
||||
import { UserEntity } from './entities/user.entity'
|
||||
import { PlayerEntity } from './entities/player.entity'
|
||||
import { AuthenticatedRequest, JwtAuthGuard } from 'src/auth/jwt-auth.guard'
|
||||
import { UpdatePasswordDto } from './dto/user_password.dto'
|
||||
import { UpdatePasswordDto } from './dto/player_password.dto'
|
||||
import { QueryPaginationDto } from 'src/common/dto/pagination-query.dto'
|
||||
import { ApiOkResponsePaginated, paginateOutput } from 'src/common/utils/pagination.utils'
|
||||
import { PaginateOutputDto } from 'src/common/dto/pagination-output.dto'
|
||||
|
||||
@Controller('users')
|
||||
export class UsersController {
|
||||
constructor(private readonly usersService: UsersService) {}
|
||||
@Controller('players')
|
||||
export class PlayersController {
|
||||
constructor(private readonly playersService: PlayersService) {}
|
||||
|
||||
@Get()
|
||||
@UseGuards(JwtAuthGuard)
|
||||
@ApiBearerAuth()
|
||||
@ApiOkResponsePaginated(UserEntity)
|
||||
@ApiOkResponsePaginated(PlayerEntity)
|
||||
@ApiUnauthorizedResponse({ description: "Non authentifié⋅e" })
|
||||
@ApiForbiddenResponse({ description: "Permission refusée" })
|
||||
async findAll(@Query() queryPagination?: QueryPaginationDto): Promise<PaginateOutputDto<UserEntity>> {
|
||||
const [users, total] = await this.usersService.findAll(queryPagination)
|
||||
return paginateOutput<UserEntity>(users.map(user => new UserEntity(user)), total, queryPagination)
|
||||
async findAll(@Query() queryPagination?: QueryPaginationDto): Promise<PaginateOutputDto<PlayerEntity>> {
|
||||
const [players, total] = await this.playersService.findAll(queryPagination)
|
||||
return paginateOutput<PlayerEntity>(players.map(player => new PlayerEntity(player)), total, queryPagination)
|
||||
}
|
||||
|
||||
@Get(':id')
|
||||
@UseGuards(JwtAuthGuard)
|
||||
@ApiBearerAuth()
|
||||
@ApiOkResponse({ type: UserEntity })
|
||||
@ApiOkResponse({ type: PlayerEntity })
|
||||
@ApiUnauthorizedResponse({ description: "Non authentifié⋅e" })
|
||||
@ApiForbiddenResponse({ description: "Permission refusée" })
|
||||
@ApiNotFoundResponse({ description: "Utilisateur⋅rice non trouvé⋅e" })
|
||||
@ApiNotFoundResponse({ description: "Joueur⋅se non trouvé⋅e" })
|
||||
async findOne(@Param('id', ParseIntPipe) id: number) {
|
||||
const user = await this.usersService.findOne(id)
|
||||
if (!user)
|
||||
throw new NotFoundException(`L'utilisateur⋅rice avec l'identifiant ${id} n'existe pas`)
|
||||
return new UserEntity(user)
|
||||
const player = await this.playersService.findOne(id)
|
||||
if (!player)
|
||||
throw new NotFoundException(`Læ joueur⋅se avec l'identifiant ${id} n'existe pas`)
|
||||
return new PlayerEntity(player)
|
||||
}
|
||||
|
||||
@Patch('/update-password')
|
||||
@ -46,7 +46,6 @@ export class UsersController {
|
||||
@ApiUnauthorizedResponse({ description: "Non authentifié⋅e" })
|
||||
@ApiForbiddenResponse({ description: "Permission refusée" })
|
||||
async updatePassword(@Req() request: AuthenticatedRequest, @Body() body: UpdatePasswordDto) {
|
||||
const user = request.user
|
||||
await this.usersService.updatePassword(user, body)
|
||||
await this.playersService.updatePassword(request.user, body)
|
||||
}
|
||||
}
|
12
server/src/players/players.module.ts
Normal file
12
server/src/players/players.module.ts
Normal file
@ -0,0 +1,12 @@
|
||||
import { Module } from '@nestjs/common'
|
||||
import { PlayersService } from './players.service'
|
||||
import { PlayersController } from './players.controller'
|
||||
import { PrismaModule } from 'src/prisma/prisma.module'
|
||||
|
||||
@Module({
|
||||
controllers: [PlayersController],
|
||||
providers: [PlayersService],
|
||||
imports: [PrismaModule],
|
||||
exports: [PlayersService],
|
||||
})
|
||||
export class PlayersModule {}
|
@ -1,15 +1,15 @@
|
||||
import { Test, TestingModule } from '@nestjs/testing'
|
||||
import { UsersService } from './users.service'
|
||||
import { PlayersService } from './players.service'
|
||||
|
||||
describe('UsersService', () => {
|
||||
let service: UsersService
|
||||
describe('PlayersService', () => {
|
||||
let service: PlayersService
|
||||
|
||||
beforeEach(async () => {
|
||||
const module: TestingModule = await Test.createTestingModule({
|
||||
providers: [UsersService],
|
||||
providers: [PlayersService],
|
||||
}).compile()
|
||||
|
||||
service = module.get<UsersService>(UsersService)
|
||||
service = module.get<PlayersService>(PlayersService)
|
||||
})
|
||||
|
||||
it('should be defined', () => {
|
@ -1,29 +1,29 @@
|
||||
import { Injectable } from '@nestjs/common'
|
||||
import { User } from '@prisma/client'
|
||||
import { Player } from '@prisma/client'
|
||||
import { PrismaService } from 'src/prisma/prisma.service'
|
||||
import * as bcrypt from 'bcrypt'
|
||||
import { UpdatePasswordDto } from './dto/user_password.dto'
|
||||
import { UpdatePasswordDto } from './dto/player_password.dto'
|
||||
import { QueryPaginationDto } from 'src/common/dto/pagination-query.dto'
|
||||
import { paginate } from 'src/common/utils/pagination.utils'
|
||||
|
||||
@Injectable()
|
||||
export class UsersService {
|
||||
export class PlayersService {
|
||||
constructor(private prisma: PrismaService) {}
|
||||
|
||||
async findAll(queryPagination?: QueryPaginationDto): Promise<[User[], number]> {
|
||||
async findAll(queryPagination?: QueryPaginationDto): Promise<[Player[], number]> {
|
||||
return [
|
||||
await this.prisma.user.findMany({ ...paginate(queryPagination) }),
|
||||
await this.prisma.user.count()
|
||||
await this.prisma.player.findMany({ ...paginate(queryPagination) }),
|
||||
await this.prisma.player.count()
|
||||
]
|
||||
}
|
||||
|
||||
async findOne(id: number): Promise<User> {
|
||||
return await this.prisma.user.findUnique({ where: { id } })
|
||||
async findOne(id: number): Promise<Player> {
|
||||
return await this.prisma.player.findUnique({ where: { id: id } })
|
||||
}
|
||||
|
||||
async updatePassword(user: User, { password }: UpdatePasswordDto): Promise<void> {
|
||||
async updatePassword(user: Player, { password }: UpdatePasswordDto): Promise<void> {
|
||||
const hashedPassword = await bcrypt.hash(password, 10)
|
||||
await this.prisma.user.update({
|
||||
await this.prisma.player.update({
|
||||
where: { id: user.id },
|
||||
data: { password: hashedPassword }
|
||||
})
|
@ -1,19 +1,19 @@
|
||||
import { Injectable } from '@nestjs/common'
|
||||
import { PrismaClient, } from '@prisma/client'
|
||||
|
||||
async function updateUserMoney(prisma: PrismaClient): Promise<void> {
|
||||
// On calcule le solde par utilisateur⋅rice pour mettre à jour l'objet User
|
||||
const moneyPerUser = await prisma.moneyUpdate.groupBy({
|
||||
by: 'userId',
|
||||
async function updatePlayerMoney(prisma: PrismaClient): Promise<void> {
|
||||
// On calcule le solde par joueur⋅se pour mettre à jour l'objet Player
|
||||
const moneyPerPlayer = await prisma.moneyUpdate.groupBy({
|
||||
by: 'playerId',
|
||||
_sum: {
|
||||
amount: true,
|
||||
}
|
||||
})
|
||||
for (const { userId, _sum } of moneyPerUser) {
|
||||
for (const { playerId, _sum } of moneyPerPlayer) {
|
||||
const { amount } = _sum
|
||||
await prisma.user.update({
|
||||
await prisma.player.update({
|
||||
where: {
|
||||
id: userId,
|
||||
id: playerId,
|
||||
},
|
||||
data: {
|
||||
money: amount
|
||||
@ -21,7 +21,7 @@ async function updateUserMoney(prisma: PrismaClient): Promise<void> {
|
||||
})
|
||||
}
|
||||
// On réinitialise le solde s'il n'y a plus aucun MoneyUpdate
|
||||
await prisma.user.updateMany({
|
||||
await prisma.player.updateMany({
|
||||
where: {
|
||||
moneyUpdates: { none: {} }
|
||||
},
|
||||
@ -39,7 +39,7 @@ function extendPrismaClient() {
|
||||
$allOperations({ model, operation, args, query }) {
|
||||
const result = query(args)
|
||||
if (!operation.startsWith("find") && !['aggregate', 'count', 'groupBy'].includes(operation))
|
||||
result.then(() => updateUserMoney(prisma))
|
||||
result.then(() => updatePlayerMoney(prisma))
|
||||
return result
|
||||
}
|
||||
}
|
||||
|
@ -10,8 +10,8 @@ export class CreateTrainDto {
|
||||
|
||||
@IsInt()
|
||||
@Type(() => Number)
|
||||
@ApiProperty({ description: "Identifiant de l'utilisateur⋅rice effectuant le trajet" })
|
||||
userId: number
|
||||
@ApiProperty({ description: "Identifiant de læ joueur⋅se effectuant le trajet" })
|
||||
playerId: number
|
||||
|
||||
@IsNumber()
|
||||
@Type(() => Number)
|
||||
|
@ -10,8 +10,8 @@ export class TrainEntity implements TrainTrip {
|
||||
@ApiProperty({ description: "Identifiant du train, donné par l'identifiant de partage Interrail" })
|
||||
id: string
|
||||
|
||||
@ApiProperty({ description: "Identifiant de l'utilisateur⋅rice effectuant le trajet" })
|
||||
userId: number
|
||||
@ApiProperty({ description: "Identifiant de læ joueur⋅se effectuant le trajet" })
|
||||
playerId: number
|
||||
|
||||
@ApiProperty({ description: "Distance estimée en mètres du trajet" })
|
||||
distance: number
|
||||
|
@ -9,7 +9,7 @@ import { ApiOkResponsePaginated, paginateOutput } from 'src/common/utils/paginat
|
||||
import { QueryPaginationDto } from 'src/common/dto/pagination-query.dto'
|
||||
import { PaginateOutputDto } from 'src/common/dto/pagination-output.dto'
|
||||
import { ImportTrainDto } from './dto/import-train.dto'
|
||||
import { UserFilterDto } from 'src/common/dto/user_filter.dto'
|
||||
import { PlayerFilterDto } from 'src/common/dto/player_filter.dto'
|
||||
|
||||
@Controller('trains')
|
||||
export class TrainsController {
|
||||
@ -33,8 +33,8 @@ export class TrainsController {
|
||||
@ApiOkResponsePaginated(TrainEntity)
|
||||
@ApiUnauthorizedResponse({ description: "Non authentifié⋅e" })
|
||||
@ApiForbiddenResponse({ description: "Permission refusée" })
|
||||
async findAll(@Query() queryPagination: QueryPaginationDto, @Query() userFilter: UserFilterDto): Promise<PaginateOutputDto<TrainEntity>> {
|
||||
const [trains, total] = await this.trainsService.findAll(queryPagination, userFilter)
|
||||
async findAll(@Query() queryPagination: QueryPaginationDto, @Query() playerFilter: PlayerFilterDto): Promise<PaginateOutputDto<TrainEntity>> {
|
||||
const [trains, total] = await this.trainsService.findAll(queryPagination, playerFilter)
|
||||
return paginateOutput<TrainEntity>(trains.map(train => new TrainEntity(train)), total, queryPagination)
|
||||
}
|
||||
|
||||
|
@ -2,13 +2,13 @@ import { Injectable, NotAcceptableException } from '@nestjs/common'
|
||||
import { CreateTrainDto } from './dto/create-train.dto'
|
||||
import { UpdateTrainDto } from './dto/update-train.dto'
|
||||
import { PrismaService } from 'src/prisma/prisma.service'
|
||||
import { TrainTrip, User } from '@prisma/client'
|
||||
import { Player, TrainTrip } from '@prisma/client'
|
||||
import { QueryPaginationDto } from 'src/common/dto/pagination-query.dto'
|
||||
import { paginate } from 'src/common/utils/pagination.utils'
|
||||
import { ImportTrainDto } from './dto/import-train.dto'
|
||||
import { InterrailJourney, InterrailLegInfo, InterrailTravelInfo } from './dto/interrail-api.dto'
|
||||
import { distanceCoordinates } from 'src/common/utils/calculus.utils'
|
||||
import { UserFilterDto } from 'src/common/dto/user_filter.dto'
|
||||
import { PlayerFilterDto } from 'src/common/dto/player_filter.dto'
|
||||
|
||||
@Injectable()
|
||||
export class TrainsService {
|
||||
@ -18,14 +18,14 @@ export class TrainsService {
|
||||
return await this.prisma.trainTrip.create({ data: createTrainDto })
|
||||
}
|
||||
|
||||
async findAll(queryPagination: QueryPaginationDto, userFilter: UserFilterDto): Promise<[TrainTrip[], number]> {
|
||||
async findAll(queryPagination: QueryPaginationDto, playerFilter: PlayerFilterDto): Promise<[TrainTrip[], number]> {
|
||||
return [
|
||||
await this.prisma.trainTrip.findMany({
|
||||
where: userFilter,
|
||||
where: playerFilter,
|
||||
...paginate(queryPagination),
|
||||
}),
|
||||
await this.prisma.trainTrip.count({
|
||||
where: userFilter,
|
||||
where: playerFilter,
|
||||
}),
|
||||
]
|
||||
}
|
||||
@ -49,7 +49,7 @@ export class TrainsService {
|
||||
})
|
||||
}
|
||||
|
||||
async import(user: User, { id: trainId }: ImportTrainDto): Promise<TrainTrip> {
|
||||
async import(player: Player, { id: trainId }: ImportTrainDto): Promise<TrainTrip> {
|
||||
const interrailResult: InterrailJourney = await fetch(`https://3uiwjsimnh.execute-api.eu-central-1.amazonaws.com/Prod/journey-import?id=${trainId}`)
|
||||
.then(data => data.json())
|
||||
if (interrailResult.data.travels.length !== 1)
|
||||
@ -83,7 +83,7 @@ export class TrainsService {
|
||||
},
|
||||
create: {
|
||||
id: trainId,
|
||||
userId: user.id,
|
||||
playerId: player.id,
|
||||
distance: distance,
|
||||
from: travel.from,
|
||||
to: travel.to,
|
||||
@ -92,7 +92,7 @@ export class TrainsService {
|
||||
infoJson: leg.infoJson,
|
||||
},
|
||||
update: {
|
||||
userId: user.id,
|
||||
playerId: player.id,
|
||||
distance: distance,
|
||||
from: travel.from,
|
||||
to: travel.to,
|
||||
|
@ -1,20 +0,0 @@
|
||||
import { Test, TestingModule } from '@nestjs/testing'
|
||||
import { UsersController } from './users.controller'
|
||||
import { UsersService } from './users.service'
|
||||
|
||||
describe('UsersController', () => {
|
||||
let controller: UsersController
|
||||
|
||||
beforeEach(async () => {
|
||||
const module: TestingModule = await Test.createTestingModule({
|
||||
controllers: [UsersController],
|
||||
providers: [UsersService],
|
||||
}).compile()
|
||||
|
||||
controller = module.get<UsersController>(UsersController)
|
||||
})
|
||||
|
||||
it('should be defined', () => {
|
||||
expect(controller).toBeDefined()
|
||||
})
|
||||
})
|
@ -1,12 +0,0 @@
|
||||
import { Module } from '@nestjs/common'
|
||||
import { UsersService } from './users.service'
|
||||
import { UsersController } from './users.controller'
|
||||
import { PrismaModule } from 'src/prisma/prisma.module'
|
||||
|
||||
@Module({
|
||||
controllers: [UsersController],
|
||||
providers: [UsersService],
|
||||
imports: [PrismaModule],
|
||||
exports: [UsersService],
|
||||
})
|
||||
export class UsersModule {}
|
Loading…
Reference in New Issue
Block a user