diff --git a/src/app.module.ts b/src/app.module.ts
index 2c2773b3c7a80e6e20b316dd2a753e32b310a49a..f2c7b7765304436488bbadb3fdfce4fbdc1fbd9a 100644
--- a/src/app.module.ts
+++ b/src/app.module.ts
@@ -18,6 +18,7 @@ import { UserModule } from './user/user.module';
 import { DrawModule } from './draw/draw.module';
 import { FactionModule } from './faction/faction.module';
 import { GameModule } from './game/game.module';
+import { ScoreModule } from './score/score.module';
 
 @Module({
   imports: [
@@ -29,6 +30,7 @@ import { GameModule } from './game/game.module';
     DrawModule,
     FactionModule,
     TrackingModule,
+    ScoreModule,
   ],
   controllers: [AppController],
   providers: [
diff --git a/src/draw/coordinate.entity.ts b/src/draw/coordinate.entity.ts
index 8f5c4e1d95cd7bf819818664aa41f662a412b316..ef5447f61cfd1dd07d1f81a8ee1fce8e8256da2a 100644
--- a/src/draw/coordinate.entity.ts
+++ b/src/draw/coordinate.entity.ts
@@ -21,7 +21,9 @@ export class MapDrawingEntity {
     onDelete: 'CASCADE',
   })
   faction: FactionEntity;
-  @ManyToOne(type => GameEntity, gameEntity => gameEntity.id)
+  @ManyToOne(type => GameEntity, gameEntity => gameEntity.id, {
+    onDelete: 'CASCADE',
+  })
   gameId: GameEntity;
 }
 
@@ -30,8 +32,20 @@ export class Game_Person_MapDrawingEntity {
   @PrimaryGeneratedColumn('uuid') GPmapDrawingId: string;
   @Column({ type: 'timestamp' }) GPCTimeStamp: Timestamp;
 
-  @ManyToOne(type => Game_PersonEntity, game_person => game_person.gamepersonId)
+  @ManyToOne(
+    type => Game_PersonEntity,
+    game_person => game_person.gamepersonId,
+    {
+      onDelete: 'CASCADE',
+    },
+  )
   game_person: Game_PersonEntity;
-  @ManyToOne(type => MapDrawingEntity, map_drawing => map_drawing.mapDrawingId)
+  @ManyToOne(
+    type => MapDrawingEntity,
+    map_drawing => map_drawing.mapDrawingId,
+    {
+      onDelete: 'CASCADE',
+    },
+  )
   map_drawing: MapDrawingEntity;
 }
diff --git a/src/draw/draw.controller.ts b/src/draw/draw.controller.ts
index 10b836118855d17bee7856203b1258f4b572c8d5..26f6cf8c56142ef190ad3bcbfd7ce9d32caa371e 100644
--- a/src/draw/draw.controller.ts
+++ b/src/draw/draw.controller.ts
@@ -12,6 +12,7 @@ import {
 import { AuthGuard } from '../shared/auth.guard';
 import { DrawService } from './draw.service';
 import { Roles, GameStates } from '../shared/guard.decorator';
+import { MapDrawingDTO, ReturnDrawingsDTO } from './mapdrawing.dto';
 
 /*
       DrawController
@@ -25,17 +26,17 @@ export class DrawController {
   constructor(private drawService: DrawService) {}
 
   @Put('mapdrawing/:id')
-  @UsePipes(new ValidationPipe())
   @Roles('admin', 'factionleader')
   @GameStates('CREATED', 'STARTED')
-  async draw(@Param('id') gameId, @Body() data) {
+  @UsePipes(new ValidationPipe())
+  async draw(@Param('id') gameId, @Body() data: MapDrawingDTO) {
     return this.drawService.draw(gameId, data);
   }
 
   @Get('map/:id')
   @UseGuards(new AuthGuard())
   @UsePipes(new ValidationPipe())
-  async drawMap(@Param('id') id, @Body() data) {
+  async drawMap(@Param('id') id, @Body() data: ReturnDrawingsDTO) {
     return this.drawService.drawMap(id, data);
   }
 }
diff --git a/src/draw/draw.service.ts b/src/draw/draw.service.ts
index ffa48d4b634a35c6b0dc4bb26391d269c9f9b76a..d5ddf23e9574771bc769e2b6d58b59a4e95ad10d 100644
--- a/src/draw/draw.service.ts
+++ b/src/draw/draw.service.ts
@@ -3,6 +3,7 @@ import { InjectRepository } from '@nestjs/typeorm';
 import { Repository } from 'typeorm';
 
 import { MapDrawingEntity } from '../draw/coordinate.entity';
+import { MapDrawingDTO, ReturnDrawingsDTO } from './mapdrawing.dto';
 
 @Injectable()
 export class DrawService {
@@ -11,11 +12,9 @@ export class DrawService {
     private mapDrawingRepository: Repository<MapDrawingEntity>,
   ) {}
 
-  async draw(gameId, data: MapDrawingEntity) {
+  async draw(gameId, data: MapDrawingDTO) {
     data['gameId'] = gameId;
-
     const drawing = await this.mapDrawingRepository.create(data);
-
     if (data.mapDrawingId == null || data.mapDrawingId == '') {
       // luo uuden instanssin.
       const mapDrawing = await this.mapDrawingRepository.insert(drawing);
@@ -27,13 +26,21 @@ export class DrawService {
   }
 
   // draw map based on game and
-  async drawMap(id, data: MapDrawingEntity) {
-    data['gameId'] = id;
-    data['drawingIsActive'] = true;
-    // get faction
-    const mapDrawings = await this.mapDrawingRepository.create(data);
-
+  async drawMap(id, data: ReturnDrawingsDTO) {
     // return mapdrawings with given faction and gameid
-    return await this.mapDrawingRepository.find(mapDrawings);
+    return await this.mapDrawingRepository.find({
+      where: [
+        {
+          gameId: id,
+          faction: data.factionId,
+          drawingIsActive: true,
+        },
+        {
+          gameId: id,
+          faction: null,
+          drawingIsActive: true,
+        },
+      ],
+    });
   }
 }
diff --git a/src/draw/mapdrawing.dto.ts b/src/draw/mapdrawing.dto.ts
index 03eca2d1057490558e271252d12a2cc1ef883273..f7e7c781a0cbd308edf5f8c14f068b449f43a05e 100644
--- a/src/draw/mapdrawing.dto.ts
+++ b/src/draw/mapdrawing.dto.ts
@@ -1,26 +1,27 @@
-import { IsUUID } from 'class-validator';
+import { IsUUID, IsOptional, IsBoolean, Allow } from 'class-validator';
 
-import { GameDTO } from '../game/game.dto';
-import { GameEntity, Game_PersonEntity } from '../game/game.entity';
 import { FactionEntity } from '../faction/faction.entity';
-import { FactionDTO } from '../faction/faction.dto';
-import { MapDrawingEntity } from '../draw/coordinate.entity';
+import { GameEntity } from '../game/game.entity';
 
 export class MapDrawingDTO {
+  @IsOptional()
+  @IsUUID('4')
+  mapDrawingId: string;
+  @Allow()
   data: JSON;
-  gameId: GameDTO;
-  faction?: FactionDTO;
-  isActive?: boolean;
-  validUntil?: string;
+  @IsOptional()
+  @IsUUID('4')
+  gameId: GameEntity;
+  @IsOptional()
+  @IsUUID('4')
+  faction?: FactionEntity;
+  @IsBoolean()
+  drawingIsActive?: boolean;
+  drawingValidTill?: string;
 }
 
-export class DrawMapDTO {
+export class ReturnDrawingsDTO {
+  @IsOptional()
   @IsUUID('4')
-  mapDrawingId: MapDrawingEntity;
-
-  gameId: GameEntity;
   factionId: FactionEntity;
-
-  gamepersonId: Game_PersonEntity;
-  data: JSON;
 }
diff --git a/src/faction/faction.controller.ts b/src/faction/faction.controller.ts
index 98fcc856d6a5e1cb469e81249eea044df4011877..7574d822c5aef8ef5c350ab349dc0801f916b753 100644
--- a/src/faction/faction.controller.ts
+++ b/src/faction/faction.controller.ts
@@ -88,4 +88,11 @@ export class FactionController {
   ) {
     return this.factionservice.joinFaction(person, data);
   }
+
+  // check if person belongs to a faction in a game
+  @Get('check-faction/:id')
+  @UseGuards(new AuthGuard())
+  checkFaction(@User('id') userId, @Param('id') gameId) {
+    return this.factionservice.verifyUser(userId, gameId);
+  }
 }
diff --git a/src/faction/faction.entity.ts b/src/faction/faction.entity.ts
index 8bc7548a4f37bf367a6cb0381bc2a131d8080da4..3aa74cf615d77deb1421d52d46d4159bf7e0d241 100644
--- a/src/faction/faction.entity.ts
+++ b/src/faction/faction.entity.ts
@@ -26,15 +26,13 @@ export class FactionEntity {
   @Column({ type: 'text' })
   factionPassword: string;
 
-  @OneToMany(type => Game_PersonEntity, game_persons => game_persons.faction, {
-    onDelete: 'SET NULL',
-  })
+  @OneToMany(type => Game_PersonEntity, game_persons => game_persons.faction)
   game_persons: Game_PersonEntity[];
-  @ManyToOne(type => GameEntity, game => game.factions)
-  game: GameEntity;
-  @OneToMany(type => MapDrawingEntity, mapDrawings => mapDrawings.faction, {
+  @ManyToOne(type => GameEntity, game => game.factions, {
     onDelete: 'CASCADE',
   })
+  game: GameEntity;
+  @OneToMany(type => MapDrawingEntity, mapDrawings => mapDrawings.faction)
   mapDrawings: MapDrawingEntity[];
 
   factionObject() {
@@ -47,7 +45,7 @@ export class FactionEntity {
   }
 }
 
-@Entity('PowerUp')
+/* @Entity('PowerUp')
 export class PowerUpEntity {
   @PrimaryGeneratedColumn('uuid') powerUpId: string;
   @Column({ type: 'text' }) powerUpName: string;
@@ -55,7 +53,9 @@ export class PowerUpEntity {
   @Column({ type: 'int' }) amount: number;
   @Column({ type: 'time' }) cooldown: string;
 
-  @OneToMany(type => FactionEntity, factions => factions.factionId)
+  @OneToMany(type => FactionEntity, factions => factions.factionId, {
+    onDelete: 'CASCADE',
+  })
   factions: Faction_PowerUpEntity[];
 }
 
@@ -81,17 +81,7 @@ export class FP_HistoryEntity {
     faction_PowerUp => faction_PowerUp.histories,
   )
   faction_PowerUp: Faction_PowerUpEntity;
-}
-
-@Entity('Score')
-export class ScoreEntity {
-  @PrimaryGeneratedColumn('uuid') scoreId: string;
-  @Column({ type: 'float' }) score: number;
-  @Column({ type: 'timestamp' }) scoreTimeStamp: Timestamp;
-
-  @ManyToOne(type => FactionEntity, factionName => factionName.factionId)
-  faction: FactionEntity;
-}
+} */
 
 @Entity('GameGroup')
 export class GameGroupEntity {
diff --git a/src/faction/faction.service.ts b/src/faction/faction.service.ts
index 76242dfe1bceda0776435b43c4fdc4cb60fe272c..e6bec65d77e45e500aad4c49f1e5f7a6168e53c4 100644
--- a/src/faction/faction.service.ts
+++ b/src/faction/faction.service.ts
@@ -129,4 +129,19 @@ export class FactionService {
     });
     return members;
   }
+
+  async verifyUser(person, game) {
+    const gameperson = await this.game_PersonRepository.findOne({
+      where: { person, game },
+      relations: ['faction'],
+    });
+    if (gameperson) {
+      return {
+        code: 200,
+        message: gameperson,
+      };
+    } else {
+      throw new HttpException('No faction was found', HttpStatus.BAD_REQUEST);
+    }
+  }
 }
diff --git a/src/game/game.controller.ts b/src/game/game.controller.ts
index 24d42bbae81d23bbba83af27d06ec58268e69127..8d7494ba4dfa4a77e22963600e45a7579fca5d5d 100644
--- a/src/game/game.controller.ts
+++ b/src/game/game.controller.ts
@@ -9,6 +9,7 @@ import {
   Put,
   UseInterceptors,
   ClassSerializerInterceptor,
+  Delete,
 } from '@nestjs/common';
 
 import { GameService } from './game.service';
@@ -39,6 +40,13 @@ export class GameController {
     return this.gameservice.editGame(id, body);
   }
 
+  @Delete('delete/:id')
+  @Roles('admin')
+  @GameStates('CREATED')
+  async deleteGame(@Param('id') id: string) {
+    return this.gameservice.deleteGame(id);
+  }
+
   @Put('edit-state/:id')
   @Roles('admin')
   @UsePipes(new ValidationPipe())
diff --git a/src/game/game.dto.ts b/src/game/game.dto.ts
index 7b912b49cbb3c5ab710063873d2a60e30db74c9e..266a8b1564e5b11fb42da755359c79d37f4b170b 100644
--- a/src/game/game.dto.ts
+++ b/src/game/game.dto.ts
@@ -100,7 +100,7 @@ export class FlagboxEventDTO {
   @IsNumber()
   @Min(0)
   @Max(3)
-  owner: number; // owner = 0, => first entry in faction db, owner = 1, => second entry etc
+  owner: number; // owner = 0, => no owner, owner = 1, => first entry in faction db
   @IsNumber()
   @Min(0)
   @Max(3)
diff --git a/src/game/game.entity.ts b/src/game/game.entity.ts
index c4f4e555ac2bb2aa45bfc0bf2eeac48349f25d86..7ae6e29955d02a2c1368b5f720200f009bd92ee1 100644
--- a/src/game/game.entity.ts
+++ b/src/game/game.entity.ts
@@ -57,19 +57,19 @@ export class Game_PersonEntity {
   @PrimaryGeneratedColumn('uuid') gamepersonId: string;
   @Column({ type: 'text', nullable: true }) role: string;
   @ManyToOne(type => FactionEntity, faction => faction.game_persons, {
-    onDelete: 'SET NULL',
+    onDelete: 'CASCADE',
   })
   faction: FactionEntity;
-  @ManyToOne(type => GameEntity, game => game.id)
+  @ManyToOne(type => GameEntity, game => game.id, {
+    onDelete: 'CASCADE',
+  })
   game: GameEntity;
   @ManyToOne(type => PersonEntity, person => person.id)
   person: PersonEntity;
-  @OneToOne(type => GameGroupEntity, group => group.leader, {
-    onDelete: 'CASCADE',
-  })
+  @OneToOne(type => GameGroupEntity, group => group.leader)
   leaderGroup: GameGroupEntity;
   @ManyToOne(type => GameGroupEntity, group => group.players, {
-    onDelete: 'CASCADE',
+    onDelete: 'NO ACTION',
   })
   @JoinColumn({ name: 'group' })
   group: GameGroupEntity;
@@ -81,9 +81,13 @@ export class ObjectivePointEntity {
   @Column({ type: 'text' }) objectivePointDescription: string;
   @Column({ type: 'float' }) objectivePointMultiplier: number;
 
-  @ManyToOne(type => MapDrawingEntity, coordinate => coordinate.data)
+  @ManyToOne(type => MapDrawingEntity, coordinate => coordinate.data, {
+    onDelete: 'CASCADE',
+  })
   coordinate: MapDrawingEntity;
-  @ManyToOne(type => GameEntity, game => game.objective_points)
+  @ManyToOne(type => GameEntity, game => game.objective_points, {
+    onDelete: 'CASCADE',
+  })
   game: GameEntity;
 }
 
@@ -103,6 +107,9 @@ export class ObjectivePoint_HistoryEntity {
   @ManyToOne(
     type => ObjectivePointEntity,
     objective_point => objective_point.objectivePointId,
+    {
+      onDelete: 'CASCADE',
+    },
   )
-  objective_point: ObjectivePointEntity;
+  objective_point: string;
 }
diff --git a/src/game/game.service.ts b/src/game/game.service.ts
index a6c20c41d97c3b8b9c9848b5ceb377682c559a21..5027c6e29d3b1a30824764e2f475d16d745de2c4 100644
--- a/src/game/game.service.ts
+++ b/src/game/game.service.ts
@@ -149,7 +149,9 @@ export class GameService {
       updatedGame.state = game.state;
       await this.gameRepository.save(updatedGame);
       // notify players about game state change
-      this.notificationGateway.server.emit(game.id, 'event update');
+      this.notificationGateway.server.emit(game.id, {
+        type: 'gamestate-update',
+      });
       return {
         code: 200,
         message: 'State was updated',
@@ -210,13 +212,14 @@ export class GameService {
     const eventUpdate = await this.objectivePoint_HistoryRepository.create({
       oP_HistoryTimestamp: data.oP_HistoryTimestamp,
       action: data.action,
-      capture: factionRef[data.capture],
-      owner: factionRef[data.owner],
-      objective_point: objectiveRef,
+      // -1 as 0 means null
+      capture: data.capture !== 0 ? factionRef[data.capture - 1] : null,
+      owner: data.owner !== 0 ? factionRef[data.owner - 1] : null,
+      objective_point: objectiveRef.objectivePointId,
     });
     await this.objectivePoint_HistoryRepository.insert(eventUpdate);
     // send flagbox event to flagbox subscribers
-    this.notificationGateway.server.emit('flagbox', 'event update');
+    this.notificationGateway.server.emit(gameId, { type: 'flagbox-event' });
     return {
       code: 201,
       message: 'OK',
diff --git a/src/notifications/notification.dto.ts b/src/notifications/notification.dto.ts
new file mode 100644
index 0000000000000000000000000000000000000000..807af14058161062d61c9b88a1d8e56637004acc
--- /dev/null
+++ b/src/notifications/notification.dto.ts
@@ -0,0 +1,12 @@
+import { IsString, Length, IsUUID, IsIn } from 'class-validator';
+
+export class NotificationdDTO {
+  // alert is for serious messages, note is for smaller updates on a situation
+  @IsIn(['alert', 'note'])
+  type: string;
+  @IsString()
+  @Length(0, 63)
+  message: string;
+  @IsUUID('4')
+  game: string;
+}
diff --git a/src/notifications/notification.entity.ts b/src/notifications/notification.entity.ts
index 3f8781633ec42bc3132c5df92f4f74045721506b..f9d5dca9290c30da406a63adf56ee06fe716a7b5 100644
--- a/src/notifications/notification.entity.ts
+++ b/src/notifications/notification.entity.ts
@@ -1,11 +1,23 @@
-import { Entity, PrimaryGeneratedColumn, Column, CreateDateColumn } from "typeorm";
+import {
+  Entity,
+  PrimaryGeneratedColumn,
+  Column,
+  CreateDateColumn,
+  ManyToOne,
+} from 'typeorm';
+
+import { GameEntity } from '../game/game.entity';
 
 // temporary table for warning notifications
 @Entity('Notifications')
 export class NotificationEntity {
-    @PrimaryGeneratedColumn('uuid') id: string;
-    @Column({type: 'text'}) message: string;
-    @CreateDateColumn() issued: Date;
-    // TODO:
-    // when game creation has been implemented, add logic so that the notifications are tied to games
-}
\ No newline at end of file
+  @PrimaryGeneratedColumn('uuid') id: string;
+  @Column('text') type: string;
+  @Column({ type: 'text' }) message: string;
+  @CreateDateColumn() issued: Date;
+
+  @ManyToOne(type => GameEntity, game => game.id, {
+    onDelete: 'CASCADE',
+  })
+  game: string;
+}
diff --git a/src/notifications/notifications.gateway.ts b/src/notifications/notifications.gateway.ts
index c30114895ffa8d4b40c3cedeaf827c5b3401cb25..5e952d6c78c6f35977f362a7459c0ebf65d1ab5e 100644
--- a/src/notifications/notifications.gateway.ts
+++ b/src/notifications/notifications.gateway.ts
@@ -6,12 +6,15 @@ import {
   OnGatewayConnection,
   OnGatewayDisconnect,
 } from '@nestjs/websockets';
-import { Logger } from '@nestjs/common';
+import { Logger, UsePipes } from '@nestjs/common';
 import { InjectRepository } from '@nestjs/typeorm';
 import { Server, Socket } from 'socket.io';
 import { Repository } from 'typeorm';
 
 import { NotificationEntity } from './notification.entity';
+import { GameEntity } from '../game/game.entity';
+import { NotificationdDTO } from './notification.dto';
+import { ValidationPipe } from '../shared/validation.pipe';
 
 @WebSocketGateway()
 export class NotificationGateway
@@ -20,6 +23,8 @@ export class NotificationGateway
     //create references to tables as repositories
     @InjectRepository(NotificationEntity)
     private notificationRepository: Repository<NotificationEntity>,
+    @InjectRepository(GameEntity)
+    private gameRepository: Repository<GameEntity>,
   ) {}
   @WebSocketServer()
   server: Server;
@@ -40,14 +45,17 @@ export class NotificationGateway
   }
 
   // notifications for when game needs to be paused / stopped
-  @SubscribeMessage('shutItDown')
-  async handleMessage(client: Socket, text: string) {
-    this.logger.log(text);
-    // send the message to all clients listening to warningToPlayers branch
-    this.server.emit('warningToPlayers', text);
-    // create entity properties
-    const message = await this.notificationRepository.create({ message: text });
-    // insert created entity NOTE: insert method doesn't check for duplicates.
-    await this.notificationRepository.insert(message);
+  @SubscribeMessage('game-info')
+  @UsePipes(new ValidationPipe())
+  async handleMessage(client: Socket, data: NotificationdDTO) {
+    // check if the game exists and is either started or paused
+    const game = await this.gameRepository.findOne({ id: data.game });
+    if (game && ['STARTED', 'PAUSED'].includes(game.state)) {
+      // send the message to all clients listening to gameId branch
+      this.server.emit(data.game, data);
+      // create entry for notification in db
+      const message = await this.notificationRepository.create(data);
+      await this.notificationRepository.insert(message);
+    }
   }
 }
diff --git a/src/notifications/notifications.module.ts b/src/notifications/notifications.module.ts
index 194c5c38155d0f976d286456a53814a08f517050..41e2fcaa36d1928dff9a60bd2c6853e240baf16f 100644
--- a/src/notifications/notifications.module.ts
+++ b/src/notifications/notifications.module.ts
@@ -3,9 +3,10 @@ import { TypeOrmModule } from '@nestjs/typeorm';
 
 import { NotificationGateway } from './notifications.gateway';
 import { NotificationEntity } from './notification.entity';
+import { GameEntity } from '../game/game.entity';
 
 @Module({
-  imports: [TypeOrmModule.forFeature([NotificationEntity])],
+  imports: [TypeOrmModule.forFeature([NotificationEntity, GameEntity])],
   providers: [NotificationGateway],
   exports: [NotificationGateway],
 })
diff --git a/src/score/score.controller.ts b/src/score/score.controller.ts
new file mode 100644
index 0000000000000000000000000000000000000000..554e0617591574ce5c34b3dff8b5fdbaacab4ca4
--- /dev/null
+++ b/src/score/score.controller.ts
@@ -0,0 +1,29 @@
+import { Controller, Post, UsePipes, Body, Param, Get } from '@nestjs/common';
+
+import { ValidationPipe } from '../shared/validation.pipe';
+import { ScoreService } from './score.service';
+import { ScoreDTO } from './score.dto';
+import { GameEntity } from '../game/game.entity';
+import { Roles, GameStates } from '../shared/guard.decorator';
+
+@Controller('score')
+export class ScoreController {
+  constructor(private scoreService: ScoreService) {}
+
+  // adds score manually to Faction
+  // :id is gameId
+  @Post('add-score/:id')
+  @Roles('admin')
+  @GameStates('STARTED')
+  @UsePipes(new ValidationPipe())
+  async addingScore(@Body() data: ScoreDTO, @Param('id') gameId: GameEntity) {
+    return this.scoreService.addScore(data, gameId);
+  }
+
+  // temporary scoreTick path, :id is gameId
+  @Get('tick-score/:id')
+  @GameStates('STARTED')
+  async scoreTick(@Param('id') gameId: GameEntity) {
+    return this.scoreService.scoreTick(gameId);
+  }
+}
diff --git a/src/score/score.dto.ts b/src/score/score.dto.ts
new file mode 100644
index 0000000000000000000000000000000000000000..99955f56eff34a41ce46111d7fd0cb9cd597386f
--- /dev/null
+++ b/src/score/score.dto.ts
@@ -0,0 +1,10 @@
+import { IsNumber, Min, Max, IsUUID } from 'class-validator';
+
+export class ScoreDTO {
+  @IsNumber()
+  @Min(1)
+  @Max(99)
+  score: number;
+  @IsUUID('4')
+  faction: string;
+}
diff --git a/src/score/score.entity.ts b/src/score/score.entity.ts
new file mode 100644
index 0000000000000000000000000000000000000000..6ca9ab77b968060a6dc88c860425119914cec030
--- /dev/null
+++ b/src/score/score.entity.ts
@@ -0,0 +1,21 @@
+import {
+  Entity,
+  PrimaryGeneratedColumn,
+  Column,
+  ManyToOne,
+  Timestamp,
+  CreateDateColumn,
+} from 'typeorm';
+import { FactionEntity } from '../faction/faction.entity';
+
+@Entity('Score')
+export class ScoreEntity {
+  @PrimaryGeneratedColumn('uuid') scoreId: string;
+  @Column({ type: 'float' }) score: number;
+  @CreateDateColumn({ type: 'timestamp' }) scoreTimeStamp: Timestamp;
+
+  @ManyToOne(type => FactionEntity, factionName => factionName.factionId, {
+    onDelete: 'CASCADE',
+  })
+  faction: string;
+}
diff --git a/src/score/score.module.ts b/src/score/score.module.ts
new file mode 100644
index 0000000000000000000000000000000000000000..c04486fc676fca0d7c6a38c74374e03e23a1008c
--- /dev/null
+++ b/src/score/score.module.ts
@@ -0,0 +1,27 @@
+import { Module } from '@nestjs/common';
+import { TypeOrmModule } from '@nestjs/typeorm';
+
+import { ScoreController } from './score.controller';
+import { ScoreService } from './score.service';
+import { FactionEntity } from '../faction/faction.entity';
+import {
+  ObjectivePointEntity,
+  ObjectivePoint_HistoryEntity,
+} from '../game/game.entity';
+import { ScoreEntity } from './score.entity';
+import { NotificationModule } from '../notifications/notifications.module';
+
+@Module({
+  imports: [
+    TypeOrmModule.forFeature([
+      ScoreEntity,
+      ObjectivePointEntity,
+      ObjectivePoint_HistoryEntity,
+      FactionEntity,
+    ]),
+    NotificationModule,
+  ],
+  controllers: [ScoreController],
+  providers: [ScoreService],
+})
+export class ScoreModule {}
diff --git a/src/score/score.service.ts b/src/score/score.service.ts
new file mode 100644
index 0000000000000000000000000000000000000000..9dad4e965ae797b31a2f708a7008048556db0992
--- /dev/null
+++ b/src/score/score.service.ts
@@ -0,0 +1,96 @@
+import { Injectable, HttpException, HttpStatus } from '@nestjs/common';
+import { InjectRepository } from '@nestjs/typeorm';
+import { Repository } from 'typeorm';
+
+import { FactionEntity } from '../faction/faction.entity';
+import { ScoreDTO } from './score.dto';
+import {
+  ObjectivePoint_HistoryEntity,
+  ObjectivePointEntity,
+  GameEntity,
+} from '../game/game.entity';
+import { ScoreEntity } from './score.entity';
+import { NotificationGateway } from '../notifications/notifications.gateway';
+
+@Injectable()
+export class ScoreService {
+  constructor(
+    @InjectRepository(ScoreEntity)
+    private scoreRepository: Repository<ScoreEntity>,
+    @InjectRepository(ObjectivePointEntity)
+    private flagRepository: Repository<ObjectivePointEntity>,
+    @InjectRepository(ObjectivePoint_HistoryEntity)
+    private flagHistoryRepository: Repository<ObjectivePoint_HistoryEntity>,
+    @InjectRepository(FactionEntity)
+    private factionRepository: Repository<FactionEntity>,
+    private notificationGateway: NotificationGateway,
+  ) {}
+
+  async addScore(scoreData: ScoreDTO, gameId: GameEntity) {
+    // check if faction exists
+    const faction = await this.factionRepository.findOne({
+      factionId: scoreData.faction,
+    });
+    if (!faction) {
+      throw new HttpException('Faction was not found', HttpStatus.BAD_REQUEST);
+    }
+    // get the previous score and add it, if it exists
+    let lastScore = await this.scoreRepository.findOne({
+      where: { faction: scoreData.faction },
+      order: { scoreTimeStamp: 'DESC' },
+    });
+    if (lastScore) {
+      scoreData.score += lastScore.score;
+    }
+    // add the score for Faction
+    const newScore = await this.scoreRepository.create(scoreData);
+    await this.scoreRepository.insert(newScore);
+    return {
+      code: 201,
+      message: 'Score updated!',
+    };
+  }
+
+  async scoreTick(gameId) {
+    // get game's flagboxes
+    const flagboxes = await this.flagRepository.find({ game: gameId });
+    // create an array of DTOs for adding score
+    let scoreData = [];
+    await Promise.all(
+      flagboxes.map(async box => {
+        // get the newest entry in history
+        let current = await this.flagHistoryRepository.findOne({
+          where: { objective_point: box.objectivePointId },
+          relations: ['owner'],
+          order: { oP_HistoryTimestamp: 'DESC' },
+        });
+        // if result was found, add score to the owner
+        if (current.owner) {
+          let index = await scoreData.findIndex(
+            i => i.faction === current.owner.factionId,
+          );
+          index !== -1
+            ? await (scoreData[index]['score'] += box.objectivePointMultiplier)
+            : await scoreData.push({
+                score: box.objectivePointMultiplier,
+                faction: current.owner.factionId,
+              });
+        }
+      }),
+    );
+    scoreData.map(async data => {
+      await this.addScore(data, gameId);
+    });
+    this.notificationGateway.server.emit(gameId, { type: 'score-update' });
+    return {
+      code: 200,
+      message: 'Scores added',
+    };
+  }
+} //
+
+// Hae kaikki Objective pointit
+// aja map funktio pelin objective pointteihin
+// jokaisella objective point ID:llä hae historystä
+// relaatio, missä uusin timestamp
+// katso uusimmista history entrystä omistaja
diff --git a/src/shared/states.guard.ts b/src/shared/states.guard.ts
index 4a4b5d423685e8ca5c2bd68cf715c50750981cd7..9e85e94e40f92ed6b016e451c592a3025a684cad 100644
--- a/src/shared/states.guard.ts
+++ b/src/shared/states.guard.ts
@@ -19,6 +19,8 @@ export class StatesGuard implements CanActivate {
     private gameRepository: Repository<GameEntity>,
   ) {}
 
+  // Checks the state for gameId and grants access if it matches the criteria
+  // allowed states are CREATED, STARTED, PAUSED, ENDED
   async canActivate(context: ExecutionContext): Promise<boolean> {
     // get game states that are allowed access, identified by @GameStates('state') decorators in controllers
     const states = this.reflector.get<string[]>('states', context.getHandler());
diff --git a/src/task/task.controller.ts b/src/task/task.controller.ts
index acadbda71b34cb0ca591d974b383bca632cd22ce..8283ba5bd2c4d7da4eb668ac6268d5165930e3f4 100644
--- a/src/task/task.controller.ts
+++ b/src/task/task.controller.ts
@@ -1,7 +1,15 @@
-import { Controller, Post, Body, UsePipes, Get, Param } from '@nestjs/common';
+import {
+  Controller,
+  Post,
+  Body,
+  UsePipes,
+  Get,
+  Param,
+  Delete,
+} from '@nestjs/common';
 
 import { TaskService } from './task.service';
-import { CreateTaskDTO, EditTaskDTO } from './task.dto';
+import { CreateTaskDTO, EditTaskDTO, DeleteTaskDTO } from './task.dto';
 import { Roles } from '../shared/guard.decorator';
 import { ValidationPipe } from '../shared/validation.pipe';
 import { User } from '../user/user.decorator';
@@ -28,7 +36,16 @@ export class TaskController {
     return this.taskService.editTask(data);
   }
 
-  // lists all the tasks for the game if user has game_person entry
+  // deletes a created task if the user has admin role in the game
+  // :id is the id of the game
+  @Delete('delete-task/:id')
+  @Roles('admin')
+  @UsePipes(new ValidationPipe())
+  async deleteTask(@Param('id') id: string, @Body() data: DeleteTaskDTO) {
+    return this.taskService.deleteTask(data);
+  }
+
+  // lists all the tasks for the game if the user has game_person entry
   // :id is the id of the game
   @Get('get-tasks/:id')
   @Roles('soldier', 'factionleader', 'admin')
diff --git a/src/task/task.dto.ts b/src/task/task.dto.ts
index a8830d7a770f8337c81b1922dcf02751eaf4e6ad..a1576e7d12c9d9a6263b445fdba293fe94e8964a 100644
--- a/src/task/task.dto.ts
+++ b/src/task/task.dto.ts
@@ -36,3 +36,8 @@ export class EditTaskDTO {
   @IsUUID('4')
   taskGame: GameEntity;
 }
+
+export class DeleteTaskDTO {
+  @IsUUID('4')
+  taskId: string;
+}
diff --git a/src/task/task.entity.ts b/src/task/task.entity.ts
index c8f7d6218f373d8bd213e49dc7b9d6b2ab8ec68e..f1c1cf103fa4338a7f10d0305888d13c097d7a09 100644
--- a/src/task/task.entity.ts
+++ b/src/task/task.entity.ts
@@ -24,7 +24,9 @@ export class TaskEntity {
     onDelete: 'CASCADE',
   })
   taskWinner: FactionEntity;
-  @ManyToOne(type => GameEntity, game => game.id)
+  @ManyToOne(type => GameEntity, game => game.id, {
+    onDelete: 'CASCADE',
+  })
   @JoinColumn({ name: 'taskGame' })
   taskGame: GameEntity;
 }
diff --git a/src/task/task.service.ts b/src/task/task.service.ts
index abada374a0c79ae4627c0968b80ce8798fadab04..eedef60368fa3db271f072dd402d675a1e84a234 100644
--- a/src/task/task.service.ts
+++ b/src/task/task.service.ts
@@ -3,7 +3,7 @@ import { Repository } from 'typeorm';
 import { InjectRepository } from '@nestjs/typeorm';
 
 import { TaskEntity } from './task.entity';
-import { CreateTaskDTO, EditTaskDTO } from './task.dto';
+import { CreateTaskDTO, EditTaskDTO, DeleteTaskDTO } from './task.dto';
 import { FactionEntity } from '../faction/faction.entity';
 import { Game_PersonEntity } from '../game/game.entity';
 import { NotificationGateway } from '../notifications/notifications.gateway';
@@ -36,10 +36,11 @@ export class TaskService {
     // notify subscribers about a new task
     // if faction was set it notifies only faction members, else everyone
     this.notificationGateway.server.emit(
-      task.faction != null ? task.faction.toString() : 'global',
-      'new task',
+      task.faction != null ? task.faction.toString() : task.taskGame.toString(),
+      { type: 'task-update' },
     );
     return {
+      code: 201,
       message: 'Task added',
     };
   }
@@ -63,10 +64,23 @@ export class TaskService {
     task.taskIsActive = false;
     await this.taskRepository.save(task);
     return {
+      code: 201,
       message: 'Task updated and closed',
     };
   }
 
+  async deleteTask(data: DeleteTaskDTO) {
+    const task = await this.taskRepository.findOne({ taskId: data.taskId });
+    if (task) {
+      await this.taskRepository.delete({ taskId: task.taskId });
+      return {
+        code: 200,
+        message: 'Task deleted',
+      };
+    }
+    throw new HttpException('Task not found', HttpStatus.BAD_REQUEST);
+  }
+
   async fetchTasks(user, taskGame) {
     const gamePerson = await this.gamePersonRepository.findOne({
       where: {
@@ -78,23 +92,22 @@ export class TaskService {
     if (gamePerson.role == 'admin') {
       return await this.taskRepository.find({
         where: { taskGame: taskGame },
-        relations: ['faction'],
+        relations: ['faction', 'taskWinner'],
       });
     } else {
       return await this.taskRepository.find({
-        relations: ['faction'],
+        relations: ['faction', 'taskWinner'],
         where: [
           {
             taskGame: taskGame,
             faction: gamePerson.faction.factionId,
-            taskIsActive: true,
           },
           {
             taskGame: taskGame,
             faction: null,
-            taskIsActive: true,
           },
         ],
+        order: { taskIsActive: 'DESC' },
       });
     }
   }
diff --git a/src/tracking/tracking.entity.ts b/src/tracking/tracking.entity.ts
index b31239101176a0316031cf6c1449205a26bcd150..cabe141a42bcfe076588e320a6eed6c20c6ceaa9 100644
--- a/src/tracking/tracking.entity.ts
+++ b/src/tracking/tracking.entity.ts
@@ -5,6 +5,8 @@ import { Game_PersonEntity } from '../game/game.entity';
 export class TrackingEntity {
   @PrimaryGeneratedColumn('uuid') id: string;
   @Column({ type: 'json', nullable: true }) data: JSON;
-  @ManyToOne(type => Game_PersonEntity, person => person.gamepersonId)
+  @ManyToOne(type => Game_PersonEntity, person => person.gamepersonId, {
+    onDelete: 'CASCADE',
+  })
   gamepersonId: Game_PersonEntity;
 }