import type { EventRole, PhotoVisibility, PlatformRole } from "@album/contracts"; export const EVENT_PERMISSIONS = { OVERVIEW_READ: "overview.read", PHOTOS_READ: "photos.read", PHOTOS_MODERATE: "photos.moderate", PHOTOS_PRIVATE_READ: "photos.private.read", PHOTOS_DELETE: "photos.delete", SETTINGS_READ: "settings.read", SETTINGS_MANAGE: "settings.manage", PEOPLE_READ: "people.read", PEOPLE_MANAGE: "people.manage", PEOPLE_GRANT_OWNER: "people.grant_owner", EVENT_DELETE: "event.delete", NOTES_READ: "notes.read", GALLERY_RELEASE: "gallery.release", AUDIT_READ: "audit.read", } as const; export type EventPermission = (typeof EVENT_PERMISSIONS)[keyof typeof EVENT_PERMISSIONS]; export const GROUP_PERMISSIONS = { GROUP_READ: "group.read", GROUP_MANAGE: "group.manage", EVENTS_CREATE: "events.create", PEOPLE_MANAGE: "group.people.manage", } as const; export type GroupPermission = (typeof GROUP_PERMISSIONS)[keyof typeof GROUP_PERMISSIONS]; export const PLATFORM_PERMISSIONS = { SETTINGS_MANAGE: "platform.settings.manage", USERS_MANAGE: "platform.users.manage", GRANT_SUPER_ADMIN: "platform.roles.grant_super_admin", GRANT_ADMIN: "platform.roles.grant_admin", EVENTS_READ: "platform.events.read", EVENTS_MODERATE: "platform.events.moderate", ENTITLEMENTS_MANAGE: "platform.entitlements.manage", AUDIT_READ: "platform.audit.read", GROUPS_ACCESS: "platform.groups.access", } as const; export type PlatformPermission = (typeof PLATFORM_PERMISSIONS)[keyof typeof PLATFORM_PERMISSIONS]; const allEventPermissions = Object.values(EVENT_PERMISSIONS); export const EVENT_ROLES = { owner: { label: "Owner", description: "Full event access, including people and deletion.", permissions: allEventPermissions, }, manager: { label: "Manager", description: "Run the event without transferring ownership or deleting it.", permissions: allEventPermissions.filter( (permission) => permission !== EVENT_PERMISSIONS.EVENT_DELETE && permission !== EVENT_PERMISSIONS.PEOPLE_GRANT_OWNER, ), }, moderator: { label: "Moderator", description: "Review photos and notes. Cannot change settings or people.", permissions: [ EVENT_PERMISSIONS.OVERVIEW_READ, EVENT_PERMISSIONS.PHOTOS_READ, EVENT_PERMISSIONS.PHOTOS_MODERATE, EVENT_PERMISSIONS.PHOTOS_DELETE, EVENT_PERMISSIONS.NOTES_READ, ], }, viewer: { label: "Viewer", description: "See event photos, including hidden ones.", permissions: [ EVENT_PERMISSIONS.OVERVIEW_READ, EVENT_PERMISSIONS.PHOTOS_READ, EVENT_PERMISSIONS.NOTES_READ, ], }, } as const satisfies Record< EventRole, { label: string; description: string; permissions: readonly EventPermission[]; } >; export const GROUP_ROLES = { owner: { label: "Owner", permissions: Object.values(GROUP_PERMISSIONS), }, member: { label: "Member", permissions: [GROUP_PERMISSIONS.GROUP_READ], }, } as const; const allPlatformPermissions = Object.values(PLATFORM_PERMISSIONS); export const PLATFORM_ROLES = { super_admin: { label: "Super admin", permissions: allPlatformPermissions, }, admin: { label: "Admin", permissions: allPlatformPermissions.filter( (permission) => permission !== PLATFORM_PERMISSIONS.GRANT_SUPER_ADMIN, ), }, moderator: { label: "Platform moderator", permissions: [ PLATFORM_PERMISSIONS.EVENTS_READ, PLATFORM_PERMISSIONS.EVENTS_MODERATE, PLATFORM_PERMISSIONS.AUDIT_READ, PLATFORM_PERMISSIONS.GROUPS_ACCESS, ], }, viewer: { label: "Platform viewer", permissions: [ PLATFORM_PERMISSIONS.EVENTS_READ, PLATFORM_PERMISSIONS.AUDIT_READ, PLATFORM_PERMISSIONS.GROUPS_ACCESS, ], }, } as const satisfies Record< PlatformRole, { label: string; permissions: readonly PlatformPermission[]; } >; export function eventPermissionsForRole(role: EventRole): EventPermission[] { return [...EVENT_ROLES[role].permissions]; } export function groupPermissionsForRole( role: "owner" | "member", ): GroupPermission[] { return [...GROUP_ROLES[role].permissions]; } export function platformPermissionsForRole( role: PlatformRole, ): PlatformPermission[] { return [...PLATFORM_ROLES[role].permissions]; } export function platformEventPermissions( role: PlatformRole, ): EventPermission[] { if (role === "super_admin" || role === "admin") return allEventPermissions; if (role === "moderator") { return [ EVENT_PERMISSIONS.OVERVIEW_READ, EVENT_PERMISSIONS.PHOTOS_READ, EVENT_PERMISSIONS.PHOTOS_MODERATE, EVENT_PERMISSIONS.PHOTOS_PRIVATE_READ, EVENT_PERMISSIONS.PHOTOS_DELETE, EVENT_PERMISSIONS.NOTES_READ, EVENT_PERMISSIONS.AUDIT_READ, ]; } return [ EVENT_PERMISSIONS.OVERVIEW_READ, EVENT_PERMISSIONS.PHOTOS_READ, EVENT_PERMISSIONS.NOTES_READ, EVENT_PERMISSIONS.AUDIT_READ, EVENT_PERMISSIONS.SETTINGS_READ, EVENT_PERMISSIONS.PEOPLE_READ, ]; } export function platformGroupPermissions( role: PlatformRole, ): GroupPermission[] { if (role === "super_admin" || role === "admin") { return Object.values(GROUP_PERMISSIONS); } if (role === "moderator" || role === "viewer") { return [GROUP_PERMISSIONS.GROUP_READ]; } return []; } export const PUBLIC_VISIBILITIES: PhotoVisibility[] = ["public"]; export const MEMBER_VISIBILITIES: PhotoVisibility[] = [ "pending", "public", "hidden", "rejected", ]; export const PRIVATE_VISIBILITIES: PhotoVisibility[] = [ "pending", "public", "hidden", "private", "rejected", ];