feat(server/rbac): 权限页聚合迁移、最后管理员保护与配置原子落盘
PageCatalog 将 admin-config 重构为 6 大聚合分类,并加旧 key 别名兼容旧链接; RbacStore 接入原子写 + 损坏备份,新增「最后管理员」保护,避免操作后系统无任何在岗管理员; ConfigStore 改用 AtomicFile 持久化;新增 Infra/AtomicFile 原子写工具(临时名带 GUID 防并发)。 Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
using System.Collections.Concurrent;
|
||||
using System.Text.Json;
|
||||
using MiGu.Server.Infra;
|
||||
|
||||
namespace MiGu.Server.Configs;
|
||||
|
||||
@@ -139,6 +140,9 @@ public sealed class ConfigStore
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogWarning(ex, "加载 {Section} 失败,回退到默认值", s);
|
||||
// S2:疑似损坏的配置先备份,避免随后写入的默认值把用户配置永久冲掉。
|
||||
var bak = AtomicFile.BackupCorrupt(file);
|
||||
if (bak != null) _logger.LogWarning("已备份疑似损坏的 {Section} 配置到 {Backup}", s, bak);
|
||||
}
|
||||
}
|
||||
_mem[s] = NewDefault(s);
|
||||
@@ -184,7 +188,7 @@ public sealed class ConfigStore
|
||||
["payload"] = toWrite.Payload
|
||||
};
|
||||
var json = JsonSerializer.Serialize(root, _jsonOpts);
|
||||
File.WriteAllText(FilePath(env.Section), json);
|
||||
AtomicFile.WriteAllText(FilePath(env.Section), json);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user