mirror of
https://github.com/ajisaacs/OpenNest.git
synced 2026-10-27 12:41:06 -04:00
Nest records gain a materialGrade field (server schema v8, blank for existing rows) that is searched, sorted and versioned like the other metadata. The Nest Info dialog gets a grade picker listing the machine configs' grades for the chosen material; density survives only an unchanged name and grade. A blank recorded grade keeps the archive's grade while the name matches, so records saved before v8 do not lose it on open. Saved Nests shows a Grade column. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
62 lines
2.1 KiB
C#
62 lines
2.1 KiB
C#
using System.Text.Json;
|
|
using System.Text.Json.Serialization;
|
|
using OpenNest.Data;
|
|
|
|
namespace OpenNest.Server;
|
|
|
|
/// <summary>
|
|
/// Reads and checks uploaded nest metadata. Text fields must be present and the status
|
|
/// must be a defined value, so invalid metadata is a 400 and never reaches storage.
|
|
/// </summary>
|
|
internal static class NestMetadata
|
|
{
|
|
// Integer statuses stay accepted for existing callers; GetError refuses undefined ones.
|
|
public static readonly JsonSerializerOptions Options = new(JsonSerializerDefaults.Web)
|
|
{
|
|
PropertyNameCaseInsensitive = true,
|
|
Converters = { new JsonStringEnumConverter(JsonNamingPolicy.CamelCase) },
|
|
};
|
|
|
|
public static bool TryRead(string? json, out NestRecord record, out string error)
|
|
{
|
|
record = new NestRecord();
|
|
if (string.IsNullOrWhiteSpace(json))
|
|
{
|
|
error = "Missing 'metadata' part.";
|
|
return false;
|
|
}
|
|
|
|
try
|
|
{
|
|
if (JsonSerializer.Deserialize<NestRecord>(json, Options) is not { } parsed)
|
|
{
|
|
error = "Missing metadata.";
|
|
return false;
|
|
}
|
|
|
|
record = parsed;
|
|
}
|
|
catch (JsonException)
|
|
{
|
|
error = "Invalid metadata JSON.";
|
|
return false;
|
|
}
|
|
|
|
error = GetError(record) ?? "";
|
|
return error.Length == 0;
|
|
}
|
|
|
|
public static string? GetError(NestRecord record)
|
|
{
|
|
if (record.Name is null) return "name must be a string.";
|
|
if (record.Customer is null) return "customer must be a string.";
|
|
if (record.Material is null) return "material must be a string.";
|
|
if (record.MaterialGrade is null) return "materialGrade must be a string.";
|
|
if (record.Comments is null) return "comments must be a string.";
|
|
if (record.MadeBy is null) return "madeBy must be a string.";
|
|
if (!Enum.IsDefined(record.Status)) return "status must be draft, quote, toBeCut or hasBeenCut.";
|
|
if (!double.IsFinite(record.Thickness)) return "thickness must be a finite number.";
|
|
return null;
|
|
}
|
|
}
|