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; export type LessonUpdateInput = z.infer; export type LessonMoveInput = z.infer; export type CardCreateInput = z.infer; export type CardUpdateInput = z.infer; export type SessionStartInput = z.infer; export type AttemptCreateInput = z.infer; 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; export type LoginInput = z.infer; export type ForgotPasswordInput = z.infer; export type ResetPasswordInput = z.infer; export type VerifyEmailInput = z.infer; export type ResendVerificationInput = z.infer; export type ProfileUpdateInput = z.infer; export type ChangePasswordInput = z.infer; export type AcceptInviteInput = z.infer; export type InviteUserInput = z.infer; export type AdminUserUpdateInput = z.infer; 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; export type AdminLessonCuratedInput = z.infer; export type MarketplaceQuery = z.infer;