mirror of
https://github.com/xCyanGrizzly/DragonsStash.git
synced 2026-05-11 06:11:15 +00:00
feat: add preview management, channel controls, invite polish, and recovery
- Auto-extract preview images from ZIP/RAR/7z archives during ingestion - Upload custom preview images via package drawer - Select preview from archive contents with on-demand extraction UI - Manually add Telegram channels by t.me link, username, or invite link - Invite code UX: bulk create, copy link, usage tracking, delete confirm - Incomplete upload recovery: verify dest messages on worker startup - Rebuild package DB by scanning destination channel with live progress Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -33,6 +33,45 @@ export async function createInviteCode(input: {
|
||||
return { success: true, data: { code } };
|
||||
}
|
||||
|
||||
export async function createBulkInviteCodes(input: {
|
||||
count: number;
|
||||
maxUses: number;
|
||||
expiresInDays: number | null;
|
||||
}): Promise<ActionResult<{ codes: string[] }>> {
|
||||
const session = await auth();
|
||||
if (!session?.user?.id || session.user.role !== "ADMIN") {
|
||||
return { success: false, error: "Unauthorized" };
|
||||
}
|
||||
|
||||
if (input.count < 1 || input.count > 25) {
|
||||
return { success: false, error: "Can generate between 1 and 25 codes at a time" };
|
||||
}
|
||||
|
||||
const expiresAt = input.expiresInDays
|
||||
? new Date(Date.now() + input.expiresInDays * 24 * 60 * 60 * 1000)
|
||||
: null;
|
||||
|
||||
const codes: string[] = [];
|
||||
|
||||
await prisma.$transaction(async (tx) => {
|
||||
for (let i = 0; i < input.count; i++) {
|
||||
const code = crypto.randomBytes(6).toString("hex");
|
||||
codes.push(code);
|
||||
await tx.inviteCode.create({
|
||||
data: {
|
||||
code,
|
||||
maxUses: input.maxUses,
|
||||
expiresAt,
|
||||
createdBy: session.user.id,
|
||||
},
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
revalidatePath("/invites");
|
||||
return { success: true, data: { codes } };
|
||||
}
|
||||
|
||||
export async function deleteInviteCode(id: string): Promise<ActionResult> {
|
||||
const session = await auth();
|
||||
if (!session?.user?.id || session.user.role !== "ADMIN") {
|
||||
@@ -48,7 +87,10 @@ export async function deleteInviteCode(id: string): Promise<ActionResult> {
|
||||
export async function getInviteCodes() {
|
||||
const codes = await prisma.inviteCode.findMany({
|
||||
orderBy: { createdAt: "desc" },
|
||||
include: { creator: { select: { name: true } } },
|
||||
include: {
|
||||
creator: { select: { name: true } },
|
||||
usedBy: { select: { id: true, name: true, email: true, createdAt: true } },
|
||||
},
|
||||
});
|
||||
return codes;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user