From b93b8b4c04d5e861cc77d6b8b8b6aad12d3d5ab5 Mon Sep 17 00:00:00 2001 From: Emmy D'Anello Date: Sun, 8 Dec 2024 16:34:06 +0100 Subject: [PATCH] Ajout structure de jeu --- .../migration.sql | 16 ++++++++++++++- server/prisma/schema.prisma | 9 ++++++++- server/prisma/seed.ts | 3 ++- server/src/app.module.ts | 3 ++- server/src/auth/auth.controller.ts | 2 +- server/src/game/entities/game.entity.ts | 17 ++++++++++++++++ server/src/game/game.controller.spec.ts | 20 +++++++++++++++++++ server/src/game/game.controller.ts | 19 ++++++++++++++++++ server/src/game/game.module.ts | 11 ++++++++++ server/src/game/game.service.spec.ts | 18 +++++++++++++++++ server/src/game/game.service.ts | 11 ++++++++++ server/src/players/entities/player.entity.ts | 3 --- 12 files changed, 124 insertions(+), 8 deletions(-) rename server/prisma/migrations/{20241208121526_init => 20241208152036_init}/migration.sql (89%) create mode 100644 server/src/game/entities/game.entity.ts create mode 100644 server/src/game/game.controller.spec.ts create mode 100644 server/src/game/game.controller.ts create mode 100644 server/src/game/game.module.ts create mode 100644 server/src/game/game.service.spec.ts create mode 100644 server/src/game/game.service.ts diff --git a/server/prisma/migrations/20241208121526_init/migration.sql b/server/prisma/migrations/20241208152036_init/migration.sql similarity index 89% rename from server/prisma/migrations/20241208121526_init/migration.sql rename to server/prisma/migrations/20241208152036_init/migration.sql index 2f645d3..f77bef0 100644 --- a/server/prisma/migrations/20241208121526_init/migration.sql +++ b/server/prisma/migrations/20241208152036_init/migration.sql @@ -7,11 +7,19 @@ CREATE TABLE "Player" ( "name" TEXT NOT NULL, "password" TEXT NOT NULL, "money" INTEGER NOT NULL DEFAULT 0, - "currentRunner" BOOLEAN NOT NULL DEFAULT false, CONSTRAINT "Player_pkey" PRIMARY KEY ("id") ); +-- CreateTable +CREATE TABLE "Game" ( + "id" SERIAL NOT NULL, + "started" BOOLEAN NOT NULL DEFAULT false, + "currentRunnerId" INTEGER, + + CONSTRAINT "Game_pkey" PRIMARY KEY ("id") +); + -- CreateTable CREATE TABLE "Geolocation" ( "id" SERIAL NOT NULL, @@ -82,6 +90,9 @@ CREATE TABLE "MoneyUpdate" ( -- CreateIndex CREATE UNIQUE INDEX "Player_name_key" ON "Player"("name"); +-- CreateIndex +CREATE UNIQUE INDEX "Game_currentRunnerId_key" ON "Game"("currentRunnerId"); + -- CreateIndex CREATE UNIQUE INDEX "Challenge_title_key" ON "Challenge"("title"); @@ -94,6 +105,9 @@ CREATE UNIQUE INDEX "MoneyUpdate_actionId_key" ON "MoneyUpdate"("actionId"); -- CreateIndex CREATE UNIQUE INDEX "MoneyUpdate_tripId_key" ON "MoneyUpdate"("tripId"); +-- AddForeignKey +ALTER TABLE "Game" ADD CONSTRAINT "Game_currentRunnerId_fkey" FOREIGN KEY ("currentRunnerId") REFERENCES "Player"("id") ON DELETE SET NULL ON UPDATE CASCADE; + -- AddForeignKey ALTER TABLE "Geolocation" ADD CONSTRAINT "Geolocation_playerId_fkey" FOREIGN KEY ("playerId") REFERENCES "Player"("id") ON DELETE RESTRICT ON UPDATE CASCADE; diff --git a/server/prisma/schema.prisma b/server/prisma/schema.prisma index 71d7a66..8a257f8 100644 --- a/server/prisma/schema.prisma +++ b/server/prisma/schema.prisma @@ -12,11 +12,18 @@ model Player { name String @unique password String money Int @default(0) - currentRunner Boolean @default(false) actions ChallengeAction[] geolocations Geolocation[] moneyUpdates MoneyUpdate[] trips TrainTrip[] + runningGame Game? +} + +model Game { + id Int @id @default(autoincrement()) + started Boolean @default(false) + currentRunner Player? @relation(fields: [currentRunnerId], references: [id]) + currentRunnerId Int? @unique } model Geolocation { diff --git a/server/prisma/seed.ts b/server/prisma/seed.ts index 1ac20a2..01e699d 100644 --- a/server/prisma/seed.ts +++ b/server/prisma/seed.ts @@ -4,6 +4,7 @@ import * as bcrypt from 'bcrypt' const prisma = new PrismaClient() async function main() { + const game = await prisma.game.create({ data: {} }) const emmyPassword = await bcrypt.hash("Emmy", 10) const emmy = await prisma.player.upsert({ where: { id: 1 }, @@ -17,7 +18,7 @@ async function main() { update: { name: 'Tamina' }, create: { name: 'Tamina', password: taminaPassword }, }) - console.log({ emmy, tamina }) + console.log({ game, emmy, tamina }) } main() diff --git a/server/src/app.module.ts b/server/src/app.module.ts index 710ba0b..99923db 100644 --- a/server/src/app.module.ts +++ b/server/src/app.module.ts @@ -8,9 +8,10 @@ import { ChallengesModule } from './challenges/challenges.module' import { ChallengeActionsModule } from './challenge-actions/challenge-actions.module' import { TrainsModule } from './trains/trains.module' import { MoneyUpdatesModule } from './money-updates/money-updates.module' +import { GameModule } from './game/game.module' @Module({ - imports: [PrismaModule, PlayersModule, AuthModule, GeolocationsModule, ChallengesModule, ChallengeActionsModule, TrainsModule, MoneyUpdatesModule], + imports: [PrismaModule, AuthModule, PlayersModule, GameModule, GeolocationsModule, ChallengesModule, ChallengeActionsModule, TrainsModule, MoneyUpdatesModule], providers: [PrismaService], }) export class AppModule {} diff --git a/server/src/auth/auth.controller.ts b/server/src/auth/auth.controller.ts index efaf45b..11f1273 100644 --- a/server/src/auth/auth.controller.ts +++ b/server/src/auth/auth.controller.ts @@ -4,8 +4,8 @@ import { ApiOkResponse, ApiTags } from '@nestjs/swagger' import { AuthEntity } from './entity/auth.entity' import { LoginDto } from './dto/login.dto' -@Controller('auth') @ApiTags('auth') +@Controller('auth') export class AuthController { constructor(private readonly authService: AuthService) {} diff --git a/server/src/game/entities/game.entity.ts b/server/src/game/entities/game.entity.ts new file mode 100644 index 0000000..17d334e --- /dev/null +++ b/server/src/game/entities/game.entity.ts @@ -0,0 +1,17 @@ +import { ApiProperty } from "@nestjs/swagger" +import { Game } from "@prisma/client" + +export class GameEntity implements Game { + constructor(partial: Partial) { + Object.assign(this, partial) + } + + @ApiProperty({ description: "Identifiant unique du jeu" }) + id: number + + @ApiProperty({ description: "Est-ce que la partie est en cours" }) + started: boolean + + @ApiProperty({ description: "Identifiant de læ joueur⋅se en course" }) + currentRunnerId: number +} diff --git a/server/src/game/game.controller.spec.ts b/server/src/game/game.controller.spec.ts new file mode 100644 index 0000000..02f350f --- /dev/null +++ b/server/src/game/game.controller.spec.ts @@ -0,0 +1,20 @@ +import { Test, TestingModule } from '@nestjs/testing' +import { GameController } from './game.controller' +import { GameService } from './game.service' + +describe('GameController', () => { + let controller: GameController + + beforeEach(async () => { + const module: TestingModule = await Test.createTestingModule({ + controllers: [GameController], + providers: [GameService], + }).compile() + + controller = module.get(GameController) + }) + + it('should be defined', () => { + expect(controller).toBeDefined() + }) +}) diff --git a/server/src/game/game.controller.ts b/server/src/game/game.controller.ts new file mode 100644 index 0000000..93651b7 --- /dev/null +++ b/server/src/game/game.controller.ts @@ -0,0 +1,19 @@ +import { Controller, Get, UseGuards } from '@nestjs/common' +import { GameService } from './game.service' +import { JwtAuthGuard } from 'src/auth/jwt-auth.guard' +import { ApiBearerAuth, ApiOkResponse, ApiUnauthorizedResponse } from '@nestjs/swagger' +import { GameEntity } from './entities/game.entity' + +@Controller('game') +export class GameController { + constructor(private readonly gameService: GameService) {} + + @Get() + @UseGuards(JwtAuthGuard) + @ApiBearerAuth() + @ApiOkResponse({ type: GameEntity }) + @ApiUnauthorizedResponse({ description: "Non authentifié⋅e" }) + async find() { + return new GameEntity(await this.gameService.find()) + } +} diff --git a/server/src/game/game.module.ts b/server/src/game/game.module.ts new file mode 100644 index 0000000..e0b4964 --- /dev/null +++ b/server/src/game/game.module.ts @@ -0,0 +1,11 @@ +import { Module } from '@nestjs/common' +import { GameService } from './game.service' +import { GameController } from './game.controller' +import { PrismaModule } from 'src/prisma/prisma.module' + +@Module({ + controllers: [GameController], + providers: [GameService], + imports: [PrismaModule], +}) +export class GameModule {} diff --git a/server/src/game/game.service.spec.ts b/server/src/game/game.service.spec.ts new file mode 100644 index 0000000..efd60e0 --- /dev/null +++ b/server/src/game/game.service.spec.ts @@ -0,0 +1,18 @@ +import { Test, TestingModule } from '@nestjs/testing' +import { GameService } from './game.service' + +describe('GameService', () => { + let service: GameService + + beforeEach(async () => { + const module: TestingModule = await Test.createTestingModule({ + providers: [GameService], + }).compile() + + service = module.get(GameService) + }) + + it('should be defined', () => { + expect(service).toBeDefined() + }) +}) diff --git a/server/src/game/game.service.ts b/server/src/game/game.service.ts new file mode 100644 index 0000000..58e8467 --- /dev/null +++ b/server/src/game/game.service.ts @@ -0,0 +1,11 @@ +import { Injectable } from '@nestjs/common' +import { PrismaService } from 'src/prisma/prisma.service' + +@Injectable() +export class GameService { + constructor (private prisma: PrismaService) {} + + async find() { + return await this.prisma.game.findUnique({ where: { id: 1 } }) + } +} diff --git a/server/src/players/entities/player.entity.ts b/server/src/players/entities/player.entity.ts index 2003f46..bb112f8 100644 --- a/server/src/players/entities/player.entity.ts +++ b/server/src/players/entities/player.entity.ts @@ -18,7 +18,4 @@ export class PlayerEntity implements Player { @ApiProperty({description: "Nombre de jetons dont dispose actuellement læ joueur⋅se"}) money: number - - @ApiProperty({description: "Est-ce que cet⋅te joueur⋅se est cellui actuellement en course"}) - currentRunner: boolean }