130 lines
4.5 KiB
TypeScript
130 lines
4.5 KiB
TypeScript
import { z } from 'zod';
|
|
|
|
export const lessonCreateSchema = z.object({
|
|
parentId: z.number().int().nullable().optional(),
|
|
name: z.string().min(1).max(200),
|
|
description: z.string().max(2000).optional().nullable(),
|
|
bidirectional: z.boolean().optional(),
|
|
});
|
|
|
|
export const lessonUpdateSchema = lessonCreateSchema.partial();
|
|
|
|
export const lessonMoveSchema = z.object({
|
|
parentId: z.number().int().nullable(),
|
|
position: z.number().int().min(0),
|
|
});
|
|
|
|
export const cardCreateSchema = z.object({
|
|
question: z.string().min(1).max(2000),
|
|
answer: z.string().min(1).max(2000),
|
|
hint: z.string().max(2000).optional().nullable(),
|
|
});
|
|
|
|
export const cardUpdateSchema = cardCreateSchema.partial();
|
|
|
|
export const sessionStartSchema = z.object({
|
|
lessonId: z.number().int().positive(),
|
|
maxCards: z.number().int().min(1).max(500).nullable().optional(),
|
|
shuffle: z.boolean().optional(),
|
|
direction: z.enum(['forward', 'backward', 'both']).optional(),
|
|
});
|
|
|
|
export const attemptCreateSchema = z.object({
|
|
cardId: z.number().int().positive(),
|
|
direction: z.enum(['forward', 'backward']),
|
|
result: z.enum(['correct', 'incorrect']),
|
|
timeToAnswerMs: z.number().int().min(0).nullable().optional(),
|
|
});
|
|
|
|
export type LessonCreateInput = z.infer<typeof lessonCreateSchema>;
|
|
export type LessonUpdateInput = z.infer<typeof lessonUpdateSchema>;
|
|
export type LessonMoveInput = z.infer<typeof lessonMoveSchema>;
|
|
export type CardCreateInput = z.infer<typeof cardCreateSchema>;
|
|
export type CardUpdateInput = z.infer<typeof cardUpdateSchema>;
|
|
export type SessionStartInput = z.infer<typeof sessionStartSchema>;
|
|
export type AttemptCreateInput = z.infer<typeof attemptCreateSchema>;
|
|
|
|
export const emailSchema = z.string().email().max(320).transform((v) => v.trim().toLowerCase());
|
|
|
|
export const registerSchema = z.object({
|
|
email: emailSchema,
|
|
displayName: z.string().trim().min(1).max(120),
|
|
password: z.string().min(8).max(200),
|
|
});
|
|
|
|
export const loginSchema = z.object({
|
|
email: emailSchema,
|
|
password: z.string().min(1).max(200),
|
|
});
|
|
|
|
export const forgotPasswordSchema = z.object({ email: emailSchema });
|
|
|
|
export const resetPasswordSchema = z.object({
|
|
token: z.string().min(20).max(200),
|
|
password: z.string().min(8).max(200),
|
|
});
|
|
|
|
export const verifyEmailSchema = z.object({
|
|
token: z.string().min(20).max(200),
|
|
});
|
|
|
|
export const resendVerificationSchema = z.object({ email: emailSchema });
|
|
|
|
export const profileUpdateSchema = z.object({
|
|
displayName: z.string().trim().min(1).max(120).optional(),
|
|
email: emailSchema.optional(),
|
|
});
|
|
|
|
export const changePasswordSchema = z.object({
|
|
currentPassword: z.string().min(1).max(200),
|
|
newPassword: z.string().min(8).max(200),
|
|
});
|
|
|
|
export const acceptInviteSchema = z.object({
|
|
token: z.string().min(20).max(200),
|
|
displayName: z.string().trim().min(1).max(120),
|
|
password: z.string().min(8).max(200),
|
|
});
|
|
|
|
export const inviteUserSchema = z.object({
|
|
email: emailSchema,
|
|
role: z.enum(['user', 'sysadmin']).default('user'),
|
|
});
|
|
|
|
export const adminUserUpdateSchema = z.object({
|
|
displayName: z.string().trim().min(1).max(120).optional(),
|
|
role: z.enum(['user', 'sysadmin']).optional(),
|
|
isActive: z.boolean().optional(),
|
|
});
|
|
|
|
export type RegisterInput = z.infer<typeof registerSchema>;
|
|
export type LoginInput = z.infer<typeof loginSchema>;
|
|
export type ForgotPasswordInput = z.infer<typeof forgotPasswordSchema>;
|
|
export type ResetPasswordInput = z.infer<typeof resetPasswordSchema>;
|
|
export type VerifyEmailInput = z.infer<typeof verifyEmailSchema>;
|
|
export type ResendVerificationInput = z.infer<typeof resendVerificationSchema>;
|
|
export type ProfileUpdateInput = z.infer<typeof profileUpdateSchema>;
|
|
export type ChangePasswordInput = z.infer<typeof changePasswordSchema>;
|
|
export type AcceptInviteInput = z.infer<typeof acceptInviteSchema>;
|
|
export type InviteUserInput = z.infer<typeof inviteUserSchema>;
|
|
export type AdminUserUpdateInput = z.infer<typeof adminUserUpdateSchema>;
|
|
|
|
export const lessonVisibilityUpdateSchema = z.object({
|
|
visibility: z.enum(['private', 'shared']),
|
|
});
|
|
|
|
export const adminLessonCuratedSchema = z.object({
|
|
isCurated: z.boolean(),
|
|
});
|
|
|
|
export const marketplaceQuerySchema = z.object({
|
|
q: z.string().trim().max(120).optional(),
|
|
curated: z.enum(['true', 'false']).optional(),
|
|
limit: z.coerce.number().int().min(1).max(100).optional(),
|
|
offset: z.coerce.number().int().min(0).optional(),
|
|
});
|
|
|
|
export type LessonVisibilityUpdateInput = z.infer<typeof lessonVisibilityUpdateSchema>;
|
|
export type AdminLessonCuratedInput = z.infer<typeof adminLessonCuratedSchema>;
|
|
export type MarketplaceQuery = z.infer<typeof marketplaceQuerySchema>;
|