import type { SelfRoleEntry, SelfRolePanelDashboard, SelfRolePanelDashboardCreate, SelfRolePanelDashboardUpdate } from '@nexumi/shared'; import type { Prisma, SelfRolePanel } from '@prisma/client'; import { prisma } from '../prisma'; function toRolesArray(raw: unknown): SelfRoleEntry[] { if (!Array.isArray(raw)) { return []; } return raw.filter( (entry): entry is SelfRoleEntry => Boolean(entry) && typeof entry === 'object' && typeof (entry as SelfRoleEntry).roleId === 'string' ); } function toDashboard(panel: SelfRolePanel): SelfRolePanelDashboard { return { id: panel.id, channelId: panel.channelId, title: panel.title, description: panel.description, mode: panel.mode as SelfRolePanelDashboard['mode'], behavior: panel.behavior as SelfRolePanelDashboard['behavior'], roles: toRolesArray(panel.roles), expiresAt: panel.expiresAt?.toISOString() ?? null }; } export async function listSelfRolePanels(guildId: string): Promise { const panels = await prisma.selfRolePanel.findMany({ where: { guildId }, orderBy: { createdAt: 'desc' } }); return panels.map(toDashboard); } export async function createSelfRolePanel( guildId: string, input: SelfRolePanelDashboardCreate ): Promise { await prisma.guild.upsert({ where: { id: guildId }, update: {}, create: { id: guildId } }); const panel = await prisma.selfRolePanel.create({ data: { guildId, channelId: input.channelId, title: input.title, description: input.description ?? null, mode: input.mode, behavior: input.behavior, roles: input.roles as unknown as Prisma.InputJsonValue, expiresAt: input.expiresAt ? new Date(input.expiresAt) : null } }); return toDashboard(panel); } export async function updateSelfRolePanel( guildId: string, panelId: string, patch: SelfRolePanelDashboardUpdate ): Promise { const existing = await prisma.selfRolePanel.findFirst({ where: { id: panelId, guildId } }); if (!existing) { return null; } const updated = await prisma.selfRolePanel.update({ where: { id: panelId }, data: { ...(patch.channelId !== undefined ? { channelId: patch.channelId } : {}), ...(patch.title !== undefined ? { title: patch.title } : {}), ...(patch.description !== undefined ? { description: patch.description } : {}), ...(patch.mode !== undefined ? { mode: patch.mode } : {}), ...(patch.behavior !== undefined ? { behavior: patch.behavior } : {}), ...(patch.roles !== undefined ? { roles: patch.roles as unknown as Prisma.InputJsonValue } : {}), ...(patch.expiresAt !== undefined ? { expiresAt: patch.expiresAt ? new Date(patch.expiresAt) : null } : {}) } }); return toDashboard(updated); } export async function deleteSelfRolePanel(guildId: string, panelId: string): Promise { const result = await prisma.selfRolePanel.deleteMany({ where: { id: panelId, guildId } }); return result.count > 0; }