-- ============================================================
-- 后端 API 资源表
-- ============================================================

CREATE SCHEMA IF NOT EXISTS sys;

CREATE TABLE sys.resource (
    id            BIGSERIAL    PRIMARY KEY,
    resource_name VARCHAR(128) NOT NULL,
    resource_code VARCHAR(128) NOT NULL,
    method        VARCHAR(16)  NOT NULL,
    path          VARCHAR(256) NOT NULL,
    description   VARCHAR(512) NOT NULL DEFAULT '',
    enabled       BOOLEAN      NOT NULL DEFAULT TRUE,
    create_time   TIMESTAMP    NOT NULL DEFAULT CURRENT_TIMESTAMP,
    update_time   TIMESTAMP    NOT NULL DEFAULT CURRENT_TIMESTAMP
);

CREATE UNIQUE INDEX uk_sys_resource_code ON sys.resource (resource_code);
CREATE UNIQUE INDEX uk_sys_resource_method_path ON sys.resource (method, path);
CREATE INDEX idx_sys_resource_enabled ON sys.resource (enabled);

COMMENT ON TABLE sys.resource IS '后端 API 资源表';
COMMENT ON COLUMN sys.resource.id IS '资源ID';
COMMENT ON COLUMN sys.resource.resource_name IS '资源名称';
COMMENT ON COLUMN sys.resource.resource_code IS '资源编码';
COMMENT ON COLUMN sys.resource.method IS 'HTTP 方法';
COMMENT ON COLUMN sys.resource.path IS 'API 路径，支持 {param} 参数形式';
COMMENT ON COLUMN sys.resource.description IS '资源说明';
COMMENT ON COLUMN sys.resource.enabled IS '是否启用资源权限';
COMMENT ON COLUMN sys.resource.create_time IS '创建时间';
COMMENT ON COLUMN sys.resource.update_time IS '更新时间';

-- ============================================================
-- 操作资源关联表
-- 当前 action_menu_id 指向 sys.menu.id，且该菜单应为 menu_type = 2(Button)。
-- ============================================================

CREATE TABLE sys.action_resource (
    id             BIGSERIAL PRIMARY KEY,
    action_menu_id BIGINT    NOT NULL,
    resource_id    BIGINT    NOT NULL
);

CREATE UNIQUE INDEX uk_sys_action_resource ON sys.action_resource (action_menu_id, resource_id);
CREATE INDEX idx_sys_action_resource_action_menu_id ON sys.action_resource (action_menu_id);
CREATE INDEX idx_sys_action_resource_resource_id ON sys.action_resource (resource_id);

COMMENT ON TABLE sys.action_resource IS '操作与后端 API 资源关联表';
COMMENT ON COLUMN sys.action_resource.id IS '主键ID';
COMMENT ON COLUMN sys.action_resource.action_menu_id IS '操作ID，当前复用 sys.menu.id(menu_type=2)';
COMMENT ON COLUMN sys.action_resource.resource_id IS '后端 API 资源ID';

-- ============================================================
-- 初始化资源
--
-- 资源表可以逐步补齐。未录入 sys.resource 的接口保持兼容放行。
-- 已录入且绑定 Action 的接口会执行后端资源权限校验。
-- 已录入但未绑定 Action 的接口作为资源清单保留，仍保持放行。
-- ============================================================

INSERT INTO sys.resource (resource_name, resource_code, method, path, description)
VALUES
    ('当前用户菜单树', 'system:menu:current-tree.query', 'GET', '/api/v3/system/menus', '查询当前登录用户可见菜单树'),
    ('当前用户信息', 'system:user:info.query', 'GET', '/api/user/info', '查询当前登录用户信息'),
    ('用户列表', 'system:user:list.query', 'GET', '/api/user/list', '用户管理列表查询'),
    ('用户详情', 'system:user:detail.query', 'GET', '/api/user/{id}', '用户详情查询'),
    ('创建用户', 'system:user:create.submit', 'POST', '/api/user', '提交创建用户'),
    ('更新用户', 'system:user:update.submit', 'PUT', '/api/user/{id}', '提交更新用户'),
    ('删除用户', 'system:user:delete.submit', 'DELETE', '/api/user/{id}', '删除用户'),
    ('重置用户密码', 'system:user:reset-password.submit', 'PUT', '/api/user/{id}/reset-password', '重置用户密码'),
    ('角色列表', 'system:role:list.query', 'GET', '/api/role/list', '角色管理列表查询'),
    ('创建角色', 'system:role:create.submit', 'POST', '/api/role', '提交创建角色'),
    ('更新角色', 'system:role:update.submit', 'PUT', '/api/role/{role_id}', '提交更新角色'),
    ('删除角色', 'system:role:delete.submit', 'DELETE', '/api/role/{role_id}', '删除角色'),
    ('角色权限详情', 'system:role:permission.query', 'GET', '/api/role/{role_id}/permissions', '查询角色菜单权限'),
    ('保存角色权限', 'system:role:permission.submit', 'PUT', '/api/role/{role_id}/permissions', '保存角色菜单权限'),
    ('菜单列表', 'system:menu:list.query', 'GET', '/api/system/menu/list', '菜单管理列表查询'),
    ('创建菜单', 'system:menu:create.submit', 'POST', '/api/system/menu', '提交创建菜单'),
    ('创建按钮', 'system:button:create.submit', 'POST', '/api/system/button', '提交创建按钮'),
    ('更新菜单', 'system:menu:update.submit', 'PUT', '/api/system/menu/{id}', '提交更新菜单'),
    ('更新按钮', 'system:button:update.submit', 'PUT', '/api/system/button/{id}', '提交更新按钮'),
    ('删除菜单或按钮', 'system:menu:delete.submit', 'DELETE', '/api/system/menu/{id}', '删除菜单或按钮'),
    ('配置分组列表', 'system:config-group:list.query', 'GET', '/api/config/group/list', '配置分组列表查询'),
    ('配置分组详情', 'system:config-group:detail.query', 'GET', '/api/config/group/{id}', '配置分组详情查询'),
    ('创建配置分组', 'system:config-group:create.submit', 'POST', '/api/config/group', '提交创建配置分组'),
    ('更新配置分组', 'system:config-group:update.submit', 'PUT', '/api/config/group/{id}', '提交更新配置分组'),
    ('删除配置分组', 'system:config-group:delete.submit', 'DELETE', '/api/config/group/{id}', '删除配置分组'),
    ('分组配置列表', 'system:config:list.query', 'GET', '/api/config/grouped', '按分组查询系统配置'),
    ('配置 Key 查询', 'system:config:by-key.query', 'GET', '/api/config/by-key/{config_key}', '按配置 Key 查询配置值'),
    ('配置 Key 批量查询', 'system:config:by-keys.query', 'POST', '/api/config/by-keys', '按配置 Key 批量查询配置值'),
    ('配置详情', 'system:config:detail.query', 'GET', '/api/config/{id}', '系统配置详情查询'),
    ('创建配置', 'system:config:create.submit', 'POST', '/api/config', '提交创建系统配置'),
    ('更新配置', 'system:config:update.submit', 'PUT', '/api/config/{id}', '提交更新系统配置'),
    ('删除配置', 'system:config:delete.submit', 'DELETE', '/api/config/{id}', '删除系统配置'),
    ('公告列表', 'system:notice:list.query', 'GET', '/api/notice/list', '公告列表查询'),
    ('公告详情', 'system:notice:detail.query', 'GET', '/api/notice/{id}', '公告详情查询'),
    ('创建公告', 'system:notice:create.submit', 'POST', '/api/notice', '提交创建公告'),
    ('更新公告', 'system:notice:update.submit', 'PUT', '/api/notice/{id}', '提交更新公告'),
    ('删除公告', 'system:notice:delete.submit', 'DELETE', '/api/notice/{id}', '删除公告'),
    ('发布公告', 'system:notice:publish.submit', 'PUT', '/api/notice/{id}/publish', '发布公告'),
    ('撤回公告', 'system:notice:revoke.submit', 'PUT', '/api/notice/{id}/revoke', '撤回公告'),
    ('置顶公告', 'system:notice:pin.submit', 'PUT', '/api/notice/{id}/pin', '置顶公告'),
    ('取消置顶公告', 'system:notice:unpin.submit', 'PUT', '/api/notice/{id}/unpin', '取消置顶公告'),
    ('通知中心列表', 'system:user-notice:list.query', 'GET', '/api/user/notice/list', '当前用户通知列表查询'),
    ('最新通知', 'system:user-notice:latest.query', 'GET', '/api/user/notice/latest', '当前用户最新通知查询'),
    ('未读通知数', 'system:user-notice:unread-count.query', 'GET', '/api/user/notice/unread-count', '当前用户未读通知数量查询'),
    ('通知详情', 'system:user-notice:detail.query', 'GET', '/api/user/notice/{id}', '当前用户通知详情查询'),
    ('标记通知已读', 'system:user-notice:read.submit', 'PUT', '/api/user/notice/{id}/read', '标记单条通知已读'),
    ('全部通知已读', 'system:user-notice:read-all.submit', 'PUT', '/api/user/notice/read-all', '标记全部通知已读'),
    ('在线用户列表', 'system:online:list.query', 'GET', '/api/online/list', '在线用户列表查询'),
    ('强制下线用户', 'system:online:kick.submit', 'DELETE', '/api/online/{login_id}', '强制指定登录用户下线'),
    ('强制下线用户设备', 'system:online:kick-device.submit', 'DELETE', '/api/online/{login_id}/{device}', '强制指定登录用户设备下线'),
    ('字典类型列表', 'system:dict-type:list.query', 'GET', '/api/dict/type/list', '字典类型列表查询'),
    ('创建字典类型', 'system:dict-type:create.submit', 'POST', '/api/dict/type', '提交创建字典类型'),
    ('更新字典类型', 'system:dict-type:update.submit', 'PUT', '/api/dict/type/{id}', '提交更新字典类型'),
    ('删除字典类型', 'system:dict-type:delete.submit', 'DELETE', '/api/dict/type/{id}', '删除字典类型'),
    ('字典数据列表', 'system:dict-data:list.query', 'GET', '/api/dict/data/list', '字典数据列表查询'),
    ('按类型查询字典数据', 'system:dict-data:by-type.query', 'GET', '/api/dict/data/by-type/{dict_type}', '按字典类型查询字典数据'),
    ('全部字典数据', 'system:dict-data:all.query', 'GET', '/api/dict/all', '查询全部启用字典数据'),
    ('创建字典数据', 'system:dict-data:create.submit', 'POST', '/api/dict/data', '提交创建字典数据'),
    ('更新字典数据', 'system:dict-data:update.submit', 'PUT', '/api/dict/data/{id}', '提交更新字典数据'),
    ('删除字典数据', 'system:dict-data:delete.submit', 'DELETE', '/api/dict/data/{id}', '删除字典数据'),
    ('登录日志列表', 'system:login-log:list.query', 'GET', '/api/login-log/list', '登录日志列表查询'),
    ('操作日志列表', 'system:operation-log:list.query', 'GET', '/api/operation-log/list', '操作日志列表查询'),
    ('操作日志详情', 'system:operation-log:detail.query', 'GET', '/api/operation-log/{id}', '操作日志详情查询'),
    ('服务器监控', 'system:monitor:server.query', 'GET', '/api/monitor/server', '查询服务器监控信息'),
    ('缓存监控信息', 'system:monitor:cache-info.query', 'GET', '/api/monitor/cache/info', '查询缓存监控信息'),
    ('缓存键列表', 'system:monitor:cache-keys.query', 'GET', '/api/monitor/cache/keys', '查询缓存键列表'),
    ('缓存键详情', 'system:monitor:cache-key-detail.query', 'GET', '/api/monitor/cache/keys/{key}/value', '查询缓存键详情'),
    ('删除缓存键', 'system:monitor:cache-key-delete.submit', 'DELETE', '/api/monitor/cache/keys/{key}', '删除指定缓存键'),
    ('批量删除缓存键', 'system:monitor:cache-keys-delete.submit', 'DELETE', '/api/monitor/cache/keys', '按模式批量删除缓存键'),
    ('任务列表', 'scheduler:job:list.query', 'GET', '/api/job/list', '任务管理列表查询'),
    ('任务详情', 'scheduler:job:detail.query', 'GET', '/api/job/{id}', '任务详情查询'),
    ('创建任务', 'scheduler:job:create.submit', 'POST', '/api/job', '提交创建任务'),
    ('更新任务', 'scheduler:job:update.submit', 'PUT', '/api/job/{id}', '提交更新任务'),
    ('删除任务', 'scheduler:job:delete.submit', 'DELETE', '/api/job/{id}', '删除任务'),
    ('触发任务', 'scheduler:job:trigger.submit', 'POST', '/api/job/{id}/trigger', '手动触发任务'),
    ('启用任务', 'scheduler:job:enable.submit', 'PUT', '/api/job/{id}/enable', '启用任务'),
    ('停用任务', 'scheduler:job:disable.submit', 'PUT', '/api/job/{id}/disable', '停用任务'),
    ('任务执行记录', 'scheduler:run:list.query', 'GET', '/api/job/{id}/tasks', '查询任务执行记录'),
    ('任务最新执行历史', 'scheduler:run:latest-history.query', 'GET', '/api/job/{id}/latest-history', '查询任务最新执行历史'),
    ('按 Key 查询任务 ID', 'scheduler:job:query-id-by-key.query', 'GET', '/api/job/query-id-by-key', '按任务 Key 查询任务 ID'),
    ('按 Key 查询任务详情', 'scheduler:job:query-by-key.query', 'GET', '/api/job/query-by-key', '按任务 Key 查询任务详情'),
    ('任务命名空间列表', 'scheduler:job:namespaces.query', 'GET', '/api/job/namespaces', '查询任务命名空间列表'),
    ('任务应用列表', 'scheduler:job:apps.query', 'GET', '/api/job/apps', '查询任务应用列表'),
    ('文件列表', 'file:manage:list.query', 'GET', '/api/file/list', '文件管理列表查询'),
    ('文件详情', 'file:manage:detail.query', 'GET', '/api/file/{id}', '文件详情查询'),
    ('删除文件', 'file:manage:delete.submit', 'DELETE', '/api/file/{id}', '删除文件'),
    ('生成文件公开链接', 'file:manage:share.create', 'POST', '/api/file/{id}/public-link', '生成文件公开分享链接'),
    ('撤销文件公开链接', 'file:manage:share.delete', 'DELETE', '/api/file/{id}/public-link', '撤销文件公开分享链接'),
    ('更新文件可见性', 'file:manage:visibility.update', 'PUT', '/api/file/{id}/visibility', '更新文件可见性'),
    ('更新文件状态', 'file:manage:status.update', 'PUT', '/api/file/{id}/status', '更新文件状态'),
    ('更新文件展示名', 'file:manage:display-name.update', 'PUT', '/api/file/{id}/display-name', '更新文件展示名称'),
    ('移动文件', 'file:manage:move.update', 'PUT', '/api/file/{id}/move', '移动文件到目录'),
    ('代理上传文件', 'file:manage:upload.submit', 'POST', '/api/file/upload', '通过后端中转上传单个文件'),
    ('代理批量上传文件', 'file:manage:upload-batch.submit', 'POST', '/api/file/upload/batch', '通过后端中转批量上传文件'),
    ('生成预签名上传链接', 'file:manage:presign-upload.submit', 'POST', '/api/file/presign/upload', '生成预签名上传地址'),
    ('确认预签名上传', 'file:manage:presign-upload-callback.submit', 'POST', '/api/file/presign/upload/callback', '确认预签名上传并入库'),
    ('生成预签名下载链接', 'file:manage:presign-download.query', 'GET', '/api/file/{id}/presign/download', '生成预签名下载地址'),
    ('代理下载文件', 'file:manage:download.query', 'GET', '/api/file/{id}/download', '通过后端代理下载文件'),
    ('初始化分片上传', 'file:manage:multipart-init.submit', 'POST', '/api/file/multipart/init', '初始化分片上传'),
    ('查询分片上传进度', 'file:manage:multipart-parts.query', 'GET', '/api/file/multipart/parts', '查询已上传分片'),
    ('完成分片上传', 'file:manage:multipart-complete.submit', 'POST', '/api/file/multipart/complete', '完成分片上传'),
    ('取消分片上传', 'file:manage:multipart-abort.submit', 'POST', '/api/file/multipart/abort', '取消分片上传'),
    ('文件夹树', 'file:folder:tree.query', 'GET', '/api/file/folder/tree', '查询文件夹树'),
    ('文件夹详情', 'file:folder:detail.query', 'GET', '/api/file/folder/{id}', '查询文件夹详情'),
    ('创建文件夹', 'file:folder:create.submit', 'POST', '/api/file/folder', '提交创建文件夹'),
    ('更新文件夹', 'file:folder:update.submit', 'PUT', '/api/file/folder/{id}', '提交更新文件夹'),
    ('删除文件夹', 'file:folder:delete.submit', 'DELETE', '/api/file/folder/{id}', '删除文件夹'),
    ('资源列表', 'system:resource:list.query', 'GET', '/api/system/resource/list', '资源权限管理列表查询'),
    ('资源选项', 'system:resource:options.query', 'GET', '/api/system/resource/options', '查询资源下拉选项'),
    ('资源详情', 'system:resource:detail.query', 'GET', '/api/system/resource/{id}', '资源权限管理详情查询'),
    ('创建资源', 'system:resource:create.submit', 'POST', '/api/system/resource', '提交创建后端 API 资源'),
    ('更新资源', 'system:resource:update.submit', 'PUT', '/api/system/resource/{id}', '提交更新后端 API 资源'),
    ('启停资源', 'system:resource:enabled.submit', 'PUT', '/api/system/resource/{id}/enabled', '启用或停用后端 API 资源'),
    ('删除资源', 'system:resource:delete.submit', 'DELETE', '/api/system/resource/{id}', '删除后端 API 资源'),
    ('按钮资源绑定详情', 'system:resource:action-binding.query', 'GET', '/api/system/action-resource/action/{action_menu_id}', '查询按钮权限绑定的资源'),
    ('保存按钮资源绑定', 'system:resource:action-binding.submit', 'PUT', '/api/system/action-resource/action/{action_menu_id}', '保存按钮权限绑定的资源'),
    ('资源关联按钮', 'system:resource:resource-actions.query', 'GET', '/api/system/action-resource/resource/{resource_id}', '查询资源关联的按钮权限'),
    ('刷新资源权限策略', 'system:resource:reload.submit', 'POST', '/api/system/resource-permission/reload', '刷新内存中的资源权限策略')
ON CONFLICT (resource_code) DO NOTHING;

INSERT INTO sys.action_resource (action_menu_id, resource_id)
SELECT m.id, r.id
FROM sys.menu m
JOIN (
    VALUES
        ('system:user:list', 'system:user:list.query'),
        ('system:user:list', 'system:user:detail.query'),
        ('system:user:create', 'system:user:create.submit'),
        ('system:user:create', 'system:role:list.query'),
        ('system:user:update', 'system:user:detail.query'),
        ('system:user:update', 'system:user:update.submit'),
        ('system:user:update', 'system:role:list.query'),
        ('system:user:delete', 'system:user:delete.submit'),
        ('system:user:reset-password', 'system:user:detail.query'),
        ('system:user:reset-password', 'system:user:reset-password.submit'),
        ('system:role:list', 'system:role:list.query'),
        ('system:role:create', 'system:role:create.submit'),
        ('system:role:update', 'system:role:list.query'),
        ('system:role:update', 'system:role:update.submit'),
        ('system:role:delete', 'system:role:delete.submit'),
        ('system:role:permission', 'system:role:permission.query'),
        ('system:role:permission', 'system:role:permission.submit'),
        ('system:role:permission', 'system:menu:list.query'),
        ('system:menu:list', 'system:menu:list.query'),
        ('system:menu:create', 'system:menu:list.query'),
        ('system:menu:create', 'system:menu:create.submit'),
        ('system:menu:update', 'system:menu:list.query'),
        ('system:menu:update', 'system:menu:update.submit'),
        ('system:menu:delete', 'system:menu:delete.submit'),
        ('system:button:create', 'system:menu:list.query'),
        ('system:button:create', 'system:button:create.submit'),
        ('system:button:update', 'system:menu:list.query'),
        ('system:button:update', 'system:button:update.submit'),
        ('system:resource:list', 'system:resource:list.query'),
        ('system:resource:list', 'system:resource:options.query'),
        ('system:resource:list', 'system:resource:detail.query'),
        ('system:resource:list', 'system:resource:resource-actions.query'),
        ('system:resource:create', 'system:resource:create.submit'),
        ('system:resource:update', 'system:resource:detail.query'),
        ('system:resource:update', 'system:resource:update.submit'),
        ('system:resource:update', 'system:resource:enabled.submit'),
        ('system:resource:delete', 'system:resource:delete.submit'),
        ('system:resource:bind', 'system:resource:options.query'),
        ('system:resource:bind', 'system:resource:action-binding.query'),
        ('system:resource:bind', 'system:resource:action-binding.submit'),
        ('system:resource:bind', 'system:resource:resource-actions.query'),
        ('system:resource:reload', 'system:resource:reload.submit'),
        ('system:config:list', 'system:config:list.query'),
        ('system:config:list', 'system:config:detail.query'),
        ('system:config:create', 'system:config:list.query'),
        ('system:config:create', 'system:config-group:list.query'),
        ('system:config:create', 'system:config:create.submit'),
        ('system:config:update', 'system:config:detail.query'),
        ('system:config:update', 'system:config-group:list.query'),
        ('system:config:update', 'system:config:update.submit'),
        ('system:config:delete', 'system:config:delete.submit'),
        ('system:config-group:list', 'system:config-group:list.query'),
        ('system:config-group:list', 'system:config-group:detail.query'),
        ('system:config-group:create', 'system:config-group:create.submit'),
        ('system:config-group:update', 'system:config-group:detail.query'),
        ('system:config-group:update', 'system:config-group:update.submit'),
        ('system:config-group:delete', 'system:config-group:delete.submit'),
        ('system:notice:list', 'system:notice:list.query'),
        ('system:notice:list', 'system:notice:detail.query'),
        ('system:notice:create', 'system:notice:create.submit'),
        ('system:notice:update', 'system:notice:detail.query'),
        ('system:notice:update', 'system:notice:update.submit'),
        ('system:notice:delete', 'system:notice:delete.submit'),
        ('system:notice:publish', 'system:notice:detail.query'),
        ('system:notice:publish', 'system:notice:publish.submit'),
        ('system:notice:revoke', 'system:notice:detail.query'),
        ('system:notice:revoke', 'system:notice:revoke.submit'),
        ('system:notice:pin', 'system:notice:detail.query'),
        ('system:notice:pin', 'system:notice:pin.submit'),
        ('system:notice:pin', 'system:notice:unpin.submit'),
        ('system:user-notice:list', 'system:user-notice:list.query'),
        ('system:user-notice:list', 'system:user-notice:latest.query'),
        ('system:user-notice:list', 'system:user-notice:unread-count.query'),
        ('system:user-notice:list', 'system:user-notice:detail.query'),
        ('system:user-notice:read', 'system:user-notice:read.submit'),
        ('system:user-notice:read', 'system:user-notice:read-all.submit'),
        ('system:online:list', 'system:online:list.query'),
        ('system:online:kick', 'system:online:kick.submit'),
        ('system:online:kick', 'system:online:kick-device.submit'),
        ('system:dict-type:list', 'system:dict-type:list.query'),
        ('system:dict-type:create', 'system:dict-type:create.submit'),
        ('system:dict-type:update', 'system:dict-type:list.query'),
        ('system:dict-type:update', 'system:dict-type:update.submit'),
        ('system:dict-type:delete', 'system:dict-type:delete.submit'),
        ('system:dict-data:list', 'system:dict-data:list.query'),
        ('system:dict-data:list', 'system:dict-data:by-type.query'),
        ('system:dict-data:list', 'system:dict-data:all.query'),
        ('system:dict-data:create', 'system:dict-type:list.query'),
        ('system:dict-data:create', 'system:dict-data:create.submit'),
        ('system:dict-data:update', 'system:dict-type:list.query'),
        ('system:dict-data:update', 'system:dict-data:update.submit'),
        ('system:dict-data:delete', 'system:dict-data:delete.submit'),
        ('system:login-log:list', 'system:login-log:list.query'),
        ('system:operation-log:list', 'system:operation-log:list.query'),
        ('system:operation-log:detail', 'system:operation-log:detail.query'),
        ('system:monitor:server', 'system:monitor:server.query'),
        ('system:monitor:cache', 'system:monitor:cache-info.query'),
        ('system:monitor:cache', 'system:monitor:cache-keys.query'),
        ('system:monitor:cache', 'system:monitor:cache-key-detail.query'),
        ('system:monitor:cache-delete', 'system:monitor:cache-key-delete.submit'),
        ('system:monitor:cache-delete', 'system:monitor:cache-keys-delete.submit'),
        ('scheduler:job:list', 'scheduler:job:list.query'),
        ('scheduler:job:list', 'scheduler:job:detail.query'),
        ('scheduler:job:list', 'scheduler:job:namespaces.query'),
        ('scheduler:job:list', 'scheduler:job:apps.query'),
        ('scheduler:job:create', 'scheduler:job:create.submit'),
        ('scheduler:job:create', 'scheduler:job:namespaces.query'),
        ('scheduler:job:create', 'scheduler:job:apps.query'),
        ('scheduler:job:update', 'scheduler:job:detail.query'),
        ('scheduler:job:update', 'scheduler:job:update.submit'),
        ('scheduler:job:update', 'scheduler:job:namespaces.query'),
        ('scheduler:job:update', 'scheduler:job:apps.query'),
        ('scheduler:job:toggle', 'scheduler:job:enable.submit'),
        ('scheduler:job:toggle', 'scheduler:job:disable.submit'),
        ('scheduler:job:trigger', 'scheduler:job:trigger.submit'),
        ('scheduler:job:delete', 'scheduler:job:delete.submit'),
        ('scheduler:run:list', 'scheduler:job:list.query'),
        ('scheduler:run:list', 'scheduler:run:list.query'),
        ('scheduler:run:list', 'scheduler:run:latest-history.query'),
        ('scheduler:run:detail', 'scheduler:run:list.query'),
        ('scheduler:run:detail', 'scheduler:run:latest-history.query'),
        ('file:manage:list', 'file:manage:list.query'),
        ('file:manage:list', 'file:manage:detail.query'),
        ('file:manage:list', 'file:folder:tree.query'),
        ('file:manage:list', 'file:folder:detail.query'),
        ('file:manage:upload', 'file:manage:upload.submit'),
        ('file:manage:upload', 'file:manage:upload-batch.submit'),
        ('file:manage:upload', 'file:manage:presign-upload.submit'),
        ('file:manage:upload', 'file:manage:presign-upload-callback.submit'),
        ('file:manage:upload', 'file:manage:multipart-init.submit'),
        ('file:manage:upload', 'file:manage:multipart-parts.query'),
        ('file:manage:upload', 'file:manage:multipart-complete.submit'),
        ('file:manage:upload', 'file:manage:multipart-abort.submit'),
        ('file:manage:update', 'file:manage:detail.query'),
        ('file:manage:update', 'file:folder:tree.query'),
        ('file:manage:update', 'file:manage:display-name.update'),
        ('file:manage:update', 'file:manage:move.update'),
        ('file:manage:update', 'file:manage:visibility.update'),
        ('file:manage:update', 'file:manage:status.update'),
        ('file:manage:delete', 'file:manage:delete.submit'),
        ('file:manage:share', 'file:manage:detail.query'),
        ('file:manage:share', 'file:manage:share.create'),
        ('file:manage:share', 'file:manage:share.delete'),
        ('file:folder:create', 'file:folder:tree.query'),
        ('file:folder:create', 'file:folder:create.submit'),
        ('file:folder:update', 'file:folder:tree.query'),
        ('file:folder:update', 'file:folder:detail.query'),
        ('file:folder:update', 'file:folder:update.submit'),
        ('file:folder:delete', 'file:folder:delete.submit'),
        ('file:manage:download', 'file:manage:presign-download.query'),
        ('file:manage:download', 'file:manage:download.query')
) AS mapping(auth_mark, resource_code) ON mapping.auth_mark = m.auth_mark
JOIN sys.resource r ON r.resource_code = mapping.resource_code
WHERE m.menu_type = 2
ON CONFLICT (action_menu_id, resource_id) DO NOTHING;
