validate shares Read's post-load composition; products, key, price rules pinned beyond the first product

ShipAuthoringStore.ValidateLoaded is the one composition of hull Validate and ValidateProducts;
Read and the draft branch of ship-authoring validate both call it (ValidateProducts is private).
Tests: a draft with an unnamed hull is refused; blank product name and key collision with the
offending product not first (both makers in turn); a negative hull price refused.
Builds untested here; the verify job runs at the end.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Meta Vens 2026-10-12 20:00:18 +02:00
commit 96bbaa6320
3 changed files with 35 additions and 11 deletions

View file

@ -205,13 +205,19 @@ public static class ShipAuthoringStore
public static (HullData Hull, ShipAuthoring Visual, FactionProductData[] Products) Read(string path)
{
var (hull, visual, products) = Load(path);
Validate(hull, visual);
ValidateProducts(hull, visual, products);
ValidateLoaded(hull, visual, products);
return (hull, visual, products);
}
// Every judgement a loaded package's records face, in one place: Read, and validate on a draft with no model yet, call it.
public static void ValidateLoaded(HullData hull, ShipAuthoring visual, FactionProductData[] products)
{
Validate(hull, visual);
ValidateProducts(hull, visual, products);
}
// What a package may sell: every product named, no name twice, and a price above 0, because generation skips price 0.
public static void ValidateProducts(HullData hull, ShipAuthoring visual, FactionProductData[] products)
private static void ValidateProducts(HullData hull, ShipAuthoring visual, FactionProductData[] products)
{
if (products.Length == 0) return;
if (products.Any(product => string.IsNullOrWhiteSpace(product.Name)))