refactor(modules): update existing module implementations across attendance, audit, auth, classes, course-plans, exams, files, homework, layout, proctoring, questions, scheduling, textbooks, users

- Update attendance components and data-access for record management

- Update audit log views, filters, and data-access

- Update auth login and register forms

- Update classes actions, components, and data-access (admin, schedule, stats)

- Update course-plans actions, form, list, progress, and schema

- Update exams actions, AI pipeline, preview components, and hooks

- Update files components (icon, list, preview, upload) and data-access

- Update homework assignment form, review view, auto-save hook, and stats-service

- Update layout sidebar, header, and navigation config

- Update proctoring actions, anti-cheat monitor, and data-access

- Update questions actions, components (dialog, actions, columns, filters), and data-access

- Update scheduling actions, auto-scheduler, components, and schema

- Update textbooks constants and text-selection hook

- Update users class-registration, import-dialog, data-access, and user-service
This commit is contained in:
SpecialX
2026-06-23 17:38:56 +08:00
parent 1a9377222c
commit 4f0ef217a0
56 changed files with 1251 additions and 850 deletions

View File

@@ -1,6 +1,6 @@
"use server"
import { requirePermission, PermissionDeniedError } from "@/shared/lib/auth-guard"
import { requirePermission } from "@/shared/lib/auth-guard"
import { Permissions } from "@/shared/types/permissions"
import { CreateQuestionSchema } from "./schema"
import type { CreateQuestionInput } from "./schema"
@@ -16,6 +16,7 @@ import {
type GetQuestionsParams,
} from "./data-access"
import type { KnowledgePointOption } from "./types"
import { handleActionError, safeJsonParse } from "@/shared/lib/action-utils"
/** Result type of getQuestions (data + meta) */
type QuestionsListResult = Awaited<ReturnType<typeof getQuestions>>
@@ -35,7 +36,7 @@ export async function createQuestionAction(
if (formData instanceof FormData) {
const jsonString = formData.get("json")
if (typeof jsonString === "string") {
rawInput = JSON.parse(jsonString) as unknown
rawInput = safeJsonParse<unknown>(jsonString, "题目内容格式无效")
} else {
return { success: false, message: "Invalid submission format. Expected JSON." }
}
@@ -53,29 +54,17 @@ export async function createQuestionAction(
const input = validatedFields.data
await createQuestionWithRelations(input, ctx.userId)
const questionId = await createQuestionWithRelations(input, ctx.userId)
revalidatePath("/teacher/questions")
return {
success: true,
message: "Question created successfully",
data: questionId,
}
} catch (e) {
if (e instanceof PermissionDeniedError) {
return { success: false, message: e.message }
}
if (e instanceof Error) {
return {
success: false,
message: e.message || "Database error occurred",
}
}
return {
success: false,
message: "An unexpected error occurred",
}
return handleActionError(e)
}
}
@@ -83,7 +72,7 @@ const UpdateQuestionSchema = z.object({
id: z.string().min(1),
type: z.enum(["single_choice", "multiple_choice", "text", "judgment", "composite"]),
difficulty: z.number().min(1).max(5),
content: z.unknown(),
content: z.record(z.string(), z.unknown()),
knowledgePointIds: z.array(z.string()).optional(),
})
@@ -100,7 +89,7 @@ export async function updateQuestionAction(
return { success: false, message: "Invalid submission format. Expected JSON." }
}
const parsed = UpdateQuestionSchema.safeParse(JSON.parse(jsonString))
const parsed = UpdateQuestionSchema.safeParse(safeJsonParse<unknown>(jsonString, "题目内容格式无效"))
if (!parsed.success) {
return {
success: false,
@@ -115,15 +104,9 @@ export async function updateQuestionAction(
revalidatePath("/teacher/questions")
return { success: true, message: "Question updated successfully" }
return { success: true, message: "Question updated successfully", data: id }
} catch (e) {
if (e instanceof PermissionDeniedError) {
return { success: false, message: e.message }
}
if (e instanceof Error) {
return { success: false, message: e.message }
}
return { success: false, message: "An unexpected error occurred" }
return handleActionError(e)
}
}
@@ -144,15 +127,9 @@ export async function deleteQuestionAction(
revalidatePath("/teacher/questions")
return { success: true, message: "Question deleted successfully" }
return { success: true, message: "Question deleted successfully", data: questionId }
} catch (e) {
if (e instanceof PermissionDeniedError) {
return { success: false, message: e.message }
}
if (e instanceof Error) {
return { success: false, message: e.message }
}
return { success: false, message: "Failed to delete question" }
return handleActionError(e)
}
}
@@ -164,11 +141,7 @@ export async function getQuestionsAction(
const data = await getQuestions(params)
return { success: true, data }
} catch (e) {
if (e instanceof PermissionDeniedError) {
return { success: false, message: e.message }
}
const message = e instanceof Error ? e.message : "Failed to fetch questions"
return { success: false, message }
return handleActionError(e)
}
}
@@ -180,10 +153,6 @@ export async function getKnowledgePointOptionsAction(): Promise<
const data = await getKnowledgePointOptions()
return { success: true, data }
} catch (e) {
if (e instanceof PermissionDeniedError) {
return { success: false, message: e.message }
}
const message = e instanceof Error ? e.message : "Failed to fetch knowledge point options"
return { success: false, message }
return handleActionError(e)
}
}