Add historyType and historyId to Appeal, update database schema, API, and email templates to include punishment details.

This commit is contained in:
akastijn 2025-08-16 23:40:20 +02:00
parent c3f3b20807
commit de1876c90c
8 changed files with 51 additions and 21 deletions

View File

@ -2,6 +2,9 @@ package com.alttd.altitudeweb.controllers.forms;
import com.alttd.altitudeweb.api.AppealsApi; import com.alttd.altitudeweb.api.AppealsApi;
import com.alttd.altitudeweb.database.Databases; import com.alttd.altitudeweb.database.Databases;
import com.alttd.altitudeweb.database.litebans.HistoryRecord;
import com.alttd.altitudeweb.database.litebans.HistoryType;
import com.alttd.altitudeweb.database.litebans.IdHistoryMapper;
import com.alttd.altitudeweb.database.web_db.forms.Appeal; import com.alttd.altitudeweb.database.web_db.forms.Appeal;
import com.alttd.altitudeweb.database.web_db.forms.AppealMapper; import com.alttd.altitudeweb.database.web_db.forms.AppealMapper;
import com.alttd.altitudeweb.mappers.AppealDataMapper; import com.alttd.altitudeweb.mappers.AppealDataMapper;
@ -56,8 +59,12 @@ public class AppealController implements AppealsApi {
} }
}); });
Appeal appeal = appealCompletableFuture.join(); Appeal appeal = appealCompletableFuture.join();
HistoryRecord history = getHistory(appeal.historyType(), appeal.historyId());
if (history == null) {
throw new ResponseStatusException(HttpStatusCode.valueOf(404), "History not found");
}
appealMail.sendAppealNotification(appeal); appealMail.sendAppealNotification(appeal, history);
AppealResponseDto appealResponseDto = new AppealResponseDto( AppealResponseDto appealResponseDto = new AppealResponseDto(
appeal.id().toString(), appeal.id().toString(),
@ -71,4 +78,23 @@ public class AppealController implements AppealsApi {
public ResponseEntity<AppealResponseDto> updateMail(UpdateMailDto updateMailDto) { public ResponseEntity<AppealResponseDto> updateMail(UpdateMailDto updateMailDto) {
throw new ResponseStatusException(HttpStatusCode.valueOf(501), "Updating mail is not yet supported"); throw new ResponseStatusException(HttpStatusCode.valueOf(501), "Updating mail is not yet supported");
} }
private HistoryRecord getHistory(String type, int id) {
HistoryType historyTypeEnum = HistoryType.getHistoryType(type);
CompletableFuture<HistoryRecord> historyRecordCompletableFuture = new CompletableFuture<>();
Connection.getConnection(Databases.LITE_BANS)
.runQuery(sqlSession -> {
log.debug("Loading history by id");
try {
HistoryRecord punishment = sqlSession.getMapper(IdHistoryMapper.class)
.getRecentHistory(historyTypeEnum, id);
historyRecordCompletableFuture.complete(punishment);
} catch (Exception e) {
log.error("Failed to load history count", e);
historyRecordCompletableFuture.completeExceptionally(e);
}
});
return historyRecordCompletableFuture.join();
}
} }

View File

@ -1,5 +1,6 @@
package com.alttd.altitudeweb.services.mail; package com.alttd.altitudeweb.services.mail;
import com.alttd.altitudeweb.database.litebans.HistoryRecord;
import com.alttd.altitudeweb.database.web_db.forms.Appeal; import com.alttd.altitudeweb.database.web_db.forms.Appeal;
import jakarta.mail.MessagingException; import jakarta.mail.MessagingException;
import jakarta.mail.internet.MimeMessage; import jakarta.mail.internet.MimeMessage;
@ -30,9 +31,9 @@ public class AppealMail {
* *
* @param appeal The appeal object containing all necessary information * @param appeal The appeal object containing all necessary information
*/ */
public void sendAppealNotification(Appeal appeal) { public void sendAppealNotification(Appeal appeal, HistoryRecord history) {
try { try {
sendEmailToAppealsTeam(appeal); sendEmailToAppealsTeam(appeal, history);
log.info("Appeal notification emails sent successfully for appeal ID: {}", appeal.id()); log.info("Appeal notification emails sent successfully for appeal ID: {}", appeal.id());
} catch (Exception e) { } catch (Exception e) {
@ -40,7 +41,7 @@ public class AppealMail {
} }
} }
private void sendEmailToAppealsTeam(Appeal appeal) throws MessagingException { private void sendEmailToAppealsTeam(Appeal appeal, HistoryRecord history) throws MessagingException {
MimeMessage message = mailSender.createMimeMessage(); MimeMessage message = mailSender.createMimeMessage();
MimeMessageHelper helper = new MimeMessageHelper(message, true); MimeMessageHelper helper = new MimeMessageHelper(message, true);
@ -51,6 +52,9 @@ public class AppealMail {
Context context = new Context(); Context context = new Context();
context.setVariable("appeal", appeal); context.setVariable("appeal", appeal);
context.setVariable("history", history);
context.setVariable("createdAt", appeal.createdAt().toString());
context.setVariable("active", history.getUntil() <= 0 || history.getUntil() > System.currentTimeMillis());
String content = templateEngine.process("appeal-email", context); String content = templateEngine.process("appeal-email", context);
helper.setText(content, true); helper.setText(content, true);

View File

@ -17,7 +17,9 @@
<li><strong>Username:</strong> <span th:text="${appeal.username}">username</span></li> <li><strong>Username:</strong> <span th:text="${appeal.username}">username</span></li>
<li><strong>UUID:</strong> <span th:text="${appeal.uuid}">uuid</span></li> <li><strong>UUID:</strong> <span th:text="${appeal.uuid}">uuid</span></li>
<li><strong>Email:</strong> <span th:text="${appeal.email}">email</span></li> <li><strong>Email:</strong> <span th:text="${appeal.email}">email</span></li>
<li><strong>Submitted:</strong> <span th:text="${appeal.createdAt}">date</span></li> <li><strong>Submitted at:</strong> <span th:text="${createdAt}">date</span></li>
<li><strong>Reason:</strong> <span th:text="${history.reason}">reason</span></li>
<li><strong>Active:</strong> <span th:text="${active}">unknown</span></li>
</ul> </ul>
<h3>Appeal:</h3> <h3>Appeal:</h3>
<p th:text="${appeal.reason}">Reason text</p> <p th:text="${appeal.reason}">Reason text</p>

View File

@ -6,6 +6,8 @@ import java.util.UUID;
public record Appeal( public record Appeal(
UUID id, UUID id,
UUID uuid, UUID uuid,
String historyType,
Integer historyId,
String username, String username,
String reason, String reason,
Instant createdAt, Instant createdAt,

View File

@ -2,38 +2,26 @@ package com.alttd.altitudeweb.database.web_db.forms;
import org.apache.ibatis.annotations.Insert; import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Select; import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.annotations.Update;
import java.util.List; import java.util.List;
public interface AppealMapper { public interface AppealMapper {
@Insert(""" @Insert("""
INSERT INTO appeals (uuid, username, reason, created_at, send_at, e_mail, assigned_to) INSERT INTO appeals (uuid, username, historyType, historyId, reason, created_at, send_at, e_mail, assigned_to)
VALUES (#{uuid}, #{username}, #{reason}, #{createdAt}, #{sendAt}, #{email}, #{assignedTo}) VALUES (#{uuid}, #{username}, #{historyType}, #{historyId}, #{reason}, #{createdAt}, #{sendAt}, #{email}, #{assignedTo})
""") """)
void createAppeal(Appeal appeal); void createAppeal(Appeal appeal);
@Update("""
UPDATE appeals
SET reason = #{reason},
created_at = #{createdAt},
send_at = #{sendAt},
e_mail = #{email},
assigned_to = #{assignedTo}
WHERE id = #{id}
""")
void updateAppeal(Appeal appeal);
@Select(""" @Select("""
SELECT id, uuid, reason, created_at AS createdAt, send_at AS sendAt, e_mail AS email, assigned_to AS assignedTo SELECT id, uuid, historyType, historyId, reason, created_at AS createdAt, send_at AS sendAt, e_mail AS email, assigned_to AS assignedTo
FROM appeals FROM appeals
WHERE id = #{id} WHERE id = #{id}
""") """)
Appeal getAppealById(int id); Appeal getAppealById(int id);
@Select(""" @Select("""
SELECT id, uuid, reason, created_at AS createdAt, send_at AS sendAt, e_mail AS email, assigned_to AS assignedTo SELECT id, uuid, historyType, historyId, reason, created_at AS createdAt, send_at AS sendAt, e_mail AS email, assigned_to AS assignedTo
FROM appeals FROM appeals
WHERE uuid = #{uuid} WHERE uuid = #{uuid}
""") """)

View File

@ -107,6 +107,8 @@ public class InitializeWebDb {
CREATE TABLE IF NOT EXISTS appeals ( CREATE TABLE IF NOT EXISTS appeals (
id UUID NOT NULL DEFAULT (UUID()) PRIMARY KEY, id UUID NOT NULL DEFAULT (UUID()) PRIMARY KEY,
uuid UUID NOT NULL, uuid UUID NOT NULL,
historyType VARCHAR(16) NOT NULL,
historyId BIGINT UNSIGNED NOT NULL,
username VARCHAR(16) NOT NULL, username VARCHAR(16) NOT NULL,
reason TEXT NOT NULL, reason TEXT NOT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL,

View File

@ -145,6 +145,7 @@ export class AppealComponent implements OnInit, AfterViewInit {
appeal: rawValue.appeal, appeal: rawValue.appeal,
email: rawValue.email, email: rawValue.email,
punishmentId: this.selectedPunishment()!.id, punishmentId: this.selectedPunishment()!.id,
punishmentType: this.selectedPunishment()!.type,
username: this.authService.username()!, username: this.authService.username()!,
uuid: uuid uuid: uuid
} }

View File

@ -92,6 +92,7 @@ components:
- username - username
- email - email
- punishmentId - punishmentId
- punishmentType
- appeal - appeal
properties: properties:
username: username:
@ -107,6 +108,10 @@ components:
punishmentId: punishmentId:
type: integer type: integer
description: Unique identifier of the punishment being appealed description: Unique identifier of the punishment being appealed
punishmentType:
type: string
enum: [ ban, mute, kick, warn ]
description: Unique identifier of the punishment being appealed
appeal: appeal:
type: string type: string
description: Appeal text explaining why the punishment should be reconsidered description: Appeal text explaining why the punishment should be reconsidered