all repos — stealth-developers @ 3c912554ab06d13914f925d43c9924f359a1a290

bot: bug closing/opening
vi did:web:vt3e.cat
Mon, 29 Jun 2026 22:49:07 +0100
commit

3c912554ab06d13914f925d43c9924f359a1a290

parent

26f02a7c5bf180e51541a9d20e2468bd36593736

M apps/bot/src/feats/bugs/buttons.tsapps/bot/src/feats/bugs/buttons.ts

@@ -1,18 +1,18 @@

import { option } from "@purrkit/router"; -import db, { bugs, eq } from "@stealth-developers/db"; +import db, { bugs, eq, getActor } from "@stealth-developers/db"; -import { errorMessage } from "@/lib"; +import { errorMessage, getTextChannel } from "@/lib"; import { useGetData } from "@/middleware"; -import { buildReportModal } from "./shared"; +import { buildReportModal, constructBugContainer } from "./shared"; export const editButton = useGetData.button("edit-bug", { options: { id: option.integer({ required: true }), }, - run: async (interaction, { id }, { actor }) => { + run: async (interaction, { id: bugId }, { actor }) => { if (!actor) return errorMessage(interaction, "Failed to retrieve your user data"); - const [bug] = await db.select().from(bugs).where(eq(bugs.id, id)); + const [bug] = await db.select().from(bugs).where(eq(bugs.id, bugId)); if (!bug) return errorMessage(interaction, "Bug not found."); if (!actor.moderator && bug.actorId !== actor.id) {

@@ -20,7 +20,73 @@ return errorMessage(interaction, "You do not have permission to edit this bug.");

} const modal = buildReportModal(bug); - console.log(modal.toJSON()); interaction.showModal(modal); }, }); + +export const bugStatusButton = useGetData.button("bug-status", { + options: { + id: option.integer({ required: true }), + status: option.string({ required: true }), + }, + run: async (interaction, { id: bugId, status }, { actor }) => { + if (!actor) return errorMessage(interaction, "Failed to retrieve your user data"); + + const [bug] = await db.select().from(bugs).where(eq(bugs.id, bugId)); + if (!bug) return errorMessage(interaction, "Bug not found."); + + if (!actor.moderator && bug.actorId !== actor.id) + return errorMessage(interaction, "You do not have permission to edit this bug."); + + await interaction.deferReply({ flags: ["Ephemeral"] }); + + const statusMap = { + open: "closed", + closed: "open", + } as const; + + const newStatus = statusMap[status as keyof typeof statusMap]; + if (!newStatus) return errorMessage(interaction, "Invalid status."); + + const [updatedBug] = await db + .update(bugs) + .set({ + status: newStatus, + closedAt: status === "closed" ? new Date() : null, + updatedAt: new Date(), + }) + .where(eq(bugs.id, bugId)) + .returning(); + + if (!updatedBug) { + return errorMessage(interaction, "Failed to update bug report status."); + } + + const originalActor = await getActor(updatedBug.actorId); + if (!originalActor) { + return errorMessage(interaction, "Failed to fetch original bug author."); + } + + const container = await constructBugContainer(updatedBug, originalActor); + if (!container) return; + + const channel = await getTextChannel("1512924775842840767"); + if (!channel) return errorMessage(interaction, "Failed to find bug report channel."); + + if (updatedBug.messageId) { + try { + const message = await channel.messages.fetch(updatedBug.messageId); + await message.edit({ + components: [container], + }); + } catch (err) { + console.error("error updating discord message:", err); + } + } + + const paddedNumber = updatedBug.bugNumber.toString().padStart(4, "0"); + await interaction.editReply({ + content: `Bug #${paddedNumber} status updated to **${status}** successfully.`, + }); + }, +});
M apps/bot/src/feats/bugs/index.tsapps/bot/src/feats/bugs/index.ts

@@ -1,6 +1,6 @@

-import { editButton } from "./buttons"; +import { bugStatusButton, editButton } from "./buttons"; import { bugCommand } from "./commands"; import { bugModal, editBugModal } from "./modals"; export const bugCommands = [bugCommand]; -export const bugComponents = [bugModal, editBugModal, editButton]; +export const bugComponents = [bugModal, editBugModal, editButton, bugStatusButton];
M apps/bot/src/feats/bugs/shared.tsapps/bot/src/feats/bugs/shared.ts

@@ -19,7 +19,7 @@ TextInputStyle,

ThumbnailBuilder, } from "discord.js"; -import { editButton } from "./buttons"; +import { bugStatusButton, editButton } from "./buttons"; import { bugModal, editBugModal } from "./modals"; export const Projects = {

@@ -169,23 +169,18 @@ export async function constructButtons(bug: Bug) {

const row = new ActionRowBuilder<ButtonBuilder>(); const isOpen = bug.status === "open"; - const statusId = isOpen ? `bug:close:${bug.id}` : `bug:open:${bug.id}`; const statusLabel = isOpen ? "Close" : "Reopen"; - const statusToggle = new ButtonBuilder() - .setCustomId(statusId) + const _statusToggle = new ButtonBuilder() + .setCustomId(bugStatusButton.id({ id: bug.id, status: bug.status || "open" })) .setLabel(statusLabel) .setStyle(isOpen ? ButtonStyle.Danger : ButtonStyle.Success); const _editButton = new ButtonBuilder() .setCustomId(editButton.id({ id: bug.id })) .setLabel("Edit") .setStyle(ButtonStyle.Secondary); - const trelloButton = new ButtonBuilder() - .setCustomId(`bug:trello:${bug.id}`) - .setLabel("Trello") - .setStyle(ButtonStyle.Secondary); - row.addComponents(statusToggle, _editButton, trelloButton); + row.addComponents(_statusToggle, _editButton); return row; }