Refactor giveaway job processing and update environment documentation
- Improved the `giveawayCreate` job handling in the bot's job processing, ensuring consistent functionality with existing commands. - Enhanced the `.env.example` file to provide clearer instructions on the usage of `BOT_TOKEN` for both the bot and WebUI. - Added the `bullmq` dependency to the WebUI package for better job management capabilities.
This commit is contained in:
131
apps/webui/src/lib/module-configs/tickets.ts
Normal file
131
apps/webui/src/lib/module-configs/tickets.ts
Normal file
@@ -0,0 +1,131 @@
|
||||
import type {
|
||||
TicketCategoryDashboard,
|
||||
TicketCategoryDashboardCreate,
|
||||
TicketCategoryDashboardUpdate,
|
||||
TicketConfigDashboard,
|
||||
TicketConfigDashboardPatch
|
||||
} from '@nexumi/shared';
|
||||
import type { TicketCategory } from '@prisma/client';
|
||||
import { prisma } from '../prisma';
|
||||
|
||||
async function ensureTicketConfig(guildId: string) {
|
||||
await prisma.guild.upsert({ where: { id: guildId }, update: {}, create: { id: guildId } });
|
||||
return prisma.ticketConfig.upsert({ where: { guildId }, update: {}, create: { guildId } });
|
||||
}
|
||||
|
||||
function toConfigDashboard(config: Awaited<ReturnType<typeof ensureTicketConfig>>): TicketConfigDashboard {
|
||||
return {
|
||||
enabled: config.enabled,
|
||||
mode: config.mode as TicketConfigDashboard['mode'],
|
||||
categoryId: config.categoryId ?? '',
|
||||
logChannelId: config.logChannelId ?? '',
|
||||
transcriptDm: config.transcriptDm,
|
||||
inactivityHours: config.inactivityHours,
|
||||
ratingEnabled: config.ratingEnabled
|
||||
};
|
||||
}
|
||||
|
||||
export async function getTicketConfigDashboard(guildId: string): Promise<TicketConfigDashboard> {
|
||||
const config = await ensureTicketConfig(guildId);
|
||||
return toConfigDashboard(config);
|
||||
}
|
||||
|
||||
export async function updateTicketConfigDashboard(
|
||||
guildId: string,
|
||||
patch: TicketConfigDashboardPatch
|
||||
): Promise<TicketConfigDashboard> {
|
||||
await ensureTicketConfig(guildId);
|
||||
|
||||
const { categoryId, logChannelId, ...rest } = patch;
|
||||
const updated = await prisma.ticketConfig.update({
|
||||
where: { guildId },
|
||||
data: {
|
||||
...rest,
|
||||
...(categoryId !== undefined ? { categoryId: categoryId === '' ? null : categoryId } : {}),
|
||||
...(logChannelId !== undefined ? { logChannelId: logChannelId === '' ? null : logChannelId } : {})
|
||||
}
|
||||
});
|
||||
return toConfigDashboard(updated);
|
||||
}
|
||||
|
||||
function toCategoryDashboard(category: TicketCategory): TicketCategoryDashboard {
|
||||
return {
|
||||
id: category.id,
|
||||
name: category.name,
|
||||
description: category.description,
|
||||
emoji: category.emoji,
|
||||
supportRoleIds: category.supportRoleIds
|
||||
};
|
||||
}
|
||||
|
||||
export async function listTicketCategories(guildId: string): Promise<TicketCategoryDashboard[]> {
|
||||
const categories = await prisma.ticketCategory.findMany({
|
||||
where: { guildId },
|
||||
orderBy: { createdAt: 'asc' }
|
||||
});
|
||||
return categories.map(toCategoryDashboard);
|
||||
}
|
||||
|
||||
export class TicketCategoryConflictError extends Error {
|
||||
constructor() {
|
||||
super('A ticket category with this name already exists');
|
||||
}
|
||||
}
|
||||
|
||||
export async function createTicketCategory(
|
||||
guildId: string,
|
||||
input: TicketCategoryDashboardCreate
|
||||
): Promise<TicketCategoryDashboard> {
|
||||
await prisma.guild.upsert({ where: { id: guildId }, update: {}, create: { id: guildId } });
|
||||
try {
|
||||
const category = await prisma.ticketCategory.create({
|
||||
data: {
|
||||
guildId,
|
||||
name: input.name,
|
||||
description: input.description ?? null,
|
||||
emoji: input.emoji ?? null,
|
||||
supportRoleIds: input.supportRoleIds
|
||||
}
|
||||
});
|
||||
return toCategoryDashboard(category);
|
||||
} catch (error) {
|
||||
if (error && typeof error === 'object' && 'code' in error && error.code === 'P2002') {
|
||||
throw new TicketCategoryConflictError();
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
export async function updateTicketCategory(
|
||||
guildId: string,
|
||||
categoryId: string,
|
||||
patch: TicketCategoryDashboardUpdate
|
||||
): Promise<TicketCategoryDashboard | null> {
|
||||
const existing = await prisma.ticketCategory.findFirst({ where: { id: categoryId, guildId } });
|
||||
if (!existing) {
|
||||
return null;
|
||||
}
|
||||
|
||||
try {
|
||||
const updated = await prisma.ticketCategory.update({
|
||||
where: { id: categoryId },
|
||||
data: {
|
||||
...(patch.name !== undefined ? { name: patch.name } : {}),
|
||||
...(patch.description !== undefined ? { description: patch.description } : {}),
|
||||
...(patch.emoji !== undefined ? { emoji: patch.emoji } : {}),
|
||||
...(patch.supportRoleIds !== undefined ? { supportRoleIds: patch.supportRoleIds } : {})
|
||||
}
|
||||
});
|
||||
return toCategoryDashboard(updated);
|
||||
} catch (error) {
|
||||
if (error && typeof error === 'object' && 'code' in error && error.code === 'P2002') {
|
||||
throw new TicketCategoryConflictError();
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
export async function deleteTicketCategory(guildId: string, categoryId: string): Promise<boolean> {
|
||||
const result = await prisma.ticketCategory.deleteMany({ where: { id: categoryId, guildId } });
|
||||
return result.count > 0;
|
||||
}
|
||||
Reference in New Issue
Block a user