This document provides a comprehensive overview of all validation rules implemented across the College ERP system using Joi validation schemas.
All request validation in the system is performed using Joi validation schemas. Each module has its own validation file containing schemas for different operations.
{
name: Joi.string().min(2).max(100).required(),
email: Joi.string().email().required(),
phone: Joi.string().min(10).max(15).required(),
dob: Joi.date().iso().optional(),
guardianName: Joi.string().max(100).optional(),
address: Joi.string().max(500).optional(),
courseId: Joi.string().uuid().required(),
sessionId: Joi.string().uuid().required()
}Validation Rules:
name: Required, string, 2-100 charactersemail: Required, valid email formatphone: Required, string, 10-15 charactersdob: Optional, valid ISO date formatguardianName: Optional, string, max 100 charactersaddress: Optional, string, max 500 characterscourseId: Required, valid UUID formatsessionId: Required, valid UUID format
{
name: Joi.string().min(2).max(100).optional(),
phone: Joi.string().min(10).max(15).optional(),
dob: Joi.date().iso().optional(),
guardianName: Joi.string().max(100).optional(),
address: Joi.string().max(500).optional()
}Validation Rules:
- All fields are optional
- Same validation rules as create, but optional
{
semesterId: Joi.string().uuid().required(),
startDate: Joi.date().iso().required(),
endDate: Joi.date().iso().optional()
}Validation Rules:
semesterId: Required, valid UUID formatstartDate: Required, valid ISO date formatendDate: Optional, valid ISO date format
{
name: Joi.string().min(2).max(100).required(),
code: Joi.string().max(20).optional(),
description: Joi.string().max(500).optional()
}Validation Rules:
name: Required, string, 2-100 characterscode: Optional, string, max 20 charactersdescription: Optional, string, max 500 characters
{
name: Joi.string().min(2).max(100).optional(),
code: Joi.string().max(20).optional(),
description: Joi.string().max(500).optional()
}Validation Rules:
- All fields are optional
- Same validation rules as create
{
code: Joi.string().max(20).required(),
name: Joi.string().min(2).max(100).required(),
durationYears: Joi.number().integer().min(1).max(8).required(),
departmentId: Joi.string().uuid().required()
}Validation Rules:
code: Required, string, max 20 charactersname: Required, string, 2-100 charactersdurationYears: Required, integer, 1-8 yearsdepartmentId: Required, valid UUID format
{
code: Joi.string().max(20).optional(),
name: Joi.string().min(2).max(100).optional(),
durationYears: Joi.number().integer().min(1).max(8).optional(),
departmentId: Joi.string().uuid().optional()
}Validation Rules:
- All fields are optional
- Same validation rules as create, but optional
{
code: Joi.string().min(2).max(20).required(),
name: Joi.string().min(2).max(100).required(),
credit: Joi.number().integer().min(1).max(10).required(),
semesterId: Joi.string().uuid().required(),
courseId: Joi.string().uuid().required()
}Validation Rules:
code: Required, string, 2-20 charactersname: Required, string, 2-100 characterscredit: Required, integer, 1-10 creditssemesterId: Required, valid UUID formatcourseId: Required, valid UUID format
{
code: Joi.string().min(2).max(20).optional(),
name: Joi.string().min(2).max(100).optional(),
credit: Joi.number().integer().min(1).max(10).optional(),
semesterId: Joi.string().uuid().optional(),
courseId: Joi.string().uuid().optional()
}Validation Rules:
- All fields are optional
- Same validation rules as create, but optional
{
number: Joi.number().integer().min(1).max(12).required(),
courseId: Joi.string().uuid().required()
}Validation Rules:
number: Required, integer, 1-12courseId: Required, valid UUID format
{
studentId: Joi.string().uuid().required(),
courseId: Joi.string().uuid().required()
}Validation Rules:
studentId: Required, valid UUID formatcourseId: Required, valid UUID format
{
status: Joi.string().valid('APPROVED', 'REJECTED', 'CANCELLED').required(),
notes: Joi.string().max(1000).optional()
}Validation Rules:
status: Required, must be one of 'APPROVED', 'REJECTED', 'CANCELLED'notes: Optional, string, max 1000 characters
{
title: Joi.string().min(2).max(200).required(),
courseId: Joi.string().uuid().required(),
departmentId: Joi.string().uuid().required(),
startDate: Joi.date().iso().required(),
endDate: Joi.date().iso().required()
}Validation Rules:
title: Required, string, 2-200 characterscourseId: Required, valid UUID formatdepartmentId: Required, valid UUID formatstartDate: Required, valid ISO date formatendDate: Required, valid ISO date format
{
title: Joi.string().min(2).max(200).optional(),
startDate: Joi.date().iso().optional(),
endDate: Joi.date().iso().optional(),
enabled: Joi.boolean().optional()
}Validation Rules:
- All fields are optional
- Same validation rules as create, but optional
{
studentId: Joi.string().uuid().required(),
admissionId: Joi.string().uuid().optional(),
totalAmount: Joi.number().precision(2).positive().required(),
status: Joi.string().valid('INITIATED', 'SUCCESS', 'FAILED', 'REFUNDED').required(),
gateway: Joi.string().required(),
txnId: Joi.string().required(),
referenceNo: Joi.string().optional(),
breakups: Joi.array().items(
Joi.object({
head: Joi.string().valid('TUITION', 'EXAM', 'INFRASTRUCTURE', 'DEVELOPMENT', 'CERTIFICATE', 'MISC').required(),
amount: Joi.number().precision(2).positive().required()
})
).required()
}Validation Rules:
studentId: Required, valid UUID formattotalAmount: Required, positive number with 2 decimal placesstatus: Required, must be one of specified valuesgateway: Required, stringtxnId: Required, stringbreakups: Required array of objects with head and amount
{
status: Joi.string().valid('SUCCESS', 'FAILED', 'REFUNDED').required(),
notes: Joi.string().max(1000).optional()
}Validation Rules:
status: Required, must be one of 'SUCCESS', 'FAILED', 'REFUNDED'notes: Optional, string, max 1000 characters
{
amount: Joi.number().precision(2).positive().required(),
reason: Joi.string().max(500).required()
}Validation Rules:
amount: Required, positive number with 2 decimal placesreason: Required, string, max 500 characters
{
type: Joi.string().valid('photo', 'document', 'certificate').required(),
documentType: Joi.string().when('type', {
is: 'document',
then: Joi.string().required(),
otherwise: Joi.string().optional()
}),
studentId: Joi.string().uuid().when('type', {
is: Joi.string().valid('photo', 'document'),
then: Joi.string().uuid().required(),
otherwise: Joi.string().optional()
}),
certificateId: Joi.string().uuid().when('type', {
is: 'certificate',
then: Joi.string().uuid().required(),
otherwise: Joi.string().optional()
})
}Validation Rules:
type: Required, must be 'photo', 'document', or 'certificate'- Conditional validation based on type
{
verified: Joi.boolean().required(),
notes: Joi.string().max(500).optional()
}Validation Rules:
verified: Required, booleannotes: Optional, string, max 500 characters
{
studentId: Joi.string().uuid().required(),
type: Joi.string().valid('BONAFIDE', 'CLC').required(),
purpose: Joi.string().max(500).optional(),
departmentId: Joi.string().uuid().required()
}Validation Rules:
studentId: Required, valid UUID formattype: Required, must be 'BONAFIDE' or 'CLC'departmentId: Required, valid UUID formatpurpose: Optional, string, max 500 characters
{
status: Joi.string().valid('APPROVED', 'REJECTED', 'ISSUED').required(),
notes: Joi.string().max(1000).optional()
}Validation Rules:
status: Required, must be one of 'APPROVED', 'REJECTED', 'ISSUED'notes: Optional, string, max 1000 characters
{
studentId: Joi.string().uuid().optional(),
type: Joi.string().valid('BONAFIDE', 'CLC').optional(),
status: Joi.string().valid('PENDING', 'APPROVED', 'REJECTED', 'ISSUED').optional(),
departmentId: Joi.string().uuid().optional()
}Validation Rules:
- All fields are optional
- Valid values as specified
{
title: Joi.string().min(1).max(200).required(),
coverUrl: Joi.string().uri().optional()
}Validation Rules:
title: Required, string, 1-200 characterscoverUrl: Optional, valid URI format
{
title: Joi.string().min(1).max(200).required(),
body: Joi.string().min(1).max(5000).required(),
isPublished: Joi.boolean().optional(),
url: Joi.string().uri().optional()
}Validation Rules:
title: Required, string, 1-200 charactersbody: Required, string, 1-5000 charactersisPublished: Optional, booleanurl: Optional, valid URI format
{
title: Joi.string().min(1).max(200).required(),
body: Joi.string().min(1).max(2000).required(),
url: Joi.string().uri().optional()
}Validation Rules:
title: Required, string, 1-200 charactersbody: Required, string, 1-2000 charactersurl: Optional, valid URI format
search: Optional, string, max 100 charactersisPublished: Optional, boolean
- All ID fields use
Joi.string().uuid().required()or.optional() - Ensures proper UUID format
- Name fields: 2-100 characters
- Title fields: 1-200 characters
- Description fields: Up to 5000 characters
- Notes fields: Up to 1000 characters
- Amounts:
Joi.number().precision(2).positive() - Years:
Joi.number().integer().min(1).max(8) - Credits:
Joi.number().integer().min(1).max(10) - Semester numbers:
Joi.number().integer().min(1).max(12)
- All dates use
Joi.date().iso().required()or.optional() - Ensures ISO 8601 date format
- All boolean fields use
Joi.boolean().optional()or.required()
- Arrays use
Joi.array().items(schema)with appropriate item validation - Ensures all items in array meet validation requirements
All validation errors return a 400 status code with detailed error messages:
{
"status": "error",
"message": "Validation error: field_name is required, field_name must be at least 2 characters long"
}- Consistency: All validation follows the same patterns across modules
- Security: Input validation prevents injection attacks
- User Experience: Clear, descriptive error messages
- Maintainability: Validation schemas are separate from business logic
- Flexibility: Optional fields allow partial updates
- Type Safety: Strict type checking prevents runtime errors
This validation framework ensures data integrity and security across all modules of the College ERP system.