From 1d7ab7fa2b998a2635a8b515fc73e9f61ab310ec Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Janis=20Daniel=20Da=CC=88hne?=
 <janis.daehne2@student.uni-halle.de>
Date: Sun, 28 Jul 2019 16:19:49 +0200
Subject: [PATCH] - added migration to remove assets from db because they are
 now in the file system - removed asset connected props

---
 src/ClientServer/Config/Constants.cs          |    2 +-
 .../EditCustomProjectController.cs            |   86 -
 .../DoExerciseAfterSolutionController.cs      |   75 +-
 .../Exercises/ExerciseOverviewController.cs   |    8 +
 .../TutorViewAssessmentController.cs          |    3 -
 src/ClientServer/Db/YapexDbContext.cs         |   35 +-
 ...190728133647_RemoveOldDbAssets.Designer.cs | 2106 +++++++++++++++++
 .../20190728133647_RemoveOldDbAssets.cs       |  157 ++
 .../SyndromDbContextModelSnapshot.cs          |  135 --
 .../CustomProjectDescription.cs               |    4 -
 .../CustomProjects/CustomProjectTest.cs       |    6 -
 src/ClientServer/Models/Exercises/Asset.cs    |   36 -
 .../Models/Exercises/ExerciseDescription.cs   |    6 -
 .../Models/Exercises/Tests/CustomTest.cs      |    7 -
 .../Models/Exercises/Tests/CustomTestAsset.cs |   39 -
 .../Models/Exercises/Tests/Test.cs            |    6 -
 .../Models/Exercises/Tests/TestAsset.cs       |   35 -
 .../Models/Interfaces/IDescription.cs         |    4 -
 .../Workers/SubmissionAssessmentWorker.cs     |    4 +-
 19 files changed, 2314 insertions(+), 440 deletions(-)
 create mode 100755 src/ClientServer/Migrations/20190728133647_RemoveOldDbAssets.Designer.cs
 create mode 100755 src/ClientServer/Migrations/20190728133647_RemoveOldDbAssets.cs
 delete mode 100644 src/ClientServer/Models/Exercises/Asset.cs
 delete mode 100644 src/ClientServer/Models/Exercises/Tests/CustomTestAsset.cs
 delete mode 100644 src/ClientServer/Models/Exercises/Tests/TestAsset.cs

diff --git a/src/ClientServer/Config/Constants.cs b/src/ClientServer/Config/Constants.cs
index 4beb412..7a314f3 100644
--- a/src/ClientServer/Config/Constants.cs
+++ b/src/ClientServer/Config/Constants.cs
@@ -13,7 +13,7 @@ namespace ClientServer.Helpers
     /// </summary>
     public static class Constants
     {
-        public static string VersionString = "2.4.0";
+        public static string VersionString = "2.4.1";
 
         /// <summary>
         /// this is only set once at program.cs!!
diff --git a/src/ClientServer/Controllers/Core/CustomProjects/EditCustomProjectController.cs b/src/ClientServer/Controllers/Core/CustomProjects/EditCustomProjectController.cs
index dfde90a..fb5a461 100644
--- a/src/ClientServer/Controllers/Core/CustomProjects/EditCustomProjectController.cs
+++ b/src/ClientServer/Controllers/Core/CustomProjects/EditCustomProjectController.cs
@@ -403,7 +403,6 @@ namespace ClientServer.Controllers.Core.customProjects
                 Description = new CustomProjectDescription()
                 {
                     Content = customProjectFromFrontend.Description.Content,
-                    Assets = new List<Asset>() //managed via separate api calls
                 },
                 Tests = tests,
                 Solutions = new List<CustomProjectSolution>() {solution},
@@ -650,7 +649,6 @@ namespace ClientServer.Controllers.Core.customProjects
                     .Where(p => p.UserId == userId && //just ensure the project is from the current user
                                 p.Id == customProjectId)
                     .Include(p => p.Description)
-                    .ThenInclude(p => p.Assets)
                     .FirstOrDefaultAsync()
                 ;
 
@@ -983,90 +981,6 @@ namespace ClientServer.Controllers.Core.customProjects
             await Response.WriteAsync(Jc.Serialize(new BasicResponse(ResponseCode.Ok, "")));
         }
 
-
-        /// <summary>
-        /// gets (downloads) the custom project test asset
-        /// </summary>
-        /// <param name="customProjectId">the custom project</param>
-        /// <param name="testId">the test id</param>
-        /// <param name="assetId">the asset id</param>
-        [HttpGet("asset/{customProjectId}/{testId}/{assetId}")]
-        public async Task GetCustomProjectTestAsset(int customProjectId, int testId, int assetId)
-        {
-            if (!await base.IsLoggedIn()) return;
-
-            int userId = GetUserId();
-
-
-            var test = await _context.CustomProjectTests
-                    .Include(p => p.TestAssets)
-                    .Where(p => p.Id == testId && p.CustomProjectId == customProjectId &&
-                                p.CustomProject.UserId == userId)
-                    .Select(p => new
-                    {
-                        Asset = p.TestAssets.FirstOrDefault(_asset => _asset.Id == assetId)
-                    })
-                    .FirstOrDefaultAsync()
-                ;
-
-
-            if (test == null)
-            {
-                Response.StatusCode = 406;
-                await
-                    Response.WriteAsync(Jc.Serialize(new BasicResponse(ResponseCode.NotFound, "test not found")));
-                return;
-            }
-
-            if (test.Asset == null)
-            {
-                Response.StatusCode = 406;
-                await
-                    Response.WriteAsync(Jc.Serialize(new BasicResponse(ResponseCode.NotFound, "asset not found")));
-                return;
-            }
-
-            var fileName = "asset";
-            if (Files.ValidFileName(test.Asset.DisplayName))
-            {
-                fileName = test.Asset.DisplayName;
-            }
-            else
-            {
-                //just try to get a file extension...
-
-                var lastIndex = test.Asset.DisplayName.LastIndexOf(".", StringComparison.Ordinal);
-                if (lastIndex == -1)
-                {
-                    //no file extension...
-                    //TODO maybe get from mime type somehow?
-                }
-                else
-                {
-                    var extension = test.Asset.DisplayName.Substring(lastIndex);
-                    fileName += extension;
-                }
-            }
-
-            var asset = new TestAsset()
-            {
-                Id = test.Asset.Id,
-                Content = test.Asset.Content,
-                DisplayName = fileName,
-                MimeType = test.Asset.MimeType,
-            };
-
-
-            Response.Headers.Add(new KeyValuePair<string, StringValues>("Content-Disposition",
-                "attachment; filename=\"" + asset.DisplayName + "\""));
-
-            byte[] content = asset.Content;
-
-
-            Response.Body.Write(content, 0, content.Length);
-            await Response.Body.FlushAsync();
-        }
-
         [HttpPost("{customProjectId}/properties")]
         public async Task UpdateCustomProjectProperties(int customProjectId,
             [FromBody] CustomProjectPropertiesFromFrontend propertiesFromFrontend)
diff --git a/src/ClientServer/Controllers/Core/Exercises/DoExerciseAfterSolution/DoExerciseAfterSolutionController.cs b/src/ClientServer/Controllers/Core/Exercises/DoExerciseAfterSolution/DoExerciseAfterSolutionController.cs
index 537e39a..c36d5a0 100644
--- a/src/ClientServer/Controllers/Core/Exercises/DoExerciseAfterSolution/DoExerciseAfterSolutionController.cs
+++ b/src/ClientServer/Controllers/Core/Exercises/DoExerciseAfterSolution/DoExerciseAfterSolutionController.cs
@@ -61,12 +61,12 @@ namespace ClientServer.Controllers.Core.Exercises.DoExerciseAfterSolution
                 return;
             }
 
-            ExerciseReleaseWithUserAsParticipation releaseWithUserAsParticipation =  await _context
+            ExerciseReleaseWithUserAsParticipation releaseWithUserAsParticipation = await _context
                 .ExerciseReleaseWithUserAsParticipations
                 .Include(p => p.ExerciseRelease)
                 .ThenInclude(p => p.Exercise.CodeTemplates)
                 .ThenInclude(p => p.TemplateFiles)
-                .FirstOrDefaultAsync(p => p.UserId == targetUserId && p.ExerciseRelease.GeneratedCode == generatedCode); 
+                .FirstOrDefaultAsync(p => p.UserId == targetUserId && p.ExerciseRelease.GeneratedCode == generatedCode);
 
 
             if (releaseWithUserAsParticipation == null)
@@ -95,17 +95,18 @@ namespace ClientServer.Controllers.Core.Exercises.DoExerciseAfterSolution
             else
             {
                 await
-                    Response.WriteAsync(Jc.Serialize(new BasicResponse(ResponseCode.InvalidRequest, "normal solution still active")));
+                    Response.WriteAsync(Jc.Serialize(new BasicResponse(ResponseCode.InvalidRequest,
+                        "normal solution still active")));
                 return;
             }
 
 
-            var afterSolution =  await _context.AfterSolutions
+            var afterSolution = await _context.AfterSolutions
                     .Include(p => p.SolutionFiles)
                     .ThenInclude(p => p.TemplateFile)
                     .FirstOrDefaultAsync(p => p.SolutionUserId == targetUserId &&
-                                         p.SolutionExerciseReleaseId == release.Id &&
-                                         p.SolutionPLangId == pLang.Id)
+                                              p.SolutionExerciseReleaseId == release.Id &&
+                                              p.SolutionPLangId == pLang.Id)
                 ;
 
             if (afterSolution == null)
@@ -137,10 +138,10 @@ namespace ClientServer.Controllers.Core.Exercises.DoExerciseAfterSolution
                             "code template not found")));
                 return;
             }
-            
+
             //template files should be loaded 
             var errorMsg = UserSolutionHelper.ReplaceReadonlyFiles(afterSolution, codeTemplate, true, false);
-            
+
             if (errorMsg != null)
             {
                 await
@@ -183,6 +184,7 @@ namespace ClientServer.Controllers.Core.Exercises.DoExerciseAfterSolution
                         //await Response.WriteAsync(Jc.Serialize(new BasicResponse(false, "file not found")));
                         //return;
                     }
+
                     isContentVisibleForUser = true;
                 }
                 else
@@ -263,19 +265,20 @@ namespace ClientServer.Controllers.Core.Exercises.DoExerciseAfterSolution
             else
             {
                 await
-                    Response.WriteAsync(Jc.Serialize(new BasicResponse(ResponseCode.InvalidRequest, "normal solution still active")));
+                    Response.WriteAsync(Jc.Serialize(new BasicResponse(ResponseCode.InvalidRequest,
+                        "normal solution still active")));
                 return;
             }
 
-            var oldAfterSolution =  await _context.AfterSolutions
+            var oldAfterSolution = await _context.AfterSolutions
                     .Include(p => p.SolutionFiles)
                     .ThenInclude(p => p.TemplateFile)
                     .Include(p => p.TestResults)
                     .Include(p => p.CustomTestResults)
                     .FirstOrDefaultAsync(p => p.SolutionUserId == userId &&
-                                         p.SolutionExerciseReleaseId ==
-                                         releaseWithUserAsParticipation.ExerciseReleaseId &&
-                                         p.SolutionPLangId == pLangId)
+                                              p.SolutionExerciseReleaseId ==
+                                              releaseWithUserAsParticipation.ExerciseReleaseId &&
+                                              p.SolutionPLangId == pLangId)
                 ;
 
             if (solutionForBackend.Id <= 0 && oldAfterSolution != null)
@@ -373,9 +376,8 @@ namespace ClientServer.Controllers.Core.Exercises.DoExerciseAfterSolution
 
                 if (oldFile == null)
                 {
-                    
                     //no solution file exists yet (user created new one for old solution)
-                    
+
                     if (solutionFile.TemplateFileId.HasValue)
                     {
                         oldTemplate =
@@ -460,9 +462,8 @@ namespace ClientServer.Controllers.Core.Exercises.DoExerciseAfterSolution
                 }
                 else
                 {
-                    
                     //backend file already exists
-                    
+
                     oldTemplate = oldFile.TemplateFile;
 
                     //overwrite old file
@@ -508,7 +509,7 @@ namespace ClientServer.Controllers.Core.Exercises.DoExerciseAfterSolution
             {
                 oldAfterSolution.CustomTestResults.Clear();
                 oldAfterSolution.TestResults.Clear();
-            }            
+            }
 
             oldAfterSolution.LastUpdatedAt = DateTimeHelper.GetUtcNow();
 
@@ -545,7 +546,7 @@ namespace ClientServer.Controllers.Core.Exercises.DoExerciseAfterSolution
                 {
                     transaction.Rollback();
 
-                   await base.HandleDbError(ex);
+                    await base.HandleDbError(ex);
                     return;
                 }
             }
@@ -626,7 +627,7 @@ namespace ClientServer.Controllers.Core.Exercises.DoExerciseAfterSolution
                 return;
             }
 
-            ExerciseReleaseWithUserAsParticipation releaseWithUserAsParticipation =  await _context
+            ExerciseReleaseWithUserAsParticipation releaseWithUserAsParticipation = await _context
                 .ExerciseReleaseWithUserAsParticipations
                 .Include(p => p.ExerciseRelease)
                 .FirstOrDefaultAsync(p => p.UserId == targetUserId && p.ExerciseRelease.GeneratedCode == releaseCode);
@@ -638,7 +639,7 @@ namespace ClientServer.Controllers.Core.Exercises.DoExerciseAfterSolution
                         Jc.Serialize(new BasicResponse(ResponseCode.NotFound, "participation not found")));
                 return;
             }
-            
+
             //check if available working time is up
             if (ReleaseHelper.IsTimeUp(releaseWithUserAsParticipation, releaseWithUserAsParticipation.ExerciseRelease))
             {
@@ -647,7 +648,8 @@ namespace ClientServer.Controllers.Core.Exercises.DoExerciseAfterSolution
             else
             {
                 await
-                    Response.WriteAsync(Jc.Serialize(new BasicResponse(ResponseCode.InvalidRequest, "normal solution still active")));
+                    Response.WriteAsync(Jc.Serialize(new BasicResponse(ResponseCode.InvalidRequest,
+                        "normal solution still active")));
                 return;
             }
 
@@ -662,8 +664,8 @@ namespace ClientServer.Controllers.Core.Exercises.DoExerciseAfterSolution
                 );
 
             var normalTestResults = await _context.TestWithAfterSolutionAsTestResults
-                .Where(p => p.Test.IsSubmitTest == false && p.AfterSolutionId == afterSolution.Id)
-                .ToListAsync()
+                    .Where(p => p.Test.IsSubmitTest == false && p.AfterSolutionId == afterSolution.Id)
+                    .ToListAsync()
                 ;
 
             if (afterSolution == null)
@@ -686,7 +688,7 @@ namespace ClientServer.Controllers.Core.Exercises.DoExerciseAfterSolution
                         p.Protocol.Split(new string[] {Constants.TestProtocolSplitString},
                             StringSplitOptions.RemoveEmptyEntries).ToList(),
                     HasCompiled = p.HasCompiled,
-                    
+
                     RunnerVersion = p.RunnerVersion,
                     TestServerVersion = p.TestServerVersion,
                     TimeForCompiling = p.TimeForCompiling,
@@ -727,7 +729,7 @@ namespace ClientServer.Controllers.Core.Exercises.DoExerciseAfterSolution
                             p.Protocol.Split(new string[] {Constants.TestProtocolSplitString},
                                 StringSplitOptions.RemoveEmptyEntries).ToList(),
                         HasCompiled = p.HasCompiled,
-                        
+
                         RunnerVersion = p.RunnerVersion,
                         TestServerVersion = p.TestServerVersion,
                         TimeForCompiling = p.TimeForCompiling,
@@ -780,7 +782,7 @@ namespace ClientServer.Controllers.Core.Exercises.DoExerciseAfterSolution
                 return;
             }
 
-            ExerciseReleaseWithUserAsParticipation releaseWithUserAsParticipation =  await _context
+            ExerciseReleaseWithUserAsParticipation releaseWithUserAsParticipation = await _context
                 .ExerciseReleaseWithUserAsParticipations
                 .Include(p => p.ExerciseRelease)
                 .FirstOrDefaultAsync(p => p.UserId == targetUserId && p.ExerciseRelease.GeneratedCode == releaseCode);
@@ -819,7 +821,8 @@ namespace ClientServer.Controllers.Core.Exercises.DoExerciseAfterSolution
             else
             {
                 await
-                    Response.WriteAsync(Jc.Serialize(new BasicResponse(ResponseCode.InvalidRequest, "normal solution still active")));
+                    Response.WriteAsync(Jc.Serialize(new BasicResponse(ResponseCode.InvalidRequest,
+                        "normal solution still active")));
                 return;
             }
 
@@ -862,7 +865,8 @@ namespace ClientServer.Controllers.Core.Exercises.DoExerciseAfterSolution
                                 release.ExerciseId == p.ExerciseId
                     )
                     .Include(p => p.TestSettings)
-                    .Include(p => p.TestAssets)
+                    .Include(p => p.AssetReferences)
+                    .ThenInclude(p => p.FileReferenceTestAsset)
                 ;
 
             var testResults = await _context.TestWithAfterSolutionAsTestResults
@@ -882,12 +886,14 @@ namespace ClientServer.Controllers.Core.Exercises.DoExerciseAfterSolution
                 .Select(p => new AssessedSubmitTestFromBackend()
                 {
                     Id = p.Test.Id,
-                    //TODO
-                    Files = p.Test.TestAssets.Select(f => new FilePreviewFromBackend()
+                    //TODO check
+                    Files = p.Test.AssetReferences.Select(f => new FilePreviewFromBackend()
                     {
                         //user cannot change test assets/or view them so not include data
-                        Id = f.Id,
-                        OriginalName = f.DisplayName,
+                        Id = f.FileReferenceTestAsset.Id,
+                        OriginalName = f.FileReferenceTestAsset.OriginalName,
+                        MimeType = f.FileReferenceTestAsset.MimeType,
+                        SizeInBytes = f.FileReferenceTestAsset.SizeInBytes,
                     }).ToList(),
                     Weight = p.Test.Weight,
                     IsSubmitTest = p.Test.IsSubmitTest,
@@ -916,7 +922,7 @@ namespace ClientServer.Controllers.Core.Exercises.DoExerciseAfterSolution
                             Protocol =
                                 p.Result.Protocol.Split(new string[] {Constants.TestProtocolSplitString},
                                     StringSplitOptions.RemoveEmptyEntries).ToList(),
-                            
+
                             RunnerVersion = p.Result.RunnerVersion,
                             TestServerVersion = p.Result.TestServerVersion,
                             TimeForCompiling = p.Result.TimeForCompiling,
@@ -931,7 +937,6 @@ namespace ClientServer.Controllers.Core.Exercises.DoExerciseAfterSolution
                     Jc.Serialize(new BasicResponseWithData<List<AssessedSubmitTestFromBackend>>(ResponseCode.Ok,
                         "", submitTestResultsForFrontend)));
         }
-        
     }
 
     #region types
diff --git a/src/ClientServer/Controllers/Core/Exercises/ExerciseOverviewController.cs b/src/ClientServer/Controllers/Core/Exercises/ExerciseOverviewController.cs
index 42f4549..0cab0cf 100644
--- a/src/ClientServer/Controllers/Core/Exercises/ExerciseOverviewController.cs
+++ b/src/ClientServer/Controllers/Core/Exercises/ExerciseOverviewController.cs
@@ -170,6 +170,8 @@ namespace ClientServer.Controllers.Core.Exercises
                             && p.ExerciseRelease.IsReleased == false
                             && p.ExerciseRelease.HideInOverviews == false
                             && p.ExerciseRelease.IsVisibleToAllAfterRelease == false
+                            && (p.ExerciseRelease.Exercise.IsOnlyVisibleToOwner == false ||
+                                p.ExerciseRelease.Exercise.UserId == userId)
                         )
                     ;
                 //when we have multiple plangs per participation this is not the same as getting the participation 
@@ -218,6 +220,8 @@ namespace ClientServer.Controllers.Core.Exercises
                             && p.ExerciseRelease.IsReleased == false
                             && p.ExerciseRelease.HideInOverviews == false
                             && p.ExerciseRelease.IsVisibleToAllAfterRelease
+                            && (p.ExerciseRelease.Exercise.IsOnlyVisibleToOwner == false ||
+                                p.ExerciseRelease.Exercise.UserId == userId)
                         )
                     ;
             }
@@ -349,6 +353,8 @@ namespace ClientServer.Controllers.Core.Exercises
                                 && p.ExerciseRelease.IsReleased
                                 && p.ExerciseRelease.IsVisibleToAllAfterRelease == false
                                 && p.ExerciseRelease.HideInOverviews == false
+                                && (p.ExerciseRelease.Exercise.IsOnlyVisibleToOwner == false ||
+                                    p.ExerciseRelease.Exercise.UserId == userId)
                             )
                     ;
 
@@ -450,6 +456,8 @@ namespace ClientServer.Controllers.Core.Exercises
                         .Where(p => p.IsReleased
                                     && p.IsVisibleToAllAfterRelease
                                     && p.HideInOverviews == false
+                                    && (p.Exercise.IsOnlyVisibleToOwner == false ||
+                                        p.Exercise.UserId == userId)
                         )
                     ;
 
diff --git a/src/ClientServer/Controllers/Core/Exercises/TutorViewAssessmentController.cs b/src/ClientServer/Controllers/Core/Exercises/TutorViewAssessmentController.cs
index 777b409..c1d49a2 100644
--- a/src/ClientServer/Controllers/Core/Exercises/TutorViewAssessmentController.cs
+++ b/src/ClientServer/Controllers/Core/Exercises/TutorViewAssessmentController.cs
@@ -174,9 +174,6 @@ namespace ClientServer.Controllers.Core.Exercises
             ExerciseReleaseWithUserAsParticipation oldParticipation = await _context
                     .ExerciseReleaseWithUserAsParticipations
                     .Include(p => p.CustomTests)
-                    .Include(p => p.CustomTests)
-                    .ThenInclude(p => p.TestAssets)
-                    .Include(p => p.CustomTests)
                     .ThenInclude(p => p.TestResultsNew)
                     .FirstOrDefaultAsync(p => p.ExerciseReleaseId == exerciseRelease.Id && p.UserId == userId)
                 ;
diff --git a/src/ClientServer/Db/YapexDbContext.cs b/src/ClientServer/Db/YapexDbContext.cs
index a72d157..070af71 100644
--- a/src/ClientServer/Db/YapexDbContext.cs
+++ b/src/ClientServer/Db/YapexDbContext.cs
@@ -105,16 +105,13 @@ namespace ClientServer.Db
         //---
 
         public DbSet<DefaultCustomTestSettings> DefaultCustomTestSettings { get; set; }
-        public DbSet<CustomTestAsset> CustomTestAssets { get; set; }
         //TODO MUST RENAME to CustomTests
         public DbSet<CustomTest> CustomTest { get; set; }
-        public DbSet<TestAsset> TestAssets { get; set; }
         public DbSet<Test> Tests { get; set; }
         public DbSet<TestSettings> TestCaseSettingses { get; set; }
         public DbSet<TestType> TestTypes { get; set; }
 
 
-        public DbSet<Asset> Assets { get; set; }
         public DbSet<Exercise> Exercises { get; set; }
         public DbSet<ExerciseDescription> ExerciseDescriptions { get; set; }
         public DbSet<MetaData> MetaDatas { get; set; }
@@ -175,13 +172,10 @@ namespace ClientServer.Db
             typeof(ExerciseReleaseWithUserAsParticipation),
             typeof(CustomTestWithSingleSolutionAsTestResult),
             typeof(DefaultCustomTestSettings),
-            typeof(CustomTestAsset),
             typeof(CustomTest),
-            typeof(TestAsset),
             typeof(Test),
             typeof(TestSettings),
             typeof(TestType),
-            typeof(Asset),
             typeof(Exercise),
             typeof(ExerciseDescription),
             typeof(MetaData),
@@ -295,12 +289,6 @@ namespace ClientServer.Db
                 .OnDelete(DeleteBehavior.Cascade)
                 ;
 
-            m.Entity<CustomProjectTest>()
-                .HasMany(p => p.TestAssets)
-                .WithOne()
-                .IsRequired()
-                .OnDelete(DeleteBehavior.Cascade)
-                ;
 
             #region custom project test asset references join table
 
@@ -392,14 +380,6 @@ namespace ClientServer.Db
                 .OnDelete(DeleteBehavior.Cascade)
                 ;
 
-            m.Entity<ExerciseDescription>()
-                .HasMany(p => p.Assets)
-                .WithOne()
-                .IsRequired()
-                .OnDelete(DeleteBehavior.Cascade)
-                ;
-
-
             #region exercise description asset references join table
             
             //see https://www.learnentityframeworkcore.com/configuration/many-to-many-relationship-configuration
@@ -532,13 +512,6 @@ namespace ClientServer.Db
                 .IsRequired()
                 .OnDelete(DeleteBehavior.Cascade)
                 ;
-
-            m.Entity<Test>()
-                .HasMany(p => p.TestAssets)
-                .WithOne()
-                .IsRequired()
-                .OnDelete(DeleteBehavior.Cascade)
-                ;
             
             #region exercise test files join table
             
@@ -933,13 +906,7 @@ namespace ClientServer.Db
                 .IsRequired()
                 .OnDelete(DeleteBehavior.Cascade)
                 ;
-            
-            m.Entity<CustomTest>()
-               .HasMany(p => p.TestAssets)
-               .WithOne()
-               .IsRequired()
-               .OnDelete(DeleteBehavior.Cascade)
-               ;
+           
 
             #region custom test asset references
 
diff --git a/src/ClientServer/Migrations/20190728133647_RemoveOldDbAssets.Designer.cs b/src/ClientServer/Migrations/20190728133647_RemoveOldDbAssets.Designer.cs
new file mode 100755
index 0000000..0da3864
--- /dev/null
+++ b/src/ClientServer/Migrations/20190728133647_RemoveOldDbAssets.Designer.cs
@@ -0,0 +1,2106 @@
+using System;
+using Microsoft.EntityFrameworkCore;
+using Microsoft.EntityFrameworkCore.Infrastructure;
+using Microsoft.EntityFrameworkCore.Metadata;
+using Microsoft.EntityFrameworkCore.Migrations;
+using ClientServer.Db;
+using ClientServer.Models.Exercises.Release;
+
+namespace ClientServer.Migrations
+{
+    [DbContext(typeof(YapexDbContext))]
+    [Migration("20190728133647_RemoveOldDbAssets")]
+    partial class RemoveOldDbAssets
+    {
+        protected override void BuildTargetModel(ModelBuilder modelBuilder)
+        {
+            modelBuilder
+                .HasAnnotation("ProductVersion", "1.0.3");
+
+            modelBuilder.Entity("ClientServer.Models.AwaitDummy", b =>
+                {
+                    b.Property<int>("Id")
+                        .ValueGeneratedOnAdd();
+
+                    b.HasKey("Id");
+
+                    b.ToTable("AwaitDummies");
+                });
+
+            modelBuilder.Entity("ClientServer.Models.CustomProjects.CustomProject", b =>
+                {
+                    b.Property<int>("Id")
+                        .ValueGeneratedOnAdd();
+
+                    b.Property<DateTime>("CreatedAt");
+
+                    b.Property<string>("DisplayName")
+                        .HasMaxLength(500);
+
+                    b.Property<int>("LastEditorPLangId");
+
+                    b.Property<DateTime>("LastUpdatedAt");
+
+                    b.Property<int>("UserId");
+
+                    b.HasKey("Id");
+
+                    b.HasIndex("UserId");
+
+                    b.ToTable("CustomProjects");
+                });
+
+            modelBuilder.Entity("ClientServer.Models.CustomProjects.CustomProjectDescription", b =>
+                {
+                    b.Property<int>("Id")
+                        .ValueGeneratedOnAdd();
+
+                    b.Property<string>("Content")
+                        .HasMaxLength(10000);
+
+                    b.Property<DateTime>("CreatedAt");
+
+                    b.Property<int>("CustomProjectId");
+
+                    b.Property<DateTime>("LastUpdatedAt");
+
+                    b.HasKey("Id");
+
+                    b.HasIndex("CustomProjectId")
+                        .IsUnique();
+
+                    b.ToTable("CustomProjectDescriptions");
+                });
+
+            modelBuilder.Entity("ClientServer.Models.CustomProjects.CustomProjectDescriptionWithFileAsAssetReference", b =>
+                {
+                    b.Property<int>("CustomProjectDescriptionId");
+
+                    b.Property<int>("FileReferenceUserFileAssetId");
+
+                    b.HasKey("CustomProjectDescriptionId", "FileReferenceUserFileAssetId");
+
+                    b.HasIndex("CustomProjectDescriptionId");
+
+                    b.HasIndex("FileReferenceUserFileAssetId");
+
+                    b.ToTable("CustomProjectDescriptionWithFileAsAssetReferences");
+                });
+
+            modelBuilder.Entity("ClientServer.Models.CustomProjects.CustomProjectSolution", b =>
+                {
+                    b.Property<int>("Id")
+                        .ValueGeneratedOnAdd();
+
+                    b.Property<DateTime>("CreatedAt");
+
+                    b.Property<int>("CustomProjectId");
+
+                    b.Property<DateTime>("LastUpdatedAt");
+
+                    b.Property<int?>("MainFileId");
+
+                    b.Property<int>("PLangId");
+
+                    b.HasKey("Id");
+
+                    b.HasIndex("CustomProjectId");
+
+                    b.HasIndex("MainFileId")
+                        .IsUnique();
+
+                    b.HasIndex("PLangId");
+
+                    b.ToTable("CustomProjectSolutions");
+                });
+
+            modelBuilder.Entity("ClientServer.Models.CustomProjects.CustomProjectSolutionFile", b =>
+                {
+                    b.Property<int>("Id")
+                        .ValueGeneratedOnAdd();
+
+                    b.Property<string>("Content")
+                        .HasMaxLength(10000);
+
+                    b.Property<DateTime>("CreatedAt");
+
+                    b.Property<int?>("CustomProjectSolutionId")
+                        .IsRequired();
+
+                    b.Property<int>("DisplayIndex");
+
+                    b.Property<string>("FileNameWithExtension")
+                        .HasMaxLength(500);
+
+                    b.Property<bool>("IsDisplayed");
+
+                    b.Property<DateTime>("LastUpdatedAt");
+
+                    b.HasKey("Id");
+
+                    b.HasIndex("CustomProjectSolutionId");
+
+                    b.ToTable("CustomProjectSolutionFiles");
+                });
+
+            modelBuilder.Entity("ClientServer.Models.CustomProjects.CustomProjectTest", b =>
+                {
+                    b.Property<int>("Id")
+                        .ValueGeneratedOnAdd();
+
+                    b.Property<string>("Content")
+                        .HasMaxLength(5000);
+
+                    b.Property<DateTime>("CreatedAt");
+
+                    b.Property<int>("CustomProjectId");
+
+                    b.Property<int>("DisplayIndex");
+
+                    b.Property<string>("DisplayName")
+                        .HasMaxLength(500);
+
+                    b.Property<DateTime>("LastUpdatedAt");
+
+                    b.Property<int>("TestSettingsId");
+
+                    b.Property<int>("TestTypeId");
+
+                    b.Property<int>("Weight");
+
+                    b.HasKey("Id");
+
+                    b.HasIndex("CustomProjectId");
+
+                    b.HasIndex("TestSettingsId")
+                        .IsUnique();
+
+                    b.HasIndex("TestTypeId");
+
+                    b.ToTable("CustomProjectTests");
+                });
+
+            modelBuilder.Entity("ClientServer.Models.CustomProjects.CustomProjectTestAsset", b =>
+                {
+                    b.Property<int>("Id")
+                        .ValueGeneratedOnAdd();
+
+                    b.Property<byte[]>("Content");
+
+                    b.Property<DateTime>("CreatedAt");
+
+                    b.Property<string>("DisplayName")
+                        .HasMaxLength(500);
+
+                    b.Property<string>("Hash")
+                        .HasMaxLength(500);
+
+                    b.Property<DateTime>("LastUpdatedAt");
+
+                    b.Property<string>("MimeType")
+                        .HasMaxLength(500);
+
+                    b.HasKey("Id");
+
+                    b.ToTable("CustomProjectTestAssets");
+                });
+
+            modelBuilder.Entity("ClientServer.Models.CustomProjects.CustomProjectTestWithFileAsAssetReference", b =>
+                {
+                    b.Property<int>("CustomProjectTestId");
+
+                    b.Property<int>("FileReferenceUserFileAssetId");
+
+                    b.HasKey("CustomProjectTestId", "FileReferenceUserFileAssetId");
+
+                    b.HasIndex("CustomProjectTestId");
+
+                    b.HasIndex("FileReferenceUserFileAssetId");
+
+                    b.ToTable("CustomProjectTestWithFileAsAssetReferences");
+                });
+
+            modelBuilder.Entity("ClientServer.Models.CustomProjects.CustomProjectTestWithSolutionAsTestResult", b =>
+                {
+                    b.Property<int>("CustomProjectSolutionId");
+
+                    b.Property<int>("CustomProjectTestId");
+
+                    b.Property<int?>("CompileTimeoutInMsUsed");
+
+                    b.Property<DateTime>("CreatedAt");
+
+                    b.Property<bool?>("HasCompiled");
+
+                    b.Property<DateTime>("LastUpdatedAt");
+
+                    b.Property<bool?>("Passed");
+
+                    b.Property<int?>("ProgramExitCode");
+
+                    b.Property<string>("Protocol")
+                        .HasMaxLength(10000);
+
+                    b.Property<string>("RunnerVersion")
+                        .HasMaxLength(500);
+
+                    b.Property<int?>("TestResultCode");
+
+                    b.Property<string>("TestServerVersion")
+                        .HasMaxLength(500);
+
+                    b.Property<int?>("TimeForCompiling");
+
+                    b.Property<int?>("TimeForUserProgram");
+
+                    b.Property<int?>("TimeoutInMsUsed");
+
+                    b.HasKey("CustomProjectSolutionId", "CustomProjectTestId");
+
+                    b.HasIndex("CustomProjectSolutionId");
+
+                    b.HasIndex("CustomProjectTestId");
+
+                    b.ToTable("CustomProjectTestWithSolutionAsTestResults");
+                });
+
+            modelBuilder.Entity("ClientServer.Models.Exercises.AfterSolutions.AfterSolution", b =>
+                {
+                    b.Property<int>("Id")
+                        .ValueGeneratedOnAdd();
+
+                    b.Property<DateTime>("CreatedAt");
+
+                    b.Property<DateTime>("LastUpdatedAt");
+
+                    b.Property<int?>("MainFileId");
+
+                    b.Property<int>("SolutionExerciseReleaseId");
+
+                    b.Property<int>("SolutionPLangId");
+
+                    b.Property<int>("SolutionUserId");
+
+                    b.HasKey("Id");
+
+                    b.HasIndex("MainFileId")
+                        .IsUnique();
+
+                    b.HasIndex("SolutionUserId", "SolutionExerciseReleaseId", "SolutionPLangId")
+                        .IsUnique();
+
+                    b.ToTable("AfterSolutions");
+                });
+
+            modelBuilder.Entity("ClientServer.Models.Exercises.AfterSolutions.AfterSolutionFile", b =>
+                {
+                    b.Property<int>("Id")
+                        .ValueGeneratedOnAdd();
+
+                    b.Property<int>("AfterSolutionId");
+
+                    b.Property<string>("Content")
+                        .HasMaxLength(10000);
+
+                    b.Property<DateTime>("CreatedAt");
+
+                    b.Property<int>("DisplayIndex");
+
+                    b.Property<string>("FileNameWithExtension")
+                        .HasMaxLength(500);
+
+                    b.Property<bool>("IsDisplayed");
+
+                    b.Property<DateTime>("LastUpdatedAt");
+
+                    b.Property<int?>("TemplateFileId");
+
+                    b.HasKey("Id");
+
+                    b.HasIndex("AfterSolutionId");
+
+                    b.HasIndex("TemplateFileId");
+
+                    b.ToTable("AfterSolutionFiles");
+                });
+
+            modelBuilder.Entity("ClientServer.Models.Exercises.AfterSolutions.CustomTestWithAfterSolutionAsTestResult", b =>
+                {
+                    b.Property<int>("CustomTestId");
+
+                    b.Property<int>("AfterSolutionId");
+
+                    b.Property<int?>("CompileTimeoutInMsUsed");
+
+                    b.Property<DateTime>("CreatedAt");
+
+                    b.Property<bool?>("HasCompiled");
+
+                    b.Property<DateTime>("LastUpdatedAt");
+
+                    b.Property<bool?>("Passed");
+
+                    b.Property<int?>("ProgramExitCode");
+
+                    b.Property<string>("Protocol")
+                        .HasMaxLength(10000);
+
+                    b.Property<string>("RunnerVersion")
+                        .HasMaxLength(500);
+
+                    b.Property<int?>("TestResultCode");
+
+                    b.Property<string>("TestServerVersion")
+                        .HasMaxLength(500);
+
+                    b.Property<int?>("TimeForCompiling");
+
+                    b.Property<int?>("TimeForUserProgram");
+
+                    b.Property<int?>("TimeoutInMsUsed");
+
+                    b.HasKey("CustomTestId", "AfterSolutionId");
+
+                    b.HasIndex("AfterSolutionId");
+
+                    b.HasIndex("CustomTestId");
+
+                    b.ToTable("CustomTestWithAfterSolutionAsTestResults");
+                });
+
+            modelBuilder.Entity("ClientServer.Models.Exercises.AfterSolutions.TestWithAfterSolutionAsTestResult", b =>
+                {
+                    b.Property<int>("TestId");
+
+                    b.Property<int>("AfterSolutionId");
+
+                    b.Property<int?>("CompileTimeoutInMsUsed");
+
+                    b.Property<DateTime>("CreatedAt");
+
+                    b.Property<bool?>("HasCompiled");
+
+                    b.Property<DateTime>("LastUpdatedAt");
+
+                    b.Property<bool?>("Passed");
+
+                    b.Property<int?>("ProgramExitCode");
+
+                    b.Property<string>("Protocol")
+                        .HasMaxLength(10000);
+
+                    b.Property<string>("RunnerVersion")
+                        .HasMaxLength(500);
+
+                    b.Property<int?>("TestResultCode");
+
+                    b.Property<string>("TestServerVersion")
+                        .HasMaxLength(500);
+
+                    b.Property<int?>("TimeForCompiling");
+
+                    b.Property<int?>("TimeForUserProgram");
+
+                    b.Property<int?>("TimeoutInMsUsed");
+
+                    b.HasKey("TestId", "AfterSolutionId");
+
+                    b.HasIndex("AfterSolutionId");
+
+                    b.HasIndex("TestId");
+
+                    b.ToTable("TestWithAfterSolutionAsTestResults");
+                });
+
+            modelBuilder.Entity("ClientServer.Models.Exercises.CodeTemplate", b =>
+                {
+                    b.Property<int>("Id")
+                        .ValueGeneratedOnAdd();
+
+                    b.Property<DateTime>("CreatedAt");
+
+                    b.Property<int>("ExerciseId");
+
+                    b.Property<DateTime>("LastUpdatedAt");
+
+                    b.Property<int?>("MainFileId");
+
+                    b.Property<int>("PLangId");
+
+                    b.HasKey("Id");
+
+                    b.HasIndex("ExerciseId");
+
+                    b.HasIndex("MainFileId")
+                        .IsUnique();
+
+                    b.HasIndex("PLangId");
+
+                    b.ToTable("Templates");
+                });
+
+            modelBuilder.Entity("ClientServer.Models.Exercises.CustomTestWithFileAsAssetReference", b =>
+                {
+                    b.Property<int>("CustomTestId");
+
+                    b.Property<int>("FileReferenceUserFileAssetId");
+
+                    b.HasKey("CustomTestId", "FileReferenceUserFileAssetId");
+
+                    b.HasIndex("CustomTestId");
+
+                    b.HasIndex("FileReferenceUserFileAssetId");
+
+                    b.ToTable("CustomTestWithFileAsAssetReferences");
+                });
+
+            modelBuilder.Entity("ClientServer.Models.Exercises.Exercise", b =>
+                {
+                    b.Property<int>("Id")
+                        .ValueGeneratedOnAdd();
+
+                    b.Property<bool>("CanUserCreateCustomTests");
+
+                    b.Property<bool>("CanUserCreateFiles");
+
+                    b.Property<DateTime>("CreatedAt");
+
+                    b.Property<string>("DisplayName")
+                        .HasMaxLength(500);
+
+                    b.Property<bool>("IsOnlyVisibleToOwner");
+
+                    b.Property<bool>("IsPermanentlyLocked");
+
+                    b.Property<DateTime>("LastUpdatedAt");
+
+                    b.Property<string>("Note")
+                        .HasMaxLength(1000);
+
+                    b.Property<string>("ShortDescription")
+                        .HasMaxLength(500);
+
+                    b.Property<int>("UserGroupId");
+
+                    b.Property<int?>("UserId");
+
+                    b.HasKey("Id");
+
+                    b.HasIndex("UserGroupId");
+
+                    b.HasIndex("UserId");
+
+                    b.ToTable("Exercises");
+                });
+
+            modelBuilder.Entity("ClientServer.Models.Exercises.ExerciseDescription", b =>
+                {
+                    b.Property<int>("Id")
+                        .ValueGeneratedOnAdd();
+
+                    b.Property<string>("Content")
+                        .HasMaxLength(10000);
+
+                    b.Property<DateTime>("CreatedAt");
+
+                    b.Property<int>("ExerciseId");
+
+                    b.Property<DateTime>("LastUpdatedAt");
+
+                    b.HasKey("Id");
+
+                    b.HasIndex("ExerciseId")
+                        .IsUnique();
+
+                    b.ToTable("ExerciseDescriptions");
+                });
+
+            modelBuilder.Entity("ClientServer.Models.Exercises.ExerciseDescriptionWithFileAsAssetReference", b =>
+                {
+                    b.Property<int>("ExerciseDescriptionId");
+
+                    b.Property<int>("FileReferenceMarkdownAssetId");
+
+                    b.HasKey("ExerciseDescriptionId", "FileReferenceMarkdownAssetId");
+
+                    b.HasIndex("ExerciseDescriptionId");
+
+                    b.HasIndex("FileReferenceMarkdownAssetId");
+
+                    b.ToTable("ExerciseDescriptionWithFileAsAssetReferences");
+                });
+
+            modelBuilder.Entity("ClientServer.Models.Exercises.MetaData", b =>
+                {
+                    b.Property<int>("Id")
+                        .ValueGeneratedOnAdd();
+
+                    b.Property<DateTime>("CreatedAt");
+
+                    b.Property<int>("ExerciseId");
+
+                    b.Property<int?>("ExerciseId1");
+
+                    b.Property<DateTime>("LastUpdatedAt");
+
+                    b.HasKey("Id");
+
+                    b.HasIndex("ExerciseId")
+                        .IsUnique();
+
+                    b.HasIndex("ExerciseId1");
+
+                    b.ToTable("MetaDatas");
+                });
+
+            modelBuilder.Entity("ClientServer.Models.Exercises.Release.ExerciseRelease", b =>
+                {
+                    b.Property<int>("Id")
+                        .ValueGeneratedOnAdd();
+
+                    b.Property<DateTime?>("AutomaticEndAt");
+
+                    b.Property<DateTime?>("AutomaticStartAt");
+
+                    b.Property<int>("AvailableWorkingTimeInMinutes");
+
+                    b.Property<DateTime>("CreatedAt");
+
+                    b.Property<int>("ExerciseId");
+
+                    b.Property<string>("GeneratedCode")
+                        .IsRequired()
+                        .HasMaxLength(500);
+
+                    b.Property<bool>("HadAutomaticAssessmentErrors");
+
+                    b.Property<bool>("HasAutomaticAssessmentFinished");
+
+                    b.Property<bool>("HasAutomaticAssessmentStarted");
+
+                    b.Property<bool>("HasLimitedWorkingTime");
+
+                    b.Property<bool>("HideExerciseLeaveActions");
+
+                    b.Property<bool>("HideInOverviews");
+
+                    b.Property<bool>("HidePrintOptions");
+
+                    b.Property<bool>("HideSiteHeaderBar");
+
+                    b.Property<bool>("IsReleased");
+
+                    b.Property<bool>("IsVisibleToAllAfterRelease");
+
+                    b.Property<DateTime>("LastUpdatedAt");
+
+                    b.Property<int?>("MaxManualPoint");
+
+                    b.Property<string>("Note")
+                        .HasMaxLength(1000);
+
+                    b.Property<int>("PLangId");
+
+                    b.Property<int>("ReleaseDurationType");
+
+                    b.Property<int>("ReleaseStartType");
+
+                    b.Property<DateTime?>("ReleasedAt");
+
+                    b.Property<bool>("RunAlsoNormalTests");
+
+                    b.Property<bool>("ShouldAutomaticAssessSubmissions");
+
+                    b.Property<bool>("ShouldClearClipboard");
+
+                    b.Property<bool>("ShowAdditionalLogButton");
+
+                    b.HasKey("Id");
+
+                    b.HasAlternateKey("GeneratedCode")
+                        .HasName("Unique_GeneratedCode");
+
+                    b.HasIndex("ExerciseId");
+
+                    b.HasIndex("PLangId");
+
+                    b.ToTable("ExerciseReleases");
+                });
+
+            modelBuilder.Entity("ClientServer.Models.Exercises.Solution.CustomTestWithSingleSolutionAsTestResult", b =>
+                {
+                    b.Property<int>("CustomTestId");
+
+                    b.Property<int>("SolutionUserId");
+
+                    b.Property<int>("SolutionExerciseReleaseId");
+
+                    b.Property<int>("SolutionPLangId");
+
+                    b.Property<int?>("CompileTimeoutInMsUsed");
+
+                    b.Property<DateTime>("CreatedAt");
+
+                    b.Property<bool?>("HasCompiled");
+
+                    b.Property<DateTime>("LastUpdatedAt");
+
+                    b.Property<bool?>("Passed");
+
+                    b.Property<int?>("ProgramExitCode");
+
+                    b.Property<string>("Protocol")
+                        .HasMaxLength(10000);
+
+                    b.Property<string>("RunnerVersion")
+                        .HasMaxLength(500);
+
+                    b.Property<int?>("TestResultCode");
+
+                    b.Property<string>("TestServerVersion")
+                        .HasMaxLength(500);
+
+                    b.Property<int?>("TimeForCompiling");
+
+                    b.Property<int?>("TimeForUserProgram");
+
+                    b.Property<int?>("TimeoutInMsUsed");
+
+                    b.HasKey("CustomTestId", "SolutionUserId", "SolutionExerciseReleaseId", "SolutionPLangId");
+
+                    b.HasIndex("CustomTestId");
+
+                    b.HasIndex("SolutionUserId", "SolutionExerciseReleaseId", "SolutionPLangId");
+
+                    b.ToTable("CustomTestWithSingleSolutionAsTestResult");
+                });
+
+            modelBuilder.Entity("ClientServer.Models.Exercises.Solution.ExerciseReleaseWithUserAsParticipation", b =>
+                {
+                    b.Property<int>("UserId");
+
+                    b.Property<int>("ExerciseReleaseId");
+
+                    b.Property<DateTime>("CreatedAt");
+
+                    b.Property<int>("LastEditedPLangId");
+
+                    b.Property<DateTime>("LastUpdatedAt");
+
+                    b.Property<bool>("LockSolutionsFlag");
+
+                    b.Property<bool>("ShouldNotCount");
+
+                    b.HasKey("UserId", "ExerciseReleaseId");
+
+                    b.HasIndex("ExerciseReleaseId");
+
+                    b.HasIndex("LastEditedPLangId");
+
+                    b.HasIndex("UserId");
+
+                    b.ToTable("ExerciseReleaseWithUserAsParticipations");
+                });
+
+            modelBuilder.Entity("ClientServer.Models.Exercises.Solution.Solution", b =>
+                {
+                    b.Property<int>("UserId");
+
+                    b.Property<int>("ExerciseReleaseId");
+
+                    b.Property<int>("PLangId");
+
+                    b.Property<int?>("AssessmentId");
+
+                    b.Property<DateTime>("CreatedAt");
+
+                    b.Property<string>("LastEditingIpAddress")
+                        .HasMaxLength(500);
+
+                    b.Property<DateTime>("LastUpdatedAt");
+
+                    b.Property<int?>("MainFileId");
+
+                    b.Property<string>("Note")
+                        .HasMaxLength(1000);
+
+                    b.HasKey("UserId", "ExerciseReleaseId", "PLangId");
+
+                    b.HasIndex("AssessmentId")
+                        .IsUnique();
+
+                    b.HasIndex("MainFileId")
+                        .IsUnique();
+
+                    b.HasIndex("PLangId");
+
+                    b.HasIndex("UserId", "ExerciseReleaseId");
+
+                    b.ToTable("Solutions");
+                });
+
+            modelBuilder.Entity("ClientServer.Models.Exercises.Solution.SolutionAssessment", b =>
+                {
+                    b.Property<int>("Id")
+                        .ValueGeneratedOnAdd();
+
+                    b.Property<string>("FeedbackForStudent")
+                        .HasMaxLength(1000);
+
+                    b.Property<string>("LastAssessmentErrorMessage")
+                        .HasMaxLength(5000);
+
+                    b.Property<int?>("ManualPoints");
+
+                    b.Property<int>("MaxNormalTestPoints");
+
+                    b.Property<int>("MaxSubmitTestPoints");
+
+                    b.Property<int?>("NormalTestPoints");
+
+                    b.Property<string>("NoteForOtherTutors")
+                        .HasMaxLength(1000);
+
+                    b.Property<int?>("SubmitTestPoints");
+
+                    b.HasKey("Id");
+
+                    b.ToTable("SolutionAssessment");
+                });
+
+            modelBuilder.Entity("ClientServer.Models.Exercises.Solution.SolutionFile", b =>
+                {
+                    b.Property<int>("Id")
+                        .ValueGeneratedOnAdd();
+
+                    b.Property<string>("Content")
+                        .HasMaxLength(10000);
+
+                    b.Property<DateTime>("CreatedAt");
+
+                    b.Property<int>("DisplayIndex");
+
+                    b.Property<string>("FileNameWithExtension")
+                        .HasMaxLength(500);
+
+                    b.Property<bool>("IsDisplayed");
+
+                    b.Property<DateTime>("LastUpdatedAt");
+
+                    b.Property<int>("SolutionExerciseReleaseId");
+
+                    b.Property<int>("SolutionPLangId");
+
+                    b.Property<int>("SolutionUserId");
+
+                    b.Property<int?>("TemplateFileId");
+
+                    b.HasKey("Id");
+
+                    b.HasIndex("TemplateFileId");
+
+                    b.HasIndex("SolutionUserId", "SolutionExerciseReleaseId", "SolutionPLangId");
+
+                    b.ToTable("SolutionFiles");
+                });
+
+            modelBuilder.Entity("ClientServer.Models.Exercises.Solution.TestWithSingleSolutionAsTestResult", b =>
+                {
+                    b.Property<int>("TestId");
+
+                    b.Property<int>("SolutionUserId");
+
+                    b.Property<int>("SolutionExerciseReleaseId");
+
+                    b.Property<int>("SolutionPLangId");
+
+                    b.Property<int?>("CompileTimeoutInMsUsed");
+
+                    b.Property<DateTime>("CreatedAt");
+
+                    b.Property<bool?>("HasCompiled");
+
+                    b.Property<DateTime>("LastUpdatedAt");
+
+                    b.Property<bool?>("Passed");
+
+                    b.Property<int?>("ProgramExitCode");
+
+                    b.Property<string>("Protocol")
+                        .HasMaxLength(10000);
+
+                    b.Property<string>("RunnerVersion")
+                        .HasMaxLength(500);
+
+                    b.Property<int?>("TestResultCode");
+
+                    b.Property<string>("TestServerVersion")
+                        .HasMaxLength(500);
+
+                    b.Property<int?>("TimeForCompiling");
+
+                    b.Property<int?>("TimeForUserProgram");
+
+                    b.Property<int?>("TimeoutInMsUsed");
+
+                    b.HasKey("TestId", "SolutionUserId", "SolutionExerciseReleaseId", "SolutionPLangId");
+
+                    b.HasIndex("TestId");
+
+                    b.HasIndex("SolutionUserId", "SolutionExerciseReleaseId", "SolutionPLangId");
+
+                    b.ToTable("TestWithSingleSolutionAsTestResult");
+                });
+
+            modelBuilder.Entity("ClientServer.Models.Exercises.Tag", b =>
+                {
+                    b.Property<int>("Id")
+                        .ValueGeneratedOnAdd();
+
+                    b.Property<DateTime>("CreatedAt");
+
+                    b.Property<string>("Description")
+                        .HasMaxLength(500);
+
+                    b.Property<string>("DisplayName")
+                        .HasMaxLength(500);
+
+                    b.Property<string>("HtmlBackgroundColor")
+                        .HasMaxLength(500);
+
+                    b.Property<string>("HtmlColor")
+                        .HasMaxLength(500);
+
+                    b.Property<string>("HtmlIcon")
+                        .HasMaxLength(500);
+
+                    b.Property<DateTime>("LastUpdatedAt");
+
+                    b.HasKey("Id");
+
+                    b.HasIndex("DisplayName")
+                        .HasName("Unique_Tag");
+
+                    b.ToTable("Tags");
+                });
+
+            modelBuilder.Entity("ClientServer.Models.Exercises.TagWithMetaData", b =>
+                {
+                    b.Property<int>("TagId");
+
+                    b.Property<int>("MetaDataId");
+
+                    b.Property<DateTime>("CreatedAt");
+
+                    b.Property<DateTime>("LastUpdatedAt");
+
+                    b.HasKey("TagId", "MetaDataId");
+
+                    b.HasIndex("MetaDataId");
+
+                    b.HasIndex("TagId");
+
+                    b.ToTable("TagWithMetaDatas");
+                });
+
+            modelBuilder.Entity("ClientServer.Models.Exercises.TemplateFile", b =>
+                {
+                    b.Property<int>("Id")
+                        .ValueGeneratedOnAdd();
+
+                    b.Property<int?>("CodeTemplateId")
+                        .IsRequired();
+
+                    b.Property<string>("Content")
+                        .HasMaxLength(10000);
+
+                    b.Property<DateTime>("CreatedAt");
+
+                    b.Property<int>("DisplayIndex");
+
+                    b.Property<string>("FileNameWithExtension")
+                        .HasMaxLength(500);
+
+                    b.Property<bool>("IsContentVisibleForUser");
+
+                    b.Property<bool>("IsEditableByUser");
+
+                    b.Property<DateTime>("LastUpdatedAt");
+
+                    b.HasKey("Id");
+
+                    b.HasIndex("CodeTemplateId");
+
+                    b.ToTable("TemplateFiles");
+                });
+
+            modelBuilder.Entity("ClientServer.Models.Exercises.Tests.CustomTest", b =>
+                {
+                    b.Property<int>("Id")
+                        .ValueGeneratedOnAdd();
+
+                    b.Property<string>("Content")
+                        .HasMaxLength(5000);
+
+                    b.Property<DateTime>("CreatedAt");
+
+                    b.Property<int>("DisplayIndex");
+
+                    b.Property<string>("DisplayName")
+                        .HasMaxLength(500);
+
+                    b.Property<int>("ExerciseReleaseId");
+
+                    b.Property<DateTime>("LastUpdatedAt");
+
+                    b.Property<int>("TestTypeId");
+
+                    b.Property<int>("UserId");
+
+                    b.HasKey("Id");
+
+                    b.HasIndex("TestTypeId");
+
+                    b.HasIndex("UserId", "ExerciseReleaseId");
+
+                    b.ToTable("CustomTest");
+                });
+
+            modelBuilder.Entity("ClientServer.Models.Exercises.Tests.DefaultCustomTestSettings", b =>
+                {
+                    b.Property<int>("Id")
+                        .ValueGeneratedOnAdd();
+
+                    b.Property<int>("CompileTimeoutInMs");
+
+                    b.Property<string>("CompilerOptions")
+                        .HasMaxLength(500);
+
+                    b.Property<DateTime>("CreatedAt");
+
+                    b.Property<int>("ExerciseId");
+
+                    b.Property<DateTime>("LastUpdatedAt");
+
+                    b.Property<int>("MaxDiskSpaceInKb");
+
+                    b.Property<int>("MemoryLimitInKb");
+
+                    b.Property<int>("TimeoutInMs");
+
+                    b.HasKey("Id");
+
+                    b.HasIndex("ExerciseId")
+                        .IsUnique();
+
+                    b.ToTable("DefaultCustomTestSettings");
+                });
+
+            modelBuilder.Entity("ClientServer.Models.Exercises.Tests.Test", b =>
+                {
+                    b.Property<int>("Id")
+                        .ValueGeneratedOnAdd();
+
+                    b.Property<string>("Content")
+                        .HasMaxLength(5000);
+
+                    b.Property<DateTime>("CreatedAt");
+
+                    b.Property<int>("DisplayIndex");
+
+                    b.Property<string>("DisplayName")
+                        .HasMaxLength(500);
+
+                    b.Property<int>("ExerciseId");
+
+                    b.Property<bool>("IsSubmitTest");
+
+                    b.Property<DateTime>("LastUpdatedAt");
+
+                    b.Property<int>("TestSettingsId");
+
+                    b.Property<int>("TestTypeId");
+
+                    b.Property<int>("Weight");
+
+                    b.HasKey("Id");
+
+                    b.HasIndex("ExerciseId");
+
+                    b.HasIndex("TestSettingsId")
+                        .IsUnique();
+
+                    b.HasIndex("TestTypeId");
+
+                    b.ToTable("Tests");
+                });
+
+            modelBuilder.Entity("ClientServer.Models.Exercises.Tests.TestSettings", b =>
+                {
+                    b.Property<int>("Id")
+                        .ValueGeneratedOnAdd();
+
+                    b.Property<int>("CompileTimeoutInMs");
+
+                    b.Property<string>("CompilerOptions")
+                        .HasMaxLength(500);
+
+                    b.Property<DateTime>("CreatedAt");
+
+                    b.Property<DateTime>("LastUpdatedAt");
+
+                    b.Property<int>("MaxDiskSpaceInKb");
+
+                    b.Property<int>("MemoryLimitInKb");
+
+                    b.Property<int>("TimeoutInMs");
+
+                    b.HasKey("Id");
+
+                    b.ToTable("TestCaseSettingses");
+                });
+
+            modelBuilder.Entity("ClientServer.Models.Exercises.Tests.TestType", b =>
+                {
+                    b.Property<int>("Id")
+                        .ValueGeneratedOnAdd();
+
+                    b.Property<DateTime>("CreatedAt");
+
+                    b.Property<string>("DisplayName")
+                        .HasMaxLength(500);
+
+                    b.Property<string>("InternalName")
+                        .HasMaxLength(500);
+
+                    b.Property<DateTime>("LastUpdatedAt");
+
+                    b.HasKey("Id");
+
+                    b.ToTable("TestTypes");
+                });
+
+            modelBuilder.Entity("ClientServer.Models.Exercises.TestWithFileAsAssetReference", b =>
+                {
+                    b.Property<int>("TestId");
+
+                    b.Property<int>("FileReferenceTestAssetId");
+
+                    b.HasKey("TestId", "FileReferenceTestAssetId");
+
+                    b.HasIndex("FileReferenceTestAssetId");
+
+                    b.HasIndex("TestId");
+
+                    b.ToTable("TestWithFileAsAssetReferences");
+                });
+
+            modelBuilder.Entity("ClientServer.Models.Files.FileReferenceMarkdownAsset", b =>
+                {
+                    b.Property<int>("Id")
+                        .ValueGeneratedOnAdd();
+
+                    b.Property<DateTime>("CreatedAt");
+
+                    b.Property<string>("Hash")
+                        .HasMaxLength(500);
+
+                    b.Property<DateTime>("LastUpdatedAt");
+
+                    b.Property<string>("MimeType")
+                        .HasMaxLength(500);
+
+                    b.Property<string>("OriginalName")
+                        .HasMaxLength(500);
+
+                    b.Property<long>("SizeInBytes");
+
+                    b.HasKey("Id");
+
+                    b.ToTable("FileReferenceMarkdownAssets");
+                });
+
+            modelBuilder.Entity("ClientServer.Models.Files.FileReferenceTestAsset", b =>
+                {
+                    b.Property<int>("Id")
+                        .ValueGeneratedOnAdd();
+
+                    b.Property<DateTime>("CreatedAt");
+
+                    b.Property<string>("Hash")
+                        .HasMaxLength(500);
+
+                    b.Property<DateTime>("LastUpdatedAt");
+
+                    b.Property<string>("MimeType")
+                        .HasMaxLength(500);
+
+                    b.Property<string>("OriginalName")
+                        .HasMaxLength(500);
+
+                    b.Property<long>("SizeInBytes");
+
+                    b.HasKey("Id");
+
+                    b.ToTable("FileReferenceTestAssets");
+                });
+
+            modelBuilder.Entity("ClientServer.Models.Files.FileReferenceUserFileAsset", b =>
+                {
+                    b.Property<int>("Id")
+                        .ValueGeneratedOnAdd();
+
+                    b.Property<DateTime>("CreatedAt");
+
+                    b.Property<string>("Hash")
+                        .HasMaxLength(500);
+
+                    b.Property<DateTime>("LastUpdatedAt");
+
+                    b.Property<string>("MimeType")
+                        .HasMaxLength(500);
+
+                    b.Property<string>("OriginalName")
+                        .HasMaxLength(500);
+
+                    b.Property<long>("SizeInBytes");
+
+                    b.HasKey("Id");
+
+                    b.ToTable("FileReferenceUserFileAssets");
+                });
+
+            modelBuilder.Entity("ClientServer.Models.Lang", b =>
+                {
+                    b.Property<int>("Id")
+                        .ValueGeneratedOnAdd();
+
+                    b.Property<DateTime>("CreatedAt");
+
+                    b.Property<string>("LangShortcut")
+                        .HasMaxLength(500);
+
+                    b.Property<string>("Language")
+                        .HasMaxLength(500);
+
+                    b.Property<DateTime>("LastUpdatedAt");
+
+                    b.HasKey("Id");
+
+                    b.ToTable("Langs");
+                });
+
+            modelBuilder.Entity("ClientServer.Models.PLang", b =>
+                {
+                    b.Property<int>("Id")
+                        .ValueGeneratedOnAdd();
+
+                    b.Property<DateTime>("CreatedAt");
+
+                    b.Property<string>("DisplayName")
+                        .HasMaxLength(500);
+
+                    b.Property<string>("EditorHighlightModeName")
+                        .HasMaxLength(500);
+
+                    b.Property<string>("FileExtensionsWithDot")
+                        .HasMaxLength(500);
+
+                    b.Property<string>("InternalName")
+                        .HasMaxLength(500);
+
+                    b.Property<DateTime>("LastUpdatedAt");
+
+                    b.HasKey("Id");
+
+                    b.ToTable("PLangs");
+                });
+
+            modelBuilder.Entity("ClientServer.Models.Users.AuthToken", b =>
+                {
+                    b.Property<int>("UserId");
+
+                    b.Property<DateTime>("CreatedAt");
+
+                    b.Property<string>("CsrfToken")
+                        .HasMaxLength(500);
+
+                    b.Property<DateTime>("ExpirationDateTime");
+
+                    b.Property<DateTime>("LastUpdatedAt");
+
+                    b.Property<string>("RandomSecret")
+                        .HasMaxLength(500);
+
+                    b.Property<string>("UserAuthToken")
+                        .HasMaxLength(500);
+
+                    b.HasKey("UserId");
+
+                    b.HasIndex("UserAuthToken")
+                        .IsUnique();
+
+                    b.HasIndex("UserId")
+                        .IsUnique();
+
+                    b.ToTable("AuthTokens");
+                });
+
+            modelBuilder.Entity("ClientServer.Models.Users.ExternalUser", b =>
+                {
+                    b.Property<int>("ExternalId")
+                        .ValueGeneratedOnAdd();
+
+                    b.Property<DateTime>("CreatedAt");
+
+                    b.Property<string>("Email")
+                        .HasMaxLength(500);
+
+                    b.Property<string>("FirstName")
+                        .HasMaxLength(500);
+
+                    b.Property<string>("LastName")
+                        .HasMaxLength(500);
+
+                    b.Property<DateTime>("LastUpdatedAt");
+
+                    b.Property<bool>("NeedToRefreshData");
+
+                    b.Property<string>("Token")
+                        .IsRequired()
+                        .HasMaxLength(500);
+
+                    b.Property<int>("UserId");
+
+                    b.HasKey("ExternalId");
+
+                    b.HasAlternateKey("Token")
+                        .HasName("Unique_ExternalToken");
+
+                    b.HasIndex("UserId")
+                        .IsUnique();
+
+                    b.ToTable("ExternalUsers");
+                });
+
+            modelBuilder.Entity("ClientServer.Models.Users.GroupRole", b =>
+                {
+                    b.Property<int>("Id")
+                        .ValueGeneratedOnAdd();
+
+                    b.Property<DateTime>("CreatedAt");
+
+                    b.Property<string>("DisplayName")
+                        .HasMaxLength(500);
+
+                    b.Property<int>("GroupRolePermissionId");
+
+                    b.Property<DateTime>("LastUpdatedAt");
+
+                    b.HasKey("Id");
+
+                    b.HasIndex("GroupRolePermissionId")
+                        .IsUnique();
+
+                    b.ToTable("GroupRoles");
+                });
+
+            modelBuilder.Entity("ClientServer.Models.Users.GroupRolePermission", b =>
+                {
+                    b.Property<int>("Id")
+                        .ValueGeneratedOnAdd();
+
+                    b.Property<bool>("CanAddUserToGroup");
+
+                    b.Property<bool>("CanAssessExercises");
+
+                    b.Property<bool>("CanChangeExercises");
+
+                    b.Property<bool>("CanChangeGroupData");
+
+                    b.Property<bool>("CanChangeOtherMembersRole");
+
+                    b.Property<bool>("CanCreateExercises");
+
+                    b.Property<bool>("CanDeleteExercises");
+
+                    b.Property<bool>("CanLockExercisesPermanently");
+
+                    b.Property<bool>("CanManageExerciseReleases");
+
+                    b.Property<bool>("CanRemoveMemberFromGroup");
+
+                    b.Property<bool>("CanSeeExercisesFromOthersInGroup");
+
+                    b.Property<bool>("CanSeeOtherMembers");
+
+                    b.Property<DateTime>("CreatedAt");
+
+                    b.Property<DateTime>("LastUpdatedAt");
+
+                    b.HasKey("Id");
+
+                    b.ToTable("GroupRolePermissions");
+                });
+
+            modelBuilder.Entity("ClientServer.Models.Users.Settings.CodeEditorSetting", b =>
+                {
+                    b.Property<int>("Id")
+                        .ValueGeneratedOnAdd();
+
+                    b.Property<DateTime>("CreatedAt");
+
+                    b.Property<int>("FontSize");
+
+                    b.Property<bool>("HighlightCurrentLine");
+
+                    b.Property<DateTime>("LastUpdatedAt");
+
+                    b.Property<bool>("ShowInvisibles");
+
+                    b.Property<bool>("ShowLineIndentions");
+
+                    b.Property<bool>("ShowLineNumbers");
+
+                    b.Property<int>("TabSize");
+
+                    b.Property<string>("Theme")
+                        .HasMaxLength(500);
+
+                    b.Property<bool>("UseWrapping");
+
+                    b.HasKey("Id");
+
+                    b.ToTable("CodeEditorSettings");
+                });
+
+            modelBuilder.Entity("ClientServer.Models.Users.Settings.UserSetting", b =>
+                {
+                    b.Property<int>("Id")
+                        .ValueGeneratedOnAdd();
+
+                    b.Property<int>("CodeEditorSettingsId");
+
+                    b.Property<DateTime>("CreatedAt");
+
+                    b.Property<int?>("LangId");
+
+                    b.Property<DateTime>("LastUpdatedAt");
+
+                    b.Property<string>("Theme")
+                        .HasMaxLength(500);
+
+                    b.Property<int?>("UserId");
+
+                    b.HasKey("Id");
+
+                    b.HasIndex("CodeEditorSettingsId")
+                        .IsUnique();
+
+                    b.HasIndex("LangId");
+
+                    b.HasIndex("UserId")
+                        .IsUnique();
+
+                    b.ToTable("UserSettingses");
+                });
+
+            modelBuilder.Entity("ClientServer.Models.Users.SystemRole", b =>
+                {
+                    b.Property<int>("Id")
+                        .ValueGeneratedOnAdd();
+
+                    b.Property<DateTime>("CreatedAt");
+
+                    b.Property<string>("DisplayName")
+                        .HasMaxLength(500);
+
+                    b.Property<string>("Email")
+                        .HasMaxLength(500);
+
+                    b.Property<DateTime>("LastUpdatedAt");
+
+                    b.Property<int>("SystemRolePermissionId");
+
+                    b.HasKey("Id");
+
+                    b.HasIndex("SystemRolePermissionId")
+                        .IsUnique();
+
+                    b.ToTable("SystemRoles");
+                });
+
+            modelBuilder.Entity("ClientServer.Models.Users.SystemRolePermission", b =>
+                {
+                    b.Property<int>("Id")
+                        .ValueGeneratedOnAdd();
+
+                    b.Property<bool>("CanChangeOtherUsersSystemRole");
+
+                    b.Property<bool>("CanChangeRoles");
+
+                    b.Property<bool>("CanChangeSystemSettings");
+
+                    b.Property<bool>("CanChangeUserData");
+
+                    b.Property<bool>("CanCreateGroups");
+
+                    b.Property<bool>("CanCreateRoles");
+
+                    b.Property<bool>("CanDeleteActivatedUsers");
+
+                    b.Property<bool>("CanDeleteGroups");
+
+                    b.Property<bool>("CanDeleteRoles");
+
+                    b.Property<bool>("CanManageNewUsers");
+
+                    b.Property<bool>("CanManageTags");
+
+                    b.Property<bool>("CanViewDashboard");
+
+                    b.Property<DateTime>("CreatedAt");
+
+                    b.Property<DateTime>("LastUpdatedAt");
+
+                    b.HasKey("Id");
+
+                    b.ToTable("SystemRolePermissions");
+                });
+
+            modelBuilder.Entity("ClientServer.Models.Users.SystemSetting", b =>
+                {
+                    b.Property<int>("Id")
+                        .ValueGeneratedOnAdd();
+
+                    b.Property<DateTime>("CreatedAt");
+
+                    b.Property<string>("CurrentServerMessage")
+                        .HasMaxLength(1000);
+
+                    b.Property<int>("CustomProjectTestCompileTimeoutInMs");
+
+                    b.Property<int>("CustomProjectTestMaxDiskSpaceInKb");
+
+                    b.Property<int>("CustomProjectTestMemoryLimitInKb");
+
+                    b.Property<int>("CustomProjectTestTimeoutInMs");
+
+                    b.Property<int>("DefaultGroupCreatorGroupRoleId");
+
+                    b.Property<int>("DefaultGroupRoleId");
+
+                    b.Property<int>("DefaultUserGroupId");
+
+                    b.Property<int>("JustRunProgramCompileTimeoutInMs");
+
+                    b.Property<int>("JustRunProgramMaxDiskSpaceInKb");
+
+                    b.Property<int>("JustRunProgramMemoryLimitInKb");
+
+                    b.Property<int>("JustRunProgramTimeoutInMs");
+
+                    b.Property<DateTime>("LastUpdatedAt");
+
+                    b.Property<int>("MaxCustomProjectsPerUser");
+
+                    b.Property<int>("MaxCustomTestsPerParticipation");
+
+                    b.Property<int>("MaxNumberOfTestsWithOneRequest");
+
+                    b.Property<int>("MaxNumberOfTestsWithOneRequestSubmitTestServer");
+
+                    b.Property<int>("SubmitTestServerTimeoutInMs");
+
+                    b.Property<string>("SubmitTestServerUrl")
+                        .HasMaxLength(500);
+
+                    b.Property<string>("TestServerConfigUiUrl")
+                        .HasMaxLength(500);
+
+                    b.Property<string>("TestServerStatsUrl")
+                        .HasMaxLength(500);
+
+                    b.Property<int>("TestServerTimeoutInMs");
+
+                    b.Property<string>("TestServerUrl")
+                        .HasMaxLength(500);
+
+                    b.HasKey("Id");
+
+                    b.HasIndex("DefaultGroupCreatorGroupRoleId")
+                        .IsUnique();
+
+                    b.HasIndex("DefaultGroupRoleId")
+                        .IsUnique();
+
+                    b.HasIndex("DefaultUserGroupId")
+                        .IsUnique();
+
+                    b.ToTable("SystemSettings");
+                });
+
+            modelBuilder.Entity("ClientServer.Models.Users.User", b =>
+                {
+                    b.Property<int>("Id")
+                        .ValueGeneratedOnAdd();
+
+                    b.Property<DateTime>("CreatedAt");
+
+                    b.Property<string>("Email")
+                        .HasMaxLength(500);
+
+                    b.Property<string>("FirstName")
+                        .HasMaxLength(500);
+
+                    b.Property<bool>("IsActivated");
+
+                    b.Property<DateTime>("LastLoginAt");
+
+                    b.Property<string>("LastName")
+                        .HasMaxLength(500);
+
+                    b.Property<DateTime>("LastUpdatedAt");
+
+                    b.Property<string>("Password")
+                        .HasMaxLength(500);
+
+                    b.Property<int?>("SystemRoleId");
+
+                    b.Property<string>("Token")
+                        .IsRequired()
+                        .HasMaxLength(500);
+
+                    b.HasKey("Id");
+
+                    b.HasAlternateKey("Token")
+                        .HasName("Unique_Token");
+
+                    b.HasIndex("SystemRoleId");
+
+                    b.ToTable("Users");
+                });
+
+            modelBuilder.Entity("ClientServer.Models.Users.UserGroup", b =>
+                {
+                    b.Property<int>("Id")
+                        .ValueGeneratedOnAdd();
+
+                    b.Property<DateTime>("CreatedAt");
+
+                    b.Property<string>("DisplayName")
+                        .HasMaxLength(500);
+
+                    b.Property<string>("Email")
+                        .HasMaxLength(500);
+
+                    b.Property<DateTime>("LastUpdatedAt");
+
+                    b.HasKey("Id");
+
+                    b.ToTable("UserGroups");
+                });
+
+            modelBuilder.Entity("ClientServer.Models.Users.UserWithUserGroup", b =>
+                {
+                    b.Property<int>("UserId");
+
+                    b.Property<int>("UserGroupId");
+
+                    b.Property<DateTime>("CreatedAt");
+
+                    b.Property<int>("GroupRoleId");
+
+                    b.Property<DateTime>("LastUpdatedAt");
+
+                    b.HasKey("UserId", "UserGroupId");
+
+                    b.HasIndex("GroupRoleId");
+
+                    b.HasIndex("UserGroupId");
+
+                    b.HasIndex("UserId");
+
+                    b.ToTable("UserWithUserGroups");
+                });
+
+            modelBuilder.Entity("ClientServer.Models.CustomProjects.CustomProject", b =>
+                {
+                    b.HasOne("ClientServer.Models.Users.User", "User")
+                        .WithMany("CustomProjects")
+                        .HasForeignKey("UserId")
+                        .OnDelete(DeleteBehavior.Cascade);
+                });
+
+            modelBuilder.Entity("ClientServer.Models.CustomProjects.CustomProjectDescription", b =>
+                {
+                    b.HasOne("ClientServer.Models.CustomProjects.CustomProject", "CustomProject")
+                        .WithOne("Description")
+                        .HasForeignKey("ClientServer.Models.CustomProjects.CustomProjectDescription", "CustomProjectId")
+                        .OnDelete(DeleteBehavior.Cascade);
+                });
+
+            modelBuilder.Entity("ClientServer.Models.CustomProjects.CustomProjectDescriptionWithFileAsAssetReference", b =>
+                {
+                    b.HasOne("ClientServer.Models.CustomProjects.CustomProjectDescription", "CustomProjectDescription")
+                        .WithMany("AssetReferences")
+                        .HasForeignKey("CustomProjectDescriptionId")
+                        .OnDelete(DeleteBehavior.Cascade);
+
+                    b.HasOne("ClientServer.Models.Files.FileReferenceUserFileAsset", "FileReferenceUserFileAsset")
+                        .WithMany("CustomProjectDescriptionWithFileAsAssetReferences")
+                        .HasForeignKey("FileReferenceUserFileAssetId")
+                        .OnDelete(DeleteBehavior.Cascade);
+                });
+
+            modelBuilder.Entity("ClientServer.Models.CustomProjects.CustomProjectSolution", b =>
+                {
+                    b.HasOne("ClientServer.Models.CustomProjects.CustomProject", "CustomProject")
+                        .WithMany("Solutions")
+                        .HasForeignKey("CustomProjectId")
+                        .OnDelete(DeleteBehavior.Cascade);
+
+                    b.HasOne("ClientServer.Models.CustomProjects.CustomProjectSolutionFile", "MainFile")
+                        .WithOne()
+                        .HasForeignKey("ClientServer.Models.CustomProjects.CustomProjectSolution", "MainFileId")
+                        .OnDelete(DeleteBehavior.SetNull);
+
+                    b.HasOne("ClientServer.Models.PLang", "PLang")
+                        .WithMany()
+                        .HasForeignKey("PLangId")
+                        .OnDelete(DeleteBehavior.Cascade);
+                });
+
+            modelBuilder.Entity("ClientServer.Models.CustomProjects.CustomProjectSolutionFile", b =>
+                {
+                    b.HasOne("ClientServer.Models.CustomProjects.CustomProjectSolution")
+                        .WithMany("SolutionFiles")
+                        .HasForeignKey("CustomProjectSolutionId")
+                        .OnDelete(DeleteBehavior.Cascade);
+                });
+
+            modelBuilder.Entity("ClientServer.Models.CustomProjects.CustomProjectTest", b =>
+                {
+                    b.HasOne("ClientServer.Models.CustomProjects.CustomProject", "CustomProject")
+                        .WithMany("Tests")
+                        .HasForeignKey("CustomProjectId")
+                        .OnDelete(DeleteBehavior.Cascade);
+
+                    b.HasOne("ClientServer.Models.Exercises.Tests.TestSettings", "TestSettings")
+                        .WithOne()
+                        .HasForeignKey("ClientServer.Models.CustomProjects.CustomProjectTest", "TestSettingsId")
+                        .OnDelete(DeleteBehavior.Cascade);
+
+                    b.HasOne("ClientServer.Models.Exercises.Tests.TestType", "TestType")
+                        .WithMany()
+                        .HasForeignKey("TestTypeId")
+                        .OnDelete(DeleteBehavior.Cascade);
+                });
+
+            modelBuilder.Entity("ClientServer.Models.CustomProjects.CustomProjectTestWithFileAsAssetReference", b =>
+                {
+                    b.HasOne("ClientServer.Models.CustomProjects.CustomProjectTest", "CustomProjectTest")
+                        .WithMany("AssetReferences")
+                        .HasForeignKey("CustomProjectTestId")
+                        .OnDelete(DeleteBehavior.Cascade);
+
+                    b.HasOne("ClientServer.Models.Files.FileReferenceUserFileAsset", "FileReferenceUserFileAsset")
+                        .WithMany("CustomProjectTestWithFileAsAssetReferences")
+                        .HasForeignKey("FileReferenceUserFileAssetId")
+                        .OnDelete(DeleteBehavior.Cascade);
+                });
+
+            modelBuilder.Entity("ClientServer.Models.CustomProjects.CustomProjectTestWithSolutionAsTestResult", b =>
+                {
+                    b.HasOne("ClientServer.Models.CustomProjects.CustomProjectSolution", "CustomProjectSolution")
+                        .WithMany("TestResults")
+                        .HasForeignKey("CustomProjectSolutionId")
+                        .OnDelete(DeleteBehavior.Cascade);
+
+                    b.HasOne("ClientServer.Models.CustomProjects.CustomProjectTest", "CustomProjectTest")
+                        .WithMany("TestResults")
+                        .HasForeignKey("CustomProjectTestId")
+                        .OnDelete(DeleteBehavior.Cascade);
+                });
+
+            modelBuilder.Entity("ClientServer.Models.Exercises.AfterSolutions.AfterSolution", b =>
+                {
+                    b.HasOne("ClientServer.Models.Exercises.AfterSolutions.AfterSolutionFile", "MainFile")
+                        .WithOne()
+                        .HasForeignKey("ClientServer.Models.Exercises.AfterSolutions.AfterSolution", "MainFileId")
+                        .OnDelete(DeleteBehavior.SetNull);
+
+                    b.HasOne("ClientServer.Models.Exercises.Solution.Solution", "Solution")
+                        .WithOne("AfterSolution")
+                        .HasForeignKey("ClientServer.Models.Exercises.AfterSolutions.AfterSolution", "SolutionUserId", "SolutionExerciseReleaseId", "SolutionPLangId")
+                        .OnDelete(DeleteBehavior.Cascade);
+                });
+
+            modelBuilder.Entity("ClientServer.Models.Exercises.AfterSolutions.AfterSolutionFile", b =>
+                {
+                    b.HasOne("ClientServer.Models.Exercises.AfterSolutions.AfterSolution", "AfterSolution")
+                        .WithMany("SolutionFiles")
+                        .HasForeignKey("AfterSolutionId")
+                        .OnDelete(DeleteBehavior.Cascade);
+
+                    b.HasOne("ClientServer.Models.Exercises.TemplateFile", "TemplateFile")
+                        .WithMany()
+                        .HasForeignKey("TemplateFileId");
+                });
+
+            modelBuilder.Entity("ClientServer.Models.Exercises.AfterSolutions.CustomTestWithAfterSolutionAsTestResult", b =>
+                {
+                    b.HasOne("ClientServer.Models.Exercises.AfterSolutions.AfterSolution", "AfterSolution")
+                        .WithMany("CustomTestResults")
+                        .HasForeignKey("AfterSolutionId")
+                        .OnDelete(DeleteBehavior.Cascade);
+
+                    b.HasOne("ClientServer.Models.Exercises.Tests.CustomTest", "CustomTest")
+                        .WithMany("AfterTestResults")
+                        .HasForeignKey("CustomTestId")
+                        .OnDelete(DeleteBehavior.Cascade);
+                });
+
+            modelBuilder.Entity("ClientServer.Models.Exercises.AfterSolutions.TestWithAfterSolutionAsTestResult", b =>
+                {
+                    b.HasOne("ClientServer.Models.Exercises.AfterSolutions.AfterSolution", "AfterSolution")
+                        .WithMany("TestResults")
+                        .HasForeignKey("AfterSolutionId")
+                        .OnDelete(DeleteBehavior.Cascade);
+
+                    b.HasOne("ClientServer.Models.Exercises.Tests.Test", "Test")
+                        .WithMany("AfterTestResults")
+                        .HasForeignKey("TestId")
+                        .OnDelete(DeleteBehavior.Cascade);
+                });
+
+            modelBuilder.Entity("ClientServer.Models.Exercises.CodeTemplate", b =>
+                {
+                    b.HasOne("ClientServer.Models.Exercises.Exercise", "Exercise")
+                        .WithMany("CodeTemplates")
+                        .HasForeignKey("ExerciseId")
+                        .OnDelete(DeleteBehavior.Cascade);
+
+                    b.HasOne("ClientServer.Models.Exercises.TemplateFile", "MainFile")
+                        .WithOne()
+                        .HasForeignKey("ClientServer.Models.Exercises.CodeTemplate", "MainFileId")
+                        .OnDelete(DeleteBehavior.SetNull);
+
+                    b.HasOne("ClientServer.Models.PLang", "PLang")
+                        .WithMany()
+                        .HasForeignKey("PLangId");
+                });
+
+            modelBuilder.Entity("ClientServer.Models.Exercises.CustomTestWithFileAsAssetReference", b =>
+                {
+                    b.HasOne("ClientServer.Models.Exercises.Tests.CustomTest", "CustomTest")
+                        .WithMany("AssetReferences")
+                        .HasForeignKey("CustomTestId")
+                        .OnDelete(DeleteBehavior.Cascade);
+
+                    b.HasOne("ClientServer.Models.Files.FileReferenceUserFileAsset", "FileReferenceUserFileAsset")
+                        .WithMany("CustomTestWithFileAsAssetReferences")
+                        .HasForeignKey("FileReferenceUserFileAssetId")
+                        .OnDelete(DeleteBehavior.Cascade);
+                });
+
+            modelBuilder.Entity("ClientServer.Models.Exercises.Exercise", b =>
+                {
+                    b.HasOne("ClientServer.Models.Users.UserGroup", "UserGroup")
+                        .WithMany("Exercises")
+                        .HasForeignKey("UserGroupId")
+                        .OnDelete(DeleteBehavior.Cascade);
+
+                    b.HasOne("ClientServer.Models.Users.User", "User")
+                        .WithMany("Exercises")
+                        .HasForeignKey("UserId")
+                        .OnDelete(DeleteBehavior.SetNull);
+                });
+
+            modelBuilder.Entity("ClientServer.Models.Exercises.ExerciseDescription", b =>
+                {
+                    b.HasOne("ClientServer.Models.Exercises.Exercise", "Exercise")
+                        .WithOne("Description")
+                        .HasForeignKey("ClientServer.Models.Exercises.ExerciseDescription", "ExerciseId")
+                        .OnDelete(DeleteBehavior.Cascade);
+                });
+
+            modelBuilder.Entity("ClientServer.Models.Exercises.ExerciseDescriptionWithFileAsAssetReference", b =>
+                {
+                    b.HasOne("ClientServer.Models.Exercises.ExerciseDescription", "ExerciseDescription")
+                        .WithMany("AssetReferences")
+                        .HasForeignKey("ExerciseDescriptionId")
+                        .OnDelete(DeleteBehavior.Cascade);
+
+                    b.HasOne("ClientServer.Models.Files.FileReferenceMarkdownAsset", "FileReferenceMarkdownAsset")
+                        .WithMany("AssetReferences")
+                        .HasForeignKey("FileReferenceMarkdownAssetId")
+                        .OnDelete(DeleteBehavior.Cascade);
+                });
+
+            modelBuilder.Entity("ClientServer.Models.Exercises.MetaData", b =>
+                {
+                    b.HasOne("ClientServer.Models.Exercises.Exercise")
+                        .WithOne("MetaData")
+                        .HasForeignKey("ClientServer.Models.Exercises.MetaData", "ExerciseId")
+                        .OnDelete(DeleteBehavior.Cascade);
+
+                    b.HasOne("ClientServer.Models.Exercises.Exercise", "Exercise")
+                        .WithMany()
+                        .HasForeignKey("ExerciseId1");
+                });
+
+            modelBuilder.Entity("ClientServer.Models.Exercises.Release.ExerciseRelease", b =>
+                {
+                    b.HasOne("ClientServer.Models.Exercises.Exercise", "Exercise")
+                        .WithMany("Releases")
+                        .HasForeignKey("ExerciseId")
+                        .OnDelete(DeleteBehavior.Cascade);
+
+                    b.HasOne("ClientServer.Models.PLang", "PLang")
+                        .WithMany()
+                        .HasForeignKey("PLangId");
+                });
+
+            modelBuilder.Entity("ClientServer.Models.Exercises.Solution.CustomTestWithSingleSolutionAsTestResult", b =>
+                {
+                    b.HasOne("ClientServer.Models.Exercises.Tests.CustomTest", "CustomTest")
+                        .WithMany("TestResultsNew")
+                        .HasForeignKey("CustomTestId")
+                        .OnDelete(DeleteBehavior.Cascade);
+
+                    b.HasOne("ClientServer.Models.Exercises.Solution.Solution", "Solution")
+                        .WithMany("CustomTestResults")
+                        .HasForeignKey("SolutionUserId", "SolutionExerciseReleaseId", "SolutionPLangId")
+                        .OnDelete(DeleteBehavior.Cascade);
+                });
+
+            modelBuilder.Entity("ClientServer.Models.Exercises.Solution.ExerciseReleaseWithUserAsParticipation", b =>
+                {
+                    b.HasOne("ClientServer.Models.Exercises.Release.ExerciseRelease", "ExerciseRelease")
+                        .WithMany("ExerciseReleaseWithUserAsParticipations")
+                        .HasForeignKey("ExerciseReleaseId")
+                        .OnDelete(DeleteBehavior.Cascade);
+
+                    b.HasOne("ClientServer.Models.PLang", "LastEditedPLang")
+                        .WithMany()
+                        .HasForeignKey("LastEditedPLangId");
+
+                    b.HasOne("ClientServer.Models.Users.User", "User")
+                        .WithMany("ExerciseReleaseWithUserAsParticipations")
+                        .HasForeignKey("UserId")
+                        .OnDelete(DeleteBehavior.Cascade);
+                });
+
+            modelBuilder.Entity("ClientServer.Models.Exercises.Solution.Solution", b =>
+                {
+                    b.HasOne("ClientServer.Models.Exercises.Solution.SolutionAssessment", "Assessment")
+                        .WithOne("Solution")
+                        .HasForeignKey("ClientServer.Models.Exercises.Solution.Solution", "AssessmentId")
+                        .OnDelete(DeleteBehavior.Cascade);
+
+                    b.HasOne("ClientServer.Models.Exercises.Solution.SolutionFile", "MainFile")
+                        .WithOne()
+                        .HasForeignKey("ClientServer.Models.Exercises.Solution.Solution", "MainFileId")
+                        .OnDelete(DeleteBehavior.SetNull);
+
+                    b.HasOne("ClientServer.Models.PLang", "PLang")
+                        .WithMany()
+                        .HasForeignKey("PLangId");
+
+                    b.HasOne("ClientServer.Models.Exercises.Solution.ExerciseReleaseWithUserAsParticipation", "ExerciseReleaseWithUserAsParticipation")
+                        .WithMany("Solutions")
+                        .HasForeignKey("UserId", "ExerciseReleaseId")
+                        .OnDelete(DeleteBehavior.Cascade);
+                });
+
+            modelBuilder.Entity("ClientServer.Models.Exercises.Solution.SolutionFile", b =>
+                {
+                    b.HasOne("ClientServer.Models.Exercises.TemplateFile", "TemplateFile")
+                        .WithMany("SolutionParts")
+                        .HasForeignKey("TemplateFileId")
+                        .OnDelete(DeleteBehavior.SetNull);
+
+                    b.HasOne("ClientServer.Models.Exercises.Solution.Solution", "Solution")
+                        .WithMany("SolutionFiles")
+                        .HasForeignKey("SolutionUserId", "SolutionExerciseReleaseId", "SolutionPLangId")
+                        .OnDelete(DeleteBehavior.Cascade);
+                });
+
+            modelBuilder.Entity("ClientServer.Models.Exercises.Solution.TestWithSingleSolutionAsTestResult", b =>
+                {
+                    b.HasOne("ClientServer.Models.Exercises.Tests.Test", "Test")
+                        .WithMany("TestResultsNew")
+                        .HasForeignKey("TestId")
+                        .OnDelete(DeleteBehavior.Cascade);
+
+                    b.HasOne("ClientServer.Models.Exercises.Solution.Solution", "Solution")
+                        .WithMany("TestResults")
+                        .HasForeignKey("SolutionUserId", "SolutionExerciseReleaseId", "SolutionPLangId")
+                        .OnDelete(DeleteBehavior.Cascade);
+                });
+
+            modelBuilder.Entity("ClientServer.Models.Exercises.TagWithMetaData", b =>
+                {
+                    b.HasOne("ClientServer.Models.Exercises.MetaData", "MetaData")
+                        .WithMany("TagWithMetaDatas")
+                        .HasForeignKey("MetaDataId")
+                        .OnDelete(DeleteBehavior.Cascade);
+
+                    b.HasOne("ClientServer.Models.Exercises.Tag", "Tag")
+                        .WithMany()
+                        .HasForeignKey("TagId")
+                        .OnDelete(DeleteBehavior.Cascade);
+                });
+
+            modelBuilder.Entity("ClientServer.Models.Exercises.TemplateFile", b =>
+                {
+                    b.HasOne("ClientServer.Models.Exercises.CodeTemplate")
+                        .WithMany("TemplateFiles")
+                        .HasForeignKey("CodeTemplateId")
+                        .OnDelete(DeleteBehavior.Cascade);
+                });
+
+            modelBuilder.Entity("ClientServer.Models.Exercises.Tests.CustomTest", b =>
+                {
+                    b.HasOne("ClientServer.Models.Exercises.Tests.TestType", "TestType")
+                        .WithMany()
+                        .HasForeignKey("TestTypeId")
+                        .OnDelete(DeleteBehavior.Cascade);
+
+                    b.HasOne("ClientServer.Models.Exercises.Solution.ExerciseReleaseWithUserAsParticipation")
+                        .WithMany("CustomTests")
+                        .HasForeignKey("UserId", "ExerciseReleaseId")
+                        .OnDelete(DeleteBehavior.Cascade);
+                });
+
+            modelBuilder.Entity("ClientServer.Models.Exercises.Tests.DefaultCustomTestSettings", b =>
+                {
+                    b.HasOne("ClientServer.Models.Exercises.Exercise", "Exercise")
+                        .WithOne("DefaultCustomTestSettings")
+                        .HasForeignKey("ClientServer.Models.Exercises.Tests.DefaultCustomTestSettings", "ExerciseId")
+                        .OnDelete(DeleteBehavior.Cascade);
+                });
+
+            modelBuilder.Entity("ClientServer.Models.Exercises.Tests.Test", b =>
+                {
+                    b.HasOne("ClientServer.Models.Exercises.Exercise", "Exercise")
+                        .WithMany("Tests")
+                        .HasForeignKey("ExerciseId")
+                        .OnDelete(DeleteBehavior.Cascade);
+
+                    b.HasOne("ClientServer.Models.Exercises.Tests.TestSettings", "TestSettings")
+                        .WithOne()
+                        .HasForeignKey("ClientServer.Models.Exercises.Tests.Test", "TestSettingsId")
+                        .OnDelete(DeleteBehavior.Cascade);
+
+                    b.HasOne("ClientServer.Models.Exercises.Tests.TestType", "TestType")
+                        .WithMany()
+                        .HasForeignKey("TestTypeId");
+                });
+
+            modelBuilder.Entity("ClientServer.Models.Exercises.TestWithFileAsAssetReference", b =>
+                {
+                    b.HasOne("ClientServer.Models.Files.FileReferenceTestAsset", "FileReferenceTestAsset")
+                        .WithMany("AssetReferences")
+                        .HasForeignKey("FileReferenceTestAssetId")
+                        .OnDelete(DeleteBehavior.Cascade);
+
+                    b.HasOne("ClientServer.Models.Exercises.Tests.Test", "Test")
+                        .WithMany("AssetReferences")
+                        .HasForeignKey("TestId")
+                        .OnDelete(DeleteBehavior.Cascade);
+                });
+
+            modelBuilder.Entity("ClientServer.Models.Users.AuthToken", b =>
+                {
+                    b.HasOne("ClientServer.Models.Users.User", "User")
+                        .WithOne()
+                        .HasForeignKey("ClientServer.Models.Users.AuthToken", "UserId")
+                        .OnDelete(DeleteBehavior.Cascade);
+                });
+
+            modelBuilder.Entity("ClientServer.Models.Users.ExternalUser", b =>
+                {
+                    b.HasOne("ClientServer.Models.Users.User", "User")
+                        .WithOne("ExternalUser")
+                        .HasForeignKey("ClientServer.Models.Users.ExternalUser", "UserId")
+                        .OnDelete(DeleteBehavior.Cascade);
+                });
+
+            modelBuilder.Entity("ClientServer.Models.Users.GroupRole", b =>
+                {
+                    b.HasOne("ClientServer.Models.Users.GroupRolePermission", "GroupRolePermission")
+                        .WithOne()
+                        .HasForeignKey("ClientServer.Models.Users.GroupRole", "GroupRolePermissionId")
+                        .OnDelete(DeleteBehavior.Cascade);
+                });
+
+            modelBuilder.Entity("ClientServer.Models.Users.Settings.UserSetting", b =>
+                {
+                    b.HasOne("ClientServer.Models.Users.Settings.CodeEditorSetting", "CodeEditorSetting")
+                        .WithOne()
+                        .HasForeignKey("ClientServer.Models.Users.Settings.UserSetting", "CodeEditorSettingsId")
+                        .OnDelete(DeleteBehavior.Cascade);
+
+                    b.HasOne("ClientServer.Models.Lang", "Lang")
+                        .WithMany()
+                        .HasForeignKey("LangId")
+                        .OnDelete(DeleteBehavior.SetNull);
+
+                    b.HasOne("ClientServer.Models.Users.User", "User")
+                        .WithOne("UserSettings")
+                        .HasForeignKey("ClientServer.Models.Users.Settings.UserSetting", "UserId")
+                        .OnDelete(DeleteBehavior.Cascade);
+                });
+
+            modelBuilder.Entity("ClientServer.Models.Users.SystemRole", b =>
+                {
+                    b.HasOne("ClientServer.Models.Users.SystemRolePermission", "SystemRolePermission")
+                        .WithOne()
+                        .HasForeignKey("ClientServer.Models.Users.SystemRole", "SystemRolePermissionId")
+                        .OnDelete(DeleteBehavior.Cascade);
+                });
+
+            modelBuilder.Entity("ClientServer.Models.Users.SystemSetting", b =>
+                {
+                    b.HasOne("ClientServer.Models.Users.GroupRole", "DefaultGroupCreatorGroupRole")
+                        .WithOne()
+                        .HasForeignKey("ClientServer.Models.Users.SystemSetting", "DefaultGroupCreatorGroupRoleId");
+
+                    b.HasOne("ClientServer.Models.Users.GroupRole", "DefaultGroupRole")
+                        .WithOne()
+                        .HasForeignKey("ClientServer.Models.Users.SystemSetting", "DefaultGroupRoleId");
+
+                    b.HasOne("ClientServer.Models.Users.UserGroup", "DefaultUserGroup")
+                        .WithOne()
+                        .HasForeignKey("ClientServer.Models.Users.SystemSetting", "DefaultUserGroupId");
+                });
+
+            modelBuilder.Entity("ClientServer.Models.Users.User", b =>
+                {
+                    b.HasOne("ClientServer.Models.Users.SystemRole", "SystemRole")
+                        .WithMany()
+                        .HasForeignKey("SystemRoleId")
+                        .OnDelete(DeleteBehavior.SetNull);
+                });
+
+            modelBuilder.Entity("ClientServer.Models.Users.UserWithUserGroup", b =>
+                {
+                    b.HasOne("ClientServer.Models.Users.GroupRole", "GroupRole")
+                        .WithMany("UserUserGroups")
+                        .HasForeignKey("GroupRoleId");
+
+                    b.HasOne("ClientServer.Models.Users.UserGroup", "UserGroup")
+                        .WithMany("UserWithUserGroups")
+                        .HasForeignKey("UserGroupId")
+                        .OnDelete(DeleteBehavior.Cascade);
+
+                    b.HasOne("ClientServer.Models.Users.User", "User")
+                        .WithMany("UserWithUserGroups")
+                        .HasForeignKey("UserId")
+                        .OnDelete(DeleteBehavior.Cascade);
+                });
+        }
+    }
+}
diff --git a/src/ClientServer/Migrations/20190728133647_RemoveOldDbAssets.cs b/src/ClientServer/Migrations/20190728133647_RemoveOldDbAssets.cs
new file mode 100755
index 0000000..81942cd
--- /dev/null
+++ b/src/ClientServer/Migrations/20190728133647_RemoveOldDbAssets.cs
@@ -0,0 +1,157 @@
+using System;
+using System.Collections.Generic;
+using Microsoft.EntityFrameworkCore.Migrations;
+
+namespace ClientServer.Migrations
+{
+    public partial class RemoveOldDbAssets : Migration
+    {
+        protected override void Up(MigrationBuilder migrationBuilder)
+        {
+            migrationBuilder.DropForeignKey(
+                name: "FK_CustomProjectTestAssets_CustomProjectTests_CustomProjectTestId",
+                table: "CustomProjectTestAssets");
+
+            migrationBuilder.DropIndex(
+                name: "IX_CustomProjectTestAssets_CustomProjectTestId",
+                table: "CustomProjectTestAssets");
+
+            migrationBuilder.DropColumn(
+                name: "CustomProjectTestId",
+                table: "CustomProjectTestAssets");
+
+            migrationBuilder.DropTable(
+                name: "Assets");
+
+            migrationBuilder.DropTable(
+                name: "CustomTestAssets");
+
+            migrationBuilder.DropTable(
+                name: "TestAssets");
+        }
+
+        protected override void Down(MigrationBuilder migrationBuilder)
+        {
+            migrationBuilder.CreateTable(
+                name: "Assets",
+                columns: table => new
+                {
+                    Id = table.Column<int>(nullable: false)
+                        .Annotation("Npgsql:ValueGeneratedOnAdd", true),
+                    AssetUrl = table.Column<string>(maxLength: 500, nullable: true),
+                    Content = table.Column<byte[]>(nullable: true),
+                    CreatedAt = table.Column<DateTime>(nullable: false),
+                    CustomProjectDescriptionId = table.Column<int>(nullable: true),
+                    DisplayName = table.Column<string>(maxLength: 500, nullable: true),
+                    ExerciseDescriptionId = table.Column<int>(nullable: false),
+                    LastUpdatedAt = table.Column<DateTime>(nullable: false),
+                    MimeType = table.Column<string>(maxLength: 500, nullable: true)
+                },
+                constraints: table =>
+                {
+                    table.PrimaryKey("PK_Assets", x => x.Id);
+                    table.ForeignKey(
+                        name: "FK_Assets_CustomProjectDescriptions_CustomProjectDescriptionId",
+                        column: x => x.CustomProjectDescriptionId,
+                        principalTable: "CustomProjectDescriptions",
+                        principalColumn: "Id",
+                        onDelete: ReferentialAction.Restrict);
+                    table.ForeignKey(
+                        name: "FK_Assets_ExerciseDescriptions_ExerciseDescriptionId",
+                        column: x => x.ExerciseDescriptionId,
+                        principalTable: "ExerciseDescriptions",
+                        principalColumn: "Id",
+                        onDelete: ReferentialAction.Cascade);
+                });
+
+            migrationBuilder.CreateTable(
+                name: "CustomTestAssets",
+                columns: table => new
+                {
+                    Id = table.Column<int>(nullable: false)
+                        .Annotation("Npgsql:ValueGeneratedOnAdd", true),
+                    Content = table.Column<byte[]>(nullable: true),
+                    CreatedAt = table.Column<DateTime>(nullable: false),
+                    CustomTestId = table.Column<int>(nullable: false),
+                    DisplayName = table.Column<string>(maxLength: 500, nullable: true),
+                    Hash = table.Column<string>(maxLength: 500, nullable: true),
+                    LastUpdatedAt = table.Column<DateTime>(nullable: false),
+                    MimeType = table.Column<string>(maxLength: 500, nullable: true)
+                },
+                constraints: table =>
+                {
+                    table.PrimaryKey("PK_CustomTestAssets", x => x.Id);
+                    table.ForeignKey(
+                        name: "FK_CustomTestAssets_CustomTest_CustomTestId",
+                        column: x => x.CustomTestId,
+                        principalTable: "CustomTest",
+                        principalColumn: "Id",
+                        onDelete: ReferentialAction.Cascade);
+                });
+
+            migrationBuilder.CreateTable(
+                name: "TestAssets",
+                columns: table => new
+                {
+                    Id = table.Column<int>(nullable: false)
+                        .Annotation("Npgsql:ValueGeneratedOnAdd", true),
+                    Content = table.Column<byte[]>(nullable: true),
+                    CreatedAt = table.Column<DateTime>(nullable: false),
+                    DisplayName = table.Column<string>(maxLength: 500, nullable: true),
+                    Hash = table.Column<string>(maxLength: 500, nullable: true),
+                    LastUpdatedAt = table.Column<DateTime>(nullable: false),
+                    MimeType = table.Column<string>(maxLength: 500, nullable: true),
+                    TestId = table.Column<int>(nullable: false)
+                },
+                constraints: table =>
+                {
+                    table.PrimaryKey("PK_TestAssets", x => x.Id);
+                    table.ForeignKey(
+                        name: "FK_TestAssets_Tests_TestId",
+                        column: x => x.TestId,
+                        principalTable: "Tests",
+                        principalColumn: "Id",
+                        onDelete: ReferentialAction.Cascade);
+                });
+
+            migrationBuilder.AddColumn<int>(
+                name: "CustomProjectTestId",
+                table: "CustomProjectTestAssets",
+                nullable: false,
+                defaultValue: 0);
+
+            migrationBuilder.CreateIndex(
+                name: "IX_CustomProjectTestAssets_CustomProjectTestId",
+                table: "CustomProjectTestAssets",
+                column: "CustomProjectTestId");
+
+            migrationBuilder.CreateIndex(
+                name: "IX_Assets_CustomProjectDescriptionId",
+                table: "Assets",
+                column: "CustomProjectDescriptionId");
+
+            migrationBuilder.CreateIndex(
+                name: "IX_Assets_ExerciseDescriptionId",
+                table: "Assets",
+                column: "ExerciseDescriptionId");
+
+            migrationBuilder.CreateIndex(
+                name: "IX_CustomTestAssets_CustomTestId",
+                table: "CustomTestAssets",
+                column: "CustomTestId");
+
+            migrationBuilder.CreateIndex(
+                name: "IX_TestAssets_TestId",
+                table: "TestAssets",
+                column: "TestId");
+
+            migrationBuilder.AddForeignKey(
+                name: "FK_CustomProjectTestAssets_CustomProjectTests_CustomProjectTestId",
+                table: "CustomProjectTestAssets",
+                column: "CustomProjectTestId",
+                principalTable: "CustomProjectTests",
+                principalColumn: "Id",
+                onDelete: ReferentialAction.Cascade);
+        }
+    }
+}
diff --git a/src/ClientServer/Migrations/SyndromDbContextModelSnapshot.cs b/src/ClientServer/Migrations/SyndromDbContextModelSnapshot.cs
index 989fc8c..72787d5 100644
--- a/src/ClientServer/Migrations/SyndromDbContextModelSnapshot.cs
+++ b/src/ClientServer/Migrations/SyndromDbContextModelSnapshot.cs
@@ -188,9 +188,6 @@ namespace ClientServer.Migrations
 
                     b.Property<DateTime>("CreatedAt");
 
-                    b.Property<int?>("CustomProjectTestId")
-                        .IsRequired();
-
                     b.Property<string>("DisplayName")
                         .HasMaxLength(500);
 
@@ -204,8 +201,6 @@ namespace ClientServer.Migrations
 
                     b.HasKey("Id");
 
-                    b.HasIndex("CustomProjectTestId");
-
                     b.ToTable("CustomProjectTestAssets");
                 });
 
@@ -416,40 +411,6 @@ namespace ClientServer.Migrations
                     b.ToTable("TestWithAfterSolutionAsTestResults");
                 });
 
-            modelBuilder.Entity("ClientServer.Models.Exercises.Asset", b =>
-                {
-                    b.Property<int>("Id")
-                        .ValueGeneratedOnAdd();
-
-                    b.Property<string>("AssetUrl")
-                        .HasMaxLength(500);
-
-                    b.Property<byte[]>("Content");
-
-                    b.Property<DateTime>("CreatedAt");
-
-                    b.Property<int?>("CustomProjectDescriptionId");
-
-                    b.Property<string>("DisplayName")
-                        .HasMaxLength(500);
-
-                    b.Property<int?>("ExerciseDescriptionId")
-                        .IsRequired();
-
-                    b.Property<DateTime>("LastUpdatedAt");
-
-                    b.Property<string>("MimeType")
-                        .HasMaxLength(500);
-
-                    b.HasKey("Id");
-
-                    b.HasIndex("CustomProjectDescriptionId");
-
-                    b.HasIndex("ExerciseDescriptionId");
-
-                    b.ToTable("Assets");
-                });
-
             modelBuilder.Entity("ClientServer.Models.Exercises.CodeTemplate", b =>
                 {
                     b.Property<int>("Id")
@@ -1004,36 +965,6 @@ namespace ClientServer.Migrations
                     b.ToTable("CustomTest");
                 });
 
-            modelBuilder.Entity("ClientServer.Models.Exercises.Tests.CustomTestAsset", b =>
-                {
-                    b.Property<int>("Id")
-                        .ValueGeneratedOnAdd();
-
-                    b.Property<byte[]>("Content");
-
-                    b.Property<DateTime>("CreatedAt");
-
-                    b.Property<int?>("CustomTestId")
-                        .IsRequired();
-
-                    b.Property<string>("DisplayName")
-                        .HasMaxLength(500);
-
-                    b.Property<string>("Hash")
-                        .HasMaxLength(500);
-
-                    b.Property<DateTime>("LastUpdatedAt");
-
-                    b.Property<string>("MimeType")
-                        .HasMaxLength(500);
-
-                    b.HasKey("Id");
-
-                    b.HasIndex("CustomTestId");
-
-                    b.ToTable("CustomTestAssets");
-                });
-
             modelBuilder.Entity("ClientServer.Models.Exercises.Tests.DefaultCustomTestSettings", b =>
                 {
                     b.Property<int>("Id")
@@ -1103,36 +1034,6 @@ namespace ClientServer.Migrations
                     b.ToTable("Tests");
                 });
 
-            modelBuilder.Entity("ClientServer.Models.Exercises.Tests.TestAsset", b =>
-                {
-                    b.Property<int>("Id")
-                        .ValueGeneratedOnAdd();
-
-                    b.Property<byte[]>("Content");
-
-                    b.Property<DateTime>("CreatedAt");
-
-                    b.Property<string>("DisplayName")
-                        .HasMaxLength(500);
-
-                    b.Property<string>("Hash")
-                        .HasMaxLength(500);
-
-                    b.Property<DateTime>("LastUpdatedAt");
-
-                    b.Property<string>("MimeType")
-                        .HasMaxLength(500);
-
-                    b.Property<int?>("TestId")
-                        .IsRequired();
-
-                    b.HasKey("Id");
-
-                    b.HasIndex("TestId");
-
-                    b.ToTable("TestAssets");
-                });
-
             modelBuilder.Entity("ClientServer.Models.Exercises.Tests.TestSettings", b =>
                 {
                     b.Property<int>("Id")
@@ -1795,14 +1696,6 @@ namespace ClientServer.Migrations
                         .OnDelete(DeleteBehavior.Cascade);
                 });
 
-            modelBuilder.Entity("ClientServer.Models.CustomProjects.CustomProjectTestAsset", b =>
-                {
-                    b.HasOne("ClientServer.Models.CustomProjects.CustomProjectTest")
-                        .WithMany("TestAssets")
-                        .HasForeignKey("CustomProjectTestId")
-                        .OnDelete(DeleteBehavior.Cascade);
-                });
-
             modelBuilder.Entity("ClientServer.Models.CustomProjects.CustomProjectTestWithFileAsAssetReference", b =>
                 {
                     b.HasOne("ClientServer.Models.CustomProjects.CustomProjectTest", "CustomProjectTest")
@@ -1880,18 +1773,6 @@ namespace ClientServer.Migrations
                         .OnDelete(DeleteBehavior.Cascade);
                 });
 
-            modelBuilder.Entity("ClientServer.Models.Exercises.Asset", b =>
-                {
-                    b.HasOne("ClientServer.Models.CustomProjects.CustomProjectDescription")
-                        .WithMany("Assets")
-                        .HasForeignKey("CustomProjectDescriptionId");
-
-                    b.HasOne("ClientServer.Models.Exercises.ExerciseDescription")
-                        .WithMany("Assets")
-                        .HasForeignKey("ExerciseDescriptionId")
-                        .OnDelete(DeleteBehavior.Cascade);
-                });
-
             modelBuilder.Entity("ClientServer.Models.Exercises.CodeTemplate", b =>
                 {
                     b.HasOne("ClientServer.Models.Exercises.Exercise", "Exercise")
@@ -2092,14 +1973,6 @@ namespace ClientServer.Migrations
                         .OnDelete(DeleteBehavior.Cascade);
                 });
 
-            modelBuilder.Entity("ClientServer.Models.Exercises.Tests.CustomTestAsset", b =>
-                {
-                    b.HasOne("ClientServer.Models.Exercises.Tests.CustomTest")
-                        .WithMany("TestAssets")
-                        .HasForeignKey("CustomTestId")
-                        .OnDelete(DeleteBehavior.Cascade);
-                });
-
             modelBuilder.Entity("ClientServer.Models.Exercises.Tests.DefaultCustomTestSettings", b =>
                 {
                     b.HasOne("ClientServer.Models.Exercises.Exercise", "Exercise")
@@ -2125,14 +1998,6 @@ namespace ClientServer.Migrations
                         .HasForeignKey("TestTypeId");
                 });
 
-            modelBuilder.Entity("ClientServer.Models.Exercises.Tests.TestAsset", b =>
-                {
-                    b.HasOne("ClientServer.Models.Exercises.Tests.Test")
-                        .WithMany("TestAssets")
-                        .HasForeignKey("TestId")
-                        .OnDelete(DeleteBehavior.Cascade);
-                });
-
             modelBuilder.Entity("ClientServer.Models.Exercises.TestWithFileAsAssetReference", b =>
                 {
                     b.HasOne("ClientServer.Models.Files.FileReferenceTestAsset", "FileReferenceTestAsset")
diff --git a/src/ClientServer/Models/CustomProjects/CustomProjectDescription.cs b/src/ClientServer/Models/CustomProjects/CustomProjectDescription.cs
index 327634b..ac89d2c 100644
--- a/src/ClientServer/Models/CustomProjects/CustomProjectDescription.cs
+++ b/src/ClientServer/Models/CustomProjects/CustomProjectDescription.cs
@@ -24,10 +24,6 @@ namespace ClientServer.Models.CustomProjects
         [MaxLength(YapexDbContext.DescriptionContentMaxStringLength)]
         public string Content { get; set; }
 
-        /// <summary>
-        /// the assets for the description e.g. images
-        /// </summary>
-        public List<Asset> Assets { get; set; }
 
         /// <summary>
         /// the assets for the description e.g. images
diff --git a/src/ClientServer/Models/CustomProjects/CustomProjectTest.cs b/src/ClientServer/Models/CustomProjects/CustomProjectTest.cs
index 4393cae..dca5353 100644
--- a/src/ClientServer/Models/CustomProjects/CustomProjectTest.cs
+++ b/src/ClientServer/Models/CustomProjects/CustomProjectTest.cs
@@ -13,7 +13,6 @@ namespace ClientServer.Models.CustomProjects
     {
         public CustomProjectTest()
         {
-            TestAssets = new List<CustomProjectTestAsset>();
             AssetReferences = new List<CustomProjectTestWithFileAsAssetReference>();
         }
         
@@ -46,11 +45,6 @@ namespace ClientServer.Models.CustomProjects
         /// </summary>
         public TestType TestType { get; set; }
         
-        /// <summary>
-        /// all related test assets for this e.g. a file to read
-        /// </summary>
-        public List<CustomProjectTestAsset> TestAssets { get; set; }
-        
         /// <summary>
         /// all related test assets for this e.g. a file to read
         /// </summary>
diff --git a/src/ClientServer/Models/Exercises/Asset.cs b/src/ClientServer/Models/Exercises/Asset.cs
deleted file mode 100644
index 03d1814..0000000
--- a/src/ClientServer/Models/Exercises/Asset.cs
+++ /dev/null
@@ -1,36 +0,0 @@
-using System.ComponentModel.DataAnnotations;
-using ClientServer.Db;
-using ClientServer.Helpers;
-
-namespace ClientServer.Models.Exercises
-{
-    /// <summary>
-    /// a asset (used e.g. for the <see cref="ExerciseDescription"/> to display images, ...)
-    /// </summary>
-    public class Asset
-    {
-        public int Id { get; set; }
-        /// <summary>
-        /// the name of the file/asset
-        /// </summary>
-        [MaxLength(YapexDbContext.DefaultMaxStringLength)]
-        public string DisplayName { get; set; }
-        /// <summary>
-        /// the asset url for assets (starts with <see cref="Constants.MarkdownAssetFileUrlPrefix"/>)
-        /// this will be translatet in the browser,
-        /// we use html5 file api for that
-        /// 
-        /// </summary>
-        [MaxLength(YapexDbContext.DefaultMaxStringLength)]
-        public string AssetUrl { get; set; }
-        /// <summary>
-        /// the content of the asset (binary)
-        /// </summary>
-        public byte[] Content { get; set; }
-        /// <summary>
-        /// the mime type (maybe we need to know what content is stored)
-        /// </summary>
-        [MaxLength(YapexDbContext.DefaultMaxStringLength)]
-        public string MimeType { get; set; }
-    }
-}
diff --git a/src/ClientServer/Models/Exercises/ExerciseDescription.cs b/src/ClientServer/Models/Exercises/ExerciseDescription.cs
index c5d07bc..0143337 100644
--- a/src/ClientServer/Models/Exercises/ExerciseDescription.cs
+++ b/src/ClientServer/Models/Exercises/ExerciseDescription.cs
@@ -13,7 +13,6 @@ namespace ClientServer.Models.Exercises
 
         public ExerciseDescription()
         {
-            Assets = new List<Asset>();
             AssetReferences = new List<ExerciseDescriptionWithFileAsAssetReference>();
         }
 
@@ -24,11 +23,6 @@ namespace ClientServer.Models.Exercises
         [MaxLength(YapexDbContext.DescriptionContentMaxStringLength)]
         public string Content { get; set; }
 
-
-        /// <summary>
-        /// the assets for the description e.g. images
-        /// </summary>
-        public List<Asset> Assets { get; set; }
         
         /// <summary>
         /// the assets for the description e.g. images
diff --git a/src/ClientServer/Models/Exercises/Tests/CustomTest.cs b/src/ClientServer/Models/Exercises/Tests/CustomTest.cs
index 5053b15..8b09a2c 100644
--- a/src/ClientServer/Models/Exercises/Tests/CustomTest.cs
+++ b/src/ClientServer/Models/Exercises/Tests/CustomTest.cs
@@ -19,7 +19,6 @@ namespace ClientServer.Models.Exercises.Tests
     {
         public CustomTest()
         {
-            TestAssets = new List<CustomTestAsset>();
             TestResultsNew = new List<CustomTestWithSingleSolutionAsTestResult>();
             AssetReferences = new  List<CustomTestWithFileAsAssetReference>();
         }
@@ -42,11 +41,6 @@ namespace ClientServer.Models.Exercises.Tests
         /// </summary>
         public int DisplayIndex { get; set; }
 
-        /// <summary>
-        /// all related assets for this test> e.g. a file to read
-        /// </summary>
-        public List<CustomTestAsset> TestAssets { get; set; }
-
         /// <summary>
         /// all related assets for this test> e.g. a file to read
         /// </summary>
@@ -60,7 +54,6 @@ namespace ClientServer.Models.Exercises.Tests
         public TestType TestType { get; set; }
 
 
-
         //ForeignKey key
 
         //composite foreign key
diff --git a/src/ClientServer/Models/Exercises/Tests/CustomTestAsset.cs b/src/ClientServer/Models/Exercises/Tests/CustomTestAsset.cs
deleted file mode 100644
index 19e085e..0000000
--- a/src/ClientServer/Models/Exercises/Tests/CustomTestAsset.cs
+++ /dev/null
@@ -1,39 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.ComponentModel.DataAnnotations;
-using System.Linq;
-using System.Threading.Tasks;
-using ClientServer.Db;
-using ClientServer.Models.Interfaces;
-
-namespace ClientServer.Models.Exercises.Tests
-{
-    /// <summary>
-    /// an asset (file) for a test
-    /// </summary>
-    public class CustomTestAsset : ITestAsset
-    {
-        public int Id { get; set; }
-        /// <summary>
-        /// the name of the file/asset
-        /// </summary>
-        [MaxLength(YapexDbContext.DefaultMaxStringLength)]
-        public string DisplayName { get; set; }
-        /// <summary>
-        /// the content of the asset (binary)
-        /// </summary>
-        public byte[] Content { get; set; }
-        /// <summary>
-        /// the mime type (maybe we need to know what content is stored)
-        /// </summary>
-        [MaxLength(YapexDbContext.DefaultMaxStringLength)]
-        public string MimeType { get; set; }
-        
-        /// <summary>
-        /// the hash of the content
-        /// can be null if not calculated but should not be null
-        /// </summary>
-        [MaxLength(YapexDbContext.DefaultMaxStringLength)]
-        public string Hash { get; set; }
-    }
-}
diff --git a/src/ClientServer/Models/Exercises/Tests/Test.cs b/src/ClientServer/Models/Exercises/Tests/Test.cs
index 8594cdb..63a9e9a 100644
--- a/src/ClientServer/Models/Exercises/Tests/Test.cs
+++ b/src/ClientServer/Models/Exercises/Tests/Test.cs
@@ -14,7 +14,6 @@ namespace ClientServer.Models.Exercises.Tests
 
         public Test()
         {
-            TestAssets = new List<TestAsset>();
             AssetReferences = new List<TestWithFileAsAssetReference>();
             TestResultsNew = new List<TestWithSingleSolutionAsTestResult>();
             AfterTestResults = new List<TestWithAfterSolutionAsTestResult>();
@@ -49,11 +48,6 @@ namespace ClientServer.Models.Exercises.Tests
 
 
         //foreign
-
-        /// <summary>
-        /// all related assets for this test e.g. a file to read
-        /// </summary>
-        public List<TestAsset> TestAssets { get; set; }
         
         /// <summary>
         /// all related assets for this test e.g. a file to read
diff --git a/src/ClientServer/Models/Exercises/Tests/TestAsset.cs b/src/ClientServer/Models/Exercises/Tests/TestAsset.cs
deleted file mode 100644
index bdf696a..0000000
--- a/src/ClientServer/Models/Exercises/Tests/TestAsset.cs
+++ /dev/null
@@ -1,35 +0,0 @@
-using System.ComponentModel.DataAnnotations;
-using ClientServer.Db;
-using ClientServer.Models.Interfaces;
-
-namespace ClientServer.Models.Exercises.Tests
-{
-    /// <summary>
-    /// an asset/file for the <see cref="Test"/>
-    /// </summary>
-    public class TestAsset : ITestAsset
-    {
-        public int Id { get; set; }
-        /// <summary>
-        /// the name of the file/asset
-        /// </summary>
-        [MaxLength(YapexDbContext.DefaultMaxStringLength)]
-        public string DisplayName { get; set; }
-        /// <summary>
-        /// the content of the asset (binary)
-        /// </summary>
-        public byte[] Content { get; set; }
-        /// <summary>
-        /// the mime type (maybe we need to know what content is stored)
-        /// </summary>
-        [MaxLength(YapexDbContext.DefaultMaxStringLength)]
-        public string MimeType { get; set; }
-        
-        /// <summary>
-        /// the hash of the content
-        /// can be null if not calculated but should not be null
-        /// </summary>
-        [MaxLength(YapexDbContext.DefaultMaxStringLength)]
-        public string Hash { get; set; }
-    }
-}
diff --git a/src/ClientServer/Models/Interfaces/IDescription.cs b/src/ClientServer/Models/Interfaces/IDescription.cs
index 74cc731..f9cbba7 100644
--- a/src/ClientServer/Models/Interfaces/IDescription.cs
+++ b/src/ClientServer/Models/Interfaces/IDescription.cs
@@ -15,9 +15,5 @@ namespace ClientServer.Models.Interfaces
         /// </summary>
         string Content { get; set; }
 
-        /// <summary>
-        /// the list of assets
-        /// </summary>
-        List<Asset> Assets { get; set; }
     }
 }
diff --git a/src/ClientServer/Workers/SubmissionAssessmentWorker.cs b/src/ClientServer/Workers/SubmissionAssessmentWorker.cs
index 455b9ca..923e035 100644
--- a/src/ClientServer/Workers/SubmissionAssessmentWorker.cs
+++ b/src/ClientServer/Workers/SubmissionAssessmentWorker.cs
@@ -364,7 +364,6 @@ namespace ClientServer.Schedulers
             {
                 normalTests =
                     context.Tests
-                        .Include(p => p.TestAssets)
                         .Include(p => p.TestSettings)
                         .Include(p => p.TestType)
                         .Where(p => p.ExerciseId == release.ExerciseId && p.IsSubmitTest == false)
@@ -374,7 +373,6 @@ namespace ClientServer.Schedulers
 
             var submitTests =
                 context.Tests
-                    .Include(p => p.TestAssets)
                     .Include(p => p.TestSettings)
                     .Include(p => p.TestType)
                     .Where(p => p.ExerciseId == release.ExerciseId && p.IsSubmitTest == true)
@@ -944,7 +942,7 @@ namespace ClientServer.Schedulers
                 }
                 catch (Exception e)
                 {
-                    Console.WriteLine(e);
+                    Console.WriteLine("[ERROR]: " + e);
                     return false;
                 }
                 
-- 
GitLab