namespace WxAgent.Service; public sealed record Page(IReadOnlyList Items, int Limit, int Offset, bool HasMore, int? NextOffset); public sealed record AccountInfo(string AccountId, string? DisplayName, string? WechatId, string? Region, string DataFingerprint, bool IsUiBindingKnown, AccountBinding? Binding = null, string BindingStatus = "Unbound"); public sealed record SessionInfo(string Name, string AutomationId, bool IsCurrent); public sealed record MessageInfo(string Fingerprint, string Type, string? Sender, string? Summary, string? Content); public sealed record ListRequest(int Limit = 50, int Offset = 0, bool IncludeContent = false, string? AccountId = null, string? Session = null); public sealed record OperationSubmitRequest( string? Kind, string? AccountId, string? TargetId, string? Text, string? IdempotencyKey, bool Confirmed, IReadOnlyList? Targets = null, bool StopOnError = true); public sealed record BroadcastItemResult(string TargetId, string State, string? ErrorCode); public sealed record BroadcastResult(IReadOnlyList TargetIds, IReadOnlyList Items, bool Stopped, string? StopReason); public sealed class ReadOnlyRequest { public static (int Limit, int Offset) Page(int limit, int offset) { if (limit is < 1 or > 200 || offset < 0) throw new ServiceException("InvalidPagination", 400, "limit must be 1..200 and offset must be non-negative."); return (limit, offset); } } public static class PageExtensions { public static Page ToPage(this IReadOnlyList values, int limit, int offset) { var items = values.Skip(offset).Take(limit).ToArray(); var hasMore = offset + items.Length < values.Count; return new Page(items, limit, offset, hasMore, hasMore ? offset + items.Length : null); } }