各类申请
This commit is contained in:
@@ -56,6 +56,10 @@ public sealed class AppDbContext(DbContextOptions<AppDbContext> options)
|
||||
public DbSet<ExamSessionInvigilator> ExamSessionInvigilators =>
|
||||
Set<ExamSessionInvigilator>();
|
||||
public DbSet<CourseAdjustment> CourseAdjustments => Set<CourseAdjustment>();
|
||||
public DbSet<CourseExemption> CourseExemptions => Set<CourseExemption>();
|
||||
public DbSet<DeferredExam> DeferredExams => Set<DeferredExam>();
|
||||
public DbSet<GradeModification> GradeModifications => Set<GradeModification>();
|
||||
public DbSet<CourseSubstitution> CourseSubstitutions => Set<CourseSubstitution>();
|
||||
public DbSet<Notification> Notifications => Set<Notification>();
|
||||
public DbSet<StudentStatusChange> StudentStatusChanges =>
|
||||
Set<StudentStatusChange>();
|
||||
@@ -673,6 +677,52 @@ public sealed class AppDbContext(DbContextOptions<AppDbContext> options)
|
||||
.HasForeignKey(x => x.StudentId).OnDelete(DeleteBehavior.Restrict);
|
||||
});
|
||||
|
||||
builder.Entity<CourseExemption>(entity =>
|
||||
{
|
||||
entity.Property(x => x.Reason).HasMaxLength(500);
|
||||
entity.Property(x => x.ReviewComment).HasMaxLength(500);
|
||||
entity.HasIndex(x => new { x.Status, x.CreatedAt });
|
||||
entity.HasIndex(x => new { x.StudentId, x.TeachingTaskId }).IsUnique();
|
||||
entity.HasOne(x => x.Student).WithMany()
|
||||
.HasForeignKey(x => x.StudentId).OnDelete(DeleteBehavior.Restrict);
|
||||
entity.HasOne(x => x.TeachingTask).WithMany()
|
||||
.HasForeignKey(x => x.TeachingTaskId).OnDelete(DeleteBehavior.Restrict);
|
||||
});
|
||||
builder.Entity<DeferredExam>(entity =>
|
||||
{
|
||||
entity.Property(x => x.Reason).HasMaxLength(500);
|
||||
entity.Property(x => x.ReviewComment).HasMaxLength(500);
|
||||
entity.HasIndex(x => new { x.Status, x.CreatedAt });
|
||||
entity.HasIndex(x => new { x.StudentId, x.TeachingTaskId }).IsUnique();
|
||||
entity.HasOne(x => x.Student).WithMany()
|
||||
.HasForeignKey(x => x.StudentId).OnDelete(DeleteBehavior.Restrict);
|
||||
entity.HasOne(x => x.TeachingTask).WithMany()
|
||||
.HasForeignKey(x => x.TeachingTaskId).OnDelete(DeleteBehavior.Restrict);
|
||||
});
|
||||
builder.Entity<GradeModification>(entity =>
|
||||
{
|
||||
entity.Property(x => x.CurrentScore).HasPrecision(5, 1);
|
||||
entity.Property(x => x.RequestedScore).HasPrecision(5, 1);
|
||||
entity.Property(x => x.Reason).HasMaxLength(500);
|
||||
entity.Property(x => x.ReviewComment).HasMaxLength(500);
|
||||
entity.HasIndex(x => new { x.Status, x.CreatedAt });
|
||||
entity.HasOne(x => x.GradeRecord).WithMany()
|
||||
.HasForeignKey(x => x.GradeRecordId).OnDelete(DeleteBehavior.Restrict);
|
||||
});
|
||||
builder.Entity<CourseSubstitution>(entity =>
|
||||
{
|
||||
entity.Property(x => x.Reason).HasMaxLength(500);
|
||||
entity.Property(x => x.ReviewComment).HasMaxLength(500);
|
||||
entity.HasIndex(x => new { x.Status, x.CreatedAt });
|
||||
entity.HasIndex(x => new { x.StudentId, x.OriginalCourseId }).IsUnique();
|
||||
entity.HasOne(x => x.Student).WithMany()
|
||||
.HasForeignKey(x => x.StudentId).OnDelete(DeleteBehavior.Restrict);
|
||||
entity.HasOne(x => x.OriginalCourse).WithMany()
|
||||
.HasForeignKey(x => x.OriginalCourseId).OnDelete(DeleteBehavior.Restrict);
|
||||
entity.HasOne(x => x.SubstituteCourse).WithMany()
|
||||
.HasForeignKey(x => x.SubstituteCourseId).OnDelete(DeleteBehavior.Restrict);
|
||||
});
|
||||
|
||||
builder.Entity<CourseAdjustment>(entity =>
|
||||
{
|
||||
entity.Property(x => x.Reason).HasMaxLength(500);
|
||||
|
||||
@@ -40,6 +40,8 @@ public sealed class DevelopmentSqliteMigrator(
|
||||
"20260725_22_course_adjustments";
|
||||
private const string AttendanceAppealMigration =
|
||||
"20260725_23_attendance_appeal";
|
||||
private const string ApprovalTablesMigration =
|
||||
"20260725_24_approval_tables";
|
||||
|
||||
public async Task MigrateAsync(CancellationToken cancellationToken = default)
|
||||
{
|
||||
@@ -270,6 +272,14 @@ public sealed class DevelopmentSqliteMigrator(
|
||||
AttendanceAppealMigration,
|
||||
attendanceAppealExists ? [] : AttendanceAppealStatements,
|
||||
cancellationToken);
|
||||
|
||||
var approvalTablesExist = await db.Database
|
||||
.SqlQueryRaw<int>("SELECT COUNT(*) AS \"Value\" FROM sqlite_master WHERE type = 'table' AND name = 'CourseExemptions'")
|
||||
.AnyAsync(value => value > 0, cancellationToken);
|
||||
await ApplyMigrationAsync(
|
||||
ApprovalTablesMigration,
|
||||
approvalTablesExist ? [] : ApprovalTableStatements,
|
||||
cancellationToken);
|
||||
}
|
||||
|
||||
private async Task ApplyMigrationAsync(
|
||||
@@ -1578,4 +1588,22 @@ public sealed class DevelopmentSqliteMigrator(
|
||||
"""ALTER TABLE "AttendanceRecords" ADD COLUMN "AppealReviewedAt" TEXT NULL;""",
|
||||
"""CREATE INDEX IF NOT EXISTS "IX_AttendanceRecords_AppealStatus" ON "AttendanceRecords" ("AppealStatus");"""
|
||||
];
|
||||
|
||||
private static readonly string[] ApprovalTableStatements =
|
||||
[
|
||||
"""CREATE TABLE "CourseExemptions" ("Id" TEXT NOT NULL CONSTRAINT "PK_CourseExemptions" PRIMARY KEY, "StudentId" TEXT NOT NULL, "TeachingTaskId" TEXT NOT NULL, "Reason" TEXT NOT NULL, "Status" INTEGER NOT NULL, "ReviewComment" TEXT NULL, "SubmittedAt" TEXT NOT NULL, "ReviewedAt" TEXT NULL, "ReviewedByUserId" TEXT NULL, "CreatedAt" TEXT NOT NULL, "UpdatedAt" TEXT NOT NULL, CONSTRAINT "FK_CourseExemptions_Students" FOREIGN KEY ("StudentId") REFERENCES "Students" ("Id") ON DELETE RESTRICT, CONSTRAINT "FK_CourseExemptions_TeachingTasks" FOREIGN KEY ("TeachingTaskId") REFERENCES "TeachingTasks" ("Id") ON DELETE RESTRICT);""",
|
||||
"""CREATE UNIQUE INDEX "IX_CourseExemptions_StudentId_TeachingTaskId" ON "CourseExemptions" ("StudentId", "TeachingTaskId");""",
|
||||
"""CREATE INDEX "IX_CourseExemptions_Status_CreatedAt" ON "CourseExemptions" ("Status", "CreatedAt");""",
|
||||
|
||||
"""CREATE TABLE "DeferredExams" ("Id" TEXT NOT NULL CONSTRAINT "PK_DeferredExams" PRIMARY KEY, "StudentId" TEXT NOT NULL, "TeachingTaskId" TEXT NOT NULL, "Reason" TEXT NOT NULL, "Status" INTEGER NOT NULL, "ReviewComment" TEXT NULL, "SubmittedAt" TEXT NOT NULL, "ReviewedAt" TEXT NULL, "ReviewedByUserId" TEXT NULL, "CreatedAt" TEXT NOT NULL, "UpdatedAt" TEXT NOT NULL, CONSTRAINT "FK_DeferredExams_Students" FOREIGN KEY ("StudentId") REFERENCES "Students" ("Id") ON DELETE RESTRICT, CONSTRAINT "FK_DeferredExams_TeachingTasks" FOREIGN KEY ("TeachingTaskId") REFERENCES "TeachingTasks" ("Id") ON DELETE RESTRICT);""",
|
||||
"""CREATE UNIQUE INDEX "IX_DeferredExams_StudentId_TeachingTaskId" ON "DeferredExams" ("StudentId", "TeachingTaskId");""",
|
||||
"""CREATE INDEX "IX_DeferredExams_Status_CreatedAt" ON "DeferredExams" ("Status", "CreatedAt");""",
|
||||
|
||||
"""CREATE TABLE "GradeModifications" ("Id" TEXT NOT NULL CONSTRAINT "PK_GradeModifications" PRIMARY KEY, "GradeRecordId" TEXT NOT NULL, "CurrentScore" TEXT NOT NULL, "RequestedScore" TEXT NOT NULL, "Reason" TEXT NOT NULL, "Status" INTEGER NOT NULL, "ReviewComment" TEXT NULL, "ApplicantUserId" TEXT NOT NULL, "SubmittedAt" TEXT NOT NULL, "CollegeReviewedAt" TEXT NULL, "CollegeReviewedByUserId" TEXT NULL, "FinalReviewedAt" TEXT NULL, "FinalReviewedByUserId" TEXT NULL, "CreatedAt" TEXT NOT NULL, "UpdatedAt" TEXT NOT NULL, CONSTRAINT "FK_GradeModifications_GradeRecords" FOREIGN KEY ("GradeRecordId") REFERENCES "GradeRecords" ("Id") ON DELETE RESTRICT);""",
|
||||
"""CREATE INDEX "IX_GradeModifications_Status_CreatedAt" ON "GradeModifications" ("Status", "CreatedAt");""",
|
||||
|
||||
"""CREATE TABLE "CourseSubstitutions" ("Id" TEXT NOT NULL CONSTRAINT "PK_CourseSubstitutions" PRIMARY KEY, "StudentId" TEXT NOT NULL, "OriginalCourseId" TEXT NOT NULL, "SubstituteCourseId" TEXT NOT NULL, "Reason" TEXT NOT NULL, "Status" INTEGER NOT NULL, "ReviewComment" TEXT NULL, "SubmittedAt" TEXT NOT NULL, "ReviewedAt" TEXT NULL, "ReviewedByUserId" TEXT NULL, "CreatedAt" TEXT NOT NULL, "UpdatedAt" TEXT NOT NULL, CONSTRAINT "FK_CourseSubstitutions_Students" FOREIGN KEY ("StudentId") REFERENCES "Students" ("Id") ON DELETE RESTRICT, CONSTRAINT "FK_CourseSubstitutions_OriginalCourse" FOREIGN KEY ("OriginalCourseId") REFERENCES "Courses" ("Id") ON DELETE RESTRICT, CONSTRAINT "FK_CourseSubstitutions_SubstituteCourse" FOREIGN KEY ("SubstituteCourseId") REFERENCES "Courses" ("Id") ON DELETE RESTRICT);""",
|
||||
"""CREATE UNIQUE INDEX "IX_CourseSubstitutions_StudentId_OriginalCourseId" ON "CourseSubstitutions" ("StudentId", "OriginalCourseId");""",
|
||||
"""CREATE INDEX "IX_CourseSubstitutions_Status_CreatedAt" ON "CourseSubstitutions" ("Status", "CreatedAt");"""
|
||||
];
|
||||
}
|
||||
|
||||
+117
@@ -0,0 +1,117 @@
|
||||
using System;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace Jiaowu.Api.Infrastructure.Persistence.Migrations.MySql
|
||||
{
|
||||
public partial class ApprovalRequests : Migration
|
||||
{
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
// CourseExemption
|
||||
migrationBuilder.CreateTable("CourseExemptions", table => new
|
||||
{
|
||||
Id = table.Column<Guid>(type: "char(36)", nullable: false),
|
||||
StudentId = table.Column<Guid>(type: "char(36)", nullable: false),
|
||||
TeachingTaskId = table.Column<Guid>(type: "char(36)", nullable: false),
|
||||
Reason = table.Column<string>(type: "varchar(500)", maxLength: 500, nullable: false),
|
||||
Status = table.Column<int>(type: "int", nullable: false),
|
||||
ReviewComment = table.Column<string>(type: "varchar(500)", maxLength: 500, nullable: true),
|
||||
SubmittedAt = table.Column<DateTime>(type: "datetime(6)", nullable: false),
|
||||
ReviewedAt = table.Column<DateTime>(type: "datetime(6)", nullable: true),
|
||||
ReviewedByUserId = table.Column<Guid>(type: "char(36)", nullable: true),
|
||||
CreatedAt = table.Column<DateTime>(type: "datetime(6)", nullable: false),
|
||||
UpdatedAt = table.Column<DateTime>(type: "datetime(6)", nullable: false)
|
||||
}, constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_CourseExemptions", x => x.Id);
|
||||
table.ForeignKey("FK_CourseExemptions_Students", x => x.StudentId, "Students", "Id", onDelete: ReferentialAction.Restrict);
|
||||
table.ForeignKey("FK_CourseExemptions_TeachingTasks", x => x.TeachingTaskId, "TeachingTasks", "Id", onDelete: ReferentialAction.Restrict);
|
||||
});
|
||||
migrationBuilder.CreateIndex("IX_CourseExemptions_Status_CreatedAt", "CourseExemptions", new[] { "Status", "CreatedAt" });
|
||||
migrationBuilder.CreateIndex("IX_CourseExemptions_StudentId_TeachingTaskId", "CourseExemptions", new[] { "StudentId", "TeachingTaskId" }, unique: true);
|
||||
|
||||
// DeferredExam
|
||||
migrationBuilder.CreateTable("DeferredExams", table => new
|
||||
{
|
||||
Id = table.Column<Guid>(type: "char(36)", nullable: false),
|
||||
StudentId = table.Column<Guid>(type: "char(36)", nullable: false),
|
||||
TeachingTaskId = table.Column<Guid>(type: "char(36)", nullable: false),
|
||||
Reason = table.Column<string>(type: "varchar(500)", maxLength: 500, nullable: false),
|
||||
Status = table.Column<int>(type: "int", nullable: false),
|
||||
ReviewComment = table.Column<string>(type: "varchar(500)", maxLength: 500, nullable: true),
|
||||
SubmittedAt = table.Column<DateTime>(type: "datetime(6)", nullable: false),
|
||||
ReviewedAt = table.Column<DateTime>(type: "datetime(6)", nullable: true),
|
||||
ReviewedByUserId = table.Column<Guid>(type: "char(36)", nullable: true),
|
||||
CreatedAt = table.Column<DateTime>(type: "datetime(6)", nullable: false),
|
||||
UpdatedAt = table.Column<DateTime>(type: "datetime(6)", nullable: false)
|
||||
}, constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_DeferredExams", x => x.Id);
|
||||
table.ForeignKey("FK_DeferredExams_Students", x => x.StudentId, "Students", "Id", onDelete: ReferentialAction.Restrict);
|
||||
table.ForeignKey("FK_DeferredExams_TeachingTasks", x => x.TeachingTaskId, "TeachingTasks", "Id", onDelete: ReferentialAction.Restrict);
|
||||
});
|
||||
migrationBuilder.CreateIndex("IX_DeferredExams_Status_CreatedAt", "DeferredExams", new[] { "Status", "CreatedAt" });
|
||||
migrationBuilder.CreateIndex("IX_DeferredExams_StudentId_TeachingTaskId", "DeferredExams", new[] { "StudentId", "TeachingTaskId" }, unique: true);
|
||||
|
||||
// GradeModification
|
||||
migrationBuilder.CreateTable("GradeModifications", table => new
|
||||
{
|
||||
Id = table.Column<Guid>(type: "char(36)", nullable: false),
|
||||
GradeRecordId = table.Column<Guid>(type: "char(36)", nullable: false),
|
||||
CurrentScore = table.Column<decimal>(type: "decimal(5,1)", precision: 5, scale: 1, nullable: false),
|
||||
RequestedScore = table.Column<decimal>(type: "decimal(5,1)", precision: 5, scale: 1, nullable: false),
|
||||
Reason = table.Column<string>(type: "varchar(500)", maxLength: 500, nullable: false),
|
||||
Status = table.Column<int>(type: "int", nullable: false),
|
||||
ReviewComment = table.Column<string>(type: "varchar(500)", maxLength: 500, nullable: true),
|
||||
ApplicantUserId = table.Column<Guid>(type: "char(36)", nullable: false),
|
||||
SubmittedAt = table.Column<DateTime>(type: "datetime(6)", nullable: false),
|
||||
CollegeReviewedAt = table.Column<DateTime>(type: "datetime(6)", nullable: true),
|
||||
CollegeReviewedByUserId = table.Column<Guid>(type: "char(36)", nullable: true),
|
||||
FinalReviewedAt = table.Column<DateTime>(type: "datetime(6)", nullable: true),
|
||||
FinalReviewedByUserId = table.Column<Guid>(type: "char(36)", nullable: true),
|
||||
CreatedAt = table.Column<DateTime>(type: "datetime(6)", nullable: false),
|
||||
UpdatedAt = table.Column<DateTime>(type: "datetime(6)", nullable: false)
|
||||
}, constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_GradeModifications", x => x.Id);
|
||||
table.ForeignKey("FK_GradeModifications_GradeRecords", x => x.GradeRecordId, "GradeRecords", "Id", onDelete: ReferentialAction.Restrict);
|
||||
});
|
||||
migrationBuilder.CreateIndex("IX_GradeModifications_Status_CreatedAt", "GradeModifications", new[] { "Status", "CreatedAt" });
|
||||
|
||||
// CourseSubstitution
|
||||
migrationBuilder.CreateTable("CourseSubstitutions", table => new
|
||||
{
|
||||
Id = table.Column<Guid>(type: "char(36)", nullable: false),
|
||||
StudentId = table.Column<Guid>(type: "char(36)", nullable: false),
|
||||
OriginalCourseId = table.Column<Guid>(type: "char(36)", nullable: false),
|
||||
SubstituteCourseId = table.Column<Guid>(type: "char(36)", nullable: false),
|
||||
Reason = table.Column<string>(type: "varchar(500)", maxLength: 500, nullable: false),
|
||||
Status = table.Column<int>(type: "int", nullable: false),
|
||||
ReviewComment = table.Column<string>(type: "varchar(500)", maxLength: 500, nullable: true),
|
||||
SubmittedAt = table.Column<DateTime>(type: "datetime(6)", nullable: false),
|
||||
ReviewedAt = table.Column<DateTime>(type: "datetime(6)", nullable: true),
|
||||
ReviewedByUserId = table.Column<Guid>(type: "char(36)", nullable: true),
|
||||
CreatedAt = table.Column<DateTime>(type: "datetime(6)", nullable: false),
|
||||
UpdatedAt = table.Column<DateTime>(type: "datetime(6)", nullable: false)
|
||||
}, constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_CourseSubstitutions", x => x.Id);
|
||||
table.ForeignKey("FK_CourseSubstitutions_Students", x => x.StudentId, "Students", "Id", onDelete: ReferentialAction.Restrict);
|
||||
table.ForeignKey("FK_CourseSubstitutions_OriginalCourse", x => x.OriginalCourseId, "Courses", "Id", onDelete: ReferentialAction.Restrict);
|
||||
table.ForeignKey("FK_CourseSubstitutions_SubstituteCourse", x => x.SubstituteCourseId, "Courses", "Id", onDelete: ReferentialAction.Restrict);
|
||||
});
|
||||
migrationBuilder.CreateIndex("IX_CourseSubstitutions_Status_CreatedAt", "CourseSubstitutions", new[] { "Status", "CreatedAt" });
|
||||
migrationBuilder.CreateIndex("IX_CourseSubstitutions_StudentId_OriginalCourseId", "CourseSubstitutions", new[] { "StudentId", "OriginalCourseId" }, unique: true);
|
||||
}
|
||||
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropTable("CourseSubstitutions");
|
||||
migrationBuilder.DropTable("GradeModifications");
|
||||
migrationBuilder.DropTable("DeferredExams");
|
||||
migrationBuilder.DropTable("CourseExemptions");
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user