namespace MoShiro.Backend.Api; /// IPv6 诊断只含配置与网络状态,不包含任一种 IP 地址。 public sealed record AgentIpv6Dto(string AgentId, string Name, bool Online, Ipv6DiagnosticDto Ipv6); /// 汇总:整个时间段由累加器精确合并得出的值(不是各点的平均)。 public sealed record SummaryDto(IReadOnlyDictionary Metrics, IReadOnlyDictionary Samples, double Coverage); public sealed record EdgePartialDto(bool First, bool Last); public sealed record GapDto(DateTimeOffset From, DateTimeOffset To, string Reason); public sealed record EventDto(long Id, string? AgentId, string Kind, DateTimeOffset At, string? Detail); public sealed record TestSummaryDto(string Id, string Plan, string Status, DateTimeOffset RequestedAt, DateTimeOffset? FinishedAt); public sealed record OverviewLineDto( string Id, string AgentId, string ProbeId, string ProbeName, string Name, IReadOnlyList Labels, bool Online, bool ProbeConnected, int EndpointChanges, SummaryDto Summary, TestSummaryDto? LastTest, string IpVersion = "ipv4"); public sealed record OverviewDto(string Range, DateTimeOffset From, DateTimeOffset To, string Step, string Source, bool Degraded, IReadOnlyList Lines); /// 列式响应:时间轴 t(Unix 毫秒)只出现一次,values 里每个数组的长度都与 t 相同;没有数据的桶是 null。 public sealed record SeriesDto( string LineId, string AgentId, string ProbeId, DateTimeOffset From, DateTimeOffset To, string Step, string Source, bool Live, bool Degraded, IReadOnlyList T, IReadOnlyDictionary Values, SummaryDto Summary, EdgePartialDto EdgePartial, IReadOnlyList Gaps, IReadOnlyList Events, IReadOnlyDictionary Versions, string IpVersion = "ipv4"); public sealed record CompareDto( string Metric, DateTimeOffset From, DateTimeOffset To, string Step, string Source, bool Degraded, IReadOnlyList T, IReadOnlyDictionary Values, IReadOnlyDictionary Summary); public sealed record DistributionBucketDto(double Le, long Count); public sealed record DistributionDto(string Metric, string Unit, IReadOnlyList Buckets, double? P50, double? P95, double? P99, long Count); public sealed record HeatmapDto( string Metric, string Step, string Source, bool Degraded, IReadOnlyList T, IReadOnlyList Edges, IReadOnlyList> Counts); /// 一条线路 = 一对(Agent,Probe);id 是 <agent_id>~<probe_id>。 public sealed record LineDto( string Id, string AgentId, string ProbeId, string ProbeName, string Name, IReadOnlyList Labels, bool Online, bool ProbeConnected, DateTimeOffset? DataSince, IReadOnlyList Kinds, TestSummaryDto? LastTest, string IpVersion = "ipv4", bool Ipv6Available = false); public sealed record DimensionDto(string Id, string Label, double Weight, double? Value, double? Score); public sealed record ScoreDto(double? Score, int Version, bool Estimated, IReadOnlyList Dimensions, IReadOnlyList Caveats); public sealed record TestStepDto(int Index, double TargetMbps, double LossPct, double? JitterP95Ms, double DeliveredMbps); public sealed record TestResultDto( IReadOnlyDictionary Metrics, IReadOnlyDictionary Scores, IReadOnlyDictionary Series, IReadOnlyList Steps, IReadOnlyList Caveats); public sealed record TestDto( string Id, string AgentId, string ProbeId, string Plan, IReadOnlyList Phases, string Status, int? Phase, string? ErrorCode, string Trigger, DateTimeOffset RequestedAt, DateTimeOffset? StartedAt, DateTimeOffset? FinishedAt, TestResultDto? Result, string IpVersion = "ipv4"); // ── 目录(由代码注册表生成) ────────────────────────────────────────── public sealed record ParamDto(string Name, string Type, System.Text.Json.JsonElement Default, double? Min, double? Max, string? Unit, IReadOnlyList? Values, string Description); public sealed record BlocksDto(string Transport, string Pacer, string Payload, string Behavior, IReadOnlyList Samplers); public sealed record ColumnDto(string Name, string Type, string Encoding, bool Nullable, string? Role); public sealed record StreamDto(string Name, IReadOnlyList Columns); public sealed record KindDto(string Id, string Title, string Description, IReadOnlyList Scopes, BlocksDto Blocks, IReadOnlyList Params, IReadOnlyList Streams); public sealed record PhaseDto(string Kind, int DurationS, System.Text.Json.JsonElement Params); public sealed record PlanDto(string Id, string Title, string Description, IReadOnlyList Phases); public sealed record MetricDto( string Id, string DefinitionId, string Accumulator, string Stat, string Label, string Description, string Unit, string Better, double? Good, double? Poor, string Version, IReadOnlyList From); public sealed record PresetDto(string Id, string Label, IReadOnlyList Metrics); public sealed record ModelDto(string Id, string Title, int Version, IReadOnlyList Needs); public sealed record LiveNodeDto(string Kind, string Id, bool Online, DateTimeOffset At); public sealed record LiveTestDto(string TestId, string Status, int? Phase, int Phases); /// /// 主机资源占用(展示页能拿到的全部内容):只有汇总的数字,没有 CPU 型号、主机名、网卡名,也没有任何 IP 地址。 /// 这些字段 Agent 根本不采集,所以即使这里写漏了也泄漏不出去。 /// public sealed record HostDto( double? CpuPercent, long? MemUsed, long? MemTotal, long? DiskUsed, long? DiskTotal, long? NetRxTotal, long? NetTxTotal, long? NetRxBps, long? NetTxBps, long? NetLinkMbps, long? UptimeSeconds, DateTimeOffset At); /// 一个 Agent 的最新主机状态;stale 表示超过 15 秒没有更新(离线,或者 Agent 关闭了上报)。 /// 节点的展示信息:只有系统、架构、国家代码、运营商,没有任何地址;站点打开「显示构建信息」之后还有版本和 tag。 public sealed record NodeInfoDto(string Id, string Kind, string? Os, string? OsName, string? Arch, string? Country, string? IspKey, string? IspName, string? Version = null, string? Tag = null); /// 一个程序的构建信息:版本、tag、提交(短)和构建时间(UTC,ISO 8601)。没设置的是 null。 public sealed record BuildDto(string Version, string? Tag, string? Commit, string? BuiltAt); /// 公开的「关于」:站点没有打开「显示构建信息」时只有 show_build: false。 public sealed record AboutDto(bool ShowBuild, BuildDto? Backend); public sealed record HostItemDto(string AgentId, string Name, bool Online, bool Stale, DateTimeOffset? LastSeenAt, HostDto? Host); public sealed record LiveHostDto(string AgentId, bool Online, HostDto Host); /// 主机资源占用的历史(列式,按步长取平均)。 public sealed record HostSeriesDto(string AgentId, DateTimeOffset From, DateTimeOffset To, string Step, IReadOnlyList T, IReadOnlyDictionary Values);