TODO: Student Import — Cell Validation Refactor¶
File: src/students/students.service.ts — validateData() method (and related helpers)
Problem¶
The current per-cell validation is hand-written with inline checks for each column: required fields, max lengths, date parsing, regex patterns, referent pair logic, etc. This approach:
- Doesn't reuse the existing DTO validation decorators (
@IsDate,@MaxLength,@IsEmail, etc.) - Duplicates business rules that are already expressed in
CreateStudentDto/ scope DTOs - Is brittle — adding a field means updating both the DTO and the import validator separately
- Produces a different error shape than the rest of the API
Goal¶
Replace the manual per-cell validation with a declarative approach that leverages the existing DTO validation pipeline or a shared schema definition, so import validation and API validation stay in sync.
Ideas to Explore¶
- Map each parsed row to
CreateStudentDtoviaplainToInstance()+validate(), then collect errors per row/column - Define a shared column-to-field schema that both the import validator and DTOs derive from
- Use a validation library (e.g., zod, class-validator bulk mode) that can validate an array of rows and return structured per-cell errors
- Keep the import-specific error response shape (
{ column, rows, reason, allowedValues }) but generate it from DTO validation errors
Scope¶
validateData()— the main validation loopvalidateHeaders()— header matching (likely stays as-is)- Error response shape —
ImportValidationErrorwith compressed row ranges (keep this UX) - Referent pair cross-column validation — custom logic that doesn't map to a single DTO field