feat(exam-homework): add audit report, i18n, error boundaries, and permission hardening

- Add comprehensive audit report for exam and homework module

- Create exam-homework i18n message files (zh-CN + en) and register namespace

- Add permission check to gradeHomeworkSubmissionAction to prevent horizontal privilege escalation

- Add Error Boundary + loading.tsx for 5 key pages (exam build/proctoring, homework assignment/submissions, student assignment)

- Refactor exam-columns to createExamColumns(t) factory for i18n support

- Refactor exam-data-table to manage columns internally via useTranslations

- Replace hardcoded strings with i18n keys in all exam/homework components and pages

- Add getHomeworkSubmissionForGrading data-access for secure grading flow
This commit is contained in:
SpecialX
2026-06-22 16:08:39 +08:00
parent fde711ce46
commit 21c7e65fee
26 changed files with 2059 additions and 463 deletions

View File

@@ -45,7 +45,7 @@ export type HomeworkSubmissionPermissionData = {
export type CreateHomeworkAssignmentData = {
assignmentId: string
sourceExamId: string
sourceExamId: string | null
title: string
description: string | null
structure: unknown
@@ -116,6 +116,32 @@ export const getHomeworkSubmissionForPermission = async (
}
}
/**
* 批改权限校验:获取提交记录及其作业的创建者信息
* 用于 gradeHomeworkSubmissionAction 校验教师是否有权批改该提交
* 返回 null 表示提交记录不存在
*/
export const getHomeworkSubmissionForGrading = async (
submissionId: string
): Promise<{
id: string
assignmentId: string
creatorId: string
sourceExamId: string | null
} | null> => {
const submission = await db.query.homeworkSubmissions.findFirst({
where: eq(homeworkSubmissions.id, submissionId),
with: { assignment: true },
})
if (!submission) return null
return {
id: submission.id,
assignmentId: submission.assignmentId,
creatorId: submission.assignment.creatorId,
sourceExamId: submission.assignment.sourceExamId,
}
}
// ---- Write functions ----
export const createHomeworkAssignment = async (