mirror of
https://github.com/rajnandan1/kener.git
synced 2026-06-23 04:10:22 +00:00
Implement indexing for users_roles table and enhance roles seeding logic to prevent FK constraint errors
This commit is contained in:
@@ -45,6 +45,7 @@ export async function up(knex: Knex): Promise<void> {
|
|||||||
table.timestamp("updated_at").defaultTo(knex.fn.now());
|
table.timestamp("updated_at").defaultTo(knex.fn.now());
|
||||||
|
|
||||||
table.primary(["roles_id", "users_id"]);
|
table.primary(["roles_id", "users_id"]);
|
||||||
|
table.index("users_id", "idx_users_roles_users_id");
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -34,9 +34,17 @@ export async function up(knex: Knex): Promise<void> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 2. Migrate users.role → users_roles
|
// 2. Read users.role into memory BEFORE dropping the column.
|
||||||
|
// On SQLite, dropColumn recreates the table (create → copy → drop → rename),
|
||||||
|
// which can discard DML inserts to tables with FKs pointing at users.
|
||||||
const users: Array<{ id: number; role: string }> = await knex("users").select("id", "role");
|
const users: Array<{ id: number; role: string }> = await knex("users").select("id", "role");
|
||||||
|
|
||||||
|
// 3. Drop the column first.
|
||||||
|
await knex.schema.alterTable("users", (table) => {
|
||||||
|
table.dropColumn("role");
|
||||||
|
});
|
||||||
|
|
||||||
|
// 4. Now populate users_roles from the in-memory snapshot.
|
||||||
for (const user of users) {
|
for (const user of users) {
|
||||||
const newRoleId = ROLE_MAP[user.role] ?? "member";
|
const newRoleId = ROLE_MAP[user.role] ?? "member";
|
||||||
|
|
||||||
@@ -51,11 +59,6 @@ export async function up(knex: Knex): Promise<void> {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 3. Now safe to drop the column
|
|
||||||
await knex.schema.alterTable("users", (table) => {
|
|
||||||
table.dropColumn("role");
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reverse map: pick the highest-precedence role when backfilling.
|
// Reverse map: pick the highest-precedence role when backfilling.
|
||||||
|
|||||||
+9
-2
@@ -45,14 +45,21 @@ export async function seed(knex: Knex): Promise<void> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 2. Seed roles_permissions for readonly roles
|
// 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)) {
|
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")
|
const existingPerms: Array<{ permissions_id: string }> = await knex("roles_permissions")
|
||||||
.where("roles_id", roleId)
|
.where("roles_id", roleId)
|
||||||
.select("permissions_id");
|
.select("permissions_id");
|
||||||
const existingSet = new Set(existingPerms.map((e) => e.permissions_id));
|
const existingSet = new Set(existingPerms.map((e) => e.permissions_id));
|
||||||
|
|
||||||
// Insert missing permissions
|
// Insert missing permissions
|
||||||
for (const permId of permissionIds) {
|
for (const permId of validPermissionIds) {
|
||||||
if (!existingSet.has(permId)) {
|
if (!existingSet.has(permId)) {
|
||||||
await knex("roles_permissions").insert({
|
await knex("roles_permissions").insert({
|
||||||
roles_id: roleId,
|
roles_id: roleId,
|
||||||
@@ -65,7 +72,7 @@ export async function seed(knex: Knex): Promise<void> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Remove permissions no longer assigned to this role
|
// Remove permissions no longer assigned to this role
|
||||||
const desiredSet = new Set(permissionIds);
|
const desiredSet = new Set(validPermissionIds);
|
||||||
const toRemove = existingPerms.filter((e) => !desiredSet.has(e.permissions_id)).map((e) => e.permissions_id);
|
const toRemove = existingPerms.filter((e) => !desiredSet.has(e.permissions_id)).map((e) => e.permissions_id);
|
||||||
if (toRemove.length > 0) {
|
if (toRemove.length > 0) {
|
||||||
await knex("roles_permissions").where("roles_id", roleId).whereIn("permissions_id", toRemove).del();
|
await knex("roles_permissions").where("roles_id", roleId).whereIn("permissions_id", toRemove).del();
|
||||||
|
|||||||
Reference in New Issue
Block a user