chore: remove concept

This commit is contained in:
2025-05-06 14:22:57 +02:00
parent 8686bc4c47
commit c6f2df9a0f
20 changed files with 22 additions and 1373 deletions
+1 -15
View File
@@ -14,9 +14,6 @@ import { ConfigService } from '@nestjs/config';
import { WordModule } from './word/words.module'; import { WordModule } from './word/words.module';
import { Message } from './games/entities/message.entity'; import { Message } from './games/entities/message.entity';
import { LobbyModule } from './lobby/lobby.module'; import { LobbyModule } from './lobby/lobby.module';
import { Concept } from './concept/entities/concept.entity';
import { ConceptModule } from './concept/concept.module';
import { ConceptType } from './concept/entities/concepttype.entity';
const configService = new ConfigService(); const configService = new ConfigService();
@@ -35,23 +32,12 @@ const configService = new ConfigService();
username: configService.get('PG_USER'), username: configService.get('PG_USER'),
database: 'concept', database: 'concept',
synchronize: configService.get('DEV_MODE') == 'true', synchronize: configService.get('DEV_MODE') == 'true',
entities: [ entities: [User, Player, Game, Message, ConceptInTurn, Topic, Word],
User,
Player,
Game,
Message,
Concept,
ConceptType,
ConceptInTurn,
Topic,
Word,
],
}), }),
LobbyModule, LobbyModule,
GamesModule, GamesModule,
UsersModule, UsersModule,
WordModule, WordModule,
ConceptModule,
], ],
}) })
export class AppModule {} export class AppModule {}
-98
View File
@@ -1,98 +0,0 @@
import { Controller, Get, Sse } from '@nestjs/common';
import { ApiOperation, ApiTags } from '@nestjs/swagger';
import { fromEvent, map, Observable } from 'rxjs';
import { EventEmitter2 } from '@nestjs/event-emitter';
import { ConceptService } from './concept.service';
import {
ConceptResponseDTO,
ConceptTypeResponseDTO,
} from 'events/dto/conceptresponse.dto';
@ApiTags('concepts')
@Controller('concepts')
export class ConceptController {
constructor(
private readonly conceptService: ConceptService,
private eventEmitter: EventEmitter2,
) {}
@Sse('/subscribe')
subscribe(): Observable<{ data: string }> {
return fromEvent(this.eventEmitter, this.conceptService.sse_prefix).pipe(
map((payload) => {
return {
data: JSON.stringify(payload),
};
}),
);
}
// @Delete(':id')
// @ApiOperation({ summary: 'Delete a concept' })
// @UseGuards(AuthGuard)
// async delete(@Param('id') id: number) {
// const concept = await this.conceptService.getById(id);
// if (!concept) {
// throw new HttpException('Concept not found', HttpStatus.NOT_FOUND);
// }
// await this.conceptService.delete(concept);
// }
// @Post('/')
// @ApiOperation({ summary: 'Submit a concept' })
// @ApiBody({ type: ConceptRecieveDTO })
// @UseGuards(AuthGuard)
// async create(@Body('value') value: string) {
// const concept = await this.conceptService.create(value, 'placeholder.jpg');
// return new ConceptResponseDTO(concept);
// }
@Get('/')
@ApiOperation({ summary: 'List enabled concept' })
async read() {
return (await this.conceptService.listActive()).map(
(w) => new ConceptResponseDTO(w),
);
}
@Get('/types')
@ApiOperation({ summary: 'List concept types' })
async readTypes() {
return (await this.conceptService.listTypes()).map(
(w) => new ConceptTypeResponseDTO(w),
);
}
@Get('/all')
@ApiOperation({ summary: 'List all concepts' })
async readAll() {
return (await this.conceptService.list()).map(
(w) => new ConceptResponseDTO(w),
);
}
// @Put(':id/enable')
// @ApiOperation({ summary: 'Enable a concept' })
// @UseGuards(AuthGuard)
// async enable(
// @Param('id', ParseIntPipe) _id: string,
// @Param('id', ConceptPipe) concept: Concept,
// ) {
// await this.conceptService.enable(concept);
// return new ConceptResponseDTO(concept);
// }
// @Put(':id/disable')
// @ApiOperation({ summary: 'Disable a concept' })
// @UseGuards(AuthGuard)
// async disable(
// @Param('id', ParseIntPipe) _id: string,
// @Param('id', ConceptPipe) concept: Concept,
// ) {
// await this.conceptService.disable(concept);
// return new ConceptResponseDTO(concept);
// }
}
-16
View File
@@ -1,16 +0,0 @@
import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { UsersModule } from 'src/users/users.module';
import { Concept } from './entities/concept.entity';
import { ConceptService } from './concept.service';
import { ConceptController } from './concept.controller';
import { ConceptType } from './entities/concepttype.entity';
@Module({
imports: [UsersModule, TypeOrmModule.forFeature([Concept, ConceptType])],
providers: [ConceptService],
controllers: [ConceptController],
})
export class ConceptModule {}
-20
View File
@@ -1,20 +0,0 @@
import {
HttpException,
HttpStatus,
Injectable,
PipeTransform,
} from '@nestjs/common';
import { ConceptService } from './concept.service';
@Injectable()
export class ConceptPipe implements PipeTransform {
constructor(private readonly conceptService: ConceptService) {}
async transform(id: number) {
const word = await this.conceptService.getById(id);
if (!word) {
throw new HttpException('Word not found', HttpStatus.NOT_FOUND);
}
return word;
}
}
-92
View File
@@ -1,92 +0,0 @@
import { HttpException, HttpStatus, Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { DeepPartial, Repository } from 'typeorm';
import { EventEmitter2 } from '@nestjs/event-emitter';
import { Concept } from './entities/concept.entity';
import {
ConceptDeleteEvent,
ConceptCreateEvent,
ConceptEnableEvent,
ConceptDisableEvent,
} from 'events/concept.events';
import { ConceptType } from './entities/concepttype.entity';
import typeSeeds from './seeds/concepttype.seed.json';
import conceptSeeds from './seeds/concept.seed.json';
@Injectable()
export class ConceptService {
sse_prefix = 'sse.concept';
constructor(
@InjectRepository(Concept) private conceptRepository: Repository<Concept>,
@InjectRepository(ConceptType)
private conceptTypeRepository: Repository<ConceptType>,
private eventEmitter: EventEmitter2,
) {
void conceptTypeRepository
.upsert(typeSeeds as DeepPartial<ConceptType>[], {
conflictPaths: ['id'],
})
.then(() => {
void conceptRepository.upsert(conceptSeeds as DeepPartial<Concept>[], {
conflictPaths: ['id'],
});
});
}
async getById(id: number) {
return await this.conceptRepository.findOneBy({ id });
}
async delete(concept: Concept) {
const conceptId = concept.id;
await this.conceptRepository.remove(concept);
this.eventEmitter.emit(this.sse_prefix, new ConceptDeleteEvent(conceptId));
}
async create(value: string, image: string) {
const concept = this.conceptRepository.create();
const conceptType = await this.conceptTypeRepository.findOneByOrFail({
id: 1,
});
concept.value = value;
concept.type = conceptType;
try {
await this.conceptRepository.save(concept);
this.eventEmitter.emit(this.sse_prefix, new ConceptCreateEvent(concept));
return concept;
} catch {
throw new HttpException('Concept already exists', HttpStatus.CONFLICT);
}
}
async listActive() {
const concepts = await this.conceptRepository.findBy({ enabled: true });
return concepts;
}
async listTypes() {
return await this.conceptTypeRepository.find();
}
async list() {
const concepts = await this.conceptRepository.find();
return concepts;
}
async enable(concept: Concept) {
concept.enabled = true;
await this.conceptRepository.save(concept);
this.eventEmitter.emit(this.sse_prefix, new ConceptEnableEvent(concept.id));
}
async disable(concept: Concept) {
concept.enabled = false;
await this.conceptRepository.save(concept);
this.eventEmitter.emit(
this.sse_prefix,
new ConceptDisableEvent(concept.id),
);
}
}
-7
View File
@@ -1,7 +0,0 @@
export class ConceptRecieveDTO {
constructor(partial: Partial<ConceptRecieveDTO>) {
Object.assign(this, partial);
}
value: string;
}
-22
View File
@@ -1,22 +0,0 @@
import { Column, Entity, ManyToOne, PrimaryColumn, Unique } from 'typeorm';
import { ConceptType } from './concepttype.entity';
@Entity()
@Unique(['value'])
export class Concept {
@PrimaryColumn()
id: number;
@Column()
value: string;
@Column({ default: false })
enabled: boolean;
@ManyToOne(() => ConceptType, {
eager: true,
nullable: false,
onDelete: 'CASCADE',
})
type: ConceptType;
}
@@ -1,25 +0,0 @@
import {
Column,
Entity,
OneToMany,
PrimaryColumn,
PrimaryGeneratedColumn,
Unique,
} from 'typeorm';
import { Concept } from './concept.entity';
@Entity()
@Unique(['value'])
export class ConceptType {
@PrimaryColumn()
id: number;
@Column()
value: string;
@OneToMany(() => Concept, (concept) => concept.type, {
lazy: true,
orphanedRowAction: 'delete',
})
concepts: Promise<Concept[]>;
}
-946
View File
@@ -1,946 +0,0 @@
[
{
"id": 1,
"type": {
"id": 1
},
"value": "object",
"enabled": true
},
{
"id": 2,
"type": {
"id": 1
},
"value": "family",
"enabled": true
},
{
"id": 3,
"type": {
"id": 1
},
"value": "female",
"enabled": true
},
{
"id": 4,
"type": {
"id": 1
},
"value": "male",
"enabled": true
},
{
"id": 5,
"type": {
"id": 1
},
"value": "job",
"enabled": true
},
{
"id": 6,
"type": {
"id": 1
},
"value": "activity",
"enabled": true
},
{
"id": 7,
"type": {
"id": 1
},
"value": "animals",
"enabled": true
},
{
"id": 8,
"type": {
"id": 1
},
"value": "nature",
"enabled": true
},
{
"id": 9,
"type": {
"id": 1
},
"value": "litterature",
"enabled": true
},
{
"id": 10,
"type": {
"id": 1
},
"value": "music",
"enabled": true
},
{
"id": 11,
"type": {
"id": 1
},
"value": "cinema",
"enabled": true
},
{
"id": 12,
"type": {
"id": 1
},
"value": "art",
"enabled": true
},
{
"id": 13,
"type": {
"id": 1
},
"value": "television",
"enabled": true
},
{
"id": 14,
"type": {
"id": 1
},
"value": "title",
"enabled": true
},
{
"id": 15,
"type": {
"id": 1
},
"value": "idea",
"enabled": true
},
{
"id": 16,
"type": {
"id": 1
},
"value": "expression",
"enabled": true
},
{
"id": 17,
"type": {
"id": 1
},
"value": "location",
"enabled": true
},
{
"id": 18,
"type": {
"id": 1
},
"value": "city",
"enabled": true
},
{
"id": 19,
"type": {
"id": 1
},
"value": "date",
"enabled": true
},
{
"id": 20,
"type": {
"id": 1
},
"value": "party",
"enabled": true
},
{
"id": 21,
"type": {
"id": 1
},
"value": "naval transport",
"enabled": true
},
{
"id": 22,
"type": {
"id": 1
},
"value": "aerial transport",
"enabled": true
},
{
"id": 23,
"type": {
"id": 1
},
"value": "land transport",
"enabled": true
},
{
"id": 24,
"type": {
"id": 1
},
"value": "tools",
"enabled": true
},
{
"id": 25,
"type": {
"id": 1
},
"value": "games",
"enabled": true
},
{
"id": 26,
"type": {
"id": 1
},
"value": "clothes",
"enabled": true
},
{
"id": 27,
"type": {
"id": 1
},
"value": "food",
"enabled": true
},
{
"id": 28,
"type": {
"id": 1
},
"value": "house",
"enabled": true
},
{
"id": 29,
"type": {
"id": 2
},
"value": "real",
"enabled": true
},
{
"id": 30,
"type": {
"id": 2
},
"value": "fictive",
"enabled": true
},
{
"id": 31,
"type": {
"id": 2
},
"value": "young",
"enabled": true
},
{
"id": 32,
"type": {
"id": 2
},
"value": "old",
"enabled": true
},
{
"id": 33,
"type": {
"id": 2
},
"value": "slow",
"enabled": true
},
{
"id": 34,
"type": {
"id": 2
},
"value": "fast",
"enabled": true
},
{
"id": 35,
"type": {
"id": 2
},
"value": "protect",
"enabled": true
},
{
"id": 36,
"type": {
"id": 2
},
"value": "attack",
"enabled": true
},
{
"id": 37,
"type": {
"id": 2
},
"value": "love",
"enabled": true
},
{
"id": 38,
"type": {
"id": 2
},
"value": "death",
"enabled": true
},
{
"id": 39,
"type": {
"id": 2
},
"value": "happy",
"enabled": true
},
{
"id": 40,
"type": {
"id": 2
},
"value": "sad",
"enabled": true
},
{
"id": 41,
"type": {
"id": 2
},
"value": "electronics",
"enabled": true
},
{
"id": 42,
"type": {
"id": 2
},
"value": "mechanics",
"enabled": true
},
{
"id": 43,
"type": {
"id": 2
},
"value": "money",
"enabled": true
},
{
"id": 44,
"type": {
"id": 2
},
"value": "time",
"enabled": true
},
{
"id": 45,
"type": {
"id": 2
},
"value": "religion",
"enabled": true
},
{
"id": 46,
"type": {
"id": 2
},
"value": "authority",
"enabled": true
},
{
"id": 47,
"type": {
"id": 2
},
"value": "chemistry",
"enabled": true
},
{
"id": 48,
"type": {
"id": 2
},
"value": "medecine",
"enabled": true
},
{
"id": 49,
"type": {
"id": 2
},
"value": "head",
"enabled": true
},
{
"id": 50,
"type": {
"id": 2
},
"value": "arm",
"enabled": true
},
{
"id": 51,
"type": {
"id": 2
},
"value": "torso",
"enabled": true
},
{
"id": 52,
"type": {
"id": 2
},
"value": "leg",
"enabled": true
},
{
"id": 53,
"type": {
"id": 2
},
"value": "ear",
"enabled": true
},
{
"id": 54,
"type": {
"id": 2
},
"value": "nose",
"enabled": true
},
{
"id": 55,
"type": {
"id": 2
},
"value": "eye",
"enabled": true
},
{
"id": 56,
"type": {
"id": 2
},
"value": "mouth",
"enabled": true
},
{
"id": 57,
"type": {
"id": 3
},
"value": "rain",
"enabled": true
},
{
"id": 58,
"type": {
"id": 3
},
"value": "thunder",
"enabled": true
},
{
"id": 59,
"type": {
"id": 3
},
"value": "night",
"enabled": true
},
{
"id": 60,
"type": {
"id": 3
},
"value": "day",
"enabled": true
},
{
"id": 61,
"type": {
"id": 3
},
"value": "fire",
"enabled": true
},
{
"id": 62,
"type": {
"id": 3
},
"value": "water",
"enabled": true
},
{
"id": 63,
"type": {
"id": 3
},
"value": "wind",
"enabled": true
},
{
"id": 64,
"type": {
"id": 3
},
"value": "earth",
"enabled": true
},
{
"id": 65,
"type": {
"id": 3
},
"value": "stone",
"enabled": true
},
{
"id": 66,
"type": {
"id": 3
},
"value": "wood",
"enabled": true
},
{
"id": 67,
"type": {
"id": 3
},
"value": "metal",
"enabled": true
},
{
"id": 68,
"type": {
"id": 3
},
"value": "cloth",
"enabled": true
},
{
"id": 69,
"type": {
"id": 3
},
"value": "plastic",
"enabled": true
},
{
"id": 70,
"type": {
"id": 3
},
"value": "paper",
"enabled": true
},
{
"id": 71,
"type": {
"id": 3
},
"value": "inverse",
"enabled": true
},
{
"id": 72,
"type": {
"id": 3
},
"value": "cut",
"enabled": true
},
{
"id": 73,
"type": {
"id": 3
},
"value": "multiple",
"enabled": true
},
{
"id": 74,
"type": {
"id": 3
},
"value": "puzzle",
"enabled": true
},
{
"id": 75,
"type": {
"id": 3
},
"value": "inside",
"enabled": true
},
{
"id": 76,
"type": {
"id": 3
},
"value": "grid",
"enabled": true
},
{
"id": 77,
"type": {
"id": 3
},
"value": "zero",
"enabled": true
},
{
"id": 78,
"type": {
"id": 3
},
"value": "one",
"enabled": true
},
{
"id": 79,
"type": {
"id": 4
},
"value": "line",
"enabled": true
},
{
"id": 80,
"type": {
"id": 4
},
"value": "curve",
"enabled": true
},
{
"id": 81,
"type": {
"id": 4
},
"value": "plus",
"enabled": true
},
{
"id": 82,
"type": {
"id": 4
},
"value": "zigzag",
"enabled": true
},
{
"id": 83,
"type": {
"id": 4
},
"value": "spiral",
"enabled": true
},
{
"id": 84,
"type": {
"id": 4
},
"value": "sinusoid",
"enabled": true
},
{
"id": 85,
"type": {
"id": 4
},
"value": "circle",
"enabled": true
},
{
"id": 86,
"type": {
"id": 4
},
"value": "disk",
"enabled": true
},
{
"id": 87,
"type": {
"id": 4
},
"value": "triangle",
"enabled": true
},
{
"id": 88,
"type": {
"id": 4
},
"value": "star",
"enabled": true
},
{
"id": 89,
"type": {
"id": 4
},
"value": "square",
"enabled": true
},
{
"id": 90,
"type": {
"id": 4
},
"value": "plane",
"enabled": true
},
{
"id": 91,
"type": {
"id": 4
},
"value": "cube",
"enabled": true
},
{
"id": 92,
"type": {
"id": 4
},
"value": "sphere",
"enabled": true
},
{
"id": 93,
"type": {
"id": 4
},
"value": "prism",
"enabled": true
},
{
"id": 94,
"type": {
"id": 4
},
"value": "cylinder",
"enabled": true
},
{
"id": 95,
"type": {
"id": 4
},
"value": "cone",
"enabled": true
},
{
"id": 96,
"type": {
"id": 4
},
"value": "hole",
"enabled": true
},
{
"id": 97,
"type": {
"id": 4
},
"value": "tall",
"enabled": true
},
{
"id": 98,
"type": {
"id": 4
},
"value": "small",
"enabled": true
},
{
"id": 99,
"type": {
"id": 4
},
"value": "large",
"enabled": true
},
{
"id": 100,
"type": {
"id": 4
},
"value": "narrow",
"enabled": true
},
{
"id": 101,
"type": {
"id": 4
},
"value": "up",
"enabled": true
},
{
"id": 102,
"type": {
"id": 4
},
"value": "down",
"enabled": true
},
{
"id": 103,
"type": {
"id": 4
},
"value": "left",
"enabled": true
},
{
"id": 104,
"type": {
"id": 4
},
"value": "right",
"enabled": true
},
{
"id": 105,
"type": {
"id": 4
},
"value": "repeat",
"enabled": true
},
{
"id": 106,
"type": {
"id": 4
},
"value": "action",
"enabled": true
},
{
"id": 107,
"type": {
"id": 5
},
"value": "red",
"enabled": true
},
{
"id": 108,
"type": {
"id": 5
},
"value": "orange",
"enabled": true
},
{
"id": 109,
"type": {
"id": 5
},
"value": "yellow",
"enabled": true
},
{
"id": 110,
"type": {
"id": 5
},
"value": "green",
"enabled": true
},
{
"id": 111,
"type": {
"id": 5
},
"value": "blue",
"enabled": true
},
{
"id": 112,
"type": {
"id": 5
},
"value": "purple",
"enabled": true
},
{
"id": 113,
"type": {
"id": 5
},
"value": "pink",
"enabled": true
},
{
"id": 114,
"type": {
"id": 5
},
"value": "brown",
"enabled": true
},
{
"id": 115,
"type": {
"id": 5
},
"value": "black",
"enabled": true
},
{
"id": 116,
"type": {
"id": 5
},
"value": "gray",
"enabled": true
},
{
"id": 117,
"type": {
"id": 5
},
"value": "white",
"enabled": true
},
{
"id": 118,
"type": {
"id": 5
},
"value": "transparent",
"enabled": true
}
]
-22
View File
@@ -1,22 +0,0 @@
[
{
"id": 1,
"value": "type"
},
{
"id": 2,
"value": "subtype"
},
{
"id": 3,
"value": "material"
},
{
"id": 4,
"value": "shape"
},
{
"id": 5,
"value": "color"
}
]
@@ -1,48 +0,0 @@
import { MigrationInterface, QueryRunner } from "typeorm";
export class Migration1735422446844 implements MigrationInterface {
name = 'Migration1735422446844'
public async up(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(`CREATE TABLE "user" ("id" character varying NOT NULL, "avatar" character varying NOT NULL, "username" character varying NOT NULL, CONSTRAINT "PK_cace4a159ff9f2512dd42373760" PRIMARY KEY ("id"))`);
await queryRunner.query(`CREATE TABLE "topic" ("id" SERIAL NOT NULL, CONSTRAINT "PK_33aa4ecb4e4f20aa0157ea7ef61" PRIMARY KEY ("id"))`);
await queryRunner.query(`CREATE TABLE "word" ("id" SERIAL NOT NULL, "value" character varying NOT NULL, "ownerId" character varying, CONSTRAINT "PK_ad026d65e30f80b7056ca31f666" PRIMARY KEY ("id"))`);
await queryRunner.query(`CREATE TABLE "concept" ("id" SERIAL NOT NULL, "value" character varying NOT NULL, CONSTRAINT "UQ_3275d953a4dc4dadeef5a8aeed4" UNIQUE ("value"), CONSTRAINT "PK_83c1330866b9866ac2d0ed2b36b" PRIMARY KEY ("id"))`);
await queryRunner.query(`CREATE TABLE "concept_in_turn" ("id" SERIAL NOT NULL, "order" integer NOT NULL DEFAULT '0', "subconcept" integer NOT NULL DEFAULT '0', "markers" integer NOT NULL DEFAULT '1', "conceptId" integer, "gameId" integer, CONSTRAINT "PK_c44692f972ab31a6245c8599b4b" PRIMARY KEY ("id"))`);
await queryRunner.query(`CREATE TABLE "game" ("id" SERIAL NOT NULL, "seed" character varying NOT NULL, "currentWord" character varying, "started" boolean NOT NULL DEFAULT false, "ownerId" character varying, CONSTRAINT "PK_352a30652cd352f552fef73dec5" PRIMARY KEY ("id"))`);
await queryRunner.query(`CREATE TABLE "player" ("id" SERIAL NOT NULL, "score" integer NOT NULL DEFAULT '0', "userId" character varying, "gameId" integer, CONSTRAINT "PK_65edadc946a7faf4b638d5e8885" PRIMARY KEY ("id"))`);
await queryRunner.query(`CREATE TABLE "word_topics_topic" ("wordId" integer NOT NULL, "topicId" integer NOT NULL, CONSTRAINT "PK_cc5d13565912abf7d0e1dcfc3a7" PRIMARY KEY ("wordId", "topicId"))`);
await queryRunner.query(`CREATE INDEX "IDX_66e5a60dcdb89fc3be327eb139" ON "word_topics_topic" ("wordId") `);
await queryRunner.query(`CREATE INDEX "IDX_3346a237bd507b395347a64ddc" ON "word_topics_topic" ("topicId") `);
await queryRunner.query(`ALTER TABLE "word" ADD CONSTRAINT "FK_e0edff82d908ba54dcd44d5cec6" FOREIGN KEY ("ownerId") REFERENCES "user"("id") ON DELETE NO ACTION ON UPDATE NO ACTION`);
await queryRunner.query(`ALTER TABLE "concept_in_turn" ADD CONSTRAINT "FK_6dfaa966f86139a62aba3b2114a" FOREIGN KEY ("conceptId") REFERENCES "concept"("id") ON DELETE NO ACTION ON UPDATE NO ACTION`);
await queryRunner.query(`ALTER TABLE "concept_in_turn" ADD CONSTRAINT "FK_f1c8614584bd8afcac818bacfd9" FOREIGN KEY ("gameId") REFERENCES "game"("id") ON DELETE NO ACTION ON UPDATE NO ACTION`);
await queryRunner.query(`ALTER TABLE "game" ADD CONSTRAINT "FK_d05575b5a28ec6dad65c2aef301" FOREIGN KEY ("ownerId") REFERENCES "user"("id") ON DELETE NO ACTION ON UPDATE NO ACTION`);
await queryRunner.query(`ALTER TABLE "player" ADD CONSTRAINT "FK_7687919bf054bf262c669d3ae21" FOREIGN KEY ("userId") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE NO ACTION`);
await queryRunner.query(`ALTER TABLE "player" ADD CONSTRAINT "FK_7dfdd31fcd2b5aa3b08ed15fe8a" FOREIGN KEY ("gameId") REFERENCES "game"("id") ON DELETE CASCADE ON UPDATE NO ACTION`);
await queryRunner.query(`ALTER TABLE "word_topics_topic" ADD CONSTRAINT "FK_66e5a60dcdb89fc3be327eb139a" FOREIGN KEY ("wordId") REFERENCES "word"("id") ON DELETE CASCADE ON UPDATE CASCADE`);
await queryRunner.query(`ALTER TABLE "word_topics_topic" ADD CONSTRAINT "FK_3346a237bd507b395347a64ddcb" FOREIGN KEY ("topicId") REFERENCES "topic"("id") ON DELETE NO ACTION ON UPDATE NO ACTION`);
}
public async down(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(`ALTER TABLE "word_topics_topic" DROP CONSTRAINT "FK_3346a237bd507b395347a64ddcb"`);
await queryRunner.query(`ALTER TABLE "word_topics_topic" DROP CONSTRAINT "FK_66e5a60dcdb89fc3be327eb139a"`);
await queryRunner.query(`ALTER TABLE "player" DROP CONSTRAINT "FK_7dfdd31fcd2b5aa3b08ed15fe8a"`);
await queryRunner.query(`ALTER TABLE "player" DROP CONSTRAINT "FK_7687919bf054bf262c669d3ae21"`);
await queryRunner.query(`ALTER TABLE "game" DROP CONSTRAINT "FK_d05575b5a28ec6dad65c2aef301"`);
await queryRunner.query(`ALTER TABLE "concept_in_turn" DROP CONSTRAINT "FK_f1c8614584bd8afcac818bacfd9"`);
await queryRunner.query(`ALTER TABLE "concept_in_turn" DROP CONSTRAINT "FK_6dfaa966f86139a62aba3b2114a"`);
await queryRunner.query(`ALTER TABLE "word" DROP CONSTRAINT "FK_e0edff82d908ba54dcd44d5cec6"`);
await queryRunner.query(`DROP INDEX "public"."IDX_3346a237bd507b395347a64ddc"`);
await queryRunner.query(`DROP INDEX "public"."IDX_66e5a60dcdb89fc3be327eb139"`);
await queryRunner.query(`DROP TABLE "word_topics_topic"`);
await queryRunner.query(`DROP TABLE "player"`);
await queryRunner.query(`DROP TABLE "game"`);
await queryRunner.query(`DROP TABLE "concept_in_turn"`);
await queryRunner.query(`DROP TABLE "concept"`);
await queryRunner.query(`DROP TABLE "word"`);
await queryRunner.query(`DROP TABLE "topic"`);
await queryRunner.query(`DROP TABLE "user"`);
}
}
@@ -1,24 +0,0 @@
import { Column, Entity, ManyToOne, PrimaryGeneratedColumn } from 'typeorm';
import { Game } from './game.entity';
import { Concept } from 'src/concept/entities/concept.entity';
@Entity()
export class ConceptInTurn {
@PrimaryGeneratedColumn()
id: number;
@ManyToOne(() => Concept)
concept: Concept;
@Column({ default: 0 })
order: number;
@Column({ default: 0 })
subconcept: number;
@Column({ default: 1 })
markers: number;
@ManyToOne(() => Game)
game: Promise<Game>;
}
-6
View File
@@ -9,7 +9,6 @@ import {
PrimaryGeneratedColumn, PrimaryGeneratedColumn,
} from 'typeorm'; } from 'typeorm';
import { Player } from './player.entity'; import { Player } from './player.entity';
import { ConceptInTurn } from './concept_in_turn.entity';
import { User } from 'src/users/entities/user.entity'; import { User } from 'src/users/entities/user.entity';
import { Word } from 'src/word/entities/word.entity'; import { Word } from 'src/word/entities/word.entity';
import { Message } from './message.entity'; import { Message } from './message.entity';
@@ -48,11 +47,6 @@ export class Game {
@Column({ default: 0 }) @Column({ default: 0 })
turn: number = 0; turn: number = 0;
@OneToMany(() => ConceptInTurn, (cit) => cit.game, {
eager: true,
})
currentConcepts: ConceptInTurn[];
@OneToMany(() => Message, (msg) => msg.game, { @OneToMany(() => Message, (msg) => msg.game, {
eager: true, eager: true,
}) })
+2 -9
View File
@@ -1,16 +1,9 @@
import { import { Injectable } from '@nestjs/common';
forwardRef,
HttpException,
HttpStatus,
Inject,
Injectable,
} from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm'; import { InjectRepository } from '@nestjs/typeorm';
import { Game } from '../entities/game.entity'; import { Game } from '../entities/game.entity';
import { Repository } from 'typeorm'; import { Repository } from 'typeorm';
import { EventEmitter2 } from '@nestjs/event-emitter'; import { EventEmitter2 } from '@nestjs/event-emitter';
import { Player } from '../entities/player.entity'; import { Player } from '../entities/player.entity';
import { User } from 'src/users/entities/user.entity';
import { import {
GameEndTurnEvent, GameEndTurnEvent,
@@ -128,7 +121,7 @@ export class GameService {
.map(({ value }) => value); .map(({ value }) => value);
} }
async end(game: Game, winner: Player) { end(_game: Game, _winner: Player) {
throw Error('Not Implemented'); throw Error('Not Implemented');
} }
} }
+6 -8
View File
@@ -1,18 +1,16 @@
import { Test, TestingModule } from '@nestjs/testing'; import { Test, TestingModule } from '@nestjs/testing';
import { LobbyController } from '../games/controllers/lobby.controller'; import { LobbyController } from './lobby.controller';
import { LobbyService } from '../services/lobby.service'; import { LobbyService } from './lobby.service';
import { Game } from '../games/entities/game.entity'; import { Game } from '../games/entities/game.entity';
import { TypeOrmModule } from '@nestjs/typeorm'; import { TypeOrmModule } from '@nestjs/typeorm';
import { Player } from '../games/entities/player.entity'; import { Player } from '../games/entities/player.entity';
import { GameService } from '../games/services/games.service'; import { GameService } from '../games/services/games.service';
import { User } from 'src/users/entities/user.entity'; import { User } from 'src/users/entities/user.entity';
import { EventEmitterModule } from '@nestjs/event-emitter'; import { EventEmitterModule } from '@nestjs/event-emitter';
import { Concept } from '../games/entities/concept.entity';
import { ConceptInTurn } from '../games/entities/concept_in_turn.entity';
describe('LobbyController', () => { describe('LobbyController', () => {
let controller: LobbyController; let controller: LobbyController;
let service: LobbyService; let _service: LobbyService;
beforeEach(async () => { beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({ const module: TestingModule = await Test.createTestingModule({
@@ -22,16 +20,16 @@ describe('LobbyController', () => {
TypeOrmModule.forRoot({ TypeOrmModule.forRoot({
type: 'sqlite', type: 'sqlite',
database: ':memory:', database: ':memory:',
entities: [Game, Player, User, Concept, ConceptInTurn], entities: [Game, Player, User],
synchronize: true, synchronize: true,
}), }),
TypeOrmModule.forFeature([Game, Player, User, Concept, ConceptInTurn]), TypeOrmModule.forFeature([Game, Player, User]),
EventEmitterModule.forRoot(), EventEmitterModule.forRoot(),
], ],
}).compile(); }).compile();
controller = module.get<LobbyController>(LobbyController); controller = module.get<LobbyController>(LobbyController);
service = module.get<LobbyService>(LobbyService); _service = module.get<LobbyService>(LobbyService);
}); });
describe('create', () => { describe('create', () => {
+2 -4
View File
@@ -3,11 +3,9 @@ import { LobbyService } from './lobby.service';
import { TypeOrmModule } from '@nestjs/typeorm'; import { TypeOrmModule } from '@nestjs/typeorm';
import { EventEmitterModule } from '@nestjs/event-emitter'; import { EventEmitterModule } from '@nestjs/event-emitter';
import { User } from 'src/users/entities/user.entity'; import { User } from 'src/users/entities/user.entity';
import { ConceptInTurn } from '../games/entities/concept_in_turn.entity';
import { Game } from '../games/entities/game.entity'; import { Game } from '../games/entities/game.entity';
import { Player } from '../games/entities/player.entity'; import { Player } from '../games/entities/player.entity';
import { GameService } from '../games/services/games.service'; import { GameService } from '../games/services/games.service';
import { Concept } from 'src/concept/entities/concept.entity';
describe('LobbyService', () => { describe('LobbyService', () => {
let service: LobbyService; let service: LobbyService;
@@ -19,10 +17,10 @@ describe('LobbyService', () => {
TypeOrmModule.forRoot({ TypeOrmModule.forRoot({
type: 'sqlite', type: 'sqlite',
database: ':memory:', database: ':memory:',
entities: [Game, Player, User, Concept, ConceptInTurn], entities: [Game, Player, User],
synchronize: true, synchronize: true,
}), }),
TypeOrmModule.forFeature([Game, Player, User, Concept, ConceptInTurn]), TypeOrmModule.forFeature([Game, Player, User]),
EventEmitterModule.forRoot(), EventEmitterModule.forRoot(),
], ],
}).compile(); }).compile();
+2 -2
View File
@@ -49,11 +49,11 @@ export class LobbyService {
return this.gameRepository.findOneBy({ owner: user }); return this.gameRepository.findOneBy({ owner: user });
} }
leaveGame(game: Game, user: User) { leaveGame(_game: Game, _user: User) {
throw Error('not implemented'); throw Error('not implemented');
} }
kickPlayer(game: Game, user: User, kickedPlayerId: string) { kickPlayer(_game: Game, _user: User, _kickedPlayerId: string) {
throw Error('not implemented'); throw Error('not implemented');
} }
+1 -1
View File
@@ -100,7 +100,7 @@ export class UsersService {
token_type_hint: 'refresh_token', token_type_hint: 'refresh_token',
}); });
const req = await fetch('https://discord.com/api/oauth2/token/revoke', { await fetch('https://discord.com/api/oauth2/token/revoke', {
method: 'POST', method: 'POST',
headers: { headers: {
'Content-Type': 'application/x-www-form-urlencoded', 'Content-Type': 'application/x-www-form-urlencoded',
+1 -1
View File
@@ -8,6 +8,6 @@ export class Topic {
name: string; name: string;
@ManyToMany((type) => Word, (word) => word.topics) @ManyToMany((_type) => Word, (word) => word.topics)
words: Promise<Word[]>; words: Promise<Word[]>;
} }
+7 -7
View File
@@ -1,4 +1,4 @@
import * as request from 'supertest'; // import * as request from 'supertest';
import { Test } from '@nestjs/testing'; import { Test } from '@nestjs/testing';
import { AppModule } from './../src/app.module'; import { AppModule } from './../src/app.module';
import { INestApplication } from '@nestjs/common'; import { INestApplication } from '@nestjs/common';
@@ -19,10 +19,10 @@ describe('AppController (e2e)', () => {
await app.close(); await app.close();
}); });
it('/ (GET)', () => { // it('/ (GET)', () => {
return request(app.getHttpServer()) // return request(app.getHttpServer())
.get('/') // .get('/')
.expect(200) // .expect(200)
.expect('Hello World!'); // .expect('Hello World!');
}); // });
}); });