using System.Text.Json; namespace CareFix.Core; public sealed record QueryResult(IReadOnlyList Columns, List Rows, bool Truncated, int DurationMs); public sealed record StepChange(string Table, string PkColumn, string PkValue, string Column, string? ExpectedOld, string? NewValue); public sealed record ValueRead(int Rows, string? Value); public sealed record SchemaColumn(string SchemaName, string TableName, string ColumnName, string DataType, bool IsNullable, bool IsPk); public sealed record SqlLimits(int MaxRowsPerSelect, int SelectTimeoutSeconds, int LockTimeoutMs); /// An error whose message is safe to show to users. Status follows HTTP codes. public sealed class OpsException(int status, string message) : Exception(message) { public int Status { get; } = status; } /// Wire protocol between the CareFix server and the on-prem agent. public static class AgentProtocol { public const string HospitalHeader = "X-CareFix-Hospital"; public const string KeyHeader = "X-CareFix-Agent-Key"; public static readonly JsonSerializerOptions Json = new(JsonSerializerDefaults.Web); public static class Kinds { public const string Select = "select"; public const string AnyRows = "anyRows"; public const string GetValue = "getValue"; public const string GetRow = "getRow"; public const string ApplySteps = "applySteps"; public const string ReadSchema = "readSchema"; public const string Test = "test"; } /// Converts JSON values that came over the wire back to plain CLR values (string, long, decimal, bool, null). public static object? ToPlain(JsonElement e) => e.ValueKind switch { JsonValueKind.Null or JsonValueKind.Undefined => null, JsonValueKind.String => e.GetString(), JsonValueKind.True => true, JsonValueKind.False => false, JsonValueKind.Number => e.TryGetInt64(out var l) ? l : e.TryGetDecimal(out var d) ? d : e.GetDouble(), _ => e.GetRawText(), }; } public sealed record AgentPoll(string Version, string MachineName); public sealed record AgentJob(long JobId, string Kind, JsonElement Payload); public sealed record AgentResult(bool Ok, JsonElement? Result, int? ErrorStatus, string? Error); public sealed record SelectPayload(string Sql); public sealed record AnyRowsPayload(string Sql, string PkValue); public sealed record ValuePayload(string Table, string PkColumn, string PkValue, string Column); public sealed record RowPayload(string Table, string PkColumn, string PkValue); public sealed record ApplyPayload(List Steps, string TicketRef); public sealed record SelectResultDto(List Columns, List Rows, bool Truncated, int DurationMs);