feat(mtconnect): serve DATA_SET/TABLE as compact JSON strings; park EVENT enumerations (#650)

Parser captures Entry/Cell content; the observation index merges /sample deltas
into the /current baseline (resetTriggered replaces, removed deletes, UNAVAILABLE
drops). Fixture gains a TABLE item and periodic DATA_SET/TABLE churn.

Claude-Session: https://claude.ai/code/session_01Ef2ozxS7QPanGT8uoATbTe
This commit is contained in:
Joseph Doherty
2026-10-08 19:15:32 -04:00
parent 8801631739
commit f8f8eb9fb8
11 changed files with 537 additions and 39 deletions
@@ -589,11 +589,12 @@ public sealed class MTConnectObservationIndexTests
/// <summary>
/// End-to-end through the real parser: the entry list that concatenates to the single token
/// "12" is caught by the parser's structured flag and never surfaces as a Good value. This is
/// the leg that would regress silently if the parser stopped setting the flag.
/// "12" must never surface as that noise. Since #650 it is served as JSON carrying the keys
/// (full semantics in <c>MTConnectDataSetTests</c>); the structured-without-entries shape above
/// stays BadNotSupported.
/// </summary>
[Fact]
public void A_parsed_data_set_observation_never_surfaces_as_a_good_value()
public void A_parsed_data_set_observation_never_surfaces_as_concatenated_text()
{
const string xml = """
<MTConnectStreams>
@@ -612,8 +613,8 @@ public sealed class MTConnectObservationIndexTests
var snap = idx.Get("ds1");
snap.StatusCode.ShouldBe(BadNotSupported);
snap.Value.ShouldBeNull();
snap.StatusCode.ShouldBe(Good);
snap.Value.ShouldBe("""{"V1":1,"V2":2}""");
}
/// <summary>An ordinary text observation is not structured — the flag must not be over-applied.</summary>