Ajout d'une structure de tentatives de courses (Run)
This commit is contained in:
		@@ -12,7 +12,8 @@ export class ChallengeActionsService {
 | 
			
		||||
  constructor(private prisma: PrismaService) { }
 | 
			
		||||
 | 
			
		||||
  async create(authenticatedPlayer: Player, createChallengeActionDto: CreateChallengeActionDto): Promise<ChallengeAction> {
 | 
			
		||||
    const data = { ...createChallengeActionDto, playerId: authenticatedPlayer.id }
 | 
			
		||||
    const game = await this.prisma.game.findUnique({ where: { id: 1 } })
 | 
			
		||||
    const data = { ...createChallengeActionDto, playerId: authenticatedPlayer.id, runId: game.currentRunId }
 | 
			
		||||
    return await this.prisma.challengeAction.create({
 | 
			
		||||
      data: data,
 | 
			
		||||
    })
 | 
			
		||||
 
 | 
			
		||||
@@ -7,33 +7,55 @@ export class ChallengeActionEntity implements ChallengeAction {
 | 
			
		||||
    Object.assign(this, partial)
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  @ApiProperty({ description: "Identifiant unique" })
 | 
			
		||||
  /**
 | 
			
		||||
   * Identifiant unique
 | 
			
		||||
   */
 | 
			
		||||
  id: number
 | 
			
		||||
 | 
			
		||||
  @ApiProperty({ description: "Identifiant de læ joueur⋅se effectuant le défi" })
 | 
			
		||||
  /**
 | 
			
		||||
   * Identifiant de læ joueur⋅se effectuant le défi
 | 
			
		||||
   */
 | 
			
		||||
  playerId: number
 | 
			
		||||
 | 
			
		||||
  @ApiProperty({ description: "Identifiant du défi rattaché à l'action" })
 | 
			
		||||
  /**
 | 
			
		||||
   * Identifiant du défi rattaché à l'action
 | 
			
		||||
   */
 | 
			
		||||
  challengeId: number
 | 
			
		||||
 | 
			
		||||
  @ApiProperty({ description: "Est-ce que le défi est actuellement en train d'être réalisé" })
 | 
			
		||||
  /**
 | 
			
		||||
   * Est-ce que le défi est actuellement en train d'être réalisé
 | 
			
		||||
   */
 | 
			
		||||
  active: boolean
 | 
			
		||||
 | 
			
		||||
  @ApiProperty({ description: "Est-ce que le défi a été réussi" })
 | 
			
		||||
  /**
 | 
			
		||||
   * Est-ce que le défi a été réussi
 | 
			
		||||
   */
 | 
			
		||||
  success: boolean
 | 
			
		||||
 | 
			
		||||
  @ApiProperty({ description: "Heure à laquelle le défi a été démarré" })
 | 
			
		||||
  /**
 | 
			
		||||
   * Heure à laquelle le défi a été démarré
 | 
			
		||||
   */
 | 
			
		||||
  start: Date
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Heure à laquelle le défi a été terminé
 | 
			
		||||
   */
 | 
			
		||||
  @IsOptional()
 | 
			
		||||
  @ApiProperty({ description: "Heure à laquelle le défi a été terminé", required: false, nullable: true })
 | 
			
		||||
  end: Date
 | 
			
		||||
  end: Date | null = null
 | 
			
		||||
 | 
			
		||||
  @IsOptional()
 | 
			
		||||
  @ApiProperty({ description: "Heure à laquelle la pénalité a commencé, si applicable", required: false, nullable: true })
 | 
			
		||||
  penaltyStart: Date
 | 
			
		||||
  /**
 | 
			
		||||
   * Heure à laquelle la pénalité a commencé, si applicable
 | 
			
		||||
   */
 | 
			
		||||
  penaltyStart: Date | null = null
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Heure à laquelle la pénalité s'est terminée, si applicable
 | 
			
		||||
   */
 | 
			
		||||
  @IsOptional()
 | 
			
		||||
  @ApiProperty({ description: "Heure à laquelle la pénalité s'est terminée, si applicable", required: false, nullable: true })
 | 
			
		||||
  penaltyEnd: Date
 | 
			
		||||
  penaltyEnd: Date | null = null
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Identifiant de la course pendant laquelle le challenge est réalisé
 | 
			
		||||
   */
 | 
			
		||||
  runId: number
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -61,8 +61,8 @@ export class ChallengesService {
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  async drawRandom(player: Player): Promise<ChallengeEntity> {
 | 
			
		||||
    const game = await this.prisma.game.findUnique({ where: { id: 1 } })
 | 
			
		||||
    if (game.currentRunnerId != player.id)
 | 
			
		||||
    const game = await this.prisma.game.findUnique({ where: { id: 1 }, include: { currentRun: true } })
 | 
			
		||||
    if (game.currentRun?.runnerId !== player.id)
 | 
			
		||||
      throw new ConflictException("Vous n'êtes pas en course, ce n'est pas à vous de tirer un défi.")
 | 
			
		||||
    const currentChallengeAction = await this.prisma.challengeAction.findFirst({
 | 
			
		||||
      where: {
 | 
			
		||||
@@ -91,6 +91,7 @@ export class ChallengesService {
 | 
			
		||||
      data: {
 | 
			
		||||
        playerId: player.id,
 | 
			
		||||
        challengeId: challenge.id,
 | 
			
		||||
        runId: game.currentRunId,
 | 
			
		||||
        active: true,
 | 
			
		||||
        success: false,
 | 
			
		||||
      }
 | 
			
		||||
 
 | 
			
		||||
@@ -6,12 +6,18 @@ export class GameEntity implements Game {
 | 
			
		||||
    Object.assign(this, partial)
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  @ApiProperty({ description: "Identifiant unique du jeu" })
 | 
			
		||||
  /**
 | 
			
		||||
   * Identifiant unique du jeu
 | 
			
		||||
   */
 | 
			
		||||
  id: number
 | 
			
		||||
 | 
			
		||||
  @ApiProperty({ description: "Est-ce que la partie est en cours" })
 | 
			
		||||
  /**
 | 
			
		||||
   * Est-ce que la partie est en cours
 | 
			
		||||
   */
 | 
			
		||||
  started: boolean
 | 
			
		||||
 | 
			
		||||
  @ApiProperty({ description: "Identifiant de læ joueur⋅se en course" })
 | 
			
		||||
  currentRunnerId: number
 | 
			
		||||
  /**
 | 
			
		||||
   * Identifiant de læ joueur⋅se en course
 | 
			
		||||
   */
 | 
			
		||||
  currentRunId: number
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -7,8 +7,8 @@ import { RepairGame } from './dto/repair-game.dto'
 | 
			
		||||
export class GameService {
 | 
			
		||||
  constructor (private prisma: PrismaService) {}
 | 
			
		||||
 | 
			
		||||
  async find(): Promise<Game> {
 | 
			
		||||
    return await this.prisma.game.findUnique({ where: { id: 1 } })
 | 
			
		||||
  async find() {
 | 
			
		||||
    return await this.prisma.game.findUnique({ where: { id: 1 }, include: { currentRun: true } })
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  async start(): Promise<Game> {
 | 
			
		||||
@@ -16,7 +16,8 @@ export class GameService {
 | 
			
		||||
    if (game.started)
 | 
			
		||||
      throw new ConflictException("La partie a déjà démarré.")
 | 
			
		||||
    const players = await this.prisma.player.findMany()
 | 
			
		||||
    const alreadyStarted = game.currentRunnerId !== null
 | 
			
		||||
    const alreadyStarted = game.currentRunId !== null
 | 
			
		||||
    let run
 | 
			
		||||
    if (!alreadyStarted) {
 | 
			
		||||
      for (const player of players) {
 | 
			
		||||
        await this.prisma.moneyUpdate.create({
 | 
			
		||||
@@ -27,30 +28,50 @@ export class GameService {
 | 
			
		||||
          }
 | 
			
		||||
        })
 | 
			
		||||
      }
 | 
			
		||||
      const runnerId = players[Math.floor(players.length * Math.random())].id
 | 
			
		||||
      run = await this.prisma.playerRun.create({
 | 
			
		||||
        data: {
 | 
			
		||||
          gameId: game.id,
 | 
			
		||||
          runnerId: runnerId,
 | 
			
		||||
        }
 | 
			
		||||
      })
 | 
			
		||||
    }
 | 
			
		||||
    else {
 | 
			
		||||
      run = game.currentRun
 | 
			
		||||
    }
 | 
			
		||||
    const runnerId = alreadyStarted ? game.currentRunnerId : players[Math.floor(players.length * Math.random())].id
 | 
			
		||||
    return await this.prisma.game.update({
 | 
			
		||||
      where: { id: 1 },
 | 
			
		||||
      data: {
 | 
			
		||||
        started: true,
 | 
			
		||||
        currentRunnerId: runnerId,
 | 
			
		||||
        currentRunId: run.id,
 | 
			
		||||
      },
 | 
			
		||||
    })
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  async switchRunningPlayer(): Promise<Game> {
 | 
			
		||||
    const game = await this.find()
 | 
			
		||||
    const newRunnerId = game.currentRunnerId == 1 ? 2 : 1
 | 
			
		||||
    await this.prisma.moneyUpdate.create({
 | 
			
		||||
    const newRunnerId = game.currentRun.runnerId == 1 ? 2 : 1
 | 
			
		||||
    const firstRun = await this.prisma.playerRun.findFirst({ where: { runnerId: newRunnerId } }) !== null
 | 
			
		||||
    const newRun = await this.prisma.playerRun.create({
 | 
			
		||||
      data: {
 | 
			
		||||
        playerId: newRunnerId,
 | 
			
		||||
        amount: 300,
 | 
			
		||||
        reason: MoneyUpdateType.START,
 | 
			
		||||
        gameId: game.id,
 | 
			
		||||
        runnerId: newRunnerId,
 | 
			
		||||
      }
 | 
			
		||||
    })
 | 
			
		||||
    if (!firstRun) {
 | 
			
		||||
      // Si c'est une nouvelle course (pas la première), on accorde un bonus de points de départ
 | 
			
		||||
      await this.prisma.moneyUpdate.create({
 | 
			
		||||
        data: {
 | 
			
		||||
          playerId: newRunnerId,
 | 
			
		||||
          amount: 300,
 | 
			
		||||
          reason: MoneyUpdateType.NEW_RUN,
 | 
			
		||||
          runId: newRun.id,
 | 
			
		||||
        }
 | 
			
		||||
      })
 | 
			
		||||
    }
 | 
			
		||||
    return await this.prisma.game.update({
 | 
			
		||||
      where: { id: game.id },
 | 
			
		||||
      data: { currentRunnerId: newRunnerId },
 | 
			
		||||
      data: { currentRunId: newRun.id },
 | 
			
		||||
    })
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@@ -67,18 +88,19 @@ export class GameService {
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  async reset(): Promise<Game> {
 | 
			
		||||
    await this.prisma.moneyUpdate.deleteMany()
 | 
			
		||||
    await this.prisma.challengeAction.deleteMany()
 | 
			
		||||
    await this.prisma.trainTrip.deleteMany()
 | 
			
		||||
    await this.prisma.geolocation.deleteMany()
 | 
			
		||||
    await this.prisma.player.updateMany({ data: { money: 0 } })
 | 
			
		||||
    await this.prisma.game.update({
 | 
			
		||||
      where: { id: 1 },
 | 
			
		||||
      data: {
 | 
			
		||||
        started: false,
 | 
			
		||||
        currentRunnerId: null,
 | 
			
		||||
        currentRunId: null,
 | 
			
		||||
      },
 | 
			
		||||
    })
 | 
			
		||||
    await this.prisma.player.updateMany({ data: { money: 0 } })
 | 
			
		||||
    await this.prisma.moneyUpdate.deleteMany()
 | 
			
		||||
    await this.prisma.challengeAction.deleteMany()
 | 
			
		||||
    await this.prisma.trainTrip.deleteMany()
 | 
			
		||||
    await this.prisma.playerRun.deleteMany()
 | 
			
		||||
    await this.prisma.geolocation.deleteMany()
 | 
			
		||||
    return await this.find()
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -1,29 +1,49 @@
 | 
			
		||||
import { ApiProperty } from "@nestjs/swagger"
 | 
			
		||||
import { MoneyUpdate, MoneyUpdateType } from "@prisma/client"
 | 
			
		||||
import { IsOptional } from "class-validator"
 | 
			
		||||
 | 
			
		||||
export class MoneyUpdateEntity implements MoneyUpdate {
 | 
			
		||||
  constructor (partial: Partial<MoneyUpdateEntity>) {
 | 
			
		||||
    Object.assign(this, partial)
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  @ApiProperty({ description: "Identifiant unique de la mise à jour de solde" })
 | 
			
		||||
  /**
 | 
			
		||||
   * Identifiant unique de la mise à jour de solde
 | 
			
		||||
   */
 | 
			
		||||
  id: number
 | 
			
		||||
 | 
			
		||||
  @ApiProperty({ description: "Joueur⋅se concerné⋅e par la mise à jour de solde" })
 | 
			
		||||
  /**
 | 
			
		||||
   * Joueur⋅se concerné⋅e par la mise à jour de solde
 | 
			
		||||
   */
 | 
			
		||||
  playerId: number
 | 
			
		||||
 | 
			
		||||
  @ApiProperty({ description: "Montant de la modification du solde" })
 | 
			
		||||
  /**
 | 
			
		||||
   * Montant de la modification du solde
 | 
			
		||||
   */
 | 
			
		||||
  amount: number
 | 
			
		||||
 | 
			
		||||
  @ApiProperty({ description: "Type de modification de solde" })
 | 
			
		||||
  /**
 | 
			
		||||
   * Type de modification de solde
 | 
			
		||||
   */
 | 
			
		||||
  reason: MoneyUpdateType
 | 
			
		||||
 | 
			
		||||
  @ApiProperty({ description: "Identifiant de la réalisation de défi, si la mise à jour est liée à un défi", nullable: true })
 | 
			
		||||
  actionId: number
 | 
			
		||||
  /**
 | 
			
		||||
   * Identifiant de la réalisation de défi, si la mise à jour est liée à un défi
 | 
			
		||||
   */
 | 
			
		||||
  actionId: number | null = null
 | 
			
		||||
 | 
			
		||||
  @ApiProperty({ description: "Identifiant du trajet acheté, si la mise à jour est liée à la réservation d'un train", nullable: true })
 | 
			
		||||
  tripId: string
 | 
			
		||||
  /**
 | 
			
		||||
   * Identifiant du trajet acheté, si la mise à jour est liée à la réservation d'un train
 | 
			
		||||
   */
 | 
			
		||||
  tripId: string | null = null
 | 
			
		||||
 | 
			
		||||
  @ApiProperty({ description: "Date et heure de la modification de solde" })
 | 
			
		||||
  /**
 | 
			
		||||
   * Idenifiant de la course rattachée, si la mise à jour est liée à une nouvelle tentative de course
 | 
			
		||||
   */
 | 
			
		||||
  runId: number | null = null
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Date et heure de la modification de solde
 | 
			
		||||
   */
 | 
			
		||||
  timestamp: Date
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -7,27 +7,48 @@ export class TrainEntity implements TrainTrip {
 | 
			
		||||
    Object.assign(this, partial)
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  @ApiProperty({ description: "Identifiant du train, donné par l'identifiant de partage Interrail" })
 | 
			
		||||
  /**
 | 
			
		||||
   * Identifiant du train, donné par l'identifiant de partage Interrail
 | 
			
		||||
   */
 | 
			
		||||
  id: string
 | 
			
		||||
 | 
			
		||||
  @ApiProperty({ description: "Identifiant de læ joueur⋅se effectuant le trajet" })
 | 
			
		||||
  /**
 | 
			
		||||
   * Identifiant de læ joueur⋅se effectuant le trajet
 | 
			
		||||
   */
 | 
			
		||||
  playerId: number
 | 
			
		||||
 | 
			
		||||
  @ApiProperty({ description: "Distance estimée en mètres du trajet" })
 | 
			
		||||
  /**
 | 
			
		||||
   * Distance estimée en mètres du trajet
 | 
			
		||||
   */ 
 | 
			
		||||
  distance: number
 | 
			
		||||
 | 
			
		||||
  @ApiProperty({ description: "Nom de la gare de départ" })
 | 
			
		||||
  /**
 | 
			
		||||
   * Nom de la gare de départ
 | 
			
		||||
   */
 | 
			
		||||
  from: string
 | 
			
		||||
 | 
			
		||||
  @ApiProperty({ description: "Nom de la gare d'arrivée" })
 | 
			
		||||
  /**
 | 
			
		||||
   * Nom de la gare d'arrivée
 | 
			
		||||
   */
 | 
			
		||||
  to: string
 | 
			
		||||
 | 
			
		||||
  @ApiProperty({ description: "Date et heure de départ du train" })
 | 
			
		||||
  /**
 | 
			
		||||
   * Date et heure de départ du train
 | 
			
		||||
   */
 | 
			
		||||
  departureTime: Date
 | 
			
		||||
 | 
			
		||||
  @ApiProperty({ description: "Date et heure d'arrivée du train" })
 | 
			
		||||
  /**
 | 
			
		||||
   * Date et heure d'arrivée du train"
 | 
			
		||||
   */
 | 
			
		||||
  arrivalTime: Date
 | 
			
		||||
 | 
			
		||||
  @ApiProperty({ description: "Informations JSON supplémentaires transmises par Interrail" })
 | 
			
		||||
  /**
 | 
			
		||||
   * Informations JSON supplémentaires transmises par Interrail
 | 
			
		||||
   */
 | 
			
		||||
  infoJson: JsonValue
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Identifiant de la course pendant laquelle ce train a été emprunté
 | 
			
		||||
   */
 | 
			
		||||
  runId: number
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -15,7 +15,9 @@ export class TrainsService {
 | 
			
		||||
  constructor(private prisma: PrismaService) { }
 | 
			
		||||
 | 
			
		||||
  async create(createTrainDto: CreateTrainDto): Promise<TrainTrip> {
 | 
			
		||||
    return await this.prisma.trainTrip.create({ data: createTrainDto })
 | 
			
		||||
    const game = await this.prisma.game.findUnique({ where: { id: 1 } })
 | 
			
		||||
    const data = { ...createTrainDto, runId: game.currentRunId }
 | 
			
		||||
    return await this.prisma.trainTrip.create({ data: data })
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  async findAll(queryPagination: QueryPaginationDto, playerFilter: PlayerFilterDto): Promise<[TrainTrip[], number]> {
 | 
			
		||||
@@ -54,6 +56,8 @@ export class TrainsService {
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  async import(player: Player, { id: trainId }: ImportTrainDto): Promise<TrainTrip> {
 | 
			
		||||
    const game = await this.prisma.game.findUnique({ where: { id: 1 } })
 | 
			
		||||
 | 
			
		||||
    if (this.findOne(trainId))
 | 
			
		||||
      throw new ConflictException(`Le train avec l'identifiant ${trainId} est déjà importé`)
 | 
			
		||||
 | 
			
		||||
@@ -95,6 +99,7 @@ export class TrainsService {
 | 
			
		||||
        departureTime: departure,
 | 
			
		||||
        arrivalTime: arrival,
 | 
			
		||||
        infoJson: leg.infoJson,
 | 
			
		||||
        runId: game.currentRunId,
 | 
			
		||||
      },
 | 
			
		||||
    })
 | 
			
		||||
    // Ajout du trajet en points
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user