refactor: P0-3/5/6 解耦修复 - 循环依赖/通知分发/课表写入口

P0-3: 修复 shared/lib <-> auth 循环依赖
- audit-logger.ts, change-logger.ts, auth-guard.ts, classes/data-access.ts
  改用动态 import("@/auth") 打破静态模块级循环依赖
- shared/lib 不再静态导入 @/auth

P0-5: messaging 改用 notifications dispatcher
- messaging/actions.ts 的 sendMessageAction 改用 sendNotification
  替代直接调用 createNotification
- 用户通知偏好(SMS/微信/邮件/站内)现在被正确尊重

P0-6: 统一 classSchedule 写入口到 scheduling/data-access
- 新增 insertClassScheduleItem/updateClassScheduleItemById/
  deleteClassScheduleItemById/replaceClassSchedule 统一写入函数
- classes/data-access.ts 的三个 schedule 写入函数委托给 scheduling
- scheduling/actions.ts 的 applyAutoScheduleAction 改用 replaceClassSchedule
- 移除 scheduling/actions.ts 中不再使用的 classSchedule/createId 导入

验证: tsc --noEmit 0 errors, npm run lint 0 errors
This commit is contained in:
SpecialX
2026-06-17 23:44:02 +08:00
parent 02dc1093fb
commit 220061d62e
7 changed files with 155 additions and 31 deletions

View File

@@ -5,7 +5,6 @@ import { cache } from "react"
import { and, asc, desc, eq, inArray, isNull, or, sql, type SQL } from "drizzle-orm"
import { createId } from "@paralleldrive/cuid2"
import { auth } from "@/auth"
import { db } from "@/shared/db"
import {
classes,
@@ -24,6 +23,11 @@ import {
users,
usersToRoles,
} from "@/shared/db/schema"
import {
insertClassScheduleItem,
updateClassScheduleItemById,
deleteClassScheduleItemById,
} from "@/modules/scheduling/data-access"
import { DEFAULT_CLASS_SUBJECTS } from "./types"
import type {
AdminClassListItem,
@@ -47,6 +51,7 @@ import type {
} from "./types"
const getSessionTeacherId = async (): Promise<string | null> => {
const { auth } = await import("@/auth")
const session = await auth()
const userId = String(session?.user?.id ?? "").trim()
if (!userId) return null
@@ -1859,9 +1864,8 @@ export async function createClassScheduleItem(data: CreateClassScheduleItemInput
if (!owned) throw new Error("Class not found")
const id = createId()
await db.insert(classSchedule).values({
id,
// Delegate DB write to scheduling module (unified write entry point)
return insertClassScheduleItem({
classId,
weekday,
startTime,
@@ -1869,8 +1873,6 @@ export async function createClassScheduleItem(data: CreateClassScheduleItemInput
course,
location,
})
return id
}
export async function updateClassScheduleItem(scheduleId: string, data: UpdateClassScheduleItemInput): Promise<void> {
@@ -1944,10 +1946,8 @@ export async function updateClassScheduleItem(scheduleId: string, data: UpdateCl
if (Object.keys(update).length === 0) return
await db
.update(classSchedule)
.set(update)
.where(eq(classSchedule.id, id))
// Delegate DB write to scheduling module (unified write entry point)
await updateClassScheduleItemById(id, update)
}
export async function deleteClassScheduleItem(scheduleId: string): Promise<void> {
@@ -1964,7 +1964,8 @@ export async function deleteClassScheduleItem(scheduleId: string): Promise<void>
if (!owned) throw new Error("Schedule item not found")
await db.delete(classSchedule).where(eq(classSchedule.id, id))
// Delegate DB write to scheduling module (unified write entry point)
await deleteClassScheduleItemById(id)
}
export const getStudentsSubjectScores = cache(