SET NAMES utf8mb4 COLLATE utf8mb4_unicode_ci; -- 098-100 may already be recorded in production, so permission delegation is added -- incrementally instead of rewriting an executed migration. external_admin_accounts is a -- small credential table; adding a fixed-width column with INPLACE + LOCK=NONE may scan/rebuild -- only that table on older supported MySQL versions while allowing concurrent reads/writes. -- Run this outside credential-creation peaks even though no users/rooms/wallet table is touched. ALTER TABLE external_admin_accounts ADD COLUMN permission_revision BIGINT UNSIGNED NOT NULL DEFAULT 1 AFTER permissions_json, ALGORITHM=INPLACE, LOCK=NONE; -- Both RBAC lookup predicates below use unique indexes (admin_permissions.code and -- admin_roles.code); the final INSERT is guarded by admin_role_permissions(role_id, -- permission_id), touches one row, and scans no business, external-account or session table. SET @now_ms = CAST(UNIX_TIMESTAMP(UTC_TIMESTAMP(3)) * 1000 AS UNSIGNED); INSERT INTO admin_permissions (name, code, kind, description, created_at_ms, updated_at_ms) VALUES ('外管用户权限配置', 'external-admin-user:permissions', 'button', '配置当前 App 外管用户权限并撤销其现有会话', @now_ms, @now_ms) ON DUPLICATE KEY UPDATE name = VALUES(name), kind = VALUES(kind), description = VALUES(description), updated_at_ms = @now_ms; -- 权限配置可以扩大外部操作者的业务能力,只授予平台管理员;运营岗位仍只拥有 -- 098/099 中的查看与启停能力,不能通过本接口进行权限委派。 INSERT IGNORE INTO admin_role_permissions (role_id, permission_id) SELECT role.id, permission.id FROM admin_roles role JOIN admin_permissions permission WHERE role.code = 'platform-admin' AND permission.code = 'external-admin-user:permissions';