feat(site-runtime): persist native-alarm display metadata so rehydrated conditions render fully (UA4)
This commit is contained in:
@@ -152,6 +152,7 @@ public class SiteStorageService
|
||||
source_reference TEXT NOT NULL,
|
||||
condition_json TEXT NOT NULL,
|
||||
last_transition_at TEXT NOT NULL,
|
||||
metadata_json TEXT,
|
||||
PRIMARY KEY (instance_unique_name, source_canonical_name, source_reference)
|
||||
);
|
||||
";
|
||||
@@ -169,6 +170,10 @@ public class SiteStorageService
|
||||
// (added in primary/backup data connections feature)
|
||||
await TryAddColumnAsync(connection, "data_connection_definitions", "backup_configuration", "TEXT");
|
||||
await TryAddColumnAsync(connection, "data_connection_definitions", "failover_retry_count", "INTEGER NOT NULL DEFAULT 3");
|
||||
|
||||
// Native-alarm display metadata (UA4) — restored on rehydration so a persisted condition
|
||||
// renders fully (type/category/message/values) before the first source snapshot arrives.
|
||||
await TryAddColumnAsync(connection, "native_alarm_state", "metadata_json", "TEXT");
|
||||
}
|
||||
|
||||
private async Task TryAddColumnAsync(SqliteConnection connection, string table, string column, string type)
|
||||
@@ -483,7 +488,7 @@ public class SiteStorageService
|
||||
/// <returns>A task that completes when the alarm condition has been inserted or updated.</returns>
|
||||
public async Task UpsertNativeAlarmAsync(
|
||||
string instanceName, string sourceCanonicalName, string sourceReference,
|
||||
string conditionJson, DateTimeOffset lastTransitionAt)
|
||||
string conditionJson, DateTimeOffset lastTransitionAt, string? metadataJson = null)
|
||||
{
|
||||
await using var connection = new SqliteConnection(_connectionString);
|
||||
await connection.OpenAsync();
|
||||
@@ -491,17 +496,19 @@ public class SiteStorageService
|
||||
await using var command = connection.CreateCommand();
|
||||
command.CommandText = @"
|
||||
INSERT INTO native_alarm_state
|
||||
(instance_unique_name, source_canonical_name, source_reference, condition_json, last_transition_at)
|
||||
VALUES (@name, @source, @ref, @json, @at)
|
||||
(instance_unique_name, source_canonical_name, source_reference, condition_json, last_transition_at, metadata_json)
|
||||
VALUES (@name, @source, @ref, @json, @at, @meta)
|
||||
ON CONFLICT(instance_unique_name, source_canonical_name, source_reference) DO UPDATE SET
|
||||
condition_json = excluded.condition_json,
|
||||
last_transition_at = excluded.last_transition_at";
|
||||
last_transition_at = excluded.last_transition_at,
|
||||
metadata_json = excluded.metadata_json";
|
||||
|
||||
command.Parameters.AddWithValue("@name", instanceName);
|
||||
command.Parameters.AddWithValue("@source", sourceCanonicalName);
|
||||
command.Parameters.AddWithValue("@ref", sourceReference);
|
||||
command.Parameters.AddWithValue("@json", conditionJson);
|
||||
command.Parameters.AddWithValue("@at", lastTransitionAt.ToString("O"));
|
||||
command.Parameters.AddWithValue("@meta", (object?)metadataJson ?? DBNull.Value);
|
||||
|
||||
await command.ExecuteNonQueryAsync();
|
||||
}
|
||||
@@ -518,7 +525,7 @@ public class SiteStorageService
|
||||
/// <returns>A task that completes when all rows have been committed.</returns>
|
||||
public async Task UpsertNativeAlarmsAsync(
|
||||
string instanceName, string sourceCanonicalName,
|
||||
IReadOnlyList<(string SourceReference, string ConditionJson, DateTimeOffset LastTransitionAt)> rows)
|
||||
IReadOnlyList<(string SourceReference, string ConditionJson, string? MetadataJson, DateTimeOffset LastTransitionAt)> rows)
|
||||
{
|
||||
if (rows.Count == 0)
|
||||
return;
|
||||
@@ -531,17 +538,19 @@ public class SiteStorageService
|
||||
command.Transaction = transaction;
|
||||
command.CommandText = @"
|
||||
INSERT INTO native_alarm_state
|
||||
(instance_unique_name, source_canonical_name, source_reference, condition_json, last_transition_at)
|
||||
VALUES (@name, @source, @ref, @json, @at)
|
||||
(instance_unique_name, source_canonical_name, source_reference, condition_json, last_transition_at, metadata_json)
|
||||
VALUES (@name, @source, @ref, @json, @at, @meta)
|
||||
ON CONFLICT(instance_unique_name, source_canonical_name, source_reference) DO UPDATE SET
|
||||
condition_json = excluded.condition_json,
|
||||
last_transition_at = excluded.last_transition_at";
|
||||
last_transition_at = excluded.last_transition_at,
|
||||
metadata_json = excluded.metadata_json";
|
||||
|
||||
var pName = command.Parameters.Add("@name", SqliteType.Text);
|
||||
var pSource = command.Parameters.Add("@source", SqliteType.Text);
|
||||
var pRef = command.Parameters.Add("@ref", SqliteType.Text);
|
||||
var pJson = command.Parameters.Add("@json", SqliteType.Text);
|
||||
var pAt = command.Parameters.Add("@at", SqliteType.Text);
|
||||
var pMeta = command.Parameters.Add("@meta", SqliteType.Text);
|
||||
pName.Value = instanceName;
|
||||
pSource.Value = sourceCanonicalName;
|
||||
|
||||
@@ -550,6 +559,7 @@ public class SiteStorageService
|
||||
pRef.Value = row.SourceReference;
|
||||
pJson.Value = row.ConditionJson;
|
||||
pAt.Value = row.LastTransitionAt.ToString("O");
|
||||
pMeta.Value = (object?)row.MetadataJson ?? DBNull.Value;
|
||||
await command.ExecuteNonQueryAsync();
|
||||
}
|
||||
|
||||
@@ -595,7 +605,7 @@ public class SiteStorageService
|
||||
|
||||
await using var command = connection.CreateCommand();
|
||||
command.CommandText = @"
|
||||
SELECT source_reference, condition_json, last_transition_at
|
||||
SELECT source_reference, condition_json, last_transition_at, metadata_json
|
||||
FROM native_alarm_state
|
||||
WHERE instance_unique_name = @name AND source_canonical_name = @source";
|
||||
command.Parameters.AddWithValue("@name", instanceName);
|
||||
@@ -608,7 +618,8 @@ public class SiteStorageService
|
||||
results.Add(new NativeAlarmRow(
|
||||
reader.GetString(0),
|
||||
reader.GetString(1),
|
||||
DateTimeOffset.Parse(reader.GetString(2), null, System.Globalization.DateTimeStyles.RoundtripKind)));
|
||||
DateTimeOffset.Parse(reader.GetString(2), null, System.Globalization.DateTimeStyles.RoundtripKind),
|
||||
reader.IsDBNull(3) ? null : reader.GetString(3)));
|
||||
}
|
||||
|
||||
return results;
|
||||
@@ -1020,5 +1031,8 @@ public class StoredDataConnectionDefinition
|
||||
|
||||
/// <summary>
|
||||
/// A single mirrored native alarm condition row from the site-local <c>native_alarm_state</c> table.
|
||||
/// <paramref name="MetadataJson"/> carries the serialized display metadata (type/category/message/
|
||||
/// values) restored on rehydration (UA4); null on rows written before the column existed.
|
||||
/// </summary>
|
||||
public record NativeAlarmRow(string SourceReference, string ConditionJson, DateTimeOffset LastTransitionAt);
|
||||
public record NativeAlarmRow(
|
||||
string SourceReference, string ConditionJson, DateTimeOffset LastTransitionAt, string? MetadataJson = null);
|
||||
|
||||
Reference in New Issue
Block a user