diff --git a/src/tools/seed/seedRoles.ts b/src/tools/seed/seedRoles.ts index 07efc1b..b39c6f2 100644 --- a/src/tools/seed/seedRoles.ts +++ b/src/tools/seed/seedRoles.ts @@ -2,6 +2,17 @@ import { getPayload } from "payload"; import config from "@payload-config"; import type { Permission } from "@/permissions"; +const resolvedConfig = await config; +const COLLECTION_SLUGS = resolvedConfig.collections.map((c) => c.slug); + +const ALL_COLLECTION_READS: Permission[] = COLLECTION_SLUGS.map( + (slug) => `${slug}:read` as Permission, +); + +const ALL_ADMIN_PAGE_MANAGE: Permission[] = COLLECTION_SLUGS.map( + (slug) => `admin:${slug}:manage` as Permission, +); + const USER_PERMISSIONS: Permission[] = [ "users:read", "ranks:read", @@ -47,34 +58,38 @@ const USER_PERMISSIONS: Permission[] = [ ]; const ADMIN_PERMISSIONS: Permission[] = [ - ...USER_PERMISSIONS, - "system:admin-access", - "users:read", - "users:update", - "users:delete", - "technologies:create", - "technologies:read", - "technologies:update", - "technologies:delete", - "tickets:read", - "tickets:update", - "tickets:staff", - "bank-accounts:create", - "bank-accounts:update", - "user-notifications:read", - "user-notifications:update", - "mission-attendances:create", - "mission-attendances:read", - "mission-attendances:update", - "mission-attendances:delete", - "missions:read", - "market-negotiations:read", - "market-negotiations:update", - "logistics:manage", - "banking:manage", - "discord:staff", - "discord:announce", - "structures:create", + ...new Set([ + ...USER_PERMISSIONS, + "system:admin-access", + "users:read", + "users:update", + "users:delete", + "technologies:create", + "technologies:read", + "technologies:update", + "technologies:delete", + "tickets:read", + "tickets:update", + "tickets:staff", + "bank-accounts:create", + "bank-accounts:update", + "user-notifications:read", + "user-notifications:update", + "mission-attendances:create", + "mission-attendances:read", + "mission-attendances:update", + "mission-attendances:delete", + "missions:read", + "market-negotiations:read", + "market-negotiations:update", + "logistics:manage", + "banking:manage", + "discord:staff", + "discord:announce", + "structures:create", + ...ALL_COLLECTION_READS, + ...ALL_ADMIN_PAGE_MANAGE, + ]), ]; interface BuiltinRole { @@ -145,9 +160,36 @@ export const seedRoles = async () => { }); if (existing.docs.length > 0) { - const doc = existing.docs[0] as { id: number }; + const doc = existing.docs[0] as { + id: number; + isSystem?: boolean; + permissions?: Permission[] | null; + }; roleIdMap.set(role.slug, doc.id); - payload.logger.info(` Role "${role.slug}" already exists (id=${doc.id}), skipping.`); + + if (role.isSystem) { + const existingPerms = doc.permissions ?? []; + const missing = role.permissions.filter((p) => !existingPerms.includes(p)); + if (missing.length > 0) { + await payload.update({ + collection: "roles", + id: doc.id, + data: { permissions: [...existingPerms, ...missing] }, + overrideAccess: true, + }); + payload.logger.info( + ` Role "${role.slug}" (id=${doc.id}) updated with ${missing.length} missing built-in permission(s).`, + ); + } else { + payload.logger.info( + ` Role "${role.slug}" already exists (id=${doc.id}), permissions up to date.`, + ); + } + } else { + payload.logger.info( + ` Role "${role.slug}" already exists (id=${doc.id}), skipping (non-system).`, + ); + } continue; }