'use server' import { revalidateTag } from 'next/cache' import { z } from 'zod' import { PERMS } from '@/lib/permission-slugs' import { prisma } from '@/lib/prisma' import { adminAction } from '@/lib/safe-action' import { ActionError, actionOk } from '@/lib/safe-action-shared' import { createEmulatorRank, deleteEmulatorRank, updateEmulatorRank } from '@/lib/services/permission-ranks' import { rcon } from '@/lib/services/rcon' import { logStaffActivity } from '@/lib/services/staff-activity' const createRankSchema = z.object({ rank_name: z.string().trim().min(1).max(25), level: z.coerce.number().int().min(1), }) export const createRank = adminAction( { schema: createRankSchema, permission: PERMS.PERMISSIONS_MANAGE }, async (ctx) => { const id = await createEmulatorRank(prisma, ctx.data) await prisma.aclRole.upsert({ where: { slug: `rank_${id}` }, create: { slug: `rank_${id}`, title: ctx.data.rank_name, description: 'CMS role synchronized from permission_ranks' }, update: { title: ctx.data.rank_name }, }) await logStaffActivity({ staffId: ctx.session.user.id, action: 'rank_create', description: `Created rank #${id}`, targetType: 'rank', targetId: id }) await rcon.send('updatepermissions') revalidateTag('permissions', { expire: 0 }) return actionOk({ id }) }, ) const deleteRankSchema = z.object({ id: z.coerce.number().int().positive() }) export const deleteRank = adminAction( { schema: deleteRankSchema, permission: PERMS.PERMISSIONS_MANAGE }, async (ctx) => { const users = await prisma.user.count({ where: { rank: ctx.data.id } }) if (users > 0) throw new ActionError(`Cannot delete: ${users} users have this rank`) const role = await prisma.aclRole.findFirst({ where: { slug: `rank_${ctx.data.id}` } }) await deleteEmulatorRank(prisma, ctx.data.id) if (role) { await prisma.$transaction([ prisma.aclModelPermission.deleteMany({ where: { modelId: role.id, modelType: 'Role' } }), prisma.aclModelRole.deleteMany({ where: { roleId: role.id } }), prisma.aclRole.delete({ where: { id: role.id } }), ]) } await logStaffActivity({ staffId: ctx.session.user.id, action: 'rank_delete', description: `Deleted rank #${ctx.data.id}`, targetType: 'rank', targetId: ctx.data.id }) await rcon.send('updatepermissions') revalidateTag('permissions', { expire: 0 }) return actionOk() }, ) const saveRankSchema = z.object({ id: z.coerce.number().int().positive(), fields: z.record(z.string(), z.union([z.string(), z.number()])), }) export const saveRank = adminAction( { schema: saveRankSchema, permission: PERMS.PERMISSIONS_MANAGE }, async (ctx) => { await updateEmulatorRank(prisma, ctx.data.id, ctx.data.fields) if (typeof ctx.data.fields.rank_name === 'string') { await prisma.aclRole.updateMany({ where: { slug: `rank_${ctx.data.id}` }, data: { title: ctx.data.fields.rank_name } }) } await logStaffActivity({ staffId: ctx.session.user.id, action: 'rank_update', description: `Updated rank #${ctx.data.id}`, targetType: 'rank', targetId: ctx.data.id }) await rcon.send('updatepermissions') revalidateTag('permissions', { expire: 0 }) return actionOk() }, ) const setCmsPermsSchema = z.object({ roleId: z.coerce.number().int().positive(), permissionSlugs: z.array(z.string().trim().min(1)).max(500), }) export const setCmsPermissions = adminAction( { schema: setCmsPermsSchema, permission: PERMS.PERMISSIONS_MANAGE }, async (ctx) => { const role = await prisma.aclRole.findUnique({ where: { id: ctx.data.roleId }, select: { id: true, slug: true } }) if (!role) throw new ActionError('Role not found') const permissions = await prisma.aclPermission.findMany({ where: { slug: { in: ctx.data.permissionSlugs } }, select: { id: true }, }) await prisma.$transaction(async (tx) => { await tx.aclModelPermission.deleteMany({ where: { modelId: role.id, modelType: 'Role' } }) if (permissions.length) { await tx.aclModelPermission.createMany({ data: permissions.map((permission) => ({ modelId: role.id, modelType: 'Role', permissionId: permission.id })), }) } }) await logStaffActivity({ staffId: ctx.session.user.id, action: 'acl_role_permissions_update', description: `Updated ${permissions.length} permissions for ${role.slug}`, targetType: 'acl_role', targetId: role.id }) revalidateTag('permissions', { expire: 0 }) return actionOk() }, )