diff --git a/apps/web/public/static/locales/en/common.json b/apps/web/public/static/locales/en/common.json index 218524b1ff..df29e2f716 100644 --- a/apps/web/public/static/locales/en/common.json +++ b/apps/web/public/static/locales/en/common.json @@ -3510,10 +3510,20 @@ "pbac_desc_update_workflows": "Edit and modify workflow settings", "pbac_desc_delete_workflows": "Remove workflows from the system", "pbac_resource_webhook": "Webhook", + "pbac_resource_availability": "Availability", + "pbac_resource_out_of_office": "Out of Office", "pbac_desc_create_webhooks": "Create webhooks", "pbac_desc_view_webhooks": "View webhooks", "pbac_desc_update_webhooks": "Update webhooks", "pbac_desc_delete_webhooks": "Delete webhooks", + "pbac_desc_create_availability": "Create availability", + "pbac_desc_view_availability": "View availability", + "pbac_desc_update_availability": "Update availability", + "pbac_desc_delete_availability": "Delete availability", + "pbac_desc_create_out_of_office": "Create out of office", + "pbac_desc_view_out_of_office": "View out of office", + "pbac_desc_update_out_of_office": "Update out of office", + "pbac_desc_delete_out_of_office": "Delete out of office", "pbac_desc_manage_workflows": "Full management access to all workflows", "pbac_desc_create_event_types": "Create event types", "pbac_desc_view_event_types": "View event types", diff --git a/packages/features/pbac/domain/types/permission-registry.ts b/packages/features/pbac/domain/types/permission-registry.ts index 3cfbc54d9d..6c7608abf0 100644 --- a/packages/features/pbac/domain/types/permission-registry.ts +++ b/packages/features/pbac/domain/types/permission-registry.ts @@ -10,6 +10,8 @@ export enum Resource { RoutingForm = "routingForm", Workflow = "workflow", Webhook = "webhook", + Availability = "availability", + OutOfOffice = "ooo", } export enum CrudAction { @@ -114,6 +116,7 @@ export const isValidPermissionString = (val: unknown): val is PermissionString = * @returns A new object without the _resource property */ export const filterResourceConfig = (config: ResourceConfig): Omit => { + // eslint-disable-next-line @typescript-eslint/no-unused-vars const { _resource, ...rest } = config; return rest; }; @@ -556,4 +559,76 @@ export const PERMISSION_REGISTRY: PermissionRegistry = { dependsOn: ["webhook.read"], }, }, + [Resource.Availability]: { + _resource: { + i18nKey: "pbac_resource_availability", + }, + [CrudAction.Create]: { + description: "Create availability", + category: "availability", + i18nKey: "pbac_action_create", + descriptionI18nKey: "pbac_desc_create_availability", + scope: [], + dependsOn: ["availability.read"], + }, + [CrudAction.Read]: { + description: "View availability", + category: "availability", + i18nKey: "pbac_action_read", + descriptionI18nKey: "pbac_desc_view_availability", + scope: [], + }, + [CrudAction.Update]: { + description: "Update availability", + category: "availability", + i18nKey: "pbac_action_update", + descriptionI18nKey: "pbac_desc_update_availability", + scope: [], + dependsOn: ["availability.read"], + }, + [CrudAction.Delete]: { + description: "Delete availability", + category: "availability", + i18nKey: "pbac_action_delete", + descriptionI18nKey: "pbac_desc_delete_availability", + scope: [], + dependsOn: ["availability.read"], + }, + }, + [Resource.OutOfOffice]: { + _resource: { + i18nKey: "pbac_resource_out_of_office", + }, + [CrudAction.Create]: { + description: "Create out of office", + category: "ooo", + i18nKey: "pbac_action_create", + descriptionI18nKey: "pbac_desc_create_out_of_office", + scope: [], + dependsOn: ["ooo.read"], + }, + [CrudAction.Read]: { + description: "View out of office", + category: "ooo", + i18nKey: "pbac_action_read", + descriptionI18nKey: "pbac_desc_view_out_of_office", + scope: [], + }, + [CrudAction.Update]: { + description: "Update out of office", + category: "ooo", + i18nKey: "pbac_action_update", + descriptionI18nKey: "pbac_desc_update_out_of_office", + scope: [], + dependsOn: ["ooo.read"], + }, + [CrudAction.Delete]: { + description: "Delete out of office", + category: "ooo", + i18nKey: "pbac_action_delete", + descriptionI18nKey: "pbac_desc_delete_out_of_office", + scope: [], + dependsOn: ["ooo.read"], + }, + }, }; diff --git a/packages/prisma/migrations/20250925134226_add_availability_ooo_permissions_default_roles/migration.sql b/packages/prisma/migrations/20250925134226_add_availability_ooo_permissions_default_roles/migration.sql new file mode 100644 index 0000000000..b07c2deb70 --- /dev/null +++ b/packages/prisma/migrations/20250925134226_add_availability_ooo_permissions_default_roles/migration.sql @@ -0,0 +1,45 @@ +-- Add availability permissions for admin role (create, read, update, delete) +INSERT INTO "RolePermission" (id, "roleId", resource, action, "createdAt") +SELECT + gen_random_uuid(), 'admin_role', resource, action, NOW() +FROM ( + VALUES + ('availability', 'create'), + ('availability', 'read'), + ('availability', 'update'), + ('availability', 'delete') +) AS permissions(resource, action) +ON CONFLICT ("roleId", resource, action) DO NOTHING; + +-- Add ooo permissions for admin role (create, read, update, delete) +INSERT INTO "RolePermission" (id, "roleId", resource, action, "createdAt") +SELECT + gen_random_uuid(), 'admin_role', resource, action, NOW() +FROM ( + VALUES + ('ooo', 'create'), + ('ooo', 'read'), + ('ooo', 'update'), + ('ooo', 'delete') +) AS permissions(resource, action) +ON CONFLICT ("roleId", resource, action) DO NOTHING; + +-- Add availability read permission for member role +INSERT INTO "RolePermission" (id, "roleId", resource, action, "createdAt") +SELECT + gen_random_uuid(), 'member_role', resource, action, NOW() +FROM ( + VALUES + ('availability', 'read') +) AS permissions(resource, action) +ON CONFLICT ("roleId", resource, action) DO NOTHING; + +-- Add ooo read permission for member role +INSERT INTO "RolePermission" (id, "roleId", resource, action, "createdAt") +SELECT + gen_random_uuid(), 'member_role', resource, action, NOW() +FROM ( + VALUES + ('ooo', 'read') +) AS permissions(resource, action) +ON CONFLICT ("roleId", resource, action) DO NOTHING;