85 lines
3.0 KiB
C#
85 lines
3.0 KiB
C#
using Dapper;
|
|
using GmRelay.DiscordBot.Infrastructure.Discord;
|
|
using GmRelay.Shared.Rendering;
|
|
using Npgsql;
|
|
|
|
namespace GmRelay.DiscordBot.Features.Sessions;
|
|
|
|
public sealed record DiscordDeleteSessionResult(
|
|
string ReplyText,
|
|
SessionBatchViewModel? UpdatedView,
|
|
string? EmptyMessage = null);
|
|
|
|
public sealed class DiscordDeleteSessionHandler(
|
|
NpgsqlDataSource dataSource,
|
|
DiscordPermissionChecker permissionChecker,
|
|
DiscordListSessionsHandler listSessionsHandler,
|
|
ILogger<DiscordDeleteSessionHandler> logger)
|
|
{
|
|
public async Task<DiscordDeleteSessionResult> HandleAsync(
|
|
string guildId,
|
|
string channelId,
|
|
ulong userId,
|
|
ulong resolvedPermissions,
|
|
ulong guildOwnerId,
|
|
Guid sessionId,
|
|
CancellationToken cancellationToken)
|
|
{
|
|
await using var connection = await dataSource.OpenConnectionAsync(cancellationToken);
|
|
|
|
var dbManagerUserIds = await connection.QueryAsync<ulong>(
|
|
@"SELECT CAST(p.external_user_id AS BIGINT)
|
|
FROM group_managers gm
|
|
JOIN players p ON p.id = gm.player_id
|
|
JOIN game_groups g ON g.id = gm.group_id
|
|
WHERE g.platform = 'Discord' AND g.external_group_id = @GuildId",
|
|
new { GuildId = guildId });
|
|
|
|
if (!permissionChecker.CanManageSchedule(guildOwnerId, userId, dbManagerUserIds, resolvedPermissions))
|
|
{
|
|
return new DiscordDeleteSessionResult(
|
|
"Только owner, администратор или manager могут удалять сессии.",
|
|
UpdatedView: null);
|
|
}
|
|
|
|
await using var transaction = await connection.BeginTransactionAsync(cancellationToken);
|
|
var deletedRows = await connection.ExecuteAsync(
|
|
"""
|
|
DELETE FROM sessions s
|
|
USING game_groups g
|
|
WHERE s.group_id = g.id
|
|
AND s.id = @SessionId
|
|
AND g.platform = 'Discord'
|
|
AND g.external_group_id = @GuildId
|
|
""",
|
|
new { SessionId = sessionId, GuildId = guildId },
|
|
transaction);
|
|
|
|
await transaction.CommitAsync(cancellationToken);
|
|
|
|
if (deletedRows == 0)
|
|
{
|
|
return new DiscordDeleteSessionResult(
|
|
"Сессия не найдена или уже удалена.",
|
|
UpdatedView: null);
|
|
}
|
|
|
|
logger.LogInformation("Deleted Discord session {SessionId} in guild {GuildId}", sessionId, guildId);
|
|
|
|
var updatedView = await listSessionsHandler.BuildScheduleAsync(
|
|
guildId,
|
|
channelId,
|
|
userId,
|
|
resolvedPermissions,
|
|
guildOwnerId,
|
|
cancellationToken);
|
|
|
|
return updatedView is null
|
|
? new DiscordDeleteSessionResult(
|
|
"Сессия удалена.",
|
|
UpdatedView: null,
|
|
EmptyMessage: "В этом сервере нет предстоящих игр.")
|
|
: new DiscordDeleteSessionResult("Сессия удалена.", updatedView);
|
|
}
|
|
}
|