diff --git a/src/lib/services/permission-ranks.test.ts b/src/lib/services/permission-ranks.test.ts index b785bfe3c7..77ea221ae0 100644 --- a/src/lib/services/permission-ranks.test.ts +++ b/src/lib/services/permission-ranks.test.ts @@ -87,8 +87,7 @@ describe("RANK_GENERAL_FIELDS", () => { }); describe("fetchEmulatorRankForEdit", () => { - it("repairs a missing permission_definitions column before loading an existing rank", async () => { - let hasRankColumn = false; + it("loads permissions from the legacy table when permission_definitions is absent", async () => { const db = { execute: async (query: SQL | string) => { const text = queryText(query); @@ -105,15 +104,21 @@ describe("fetchEmulatorRankForEdit", () => { ]; } if (text.includes("FROM information_schema.columns")) { - return [[{ c: hasRankColumn ? 1 : 0 }], []]; + return [[], []]; } - if (text.includes("ALTER TABLE permission_definitions")) { - hasRankColumn = true; - return [{ affectedRows: 0 }, []]; - } - if (text.includes("FROM permission_definitions")) { - if (!hasRankColumn) throw new Error("Unknown column 'rank_11'"); - return [[{ permission_key: "cmd_ban", max_value: 1, value: 0 }], []]; + if (text.includes("FROM permissions")) { + return [ + [ + { + id: 11, + rank_name: "Developer", + level: 11, + cmd_ban: 1, + cmd_owner: 2, + }, + ], + [], + ]; } throw new Error(`Unexpected query: ${text}`); }, @@ -126,8 +131,8 @@ describe("fetchEmulatorRankForEdit", () => { fetchEmulatorRankForEdit(db as never, 11), ).resolves.toMatchObject({ id: 11, - permissions: { cmd_ban: "0" }, + permissions: { cmd_ban: "1", cmd_owner: "2" }, + permissionMaxValues: { cmd_ban: 1, cmd_owner: 2 }, }); - expect(hasRankColumn).toBe(true); }); }); diff --git a/src/lib/services/permission-ranks.ts b/src/lib/services/permission-ranks.ts index d8db442917..95f4643357 100644 --- a/src/lib/services/permission-ranks.ts +++ b/src/lib/services/permission-ranks.ts @@ -124,28 +124,52 @@ export async function fetchEmulatorRankForEdit( ); if (rankRows.length === 0) return null; - await ensurePermissionRankColumn(db, rankId); const rankColumn = getRankPermissionColumn(rankId); - const permissionRows = await rawRows< - { - permission_key: string; - max_value: number; - value: number | string | null; - }[] - >( - db, - sql` - SELECT permission_key, max_value, ${sql.raw(quoteIdentifier(rankColumn))} AS value - FROM permission_definitions - ORDER BY permission_key ASC - `, - ); - const permissions: Record = {}; const permissionMaxValues: Record = {}; - for (const row of permissionRows) { - permissions[row.permission_key] = String(row.value ?? 0); - permissionMaxValues[row.permission_key] = Number(row.max_value ?? 1); + const definitionColumns = await getTableColumns(db, "permission_definitions"); + if (definitionColumns.has(rankColumn)) { + const permissionRows = await rawRows< + { + permission_key: string; + max_value: number; + value: number | string | null; + }[] + >( + db, + sql` + SELECT permission_key, max_value, ${sql.raw(quoteIdentifier(rankColumn))} AS value + FROM permission_definitions + ORDER BY permission_key ASC + `, + ); + + for (const permission of permissionRows) { + permissions[permission.permission_key] = String(permission.value ?? 0); + permissionMaxValues[permission.permission_key] = Number( + permission.max_value ?? 1, + ); + } + } else { + const legacyRows = await rawRows[]>( + db, + sql`SELECT * FROM permissions WHERE id = ${rankId} LIMIT 1`, + ); + for (const [key, value] of Object.entries(legacyRows[0] ?? {})) { + if ( + key === "id" || + RANK_GENERAL_FIELDS.has(key) || + !VALID_KEY.test(key) + ) { + continue; + } + const permissionValue = + typeof value === "string" || typeof value === "number" + ? toPermissionValue(value) + : 0; + permissions[key] = String(permissionValue); + permissionMaxValues[key] = Math.max(1, permissionValue); + } } const row = rankRows[0];