feat(modules): add leave-requests, invitation-codes, and standards modules

- Add leave-requests module for staff and student leave request management

- Add invitation-codes module for class invitation code generation and redemption

- Add standards module for curriculum standards management
This commit is contained in:
SpecialX
2026-07-03 10:24:07 +08:00
parent ac1de9e433
commit 7567f317e1
19 changed files with 3192 additions and 0 deletions

View File

@@ -0,0 +1,68 @@
/**
* M1 课标Standards模块 - Zod 验证 schema
*
* 所有错误消息使用 i18n 键,由 actions 层通过 translateFieldErrors() 翻译。
*/
import { z } from "zod";
export const createStandardSchema = z.object({
code: z.string().min(1, "error.codeRequired").max(100, "error.codeTooLong"),
title: z.string().min(1, "error.titleRequired").max(255, "error.titleTooLong"),
description: z.string().max(2000, "error.descriptionTooLong").optional(),
level: z.enum(["national", "curriculum", "custom"]),
parentId: z.string().optional(),
subjectId: z.string().optional(),
gradeId: z.string().optional(),
stage: z.enum(["primary", "junior_high", "senior_high"]).optional(),
sortOrder: z.number().int().min(0).default(0),
});
export const updateStandardSchema = z.object({
id: z.string().min(1, "error.idRequired"),
title: z.string().min(1, "error.titleRequired").max(255, "error.titleTooLong").optional(),
description: z.string().max(2000, "error.descriptionTooLong").optional(),
parentId: z.string().optional(),
sortOrder: z.number().int().min(0).optional(),
isActive: z.boolean().optional(),
});
export const getStandardsParamsSchema = z.object({
level: z.enum(["national", "curriculum", "custom"]).optional(),
parentId: z.string().optional(),
subjectId: z.string().optional(),
gradeId: z.string().optional(),
stage: z.enum(["primary", "junior_high", "senior_high"]).optional(),
includeInactive: z.boolean().optional(),
asTree: z.boolean().optional(),
});
export const importStandardsSchema = z.object({
standards: z
.array(
z.object({
code: z.string().min(1, "error.codeRequired"),
title: z.string().min(1, "error.titleRequired"),
description: z.string().optional(),
level: z.enum(["national", "curriculum", "custom"]),
parentId: z.string().optional(),
subjectId: z.string().optional(),
gradeId: z.string().optional(),
stage: z.enum(["primary", "junior_high", "senior_high"]).optional(),
sortOrder: z.number().int().min(0).optional(),
}),
)
.min(1, "error.atLeastOneStandard"),
conflictStrategy: z.enum(["skip", "update", "fail"]).default("skip"),
});
export const linkPlanToStandardSchema = z.object({
planId: z.string().min(1, "error.planIdRequired"),
standardId: z.string().min(1, "error.standardIdRequired"),
relationType: z.enum(["primary", "related"]).default("primary"),
});
export type CreateStandardInput = z.infer<typeof createStandardSchema>;
export type UpdateStandardInput = z.infer<typeof updateStandardSchema>;
export type GetStandardsParamsInput = z.infer<typeof getStandardsParamsSchema>;
export type ImportStandardsInputZod = z.infer<typeof importStandardsSchema>;
export type LinkPlanToStandardInput = z.infer<typeof linkPlanToStandardSchema>;