refactor(lesson-preparation): V2 审计深度修复 — Server Actions i18n + 错误码模式 + 类型断言清零 + a11y 深度修复 + Tracker 埋点接入
V2-1: 12 个 Server Action 通过 getTranslations 翻译错误消息;Service/DataAccess 层抛出错误码异常(PublishServiceError/LessonPlanDataError),Actions 层通过 PUBLISH_ERROR_KEY_MAP 翻译为 i18n 消息 V2-2: SYSTEM_TEMPLATES name/title 改为 i18n 键,createLessonPlan 接受 translateTitle 函数在服务端翻译后存储到 DB V2-3: 8 处 as unknown as 断言替换为显式类型映射函数(mapRowToLessonPlan/mapRowToListItem/mapRowToTemplate/mapRowToVersion)+ 类型守卫(isLessonPlanStatus/isTemplateType/isTemplateScope) V2-4: MiniMap nodeColor 复用 lib/node-summary.ts 的 getNodeColor V2-5: a11y 深度修复 — lesson-plan-filters/exercise-block/inline-question-editor 的 select 添加 label htmlFor 关联;exercise-block 题目列表改为 ul/li;node-editor 画布添加 role=application + 键盘导航配置 V2-6: Tracker 埋点接入 — 新增 useLessonPlanTrackerSafe hook,在 create/save/publish/revert/duplicate/archive 6 处调用 tracker.track 同步更新架构图 004 和 005 文档
This commit is contained in:
@@ -1,12 +1,13 @@
|
||||
"use server";
|
||||
|
||||
import { revalidatePath } from "next/cache";
|
||||
import { getTranslations } from "next-intl/server";
|
||||
import {
|
||||
requirePermission,
|
||||
PermissionDeniedError,
|
||||
} from "@/shared/lib/auth-guard";
|
||||
import { Permissions } from "@/shared/types/permissions";
|
||||
import { publishLessonPlanHomework } from "./publish-service";
|
||||
import { publishLessonPlanHomework, PublishServiceError } from "./publish-service";
|
||||
import type { ActionState } from "./types";
|
||||
|
||||
export async function publishLessonPlanHomeworkAction(input: {
|
||||
@@ -16,6 +17,7 @@ export async function publishLessonPlanHomeworkAction(input: {
|
||||
availableAt?: string;
|
||||
dueAt?: string;
|
||||
}): Promise<ActionState<{ examId: string; assignmentId: string }>> {
|
||||
const t = await getTranslations("lessonPreparation");
|
||||
try {
|
||||
const ctx = await requirePermission(
|
||||
Permissions.LESSON_PLAN_PUBLISH,
|
||||
@@ -43,9 +45,25 @@ export async function publishLessonPlanHomeworkAction(input: {
|
||||
} catch (e) {
|
||||
if (e instanceof PermissionDeniedError)
|
||||
return { success: false, message: e.message };
|
||||
// publish-service 抛出 PublishServiceError(含 code),翻译为 i18n 消息
|
||||
if (e instanceof PublishServiceError) {
|
||||
const messageKey = PUBLISH_ERROR_KEY_MAP[e.code] ?? "error.publish";
|
||||
return { success: false, message: t(messageKey) };
|
||||
}
|
||||
return {
|
||||
success: false,
|
||||
message: e instanceof Error ? e.message : "发布失败",
|
||||
message: e instanceof Error ? e.message : t("error.publish"),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
// publish-service 错误码 → i18n 键映射
|
||||
const PUBLISH_ERROR_KEY_MAP: Record<string, string> = {
|
||||
PLAN_NOT_FOUND: "publish.planNotFound",
|
||||
NO_PERMISSION: "publish.noPermission",
|
||||
NO_EXERCISE_BLOCK: "publish.noExerciseBlock",
|
||||
NO_QUESTIONS: "publish.noQuestions",
|
||||
ALREADY_PUBLISHED: "publish.alreadyPublished",
|
||||
NO_SUBJECT_OR_GRADE: "publish.noSubjectOrGrade",
|
||||
NO_STUDENTS: "publish.noStudents",
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user