using DocumentOperator.Application.SwissQrCode.Queries; using FluentValidation; namespace DocumentOperator.Application.SwissQrCode.Queries; /// /// Validates ExtractSwissQrCodeQuery before handler execution. /// Ensures exactly ONE input method is provided (either PdfBytes OR Base64Pdf, not both, not none). /// public sealed class ExtractSwissQrCodeQueryValidator : AbstractValidator { public ExtractSwissQrCodeQueryValidator() { RuleFor(x => x) .Must(HasExactlyOneInput) .WithMessage("Either PdfBytes or Base64Pdf must be provided, but not both"); // Validate Base64 format if provided When(x => !string.IsNullOrWhiteSpace(x.Base64Pdf), () => { RuleFor(x => x.Base64Pdf) .Must(BeValidBase64) .WithMessage("Invalid Base64 format"); }); // Validate byte array if provided When(x => x.PdfBytes != null, () => { RuleFor(x => x.PdfBytes) .NotEmpty() .WithMessage("PdfBytes cannot be empty"); }); } private static bool HasExactlyOneInput(ExtractSwissQrCodeQuery request) { var hasPdfBytes = request.PdfBytes != null && request.PdfBytes.Length > 0; var hasBase64 = !string.IsNullOrWhiteSpace(request.Base64Pdf); // XOR: exactly one must be true return hasPdfBytes ^ hasBase64; } private static bool BeValidBase64(string? base64) { if (string.IsNullOrWhiteSpace(base64)) return false; try { Convert.FromBase64String(base64); return true; } catch (FormatException) { return false; } } }