diff --git a/database/migrations/1784800000000-addTicketCategoriesPermissions.ts b/database/migrations/1784800000000-addTicketCategoriesPermissions.ts new file mode 100644 index 0000000..c998280 --- /dev/null +++ b/database/migrations/1784800000000-addTicketCategoriesPermissions.ts @@ -0,0 +1,175 @@ +import { MigrationInterface, QueryRunner } from "typeorm"; + +const NEW_PERMISSIONS = [ + { name: "ticket_categories_create", title: "ایجاد دسته‌بندی تیکت", source: "tickets_create" }, + { name: "ticket_categories_read", title: "مشاهده دسته‌بندی تیکت", source: "tickets_read" }, + { name: "ticket_categories_update", title: "ویرایش دسته‌بندی تیکت", source: "tickets_update" }, + { name: "ticket_categories_delete", title: "حذف دسته‌بندی تیکت", source: "tickets_delete" }, +] as const; + +const CURRENT_ENUM_VALUES = [ + "services_create", + "services_read", + "services_update", + "services_delete", + "customers_create", + "customers_read", + "customers_update", + "customers_delete", + "agents_create", + "agents_read", + "agents_update", + "agents_delete", + "developers_create", + "developers_read", + "developers_update", + "developers_delete", + "invoices_create", + "invoices_read", + "invoices_update", + "invoices_delete", + "transactions_create", + "transactions_read", + "transactions_update", + "transactions_delete", + "discounts_create", + "discounts_read", + "discounts_update", + "discounts_delete", + "admins_create", + "admins_read", + "admins_update", + "admins_delete", + "tickets_create", + "tickets_read", + "tickets_update", + "tickets_delete", + "criticisms_create", + "criticisms_read", + "criticisms_update", + "criticisms_delete", + "contacts_us_create", + "contacts_us_read", + "contacts_us_update", + "contacts_us_delete", + "advertisements_create", + "advertisements_read", + "advertisements_update", + "advertisements_delete", + "announcements_create", + "announcements_read", + "announcements_update", + "announcements_delete", + "blogs_create", + "blogs_read", + "blogs_update", + "blogs_delete", + "learnings_create", + "learnings_read", + "learnings_update", + "learnings_delete", + "settings_create", + "settings_read", + "settings_update", + "settings_delete", + "bank_accounts_create", + "bank_accounts_read", + "bank_accounts_update", + "bank_accounts_delete", + "payments_create", + "payments_read", + "payments_update", + "payments_delete", + "support_plan_create", + "support_plan_read", + "support_plan_update", + "support_plan_delete", + "reseller_create", + "reseller_read", + "reseller_update", + "reseller_delete", + "workspace_create", + "workspace_read", + "workspace_update", + "workspace_delete", + "project_create", + "project_read", + "project_update", + "project_delete", + "task_create", + "task_read", + "task_update", + "task_delete", + "task_phase_create", + "task_phase_read", + "task_phase_update", + "task_phase_delete", + "logs", + "manage_sso_clients", + "dmenu", + "dkala", + "dpage", + "dmail", + "view_all_workspaces", + "view_all_projects", +]; + +const UPDATED_ENUM_VALUES = [ + ...CURRENT_ENUM_VALUES.slice(0, CURRENT_ENUM_VALUES.indexOf("tickets_delete") + 1), + ...NEW_PERMISSIONS.map((p) => p.name), + ...CURRENT_ENUM_VALUES.slice(CURRENT_ENUM_VALUES.indexOf("tickets_delete") + 1), +]; + +export class AddTicketCategoriesPermissions1784800000000 implements MigrationInterface { + name = "AddTicketCategoriesPermissions1784800000000"; + + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "permission" ALTER COLUMN "name" TYPE text USING "name"::text`); + await queryRunner.query(`DROP TYPE "public"."permission_name_enum"`); + + const enumList = UPDATED_ENUM_VALUES.map((v) => `'${v}'`).join(", "); + await queryRunner.query(`CREATE TYPE "public"."permission_name_enum" AS ENUM(${enumList})`); + await queryRunner.query( + `ALTER TABLE "permission" ALTER COLUMN "name" TYPE "public"."permission_name_enum" USING "name"::"public"."permission_name_enum"`, + ); + + for (const perm of NEW_PERMISSIONS) { + const inserted = await queryRunner.query( + `INSERT INTO "permission" ("id", "name", "title", "group", "createdAt", "updatedAt") + VALUES (uuid_generate_v4(), $1, $2, 'support', NOW(), NOW()) + RETURNING id`, + [perm.name, perm.title], + ); + const newId = inserted[0].id as string; + + const sourcePerm = await queryRunner.query(`SELECT id FROM "permission" WHERE "name" = $1`, [perm.source]); + if (!sourcePerm.length) continue; + + await queryRunner.query( + `INSERT INTO "role_permission_relation" ("roleId", "permissionId") + SELECT "roleId", $1 FROM "role_permission_relation" WHERE "permissionId" = $2 + ON CONFLICT ("roleId", "permissionId") DO NOTHING`, + [newId, sourcePerm[0].id], + ); + } + } + + public async down(queryRunner: QueryRunner): Promise { + for (const perm of NEW_PERMISSIONS) { + const rows = await queryRunner.query(`SELECT id FROM "permission" WHERE "name" = $1`, [perm.name]); + if (!rows.length) continue; + + await queryRunner.query(`DELETE FROM "role_permission_relation" WHERE "permissionId" = $1`, [rows[0].id]); + await queryRunner.query(`DELETE FROM "permission" WHERE "id" = $1`, [rows[0].id]); + } + + await queryRunner.query(`ALTER TABLE "permission" ALTER COLUMN "name" TYPE text USING "name"::text`); + await queryRunner.query(`DROP TYPE "public"."permission_name_enum"`); + + const enumList = CURRENT_ENUM_VALUES.map((v) => `'${v}'`).join(", "); + await queryRunner.query(`CREATE TYPE "public"."permission_name_enum" AS ENUM(${enumList})`); + await queryRunner.query( + `ALTER TABLE "permission" ALTER COLUMN "name" TYPE "public"."permission_name_enum" USING "name"::"public"."permission_name_enum"`, + ); + } +} diff --git a/src/modules/tickets/tickets.controller.ts b/src/modules/tickets/tickets.controller.ts index 7912a6d..f753e73 100755 --- a/src/modules/tickets/tickets.controller.ts +++ b/src/modules/tickets/tickets.controller.ts @@ -24,14 +24,14 @@ export class TicketsController { //----------------- ticket categories ------------------- @ApiOperation({ summary: "Create ticket category => admin route" }) - @PermissionsDec(PermissionEnum.TICKETS_CREATE) + @PermissionsDec(PermissionEnum.TICKET_CATEGORIES_CREATE) @Post("category") createTicketCategory(@Body() createDto: CreateTicketCategoryDto, @UserIpAndHeaders() userIpAndHeaders: IUserIpAndHeaders) { return this.ticketsService.createTicketCategory(createDto, userIpAndHeaders); } @ApiOperation({ summary: "Update ticket category => admin route" }) - @PermissionsDec(PermissionEnum.TICKETS_UPDATE) + @PermissionsDec(PermissionEnum.TICKET_CATEGORIES_UPDATE) @Patch("category/:id") updateCategory( @Param() paramDto: ParamDto, @@ -49,7 +49,7 @@ export class TicketsController { @ApiOperation({ summary: "Get ticket categories list => admin route" }) @AdminRoute() - @PermissionsDec(PermissionEnum.TICKETS_READ) + @PermissionsDec(PermissionEnum.TICKET_CATEGORIES_READ) @Get("categories-list") getCategoriesList(@Query() queryDto: SearchTicketCategoryDto) { return this.ticketsService.getCategoriesList(queryDto); @@ -58,7 +58,7 @@ export class TicketsController { @ApiOperation({ summary: "toggle status of categories => admin route" }) @AdminRoute() @HttpCode(HttpStatus.OK) - @PermissionsDec(PermissionEnum.TICKETS_UPDATE) + @PermissionsDec(PermissionEnum.TICKET_CATEGORIES_UPDATE) @Post("category/toggle-status/:id") toggleCategoryStatus(@Param() paramDto: ParamDto, @UserIpAndHeaders() userIpAndHeaders: IUserIpAndHeaders) { return this.ticketsService.toggleCategoryStatus(paramDto, userIpAndHeaders); diff --git a/src/modules/users/constants/permission-meta.ts b/src/modules/users/constants/permission-meta.ts index f1b9571..fbec28b 100644 --- a/src/modules/users/constants/permission-meta.ts +++ b/src/modules/users/constants/permission-meta.ts @@ -52,6 +52,11 @@ export const permissionMeta: Record = { [PermissionEnum.TICKETS_UPDATE]: { title: "ویرایش تیکت‌ها", group: PermissionGroupEnum.SUPPORT }, [PermissionEnum.TICKETS_DELETE]: { title: "حذف تیکت‌ها", group: PermissionGroupEnum.SUPPORT }, + [PermissionEnum.TICKET_CATEGORIES_CREATE]: { title: "ایجاد دسته‌بندی تیکت", group: PermissionGroupEnum.SUPPORT }, + [PermissionEnum.TICKET_CATEGORIES_READ]: { title: "مشاهده دسته‌بندی تیکت", group: PermissionGroupEnum.SUPPORT }, + [PermissionEnum.TICKET_CATEGORIES_UPDATE]: { title: "ویرایش دسته‌بندی تیکت", group: PermissionGroupEnum.SUPPORT }, + [PermissionEnum.TICKET_CATEGORIES_DELETE]: { title: "حذف دسته‌بندی تیکت", group: PermissionGroupEnum.SUPPORT }, + [PermissionEnum.CRITICISMS_CREATE]: { title: "ایجاد انتقادات", group: PermissionGroupEnum.OTHER }, [PermissionEnum.CRITICISMS_READ]: { title: "مشاهده انتقادات", group: PermissionGroupEnum.OTHER }, [PermissionEnum.CRITICISMS_UPDATE]: { title: "ویرایش انتقادات", group: PermissionGroupEnum.OTHER }, diff --git a/src/modules/users/enums/permission.enum.ts b/src/modules/users/enums/permission.enum.ts index 79d98d6..81c8014 100755 --- a/src/modules/users/enums/permission.enum.ts +++ b/src/modules/users/enums/permission.enum.ts @@ -53,6 +53,12 @@ export enum PermissionEnum { TICKETS_UPDATE = "tickets_update", TICKETS_DELETE = "tickets_delete", + // ticket_categories + TICKET_CATEGORIES_CREATE = "ticket_categories_create", + TICKET_CATEGORIES_READ = "ticket_categories_read", + TICKET_CATEGORIES_UPDATE = "ticket_categories_update", + TICKET_CATEGORIES_DELETE = "ticket_categories_delete", + // criticisms CRITICISMS_CREATE = "criticisms_create", CRITICISMS_READ = "criticisms_read",