From d8b7b65c59344189e94e57088bc8d556eaa69259 Mon Sep 17 00:00:00 2001
From: Jan Tymel <410388@mail.muni.cz>
Date: Sat, 14 Nov 2020 20:16:35 +0100
Subject: [PATCH] First iteration of deployable application with in-memory H2
 DB

---
 pom.xml                                       | 211 ++++++++++--------
 .../com/example/demo/DemoApplication.java     |  54 ++---
 .../controller/GameDefinitionController.java  |  45 ++++
 .../example/demo/domain/AssessmentLevel.java  |  20 +-
 .../com/example/demo/domain/Attachment.java   |  13 ++
 .../com/example/demo/domain/BaseLevel.java    |  54 ++++-
 .../com/example/demo/domain/GameLevel.java    |  35 +--
 .../java/com/example/demo/domain/Hint.java    |  13 ++
 .../com/example/demo/domain/InfoLevel.java    |  19 +-
 .../com/example/demo/domain/UnityLevel.java   |  22 ++
 .../com/example/demo/dto/BaseLevelDto.java    |  27 ++-
 .../dto/input/GameDefinitionCreateDto.java    |  14 ++
 .../com/example/demo/dto/input/LevelType.java |   8 +
 .../demo/service/GameDefinitionService.java   |  14 ++
 src/main/resources/application.properties     |   8 +-
 15 files changed, 354 insertions(+), 203 deletions(-)
 create mode 100644 src/main/java/com/example/demo/controller/GameDefinitionController.java
 create mode 100644 src/main/java/com/example/demo/domain/UnityLevel.java
 create mode 100644 src/main/java/com/example/demo/dto/input/GameDefinitionCreateDto.java
 create mode 100644 src/main/java/com/example/demo/dto/input/LevelType.java
 create mode 100644 src/main/java/com/example/demo/service/GameDefinitionService.java

diff --git a/pom.xml b/pom.xml
index bf4f2abf..4ff45e95 100644
--- a/pom.xml
+++ b/pom.xml
@@ -1,113 +1,126 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
-	<modelVersion>4.0.0</modelVersion>
-	<parent>
-		<groupId>org.springframework.boot</groupId>
-		<artifactId>spring-boot-starter-parent</artifactId>
-		<version>2.2.4.RELEASE</version>
-		<relativePath/> <!-- lookup parent from repository -->
-	</parent>
-	<groupId>com.example</groupId>
-	<artifactId>demo</artifactId>
-	<version>0.0.1-SNAPSHOT</version>
-	<packaging>jar</packaging>
-	<name>demo</name>
-	<description>Demo project for Spring Boot</description>
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <groupId>org.springframework.boot</groupId>
+        <artifactId>spring-boot-starter-parent</artifactId>
+        <version>2.2.4.RELEASE</version>
+        <relativePath/> <!-- lookup parent from repository -->
+    </parent>
+    <groupId>com.example</groupId>
+    <artifactId>demo</artifactId>
+    <version>0.0.1-SNAPSHOT</version>
+    <packaging>jar</packaging>
+    <name>demo</name>
+    <description>Demo project for Spring Boot</description>
 
-	<properties>
-		<java.version>11</java.version>
+    <properties>
+        <java.version>11</java.version>
 
-		<projectlombok.version>1.18.12</projectlombok.version>
-		<org.mapstruct.version>1.3.1.Final</org.mapstruct.version>
-	</properties>
+        <projectlombok.version>1.18.12</projectlombok.version>
+        <org.mapstruct.version>1.3.1.Final</org.mapstruct.version>
+    </properties>
 
-	<dependencies>
-		<dependency>
-			<groupId>org.springframework.boot</groupId>
-			<artifactId>spring-boot-starter-data-jpa</artifactId>
-		</dependency>
-		<dependency>
-			<groupId>org.springframework.boot</groupId>
-			<artifactId>spring-boot-starter-web</artifactId>
-		</dependency>
+    <dependencies>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-data-jpa</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-web</artifactId>
+        </dependency>
 
-		<dependency>
-			<groupId>org.springframework.boot</groupId>
-			<artifactId>spring-boot-starter-tomcat</artifactId>
-			<scope>provided</scope>
-		</dependency>
-		<dependency>
-			<groupId>org.springframework.boot</groupId>
-			<artifactId>spring-boot-starter-test</artifactId>
-			<scope>test</scope>
-			<exclusions>
-				<exclusion>
-					<groupId>org.junit.vintage</groupId>
-					<artifactId>junit-vintage-engine</artifactId>
-				</exclusion>
-			</exclusions>
-		</dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-tomcat</artifactId>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-test</artifactId>
+            <scope>test</scope>
+            <exclusions>
+                <exclusion>
+                    <groupId>org.junit.vintage</groupId>
+                    <artifactId>junit-vintage-engine</artifactId>
+                </exclusion>
+            </exclusions>
+        </dependency>
 
-		<dependency>
-			<groupId>org.projectlombok</groupId>
-			<artifactId>lombok</artifactId>
-			<version>1.18.12</version>
-<!--			<version>${projectlombok.version}</version>-->
-		</dependency>
+        <!--		TODO: just for development purposes-->
+<!--        <dependency>-->
+<!--            <groupId>com.h2database</groupId>-->
+<!--            <artifactId>h2</artifactId>-->
+<!--            <version>1.4.200</version>-->
+<!--        </dependency>-->
 
-		<dependency>
-			<groupId>org.mapstruct</groupId>
-			<artifactId>mapstruct</artifactId>
-			<version>1.3.1.Final</version>
-<!--			<version>${org.mapstruct.version}</version>-->
-		</dependency>
+        <dependency>
+            <groupId>com.h2database</groupId>
+            <artifactId>h2</artifactId>
+            <scope>runtime</scope>
+        </dependency>
 
-		<dependency>
-			<groupId>org.apache.commons</groupId>
-			<artifactId>commons-collections4</artifactId>
-			<version>4.4</version>
-		</dependency>
+        <dependency>
+            <groupId>org.projectlombok</groupId>
+            <artifactId>lombok</artifactId>
+            <version>1.18.12</version>
+            <!--			<version>${projectlombok.version}</version>-->
+        </dependency>
 
-		<!-- swagger -->
-		<dependency>
-			<groupId>io.springfox</groupId>
-			<artifactId>springfox-swagger2</artifactId>
-			<version>2.9.2</version>
-<!--			<version>${swagger.version}</version>-->
-		</dependency>
-		<dependency>
-			<groupId>io.springfox</groupId>
-			<artifactId>springfox-swagger-ui</artifactId>
-			<version>2.9.2</version>
-<!--			<version>${swagger.version}</version>-->
-		</dependency>
-	</dependencies>
+        <dependency>
+            <groupId>org.mapstruct</groupId>
+            <artifactId>mapstruct</artifactId>
+            <version>1.3.1.Final</version>
+            <!--			<version>${org.mapstruct.version}</version>-->
+        </dependency>
 
-	<build>
-		<plugins>
-			<plugin>
-				<groupId>org.springframework.boot</groupId>
-				<artifactId>spring-boot-maven-plugin</artifactId>
-			</plugin>
+        <dependency>
+            <groupId>org.apache.commons</groupId>
+            <artifactId>commons-collections4</artifactId>
+            <version>4.4</version>
+        </dependency>
 
-			<plugin>
-				<groupId>org.apache.maven.plugins</groupId>
-				<artifactId>maven-compiler-plugin</artifactId>
-				<version>3.5.1</version>
-				<configuration>
-					<source>11</source>
-					<target>11</target>
-					<annotationProcessorPaths>
-						<path>
-							<groupId>org.mapstruct</groupId>
-							<artifactId>mapstruct-processor</artifactId>
-							<version>${org.mapstruct.version}</version>
-						</path>
-					</annotationProcessorPaths>
-				</configuration>
-			</plugin>
-		</plugins>
-	</build>
+        <!-- swagger -->
+        <dependency>
+            <groupId>io.springfox</groupId>
+            <artifactId>springfox-swagger2</artifactId>
+            <version>2.9.2</version>
+            <!--			<version>${swagger.version}</version>-->
+        </dependency>
+        <dependency>
+            <groupId>io.springfox</groupId>
+            <artifactId>springfox-swagger-ui</artifactId>
+            <version>2.9.2</version>
+            <!--			<version>${swagger.version}</version>-->
+        </dependency>
+    </dependencies>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.springframework.boot</groupId>
+                <artifactId>spring-boot-maven-plugin</artifactId>
+            </plugin>
+
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-compiler-plugin</artifactId>
+                <version>3.5.1</version>
+                <configuration>
+                    <source>11</source>
+                    <target>11</target>
+                    <annotationProcessorPaths>
+                        <path>
+                            <groupId>org.mapstruct</groupId>
+                            <artifactId>mapstruct-processor</artifactId>
+                            <version>${org.mapstruct.version}</version>
+                        </path>
+                    </annotationProcessorPaths>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
 
 </project>
diff --git a/src/main/java/com/example/demo/DemoApplication.java b/src/main/java/com/example/demo/DemoApplication.java
index cc28f6ce..b619423f 100644
--- a/src/main/java/com/example/demo/DemoApplication.java
+++ b/src/main/java/com/example/demo/DemoApplication.java
@@ -23,31 +23,31 @@ public class DemoApplication {
         SpringApplication.run(DemoApplication.class, args);
     }
 
-    @Bean
-    CommandLineRunner anotherDemo(GameLevelRepository gameLevelRepository) {
-        return args -> {
-
-            gameLevelRepository.deleteAll();
-
-            GameLevel gameLevel = new GameLevel();
-            gameLevel.setTitle("Title");
-
-
-            GameLevel savedGameLevel = gameLevelRepository.save(gameLevel);
-            log.info("Saved game level: {}", savedGameLevel);
-
-            Optional<GameLevel> foundGameLevel = gameLevelRepository.findById(savedGameLevel.getId());
-            log.info("Saved game level: {}", foundGameLevel);
-        };
-    }
-
-    @Bean
-    CommandLineRunner yetAnotherDemo(GameLevelService gameLevelService) {
-        return args -> {
-
-            List<GameLevelDto> allGameLevels = gameLevelService.findAllGameLevels();
-            allGameLevels.forEach(gameLevel -> log.info("Found game level with ID {} and title {}", gameLevel.getId(),
-                                                        gameLevel.getTitle()));
-        };
-    }
+//    @Bean
+//    CommandLineRunner anotherDemo(GameLevelRepository gameLevelRepository) {
+//        return args -> {
+//
+//            gameLevelRepository.deleteAll();
+//
+//            GameLevel gameLevel = new GameLevel();
+//            gameLevel.setTitle("Title");
+//
+//
+//            GameLevel savedGameLevel = gameLevelRepository.save(gameLevel);
+//            log.info("Saved game level: {}", savedGameLevel);
+//
+//            Optional<GameLevel> foundGameLevel = gameLevelRepository.findById(savedGameLevel.getId());
+//            log.info("Saved game level: {}", foundGameLevel);
+//        };
+//    }
+//
+//    @Bean
+//    CommandLineRunner yetAnotherDemo(GameLevelService gameLevelService) {
+//        return args -> {
+//
+//            List<GameLevelDto> allGameLevels = gameLevelService.findAllGameLevels();
+//            allGameLevels.forEach(gameLevel -> log.info("Found game level with ID {} and title {}", gameLevel.getId(),
+//                                                        gameLevel.getTitle()));
+//        };
+//    }
 }
diff --git a/src/main/java/com/example/demo/controller/GameDefinitionController.java b/src/main/java/com/example/demo/controller/GameDefinitionController.java
new file mode 100644
index 00000000..7b27160b
--- /dev/null
+++ b/src/main/java/com/example/demo/controller/GameDefinitionController.java
@@ -0,0 +1,45 @@
+package com.example.demo.controller;
+
+import com.example.demo.dto.input.GameDefinitionCreateDto;
+import com.example.demo.service.GameDefinitionService;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import io.swagger.annotations.ApiParam;
+import io.swagger.annotations.ApiResponse;
+import io.swagger.annotations.ApiResponses;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.MediaType;
+import org.springframework.web.bind.annotation.CrossOrigin;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RestController;
+
+@RestController
+@RequestMapping("/game-definition")
+@CrossOrigin(origins = "*", allowCredentials = "true", allowedHeaders = "*",
+             methods = {RequestMethod.GET, RequestMethod.POST, RequestMethod.DELETE, RequestMethod.PUT})
+@Api(value = "/game-definition", tags = {"Game Definition"})
+public class GameDefinitionController {
+
+    private static final Logger LOG = LoggerFactory.getLogger(GameDefinitionController.class);
+
+    private final GameDefinitionService gameDefinitionService;
+
+    @Autowired
+    public GameDefinitionController(GameDefinitionService gameDefinitionService) {
+        this.gameDefinitionService = gameDefinitionService;
+    }
+
+    @PostMapping(produces = MediaType.APPLICATION_JSON_VALUE)
+    @ApiOperation(value = "Create a new game definition")
+    @ApiResponses(value = {@ApiResponse(code = 200, message = "New game definition created"),
+                           @ApiResponse(code = 500, message = "Unexpected application error")})
+    public GameDefinitionCreateDto createGameLevel(@ApiParam(value = "Game definition", required = true) @RequestBody(required = true)
+                                            GameDefinitionCreateDto gameLevelCreateDto) {
+        return gameDefinitionService.createGameDefinition(gameLevelCreateDto);
+    }
+}
diff --git a/src/main/java/com/example/demo/domain/AssessmentLevel.java b/src/main/java/com/example/demo/domain/AssessmentLevel.java
index ac25e69a..a2340630 100644
--- a/src/main/java/com/example/demo/domain/AssessmentLevel.java
+++ b/src/main/java/com/example/demo/domain/AssessmentLevel.java
@@ -2,27 +2,12 @@ package com.example.demo.domain;
 
 
 import javax.persistence.Entity;
-import javax.persistence.GeneratedValue;
-import javax.persistence.Id;
 
 @Entity
 public class AssessmentLevel extends BaseLevel {
 
-    @Id
-    @GeneratedValue
-    private Long id;
-
     private String assessmentType;
 
-
-    public Long getId() {
-        return id;
-    }
-
-    public void setId(Long id) {
-        this.id = id;
-    }
-
     public String getAssessmentType() {
         return assessmentType;
     }
@@ -33,9 +18,6 @@ public class AssessmentLevel extends BaseLevel {
 
     @Override
     public String toString() {
-        return "AssessmentLevel{" +
-            "id=" + id +
-            ", assessmentType='" + assessmentType + '\'' +
-            "} " + super.toString();
+        return "AssessmentLevel{" + ", assessmentType='" + assessmentType + '\'' + "} " + super.toString();
     }
 }
diff --git a/src/main/java/com/example/demo/domain/Attachment.java b/src/main/java/com/example/demo/domain/Attachment.java
index 0231a99b..439aaded 100644
--- a/src/main/java/com/example/demo/domain/Attachment.java
+++ b/src/main/java/com/example/demo/domain/Attachment.java
@@ -1,8 +1,10 @@
 package com.example.demo.domain;
 
 import javax.persistence.Entity;
+import javax.persistence.FetchType;
 import javax.persistence.GeneratedValue;
 import javax.persistence.Id;
+import javax.persistence.ManyToOne;
 import java.time.LocalDateTime;
 
 @Entity
@@ -15,6 +17,9 @@ public class Attachment {
     private String content;
     private LocalDateTime creationTime;
 
+    @ManyToOne(fetch = FetchType.LAZY)
+    private GameLevel gameLevel;
+
     public Long getId() {
         return id;
     }
@@ -39,6 +44,14 @@ public class Attachment {
         this.creationTime = creationTime;
     }
 
+    public GameLevel getGameLevel() {
+        return gameLevel;
+    }
+
+    public void setGameLevel(GameLevel gameLevel) {
+        this.gameLevel = gameLevel;
+    }
+
     @Override
     public String toString() {
         return "Attachment{" + "id=" + id + ", content='" + content + '\'' + ", creationTime=" + creationTime + '}';
diff --git a/src/main/java/com/example/demo/domain/BaseLevel.java b/src/main/java/com/example/demo/domain/BaseLevel.java
index adc11e19..37f6ddf3 100644
--- a/src/main/java/com/example/demo/domain/BaseLevel.java
+++ b/src/main/java/com/example/demo/domain/BaseLevel.java
@@ -1,13 +1,32 @@
 package com.example.demo.domain;
 
 
-import javax.persistence.MappedSuperclass;
+import javax.persistence.Entity;
+import javax.persistence.FetchType;
+import javax.persistence.GeneratedValue;
+import javax.persistence.Id;
+import javax.persistence.Inheritance;
+import javax.persistence.InheritanceType;
+import javax.persistence.ManyToOne;
 
-@MappedSuperclass
+
+// good source for entity inheritance: http://blog.marcinchwedczuk.pl/mapping-inheritance-in-hibernate
+
+@Entity
+@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
 public abstract class BaseLevel {
+
+    @Id
+    @GeneratedValue
+    private Long id;
+
     private String title;
     private String estimatedDuration;
     private Long maxScore;
+    private Integer orderInTrainingDefinition;
+
+    @ManyToOne(fetch = FetchType.LAZY)
+    private UnityLevel unityLevel;
 
     public String getTitle() {
         return title;
@@ -33,12 +52,33 @@ public abstract class BaseLevel {
         this.maxScore = maxScore;
     }
 
+    public Integer getOrderInTrainingDefinition() {
+        return orderInTrainingDefinition;
+    }
+
+    public void setOrderInTrainingDefinition(Integer orderInTrainingDefinition) {
+        this.orderInTrainingDefinition = orderInTrainingDefinition;
+    }
+
+    public Long getId() {
+        return id;
+    }
+
+    public void setId(Long id) {
+        this.id = id;
+    }
+
+    public UnityLevel getUnityLevel() {
+        return unityLevel;
+    }
+
+    public void setUnityLevel(UnityLevel unityLevel) {
+        this.unityLevel = unityLevel;
+    }
+
     @Override
     public String toString() {
-        return "BaseLevel{" +
-            "title='" + title + '\'' +
-            ", estimatedDuration='" + estimatedDuration + '\'' +
-            ", maxScore=" + maxScore +
-            '}';
+        return "BaseLevel{" + "title='" + title + '\'' + ", estimatedDuration='" + estimatedDuration + '\'' +
+               ", maxScore=" + maxScore + '}';
     }
 }
diff --git a/src/main/java/com/example/demo/domain/GameLevel.java b/src/main/java/com/example/demo/domain/GameLevel.java
index fbbe2dba..4edf0956 100644
--- a/src/main/java/com/example/demo/domain/GameLevel.java
+++ b/src/main/java/com/example/demo/domain/GameLevel.java
@@ -1,8 +1,10 @@
 package com.example.demo.domain;
 
+import javax.persistence.CascadeType;
 import javax.persistence.Entity;
-import javax.persistence.GeneratedValue;
-import javax.persistence.Id;
+import javax.persistence.FetchType;
+import javax.persistence.OneToMany;
+import javax.persistence.OrderBy;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Objects;
@@ -11,28 +13,20 @@ import java.util.Objects;
 @Entity
 public class GameLevel extends BaseLevel {
 
-    @Id
-    @GeneratedValue
-    private Long id;
-
     private String content;
     private boolean solutionPenalized;
     private String flag;
     private String solution;
     private Long incorrectFlagLimit;
 
+    @OrderBy
+    @OneToMany(mappedBy = "gameLevel", cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.LAZY)
     private List<Attachment> attachments;
 
+    @OrderBy
+    @OneToMany(mappedBy = "gameLevel", cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.LAZY)
     private List<Hint> hints;
 
-    public Long getId() {
-        return id;
-    }
-
-    public void setId(Long id) {
-        this.id = id;
-    }
-
     public String getContent() {
         return content;
     }
@@ -94,15 +88,8 @@ public class GameLevel extends BaseLevel {
 
     @Override
     public String toString() {
-        return "GameLevel{" +
-            "id=" + id +
-            ", content='" + content + '\'' +
-            ", solutionPenalized='" + solutionPenalized + '\'' +
-            ", flag='" + flag + '\'' +
-            ", solution='" + solution + '\'' +
-            ", attachments='" + attachments + '\'' +
-            ", incorrectFlagLimit='" + incorrectFlagLimit + '\'' +
-            ", hints=" + hints +
-            "} " + super.toString();
+        return "GameLevel{" + ", content='" + content + '\'' + ", solutionPenalized='" + solutionPenalized + '\'' +
+               ", flag='" + flag + '\'' + ", solution='" + solution + '\'' + ", attachments='" + attachments + '\'' +
+               ", incorrectFlagLimit='" + incorrectFlagLimit + '\'' + ", hints=" + hints + "} " + super.toString();
     }
 }
diff --git a/src/main/java/com/example/demo/domain/Hint.java b/src/main/java/com/example/demo/domain/Hint.java
index c820873d..40217ed6 100644
--- a/src/main/java/com/example/demo/domain/Hint.java
+++ b/src/main/java/com/example/demo/domain/Hint.java
@@ -2,8 +2,10 @@ package com.example.demo.domain;
 
 
 import javax.persistence.Entity;
+import javax.persistence.FetchType;
 import javax.persistence.GeneratedValue;
 import javax.persistence.Id;
+import javax.persistence.ManyToOne;
 
 @Entity
 public class Hint {
@@ -17,6 +19,9 @@ public class Hint {
     private Long hintPenalty;
     private Long orderInLevel;
 
+    @ManyToOne(fetch = FetchType.LAZY)
+    private GameLevel gameLevel;
+
     public Long getId() {
         return id;
     }
@@ -57,6 +62,14 @@ public class Hint {
         this.orderInLevel = orderInLevel;
     }
 
+    public GameLevel getGameLevel() {
+        return gameLevel;
+    }
+
+    public void setGameLevel(GameLevel gameLevel) {
+        this.gameLevel = gameLevel;
+    }
+
     @Override
     public String toString() {
         return "Hint{" +
diff --git a/src/main/java/com/example/demo/domain/InfoLevel.java b/src/main/java/com/example/demo/domain/InfoLevel.java
index 49de0947..f862d565 100644
--- a/src/main/java/com/example/demo/domain/InfoLevel.java
+++ b/src/main/java/com/example/demo/domain/InfoLevel.java
@@ -1,26 +1,12 @@
 package com.example.demo.domain;
 
 import javax.persistence.Entity;
-import javax.persistence.GeneratedValue;
-import javax.persistence.Id;
 
 @Entity
 public class InfoLevel extends BaseLevel {
 
-    @Id
-    @GeneratedValue
-    private Long id;
-
     private String content;
 
-    public Long getId() {
-        return id;
-    }
-
-    public void setId(Long id) {
-        this.id = id;
-    }
-
     public String getContent() {
         return content;
     }
@@ -31,9 +17,6 @@ public class InfoLevel extends BaseLevel {
 
     @Override
     public String toString() {
-        return "InfoLevel{" +
-            "id=" + id +
-            ", content='" + content + '\'' +
-            "} " + super.toString();
+        return "InfoLevel{" + ", content='" + content + '\'' + "} " + super.toString();
     }
 }
diff --git a/src/main/java/com/example/demo/domain/UnityLevel.java b/src/main/java/com/example/demo/domain/UnityLevel.java
new file mode 100644
index 00000000..3b145a38
--- /dev/null
+++ b/src/main/java/com/example/demo/domain/UnityLevel.java
@@ -0,0 +1,22 @@
+package com.example.demo.domain;
+
+import javax.persistence.CascadeType;
+import javax.persistence.Entity;
+import javax.persistence.FetchType;
+import javax.persistence.GeneratedValue;
+import javax.persistence.Id;
+import javax.persistence.OneToMany;
+import javax.persistence.OrderBy;
+import java.util.List;
+
+@Entity
+public class UnityLevel {
+
+    @Id
+    @GeneratedValue
+    private Long id;
+
+    @OrderBy
+    @OneToMany(mappedBy = "unityLevel", cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.LAZY)
+    private List<BaseLevel> subLevels;
+}
diff --git a/src/main/java/com/example/demo/dto/BaseLevelDto.java b/src/main/java/com/example/demo/dto/BaseLevelDto.java
index fb0ea942..b00c134c 100644
--- a/src/main/java/com/example/demo/dto/BaseLevelDto.java
+++ b/src/main/java/com/example/demo/dto/BaseLevelDto.java
@@ -2,12 +2,22 @@ package com.example.demo.dto;
 
 import java.io.Serializable;
 
-public class BaseLevelDto implements Serializable {
+public abstract class BaseLevelDto implements Serializable {
 
+    private Long id;
     private String title;
+    private Integer order;
     private String estimatedDuration;
     private Long maxScore;
 
+    public Long getId() {
+        return id;
+    }
+
+    public void setId(Long id) {
+        this.id = id;
+    }
+
     public String getTitle() {
         return title;
     }
@@ -16,6 +26,14 @@ public class BaseLevelDto implements Serializable {
         this.title = title;
     }
 
+    public Integer getOrder() {
+        return order;
+    }
+
+    public void setOrder(Integer order) {
+        this.order = order;
+    }
+
     public String getEstimatedDuration() {
         return estimatedDuration;
     }
@@ -34,10 +52,7 @@ public class BaseLevelDto implements Serializable {
 
     @Override
     public String toString() {
-        return "BaseLevelDto{" +
-            "title='" + title + '\'' +
-            ", estimatedDuration='" + estimatedDuration + '\'' +
-            ", maxScore=" + maxScore +
-            '}';
+        return "BaseLevelDto{" + "id=" + id + ", title='" + title + '\'' + ", order=" + order +
+               ", estimatedDuration='" + estimatedDuration + '\'' + ", maxScore=" + maxScore + '}';
     }
 }
diff --git a/src/main/java/com/example/demo/dto/input/GameDefinitionCreateDto.java b/src/main/java/com/example/demo/dto/input/GameDefinitionCreateDto.java
new file mode 100644
index 00000000..60ead660
--- /dev/null
+++ b/src/main/java/com/example/demo/dto/input/GameDefinitionCreateDto.java
@@ -0,0 +1,14 @@
+package com.example.demo.dto.input;
+
+import lombok.Data;
+
+import java.util.List;
+
+@Data
+public class GameDefinitionCreateDto {
+    private Long id;
+    private String title;
+    private Integer order;
+    private LevelType type;
+    private List<? extends GameDefinitionCreateDto> subLevels;
+}
diff --git a/src/main/java/com/example/demo/dto/input/LevelType.java b/src/main/java/com/example/demo/dto/input/LevelType.java
new file mode 100644
index 00000000..9b0c5cd3
--- /dev/null
+++ b/src/main/java/com/example/demo/dto/input/LevelType.java
@@ -0,0 +1,8 @@
+package com.example.demo.dto.input;
+
+public enum LevelType {
+    ASSESSMENT,
+    GAME,
+    INFO,
+    UNITY
+}
diff --git a/src/main/java/com/example/demo/service/GameDefinitionService.java b/src/main/java/com/example/demo/service/GameDefinitionService.java
new file mode 100644
index 00000000..3e343398
--- /dev/null
+++ b/src/main/java/com/example/demo/service/GameDefinitionService.java
@@ -0,0 +1,14 @@
+package com.example.demo.service;
+
+import com.example.demo.dto.input.GameDefinitionCreateDto;
+import org.springframework.stereotype.Service;
+
+@Service
+public class GameDefinitionService {
+
+    public GameDefinitionCreateDto createGameDefinition(GameDefinitionCreateDto gameDefinitionCreateDto) {
+
+
+        return null;
+    }
+}
diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties
index 13c2b023..5e482e30 100644
--- a/src/main/resources/application.properties
+++ b/src/main/resources/application.properties
@@ -1,3 +1,5 @@
-spring.data.neo4j.username=neo4j
-spring.data.neo4j.password=password
-
+#spring.datasource.url=jdbc:h2:mem:testdb
+#spring.datasource.driverClassName=org.h2.Driver
+#spring.datasource.username=sa
+#spring.datasource.password=password
+#spring.jpa.database-platform=org.hibernate.dialect.H2Dialect
-- 
GitLab