Merge exams grading into homework
Redirect /teacher/exams/grading* to /teacher/homework/submissions; remove exam grading UI/actions/data-access; add homework student workflow and update design docs.
This commit is contained in:
@@ -269,6 +269,127 @@ export const submissionAnswers = mysqlTable("submission_answers", {
|
||||
submissionIdx: index("submission_idx").on(table.submissionId),
|
||||
}));
|
||||
|
||||
export const homeworkAssignments = mysqlTable("homework_assignments", {
|
||||
id: id("id").primaryKey(),
|
||||
sourceExamId: varchar("source_exam_id", { length: 128 }).notNull(),
|
||||
title: varchar("title", { length: 255 }).notNull(),
|
||||
description: text("description"),
|
||||
structure: json("structure"),
|
||||
status: varchar("status", { length: 50 }).default("draft"),
|
||||
creatorId: varchar("creator_id", { length: 128 }).notNull(),
|
||||
availableAt: timestamp("available_at"),
|
||||
dueAt: timestamp("due_at"),
|
||||
allowLate: boolean("allow_late").default(false).notNull(),
|
||||
lateDueAt: timestamp("late_due_at"),
|
||||
maxAttempts: int("max_attempts").default(1).notNull(),
|
||||
createdAt: timestamp("created_at").defaultNow().notNull(),
|
||||
updatedAt: timestamp("updated_at").defaultNow().onUpdateNow().notNull(),
|
||||
}, (table) => ({
|
||||
creatorIdx: index("hw_assignment_creator_idx").on(table.creatorId),
|
||||
sourceExamIdx: index("hw_assignment_source_exam_idx").on(table.sourceExamId),
|
||||
statusIdx: index("hw_assignment_status_idx").on(table.status),
|
||||
sourceExamFk: foreignKey({
|
||||
columns: [table.sourceExamId],
|
||||
foreignColumns: [exams.id],
|
||||
name: "hw_asg_exam_fk",
|
||||
}).onDelete("cascade"),
|
||||
creatorFk: foreignKey({
|
||||
columns: [table.creatorId],
|
||||
foreignColumns: [users.id],
|
||||
name: "hw_asg_creator_fk",
|
||||
}).onDelete("cascade"),
|
||||
}));
|
||||
|
||||
export const homeworkAssignmentQuestions = mysqlTable("homework_assignment_questions", {
|
||||
assignmentId: varchar("assignment_id", { length: 128 }).notNull(),
|
||||
questionId: varchar("question_id", { length: 128 }).notNull(),
|
||||
score: int("score").default(0),
|
||||
order: int("order").default(0),
|
||||
}, (table) => ({
|
||||
pk: primaryKey({ columns: [table.assignmentId, table.questionId] }),
|
||||
assignmentIdx: index("hw_assignment_questions_assignment_idx").on(table.assignmentId),
|
||||
assignmentFk: foreignKey({
|
||||
columns: [table.assignmentId],
|
||||
foreignColumns: [homeworkAssignments.id],
|
||||
name: "hw_aq_a_fk",
|
||||
}).onDelete("cascade"),
|
||||
questionFk: foreignKey({
|
||||
columns: [table.questionId],
|
||||
foreignColumns: [questions.id],
|
||||
name: "hw_aq_q_fk",
|
||||
}).onDelete("cascade"),
|
||||
}));
|
||||
|
||||
export const homeworkAssignmentTargets = mysqlTable("homework_assignment_targets", {
|
||||
assignmentId: varchar("assignment_id", { length: 128 }).notNull(),
|
||||
studentId: varchar("student_id", { length: 128 }).notNull(),
|
||||
createdAt: timestamp("created_at").defaultNow().notNull(),
|
||||
}, (table) => ({
|
||||
pk: primaryKey({ columns: [table.assignmentId, table.studentId] }),
|
||||
assignmentIdx: index("hw_assignment_targets_assignment_idx").on(table.assignmentId),
|
||||
studentIdx: index("hw_assignment_targets_student_idx").on(table.studentId),
|
||||
assignmentFk: foreignKey({
|
||||
columns: [table.assignmentId],
|
||||
foreignColumns: [homeworkAssignments.id],
|
||||
name: "hw_at_a_fk",
|
||||
}).onDelete("cascade"),
|
||||
studentFk: foreignKey({
|
||||
columns: [table.studentId],
|
||||
foreignColumns: [users.id],
|
||||
name: "hw_at_s_fk",
|
||||
}).onDelete("cascade"),
|
||||
}));
|
||||
|
||||
export const homeworkSubmissions = mysqlTable("homework_submissions", {
|
||||
id: id("id").primaryKey(),
|
||||
assignmentId: varchar("assignment_id", { length: 128 }).notNull(),
|
||||
studentId: varchar("student_id", { length: 128 }).notNull(),
|
||||
attemptNo: int("attempt_no").default(1).notNull(),
|
||||
score: int("score"),
|
||||
status: varchar("status", { length: 50 }).default("started"),
|
||||
startedAt: timestamp("started_at").defaultNow().notNull(),
|
||||
submittedAt: timestamp("submitted_at"),
|
||||
isLate: boolean("is_late").default(false).notNull(),
|
||||
createdAt: timestamp("created_at").defaultNow().notNull(),
|
||||
updatedAt: timestamp("updated_at").defaultNow().onUpdateNow().notNull(),
|
||||
}, (table) => ({
|
||||
assignmentStudentIdx: index("hw_assignment_student_idx").on(table.assignmentId, table.studentId),
|
||||
assignmentFk: foreignKey({
|
||||
columns: [table.assignmentId],
|
||||
foreignColumns: [homeworkAssignments.id],
|
||||
name: "hw_sub_a_fk",
|
||||
}).onDelete("cascade"),
|
||||
studentFk: foreignKey({
|
||||
columns: [table.studentId],
|
||||
foreignColumns: [users.id],
|
||||
name: "hw_sub_student_fk",
|
||||
}).onDelete("cascade"),
|
||||
}));
|
||||
|
||||
export const homeworkAnswers = mysqlTable("homework_answers", {
|
||||
id: id("id").primaryKey(),
|
||||
submissionId: varchar("submission_id", { length: 128 }).notNull(),
|
||||
questionId: varchar("question_id", { length: 128 }).notNull(),
|
||||
answerContent: json("answer_content"),
|
||||
score: int("score"),
|
||||
feedback: text("feedback"),
|
||||
createdAt: timestamp("created_at").defaultNow().notNull(),
|
||||
updatedAt: timestamp("updated_at").defaultNow().onUpdateNow().notNull(),
|
||||
}, (table) => ({
|
||||
submissionIdx: index("hw_answer_submission_idx").on(table.submissionId),
|
||||
submissionQuestionIdx: index("hw_answer_submission_question_idx").on(table.submissionId, table.questionId),
|
||||
submissionFk: foreignKey({
|
||||
columns: [table.submissionId],
|
||||
foreignColumns: [homeworkSubmissions.id],
|
||||
name: "hw_ans_sub_fk",
|
||||
}).onDelete("cascade"),
|
||||
questionFk: foreignKey({
|
||||
columns: [table.questionId],
|
||||
foreignColumns: [questions.id],
|
||||
name: "hw_ans_q_fk",
|
||||
}),
|
||||
}));
|
||||
|
||||
// Re-export old courses table if needed or deprecate it.
|
||||
// Assuming we are replacing the old simple schema with this robust one.
|
||||
// But if there were existing tables, we might keep them or comment them out.
|
||||
|
||||
Reference in New Issue
Block a user