namespace OpenNest.Data;
///
/// Bounds shared by the drawing set client and server. The client checks them before
/// sending; the server refuses anything outside them with no state change. Whether each
/// member's drawing exists is checked by the server.
///
public static class DrawingSetRules
{
public const int MaxMembers = 500;
public const int MaxQuantity = 100_000;
/// Largest accepted set JSON body (1 MiB): room for members echoed with their drawings.
public const int MaxBodyBytes = 1024 * 1024;
/// The first rule breaks, or null when it may be saved.
public static string? GetError(DrawingSetRecord? record)
{
if (record is null)
return "Missing set.";
if (string.IsNullOrWhiteSpace(record.Name))
return "name is required.";
var error = DrawingLibraryRules.TextError("name", record.Name, DrawingLibraryRules.MaxTextLength)
?? DrawingLibraryRules.TextError("customer", record.Customer, DrawingLibraryRules.MaxTextLength)
?? DrawingLibraryRules.TextError("savedBy", record.SavedBy, DrawingLibraryRules.MaxTextLength)
?? DrawingLibraryRules.TextError("notes", record.Notes, DrawingLibraryRules.MaxNotesLength);
if (error is not null)
return error;
if (record.Members is null)
return "members is required.";
if (record.Members.Count > MaxMembers)
return $"A set may have at most {MaxMembers} members.";
var seen = new HashSet();
for (var i = 0; i < record.Members.Count; i++)
{
var member = record.Members[i];
if (member is null)
return $"members[{i}] is required.";
if (member.DrawingId == Guid.Empty)
return $"members[{i}].drawingId is required.";
if (member.Quantity < 1 || member.Quantity > MaxQuantity)
return $"members[{i}].quantity must be between 1 and {MaxQuantity}.";
if (!seen.Add(member.DrawingId))
return $"members[{i}] repeats drawing {member.DrawingId}: use one member with a larger quantity.";
}
return null;
}
}