import { ok, err } from "@tailor-platform/erp-kit/core"; import type { Transaction } from "../generated/kysely-tailordb"; import { RoleAlreadyExistsError, MissingRequiredFieldError, InvalidPermissionError, } from "../lib/errors.generated"; import { validatePermissionKey } from "../lib/validatePermissionKey"; interface CreateRoleInput { name: string; description?: string; permissions?: string[]; } /** * Function: createRole * * Creates a new role with the specified name. * Validates that the name is unique within the system. */ export async function run>( db: Transaction, input: CreateRoleInput & CF, ) { const { name, description, permissions, ...customFields } = input; if (!name || name.trim() === "") { return err(new MissingRequiredFieldError("name")); } if (permissions) { for (const key of permissions) { if (!validatePermissionKey(key)) { return err(new InvalidPermissionError(key)); } } } const existingRole = await db .selectFrom("Role") .selectAll() .where("name", "=", name) .forUpdate() .executeTakeFirst(); if (existingRole) { return err(new RoleAlreadyExistsError(name)); } // 3. Create role const role = await db .insertInto("Role") .values({ ...(customFields as Record), name, description: description ?? null, permissions: permissions ?? null, status: "ACTIVE", }) .returningAll() .executeTakeFirstOrThrow(); return ok({ role }); }