Refactor giveaway job processing and enhance environment documentation

- Improved handling of the `giveawayCreate` job in the bot's job processing for better consistency.
- Updated `.env.example` to clarify the usage of `BOT_TOKEN` for both the bot and WebUI.
- Added `bullmq` dependency to the WebUI package for enhanced job management capabilities.
This commit is contained in:
smueller
2026-07-22 15:31:03 +02:00
parent 429f974bfc
commit 387fbf11da
32 changed files with 2620 additions and 0 deletions

View File

@@ -0,0 +1,99 @@
import type {
SuggestionAction,
SuggestionConfigDashboard,
SuggestionConfigDashboardPatch,
SuggestionDashboard,
SuggestionListQuery
} from '@nexumi/shared';
import type { Suggestion } from '@prisma/client';
import { prisma } from '../prisma';
async function ensureSuggestionConfig(guildId: string) {
await prisma.guild.upsert({ where: { id: guildId }, update: {}, create: { id: guildId } });
return prisma.suggestionConfig.upsert({ where: { guildId }, update: {}, create: { guildId } });
}
function toConfigDashboard(
config: Awaited<ReturnType<typeof ensureSuggestionConfig>>
): SuggestionConfigDashboard {
return {
enabled: config.enabled,
openChannelId: config.openChannelId ?? '',
approvedChannelId: config.approvedChannelId ?? '',
deniedChannelId: config.deniedChannelId ?? '',
createThread: config.createThread
};
}
export async function getSuggestionConfigDashboard(guildId: string): Promise<SuggestionConfigDashboard> {
const config = await ensureSuggestionConfig(guildId);
return toConfigDashboard(config);
}
export async function updateSuggestionConfigDashboard(
guildId: string,
patch: SuggestionConfigDashboardPatch
): Promise<SuggestionConfigDashboard> {
await ensureSuggestionConfig(guildId);
const { openChannelId, approvedChannelId, deniedChannelId, ...rest } = patch;
const updated = await prisma.suggestionConfig.update({
where: { guildId },
data: {
...rest,
...(openChannelId !== undefined ? { openChannelId: openChannelId === '' ? null : openChannelId } : {}),
...(approvedChannelId !== undefined
? { approvedChannelId: approvedChannelId === '' ? null : approvedChannelId }
: {}),
...(deniedChannelId !== undefined
? { deniedChannelId: deniedChannelId === '' ? null : deniedChannelId }
: {})
}
});
return toConfigDashboard(updated);
}
function toSuggestionDashboard(suggestion: Suggestion): SuggestionDashboard {
return {
id: suggestion.id,
authorId: suggestion.authorId,
content: suggestion.content,
status: suggestion.status as SuggestionDashboard['status'],
upvotes: suggestion.upvotes,
downvotes: suggestion.downvotes,
staffReason: suggestion.staffReason,
createdAt: suggestion.createdAt.toISOString()
};
}
export async function listSuggestions(
guildId: string,
query: SuggestionListQuery
): Promise<SuggestionDashboard[]> {
const suggestions = await prisma.suggestion.findMany({
where: { guildId, ...(query.status ? { status: query.status } : {}) },
orderBy: { createdAt: 'desc' },
take: query.limit
});
return suggestions.map(toSuggestionDashboard);
}
export async function applySuggestionAction(
guildId: string,
suggestionId: string,
action: SuggestionAction
): Promise<SuggestionDashboard | null> {
const existing = await prisma.suggestion.findFirst({ where: { id: suggestionId, guildId } });
if (!existing) {
return null;
}
const updated = await prisma.suggestion.update({
where: { id: suggestionId },
data: {
status: action.status,
staffReason: action.staffReason ?? null
}
});
return toSuggestionDashboard(updated);
}