using FluentValidation.Results; using SeaHaven.Services.DTOs; namespace SeaHaven.Services.Validation { /// /// SH-138 site-contact request validation shared by location create and update. /// Null contacts means legacy behavior (no validation, no mutation); /// a present array must contain 1..20 complete rows. /// public static class SiteContactsValidation { public const int MaxContacts = 20; public const int MaxNameLength = 100; public const int MaxPhoneLength = 20; public static List Validate(IReadOnlyList contacts) { var failures = new List(); if (contacts.Count == 0) { failures.Add(new ValidationFailure( nameof(LocationCreateRequestDTO.Contacts), "Contacts must contain at least one contact when provided.")); return failures; } if (contacts.Count > MaxContacts) { failures.Add(new ValidationFailure( nameof(LocationCreateRequestDTO.Contacts), $"Contacts cannot exceed {MaxContacts} entries.")); return failures; } var seenIds = new HashSet(); for (var i = 0; i < contacts.Count; i++) { var row = contacts[i]; var name = row.Name?.Trim(); var phone = row.Phone?.Trim(); if (string.IsNullOrWhiteSpace(name)) { failures.Add(new ValidationFailure( $"{nameof(LocationCreateRequestDTO.Contacts)}[{i}].{nameof(SiteContactRequestDTO.Name)}", "Contact name is required.")); } else if (name.Length > MaxNameLength) { failures.Add(new ValidationFailure( $"{nameof(LocationCreateRequestDTO.Contacts)}[{i}].{nameof(SiteContactRequestDTO.Name)}", $"Contact name cannot exceed {MaxNameLength} characters.")); } if (string.IsNullOrWhiteSpace(phone)) { failures.Add(new ValidationFailure( $"{nameof(LocationCreateRequestDTO.Contacts)}[{i}].{nameof(SiteContactRequestDTO.Phone)}", "Contact phone is required.")); } else if (phone.Length > MaxPhoneLength) { failures.Add(new ValidationFailure( $"{nameof(LocationCreateRequestDTO.Contacts)}[{i}].{nameof(SiteContactRequestDTO.Phone)}", $"Contact phone cannot exceed {MaxPhoneLength} characters.")); } if (row.Id is int id && !seenIds.Add(id)) { failures.Add(new ValidationFailure( $"{nameof(LocationCreateRequestDTO.Contacts)}[{i}].{nameof(SiteContactRequestDTO.Id)}", $"Contact id {id} appears more than once.")); } } return failures; } } }