namespace SVSim.Database.Services.Guild; public sealed record ChatWindow(IReadOnlyList Messages, int WaitIntervalSeconds); public sealed record ChatPostResult(bool Ok, int? AssignedMessageId); public interface IGuildChatService { Task GetWindowAsync(long viewerId, int startMessageId, int direction, int waitIntervalHint, CancellationToken ct = default); Task PostTextOrStampAsync(long viewerId, int type, string message, CancellationToken ct = default); Task PostDeckAsync(long viewerId, string deckPayloadJson, CancellationToken ct = default); Task DeleteDeckAsync(long viewerId, int messageId, CancellationToken ct = default); Task PostReplayAsync(long viewerId, string replayPayloadJson, CancellationToken ct = default); Task GetReplayDetailAsync(long viewerId, int messageId, CancellationToken ct = default); Task GetDeckLogAsync(long viewerId, int messageId, CancellationToken ct = default); /// Emit a system-event row. Called by IGuildService at create/join/leave/remove/role-change/description-change. Task EmitSystemEventAsync(int guildId, long actorViewerId, Entities.Guild.GuildChatMessageType type, string? body = null, CancellationToken ct = default); }