[AB-76] adding evaluation job for suggestions

This commit is contained in:
Sheldan
2022-11-11 00:06:16 +01:00
parent ea2f62b721
commit d315113395
18 changed files with 199 additions and 29 deletions

View File

@@ -46,7 +46,7 @@ public class Accept extends AbstractConditionableCommand {
Long suggestionId = (Long) parameters.get(0); Long suggestionId = (Long) parameters.get(0);
String text = parameters.size() == 2 ? (String) parameters.get(1) : ""; String text = parameters.size() == 2 ? (String) parameters.get(1) : "";
log.debug("Using default reason for accept: {}.", parameters.size() != 2); log.debug("Using default reason for accept: {}.", parameters.size() != 2);
return suggestionService.acceptSuggestion(suggestionId, commandContext.getAuthor(), text) return suggestionService.acceptSuggestion(commandContext.getGuild().getIdLong(), suggestionId, commandContext.getAuthor(), text)
.thenApply(aVoid -> CommandResult.fromSuccess()); .thenApply(aVoid -> CommandResult.fromSuccess());
} }
@@ -59,7 +59,7 @@ public class Accept extends AbstractConditionableCommand {
} else { } else {
acceptText = ""; acceptText = "";
} }
return suggestionService.acceptSuggestion(suggestionId, event.getMember(), acceptText) return suggestionService.acceptSuggestion(event.getGuild().getIdLong(), suggestionId, event.getMember(), acceptText)
.thenCompose(unused -> interactionService.replyEmbed(ACCEPT_RESPONSE, event)) .thenCompose(unused -> interactionService.replyEmbed(ACCEPT_RESPONSE, event))
.thenApply(aVoid -> CommandResult.fromSuccess()); .thenApply(aVoid -> CommandResult.fromSuccess());
} }

View File

@@ -46,7 +46,7 @@ public class Reject extends AbstractConditionableCommand {
Long suggestionId = (Long) parameters.get(0); Long suggestionId = (Long) parameters.get(0);
String text = parameters.size() == 2 ? (String) parameters.get(1) : ""; String text = parameters.size() == 2 ? (String) parameters.get(1) : "";
log.debug("Using default reason for reject: {}.", parameters.size() != 2); log.debug("Using default reason for reject: {}.", parameters.size() != 2);
return suggestionService.rejectSuggestion(suggestionId, commandContext.getAuthor(), text) return suggestionService.rejectSuggestion(commandContext.getGuild().getIdLong(), suggestionId, commandContext.getAuthor(), text)
.thenApply(aVoid -> CommandResult.fromSuccess()); .thenApply(aVoid -> CommandResult.fromSuccess());
} }
@@ -59,7 +59,7 @@ public class Reject extends AbstractConditionableCommand {
} else { } else {
rejectText = ""; rejectText = "";
} }
return suggestionService.rejectSuggestion(suggestionId, event.getMember(), rejectText) return suggestionService.rejectSuggestion(event.getGuild().getIdLong(), suggestionId, event.getMember(), rejectText)
.thenCompose(unused -> interactionService.replyEmbed(REJECT_RESPONSE, event)) .thenCompose(unused -> interactionService.replyEmbed(REJECT_RESPONSE, event))
.thenApply(aVoid -> CommandResult.fromSuccess()); .thenApply(aVoid -> CommandResult.fromSuccess());
} }

View File

@@ -41,14 +41,14 @@ public class UnSuggest extends AbstractConditionableCommand {
public CompletableFuture<CommandResult> executeAsync(CommandContext commandContext) { public CompletableFuture<CommandResult> executeAsync(CommandContext commandContext) {
List<Object> parameters = commandContext.getParameters().getParameters(); List<Object> parameters = commandContext.getParameters().getParameters();
Long suggestionId = (Long) parameters.get(0); Long suggestionId = (Long) parameters.get(0);
return suggestionService.removeSuggestion(suggestionId, commandContext.getAuthor()) return suggestionService.removeSuggestion(commandContext.getGuild().getIdLong(), suggestionId, commandContext.getAuthor())
.thenApply(aVoid -> CommandResult.fromSuccess()); .thenApply(aVoid -> CommandResult.fromSuccess());
} }
@Override @Override
public CompletableFuture<CommandResult> executeSlash(SlashCommandInteractionEvent event) { public CompletableFuture<CommandResult> executeSlash(SlashCommandInteractionEvent event) {
Long suggestionId = slashCommandParameterService.getCommandOption(SUGGESTION_ID_PARAMETER, event, Long.class, Integer.class).longValue(); Long suggestionId = slashCommandParameterService.getCommandOption(SUGGESTION_ID_PARAMETER, event, Long.class, Integer.class).longValue();
return suggestionService.removeSuggestion(suggestionId, event.getMember()) return suggestionService.removeSuggestion(event.getMember().getIdLong(), suggestionId, event.getMember())
.thenCompose(unused -> interactionService.replyEmbed(UN_SUGGEST_RESPONSE, event)) .thenCompose(unused -> interactionService.replyEmbed(UN_SUGGEST_RESPONSE, event))
.thenApply(aVoid -> CommandResult.fromSuccess()); .thenApply(aVoid -> CommandResult.fromSuccess());
} }

View File

@@ -46,7 +46,7 @@ public class Veto extends AbstractConditionableCommand {
Long suggestionId = (Long) parameters.get(0); Long suggestionId = (Long) parameters.get(0);
String text = parameters.size() == 2 ? (String) parameters.get(1) : ""; String text = parameters.size() == 2 ? (String) parameters.get(1) : "";
log.debug("Using default reason for veto: {}.", parameters.size() != 2); log.debug("Using default reason for veto: {}.", parameters.size() != 2);
return suggestionService.vetoSuggestion(suggestionId, commandContext.getAuthor(), text) return suggestionService.vetoSuggestion(commandContext.getGuild().getIdLong(), suggestionId, commandContext.getAuthor(), text)
.thenApply(aVoid -> CommandResult.fromSuccess()); .thenApply(aVoid -> CommandResult.fromSuccess());
} }
@@ -59,7 +59,7 @@ public class Veto extends AbstractConditionableCommand {
} else { } else {
vetoText = ""; vetoText = "";
} }
return suggestionService.vetoSuggestion(suggestionId, event.getMember(), vetoText) return suggestionService.vetoSuggestion(event.getGuild().getIdLong(), suggestionId, event.getMember(), vetoText)
.thenCompose(unused -> interactionService.replyEmbed(VETO_RESPONSE, event)) .thenCompose(unused -> interactionService.replyEmbed(VETO_RESPONSE, event))
.thenApply(aVoid -> CommandResult.fromSuccess()); .thenApply(aVoid -> CommandResult.fromSuccess());
} }

View File

@@ -0,0 +1,41 @@
package dev.sheldan.abstracto.suggestion.job;
import dev.sheldan.abstracto.suggestion.service.SuggestionService;
import lombok.extern.slf4j.Slf4j;
import org.quartz.DisallowConcurrentExecution;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.quartz.PersistJobDataAfterExecution;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.quartz.QuartzJobBean;
import org.springframework.stereotype.Component;
@Slf4j
@DisallowConcurrentExecution
@Component
@PersistJobDataAfterExecution
public class SuggestionEvaluationJob extends QuartzJobBean {
private Long suggestionId;
private Long serverId;
@Autowired
private SuggestionService suggestionService;
@Override
protected void executeInternal(JobExecutionContext jobExecutionContext) throws JobExecutionException {
log.info("Executing suggestion evaluation job for suggestion {} in server {}.", suggestionId, serverId);
try {
suggestionService.evaluateSuggestion(serverId, suggestionId)
.thenAccept(unused -> {
log.info("Finished evaluation suggestion {} in server {}.", suggestionId, serverId);
})
.exceptionally(throwable -> {
log.error("Failed to evaluate suggestion {} in server {}.", suggestionId, serverId, throwable);
return null;
});
} catch (Exception exception) {
log.error("Suggestion evaluation up job failed.", exception);
}
}
}

View File

@@ -126,6 +126,11 @@ public class SuggestionServiceBean implements SuggestionService {
AUserInAServer userSuggester = userInServerManagementService.loadOrCreateUser(suggester); AUserInAServer userSuggester = userInServerManagementService.loadOrCreateUser(suggester);
Long newSuggestionId = counterService.getNextCounterValue(server, SUGGESTION_COUNTER_KEY); Long newSuggestionId = counterService.getNextCounterValue(server, SUGGESTION_COUNTER_KEY);
Boolean useButtons = featureModeService.featureModeActive(SuggestionFeatureDefinition.SUGGEST, serverId, SuggestionFeatureMode.SUGGESTION_BUTTONS); Boolean useButtons = featureModeService.featureModeActive(SuggestionFeatureDefinition.SUGGEST, serverId, SuggestionFeatureMode.SUGGESTION_BUTTONS);
Boolean autoEvaluationEnabled = featureModeService.featureModeActive(SuggestionFeatureDefinition.SUGGEST, serverId, SuggestionFeatureMode.SUGGESTION_AUTO_EVALUATE);
Long autoEvaluateDays = null;
if(autoEvaluationEnabled) {
autoEvaluateDays = configService.getLongValueOrConfigDefault(SUGGESTION_AUTO_EVALUATE_DAYS_CONFIG_KEY, serverId);
}
SuggestionLog model = SuggestionLog SuggestionLog model = SuggestionLog
.builder() .builder()
.suggestionId(newSuggestionId) .suggestionId(newSuggestionId)
@@ -137,6 +142,8 @@ public class SuggestionServiceBean implements SuggestionService {
.useButtons(useButtons) .useButtons(useButtons)
.suggester(suggester.getUser()) .suggester(suggester.getUser())
.text(text) .text(text)
.autoEvaluationEnabled(autoEvaluationEnabled)
.autoEvaluationTargetDate(autoEvaluationEnabled ? Instant.now().plus(autoEvaluateDays, ChronoUnit.DAYS) : null)
.build(); .build();
if(useButtons) { if(useButtons) {
setupButtonIds(model); setupButtonIds(model);
@@ -200,6 +207,10 @@ public class SuggestionServiceBean implements SuggestionService {
String triggerKey = scheduleSuggestionReminder(serverId, suggestionId); String triggerKey = scheduleSuggestionReminder(serverId, suggestionId);
suggestion.setSuggestionReminderJobTriggerKey(triggerKey); suggestion.setSuggestionReminderJobTriggerKey(triggerKey);
} }
if(featureModeService.featureModeActive(SuggestionFeatureDefinition.SUGGEST, serverId, SuggestionFeatureMode.SUGGESTION_AUTO_EVALUATE)) {
String triggerKey = scheduleEvaluationReminder(serverId, suggestionId);
suggestion.setSuggestionEvaluationJobTriggerKey(triggerKey);
}
} }
private String scheduleSuggestionReminder(Long serverId, Long suggestionId) { private String scheduleSuggestionReminder(Long serverId, Long suggestionId) {
@@ -214,25 +225,50 @@ public class SuggestionServiceBean implements SuggestionService {
return triggerKey; return triggerKey;
} }
private String scheduleEvaluationReminder(Long serverId, Long suggestionId) {
HashMap<Object, Object> parameters = new HashMap<>();
parameters.put("serverId", serverId.toString());
parameters.put("suggestionId", suggestionId.toString());
JobParameters jobParameters = JobParameters.builder().parameters(parameters).build();
Long days = configService.getLongValueOrConfigDefault(SuggestionService.SUGGESTION_AUTO_EVALUATE_DAYS_CONFIG_KEY, serverId);
Instant targetDate = Instant.now().plus(days, ChronoUnit.DAYS);
String triggerKey = schedulerService.executeJobWithParametersOnce("suggestionEvaluationJob", "suggestion", jobParameters, Date.from(targetDate));
log.info("Starting scheduled job with trigger {} to execute suggestion evaluation in server {} for suggestion {}.", triggerKey, serverId, suggestionId);
return triggerKey;
}
@Override @Override
public CompletableFuture<Void> acceptSuggestion(Long suggestionId, Member actingMember, String text) { public CompletableFuture<Void> acceptSuggestion(Long serverId, Long suggestionId, Member actingMember, String text) {
return self.setSuggestionToFinalState(actingMember, suggestionId, text, SuggestionState.ACCEPTED); return self.setSuggestionToFinalState(actingMember, serverId, suggestionId, text, SuggestionState.ACCEPTED);
}
@Override
public CompletableFuture<Void> evaluateSuggestion(Long serverId, Long suggestionId) {
Long approvalPercentage = configService.getLongValueOrConfigDefault(SUGGESTION_AUTO_EVALUATE_PERCENTAGE_CONFIG_KEY, serverId);
Suggestion suggestion = suggestionManagementService.getSuggestion(serverId, suggestionId);
Long agreements = suggestionVoteManagementService.getDecisionsForSuggestion(suggestion, SuggestionDecision.AGREE);
Long disagreements = suggestionVoteManagementService.getDecisionsForSuggestion(suggestion, SuggestionDecision.DISAGREE);
double suggestionPercentage = ((double) agreements) / (disagreements + agreements) * 100;
if(suggestionPercentage > approvalPercentage) {
return acceptSuggestion(serverId, suggestionId, null, null);
} else {
return rejectSuggestion(serverId, suggestionId, null, null);
}
} }
@Transactional @Transactional
public CompletableFuture<Void> setSuggestionToFinalState(Member executingMember, Long suggestionId, String text, SuggestionState state) { public CompletableFuture<Void> setSuggestionToFinalState(Member executingMember, Long serverId, Long suggestionId, String text, SuggestionState state) {
Long serverId = executingMember.getGuild().getIdLong();
postTargetService.validatePostTarget(SuggestionPostTarget.SUGGESTION, serverId); postTargetService.validatePostTarget(SuggestionPostTarget.SUGGESTION, serverId);
Suggestion suggestion = suggestionManagementService.getSuggestion(serverId, suggestionId); Suggestion suggestion = suggestionManagementService.getSuggestion(serverId, suggestionId);
suggestionManagementService.setSuggestionState(suggestion, state); suggestionManagementService.setSuggestionState(suggestion, state);
cancelSuggestionReminder(suggestion); cancelSuggestionJobs(suggestion);
log.info("Setting suggestion {} in server {} to state {}", suggestionId, suggestion.getServer().getId(), state); log.info("Setting suggestion {} in server {} to state {}", suggestionId, suggestion.getServer().getId(), state);
return updateSuggestion(executingMember, text, suggestion); return updateSuggestion(executingMember, text, suggestion);
} }
@Override @Override
public CompletableFuture<Void> vetoSuggestion(Long suggestionId, Member actingMember, String text) { public CompletableFuture<Void> vetoSuggestion(Long serverId, Long suggestionId, Member actingMember, String text) {
return self.setSuggestionToFinalState(actingMember, suggestionId, text, SuggestionState.VETOED); return self.setSuggestionToFinalState(actingMember, serverId, suggestionId, text, SuggestionState.VETOED);
} }
private CompletableFuture<Void> updateSuggestion(Member memberExecutingCommand, String reason, Suggestion suggestion) { private CompletableFuture<Void> updateSuggestion(Member memberExecutingCommand, String reason, Suggestion suggestion) {
@@ -300,13 +336,12 @@ public class SuggestionServiceBean implements SuggestionService {
} }
@Override @Override
public CompletableFuture<Void> rejectSuggestion(Long suggestionId, Member actingMember, String text) { public CompletableFuture<Void> rejectSuggestion(Long serverId, Long suggestionId, Member actingMember, String text) {
return self.setSuggestionToFinalState(actingMember, suggestionId, text, SuggestionState.REJECTED); return self.setSuggestionToFinalState(actingMember, serverId, suggestionId, text, SuggestionState.REJECTED);
} }
@Override @Override
public CompletableFuture<Void> removeSuggestion(Long suggestionId, Member member) { public CompletableFuture<Void> removeSuggestion(Long serverId, Long suggestionId, Member member) {
Long serverId = member.getGuild().getIdLong();
Suggestion suggestion = suggestionManagementService.getSuggestion(serverId, suggestionId); Suggestion suggestion = suggestionManagementService.getSuggestion(serverId, suggestionId);
if(member.getIdLong() != suggestion.getSuggester().getUserReference().getId() || if(member.getIdLong() != suggestion.getSuggester().getUserReference().getId() ||
suggestion.getCreated().isBefore(Instant.now().minus(Duration.ofSeconds(removalMaxAgeSeconds)))) { suggestion.getCreated().isBefore(Instant.now().minus(Duration.ofSeconds(removalMaxAgeSeconds)))) {
@@ -371,11 +406,15 @@ public class SuggestionServiceBean implements SuggestionService {
} }
@Override @Override
public void cancelSuggestionReminder(Suggestion suggestion) { public void cancelSuggestionJobs(Suggestion suggestion) {
if(suggestion.getSuggestionReminderJobTriggerKey() != null) { if(suggestion.getSuggestionReminderJobTriggerKey() != null) {
log.info("Cancelling reminder for suggestion {} in server {}.", suggestion.getSuggestionId().getId(), suggestion.getSuggestionId().getServerId()); log.info("Cancelling reminder for suggestion {} in server {}.", suggestion.getSuggestionId().getId(), suggestion.getSuggestionId().getServerId());
schedulerService.stopTrigger(suggestion.getSuggestionReminderJobTriggerKey()); schedulerService.stopTrigger(suggestion.getSuggestionReminderJobTriggerKey());
} }
if(suggestion.getSuggestionEvaluationJobTriggerKey() != null) {
log.info("Cancelling evaluation job for suggestion {} in server {}.", suggestion.getSuggestionId().getId(), suggestion.getSuggestionId().getServerId());
schedulerService.stopTrigger(suggestion.getSuggestionEvaluationJobTriggerKey());
}
} }
@Override @Override
@@ -398,7 +437,7 @@ public class SuggestionServiceBean implements SuggestionService {
@Transactional @Transactional
public void deleteSuggestion(Long suggestionId, Long serverId) { public void deleteSuggestion(Long suggestionId, Long serverId) {
Suggestion suggestion = suggestionManagementService.getSuggestion(serverId, suggestionId); Suggestion suggestion = suggestionManagementService.getSuggestion(serverId, suggestionId);
cancelSuggestionReminder(suggestion); cancelSuggestionJobs(suggestion);
suggestionVoteManagementService.deleteSuggestionVotes(suggestion); suggestionVoteManagementService.deleteSuggestionVotes(suggestion);
suggestionManagementService.deleteSuggestion(suggestion); suggestionManagementService.deleteSuggestion(suggestion);
} }

View File

@@ -0,0 +1,11 @@
<?xml version="1.1" encoding="UTF-8" standalone="no"?>
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
xmlns:ext="http://www.liquibase.org/xml/ns/dbchangelog-ext"
xmlns:pro="http://www.liquibase.org/xml/ns/pro"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog dbchangelog.xsd
http://www.liquibase.org/xml/ns/dbchangelog-ext dbchangelog.xsd
http://www.liquibase.org/xml/ns/pro dbchangelog.xsd" >
<include file="seedData/data.xml" relativeToChangelogFile="true"/>
<include file="tables/tables.xml" relativeToChangelogFile="true"/>
</databaseChangeLog>

View File

@@ -0,0 +1,10 @@
<?xml version="1.1" encoding="UTF-8" standalone="no"?>
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
xmlns:ext="http://www.liquibase.org/xml/ns/dbchangelog-ext"
xmlns:pro="http://www.liquibase.org/xml/ns/pro"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog dbchangelog.xsd
http://www.liquibase.org/xml/ns/dbchangelog-ext dbchangelog.xsd
http://www.liquibase.org/xml/ns/pro dbchangelog.xsd" >
<include file="suggestionEvaluationJob.xml" relativeToChangelogFile="true"/>
</databaseChangeLog>

View File

@@ -0,0 +1,18 @@
<?xml version="1.1" encoding="UTF-8" standalone="no"?>
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
xmlns:ext="http://www.liquibase.org/xml/ns/dbchangelog-ext"
xmlns:pro="http://www.liquibase.org/xml/ns/pro"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog dbchangelog.xsd
http://www.liquibase.org/xml/ns/dbchangelog-ext dbchangelog.xsd
http://www.liquibase.org/xml/ns/pro dbchangelog.xsd" >
<changeSet author="Sheldan" id="suggestion-evaluation-job-insert">
<insert tableName="scheduler_job">
<column name="name" value="suggestionEvaluationJob"/>
<column name="group_name" value="suggestion"/>
<column name="clazz" value="dev.sheldan.abstracto.suggestion.job.SuggestionEvaluationJob"/>
<column name="active" value="true"/>
<column name="recovery" value="false"/>
</insert>
</changeSet>
</databaseChangeLog>

View File

@@ -0,0 +1,15 @@
<?xml version="1.1" encoding="UTF-8" standalone="no"?>
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
xmlns:ext="http://www.liquibase.org/xml/ns/dbchangelog-ext"
xmlns:pro="http://www.liquibase.org/xml/ns/pro"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog dbchangelog.xsd
http://www.liquibase.org/xml/ns/dbchangelog-ext dbchangelog.xsd
http://www.liquibase.org/xml/ns/pro dbchangelog.xsd" >
<changeSet author="Sheldan" id="suggestion-add-suggestion-evaluation-job-colum">
<addColumn tableName="suggestion" >
<column name="evaluation_job_trigger_key"
type="varchar(255)"/>
</addColumn>
</changeSet>
</databaseChangeLog>

View File

@@ -0,0 +1,10 @@
<?xml version="1.1" encoding="UTF-8" standalone="no"?>
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
xmlns:ext="http://www.liquibase.org/xml/ns/dbchangelog-ext"
xmlns:pro="http://www.liquibase.org/xml/ns/pro"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog dbchangelog.xsd
http://www.liquibase.org/xml/ns/dbchangelog-ext dbchangelog.xsd
http://www.liquibase.org/xml/ns/pro dbchangelog.xsd" >
<include file="suggestion.xml" relativeToChangelogFile="true"/>
</databaseChangeLog>

View File

@@ -11,4 +11,5 @@
<include file="1.2.13/collection.xml" relativeToChangelogFile="true"/> <include file="1.2.13/collection.xml" relativeToChangelogFile="true"/>
<include file="1.3.8/collection.xml" relativeToChangelogFile="true"/> <include file="1.3.8/collection.xml" relativeToChangelogFile="true"/>
<include file="1.4.0/collection.xml" relativeToChangelogFile="true"/> <include file="1.4.0/collection.xml" relativeToChangelogFile="true"/>
<include file="1.4.8/collection.xml" relativeToChangelogFile="true"/>
</databaseChangeLog> </databaseChangeLog>

View File

@@ -14,6 +14,16 @@ abstracto.featureModes.suggestionReminder.enabled=false
abstracto.systemConfigs.suggestionReminderDays.name=suggestionReminderDays abstracto.systemConfigs.suggestionReminderDays.name=suggestionReminderDays
abstracto.systemConfigs.suggestionReminderDays.longValue=7 abstracto.systemConfigs.suggestionReminderDays.longValue=7
abstracto.systemConfigs.suggestionAutoEvaluateDays.name=suggestionAutoEvaluateDays
abstracto.systemConfigs.suggestionAutoEvaluateDays.longValue=7
abstracto.systemConfigs.suggestionAutoEvaluatePercentage.name=suggestionAutoEvaluatePercentage
abstracto.systemConfigs.suggestionAutoEvaluatePercentage.longValue=50
abstracto.featureModes.suggestionAutoEvaluate.featureName=suggestion
abstracto.featureModes.suggestionAutoEvaluate.mode=suggestionAutoEvaluate
abstracto.featureModes.suggestionAutoEvaluate.enabled=false
abstracto.featureModes.suggestionButton.featureName=suggestion abstracto.featureModes.suggestionButton.featureName=suggestion
abstracto.featureModes.suggestionButton.mode=suggestionButton abstracto.featureModes.suggestionButton.mode=suggestionButton
abstracto.featureModes.suggestionButton.enabled=true abstracto.featureModes.suggestionButton.enabled=true

View File

@@ -33,11 +33,16 @@ public class SuggestionFeatureConfig implements FeatureConfig {
@Override @Override
public List<FeatureMode> getAvailableModes() { public List<FeatureMode> getAvailableModes() {
return Arrays.asList(SuggestionFeatureMode.SUGGESTION_REMINDER, SuggestionFeatureMode.SUGGESTION_BUTTONS); return Arrays.asList(
SuggestionFeatureMode.SUGGESTION_REMINDER,
SuggestionFeatureMode.SUGGESTION_BUTTONS,
SuggestionFeatureMode.SUGGESTION_AUTO_EVALUATE);
} }
@Override @Override
public List<String> getRequiredSystemConfigKeys() { public List<String> getRequiredSystemConfigKeys() {
return Arrays.asList(SuggestionService.SUGGESTION_REMINDER_DAYS_CONFIG_KEY); return Arrays.asList(SuggestionService.SUGGESTION_REMINDER_DAYS_CONFIG_KEY,
SuggestionService.SUGGESTION_AUTO_EVALUATE_DAYS_CONFIG_KEY,
SuggestionService.SUGGESTION_AUTO_EVALUATE_PERCENTAGE_CONFIG_KEY);
} }
} }

View File

@@ -5,7 +5,7 @@ import lombok.Getter;
@Getter @Getter
public enum SuggestionFeatureMode implements FeatureMode { public enum SuggestionFeatureMode implements FeatureMode {
SUGGESTION_REMINDER("suggestionReminder"), SUGGESTION_BUTTONS("suggestionButton"); SUGGESTION_REMINDER("suggestionReminder"), SUGGESTION_BUTTONS("suggestionButton"), SUGGESTION_AUTO_EVALUATE("suggestionAutoEvaluate");
private final String key; private final String key;

View File

@@ -69,4 +69,7 @@ public class Suggestion implements Serializable {
@Column(name = "job_trigger_key") @Column(name = "job_trigger_key")
private String suggestionReminderJobTriggerKey; private String suggestionReminderJobTriggerKey;
@Column(name = "evaluation_job_trigger_key")
private String suggestionEvaluationJobTriggerKey;
} }

View File

@@ -10,6 +10,8 @@ import lombok.experimental.SuperBuilder;
import net.dv8tion.jda.api.entities.Member; import net.dv8tion.jda.api.entities.Member;
import net.dv8tion.jda.api.entities.User; import net.dv8tion.jda.api.entities.User;
import java.time.Instant;
@Getter @Getter
@Setter @Setter
@SuperBuilder @SuperBuilder
@@ -29,6 +31,8 @@ public class SuggestionLog {
private ButtonConfigModel agreeButtonModel; private ButtonConfigModel agreeButtonModel;
private ButtonConfigModel disAgreeButtonModel; private ButtonConfigModel disAgreeButtonModel;
private ButtonConfigModel removeVoteButtonModel; private ButtonConfigModel removeVoteButtonModel;
private Instant autoEvaluationTargetDate;
private Boolean autoEvaluationEnabled;
public String getOriginalMessageUrl() { public String getOriginalMessageUrl() {
return MessageUtils.buildMessageUrl(serverId, originalChannelId , originalMessageId); return MessageUtils.buildMessageUrl(serverId, originalChannelId , originalMessageId);

View File

@@ -10,14 +10,17 @@ import java.util.concurrent.CompletableFuture;
public interface SuggestionService { public interface SuggestionService {
String SUGGESTION_REMINDER_DAYS_CONFIG_KEY = "suggestionReminderDays"; String SUGGESTION_REMINDER_DAYS_CONFIG_KEY = "suggestionReminderDays";
String SUGGESTION_AUTO_EVALUATE_DAYS_CONFIG_KEY = "suggestionAutoEvaluateDays";
String SUGGESTION_AUTO_EVALUATE_PERCENTAGE_CONFIG_KEY = "suggestionAutoEvaluatePercentage";
CompletableFuture<Void> createSuggestionMessage(ServerChannelMessageUser cause, String text, String attachmentURL); CompletableFuture<Void> createSuggestionMessage(ServerChannelMessageUser cause, String text, String attachmentURL);
CompletableFuture<Void> acceptSuggestion(Long suggestionId, Member actingMember, String text); CompletableFuture<Void> acceptSuggestion(Long serverId, Long suggestionId, Member actingMember, String text);
CompletableFuture<Void> vetoSuggestion(Long suggestionId, Member actingMember, String text); CompletableFuture<Void> evaluateSuggestion(Long serverId, Long suggestionId);
CompletableFuture<Void> rejectSuggestion(Long suggestionId, Member actingMember, String text); CompletableFuture<Void> vetoSuggestion(Long serverId, Long suggestionId, Member actingMember, String text);
CompletableFuture<Void> removeSuggestion(Long suggestionId, Member member); CompletableFuture<Void> rejectSuggestion(Long serverId, Long suggestionId, Member actingMember, String text);
CompletableFuture<Void> removeSuggestion(Long serverId, Long suggestionId, Member member);
void cleanUpSuggestions(); void cleanUpSuggestions();
CompletableFuture<Void> remindAboutSuggestion(ServerSpecificId suggestionId); CompletableFuture<Void> remindAboutSuggestion(ServerSpecificId suggestionId);
void cancelSuggestionReminder(Suggestion suggestion); void cancelSuggestionJobs(Suggestion suggestion);
SuggestionInfoModel getSuggestionInfo(Long serverId, Long suggestionId); SuggestionInfoModel getSuggestionInfo(Long serverId, Long suggestionId);
SuggestionInfoModel getSuggestionInfo(ServerSpecificId suggestionId); SuggestionInfoModel getSuggestionInfo(ServerSpecificId suggestionId);
} }