mirror of
https://github.com/rajnandan1/kener.git
synced 2026-06-23 04:10:22 +00:00
107 lines
3.7 KiB
TypeScript
107 lines
3.7 KiB
TypeScript
import type { Knex } from "knex";
|
|
import { permissions } from "../src/lib/allPerms.ts";
|
|
|
|
/**
|
|
* Seeds the three readonly roles (admin, editor, member),
|
|
* assigns permissions to each role in roles_permissions,
|
|
* and migrates existing users.role → users_roles.
|
|
*
|
|
* Permission mapping derived from src/routes/(manage)/manage/api/+server.ts:
|
|
*
|
|
* admin → all permissions
|
|
* editor → all except api_keys.delete (AdminCan-only)
|
|
* member → all .read permissions only
|
|
*/
|
|
|
|
const readonlyRoles = [
|
|
{ id: "admin", role_name: "Administrator" },
|
|
{ id: "editor", role_name: "Editor" },
|
|
{ id: "member", role_name: "Member" },
|
|
];
|
|
|
|
const allPermissionIds = permissions.map((p) => p.id);
|
|
const readPermissionIds = allPermissionIds.filter((id) => id.endsWith(".read"));
|
|
|
|
const rolePermissions: Record<string, string[]> = {
|
|
admin: allPermissionIds,
|
|
editor: allPermissionIds.filter((id) => id !== "api_keys.delete"),
|
|
member: readPermissionIds,
|
|
};
|
|
|
|
export async function seed(knex: Knex): Promise<void> {
|
|
// 1. Ensure readonly roles exist
|
|
for (const role of readonlyRoles) {
|
|
const existing = await knex("roles").where("id", role.id).first();
|
|
if (!existing) {
|
|
await knex("roles").insert({
|
|
id: role.id,
|
|
role_name: role.role_name,
|
|
readonly: 1,
|
|
status: "ACTIVE",
|
|
created_at: knex.fn.now(),
|
|
updated_at: knex.fn.now(),
|
|
});
|
|
}
|
|
}
|
|
|
|
// 2. Seed roles_permissions for readonly roles
|
|
// Only insert permissions that actually exist in the permissions table
|
|
// to avoid FK constraint errors if permissions seed hasn't run yet.
|
|
const existingPermRows: Array<{ id: string }> = await knex("permissions").select("id");
|
|
const existingPermIds = new Set(existingPermRows.map((p) => p.id));
|
|
|
|
for (const [roleId, permissionIds] of Object.entries(rolePermissions)) {
|
|
const validPermissionIds = permissionIds.filter((id) => existingPermIds.has(id));
|
|
|
|
const existingPerms: Array<{ permissions_id: string }> = await knex("roles_permissions")
|
|
.where("roles_id", roleId)
|
|
.select("permissions_id");
|
|
const existingSet = new Set(existingPerms.map((e) => e.permissions_id));
|
|
|
|
// Insert missing permissions
|
|
for (const permId of validPermissionIds) {
|
|
if (!existingSet.has(permId)) {
|
|
await knex("roles_permissions").insert({
|
|
roles_id: roleId,
|
|
permissions_id: permId,
|
|
status: "ACTIVE",
|
|
created_at: knex.fn.now(),
|
|
updated_at: knex.fn.now(),
|
|
});
|
|
}
|
|
}
|
|
|
|
// Remove permissions no longer assigned to this role
|
|
const desiredSet = new Set(validPermissionIds);
|
|
const toRemove = existingPerms.filter((e) => !desiredSet.has(e.permissions_id)).map((e) => e.permissions_id);
|
|
if (toRemove.length > 0) {
|
|
await knex("roles_permissions").where("roles_id", roleId).whereIn("permissions_id", toRemove).del();
|
|
}
|
|
}
|
|
|
|
// 3. Migrate existing users: read users.role → insert into users_roles
|
|
const hasRoleColumn = await knex.schema.hasColumn("users", "role");
|
|
if (hasRoleColumn) {
|
|
const users: Array<{ id: number; role: string }> = await knex("users").select("id", "role");
|
|
|
|
for (const user of users) {
|
|
if (!user.role) continue;
|
|
|
|
// Only migrate if a matching role exists
|
|
const roleExists = await knex("roles").where("id", user.role).first();
|
|
if (!roleExists) continue;
|
|
|
|
// Skip if already assigned
|
|
const existing = await knex("users_roles").where({ roles_id: user.role, users_id: user.id }).first();
|
|
if (!existing) {
|
|
await knex("users_roles").insert({
|
|
roles_id: user.role,
|
|
users_id: user.id,
|
|
created_at: knex.fn.now(),
|
|
updated_at: knex.fn.now(),
|
|
});
|
|
}
|
|
}
|
|
}
|
|
}
|