using Extrudex.API.DTOs.PrintJobs; using FluentValidation; namespace Extrudex.API.Validators; /// /// Validation rules for creating a PrintJob. /// public class CreatePrintJobRequestValidator : AbstractValidator { private static readonly string[] ValidDataSources = { "Mqtt", "Moonraker", "Manual" }; public CreatePrintJobRequestValidator() { RuleFor(x => x.PrinterId) .NotEmpty().WithMessage("PrinterId is required."); RuleFor(x => x.SpoolId) .NotEmpty().WithMessage("SpoolId is required."); RuleFor(x => x.PrintName) .NotEmpty().WithMessage("PrintName is required.") .MaximumLength(200).WithMessage("PrintName must not exceed 200 characters."); RuleFor(x => x.MmExtruded) .GreaterThanOrEqualTo(0).WithMessage("MmExtruded must be non-negative."); RuleFor(x => x.GramsDerived) .GreaterThanOrEqualTo(0).WithMessage("GramsDerived must be non-negative."); RuleFor(x => x.DataSource) .Must(x => ValidDataSources.Contains(x, StringComparer.OrdinalIgnoreCase)) .WithMessage("DataSource must be 'Mqtt', 'Moonraker', or 'Manual'."); RuleFor(x => x.FilamentDiameterAtPrintMm) .GreaterThan(0).WithMessage("Filament diameter must be greater than zero."); RuleFor(x => x.MaterialDensityAtPrint) .GreaterThan(0).WithMessage("Material density must be greater than zero."); When(x => x.GcodeFilePath != null, () => { RuleFor(x => x.GcodeFilePath!) .MaximumLength(500).WithMessage("G-code file path must not exceed 500 characters."); }); When(x => x.Notes != null, () => { RuleFor(x => x.Notes!) .MaximumLength(2000).WithMessage("Notes must not exceed 2000 characters."); }); } } /// /// Validation rules for updating a PrintJob. /// public class UpdatePrintJobRequestValidator : AbstractValidator { public UpdatePrintJobRequestValidator() { RuleFor(x => x.PrinterId) .NotEmpty().WithMessage("PrinterId is required."); RuleFor(x => x.SpoolId) .NotEmpty().WithMessage("SpoolId is required."); RuleFor(x => x.PrintName) .NotEmpty().WithMessage("PrintName is required.") .MaximumLength(200).WithMessage("PrintName must not exceed 200 characters."); RuleFor(x => x.MmExtruded) .GreaterThanOrEqualTo(0).WithMessage("MmExtruded must be non-negative."); RuleFor(x => x.GramsDerived) .GreaterThanOrEqualTo(0).WithMessage("GramsDerived must be non-negative."); When(x => x.GcodeFilePath != null, () => { RuleFor(x => x.GcodeFilePath!) .MaximumLength(500).WithMessage("G-code file path must not exceed 500 characters."); }); When(x => x.Notes != null, () => { RuleFor(x => x.Notes!) .MaximumLength(2000).WithMessage("Notes must not exceed 2000 characters."); }); } } /// /// Validation rules for updating a PrintJob status. /// public class UpdatePrintJobStatusRequestValidator : AbstractValidator { private static readonly string[] ValidStatuses = { "Queued", "Printing", "Completed", "Cancelled", "Failed" }; public UpdatePrintJobStatusRequestValidator() { RuleFor(x => x.Status) .NotEmpty().WithMessage("Status is required.") .Must(x => ValidStatuses.Contains(x, StringComparer.OrdinalIgnoreCase)) .WithMessage("Status must be one of: Queued, Printing, Completed, Cancelled, Failed."); } }