Huge work
This commit is contained in:
@@ -14,4 +14,8 @@
|
|||||||
<PackageReference Include="Pomelo.EntityFrameworkCore.MySql" Version="5.0.1" />
|
<PackageReference Include="Pomelo.EntityFrameworkCore.MySql" Version="5.0.1" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<Folder Include="Migrations\" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
@@ -9,7 +9,7 @@ using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
|||||||
namespace KTUSAPS.Data.Migrations
|
namespace KTUSAPS.Data.Migrations
|
||||||
{
|
{
|
||||||
[DbContext(typeof(SAPSDataContext))]
|
[DbContext(typeof(SAPSDataContext))]
|
||||||
[Migration("20210909173149_Initial")]
|
[Migration("20211015122630_Initial")]
|
||||||
partial class Initial
|
partial class Initial
|
||||||
{
|
{
|
||||||
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
||||||
@@ -50,6 +50,9 @@ namespace KTUSAPS.Data.Migrations
|
|||||||
.HasMaxLength(320)
|
.HasMaxLength(320)
|
||||||
.HasColumnType("varchar(320)");
|
.HasColumnType("varchar(320)");
|
||||||
|
|
||||||
|
b.Property<int>("IssueTypeId")
|
||||||
|
.HasColumnType("int");
|
||||||
|
|
||||||
b.Property<bool>("Publishable")
|
b.Property<bool>("Publishable")
|
||||||
.HasColumnType("tinyint(1)");
|
.HasColumnType("tinyint(1)");
|
||||||
|
|
||||||
@@ -62,9 +65,28 @@ namespace KTUSAPS.Data.Migrations
|
|||||||
|
|
||||||
b.HasKey("Id");
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("IssueTypeId");
|
||||||
|
|
||||||
b.ToTable("Issues");
|
b.ToTable("Issues");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("KTUSAPS.Data.Model.IssueType", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("int");
|
||||||
|
|
||||||
|
b.Property<string>("Name")
|
||||||
|
.HasColumnType("longtext");
|
||||||
|
|
||||||
|
b.Property<string>("NameEn")
|
||||||
|
.HasColumnType("longtext");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.ToTable("IssueTypes");
|
||||||
|
});
|
||||||
|
|
||||||
modelBuilder.Entity("KTUSAPS.Data.Model.PublishedFeedback", b =>
|
modelBuilder.Entity("KTUSAPS.Data.Model.PublishedFeedback", b =>
|
||||||
{
|
{
|
||||||
b.Property<int>("Id")
|
b.Property<int>("Id")
|
||||||
@@ -169,6 +191,17 @@ namespace KTUSAPS.Data.Migrations
|
|||||||
b.ToTable("Votes");
|
b.ToTable("Votes");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("KTUSAPS.Data.Model.Issue", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("KTUSAPS.Data.Model.IssueType", "IssueType")
|
||||||
|
.WithMany("Issues")
|
||||||
|
.HasForeignKey("IssueTypeId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.Navigation("IssueType");
|
||||||
|
});
|
||||||
|
|
||||||
modelBuilder.Entity("KTUSAPS.Data.Model.PublishedFeedback", b =>
|
modelBuilder.Entity("KTUSAPS.Data.Model.PublishedFeedback", b =>
|
||||||
{
|
{
|
||||||
b.HasOne("KTUSAPS.Data.Model.Issue", "Issue")
|
b.HasOne("KTUSAPS.Data.Model.Issue", "Issue")
|
||||||
@@ -211,6 +244,11 @@ namespace KTUSAPS.Data.Migrations
|
|||||||
b.Navigation("Problem");
|
b.Navigation("Problem");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("KTUSAPS.Data.Model.IssueType", b =>
|
||||||
|
{
|
||||||
|
b.Navigation("Issues");
|
||||||
|
});
|
||||||
|
|
||||||
modelBuilder.Entity("KTUSAPS.Data.Model.PublishedProblem", b =>
|
modelBuilder.Entity("KTUSAPS.Data.Model.PublishedProblem", b =>
|
||||||
{
|
{
|
||||||
b.Navigation("Votes");
|
b.Navigation("Votes");
|
@@ -27,24 +27,19 @@ namespace KTUSAPS.Data.Migrations
|
|||||||
.Annotation("MySql:CharSet", "utf8mb4");
|
.Annotation("MySql:CharSet", "utf8mb4");
|
||||||
|
|
||||||
migrationBuilder.CreateTable(
|
migrationBuilder.CreateTable(
|
||||||
name: "Issues",
|
name: "IssueTypes",
|
||||||
columns: table => new
|
columns: table => new
|
||||||
{
|
{
|
||||||
Id = table.Column<int>(type: "int", nullable: false)
|
Id = table.Column<int>(type: "int", nullable: false)
|
||||||
.Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn),
|
.Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn),
|
||||||
UserID = table.Column<string>(type: "varchar(64)", maxLength: 64, nullable: true)
|
Name = table.Column<string>(type: "longtext", nullable: true)
|
||||||
.Annotation("MySql:CharSet", "utf8mb4"),
|
.Annotation("MySql:CharSet", "utf8mb4"),
|
||||||
Email = table.Column<string>(type: "varchar(320)", maxLength: 320, nullable: true)
|
NameEn = table.Column<string>(type: "longtext", nullable: true)
|
||||||
.Annotation("MySql:CharSet", "utf8mb4"),
|
|
||||||
Publishable = table.Column<bool>(type: "tinyint(1)", nullable: false),
|
|
||||||
Solved = table.Column<bool>(type: "tinyint(1)", nullable: false),
|
|
||||||
Created = table.Column<DateTime>(type: "datetime(6)", nullable: false),
|
|
||||||
Description = table.Column<string>(type: "longtext", nullable: true)
|
|
||||||
.Annotation("MySql:CharSet", "utf8mb4")
|
.Annotation("MySql:CharSet", "utf8mb4")
|
||||||
},
|
},
|
||||||
constraints: table =>
|
constraints: table =>
|
||||||
{
|
{
|
||||||
table.PrimaryKey("PK_Issues", x => x.Id);
|
table.PrimaryKey("PK_IssueTypes", x => x.Id);
|
||||||
})
|
})
|
||||||
.Annotation("MySql:CharSet", "utf8mb4");
|
.Annotation("MySql:CharSet", "utf8mb4");
|
||||||
|
|
||||||
@@ -66,6 +61,35 @@ namespace KTUSAPS.Data.Migrations
|
|||||||
})
|
})
|
||||||
.Annotation("MySql:CharSet", "utf8mb4");
|
.Annotation("MySql:CharSet", "utf8mb4");
|
||||||
|
|
||||||
|
migrationBuilder.CreateTable(
|
||||||
|
name: "Issues",
|
||||||
|
columns: table => new
|
||||||
|
{
|
||||||
|
Id = table.Column<int>(type: "int", nullable: false)
|
||||||
|
.Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn),
|
||||||
|
UserID = table.Column<string>(type: "varchar(64)", maxLength: 64, nullable: true)
|
||||||
|
.Annotation("MySql:CharSet", "utf8mb4"),
|
||||||
|
Email = table.Column<string>(type: "varchar(320)", maxLength: 320, nullable: true)
|
||||||
|
.Annotation("MySql:CharSet", "utf8mb4"),
|
||||||
|
Publishable = table.Column<bool>(type: "tinyint(1)", nullable: false),
|
||||||
|
Solved = table.Column<bool>(type: "tinyint(1)", nullable: false),
|
||||||
|
Created = table.Column<DateTime>(type: "datetime(6)", nullable: false),
|
||||||
|
Description = table.Column<string>(type: "longtext", nullable: true)
|
||||||
|
.Annotation("MySql:CharSet", "utf8mb4"),
|
||||||
|
IssueTypeId = table.Column<int>(type: "int", nullable: false)
|
||||||
|
},
|
||||||
|
constraints: table =>
|
||||||
|
{
|
||||||
|
table.PrimaryKey("PK_Issues", x => x.Id);
|
||||||
|
table.ForeignKey(
|
||||||
|
name: "FK_Issues_IssueTypes_IssueTypeId",
|
||||||
|
column: x => x.IssueTypeId,
|
||||||
|
principalTable: "IssueTypes",
|
||||||
|
principalColumn: "Id",
|
||||||
|
onDelete: ReferentialAction.Cascade);
|
||||||
|
})
|
||||||
|
.Annotation("MySql:CharSet", "utf8mb4");
|
||||||
|
|
||||||
migrationBuilder.CreateTable(
|
migrationBuilder.CreateTable(
|
||||||
name: "PublishedFeedbacks",
|
name: "PublishedFeedbacks",
|
||||||
columns: table => new
|
columns: table => new
|
||||||
@@ -147,6 +171,11 @@ namespace KTUSAPS.Data.Migrations
|
|||||||
})
|
})
|
||||||
.Annotation("MySql:CharSet", "utf8mb4");
|
.Annotation("MySql:CharSet", "utf8mb4");
|
||||||
|
|
||||||
|
migrationBuilder.CreateIndex(
|
||||||
|
name: "IX_Issues_IssueTypeId",
|
||||||
|
table: "Issues",
|
||||||
|
column: "IssueTypeId");
|
||||||
|
|
||||||
migrationBuilder.CreateIndex(
|
migrationBuilder.CreateIndex(
|
||||||
name: "IX_PublishedFeedbacks_IssueId",
|
name: "IX_PublishedFeedbacks_IssueId",
|
||||||
table: "PublishedFeedbacks",
|
table: "PublishedFeedbacks",
|
||||||
@@ -190,6 +219,9 @@ namespace KTUSAPS.Data.Migrations
|
|||||||
|
|
||||||
migrationBuilder.DropTable(
|
migrationBuilder.DropTable(
|
||||||
name: "Solutions");
|
name: "Solutions");
|
||||||
|
|
||||||
|
migrationBuilder.DropTable(
|
||||||
|
name: "IssueTypes");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@@ -48,6 +48,9 @@ namespace KTUSAPS.Data.Migrations
|
|||||||
.HasMaxLength(320)
|
.HasMaxLength(320)
|
||||||
.HasColumnType("varchar(320)");
|
.HasColumnType("varchar(320)");
|
||||||
|
|
||||||
|
b.Property<int>("IssueTypeId")
|
||||||
|
.HasColumnType("int");
|
||||||
|
|
||||||
b.Property<bool>("Publishable")
|
b.Property<bool>("Publishable")
|
||||||
.HasColumnType("tinyint(1)");
|
.HasColumnType("tinyint(1)");
|
||||||
|
|
||||||
@@ -60,9 +63,28 @@ namespace KTUSAPS.Data.Migrations
|
|||||||
|
|
||||||
b.HasKey("Id");
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("IssueTypeId");
|
||||||
|
|
||||||
b.ToTable("Issues");
|
b.ToTable("Issues");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("KTUSAPS.Data.Model.IssueType", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("int");
|
||||||
|
|
||||||
|
b.Property<string>("Name")
|
||||||
|
.HasColumnType("longtext");
|
||||||
|
|
||||||
|
b.Property<string>("NameEn")
|
||||||
|
.HasColumnType("longtext");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.ToTable("IssueTypes");
|
||||||
|
});
|
||||||
|
|
||||||
modelBuilder.Entity("KTUSAPS.Data.Model.PublishedFeedback", b =>
|
modelBuilder.Entity("KTUSAPS.Data.Model.PublishedFeedback", b =>
|
||||||
{
|
{
|
||||||
b.Property<int>("Id")
|
b.Property<int>("Id")
|
||||||
@@ -167,6 +189,17 @@ namespace KTUSAPS.Data.Migrations
|
|||||||
b.ToTable("Votes");
|
b.ToTable("Votes");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("KTUSAPS.Data.Model.Issue", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("KTUSAPS.Data.Model.IssueType", "IssueType")
|
||||||
|
.WithMany("Issues")
|
||||||
|
.HasForeignKey("IssueTypeId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.Navigation("IssueType");
|
||||||
|
});
|
||||||
|
|
||||||
modelBuilder.Entity("KTUSAPS.Data.Model.PublishedFeedback", b =>
|
modelBuilder.Entity("KTUSAPS.Data.Model.PublishedFeedback", b =>
|
||||||
{
|
{
|
||||||
b.HasOne("KTUSAPS.Data.Model.Issue", "Issue")
|
b.HasOne("KTUSAPS.Data.Model.Issue", "Issue")
|
||||||
@@ -209,6 +242,11 @@ namespace KTUSAPS.Data.Migrations
|
|||||||
b.Navigation("Problem");
|
b.Navigation("Problem");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("KTUSAPS.Data.Model.IssueType", b =>
|
||||||
|
{
|
||||||
|
b.Navigation("Issues");
|
||||||
|
});
|
||||||
|
|
||||||
modelBuilder.Entity("KTUSAPS.Data.Model.PublishedProblem", b =>
|
modelBuilder.Entity("KTUSAPS.Data.Model.PublishedProblem", b =>
|
||||||
{
|
{
|
||||||
b.Navigation("Votes");
|
b.Navigation("Votes");
|
||||||
|
@@ -22,7 +22,15 @@ namespace KTUSAPS.Data.Model
|
|||||||
[MaxLength]
|
[MaxLength]
|
||||||
public string Description { get; set; }
|
public string Description { get; set; }
|
||||||
|
|
||||||
public PublishedProblem Problem { get; set; }
|
public int IssueTypeId { get; set; }
|
||||||
public PublishedFeedback Feedback { get; set; }
|
public virtual IssueType IssueType { get; set; }
|
||||||
|
|
||||||
|
public virtual PublishedProblem Problem { get; set; }
|
||||||
|
public virtual PublishedFeedback Feedback { get; set; }
|
||||||
|
|
||||||
|
public Issue()
|
||||||
|
{
|
||||||
|
Created = DateTime.Now;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
18
KTUSAPS.Data/Model/IssueType.cs
Normal file
18
KTUSAPS.Data/Model/IssueType.cs
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace KTUSAPS.Data.Model
|
||||||
|
{
|
||||||
|
public class IssueType
|
||||||
|
{
|
||||||
|
public int Id { get; set; }
|
||||||
|
public string Name { get; set; }
|
||||||
|
public string NameEn { get; set; }
|
||||||
|
|
||||||
|
public virtual ICollection<Issue> Issues { get; set; }
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@@ -1,18 +1,19 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<ClassDiagram MajorVersion="1" MinorVersion="1">
|
<ClassDiagram MajorVersion="1" MinorVersion="1">
|
||||||
<Class Name="KTUSAPS.Data.Model.Issue">
|
<Class Name="KTUSAPS.Data.Model.Issue">
|
||||||
<Position X="0.5" Y="0.75" Width="1.5" />
|
<Position X="10.25" Y="1" Width="1.5" />
|
||||||
<TypeIdentifier>
|
<TypeIdentifier>
|
||||||
<HashCode>AAACAAJAACAgAAAAAAACAAgIAAAAAAQAAAAAAAAAAAA=</HashCode>
|
<HashCode>AIACAAJQACAgAAAAAAACAAgIAAAAAAQAAAAAAAAAAAA=</HashCode>
|
||||||
<FileName>Model\Issue.cs</FileName>
|
<FileName>Model\Issue.cs</FileName>
|
||||||
</TypeIdentifier>
|
</TypeIdentifier>
|
||||||
<ShowAsAssociation>
|
<ShowAsAssociation>
|
||||||
<Property Name="Problem" />
|
<Property Name="Problem" />
|
||||||
<Property Name="Feedback" />
|
<Property Name="Feedback" />
|
||||||
|
<Property Name="IssueType" />
|
||||||
</ShowAsAssociation>
|
</ShowAsAssociation>
|
||||||
</Class>
|
</Class>
|
||||||
<Class Name="KTUSAPS.Data.Model.PublishedFeedback">
|
<Class Name="KTUSAPS.Data.Model.PublishedFeedback">
|
||||||
<Position X="2.75" Y="3.75" Width="1.5" />
|
<Position X="6.5" Y="3" Width="1.5" />
|
||||||
<TypeIdentifier>
|
<TypeIdentifier>
|
||||||
<HashCode>AAECAAAAAAAAAAAACAIAAAAAAAAAAAQAEAAAAAAAAAA=</HashCode>
|
<HashCode>AAECAAAAAAAAAAAACAIAAAAAAAAAAAQAEAAAAAAAAAA=</HashCode>
|
||||||
<FileName>Model\PublishedFeedback.cs</FileName>
|
<FileName>Model\PublishedFeedback.cs</FileName>
|
||||||
@@ -22,9 +23,9 @@
|
|||||||
</ShowAsAssociation>
|
</ShowAsAssociation>
|
||||||
</Class>
|
</Class>
|
||||||
<Class Name="KTUSAPS.Data.Model.PublishedProblem">
|
<Class Name="KTUSAPS.Data.Model.PublishedProblem">
|
||||||
<Position X="2.75" Y="0.75" Width="1.5" />
|
<Position X="4" Y="0.5" Width="1.5" />
|
||||||
<TypeIdentifier>
|
<TypeIdentifier>
|
||||||
<HashCode>ACECABAAAAEAAAgAAAABAAAAEAAAQAQAEAAAAAAAAAA=</HashCode>
|
<HashCode>ACECABAAAAEAAAgAAAABAAAAAAAAAAQAEAAAAAAAAAA=</HashCode>
|
||||||
<FileName>Model\PublishedProblem.cs</FileName>
|
<FileName>Model\PublishedProblem.cs</FileName>
|
||||||
</TypeIdentifier>
|
</TypeIdentifier>
|
||||||
<ShowAsAssociation>
|
<ShowAsAssociation>
|
||||||
@@ -36,7 +37,7 @@
|
|||||||
</ShowAsCollectionAssociation>
|
</ShowAsCollectionAssociation>
|
||||||
</Class>
|
</Class>
|
||||||
<Class Name="KTUSAPS.Data.Model.Solution">
|
<Class Name="KTUSAPS.Data.Model.Solution">
|
||||||
<Position X="6" Y="0.5" Width="1.5" />
|
<Position X="0.75" Y="0.75" Width="1.5" />
|
||||||
<TypeIdentifier>
|
<TypeIdentifier>
|
||||||
<HashCode>AAACAAIABAAAAQAAAAAAAAAAAAAAAAQAAAAAAAAAAAA=</HashCode>
|
<HashCode>AAACAAIABAAAAQAAAAAAAAAAAAAAAAQAAAAAAAAAAAA=</HashCode>
|
||||||
<FileName>Model\Solution.cs</FileName>
|
<FileName>Model\Solution.cs</FileName>
|
||||||
@@ -46,7 +47,7 @@
|
|||||||
</ShowAsAssociation>
|
</ShowAsAssociation>
|
||||||
</Class>
|
</Class>
|
||||||
<Class Name="KTUSAPS.Data.Model.Vote">
|
<Class Name="KTUSAPS.Data.Model.Vote">
|
||||||
<Position X="6" Y="2.5" Width="1.5" />
|
<Position X="3.5" Y="4.5" Width="1.5" />
|
||||||
<TypeIdentifier>
|
<TypeIdentifier>
|
||||||
<HashCode>AAAAAAIAAAAAEAAAAAAAAAgAAAAAAAAAAAAAAAAAAAA=</HashCode>
|
<HashCode>AAAAAAIAAAAAEAAAAAAAAAgAAAAAAAAAAAAAAAAAAAA=</HashCode>
|
||||||
<FileName>Model\Vote.cs</FileName>
|
<FileName>Model\Vote.cs</FileName>
|
||||||
@@ -55,5 +56,15 @@
|
|||||||
<Property Name="Problem" />
|
<Property Name="Problem" />
|
||||||
</ShowAsAssociation>
|
</ShowAsAssociation>
|
||||||
</Class>
|
</Class>
|
||||||
|
<Class Name="KTUSAPS.Data.Model.IssueType">
|
||||||
|
<Position X="12.25" Y="5.25" Width="1.5" />
|
||||||
|
<TypeIdentifier>
|
||||||
|
<HashCode>AAECAAAAAAAAAAAAACAAAAQAAAAAAAAAAAAAAAAAAAA=</HashCode>
|
||||||
|
<FileName>Model\IssueType.cs</FileName>
|
||||||
|
</TypeIdentifier>
|
||||||
|
<ShowAsCollectionAssociation>
|
||||||
|
<Property Name="Issues" />
|
||||||
|
</ShowAsCollectionAssociation>
|
||||||
|
</Class>
|
||||||
<Font Name="Segoe UI" Size="9" />
|
<Font Name="Segoe UI" Size="9" />
|
||||||
</ClassDiagram>
|
</ClassDiagram>
|
@@ -22,6 +22,11 @@ namespace KTUSAPS.Data.Model
|
|||||||
public DateTime Created { get; set; }
|
public DateTime Created { get; set; }
|
||||||
|
|
||||||
public int? IssueId { get; set; }
|
public int? IssueId { get; set; }
|
||||||
public Issue Issue { get; set; }
|
public virtual Issue Issue { get; set; }
|
||||||
|
|
||||||
|
public PublishedFeedback()
|
||||||
|
{
|
||||||
|
Created = DateTime.Now;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -18,20 +18,19 @@ namespace KTUSAPS.Data.Model
|
|||||||
[Required]
|
[Required]
|
||||||
[MaxLength]
|
[MaxLength]
|
||||||
public string ProblemEn { get; set; }
|
public string ProblemEn { get; set; }
|
||||||
[MaxLength]
|
|
||||||
public string ResponseLt { get; set; }
|
|
||||||
[MaxLength]
|
|
||||||
public string ResponseEn { get; set; }
|
|
||||||
|
|
||||||
public DateTime Created { get; set; }
|
public DateTime Created { get; set; }
|
||||||
|
|
||||||
public int? IssueId { get; set; }
|
public int? IssueId { get; set; }
|
||||||
public Issue Issue { get; set; }
|
public virtual Issue Issue { get; set; }
|
||||||
|
|
||||||
public int? SolutionId { get; set; }
|
public int? SolutionId { get; set; }
|
||||||
public Solution Solution { get; set; }
|
public virtual Solution Solution { get; set; }
|
||||||
public ICollection<Vote> Votes { get; set; }
|
public ICollection<Vote> Votes { get; set; }
|
||||||
|
|
||||||
|
public PublishedProblem()
|
||||||
|
{
|
||||||
|
Created = DateTime.Now;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -14,7 +14,12 @@ namespace KTUSAPS.Data.Model
|
|||||||
public string SolutionEn { get; set; }
|
public string SolutionEn { get; set; }
|
||||||
|
|
||||||
|
|
||||||
public PublishedProblem Problem { get; set; }
|
public virtual PublishedProblem Problem { get; set; }
|
||||||
public DateTime Created { get; set; }
|
public DateTime Created { get; set; }
|
||||||
|
|
||||||
|
public Solution()
|
||||||
|
{
|
||||||
|
Created = DateTime.Now;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@@ -12,7 +12,7 @@ namespace KTUSAPS.Data.Model
|
|||||||
[MaxLength(64)]
|
[MaxLength(64)]
|
||||||
public string UserId { get; set; }
|
public string UserId { get; set; }
|
||||||
public int ProblemId { get; set; }
|
public int ProblemId { get; set; }
|
||||||
public PublishedProblem Problem { get; set; }
|
public virtual PublishedProblem Problem { get; set; }
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -26,6 +26,7 @@ namespace KTUSAPS.Data
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public DbSet<IssueType> IssueTypes { get; set; }
|
||||||
public DbSet<Issue> Issues { get; set; }
|
public DbSet<Issue> Issues { get; set; }
|
||||||
public DbSet<PublishedFeedback> PublishedFeedbacks { get; set; }
|
public DbSet<PublishedFeedback> PublishedFeedbacks { get; set; }
|
||||||
public DbSet<PublishedProblem> PublishedProblems { get; set; }
|
public DbSet<PublishedProblem> PublishedProblems { get; set; }
|
||||||
|
@@ -19,6 +19,15 @@
|
|||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div v-if="$store.getters['auth/isExpiringSoon']" class="container">
|
||||||
|
<div class="alert alert-warning">
|
||||||
|
<h4 class="alert-heading">Greitai baisis jūsų sesija</h4>
|
||||||
|
<span>
|
||||||
|
Po {{ expiresIn }} baigsis jūsų sesija.
|
||||||
|
<a :href="$store.getters['auth/loginUrl']">Pratęsti sesija.</a>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<router-view />
|
<router-view />
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@@ -30,6 +39,12 @@ export default {
|
|||||||
components: {
|
components: {
|
||||||
NavMenu,
|
NavMenu,
|
||||||
},
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
expiresIn: '',
|
||||||
|
interval: null,
|
||||||
|
}
|
||||||
|
},
|
||||||
created() {
|
created() {
|
||||||
this.$store.dispatch('auth/initialize')
|
this.$store.dispatch('auth/initialize')
|
||||||
},
|
},
|
||||||
@@ -43,6 +58,26 @@ export default {
|
|||||||
return location.protocol !== 'https:'
|
return location.protocol !== 'https:'
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
methods: {
|
||||||
|
updateExpiry() {
|
||||||
|
const totalSeconds = Math.floor(
|
||||||
|
(this.$store.getters['auth/expires'] - new Date()) / 1000
|
||||||
|
)
|
||||||
|
const seconds = totalSeconds % 60
|
||||||
|
const minutes = Math.floor(totalSeconds / 60)
|
||||||
|
if (minutes) {
|
||||||
|
this.expiresIn = `${minutes} min. ir ${seconds} sek.`
|
||||||
|
} else {
|
||||||
|
this.expiresIn = `${seconds} sek.`
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
this.interval = setInterval(this.updateExpiry, 1000)
|
||||||
|
},
|
||||||
|
beforeUnmount() {
|
||||||
|
clearInterval(this.interval)
|
||||||
|
},
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
@@ -27,6 +27,9 @@
|
|||||||
>Pagrindinis</router-link
|
>Pagrindinis</router-link
|
||||||
>
|
>
|
||||||
</li>
|
</li>
|
||||||
|
<li class="nav-item">
|
||||||
|
<a href="/swagger" class="nav-link">Swagger UI</a>
|
||||||
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
<div class="navbar-nav">
|
<div class="navbar-nav">
|
||||||
<span v-if="$store.getters['auth/isValid']" class="navbar-text"
|
<span v-if="$store.getters['auth/isValid']" class="navbar-text"
|
||||||
|
@@ -29,7 +29,7 @@
|
|||||||
</table>
|
</table>
|
||||||
<h3>Techninė duomenų reprezentacija</h3>
|
<h3>Techninė duomenų reprezentacija</h3>
|
||||||
<a
|
<a
|
||||||
href="https://docs.microsoft.com/en-us/azure/active-directory/develop/access-tokens"
|
href="https://docs.microsoft.com/en-us/azure/active-directory/develop/id-tokens"
|
||||||
>Dokumentacija apie laukų reikšmes</a
|
>Dokumentacija apie laukų reikšmes</a
|
||||||
>
|
>
|
||||||
<pre>{{ $store.state.auth.tokenData }}</pre>
|
<pre>{{ $store.state.auth.tokenData }}</pre>
|
||||||
@@ -92,7 +92,7 @@ export default {
|
|||||||
serverVerify() {
|
serverVerify() {
|
||||||
this.verificationResult = null
|
this.verificationResult = null
|
||||||
axios
|
axios
|
||||||
.get('/test/authed', {
|
.get('/api/AuthMetadata/authed', {
|
||||||
headers: { Authorization: `Bearer ${this.$store.state.auth.token}` },
|
headers: { Authorization: `Bearer ${this.$store.state.auth.token}` },
|
||||||
})
|
})
|
||||||
.then(response => {
|
.then(response => {
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
import { createStore, createLogger } from "vuex";
|
import { createStore, createLogger } from 'vuex'
|
||||||
import auth from "./modules/auth";
|
import auth from './modules/auth'
|
||||||
|
|
||||||
const debug = process.env.NODE_ENV !== "production";
|
const debug = process.env.NODE_ENV !== 'production'
|
||||||
|
|
||||||
export default createStore({
|
export default createStore({
|
||||||
modules: {
|
modules: {
|
||||||
@@ -9,4 +9,4 @@ export default createStore({
|
|||||||
},
|
},
|
||||||
strict: debug,
|
strict: debug,
|
||||||
plugins: debug ? [createLogger()] : [],
|
plugins: debug ? [createLogger()] : [],
|
||||||
});
|
})
|
||||||
|
@@ -52,7 +52,15 @@ const getters = {
|
|||||||
},
|
},
|
||||||
userId(state, getters) {
|
userId(state, getters) {
|
||||||
if (!getters.isValid) return null
|
if (!getters.isValid) return null
|
||||||
return state.tokenData.email
|
return state.tokenData.sub
|
||||||
|
},
|
||||||
|
isExpiringSoon(state, getters) {
|
||||||
|
if (!getters.isValid) return false
|
||||||
|
return true
|
||||||
|
},
|
||||||
|
expires(state, getters) {
|
||||||
|
if (!getters.isValid) return 0
|
||||||
|
return new Date(state.tokenData.exp * 1000)
|
||||||
},
|
},
|
||||||
loginUrl(state, getters) {
|
loginUrl(state, getters) {
|
||||||
if (!getters.isReady) return null
|
if (!getters.isReady) return null
|
||||||
|
@@ -1,4 +1,5 @@
|
|||||||
using Microsoft.AspNetCore.Http;
|
using Microsoft.AspNetCore.Authorization;
|
||||||
|
using Microsoft.AspNetCore.Http;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
using Microsoft.Extensions.Configuration;
|
using Microsoft.Extensions.Configuration;
|
||||||
using System;
|
using System;
|
||||||
@@ -10,15 +11,39 @@ namespace KTUSAPS.Controllers
|
|||||||
{
|
{
|
||||||
[Route("api/[controller]")]
|
[Route("api/[controller]")]
|
||||||
[ApiController]
|
[ApiController]
|
||||||
|
[Produces("application/json")]
|
||||||
public class AuthMetadataController : ControllerBase
|
public class AuthMetadataController : ControllerBase
|
||||||
{
|
{
|
||||||
|
public class AuthMetadata
|
||||||
|
{
|
||||||
|
public string ClientId { get; set; }
|
||||||
|
public string Authority { get; set; }
|
||||||
|
public string Tenant { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
private readonly IConfiguration _configuration;
|
private readonly IConfiguration _configuration;
|
||||||
public AuthMetadataController(IConfiguration configuration)
|
public AuthMetadataController(IConfiguration configuration)
|
||||||
{
|
{
|
||||||
_configuration = configuration;
|
_configuration = configuration;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Get authethication metadata needed to obtain token.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
[HttpGet]
|
[HttpGet]
|
||||||
public object Index() => new { ClientId = _configuration["ClientId"], Authority = _configuration["Authority"], Tenant = _configuration["Tenant"] };
|
public AuthMetadata Index() => new AuthMetadata { ClientId = _configuration["ClientId"], Authority = _configuration["Authority"], Tenant = _configuration["Tenant"] };
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Returns true is provided token is valid, else throws exception
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
/// <response code="200">Provided token is correct.</response>
|
||||||
|
/// <response code="401">No valid token provided.</response>
|
||||||
|
[Authorize]
|
||||||
|
[ProducesResponseType(StatusCodes.Status401Unauthorized)]
|
||||||
|
[ProducesResponseType(StatusCodes.Status200OK)]
|
||||||
|
[HttpGet("Authed")]
|
||||||
|
public bool IsAuthed() => true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
96
KTUSAPS/Controllers/IssueController.cs
Normal file
96
KTUSAPS/Controllers/IssueController.cs
Normal file
@@ -0,0 +1,96 @@
|
|||||||
|
using KTUSAPS.Data.Model;
|
||||||
|
using KTUSAPS.Extensions;
|
||||||
|
using Microsoft.AspNetCore.Http;
|
||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace KTUSAPS.Controllers
|
||||||
|
{
|
||||||
|
[Route("api/[controller]")]
|
||||||
|
[ApiController]
|
||||||
|
public class IssueController : ControllerBase
|
||||||
|
{
|
||||||
|
private readonly Data.SAPSDataContext dataContext;
|
||||||
|
|
||||||
|
public IssueController(Data.SAPSDataContext dataContext)
|
||||||
|
{
|
||||||
|
this.dataContext = dataContext;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
[HttpGet]
|
||||||
|
[ProducesResponseType(StatusCodes.Status200OK)]
|
||||||
|
public IEnumerable<Issue> GetIssues()
|
||||||
|
{
|
||||||
|
return dataContext.Issues;
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpPost]
|
||||||
|
[ProducesResponseType(StatusCodes.Status201Created)]
|
||||||
|
[ProducesResponseType(StatusCodes.Status400BadRequest)]
|
||||||
|
public async Task<ActionResult<Issue>> CreateIssueAsync([FromBody] Issue issueToCreate)
|
||||||
|
{
|
||||||
|
if (issueToCreate == null)
|
||||||
|
return BadRequest("No data provided for object to be created.");
|
||||||
|
if (issueToCreate.Id != default)
|
||||||
|
return BadRequest("Id has been set on create request, please do not do that, set id to 0 or ommit it.");
|
||||||
|
if (issueToCreate.IssueTypeId == default)
|
||||||
|
return BadRequest("No typeId has been specified");
|
||||||
|
if (issueToCreate.Problem != null && issueToCreate.Feedback != null && issueToCreate.IssueType != null)
|
||||||
|
return BadRequest("Do not privide navigation property values.");
|
||||||
|
// TODO: Enable next line and make thoes two fields come from user identity
|
||||||
|
//if (issueToCreate.UserID != default || issueToCreate.Email != default)
|
||||||
|
// return BadRequest("Do not provide indentity values.");
|
||||||
|
|
||||||
|
var createdValue = await dataContext.AddAsync(issueToCreate);
|
||||||
|
await dataContext.SaveChangesAsync();
|
||||||
|
var url = Url.ActionLink(action: nameof(GetIssue), values: new { Id = createdValue.Entity.Id });
|
||||||
|
return Created(url, createdValue.Entity);
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpGet("{id}")]
|
||||||
|
[ProducesResponseType(StatusCodes.Status200OK)]
|
||||||
|
[ProducesResponseType(StatusCodes.Status404NotFound)]
|
||||||
|
public ActionResult<Issue> GetIssue(int id)
|
||||||
|
{
|
||||||
|
var issue = dataContext.Issues.AsQueryable().Where(i => i.Id == id).FirstOrDefault();
|
||||||
|
if(issue == default)
|
||||||
|
return NotFound();
|
||||||
|
return Ok(issue);
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpPatch("{id}")]
|
||||||
|
[ProducesResponseType(StatusCodes.Status200OK)]
|
||||||
|
[ProducesResponseType(StatusCodes.Status404NotFound)]
|
||||||
|
public async Task<ActionResult<Issue>> UpdateIssueAsync(int id, [FromBody] Issue issue)
|
||||||
|
{
|
||||||
|
var databaseIssue = dataContext.Issues.AsQueryable().Where(i => i.Id == id).FirstOrDefault();
|
||||||
|
if (databaseIssue == default)
|
||||||
|
return NotFound();
|
||||||
|
var eIssue = dataContext.Attach(databaseIssue);
|
||||||
|
eIssue.MovePropertyDataWhiteList(issue, new string[] {
|
||||||
|
nameof(databaseIssue.Description),
|
||||||
|
nameof(databaseIssue.IssueTypeId),
|
||||||
|
nameof(databaseIssue.Publishable)
|
||||||
|
});
|
||||||
|
await dataContext.SaveChangesAsync();
|
||||||
|
return Ok(eIssue.Entity);
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpDelete("{id}")]
|
||||||
|
[ProducesResponseType(StatusCodes.Status204NoContent)]
|
||||||
|
[ProducesResponseType(StatusCodes.Status404NotFound)]
|
||||||
|
public async Task<IActionResult> DeleteIssueAsync(int id)
|
||||||
|
{
|
||||||
|
var issue = dataContext.Issues.AsQueryable().Where(i => i.Id == id).FirstOrDefault();
|
||||||
|
if (issue == default)
|
||||||
|
return NotFound();
|
||||||
|
dataContext.Issues.Remove(issue);
|
||||||
|
await dataContext.SaveChangesAsync();
|
||||||
|
return NoContent();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -1,26 +0,0 @@
|
|||||||
using Microsoft.AspNetCore.Authentication.JwtBearer;
|
|
||||||
using Microsoft.AspNetCore.Authorization;
|
|
||||||
using Microsoft.AspNetCore.Http;
|
|
||||||
using Microsoft.AspNetCore.Mvc;
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace KTUSAPS.Controllers
|
|
||||||
{
|
|
||||||
[Route("[controller]")]
|
|
||||||
[Authorize]
|
|
||||||
[ApiController]
|
|
||||||
public class TestController : ControllerBase
|
|
||||||
{
|
|
||||||
[HttpGet]
|
|
||||||
public object[] Index()
|
|
||||||
{
|
|
||||||
return HttpContext.User.Claims.Select(x => new { Name = x.Type, Value= x.Value }).ToArray();
|
|
||||||
}
|
|
||||||
|
|
||||||
[HttpGet("authed")]
|
|
||||||
public bool IsAuthed() => true;
|
|
||||||
}
|
|
||||||
}
|
|
44
KTUSAPS/Extensions/EntityEntryExtensions.cs
Normal file
44
KTUSAPS/Extensions/EntityEntryExtensions.cs
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
using Microsoft.EntityFrameworkCore.ChangeTracking;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
|
||||||
|
namespace KTUSAPS.Extensions
|
||||||
|
{
|
||||||
|
public static class EntityEntryExtensions
|
||||||
|
{
|
||||||
|
public static void MovePropertyDataBlackList(this EntityEntry target, object source, IEnumerable<string> blacklistedProprties)
|
||||||
|
{
|
||||||
|
MovePropertyData(target, source, (prop) => blacklistedProprties.Contains(prop.Metadata.Name));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void MovePropertyDataWhiteList(this EntityEntry target, object source, IEnumerable<string> whitelistedProprties)
|
||||||
|
{
|
||||||
|
MovePropertyData(target, source, (prop) => !whitelistedProprties.Contains(prop.Metadata.Name));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void MovePropertyData(this EntityEntry target, object source, Func<PropertyEntry, bool> isBlacklisted)
|
||||||
|
{
|
||||||
|
foreach (var prop in target.Properties)
|
||||||
|
{
|
||||||
|
if (isBlacklisted(prop))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
var propertyInfo = prop.Metadata.PropertyInfo;
|
||||||
|
var newValue = propertyInfo.GetValue(source);
|
||||||
|
if (!newValue.isDefault()) {
|
||||||
|
prop.CurrentValue = newValue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static bool isDefault(this object value)
|
||||||
|
{
|
||||||
|
if(value == default)
|
||||||
|
return true;
|
||||||
|
if (value is int || value is long)
|
||||||
|
return (int)value == default(int);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -11,8 +11,10 @@
|
|||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="5.0.8" />
|
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="5.0.10" />
|
||||||
<PackageReference Include="VueCliMiddleware" Version="3.0.0" />
|
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.2.1" />
|
||||||
|
<PackageReference Include="Swashbuckle.AspNetCore.Annotations" Version="6.2.1" />
|
||||||
|
<PackageReference Include="VueCliMiddleware" Version="5.0.0" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
@@ -22,6 +24,10 @@
|
|||||||
<None Include="$(SpaRoot)**" Exclude="$(SpaRoot)node_modules\**" />
|
<None Include="$(SpaRoot)**" Exclude="$(SpaRoot)node_modules\**" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\KTUSAPS.Data\KTUSAPS.Data.csproj" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
<Target Name="DebugEnsureNodeEnv" BeforeTargets="Build" Condition=" '$(Configuration)' == 'Debug' And !Exists('$(SpaRoot)node_modules') ">
|
<Target Name="DebugEnsureNodeEnv" BeforeTargets="Build" Condition=" '$(Configuration)' == 'Debug' And !Exists('$(SpaRoot)node_modules') ">
|
||||||
<!-- Ensure Node.js is installed -->
|
<!-- Ensure Node.js is installed -->
|
||||||
<Exec Command="node --version" ContinueOnError="true">
|
<Exec Command="node --version" ContinueOnError="true">
|
||||||
|
138
KTUSAPS/Services/DatabaseInitializationService.cs
Normal file
138
KTUSAPS/Services/DatabaseInitializationService.cs
Normal file
@@ -0,0 +1,138 @@
|
|||||||
|
using KTUSAPS.Data;
|
||||||
|
using KTUSAPS.Data.Model;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
using Microsoft.Extensions.Hosting;
|
||||||
|
using Microsoft.Extensions.Logging;
|
||||||
|
using System;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace KTUSAPS.Services
|
||||||
|
{
|
||||||
|
public class DatabaseInitializationService : IHostedService
|
||||||
|
{
|
||||||
|
private readonly IServiceProvider serviceProvider;
|
||||||
|
private readonly ILogger<DatabaseInitializationService> logger;
|
||||||
|
|
||||||
|
public DatabaseInitializationService(IServiceProvider serviceProvider, ILogger<DatabaseInitializationService> logger)
|
||||||
|
{
|
||||||
|
this.serviceProvider = serviceProvider;
|
||||||
|
this.logger = logger;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public async Task StartAsync(CancellationToken cancellationToken)
|
||||||
|
{
|
||||||
|
using var scope = serviceProvider.CreateScope();
|
||||||
|
var dataContext = scope.ServiceProvider.GetRequiredService<SAPSDataContext>();
|
||||||
|
var migrations = (await dataContext.Database.GetPendingMigrationsAsync(cancellationToken: cancellationToken)).ToList();
|
||||||
|
if(migrations.Any())
|
||||||
|
{
|
||||||
|
logger.LogInformation($"There are {migrations.Count} pending migrations. Applying them");
|
||||||
|
try
|
||||||
|
{
|
||||||
|
await dataContext.Database.MigrateAsync(cancellationToken: cancellationToken);
|
||||||
|
await Seed(dataContext);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
logger.LogError("Migration failed. Database may be corrupt!");
|
||||||
|
logger.LogError(ex, "Migration failed.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task Seed(SAPSDataContext dataContext)
|
||||||
|
{
|
||||||
|
var generalIssueType = await dataContext.IssueTypes.AddAsync(new IssueType()
|
||||||
|
{
|
||||||
|
Name = "Bendra",
|
||||||
|
NameEn = "General"
|
||||||
|
});
|
||||||
|
var otherIssueType = await dataContext.IssueTypes.AddAsync(new IssueType()
|
||||||
|
{
|
||||||
|
Name = "Kita",
|
||||||
|
NameEn = "Other"
|
||||||
|
});
|
||||||
|
var feedbackIssueType = await dataContext.IssueTypes.AddAsync(new IssueType()
|
||||||
|
{
|
||||||
|
Name = "Atsiliepimas",
|
||||||
|
NameEn = "Feedback"
|
||||||
|
});
|
||||||
|
await dataContext.SaveChangesAsync();
|
||||||
|
|
||||||
|
var issue1 = await dataContext.Issues.AddAsync(new Issue()
|
||||||
|
{
|
||||||
|
Created = DateTime.Now.AddDays(-5),
|
||||||
|
Description = "Man nepatinka dėstytojas.",
|
||||||
|
Email = "karolis.kundrotas@ktu.edu",
|
||||||
|
Publishable = true,
|
||||||
|
IssueType = generalIssueType.Entity
|
||||||
|
});
|
||||||
|
var issue2 = await dataContext.Issues.AddAsync(new Issue()
|
||||||
|
{
|
||||||
|
Created = DateTime.Now.AddDays(-12).AddHours(3),
|
||||||
|
Description = "Dėtytoja atsiskaitymo metu leido nusirašynėti kitiems, o man neleido.",
|
||||||
|
Email = "karolis.kundrotas@ktu.edu",
|
||||||
|
Publishable = true,
|
||||||
|
IssueType = otherIssueType.Entity
|
||||||
|
});
|
||||||
|
var issue3 = await dataContext.Issues.AddAsync(new Issue()
|
||||||
|
{
|
||||||
|
Created = DateTime.Now.AddDays(-18),
|
||||||
|
Description = "Tinklų destytoja per paskaitą neatsako į klausimus ir per paskaitą nieko neišmoko.",
|
||||||
|
Email = "karolis.kundrotas@ktu.edu",
|
||||||
|
Publishable = false,
|
||||||
|
IssueType = generalIssueType.Entity
|
||||||
|
});
|
||||||
|
var issue4 = await dataContext.Issues.AddAsync(new Issue()
|
||||||
|
{
|
||||||
|
Created = DateTime.Now.AddDays(-18),
|
||||||
|
Description = "Saitynų destytojas Tomas labai maloniai ir profesonaliai bendrauja.",
|
||||||
|
Email = "karolis.kundrotas@ktu.edu",
|
||||||
|
Publishable = true,
|
||||||
|
IssueType = feedbackIssueType.Entity,
|
||||||
|
Solved = true
|
||||||
|
});
|
||||||
|
await dataContext.SaveChangesAsync();
|
||||||
|
|
||||||
|
await dataContext.PublishedFeedbacks.AddAsync(new PublishedFeedback()
|
||||||
|
{
|
||||||
|
Issue = issue4.Entity,
|
||||||
|
FeedbackLt = "Studentas mano kad Saitynų dėstytojas Tomas yra profesonalus ir mandagiai bendraujantis.",
|
||||||
|
FeedbackEn = "Student thinks that Site creation module lecturer Tomas is profesonal ir pleasant at communications.",
|
||||||
|
});
|
||||||
|
|
||||||
|
var problem1 = await dataContext.PublishedProblems.AddAsync(new PublishedProblem()
|
||||||
|
{
|
||||||
|
Issue = issue2.Entity,
|
||||||
|
ProblemLt = "Atsikaitymo metu buvo leista nusirašynėti.",
|
||||||
|
ProblemEn = "During exam cheating was allowed.",
|
||||||
|
});
|
||||||
|
var problem2 = await dataContext.PublishedProblems.AddAsync(new PublishedProblem()
|
||||||
|
{
|
||||||
|
Issue = issue3.Entity,
|
||||||
|
ProblemLt = "Dėstytoja V. Pavardenė nemoko studentų per paskaitas, neraguoja į studentų klausimus, nesuteikia pagalbos.",
|
||||||
|
ProblemEn = "Lecturer V. Pavardenė does not lecture students, do not react to student questions and doesn't provide help."
|
||||||
|
});
|
||||||
|
|
||||||
|
await dataContext.SaveChangesAsync();
|
||||||
|
|
||||||
|
await dataContext.Solutions.AddAsync(new Solution()
|
||||||
|
{
|
||||||
|
Problem = problem2.Entity,
|
||||||
|
SolutionLt = "V. Parvedenei buvo priskirta tarnybinę nuobauda.",
|
||||||
|
SolutionEn = ""
|
||||||
|
});
|
||||||
|
|
||||||
|
await dataContext.SaveChangesAsync();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task StopAsync(CancellationToken cancellationToken)
|
||||||
|
{
|
||||||
|
return Task.CompletedTask;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -1,9 +1,12 @@
|
|||||||
|
using KTUSAPS.Services;
|
||||||
using Microsoft.AspNetCore.Authentication.JwtBearer;
|
using Microsoft.AspNetCore.Authentication.JwtBearer;
|
||||||
using Microsoft.AspNetCore.Builder;
|
using Microsoft.AspNetCore.Builder;
|
||||||
using Microsoft.AspNetCore.Hosting;
|
using Microsoft.AspNetCore.Hosting;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
using Microsoft.Extensions.Configuration;
|
using Microsoft.Extensions.Configuration;
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
using Microsoft.Extensions.Hosting;
|
using Microsoft.Extensions.Hosting;
|
||||||
|
using System;
|
||||||
using VueCliMiddleware;
|
using VueCliMiddleware;
|
||||||
|
|
||||||
namespace KTUSAPS
|
namespace KTUSAPS
|
||||||
@@ -39,7 +42,12 @@ namespace KTUSAPS
|
|||||||
.RequireAuthenticatedUser()
|
.RequireAuthenticatedUser()
|
||||||
.Build();
|
.Build();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
var connectionString = Configuration.GetConnectionString("Main");
|
||||||
|
services.AddDbContext<Data.SAPSDataContext>((options) => options.UseMySql(connectionString, ServerVersion.AutoDetect(connectionString)));
|
||||||
|
services.AddHostedService<DatabaseInitializationService>();
|
||||||
|
|
||||||
|
services.AddSwaggerGen();
|
||||||
}
|
}
|
||||||
|
|
||||||
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
|
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
|
||||||
@@ -48,8 +56,16 @@ namespace KTUSAPS
|
|||||||
if (env.IsDevelopment())
|
if (env.IsDevelopment())
|
||||||
{
|
{
|
||||||
app.UseDeveloperExceptionPage();
|
app.UseDeveloperExceptionPage();
|
||||||
|
|
||||||
|
app.UseSwaggerUI(c =>
|
||||||
|
{
|
||||||
|
c.SwaggerEndpoint("/swagger/v1/swagger.json", "API");
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
app.UseSwagger(c =>
|
||||||
|
{
|
||||||
|
});
|
||||||
app.UseRouting();
|
app.UseRouting();
|
||||||
app.UseSpaStaticFiles();
|
app.UseSpaStaticFiles();
|
||||||
app.UseAuthentication();
|
app.UseAuthentication();
|
||||||
|
@@ -1,4 +1,7 @@
|
|||||||
{
|
{
|
||||||
|
"ConnectionStrings": {
|
||||||
|
"Main": "Server=localhost;User=saps_dev;Password=;Database=saps_dev"
|
||||||
|
},
|
||||||
"Logging": {
|
"Logging": {
|
||||||
"LogLevel": {
|
"LogLevel": {
|
||||||
"Default": "Information",
|
"Default": "Information",
|
||||||
|
@@ -1,4 +1,7 @@
|
|||||||
{
|
{
|
||||||
|
"ConnectionStrings": {
|
||||||
|
"Main": "Server=localhost;User=saps;Password=B35eJUmIJxeG0g9yi6ni;Database=saps"
|
||||||
|
},
|
||||||
"Logging": {
|
"Logging": {
|
||||||
"LogLevel": {
|
"LogLevel": {
|
||||||
"Default": "Information",
|
"Default": "Information",
|
||||||
|
Reference in New Issue
Block a user