diff --git a/backend/src/main/java/com/alttd/altitudeweb/services/discord/AppealDiscord.java b/backend/src/main/java/com/alttd/altitudeweb/services/discord/AppealDiscord.java index 9eba222..3301b10 100644 --- a/backend/src/main/java/com/alttd/altitudeweb/services/discord/AppealDiscord.java +++ b/backend/src/main/java/com/alttd/altitudeweb/services/discord/AppealDiscord.java @@ -1,6 +1,8 @@ package com.alttd.altitudeweb.services.discord; import com.alttd.altitudeweb.database.Databases; +import com.alttd.altitudeweb.database.discord.AppealList; +import com.alttd.altitudeweb.database.discord.AppealListMapper; import com.alttd.altitudeweb.database.discord.OutputChannel; import com.alttd.altitudeweb.database.discord.OutputChannelMapper; import com.alttd.altitudeweb.database.litebans.HistoryCountMapper; @@ -8,6 +10,7 @@ import com.alttd.altitudeweb.database.litebans.HistoryRecord; import com.alttd.altitudeweb.database.litebans.HistoryType; import com.alttd.altitudeweb.database.litebans.UserType; import com.alttd.altitudeweb.database.web_db.forms.Appeal; +import com.alttd.altitudeweb.database.web_db.forms.AppealMapper; import com.alttd.altitudeweb.setup.Connection; import com.alttd.webinterface.objects.MessageForEmbed; import com.alttd.webinterface.send_message.DiscordSender; @@ -19,6 +22,8 @@ import java.time.ZoneId; import java.time.format.DateTimeFormatter; import java.util.ArrayList; import java.util.List; +import java.util.Optional; +import java.util.UUID; import java.util.concurrent.CompletableFuture; @Slf4j @@ -88,6 +93,22 @@ public class AppealDiscord { "Kicks: " + kicks, true )); + Optional optionalAssignedTo = assignAppeal(); + if (optionalAssignedTo.isPresent()) { + Long assignedTo = optionalAssignedTo.get(); + fields.add(new DiscordSender.EmbedField( + "Assigned to", + "Assigned to: <@" + assignedTo + ">", + true + )); + assignAppealTo(appeal.id(), assignedTo); + } else { + fields.add(new DiscordSender.EmbedField( + "Assigned to", + "Assigned to: None (failed to assign)", + true + )); + } String description = safe(appeal.reason()); @@ -102,6 +123,16 @@ public class AppealDiscord { DiscordSender.getInstance().sendEmbedWithThreadToChannels(channelIds, newAppealSubmitted, "Appeal"); } + private void assignAppealTo(UUID appealId, Long assignedTo) { + Connection.getConnection(Databases.DEFAULT).runQuery(sql -> { + try { + sql.getMapper(AppealMapper.class).assignAppeal(appealId, assignedTo); + } catch (Exception e) { + log.error("Failed to assign appeal to {}", assignedTo, e); + } + }); + } + private CompletableFuture getCountAsync(HistoryType type, java.util.UUID uuid) { CompletableFuture future = new CompletableFuture<>(); Connection.getConnection(Databases.LITE_BANS).runQuery(sql -> { @@ -126,4 +157,49 @@ public class AppealDiscord { return instant.atZone(ZoneId.of("UTC")) .format(DateTimeFormatter.ofPattern("yyyy MMMM dd hh:mm a '(UTC)'")); } + + private Optional assignAppeal() { + CompletableFuture assignToCompletableFuture = new CompletableFuture<>(); + Connection.getConnection(Databases.DISCORD).runQuery(sql -> { + try { + AppealListMapper mapper = sql.getMapper(AppealListMapper.class); + List appealList = mapper + .getAppealList(); + + + if (appealList.isEmpty()) { + log.warn("No appeal lists found. Skipping assignment."); + assignToCompletableFuture.complete(0L); + return; + } + Optional optionalAssignTo = appealList + .stream() + .filter(AppealList::next).findFirst(); + AppealList assignTo = optionalAssignTo.orElseGet(appealList::getFirst); + assignToCompletableFuture.complete(assignTo.userId()); + + try { + Optional optionalNextAppealList = appealList + .stream() + .filter(entry -> entry.userId() > assignTo.userId()) + .sorted() + .findFirst(); + AppealList nextAppealList = optionalNextAppealList.orElse(appealList.stream().sorted().findFirst().orElse(assignTo)); + mapper.updateNext(assignTo.userId(), false); + mapper.updateNext(nextAppealList.userId(), true); + } catch (Exception e) { + log.error("Failed to assign next appeal", e); + } + + } catch (Exception e) { + log.error("Failed to load appeal list", e); + assignToCompletableFuture.complete(0L); + } + }); + Long assignTo = assignToCompletableFuture.join(); + if (assignTo.equals(0L)) { + return Optional.empty(); + } + return Optional.of(assignTo); + } } diff --git a/database/src/main/java/com/alttd/altitudeweb/database/discord/AppealList.java b/database/src/main/java/com/alttd/altitudeweb/database/discord/AppealList.java new file mode 100644 index 0000000..e82e583 --- /dev/null +++ b/database/src/main/java/com/alttd/altitudeweb/database/discord/AppealList.java @@ -0,0 +1,4 @@ +package com.alttd.altitudeweb.database.discord; + +public record AppealList(Long userId, boolean next) { +} diff --git a/database/src/main/java/com/alttd/altitudeweb/database/discord/AppealListMapper.java b/database/src/main/java/com/alttd/altitudeweb/database/discord/AppealListMapper.java new file mode 100644 index 0000000..cd35acb --- /dev/null +++ b/database/src/main/java/com/alttd/altitudeweb/database/discord/AppealListMapper.java @@ -0,0 +1,25 @@ +package com.alttd.altitudeweb.database.discord; + +import org.apache.ibatis.annotations.Param; +import org.apache.ibatis.annotations.Select; +import org.apache.ibatis.annotations.Update; + +import java.util.List; + +public interface AppealListMapper { + + @Select(""" + SELECT userId, next + FROM appeal_list + ORDER BY userId; + """) + List getAppealList(); + + @Update(""" + UPDATE appeal_list + SET next = #{next} + WHERE userId = #{userId} + """) + void updateNext(@Param("userId") long userId, @Param("next") boolean next); + +} diff --git a/database/src/main/java/com/alttd/altitudeweb/database/web_db/forms/AppealMapper.java b/database/src/main/java/com/alttd/altitudeweb/database/web_db/forms/AppealMapper.java index aa9dcca..081f5c5 100644 --- a/database/src/main/java/com/alttd/altitudeweb/database/web_db/forms/AppealMapper.java +++ b/database/src/main/java/com/alttd/altitudeweb/database/web_db/forms/AppealMapper.java @@ -34,4 +34,10 @@ public interface AppealMapper { WHERE id = #{id} """) void markAppealAsSent(UUID id); + + @Update(""" + UPDATE appeals SET assigned_to = #{assignedTo} + WHERE id = #{id} + """) + void assignAppeal(UUID id, Long assignedTo); } diff --git a/database/src/main/java/com/alttd/altitudeweb/setup/InitializeDiscord.java b/database/src/main/java/com/alttd/altitudeweb/setup/InitializeDiscord.java index 630e57d..7e4e277 100644 --- a/database/src/main/java/com/alttd/altitudeweb/setup/InitializeDiscord.java +++ b/database/src/main/java/com/alttd/altitudeweb/setup/InitializeDiscord.java @@ -1,6 +1,7 @@ package com.alttd.altitudeweb.setup; import com.alttd.altitudeweb.database.Databases; +import com.alttd.altitudeweb.database.discord.AppealListMapper; import com.alttd.altitudeweb.database.discord.OutputChannelMapper; import com.alttd.altitudeweb.database.luckperms.TeamMemberMapper; import lombok.extern.slf4j.Slf4j; @@ -12,6 +13,7 @@ public class InitializeDiscord { log.info("Initializing Discord"); Connection.getConnection(Databases.DISCORD, (configuration) -> { configuration.addMapper(OutputChannelMapper.class); + configuration.addMapper(AppealListMapper.class); }).join(); log.debug("Initialized Discord"); }