feat(mesh-phase4): LocalDb alarm-condition-state store (replicated, pair-local)

Claude-Session: https://claude.ai/code/session_01GASWkNEi68FSCtvr6rLoEW
This commit is contained in:
Joseph Doherty
2026-07-23 12:19:44 -04:00
parent 34b613d942
commit 4f4cdd05ec
7 changed files with 754 additions and 5 deletions
@@ -46,7 +46,7 @@ public sealed class LocalDbSetupTests : IDisposable
}
[Fact]
public void OnReady_RegistersExactlyTheThreeReplicatedTables()
public void OnReady_RegistersExactlyTheFourReplicatedTables()
{
// Both directions are load-bearing. "No fewer" catches a dropped RegisterReplicated call
// (that table then never replicates). "No more" catches an accidental registration —
@@ -54,7 +54,7 @@ public sealed class LocalDbSetupTests : IDisposable
var db = BuildDb();
db.ReplicatedTables.Keys.OrderBy(k => k, StringComparer.Ordinal)
.ShouldBe(["alarm_sf_events", "deployment_artifacts", "deployment_pointer"]);
.ShouldBe(["alarm_condition_state", "alarm_sf_events", "deployment_artifacts", "deployment_pointer"]);
}
[Fact]
@@ -89,6 +89,16 @@ public sealed class LocalDbSetupTests : IDisposable
db.ReplicatedTables["alarm_sf_events"].PkColumns.ShouldBe(["id"]);
}
[Fact]
public void AlarmConditionState_PkIsTheScriptedAlarmId()
{
// One condition-state row per alarm identity. The pair's two nodes converge on the same row
// under LWW rather than each keeping its own, and Save is an unconditional upsert onto it.
var db = BuildDb();
db.ReplicatedTables["alarm_condition_state"].PkColumns.ShouldBe(["scripted_alarm_id"]);
}
[Fact]
public async Task AlarmSfEventRows_EnterTheOplog()
{